 Chromium Code Reviews
 Chromium Code Reviews Issue 2696713003:
  blink_gc_plugin: detect singletons with embedded ScriptWrappables.
    
  
    Issue 2696713003:
  blink_gc_plugin: detect singletons with embedded ScriptWrappables. 
  | OLD | NEW | 
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "BlinkGCPluginConsumer.h" | 5 #include "BlinkGCPluginConsumer.h" | 
| 6 | 6 | 
| 7 #include <algorithm> | 7 #include <algorithm> | 
| 8 #include <set> | 8 #include <set> | 
| 9 | 9 | 
| 10 #include "CheckDispatchVisitor.h" | 10 #include "CheckDispatchVisitor.h" | 
| 11 #include "CheckFieldsVisitor.h" | 11 #include "CheckFieldsVisitor.h" | 
| 12 #include "CheckFinalizerVisitor.h" | 12 #include "CheckFinalizerVisitor.h" | 
| 13 #include "CheckGCRootsVisitor.h" | 13 #include "CheckGCRootsVisitor.h" | 
| 14 #include "CheckSingletonVisitor.h" | |
| 14 #include "CheckTraceVisitor.h" | 15 #include "CheckTraceVisitor.h" | 
| 15 #include "CollectVisitor.h" | 16 #include "CollectVisitor.h" | 
| 16 #include "JsonWriter.h" | 17 #include "JsonWriter.h" | 
| 17 #include "RecordInfo.h" | 18 #include "RecordInfo.h" | 
| 18 #include "clang/AST/RecursiveASTVisitor.h" | 19 #include "clang/AST/RecursiveASTVisitor.h" | 
| 19 #include "clang/Sema/Sema.h" | 20 #include "clang/Sema/Sema.h" | 
| 20 | 21 | 
| 21 using namespace clang; | 22 using namespace clang; | 
| 22 | 23 | 
| 23 namespace { | 24 namespace { | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 Config::UseLegacyNames(); | 81 Config::UseLegacyNames(); | 
| 81 } | 82 } | 
| 82 | 83 | 
| 83 void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) { | 84 void BlinkGCPluginConsumer::HandleTranslationUnit(ASTContext& context) { | 
| 84 // Don't run the plugin if the compilation unit is already invalid. | 85 // Don't run the plugin if the compilation unit is already invalid. | 
| 85 if (reporter_.hasErrorOccurred()) | 86 if (reporter_.hasErrorOccurred()) | 
| 86 return; | 87 return; | 
| 87 | 88 | 
| 88 ParseFunctionTemplates(context.getTranslationUnitDecl()); | 89 ParseFunctionTemplates(context.getTranslationUnitDecl()); | 
| 89 | 90 | 
| 90 CollectVisitor visitor; | 91 CollectVisitor visitor(options_.warn_singleton_with_scriptwrappables); | 
| 91 visitor.TraverseDecl(context.getTranslationUnitDecl()); | 92 visitor.TraverseDecl(context.getTranslationUnitDecl()); | 
| 92 | 93 | 
| 93 if (options_.dump_graph) { | 94 if (options_.dump_graph) { | 
| 94 std::error_code err; | 95 std::error_code err; | 
| 95 // TODO: Make createDefaultOutputFile or a shorter createOutputFile work. | 96 // TODO: Make createDefaultOutputFile or a shorter createOutputFile work. | 
| 96 json_ = JsonWriter::from(instance_.createOutputFile( | 97 json_ = JsonWriter::from(instance_.createOutputFile( | 
| 97 "", // OutputPath | 98 "", // OutputPath | 
| 98 err, // Errors | 99 err, // Errors | 
| 99 true, // Binary | 100 true, // Binary | 
| 100 true, // RemoveFileOnSignal | 101 true, // RemoveFileOnSignal | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 113 << "Failed to create an output file for the object graph.\n"; | 114 << "Failed to create an output file for the object graph.\n"; | 
| 114 } | 115 } | 
| 115 } | 116 } | 
| 116 | 117 | 
| 117 for (const auto& record : visitor.record_decls()) | 118 for (const auto& record : visitor.record_decls()) | 
| 118 CheckRecord(cache_.Lookup(record)); | 119 CheckRecord(cache_.Lookup(record)); | 
| 119 | 120 | 
| 120 for (const auto& method : visitor.trace_decls()) | 121 for (const auto& method : visitor.trace_decls()) | 
| 121 CheckTracingMethod(method); | 122 CheckTracingMethod(method); | 
| 122 | 123 | 
| 124 for (const auto& singleton : visitor.singleton_decls()) | |
| 125 CheckStaticSingleton(singleton); | |
| 126 | |
| 123 if (json_) { | 127 if (json_) { | 
| 124 json_->CloseList(); | 128 json_->CloseList(); | 
| 125 delete json_; | 129 delete json_; | 
| 126 json_ = 0; | 130 json_ = 0; | 
| 127 } | 131 } | 
| 128 } | 132 } | 
| 129 | 133 | 
| 130 void BlinkGCPluginConsumer::ParseFunctionTemplates(TranslationUnitDecl* decl) { | 134 void BlinkGCPluginConsumer::ParseFunctionTemplates(TranslationUnitDecl* decl) { | 
| 131 if (!instance_.getLangOpts().DelayedTemplateParsing) | 135 if (!instance_.getLangOpts().DelayedTemplateParsing) | 
| 132 return; // Nothing to do. | 136 return; // Nothing to do. | 
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 for (auto& field : parent->GetFields()) { | 561 for (auto& field : parent->GetFields()) { | 
| 558 if (!field.second.IsProperlyTraced() || | 562 if (!field.second.IsProperlyTraced() || | 
| 559 field.second.IsInproperlyTraced()) { | 563 field.second.IsInproperlyTraced()) { | 
| 560 // Report one or more tracing-related field errors. | 564 // Report one or more tracing-related field errors. | 
| 561 reporter_.FieldsImproperlyTraced(parent, trace); | 565 reporter_.FieldsImproperlyTraced(parent, trace); | 
| 562 break; | 566 break; | 
| 563 } | 567 } | 
| 564 } | 568 } | 
| 565 } | 569 } | 
| 566 | 570 | 
| 571 void BlinkGCPluginConsumer::CheckStaticSingleton(clang::VarDecl* singleton) { | |
| 572 // Ignorance is a declaration-level annotation, so eagerly checked for | |
| 573 // before adding it to the processing set. | |
| 574 assert(!Config::IsIgnoreAnnotated(singleton)); | |
| 575 | |
| 576 const Type* singleton_type = singleton->getType().getTypePtr(); | |
| 577 if (singleton_type->isPointerType() || singleton_type->isReferenceType()) | |
| 578 singleton_type = singleton_type->getPointeeType().getTypePtr(); | |
| 579 | |
| 580 CXXRecordDecl* record = singleton_type->getAsCXXRecordDecl(); | |
| 581 if (!record) | |
| 582 return; | |
| 583 | |
| 584 RecordInfo* info = cache_.Lookup(record); | |
| 585 if (!info) | |
| 586 return; | |
| 587 | |
| 588 // Walk over singleton type, looking for undesirable ScriptWrappable | |
| 589 // references. | |
| 590 CheckSingletonVisitor visitor; | |
| 591 if (!visitor.CheckIfSafe(info, singleton_type)) { | |
| 592 reporter_.StaticSingletonContainsScriptWrappable(singleton); | |
| 593 for (auto error : visitor.illegal_types()) { | |
| 
dcheng
2017/02/16 04:35:51
const auto& to suppress a copy
 
sof
2017/02/16 06:45:34
done, thanks for catching that one.
 | |
| 594 reporter_.NoteUnsafeScriptWrappableField( | |
| 595 singleton, error.first, | |
| 596 QualType::getAsString( | |
| 597 error.second->getCanonicalTypeInternal().split())); | |
| 598 } | |
| 599 } | |
| 600 } | |
| 601 | |
| 567 void BlinkGCPluginConsumer::DumpClass(RecordInfo* info) { | 602 void BlinkGCPluginConsumer::DumpClass(RecordInfo* info) { | 
| 568 if (!json_) | 603 if (!json_) | 
| 569 return; | 604 return; | 
| 570 | 605 | 
| 571 json_->OpenObject(); | 606 json_->OpenObject(); | 
| 572 json_->Write("name", info->record()->getQualifiedNameAsString()); | 607 json_->Write("name", info->record()->getQualifiedNameAsString()); | 
| 573 json_->Write("loc", GetLocString(info->record()->getLocStart())); | 608 json_->Write("loc", GetLocString(info->record()->getLocStart())); | 
| 574 json_->CloseObject(); | 609 json_->CloseObject(); | 
| 575 | 610 | 
| 576 class DumpEdgeVisitor : public RecursiveEdgeVisitor { | 611 class DumpEdgeVisitor : public RecursiveEdgeVisitor { | 
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 717 SourceLocation spelling_location = source_manager.getSpellingLoc(loc); | 752 SourceLocation spelling_location = source_manager.getSpellingLoc(loc); | 
| 718 PresumedLoc ploc = source_manager.getPresumedLoc(spelling_location); | 753 PresumedLoc ploc = source_manager.getPresumedLoc(spelling_location); | 
| 719 if (ploc.isInvalid()) { | 754 if (ploc.isInvalid()) { | 
| 720 // If we're in an invalid location, we're looking at things that aren't | 755 // If we're in an invalid location, we're looking at things that aren't | 
| 721 // actually stated in the source. | 756 // actually stated in the source. | 
| 722 return false; | 757 return false; | 
| 723 } | 758 } | 
| 724 *filename = ploc.getFilename(); | 759 *filename = ploc.getFilename(); | 
| 725 return true; | 760 return true; | 
| 726 } | 761 } | 
| OLD | NEW |