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

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: 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') | tools/clang/blink_gc_plugin/RecordInfo.cpp » ('J')
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 6603d6e6b804d31dc32ff4864621a53058fe0c1b..1c74e05056b5db448fee6041d9cab7384f189876 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:";
@@ -97,6 +100,14 @@ const char kBaseRequiresFinalizationNote[] =
const char kFieldRequiresFinalizationNote[] =
"[blink-gc] Field %0 requiring finalization declared here:";
+const char kDerivesNonStackAllocated[] =
+ "[blink-gc] Stack-allocated class %0 derives class %1"
+ " which is not stack allocated.";
+
+const char kDerivesStackAllocated[] =
+ "[blink-gc] Class %0 derives stack-allocated class %1"
+ " but is not itself stack allocated";
+
struct BlinkGCPluginOptions {
BlinkGCPluginOptions() : enable_oilpan(false) {}
bool enable_oilpan;
@@ -419,11 +430,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) {
@@ -439,6 +451,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;
@@ -449,13 +464,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_;
};
@@ -503,6 +520,10 @@ class BlinkGCPluginConsumer : public ASTConsumer {
getErrorLevel(), kMissingFinalize);
diag_missing_finalize_dispatch_ = diagnostic_.getCustomDiagID(
getErrorLevel(), kMissingFinalizeDispatch);
+ diag_derives_non_stack_allocated_ = diagnostic_.getCustomDiagID(
+ getErrorLevel(), kDerivesNonStackAllocated);
+ diag_derives_stack_allocated_ = diagnostic_.getCustomDiagID(
+ getErrorLevel(), kDerivesStackAllocated);
// Register note messages.
diag_field_requires_tracing_note_ = diagnostic_.getCustomDiagID(
@@ -513,6 +534,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(
@@ -574,10 +597,22 @@ 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.
+ bool stack_allocated = info->IsStackAllocated();
+ for (RecordInfo::Bases::iterator it = info->GetBases().begin();
+ it != info->GetBases().end();
+ ++it) {
+ bool stack_allocated_base = it->second.info()->IsStackAllocated();
+ if (stack_allocated && !stack_allocated_base)
+ ReportDerivesNonStackAllocated(info, &it->second);
+
+ if (!stack_allocated && stack_allocated_base)
+ ReportDerivesStackAllocated(info, &it->second);
+ }
+
if (info->RequiresTraceMethod() && !info->GetTraceMethod())
ReportClassRequiresTraceMethod(info);
@@ -880,6 +915,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_);
}
}
}
@@ -973,6 +1010,22 @@ 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 ReportDerivesStackAllocated(RecordInfo* info, BasePoint* base) {
+ SourceLocation loc = base->spec().getLocStart();
+ SourceManager& manager = instance_.getSourceManager();
+ FullSourceLoc full_loc(loc, manager);
+ diagnostic_.Report(full_loc, diag_derives_stack_allocated_)
+ << info->record() << base->info()->record();
+ }
+
void NoteFieldRequiresTracing(RecordInfo* holder, FieldDecl* field) {
NoteField(field, diag_field_requires_tracing_note_);
}
@@ -1036,11 +1089,14 @@ class BlinkGCPluginConsumer : public ASTConsumer {
unsigned diag_missing_trace_dispatch_;
unsigned diag_missing_finalize_;
unsigned diag_missing_finalize_dispatch_;
+ unsigned diag_derives_non_stack_allocated_;
+ unsigned diag_derives_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') | tools/clang/blink_gc_plugin/RecordInfo.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698