| 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 |