Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(658)

Side by Side Diff: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp

Issue 374593002: Support ignorance of base class finalizers. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/tests/class_requires_finalization_base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // This clang plugin checks various invariants of the Blink garbage 5 // This clang plugin checks various invariants of the Blink garbage
6 // collection infrastructure. 6 // collection infrastructure.
7 // 7 //
8 // Errors are described at: 8 // Errors are described at:
9 // http://www.chromium.org/developers/blink-gc-plugin-errors 9 // http://www.chromium.org/developers/blink-gc-plugin-errors
10 10
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 "[blink-gc] Garbage collected class %0" 129 "[blink-gc] Garbage collected class %0"
130 " is not permitted to declare a pure-virtual trace method."; 130 " is not permitted to declare a pure-virtual trace method.";
131 131
132 struct BlinkGCPluginOptions { 132 struct BlinkGCPluginOptions {
133 BlinkGCPluginOptions() : enable_oilpan(false), dump_graph(false) {} 133 BlinkGCPluginOptions() : enable_oilpan(false), dump_graph(false) {}
134 bool enable_oilpan; 134 bool enable_oilpan;
135 bool dump_graph; 135 bool dump_graph;
136 std::set<std::string> ignored_classes; 136 std::set<std::string> ignored_classes;
137 std::set<std::string> checked_namespaces; 137 std::set<std::string> checked_namespaces;
138 std::vector<std::string> ignored_directories; 138 std::vector<std::string> ignored_directories;
139 std::set<std::string> ignored_base_class_finalizers;
139 }; 140 };
140 141
141 typedef std::vector<CXXRecordDecl*> RecordVector; 142 typedef std::vector<CXXRecordDecl*> RecordVector;
142 typedef std::vector<CXXMethodDecl*> MethodVector; 143 typedef std::vector<CXXMethodDecl*> MethodVector;
143 144
144 // Test if a template specialization is an instantiation. 145 // Test if a template specialization is an instantiation.
145 static bool IsTemplateInstantiation(CXXRecordDecl* record) { 146 static bool IsTemplateInstantiation(CXXRecordDecl* record) {
146 ClassTemplateSpecializationDecl* spec = 147 ClassTemplateSpecializationDecl* spec =
147 dyn_cast<ClassTemplateSpecializationDecl>(record); 148 dyn_cast<ClassTemplateSpecializationDecl>(record);
148 if (!spec) 149 if (!spec)
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 json_(0) { 576 json_(0) {
576 577
577 // Only check structures in the blink, WebCore and WebKit namespaces. 578 // Only check structures in the blink, WebCore and WebKit namespaces.
578 options_.checked_namespaces.insert("blink"); 579 options_.checked_namespaces.insert("blink");
579 options_.checked_namespaces.insert("WebCore"); 580 options_.checked_namespaces.insert("WebCore");
580 options_.checked_namespaces.insert("WebKit"); 581 options_.checked_namespaces.insert("WebKit");
581 582
582 // Ignore GC implementation files. 583 // Ignore GC implementation files.
583 options_.ignored_directories.push_back("/heap/"); 584 options_.ignored_directories.push_back("/heap/");
584 585
586 // Following http://crrev.com/369633033 (Blink r177436),
587 // ignore WebCore::ScriptWrappable.
588 options_.ignored_base_class_finalizers.insert("ScriptWrappable::WebCore");
zerny-chromium 2014/07/07 09:04:33 Lets swap this so it is ns::record
589
585 // Register warning/error messages. 590 // Register warning/error messages.
586 diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID( 591 diag_class_must_left_mostly_derive_gc_ = diagnostic_.getCustomDiagID(
587 getErrorLevel(), kClassMustLeftMostlyDeriveGC); 592 getErrorLevel(), kClassMustLeftMostlyDeriveGC);
588 diag_class_requires_trace_method_ = 593 diag_class_requires_trace_method_ =
589 diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod); 594 diagnostic_.getCustomDiagID(getErrorLevel(), kClassRequiresTraceMethod);
590 diag_base_requires_tracing_ = 595 diag_base_requires_tracing_ =
591 diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing); 596 diagnostic_.getCustomDiagID(getErrorLevel(), kBaseRequiresTracing);
592 diag_fields_require_tracing_ = 597 diag_fields_require_tracing_ =
593 diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing); 598 diagnostic_.getCustomDiagID(getErrorLevel(), kFieldsRequireTracing);
594 diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID( 599 diag_class_contains_invalid_fields_ = diagnostic_.getCustomDiagID(
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
853 dtor, &visitor.finalized_fields()); 858 dtor, &visitor.finalized_fields());
854 } 859 }
855 } 860 }
856 return; 861 return;
857 } 862 }
858 863
859 // Don't require finalization of a mixin that has not yet been "mixed in". 864 // Don't require finalization of a mixin that has not yet been "mixed in".
860 if (info->IsGCMixin()) 865 if (info->IsGCMixin())
861 return; 866 return;
862 867
868 // If class has no destructor and all base class destructors can
869 // safely be ignored, do not require finalization.
870 bool has_relevant_dtors = dtor && dtor->isUserProvided();
871 for (RecordInfo::Bases::iterator it = info->GetBases().begin();
872 !has_relevant_dtors && it != info->GetBases().end();
873 ++it) {
874 if (it->second.info()->NeedsFinalization())
875 has_relevant_dtors = !IsIgnoredFinalizableBaseClass(it->second.info());
876 }
877
878 if (!has_relevant_dtors)
879 return;
zerny-chromium 2014/07/07 09:04:33 This will allow erroneous code to pass the plugin,
880
863 // Report the finalization error, and proceed to print possible causes for 881 // Report the finalization error, and proceed to print possible causes for
864 // the finalization requirement. 882 // the finalization requirement.
865 ReportClassRequiresFinalization(info); 883 ReportClassRequiresFinalization(info);
866 884
867 if (dtor && dtor->isUserProvided()) 885 if (dtor && dtor->isUserProvided())
868 NoteUserDeclaredDestructor(dtor); 886 NoteUserDeclaredDestructor(dtor);
869 887
870 for (RecordInfo::Bases::iterator it = info->GetBases().begin(); 888 for (RecordInfo::Bases::iterator it = info->GetBases().begin();
871 it != info->GetBases().end(); 889 it != info->GetBases().end();
872 ++it) { 890 ++it) {
873 if (it->second.info()->NeedsFinalization()) 891 if (it->second.info()->NeedsFinalization())
874 NoteBaseRequiresFinalization(&it->second); 892 if (!IsIgnoredFinalizableBaseClass(it->second.info()))
893 NoteBaseRequiresFinalization(&it->second);
875 } 894 }
876 895
877 for (RecordInfo::Fields::iterator it = info->GetFields().begin(); 896 for (RecordInfo::Fields::iterator it = info->GetFields().begin();
878 it != info->GetFields().end(); 897 it != info->GetFields().end();
879 ++it) { 898 ++it) {
880 if (it->second.edge()->NeedsFinalization()) 899 if (it->second.edge()->NeedsFinalization())
881 NoteField(&it->second, diag_field_requires_finalization_note_); 900 NoteField(&it->second, diag_field_requires_finalization_note_);
882 } 901 }
883 } 902 }
884 903
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1077 bool IsIgnoredClass(RecordInfo* info) { 1096 bool IsIgnoredClass(RecordInfo* info) {
1078 // Ignore any class prefixed by SameSizeAs. These are used in 1097 // Ignore any class prefixed by SameSizeAs. These are used in
1079 // Blink to verify class sizes and don't need checking. 1098 // Blink to verify class sizes and don't need checking.
1080 const string SameSizeAs = "SameSizeAs"; 1099 const string SameSizeAs = "SameSizeAs";
1081 if (info->name().compare(0, SameSizeAs.size(), SameSizeAs) == 0) 1100 if (info->name().compare(0, SameSizeAs.size(), SameSizeAs) == 0)
1082 return true; 1101 return true;
1083 return options_.ignored_classes.find(info->name()) != 1102 return options_.ignored_classes.find(info->name()) !=
1084 options_.ignored_classes.end(); 1103 options_.ignored_classes.end();
1085 } 1104 }
1086 1105
1106 bool IsIgnoredFinalizableBaseClass(RecordInfo* info) {
1107 NamespaceDecl* ns =
1108 dyn_cast<NamespaceDecl>(info->record()->getDeclContext());
1109 if (!ns)
1110 return false;
1111
1112 string qualified_name =
1113 string(info->name()).append("::").append(ns->getName());
1114 return options_.ignored_base_class_finalizers.find(qualified_name) !=
1115 options_.ignored_base_class_finalizers.end();
1116 }
1117
1087 bool InIgnoredDirectory(RecordInfo* info) { 1118 bool InIgnoredDirectory(RecordInfo* info) {
1088 string filename; 1119 string filename;
1089 if (!GetFilename(info->record()->getLocStart(), &filename)) 1120 if (!GetFilename(info->record()->getLocStart(), &filename))
1090 return false; // TODO: should we ignore non-existing file locations? 1121 return false; // TODO: should we ignore non-existing file locations?
1091 std::vector<string>::iterator it = options_.ignored_directories.begin(); 1122 std::vector<string>::iterator it = options_.ignored_directories.begin();
1092 for (; it != options_.ignored_directories.end(); ++it) 1123 for (; it != options_.ignored_directories.end(); ++it)
1093 if (filename.find(*it) != string::npos) 1124 if (filename.find(*it) != string::npos)
1094 return true; 1125 return true;
1095 return false; 1126 return false;
1096 } 1127 }
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
1477 1508
1478 private: 1509 private:
1479 BlinkGCPluginOptions options_; 1510 BlinkGCPluginOptions options_;
1480 }; 1511 };
1481 1512
1482 } // namespace 1513 } // namespace
1483 1514
1484 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( 1515 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X(
1485 "blink-gc-plugin", 1516 "blink-gc-plugin",
1486 "Check Blink GC invariants"); 1517 "Check Blink GC invariants");
OLDNEW
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/tests/class_requires_finalization_base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698