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

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

Issue 1167123002: Check Member<T> validity for stack allocated objects. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 6 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/RecordInfo.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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 64
65 const char kRawPtrToGCManagedClassNote[] = 65 const char kRawPtrToGCManagedClassNote[] =
66 "[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:";
67 67
68 const char kRefPtrToGCManagedClassNote[] = 68 const char kRefPtrToGCManagedClassNote[] =
69 "[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:";
70 70
71 const char kOwnPtrToGCManagedClassNote[] = 71 const char kOwnPtrToGCManagedClassNote[] =
72 "[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:";
73 73
74 const char kMemberToGCUnmanagedClassNote[] =
75 "[blink-gc] Member field %0 to non-GC managed class declared here:";
76
74 const char kStackAllocatedFieldNote[] = 77 const char kStackAllocatedFieldNote[] =
75 "[blink-gc] Stack-allocated field %0 declared here:"; 78 "[blink-gc] Stack-allocated field %0 declared here:";
76 79
77 const char kMemberInUnmanagedClassNote[] = 80 const char kMemberInUnmanagedClassNote[] =
78 "[blink-gc] Member field %0 in unmanaged class declared here:"; 81 "[blink-gc] Member field %0 in unmanaged class declared here:";
79 82
80 const char kPartObjectToGCDerivedClassNote[] = 83 const char kPartObjectToGCDerivedClassNote[] =
81 "[blink-gc] Part-object field %0 to a GC derived class declared here:"; 84 "[blink-gc] Part-object field %0 to a GC derived class declared here:";
82 85
83 const char kPartObjectContainsGCRootNote[] = 86 const char kPartObjectContainsGCRootNote[] =
(...skipping 760 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 // - An on-heap class must never contain GC roots. 847 // - An on-heap class must never contain GC roots.
845 // - Only stack-allocated types may point to stack-allocated types. 848 // - Only stack-allocated types may point to stack-allocated types.
846 class CheckFieldsVisitor : public RecursiveEdgeVisitor { 849 class CheckFieldsVisitor : public RecursiveEdgeVisitor {
847 public: 850 public:
848 851
849 enum Error { 852 enum Error {
850 kRawPtrToGCManaged, 853 kRawPtrToGCManaged,
851 kRawPtrToGCManagedWarning, 854 kRawPtrToGCManagedWarning,
852 kRefPtrToGCManaged, 855 kRefPtrToGCManaged,
853 kOwnPtrToGCManaged, 856 kOwnPtrToGCManaged,
857 kMemberToGCUnmanaged,
854 kMemberInUnmanaged, 858 kMemberInUnmanaged,
855 kPtrFromHeapToStack, 859 kPtrFromHeapToStack,
856 kGCDerivedPartObject 860 kGCDerivedPartObject
857 }; 861 };
858 862
859 typedef std::vector<std::pair<FieldPoint*, Error> > Errors; 863 typedef std::vector<std::pair<FieldPoint*, Error> > Errors;
860 864
861 CheckFieldsVisitor(const BlinkGCPluginOptions& options) 865 CheckFieldsVisitor(const BlinkGCPluginOptions& options)
862 : options_(options), current_(0), stack_allocated_host_(false) {} 866 : options_(options), current_(0), stack_allocated_host_(false) {}
863 867
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 return; 906 return;
903 } 907 }
904 908
905 if (!Parent() && 909 if (!Parent() &&
906 edge->value()->IsGCDerived() && 910 edge->value()->IsGCDerived() &&
907 !edge->value()->IsGCMixin()) { 911 !edge->value()->IsGCMixin()) {
908 invalid_fields_.push_back(std::make_pair(current_, kGCDerivedPartObject)); 912 invalid_fields_.push_back(std::make_pair(current_, kGCDerivedPartObject));
909 return; 913 return;
910 } 914 }
911 915
916 // If in a stack allocated context, be fairly insistent that T in Member<T>
917 // is GC allocated, as stack allocated objects do not have a trace()
918 // that separately verifies the validity of Member<T>.
919 //
920 // Notice that an error is only reported if T's definition is in scope;
921 // we do not require that it must be brought into scope as that would
922 // prevent declarations of mutually dependent class types.
923 //
924 // (Note: Member<>'s constructor will at run-time verify that the
925 // pointer it wraps is indeed heap allocated.)
926 if (stack_allocated_host_ && Parent() && Parent()->IsMember() &&
927 edge->value()->HasDefinition() && !edge->value()->IsGCAllocated()) {
928 invalid_fields_.push_back(std::make_pair(current_,
929 kMemberToGCUnmanaged));
930 return;
931 }
932
912 if (!Parent() || !edge->value()->IsGCAllocated()) 933 if (!Parent() || !edge->value()->IsGCAllocated())
913 return; 934 return;
914 935
915 // In transition mode, disallow OwnPtr<T>, RawPtr<T> to GC allocated T's, 936 // In transition mode, disallow OwnPtr<T>, RawPtr<T> to GC allocated T's,
916 // also disallow T* in stack-allocated types. 937 // also disallow T* in stack-allocated types.
917 if (options_.enable_oilpan) { 938 if (options_.enable_oilpan) {
918 if (Parent()->IsOwnPtr() || 939 if (Parent()->IsOwnPtr() ||
919 Parent()->IsRawPtrClass() || 940 Parent()->IsRawPtrClass() ||
920 (stack_allocated_host_ && Parent()->IsRawPtr())) { 941 (stack_allocated_host_ && Parent()->IsRawPtr())) {
921 invalid_fields_.push_back(std::make_pair( 942 invalid_fields_.push_back(std::make_pair(
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1052 diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID( 1073 diag_base_requires_tracing_note_ = diagnostic_.getCustomDiagID(
1053 DiagnosticsEngine::Note, kBaseRequiresTracingNote); 1074 DiagnosticsEngine::Note, kBaseRequiresTracingNote);
1054 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID( 1075 diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID(
1055 DiagnosticsEngine::Note, kFieldRequiresTracingNote); 1076 DiagnosticsEngine::Note, kFieldRequiresTracingNote);
1056 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( 1077 diag_raw_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
1057 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote); 1078 DiagnosticsEngine::Note, kRawPtrToGCManagedClassNote);
1058 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( 1079 diag_ref_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
1059 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote); 1080 DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote);
1060 diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID( 1081 diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
1061 DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote); 1082 DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote);
1083 diag_member_to_gc_unmanaged_class_note_ = diagnostic_.getCustomDiagID(
1084 DiagnosticsEngine::Note, kMemberToGCUnmanagedClassNote);
1062 diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID( 1085 diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID(
1063 DiagnosticsEngine::Note, kStackAllocatedFieldNote); 1086 DiagnosticsEngine::Note, kStackAllocatedFieldNote);
1064 diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID( 1087 diag_member_in_unmanaged_class_note_ = diagnostic_.getCustomDiagID(
1065 DiagnosticsEngine::Note, kMemberInUnmanagedClassNote); 1088 DiagnosticsEngine::Note, kMemberInUnmanagedClassNote);
1066 diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID( 1089 diag_part_object_to_gc_derived_class_note_ = diagnostic_.getCustomDiagID(
1067 DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote); 1090 DiagnosticsEngine::Note, kPartObjectToGCDerivedClassNote);
1068 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID( 1091 diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID(
1069 DiagnosticsEngine::Note, kPartObjectContainsGCRootNote); 1092 DiagnosticsEngine::Note, kPartObjectContainsGCRootNote);
1070 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID( 1093 diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID(
1071 DiagnosticsEngine::Note, kFieldContainsGCRootNote); 1094 DiagnosticsEngine::Note, kFieldContainsGCRootNote);
(...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after
1825 it != errors->end(); 1848 it != errors->end();
1826 ++it) { 1849 ++it) {
1827 unsigned error; 1850 unsigned error;
1828 if (it->second == CheckFieldsVisitor::kRawPtrToGCManaged || 1851 if (it->second == CheckFieldsVisitor::kRawPtrToGCManaged ||
1829 it->second == CheckFieldsVisitor::kRawPtrToGCManagedWarning) { 1852 it->second == CheckFieldsVisitor::kRawPtrToGCManagedWarning) {
1830 error = diag_raw_ptr_to_gc_managed_class_note_; 1853 error = diag_raw_ptr_to_gc_managed_class_note_;
1831 } else if (it->second == CheckFieldsVisitor::kRefPtrToGCManaged) { 1854 } else if (it->second == CheckFieldsVisitor::kRefPtrToGCManaged) {
1832 error = diag_ref_ptr_to_gc_managed_class_note_; 1855 error = diag_ref_ptr_to_gc_managed_class_note_;
1833 } else if (it->second == CheckFieldsVisitor::kOwnPtrToGCManaged) { 1856 } else if (it->second == CheckFieldsVisitor::kOwnPtrToGCManaged) {
1834 error = diag_own_ptr_to_gc_managed_class_note_; 1857 error = diag_own_ptr_to_gc_managed_class_note_;
1858 } else if (it->second == CheckFieldsVisitor::kMemberToGCUnmanaged) {
1859 error = diag_member_to_gc_unmanaged_class_note_;
1835 } else if (it->second == CheckFieldsVisitor::kMemberInUnmanaged) { 1860 } else if (it->second == CheckFieldsVisitor::kMemberInUnmanaged) {
1836 error = diag_member_in_unmanaged_class_note_; 1861 error = diag_member_in_unmanaged_class_note_;
1837 } else if (it->second == CheckFieldsVisitor::kPtrFromHeapToStack) { 1862 } else if (it->second == CheckFieldsVisitor::kPtrFromHeapToStack) {
1838 error = diag_stack_allocated_field_note_; 1863 error = diag_stack_allocated_field_note_;
1839 } else if (it->second == CheckFieldsVisitor::kGCDerivedPartObject) { 1864 } else if (it->second == CheckFieldsVisitor::kGCDerivedPartObject) {
1840 error = diag_part_object_to_gc_derived_class_note_; 1865 error = diag_part_object_to_gc_derived_class_note_;
1841 } else { 1866 } else {
1842 assert(false && "Unknown field error"); 1867 assert(false && "Unknown field error");
1843 } 1868 }
1844 NoteField(it->first, error); 1869 NoteField(it->first, error);
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
2101 unsigned diag_missing_finalize_dispatch_; 2126 unsigned diag_missing_finalize_dispatch_;
2102 unsigned diag_derives_non_stack_allocated_; 2127 unsigned diag_derives_non_stack_allocated_;
2103 unsigned diag_class_overrides_new_; 2128 unsigned diag_class_overrides_new_;
2104 unsigned diag_class_declares_pure_virtual_trace_; 2129 unsigned diag_class_declares_pure_virtual_trace_;
2105 unsigned diag_left_most_base_must_be_polymorphic_; 2130 unsigned diag_left_most_base_must_be_polymorphic_;
2106 unsigned diag_base_class_must_declare_virtual_trace_; 2131 unsigned diag_base_class_must_declare_virtual_trace_;
2107 unsigned diag_class_must_declare_gc_mixin_trace_method_; 2132 unsigned diag_class_must_declare_gc_mixin_trace_method_;
2108 2133
2109 unsigned diag_base_requires_tracing_note_; 2134 unsigned diag_base_requires_tracing_note_;
2110 unsigned diag_field_requires_tracing_note_; 2135 unsigned diag_field_requires_tracing_note_;
2111 unsigned diag_field_illegally_traced_note_;
2112 unsigned diag_raw_ptr_to_gc_managed_class_note_; 2136 unsigned diag_raw_ptr_to_gc_managed_class_note_;
2113 unsigned diag_ref_ptr_to_gc_managed_class_note_; 2137 unsigned diag_ref_ptr_to_gc_managed_class_note_;
2114 unsigned diag_own_ptr_to_gc_managed_class_note_; 2138 unsigned diag_own_ptr_to_gc_managed_class_note_;
2139 unsigned diag_member_to_gc_unmanaged_class_note_;
2115 unsigned diag_stack_allocated_field_note_; 2140 unsigned diag_stack_allocated_field_note_;
2116 unsigned diag_member_in_unmanaged_class_note_; 2141 unsigned diag_member_in_unmanaged_class_note_;
2117 unsigned diag_part_object_to_gc_derived_class_note_; 2142 unsigned diag_part_object_to_gc_derived_class_note_;
2118 unsigned diag_part_object_contains_gc_root_note_; 2143 unsigned diag_part_object_contains_gc_root_note_;
2119 unsigned diag_field_contains_gc_root_note_; 2144 unsigned diag_field_contains_gc_root_note_;
2120 unsigned diag_finalized_field_note_; 2145 unsigned diag_finalized_field_note_;
2121 unsigned diag_eagerly_finalized_field_note_; 2146 unsigned diag_eagerly_finalized_field_note_;
2122 unsigned diag_user_declared_destructor_note_; 2147 unsigned diag_user_declared_destructor_note_;
2123 unsigned diag_user_declared_finalizer_note_; 2148 unsigned diag_user_declared_finalizer_note_;
2124 unsigned diag_base_requires_finalization_note_; 2149 unsigned diag_base_requires_finalization_note_;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2169 2194
2170 private: 2195 private:
2171 BlinkGCPluginOptions options_; 2196 BlinkGCPluginOptions options_;
2172 }; 2197 };
2173 2198
2174 } // namespace 2199 } // namespace
2175 2200
2176 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( 2201 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X(
2177 "blink-gc-plugin", 2202 "blink-gc-plugin",
2178 "Check Blink GC invariants"); 2203 "Check Blink GC invariants");
OLDNEW
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/RecordInfo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698