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

Unified Diff: tools/clang/blink_gc_plugin/CheckFinalizerVisitor.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 side-by-side diff with in-line comments
Download patch
Index: tools/clang/blink_gc_plugin/CheckFinalizerVisitor.cpp
diff --git a/tools/clang/blink_gc_plugin/CheckFinalizerVisitor.cpp b/tools/clang/blink_gc_plugin/CheckFinalizerVisitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f0a9bf3dba0a15198331c5a862c8fcfefceed212
--- /dev/null
+++ b/tools/clang/blink_gc_plugin/CheckFinalizerVisitor.cpp
@@ -0,0 +1,133 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "CheckFinalizerVisitor.h"
+
+using namespace clang;
+
+namespace {
+
+// Simple visitor to determine if the content of a field might be collected
+// during finalization.
+class MightBeCollectedVisitor : public EdgeVisitor {
+ public:
+ explicit MightBeCollectedVisitor(bool is_eagerly_finalized);
+
+ bool might_be_collected() const;
+ bool as_eagerly_finalized() const;
+
+ void VisitMember(Member* edge) override;
+ void VisitCollection(Collection* edge) override;
+
+ private:
+ bool might_be_collected_;
+ bool is_eagerly_finalized_;
+ bool as_eagerly_finalized_;
+};
+
+MightBeCollectedVisitor::MightBeCollectedVisitor(bool is_eagerly_finalized)
+ : might_be_collected_(false),
+ is_eagerly_finalized_(is_eagerly_finalized),
+ as_eagerly_finalized_(false) {
+}
+
+bool MightBeCollectedVisitor::might_be_collected() const {
+ return might_be_collected_;
+}
+
+bool MightBeCollectedVisitor::as_eagerly_finalized() const {
+ return as_eagerly_finalized_;
+}
+
+void MightBeCollectedVisitor::VisitMember(Member* edge) {
+ 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 MightBeCollectedVisitor::VisitCollection(Collection* edge) {
+ if (edge->on_heap() && !is_eagerly_finalized_) {
+ might_be_collected_ = !edge->is_root();
+ } else {
+ edge->AcceptMembers(this);
+ }
+}
+
+} // namespace
+
+CheckFinalizerVisitor::CheckFinalizerVisitor(RecordCache* cache,
+ bool is_eagerly_finalized)
+ : blacklist_context_(false),
+ cache_(cache),
+ is_eagerly_finalized_(is_eagerly_finalized) {
+}
+
+CheckFinalizerVisitor::Errors& CheckFinalizerVisitor::finalized_fields() {
+ return finalized_fields_;
+}
+
+bool CheckFinalizerVisitor::WalkUpFromCXXOperatorCallExpr(
+ CXXOperatorCallExpr* expr) {
+ // Only continue the walk-up if the operator is a blacklisted one.
+ switch (expr->getOperator()) {
+ case OO_Arrow:
+ case OO_Subscript:
+ this->WalkUpFromCallExpr(expr);
+ return true;
+ default:
+ return true;
+ }
+}
+
+bool CheckFinalizerVisitor::WalkUpFromCallExpr(CallExpr* expr) {
+ // We consider all non-operator calls to be blacklisted contexts.
+ bool prev_blacklist_context = blacklist_context_;
+ blacklist_context_ = true;
+ for (size_t i = 0; i < expr->getNumArgs(); ++i)
+ this->TraverseStmt(expr->getArg(i));
+ blacklist_context_ = prev_blacklist_context;
+ return true;
+}
+
+bool CheckFinalizerVisitor::VisitMemberExpr(MemberExpr* member) {
+ FieldDecl* field = dyn_cast<FieldDecl>(member->getMemberDecl());
+ if (!field)
+ return true;
+
+ RecordInfo* info = cache_->Lookup(field->getParent());
+ if (!info)
+ return true;
+
+ RecordInfo::Fields::iterator it = info->GetFields().find(field);
+ if (it == info->GetFields().end())
+ return true;
+
+ 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 CheckFinalizerVisitor::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();
+}
« no previous file with comments | « tools/clang/blink_gc_plugin/CheckFinalizerVisitor.h ('k') | tools/clang/blink_gc_plugin/CheckGCRootsVisitor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698