OLD | NEW |
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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 | 52 |
53 const char kClassRequiresFinalization[] = | 53 const char kClassRequiresFinalization[] = |
54 "[blink-gc] Class %0 requires finalization."; | 54 "[blink-gc] Class %0 requires finalization."; |
55 | 55 |
56 const char kClassDoesNotRequireFinalization[] = | 56 const char kClassDoesNotRequireFinalization[] = |
57 "[blink-gc] Class %0 may not require finalization."; | 57 "[blink-gc] Class %0 may not require finalization."; |
58 | 58 |
59 const char kFinalizerAccessesFinalizedField[] = | 59 const char kFinalizerAccessesFinalizedField[] = |
60 "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; | 60 "[blink-gc] Finalizer %0 accesses potentially finalized field %1."; |
61 | 61 |
| 62 const char kFinalizerAccessesEagerlyFinalizedField[] = |
| 63 "[blink-gc] Finalizer %0 accesses eagerly finalized field %1."; |
| 64 |
62 const char kRawPtrToGCManagedClassNote[] = | 65 const char kRawPtrToGCManagedClassNote[] = |
63 "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; | 66 "[blink-gc] Raw pointer field %0 to a GC managed class declared here:"; |
64 | 67 |
65 const char kRefPtrToGCManagedClassNote[] = | 68 const char kRefPtrToGCManagedClassNote[] = |
66 "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; | 69 "[blink-gc] RefPtr field %0 to a GC managed class declared here:"; |
67 | 70 |
68 const char kOwnPtrToGCManagedClassNote[] = | 71 const char kOwnPtrToGCManagedClassNote[] = |
69 "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; | 72 "[blink-gc] OwnPtr field %0 to a GC managed class declared here:"; |
70 | 73 |
71 const char kStackAllocatedFieldNote[] = | 74 const char kStackAllocatedFieldNote[] = |
(...skipping 29 matching lines...) Expand all Loading... |
101 | 104 |
102 const char kMissingTraceDispatch[] = | 105 const char kMissingTraceDispatch[] = |
103 "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; | 106 "[blink-gc] Missing dispatch to class %0 in manual trace dispatch."; |
104 | 107 |
105 const char kMissingFinalizeDispatch[] = | 108 const char kMissingFinalizeDispatch[] = |
106 "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; | 109 "[blink-gc] Missing dispatch to class %0 in manual finalize dispatch."; |
107 | 110 |
108 const char kFinalizedFieldNote[] = | 111 const char kFinalizedFieldNote[] = |
109 "[blink-gc] Potentially finalized field %0 declared here:"; | 112 "[blink-gc] Potentially finalized field %0 declared here:"; |
110 | 113 |
| 114 const char kEagerlyFinalizedFieldNote[] = |
| 115 "[blink-gc] Field %0 having eagerly finalized value, declared here:"; |
| 116 |
111 const char kUserDeclaredDestructorNote[] = | 117 const char kUserDeclaredDestructorNote[] = |
112 "[blink-gc] User-declared destructor declared here:"; | 118 "[blink-gc] User-declared destructor declared here:"; |
113 | 119 |
114 const char kUserDeclaredFinalizerNote[] = | 120 const char kUserDeclaredFinalizerNote[] = |
115 "[blink-gc] User-declared finalizer declared here:"; | 121 "[blink-gc] User-declared finalizer declared here:"; |
116 | 122 |
117 const char kBaseRequiresFinalizationNote[] = | 123 const char kBaseRequiresFinalizationNote[] = |
118 "[blink-gc] Base class %0 requiring finalization declared here:"; | 124 "[blink-gc] Base class %0 requiring finalization declared here:"; |
119 | 125 |
120 const char kFieldRequiresFinalizationNote[] = | 126 const char kFieldRequiresFinalizationNote[] = |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 // either a Member, a heap-allocated collection or an off-heap collection that | 242 // either a Member, a heap-allocated collection or an off-heap collection that |
237 // contains Members. Invalid uses are currently identified as passing the field | 243 // contains Members. Invalid uses are currently identified as passing the field |
238 // as the argument of a procedure call or using the -> or [] operators on it. | 244 // as the argument of a procedure call or using the -> or [] operators on it. |
239 class CheckFinalizerVisitor | 245 class CheckFinalizerVisitor |
240 : public RecursiveASTVisitor<CheckFinalizerVisitor> { | 246 : public RecursiveASTVisitor<CheckFinalizerVisitor> { |
241 private: | 247 private: |
242 // Simple visitor to determine if the content of a field might be collected | 248 // Simple visitor to determine if the content of a field might be collected |
243 // during finalization. | 249 // during finalization. |
244 class MightBeCollectedVisitor : public EdgeVisitor { | 250 class MightBeCollectedVisitor : public EdgeVisitor { |
245 public: | 251 public: |
246 MightBeCollectedVisitor() : might_be_collected_(false) {} | 252 MightBeCollectedVisitor(bool is_eagerly_finalized) |
| 253 : might_be_collected_(false) |
| 254 , is_eagerly_finalized_(is_eagerly_finalized) |
| 255 , as_eagerly_finalized_(false) {} |
247 bool might_be_collected() { return might_be_collected_; } | 256 bool might_be_collected() { return might_be_collected_; } |
248 void VisitMember(Member* edge) override { might_be_collected_ = true; } | 257 bool as_eagerly_finalized() { return as_eagerly_finalized_; } |
| 258 void VisitMember(Member* edge) override { |
| 259 if (is_eagerly_finalized_) { |
| 260 if (edge->ptr()->IsValue()) { |
| 261 Value* member = static_cast<Value*>(edge->ptr()); |
| 262 if (member->value()->IsEagerlyFinalized()) { |
| 263 might_be_collected_ = true; |
| 264 as_eagerly_finalized_ = true; |
| 265 } |
| 266 } |
| 267 return; |
| 268 } |
| 269 might_be_collected_ = true; |
| 270 } |
249 void VisitCollection(Collection* edge) override { | 271 void VisitCollection(Collection* edge) override { |
250 if (edge->on_heap()) { | 272 if (edge->on_heap() && !is_eagerly_finalized_) { |
251 might_be_collected_ = !edge->is_root(); | 273 might_be_collected_ = !edge->is_root(); |
252 } else { | 274 } else { |
253 edge->AcceptMembers(this); | 275 edge->AcceptMembers(this); |
254 } | 276 } |
255 } | 277 } |
256 | 278 |
257 private: | 279 private: |
258 bool might_be_collected_; | 280 bool might_be_collected_; |
| 281 bool is_eagerly_finalized_; |
| 282 bool as_eagerly_finalized_; |
259 }; | 283 }; |
260 | 284 |
261 public: | 285 public: |
262 typedef std::vector<std::pair<MemberExpr*, FieldPoint*> > Errors; | 286 class Error { |
| 287 public: |
| 288 Error(MemberExpr *member, |
| 289 bool as_eagerly_finalized, |
| 290 FieldPoint* field) |
| 291 : member_(member) |
| 292 , as_eagerly_finalized_(as_eagerly_finalized) |
| 293 , field_(field) {} |
263 | 294 |
264 CheckFinalizerVisitor(RecordCache* cache) | 295 MemberExpr* member_; |
265 : blacklist_context_(false), cache_(cache) {} | 296 bool as_eagerly_finalized_; |
| 297 FieldPoint* field_; |
| 298 }; |
| 299 |
| 300 typedef std::vector<Error> Errors; |
| 301 |
| 302 CheckFinalizerVisitor(RecordCache* cache, bool is_eagerly_finalized) |
| 303 : blacklist_context_(false) |
| 304 , cache_(cache) |
| 305 , is_eagerly_finalized_(is_eagerly_finalized) {} |
266 | 306 |
267 Errors& finalized_fields() { return finalized_fields_; } | 307 Errors& finalized_fields() { return finalized_fields_; } |
268 | 308 |
269 bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr* expr) { | 309 bool WalkUpFromCXXOperatorCallExpr(CXXOperatorCallExpr* expr) { |
270 // Only continue the walk-up if the operator is a blacklisted one. | 310 // Only continue the walk-up if the operator is a blacklisted one. |
271 switch (expr->getOperator()) { | 311 switch (expr->getOperator()) { |
272 case OO_Arrow: | 312 case OO_Arrow: |
273 case OO_Subscript: | 313 case OO_Subscript: |
274 this->WalkUpFromCallExpr(expr); | 314 this->WalkUpFromCallExpr(expr); |
275 default: | 315 default: |
(...skipping 17 matching lines...) Expand all Loading... |
293 return true; | 333 return true; |
294 | 334 |
295 RecordInfo* info = cache_->Lookup(field->getParent()); | 335 RecordInfo* info = cache_->Lookup(field->getParent()); |
296 if (!info) | 336 if (!info) |
297 return true; | 337 return true; |
298 | 338 |
299 RecordInfo::Fields::iterator it = info->GetFields().find(field); | 339 RecordInfo::Fields::iterator it = info->GetFields().find(field); |
300 if (it == info->GetFields().end()) | 340 if (it == info->GetFields().end()) |
301 return true; | 341 return true; |
302 | 342 |
303 if (blacklist_context_ && MightBeCollected(&it->second)) | 343 if (seen_members_.find(member) != seen_members_.end()) |
304 finalized_fields_.push_back(std::make_pair(member, &it->second)); | 344 return true; |
| 345 |
| 346 bool as_eagerly_finalized = false; |
| 347 if (blacklist_context_ && |
| 348 MightBeCollected(&it->second, as_eagerly_finalized)) { |
| 349 finalized_fields_.push_back( |
| 350 Error(member, as_eagerly_finalized, &it->second)); |
| 351 seen_members_.insert(member); |
| 352 } |
305 return true; | 353 return true; |
306 } | 354 } |
307 | 355 |
308 bool MightBeCollected(FieldPoint* point) { | 356 bool MightBeCollected(FieldPoint* point, bool& as_eagerly_finalized) { |
309 MightBeCollectedVisitor visitor; | 357 MightBeCollectedVisitor visitor(is_eagerly_finalized_); |
310 point->edge()->Accept(&visitor); | 358 point->edge()->Accept(&visitor); |
| 359 as_eagerly_finalized = visitor.as_eagerly_finalized(); |
311 return visitor.might_be_collected(); | 360 return visitor.might_be_collected(); |
312 } | 361 } |
313 | 362 |
314 private: | 363 private: |
315 bool blacklist_context_; | 364 bool blacklist_context_; |
316 Errors finalized_fields_; | 365 Errors finalized_fields_; |
| 366 std::set<MemberExpr*> seen_members_; |
317 RecordCache* cache_; | 367 RecordCache* cache_; |
| 368 bool is_eagerly_finalized_; |
318 }; | 369 }; |
319 | 370 |
320 // This visitor checks that a method contains within its body, a call to a | 371 // This visitor checks that a method contains within its body, a call to a |
321 // method on the provided receiver class. This is used to check manual | 372 // method on the provided receiver class. This is used to check manual |
322 // dispatching for trace and finalize methods. | 373 // dispatching for trace and finalize methods. |
323 class CheckDispatchVisitor : public RecursiveASTVisitor<CheckDispatchVisitor> { | 374 class CheckDispatchVisitor : public RecursiveASTVisitor<CheckDispatchVisitor> { |
324 public: | 375 public: |
325 CheckDispatchVisitor(RecordInfo* receiver) | 376 CheckDispatchVisitor(RecordInfo* receiver) |
326 : receiver_(receiver), dispatched_to_receiver_(false) {} | 377 : receiver_(receiver), dispatched_to_receiver_(false) {} |
327 | 378 |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
962 diag_class_contains_invalid_fields_warning_ = diagnostic_.getCustomDiagID( | 1013 diag_class_contains_invalid_fields_warning_ = diagnostic_.getCustomDiagID( |
963 DiagnosticsEngine::Warning, kClassContainsInvalidFields); | 1014 DiagnosticsEngine::Warning, kClassContainsInvalidFields); |
964 diag_class_contains_gc_root_ = | 1015 diag_class_contains_gc_root_ = |
965 diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); | 1016 diagnostic_.getCustomDiagID(getErrorLevel(), kClassContainsGCRoot); |
966 diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( | 1017 diag_class_requires_finalization_ = diagnostic_.getCustomDiagID( |
967 getErrorLevel(), kClassRequiresFinalization); | 1018 getErrorLevel(), kClassRequiresFinalization); |
968 diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( | 1019 diag_class_does_not_require_finalization_ = diagnostic_.getCustomDiagID( |
969 DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); | 1020 DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization); |
970 diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( | 1021 diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID( |
971 getErrorLevel(), kFinalizerAccessesFinalizedField); | 1022 getErrorLevel(), kFinalizerAccessesFinalizedField); |
| 1023 diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID( |
| 1024 getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField); |
972 diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( | 1025 diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID( |
973 getErrorLevel(), kOverriddenNonVirtualTrace); | 1026 getErrorLevel(), kOverriddenNonVirtualTrace); |
974 diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( | 1027 diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID( |
975 getErrorLevel(), kMissingTraceDispatchMethod); | 1028 getErrorLevel(), kMissingTraceDispatchMethod); |
976 diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( | 1029 diag_missing_finalize_dispatch_method_ = diagnostic_.getCustomDiagID( |
977 getErrorLevel(), kMissingFinalizeDispatchMethod); | 1030 getErrorLevel(), kMissingFinalizeDispatchMethod); |
978 diag_virtual_and_manual_dispatch_ = | 1031 diag_virtual_and_manual_dispatch_ = |
979 diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); | 1032 diagnostic_.getCustomDiagID(getErrorLevel(), kVirtualAndManualDispatch); |
980 diag_missing_trace_dispatch_ = | 1033 diag_missing_trace_dispatch_ = |
981 diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); | 1034 diagnostic_.getCustomDiagID(getErrorLevel(), kMissingTraceDispatch); |
(...skipping 29 matching lines...) Expand all Loading... |
1011 diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( | 1064 diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( |
1012 DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); | 1065 DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); |
1013 diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( | 1066 diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( |
1014 DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); | 1067 DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); |
1015 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 1068 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( |
1016 DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); | 1069 DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); |
1017 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( | 1070 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( |
1018 DiagnosticsEngine::Note, kFieldContainsGCRootNote); | 1071 DiagnosticsEngine::Note, kFieldContainsGCRootNote); |
1019 diag_finalized_field_note_ = diagnostic_.getCustomDiagID( | 1072 diag_finalized_field_note_ = diagnostic_.getCustomDiagID( |
1020 DiagnosticsEngine::Note, kFinalizedFieldNote); | 1073 DiagnosticsEngine::Note, kFinalizedFieldNote); |
| 1074 diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID( |
| 1075 DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote); |
1021 diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( | 1076 diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID( |
1022 DiagnosticsEngine::Note, kUserDeclaredDestructorNote); | 1077 DiagnosticsEngine::Note, kUserDeclaredDestructorNote); |
1023 diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( | 1078 diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID( |
1024 DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); | 1079 DiagnosticsEngine::Note, kUserDeclaredFinalizerNote); |
1025 diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( | 1080 diag_base_requires_finalization_note_ = diagnostic_.getCustomDiagID( |
1026 DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); | 1081 DiagnosticsEngine::Note, kBaseRequiresFinalizationNote); |
1027 diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( | 1082 diag_field_requires_finalization_note_ = diagnostic_.getCustomDiagID( |
1028 DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); | 1083 DiagnosticsEngine::Note, kFieldRequiresFinalizationNote); |
1029 diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( | 1084 diag_overridden_non_virtual_trace_note_ = diagnostic_.getCustomDiagID( |
1030 DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); | 1085 DiagnosticsEngine::Note, kOverriddenNonVirtualTraceNote); |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1380 } | 1435 } |
1381 } | 1436 } |
1382 | 1437 |
1383 // TODO: Should we collect destructors similar to trace methods? | 1438 // TODO: Should we collect destructors similar to trace methods? |
1384 void CheckFinalization(RecordInfo* info) { | 1439 void CheckFinalization(RecordInfo* info) { |
1385 CXXDestructorDecl* dtor = info->record()->getDestructor(); | 1440 CXXDestructorDecl* dtor = info->record()->getDestructor(); |
1386 | 1441 |
1387 // For finalized classes, check the finalization method if possible. | 1442 // For finalized classes, check the finalization method if possible. |
1388 if (info->IsGCFinalized()) { | 1443 if (info->IsGCFinalized()) { |
1389 if (dtor && dtor->hasBody()) { | 1444 if (dtor && dtor->hasBody()) { |
1390 CheckFinalizerVisitor visitor(&cache_); | 1445 CheckFinalizerVisitor visitor(&cache_, info->IsEagerlyFinalized()); |
1391 visitor.TraverseCXXMethodDecl(dtor); | 1446 visitor.TraverseCXXMethodDecl(dtor); |
1392 if (!visitor.finalized_fields().empty()) { | 1447 if (!visitor.finalized_fields().empty()) { |
1393 ReportFinalizerAccessesFinalizedFields( | 1448 ReportFinalizerAccessesFinalizedFields( |
1394 dtor, &visitor.finalized_fields()); | 1449 dtor, &visitor.finalized_fields()); |
1395 } | 1450 } |
1396 } | 1451 } |
1397 return; | 1452 return; |
1398 } | 1453 } |
1399 | 1454 |
1400 // Don't require finalization of a mixin that has not yet been "mixed in". | 1455 // Don't require finalization of a mixin that has not yet been "mixed in". |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1809 NoteFieldContainsGCRoot(point); | 1864 NoteFieldContainsGCRoot(point); |
1810 } | 1865 } |
1811 } | 1866 } |
1812 | 1867 |
1813 void ReportFinalizerAccessesFinalizedFields( | 1868 void ReportFinalizerAccessesFinalizedFields( |
1814 CXXMethodDecl* dtor, | 1869 CXXMethodDecl* dtor, |
1815 CheckFinalizerVisitor::Errors* fields) { | 1870 CheckFinalizerVisitor::Errors* fields) { |
1816 for (CheckFinalizerVisitor::Errors::iterator it = fields->begin(); | 1871 for (CheckFinalizerVisitor::Errors::iterator it = fields->begin(); |
1817 it != fields->end(); | 1872 it != fields->end(); |
1818 ++it) { | 1873 ++it) { |
1819 SourceLocation loc = it->first->getLocStart(); | 1874 SourceLocation loc = it->member_->getLocStart(); |
1820 SourceManager& manager = instance_.getSourceManager(); | 1875 SourceManager& manager = instance_.getSourceManager(); |
| 1876 bool as_eagerly_finalized = it->as_eagerly_finalized_; |
| 1877 unsigned diag_error = as_eagerly_finalized ? |
| 1878 diag_finalizer_eagerly_finalized_field_ : |
| 1879 diag_finalizer_accesses_finalized_field_; |
| 1880 unsigned diag_note = as_eagerly_finalized ? |
| 1881 diag_eagerly_finalized_field_note_ : |
| 1882 diag_finalized_field_note_; |
1821 FullSourceLoc full_loc(loc, manager); | 1883 FullSourceLoc full_loc(loc, manager); |
1822 diagnostic_.Report(full_loc, diag_finalizer_accesses_finalized_field_) | 1884 diagnostic_.Report(full_loc, diag_error) |
1823 << dtor << it->second->field(); | 1885 << dtor << it->field_->field(); |
1824 NoteField(it->second, diag_finalized_field_note_); | 1886 NoteField(it->field_, diag_note); |
1825 } | 1887 } |
1826 } | 1888 } |
1827 | 1889 |
1828 void ReportClassRequiresFinalization(RecordInfo* info) { | 1890 void ReportClassRequiresFinalization(RecordInfo* info) { |
1829 SourceLocation loc = info->record()->getInnerLocStart(); | 1891 SourceLocation loc = info->record()->getInnerLocStart(); |
1830 SourceManager& manager = instance_.getSourceManager(); | 1892 SourceManager& manager = instance_.getSourceManager(); |
1831 FullSourceLoc full_loc(loc, manager); | 1893 FullSourceLoc full_loc(loc, manager); |
1832 diagnostic_.Report(full_loc, diag_class_requires_finalization_) | 1894 diagnostic_.Report(full_loc, diag_class_requires_finalization_) |
1833 << info->record(); | 1895 << info->record(); |
1834 } | 1896 } |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2023 unsigned diag_class_must_left_mostly_derive_gc_; | 2085 unsigned diag_class_must_left_mostly_derive_gc_; |
2024 unsigned diag_class_requires_trace_method_; | 2086 unsigned diag_class_requires_trace_method_; |
2025 unsigned diag_base_requires_tracing_; | 2087 unsigned diag_base_requires_tracing_; |
2026 unsigned diag_fields_require_tracing_; | 2088 unsigned diag_fields_require_tracing_; |
2027 unsigned diag_class_contains_invalid_fields_; | 2089 unsigned diag_class_contains_invalid_fields_; |
2028 unsigned diag_class_contains_invalid_fields_warning_; | 2090 unsigned diag_class_contains_invalid_fields_warning_; |
2029 unsigned diag_class_contains_gc_root_; | 2091 unsigned diag_class_contains_gc_root_; |
2030 unsigned diag_class_requires_finalization_; | 2092 unsigned diag_class_requires_finalization_; |
2031 unsigned diag_class_does_not_require_finalization_; | 2093 unsigned diag_class_does_not_require_finalization_; |
2032 unsigned diag_finalizer_accesses_finalized_field_; | 2094 unsigned diag_finalizer_accesses_finalized_field_; |
| 2095 unsigned diag_finalizer_eagerly_finalized_field_; |
2033 unsigned diag_overridden_non_virtual_trace_; | 2096 unsigned diag_overridden_non_virtual_trace_; |
2034 unsigned diag_missing_trace_dispatch_method_; | 2097 unsigned diag_missing_trace_dispatch_method_; |
2035 unsigned diag_missing_finalize_dispatch_method_; | 2098 unsigned diag_missing_finalize_dispatch_method_; |
2036 unsigned diag_virtual_and_manual_dispatch_; | 2099 unsigned diag_virtual_and_manual_dispatch_; |
2037 unsigned diag_missing_trace_dispatch_; | 2100 unsigned diag_missing_trace_dispatch_; |
2038 unsigned diag_missing_finalize_dispatch_; | 2101 unsigned diag_missing_finalize_dispatch_; |
2039 unsigned diag_derives_non_stack_allocated_; | 2102 unsigned diag_derives_non_stack_allocated_; |
2040 unsigned diag_class_overrides_new_; | 2103 unsigned diag_class_overrides_new_; |
2041 unsigned diag_class_declares_pure_virtual_trace_; | 2104 unsigned diag_class_declares_pure_virtual_trace_; |
2042 unsigned diag_left_most_base_must_be_polymorphic_; | 2105 unsigned diag_left_most_base_must_be_polymorphic_; |
2043 unsigned diag_base_class_must_declare_virtual_trace_; | 2106 unsigned diag_base_class_must_declare_virtual_trace_; |
2044 unsigned diag_class_must_declare_gc_mixin_trace_method_; | 2107 unsigned diag_class_must_declare_gc_mixin_trace_method_; |
2045 | 2108 |
2046 unsigned diag_base_requires_tracing_note_; | 2109 unsigned diag_base_requires_tracing_note_; |
2047 unsigned diag_field_requires_tracing_note_; | 2110 unsigned diag_field_requires_tracing_note_; |
| 2111 unsigned diag_field_illegally_traced_note_; |
2048 unsigned diag_raw_ptr_to_gc_managed_class_note_; | 2112 unsigned diag_raw_ptr_to_gc_managed_class_note_; |
2049 unsigned diag_ref_ptr_to_gc_managed_class_note_; | 2113 unsigned diag_ref_ptr_to_gc_managed_class_note_; |
2050 unsigned diag_own_ptr_to_gc_managed_class_note_; | 2114 unsigned diag_own_ptr_to_gc_managed_class_note_; |
2051 unsigned diag_stack_allocated_field_note_; | 2115 unsigned diag_stack_allocated_field_note_; |
2052 unsigned diag_member_in_unmanaged_class_note_; | 2116 unsigned diag_member_in_unmanaged_class_note_; |
2053 unsigned diag_part_object_to_gc_derived_class_note_; | 2117 unsigned diag_part_object_to_gc_derived_class_note_; |
2054 unsigned diag_part_object_contains_gc_root_note_; | 2118 unsigned diag_part_object_contains_gc_root_note_; |
2055 unsigned diag_field_contains_gc_root_note_; | 2119 unsigned diag_field_contains_gc_root_note_; |
2056 unsigned diag_finalized_field_note_; | 2120 unsigned diag_finalized_field_note_; |
| 2121 unsigned diag_eagerly_finalized_field_note_; |
2057 unsigned diag_user_declared_destructor_note_; | 2122 unsigned diag_user_declared_destructor_note_; |
2058 unsigned diag_user_declared_finalizer_note_; | 2123 unsigned diag_user_declared_finalizer_note_; |
2059 unsigned diag_base_requires_finalization_note_; | 2124 unsigned diag_base_requires_finalization_note_; |
2060 unsigned diag_field_requires_finalization_note_; | 2125 unsigned diag_field_requires_finalization_note_; |
2061 unsigned diag_overridden_non_virtual_trace_note_; | 2126 unsigned diag_overridden_non_virtual_trace_note_; |
2062 unsigned diag_manual_dispatch_method_note_; | 2127 unsigned diag_manual_dispatch_method_note_; |
2063 | 2128 |
2064 CompilerInstance& instance_; | 2129 CompilerInstance& instance_; |
2065 DiagnosticsEngine& diagnostic_; | 2130 DiagnosticsEngine& diagnostic_; |
2066 BlinkGCPluginOptions options_; | 2131 BlinkGCPluginOptions options_; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2104 | 2169 |
2105 private: | 2170 private: |
2106 BlinkGCPluginOptions options_; | 2171 BlinkGCPluginOptions options_; |
2107 }; | 2172 }; |
2108 | 2173 |
2109 } // namespace | 2174 } // namespace |
2110 | 2175 |
2111 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( | 2176 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( |
2112 "blink-gc-plugin", | 2177 "blink-gc-plugin", |
2113 "Check Blink GC invariants"); | 2178 "Check Blink GC invariants"); |
OLD | NEW |