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

Unified Diff: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp

Issue 206123004: Add checks for stack-allocated types and their uses in fields. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 6 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/RecordInfo.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
diff --git a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
index bc6674a28a8ab35602561aec91846b4821065065..89f0bd419bb94037deb240e7fb10e41ca09637a4 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
+++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
@@ -56,6 +56,9 @@ const char kRefPtrToGCManagedClassNote[] =
const char kOwnPtrToGCManagedClassNote[] =
"[blink-gc] OwnPtr field %0 to a GC managed class declared here:";
+const char kStackAllocatedFieldNote[] =
+ "[blink-gc] Stack-allocated field %0 declared here:";
+
const char kPartObjectContainsGCRoot[] =
"[blink-gc] Field %0 with embedded GC root in %1 declared here:";
@@ -102,6 +105,10 @@ const char kFieldRequiresFinalizationNote[] =
const char kManualDispatchMethodNote[] =
"[blink-gc] Manual dispatch %0 declared here:";
+const char kDerivesNonStackAllocated[] =
+ "[blink-gc] Stack-allocated class %0 derives class %1"
+ " which is not stack allocated.";
+
struct BlinkGCPluginOptions {
BlinkGCPluginOptions() : enable_oilpan(false) {}
bool enable_oilpan;
@@ -424,11 +431,12 @@ class CheckFieldsVisitor : public RecursiveEdgeVisitor {
typedef std::vector<std::pair<FieldPoint*, Edge*> > Errors;
CheckFieldsVisitor(const BlinkGCPluginOptions& options)
- : options_(options), current_(0) {}
+ : options_(options), current_(0), stack_allocated_host_(false) {}
Errors& invalid_fields() { return invalid_fields_; }
bool ContainsInvalidFields(RecordInfo* info) {
+ stack_allocated_host_ = info->IsStackAllocated();
for (RecordInfo::Fields::iterator it = info->GetFields().begin();
it != info->GetFields().end();
++it) {
@@ -444,6 +452,9 @@ class CheckFieldsVisitor : public RecursiveEdgeVisitor {
if (edge->value()->record()->isUnion())
return;
+ if (!stack_allocated_host_ && edge->value()->IsStackAllocated())
+ invalid_fields_.push_back(std::make_pair(current_, edge));
+
if (!Parent() || !edge->value()->IsGCAllocated())
return;
@@ -454,13 +465,15 @@ class CheckFieldsVisitor : public RecursiveEdgeVisitor {
if (options_.enable_oilpan)
return;
- if (Parent()->IsRawPtr() || Parent()->IsRefPtr())
+ if ((!stack_allocated_host_ && Parent()->IsRawPtr()) ||
+ Parent()->IsRefPtr())
invalid_fields_.push_back(std::make_pair(current_, Parent()));
}
private:
const BlinkGCPluginOptions& options_;
FieldPoint* current_;
+ bool stack_allocated_host_;
Errors invalid_fields_;
};
@@ -510,6 +523,8 @@ class BlinkGCPluginConsumer : public ASTConsumer {
getErrorLevel(), kMissingTraceDispatch);
diag_missing_finalize_dispatch_ = diagnostic_.getCustomDiagID(
getErrorLevel(), kMissingFinalizeDispatch);
+ diag_derives_non_stack_allocated_ = diagnostic_.getCustomDiagID(
+ getErrorLevel(), kDerivesNonStackAllocated);
// Register note messages.
diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID(
@@ -520,6 +535,8 @@ class BlinkGCPluginConsumer : public ASTConsumer {
DiagnosticsEngine::Note, kRefPtrToGCManagedClassNote);
diag_own_ptr_to_gc_managed_class_note_ = diagnostic_.getCustomDiagID(
DiagnosticsEngine::Note, kOwnPtrToGCManagedClassNote);
+ diag_stack_allocated_field_note_ = diagnostic_.getCustomDiagID(
+ DiagnosticsEngine::Note, kStackAllocatedFieldNote);
diag_part_object_contains_gc_root_note_ = diagnostic_.getCustomDiagID(
DiagnosticsEngine::Note, kPartObjectContainsGCRoot);
diag_field_contains_gc_root_note_ = diagnostic_.getCustomDiagID(
@@ -585,10 +602,19 @@ class BlinkGCPluginConsumer : public ASTConsumer {
// Check a class-like object (eg, class, specialization, instantiation).
void CheckClass(RecordInfo* info) {
- // Don't enforce tracing of stack allocated objects.
- if (!info || info->IsStackAllocated())
+ if (!info)
return;
+ // Check consistency of stack-allocated hierarchies.
+ if (info->IsStackAllocated()) {
+ for (RecordInfo::Bases::iterator it = info->GetBases().begin();
+ it != info->GetBases().end();
+ ++it) {
+ if (!it->second.info()->IsStackAllocated())
+ ReportDerivesNonStackAllocated(info, &it->second);
+ }
+ }
+
if (info->RequiresTraceMethod() && !info->GetTraceMethod())
ReportClassRequiresTraceMethod(info);
@@ -894,6 +920,8 @@ class BlinkGCPluginConsumer : public ASTConsumer {
NoteField(it->first, diag_ref_ptr_to_gc_managed_class_note_);
} else if (it->second->IsOwnPtr()) {
NoteField(it->first, diag_own_ptr_to_gc_managed_class_note_);
+ } else if (it->second->IsValue()) {
+ NoteField(it->first, diag_stack_allocated_field_note_);
}
}
}
@@ -997,6 +1025,14 @@ class BlinkGCPluginConsumer : public ASTConsumer {
diagnostic_.Report(full_loc, error) << receiver->record();
}
+ void ReportDerivesNonStackAllocated(RecordInfo* info, BasePoint* base) {
+ SourceLocation loc = base->spec().getLocStart();
+ SourceManager& manager = instance_.getSourceManager();
+ FullSourceLoc full_loc(loc, manager);
+ diagnostic_.Report(full_loc, diag_derives_non_stack_allocated_)
+ << info->record() << base->info()->record();
+ }
+
void NoteManualDispatchMethod(CXXMethodDecl* dispatch) {
SourceLocation loc = dispatch->getLocStart();
SourceManager& manager = instance_.getSourceManager();
@@ -1075,11 +1111,13 @@ class BlinkGCPluginConsumer : public ASTConsumer {
unsigned diag_virtual_and_manual_dispatch_;
unsigned diag_missing_trace_dispatch_;
unsigned diag_missing_finalize_dispatch_;
+ unsigned diag_derives_non_stack_allocated_;
unsigned diag_field_requires_tracing_note_;
unsigned diag_raw_ptr_to_gc_managed_class_note_;
unsigned diag_ref_ptr_to_gc_managed_class_note_;
unsigned diag_own_ptr_to_gc_managed_class_note_;
+ unsigned diag_stack_allocated_field_note_;
unsigned diag_part_object_contains_gc_root_note_;
unsigned diag_field_contains_gc_root_note_;
unsigned diag_finalized_field_note_;
« 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