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

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

Issue 1158623002: Extend destructor checks to account for eagerly finalized class types. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: updated to look for IsEagerlyFinalizedMarker instead Created 5 years, 7 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/Config.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 a6f32c73ce70b63548dc379ede77c72218e41830..f8a7a84d801d248cf0f377b1a1fe297c77b3b401 100644
--- a/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
+++ b/tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp
@@ -59,6 +59,9 @@ const char kClassDoesNotRequireFinalization[] =
const char kFinalizerAccessesFinalizedField[] =
"[blink-gc] Finalizer %0 accesses potentially finalized field %1.";
+const char kFinalizerAccessesEagerlyFinalizedField[] =
+ "[blink-gc] Finalizer %0 accesses eagerly finalized field %1.";
+
const char kRawPtrToGCManagedClassNote[] =
"[blink-gc] Raw pointer field %0 to a GC managed class declared here:";
@@ -108,6 +111,9 @@ const char kMissingFinalizeDispatch[] =
const char kFinalizedFieldNote[] =
"[blink-gc] Potentially finalized field %0 declared here:";
+const char kEagerlyFinalizedFieldNote[] =
+ "[blink-gc] Field %0 having eagerly finalized value, declared here:";
+
const char kUserDeclaredDestructorNote[] =
"[blink-gc] User-declared destructor declared here:";
@@ -243,11 +249,27 @@ class CheckFinalizerVisitor
// during finalization.
class MightBeCollectedVisitor : public EdgeVisitor {
public:
- MightBeCollectedVisitor() : might_be_collected_(false) {}
+ MightBeCollectedVisitor(bool is_eagerly_finalized)
+ : might_be_collected_(false)
+ , is_eagerly_finalized_(is_eagerly_finalized)
+ , as_eagerly_finalized_(false) {}
bool might_be_collected() { return might_be_collected_; }
- void VisitMember(Member* edge) override { might_be_collected_ = true; }
+ bool as_eagerly_finalized() { return as_eagerly_finalized_; }
+ void VisitMember(Member* edge) override {
+ if (is_eagerly_finalized_) {
+ if (edge->ptr()->IsValue()) {
+ Value* member = static_cast<Value*>(edge->ptr());
+ if (member->value()->IsEagerlyFinalized()) {
+ might_be_collected_ = true;
+ as_eagerly_finalized_ = true;
+ }
+ }
+ return;
+ }
+ might_be_collected_ = true;
+ }
void VisitCollection(Collection* edge) override {
- if (edge->on_heap()) {
+ if (edge->on_heap() && !is_eagerly_finalized_) {
might_be_collected_ = !edge->is_root();
} else {
edge->AcceptMembers(this);
@@ -256,13 +278,31 @@ class CheckFinalizerVisitor
private:
bool might_be_collected_;
+ bool is_eagerly_finalized_;
+ bool as_eagerly_finalized_;
};
public:
- typedef std::vector<std::pair<MemberExpr*, FieldPoint*> > Errors;
+ class Error {
+ public:
+ Error(MemberExpr *member,
+ bool as_eagerly_finalized,
+ FieldPoint* field)
+ : member_(member)
+ , as_eagerly_finalized_(as_eagerly_finalized)
+ , field_(field) {}
- CheckFinalizerVisitor(RecordCache* cache)
- : blacklist_context_(false), cache_(cache) {}
+ MemberExpr* member_;
+ bool as_eagerly_finalized_;
+ FieldPoint* field_;
+ };
+
+ typedef std::vector<Error> Errors;
+
+ CheckFinalizerVisitor(RecordCache* cache, bool is_eagerly_finalized)
+ : blacklist_context_(false)
+ , cache_(cache)
+ , is_eagerly_finalized_(is_eagerly_finalized) {}
Errors& finalized_fields() { return finalized_fields_; }
@@ -300,21 +340,32 @@ class CheckFinalizerVisitor
if (it == info->GetFields().end())
return true;
- if (blacklist_context_ && MightBeCollected(&it->second))
- finalized_fields_.push_back(std::make_pair(member, &it->second));
+ if (seen_members_.find(member) != seen_members_.end())
+ return true;
+
+ bool as_eagerly_finalized = false;
+ if (blacklist_context_ &&
+ MightBeCollected(&it->second, as_eagerly_finalized)) {
+ finalized_fields_.push_back(
+ Error(member, as_eagerly_finalized, &it->second));
+ seen_members_.insert(member);
+ }
return true;
}
- bool MightBeCollected(FieldPoint* point) {
- MightBeCollectedVisitor visitor;
+ bool MightBeCollected(FieldPoint* point, bool& as_eagerly_finalized) {
+ MightBeCollectedVisitor visitor(is_eagerly_finalized_);
point->edge()->Accept(&visitor);
+ as_eagerly_finalized = visitor.as_eagerly_finalized();
return visitor.might_be_collected();
}
private:
bool blacklist_context_;
Errors finalized_fields_;
+ std::set<MemberExpr*> seen_members_;
RecordCache* cache_;
+ bool is_eagerly_finalized_;
};
// This visitor checks that a method contains within its body, a call to a
@@ -969,6 +1020,8 @@ class BlinkGCPluginConsumer : public ASTConsumer {
DiagnosticsEngine::Warning, kClassDoesNotRequireFinalization);
diag_finalizer_accesses_finalized_field_ = diagnostic_.getCustomDiagID(
getErrorLevel(), kFinalizerAccessesFinalizedField);
+ diag_finalizer_eagerly_finalized_field_ = diagnostic_.getCustomDiagID(
+ getErrorLevel(), kFinalizerAccessesEagerlyFinalizedField);
diag_overridden_non_virtual_trace_ = diagnostic_.getCustomDiagID(
getErrorLevel(), kOverriddenNonVirtualTrace);
diag_missing_trace_dispatch_method_ = diagnostic_.getCustomDiagID(
@@ -1018,6 +1071,8 @@ class BlinkGCPluginConsumer : public ASTConsumer {
DiagnosticsEngine::Note, kFieldContainsGCRootNote);
diag_finalized_field_note_ = diagnostic_.getCustomDiagID(
DiagnosticsEngine::Note, kFinalizedFieldNote);
+ diag_eagerly_finalized_field_note_ = diagnostic_.getCustomDiagID(
+ DiagnosticsEngine::Note, kEagerlyFinalizedFieldNote);
diag_user_declared_destructor_note_ = diagnostic_.getCustomDiagID(
DiagnosticsEngine::Note, kUserDeclaredDestructorNote);
diag_user_declared_finalizer_note_ = diagnostic_.getCustomDiagID(
@@ -1387,7 +1442,7 @@ class BlinkGCPluginConsumer : public ASTConsumer {
// For finalized classes, check the finalization method if possible.
if (info->IsGCFinalized()) {
if (dtor && dtor->hasBody()) {
- CheckFinalizerVisitor visitor(&cache_);
+ CheckFinalizerVisitor visitor(&cache_, info->IsEagerlyFinalized());
visitor.TraverseCXXMethodDecl(dtor);
if (!visitor.finalized_fields().empty()) {
ReportFinalizerAccessesFinalizedFields(
@@ -1816,12 +1871,19 @@ class BlinkGCPluginConsumer : public ASTConsumer {
for (CheckFinalizerVisitor::Errors::iterator it = fields->begin();
it != fields->end();
++it) {
- SourceLocation loc = it->first->getLocStart();
+ SourceLocation loc = it->member_->getLocStart();
SourceManager& manager = instance_.getSourceManager();
+ bool as_eagerly_finalized = it->as_eagerly_finalized_;
+ unsigned diag_error = as_eagerly_finalized ?
+ diag_finalizer_eagerly_finalized_field_ :
+ diag_finalizer_accesses_finalized_field_;
+ unsigned diag_note = as_eagerly_finalized ?
+ diag_eagerly_finalized_field_note_ :
+ diag_finalized_field_note_;
FullSourceLoc full_loc(loc, manager);
- diagnostic_.Report(full_loc, diag_finalizer_accesses_finalized_field_)
- << dtor << it->second->field();
- NoteField(it->second, diag_finalized_field_note_);
+ diagnostic_.Report(full_loc, diag_error)
+ << dtor << it->field_->field();
+ NoteField(it->field_, diag_note);
}
}
@@ -2030,6 +2092,7 @@ class BlinkGCPluginConsumer : public ASTConsumer {
unsigned diag_class_requires_finalization_;
unsigned diag_class_does_not_require_finalization_;
unsigned diag_finalizer_accesses_finalized_field_;
+ unsigned diag_finalizer_eagerly_finalized_field_;
unsigned diag_overridden_non_virtual_trace_;
unsigned diag_missing_trace_dispatch_method_;
unsigned diag_missing_finalize_dispatch_method_;
@@ -2045,6 +2108,7 @@ class BlinkGCPluginConsumer : public ASTConsumer {
unsigned diag_base_requires_tracing_note_;
unsigned diag_field_requires_tracing_note_;
+ unsigned diag_field_illegally_traced_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_;
@@ -2054,6 +2118,7 @@ class BlinkGCPluginConsumer : public ASTConsumer {
unsigned diag_part_object_contains_gc_root_note_;
unsigned diag_field_contains_gc_root_note_;
unsigned diag_finalized_field_note_;
+ unsigned diag_eagerly_finalized_field_note_;
unsigned diag_user_declared_destructor_note_;
unsigned diag_user_declared_finalizer_note_;
unsigned diag_base_requires_finalization_note_;
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/Config.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698