Commit 3b531d10 authored by zerny@chromium.org's avatar zerny@chromium.org

Blink GC plugin: disallow pure-virtual trace methods.

BUG=334149
R=ager@chromium.org
NOTRY=true

Review URL: https://codereview.chromium.org/278513005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269547 0039d316-1c4b-4281-b951-d872f2087c98
parent cdafa453
...@@ -120,6 +120,10 @@ const char kClassOverridesNew[] = ...@@ -120,6 +120,10 @@ const char kClassOverridesNew[] =
"[blink-gc] Garbage collected class %0" "[blink-gc] Garbage collected class %0"
" is not permitted to override its new operator."; " is not permitted to override its new operator.";
const char kClassDeclaresPureVirtualTrace[] =
"[blink-gc] Garbage collected class %0"
" is not permitted to declare a pure-virtual trace method.";
struct BlinkGCPluginOptions { struct BlinkGCPluginOptions {
BlinkGCPluginOptions() : enable_oilpan(false), dump_graph(false) {} BlinkGCPluginOptions() : enable_oilpan(false), dump_graph(false) {}
bool enable_oilpan; bool enable_oilpan;
...@@ -570,6 +574,8 @@ class BlinkGCPluginConsumer : public ASTConsumer { ...@@ -570,6 +574,8 @@ class BlinkGCPluginConsumer : public ASTConsumer {
diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated); diagnostic_.getCustomDiagID(getErrorLevel(), kDerivesNonStackAllocated);
diag_class_overrides_new_ = diag_class_overrides_new_ =
diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew); diagnostic_.getCustomDiagID(getErrorLevel(), kClassOverridesNew);
diag_class_declares_pure_virtual_trace_ = diagnostic_.getCustomDiagID(
getErrorLevel(), kClassDeclaresPureVirtualTrace);
// Register note messages. // Register note messages.
diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID(
...@@ -692,8 +698,12 @@ class BlinkGCPluginConsumer : public ASTConsumer { ...@@ -692,8 +698,12 @@ class BlinkGCPluginConsumer : public ASTConsumer {
} }
} }
if (info->RequiresTraceMethod() && !info->GetTraceMethod()) if (CXXMethodDecl* trace = info->GetTraceMethod()) {
if (trace->isPure())
ReportClassDeclaresPureVirtualTrace(info, trace);
} else if (info->RequiresTraceMethod()) {
ReportClassRequiresTraceMethod(info); ReportClassRequiresTraceMethod(info);
}
{ {
CheckFieldsVisitor visitor(options_); CheckFieldsVisitor visitor(options_);
...@@ -1252,6 +1262,15 @@ class BlinkGCPluginConsumer : public ASTConsumer { ...@@ -1252,6 +1262,15 @@ class BlinkGCPluginConsumer : public ASTConsumer {
diagnostic_.Report(full_loc, diag_class_overrides_new_) << info->record(); diagnostic_.Report(full_loc, diag_class_overrides_new_) << info->record();
} }
void ReportClassDeclaresPureVirtualTrace(RecordInfo* info,
CXXMethodDecl* trace) {
SourceLocation loc = trace->getLocStart();
SourceManager& manager = instance_.getSourceManager();
FullSourceLoc full_loc(loc, manager);
diagnostic_.Report(full_loc, diag_class_declares_pure_virtual_trace_)
<< info->record();
}
void NoteManualDispatchMethod(CXXMethodDecl* dispatch) { void NoteManualDispatchMethod(CXXMethodDecl* dispatch) {
SourceLocation loc = dispatch->getLocStart(); SourceLocation loc = dispatch->getLocStart();
SourceManager& manager = instance_.getSourceManager(); SourceManager& manager = instance_.getSourceManager();
...@@ -1333,6 +1352,7 @@ class BlinkGCPluginConsumer : public ASTConsumer { ...@@ -1333,6 +1352,7 @@ class BlinkGCPluginConsumer : public ASTConsumer {
unsigned diag_missing_finalize_dispatch_; unsigned diag_missing_finalize_dispatch_;
unsigned diag_derives_non_stack_allocated_; unsigned diag_derives_non_stack_allocated_;
unsigned diag_class_overrides_new_; unsigned diag_class_overrides_new_;
unsigned diag_class_declares_pure_virtual_trace_;
unsigned diag_field_requires_tracing_note_; unsigned diag_field_requires_tracing_note_;
unsigned diag_raw_ptr_to_gc_managed_class_note_; unsigned diag_raw_ptr_to_gc_managed_class_note_;
......
...@@ -272,11 +272,11 @@ RecordInfo::Bases& RecordInfo::GetBases() { ...@@ -272,11 +272,11 @@ RecordInfo::Bases& RecordInfo::GetBases() {
return *bases_; return *bases_;
} }
bool RecordInfo::InheritsNonPureTrace() { bool RecordInfo::InheritsTrace() {
if (CXXMethodDecl* trace = GetTraceMethod()) if (GetTraceMethod())
return !trace->isPure(); return true;
for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) { for (Bases::iterator it = GetBases().begin(); it != GetBases().end(); ++it) {
if (it->second.info()->InheritsNonPureTrace()) if (it->second.info()->InheritsTrace())
return true; return true;
} }
return false; return false;
...@@ -323,7 +323,7 @@ RecordInfo::Bases* RecordInfo::CollectBases() { ...@@ -323,7 +323,7 @@ RecordInfo::Bases* RecordInfo::CollectBases() {
if (!info) if (!info)
continue; continue;
CXXRecordDecl* base = info->record(); CXXRecordDecl* base = info->record();
TracingStatus status = info->InheritsNonPureTrace() TracingStatus status = info->InheritsTrace()
? TracingStatus::Needed() ? TracingStatus::Needed()
: TracingStatus::Unneeded(); : TracingStatus::Unneeded();
bases->insert(std::make_pair(base, BasePoint(spec, info, status))); bases->insert(std::make_pair(base, BasePoint(spec, info, status)));
......
...@@ -109,7 +109,7 @@ class RecordInfo { ...@@ -109,7 +109,7 @@ class RecordInfo {
Fields* CollectFields(); Fields* CollectFields();
Bases* CollectBases(); Bases* CollectBases();
void DetermineTracingMethods(); void DetermineTracingMethods();
bool InheritsNonPureTrace(); bool InheritsTrace();
Edge* CreateEdge(const clang::Type* type); Edge* CreateEdge(const clang::Type* type);
......
...@@ -4,11 +4,4 @@ ...@@ -4,11 +4,4 @@
#include "pure_virtual_trace.h" #include "pure_virtual_trace.h"
namespace WebCore { // Nothing to define
void C::trace(Visitor* visitor) {
visitor->trace(m_a);
// Is not required to trace base classes B and A.
}
}
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef PURE_VIRTUAL_BASE_H_ #ifndef PURE_VIRTUAL_TRACE_H_
#define PURE_VIRTUAL_BASE_H_ #define PURE_VIRTUAL_TRACE_H_
#include "heap/stubs.h" #include "heap/stubs.h"
...@@ -14,18 +14,6 @@ public: ...@@ -14,18 +14,6 @@ public:
virtual void trace(Visitor*) = 0; virtual void trace(Visitor*) = 0;
}; };
class B : public A {
public:
// Does not need a trace method.
};
class C : public B {
public:
void trace(Visitor*);
private:
Member<A> m_a;
};
} }
#endif #endif
In file included from pure_virtual_trace.cpp:5:
./pure_virtual_trace.h:14:5: warning: [blink-gc] Garbage collected class 'A' is not permitted to declare a pure-virtual trace method.
virtual void trace(Visitor*) = 0;
^
1 warning generated.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment