| Index: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
|
| diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
|
| index d60dd9572d84738d22f540395377b29c817d7870..fe09a8f3005db5747365fa1fd2606c318128ed19 100644
|
| --- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
|
| +++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
|
| @@ -951,12 +951,17 @@ class BlinkGCPluginConsumer : public ASTConsumer {
|
| if (CXXMethodDecl* trace = info->GetTraceMethod()) {
|
| if (trace->isPure())
|
| ReportClassDeclaresPureVirtualTrace(info, trace);
|
| - if (info->record()->isPolymorphic())
|
| - CheckPolymorphicClass(info, trace);
|
| } else if (info->RequiresTraceMethod()) {
|
| ReportClassRequiresTraceMethod(info);
|
| }
|
|
|
| + // Check polymorphic classes that are GC-derived or have a trace method.
|
| + if (info->record()->hasDefinition() && info->record()->isPolymorphic()) {
|
| + CXXMethodDecl* trace = info->GetTraceMethod();
|
| + if (trace || info->IsGCDerived())
|
| + CheckPolymorphicClass(info, trace);
|
| + }
|
| +
|
| {
|
| CheckFieldsVisitor visitor(options_);
|
| if (visitor.ContainsInvalidFields(info))
|
| @@ -1010,8 +1015,8 @@ class BlinkGCPluginConsumer : public ASTConsumer {
|
| // hold to satisfy that assumption:
|
| //
|
| // 1. If trace is virtual, then it must be defined in the left-most base.
|
| - // This ensures that if the vtable is initialized and it contains a pointer to
|
| - // the trace method.
|
| + // This ensures that if the vtable is initialized then it contains a pointer
|
| + // to the trace method.
|
| //
|
| // 2. If trace is non-virtual, then the trace method is defined and we must
|
| // ensure that the left-most base defines a vtable. This ensures that the
|
| @@ -1041,7 +1046,7 @@ class BlinkGCPluginConsumer : public ASTConsumer {
|
| return;
|
|
|
| // Stop with the left-most prior to a safe polymorphic base (a safe base
|
| - // is non-polymorphic and contains no fields that need tracing).
|
| + // is non-polymorphic and contains no fields).
|
| if (Config::IsSafePolymorphicBase(name))
|
| break;
|
|
|
| @@ -1052,7 +1057,7 @@ class BlinkGCPluginConsumer : public ASTConsumer {
|
| if (RecordInfo* left_most_info = cache_.Lookup(left_most)) {
|
|
|
| // Check condition (1):
|
| - if (trace->isVirtual()) {
|
| + if (trace && trace->isVirtual()) {
|
| if (CXXMethodDecl* trace = left_most_info->GetTraceMethod()) {
|
| if (trace->isVirtual())
|
| return;
|
| @@ -1062,7 +1067,7 @@ class BlinkGCPluginConsumer : public ASTConsumer {
|
| }
|
|
|
| // Check condition (2):
|
| - if (DeclaresVirtualMethods(info->record()))
|
| + if (DeclaresVirtualMethods(left_most))
|
| return;
|
| if (left_most_base) {
|
| ++it; // Get the base next to the "safe polymorphic base"
|
|
|