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

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

Issue 1385193002: Bisect clang Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 246985 Created 5 years, 2 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "CheckFieldsVisitor.h"
6
7 #include <cassert>
8
9 #include "BlinkGCPluginOptions.h"
10 #include "RecordInfo.h"
11
12 CheckFieldsVisitor::CheckFieldsVisitor(const BlinkGCPluginOptions& options)
13 : options_(options),
14 current_(0),
15 stack_allocated_host_(false) {
16 }
17
18 CheckFieldsVisitor::Errors& CheckFieldsVisitor::invalid_fields() {
19 return invalid_fields_;
20 }
21
22 bool CheckFieldsVisitor::ContainsInvalidFields(RecordInfo* info) {
23 stack_allocated_host_ = info->IsStackAllocated();
24 managed_host_ = stack_allocated_host_ ||
25 info->IsGCAllocated() ||
26 info->IsNonNewable() ||
27 info->IsOnlyPlacementNewable();
28 for (RecordInfo::Fields::iterator it = info->GetFields().begin();
29 it != info->GetFields().end();
30 ++it) {
31 context().clear();
32 current_ = &it->second;
33 current_->edge()->Accept(this);
34 }
35 return !invalid_fields_.empty();
36 }
37
38 void CheckFieldsVisitor::AtMember(Member* edge) {
39 if (managed_host_)
40 return;
41 // A member is allowed to appear in the context of a root.
42 for (Context::iterator it = context().begin();
43 it != context().end();
44 ++it) {
45 if ((*it)->Kind() == Edge::kRoot)
46 return;
47 }
48 invalid_fields_.push_back(std::make_pair(current_, kMemberInUnmanaged));
49 }
50
51 void CheckFieldsVisitor::AtValue(Value* edge) {
52 // TODO: what should we do to check unions?
53 if (edge->value()->record()->isUnion())
54 return;
55
56 if (!stack_allocated_host_ && edge->value()->IsStackAllocated()) {
57 invalid_fields_.push_back(std::make_pair(current_, kPtrFromHeapToStack));
58 return;
59 }
60
61 if (!Parent() &&
62 edge->value()->IsGCDerived() &&
63 !edge->value()->IsGCMixin()) {
64 invalid_fields_.push_back(std::make_pair(current_, kGCDerivedPartObject));
65 return;
66 }
67
68 // If in a stack allocated context, be fairly insistent that T in Member<T>
69 // is GC allocated, as stack allocated objects do not have a trace()
70 // that separately verifies the validity of Member<T>.
71 //
72 // Notice that an error is only reported if T's definition is in scope;
73 // we do not require that it must be brought into scope as that would
74 // prevent declarations of mutually dependent class types.
75 //
76 // (Note: Member<>'s constructor will at run-time verify that the
77 // pointer it wraps is indeed heap allocated.)
78 if (stack_allocated_host_ && Parent() && Parent()->IsMember() &&
79 edge->value()->HasDefinition() && !edge->value()->IsGCAllocated()) {
80 invalid_fields_.push_back(std::make_pair(current_,
81 kMemberToGCUnmanaged));
82 return;
83 }
84
85 if (!Parent() || !edge->value()->IsGCAllocated())
86 return;
87
88 // In transition mode, disallow OwnPtr<T>, RawPtr<T> to GC allocated T's,
89 // also disallow T* in stack-allocated types.
90 if (options_.enable_oilpan) {
91 if (Parent()->IsOwnPtr() ||
92 Parent()->IsRawPtrClass() ||
93 (stack_allocated_host_ && Parent()->IsRawPtr())) {
94 invalid_fields_.push_back(std::make_pair(
95 current_, InvalidSmartPtr(Parent())));
96 return;
97 }
98 if (options_.warn_raw_ptr && Parent()->IsRawPtr()) {
99 if (static_cast<RawPtr*>(Parent())->HasReferenceType()) {
100 invalid_fields_.push_back(std::make_pair(
101 current_, kReferencePtrToGCManagedWarning));
102 } else {
103 invalid_fields_.push_back(std::make_pair(
104 current_, kRawPtrToGCManagedWarning));
105 }
106 }
107 return;
108 }
109
110 if (Parent()->IsRawPtr() || Parent()->IsRefPtr() || Parent()->IsOwnPtr()) {
111 invalid_fields_.push_back(std::make_pair(
112 current_, InvalidSmartPtr(Parent())));
113 return;
114 }
115 }
116
117 void CheckFieldsVisitor::AtCollection(Collection* edge) {
118 if (edge->on_heap() && Parent() && Parent()->IsOwnPtr())
119 invalid_fields_.push_back(std::make_pair(current_, kOwnPtrToGCManaged));
120 }
121
122 bool CheckFieldsVisitor::IsWarning(Error error) {
123 if (error == kRawPtrToGCManagedWarning)
124 return true;
125 if (error == kReferencePtrToGCManagedWarning)
126 return true;
127 return false;
128 }
129
130 bool CheckFieldsVisitor::IsRawPtrError(Error error) {
131 return (error == kRawPtrToGCManaged ||
132 error == kRawPtrToGCManagedWarning);
133 }
134
135 bool CheckFieldsVisitor::IsReferencePtrError(Error error) {
136 return (error == kReferencePtrToGCManaged ||
137 error == kReferencePtrToGCManagedWarning);
138 }
139
140 CheckFieldsVisitor::Error CheckFieldsVisitor::InvalidSmartPtr(Edge* ptr) {
141 if (ptr->IsRawPtr()) {
142 if (static_cast<RawPtr*>(ptr)->HasReferenceType())
143 return kReferencePtrToGCManaged;
144 else
145 return kRawPtrToGCManaged;
146 }
147 if (ptr->IsRefPtr())
148 return kRefPtrToGCManaged;
149 if (ptr->IsOwnPtr())
150 return kOwnPtrToGCManaged;
151 assert(false && "Unknown smart pointer kind");
152 }
OLDNEW
« no previous file with comments | « tools/clang/blink_gc_plugin/CheckFieldsVisitor.h ('k') | tools/clang/blink_gc_plugin/CheckFinalizerVisitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698