Commit be83e30f authored by Keishi Hattori's avatar Keishi Hattori Committed by Commit Bot

blink_gc_plugin: Handle TraceIfNeeded for resolved T

TraceIfNeeded with a template T is already handled properly,
but TraceIfNeeded with a resolved T, like TraceIfNeeded<Member<Node>>
was not treated as a traced field.

Bug: 1044898
Change-Id: I9f394290d7cc3ec8ad8d7b1c0489b7044b757513
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2032751Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarAnton Bikineev <bikineev@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Commit-Queue: Keishi Hattori <keishi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#737674}
parent 2b4bec80
......@@ -43,6 +43,11 @@ bool CheckTraceVisitor::VisitCallExpr(CallExpr* call) {
return true;
}
if (ImplicitCastExpr* expr = dyn_cast<ImplicitCastExpr>(callee)) {
if (CheckImplicitCastExpr(call, expr))
return true;
}
// A tracing call will have either a |visitor| or a |m_field| argument.
// A registerWeakMembers call will have a |this| argument.
if (call->getNumArgs() != 1)
......@@ -70,7 +75,6 @@ bool CheckTraceVisitor::VisitCallExpr(CallExpr* call) {
if (CXXMemberCallExpr* expr = dyn_cast<CXXMemberCallExpr>(call)) {
if (CheckTraceFieldMemberCall(expr) || CheckRegisterWeakMembers(expr))
return true;
}
CheckTraceBaseCall(call);
......@@ -164,7 +168,8 @@ void CheckTraceVisitor::CheckCXXDependentScopeMemberExpr(
}
}
// Check for TraceIfNeeded<T>::trace(visitor, &field)
// Check for TraceIfNeeded<T>::trace(visitor, &field) where T cannot be
// resolved
if (call->getNumArgs() == 2 && fn_name == kTraceName &&
tmpl->getName() == kTraceIfNeededName) {
FindFieldVisitor finder;
......@@ -370,3 +375,28 @@ void CheckTraceVisitor::MarkAllWeakMembersTraced() {
field.second.MarkTraced();
}
}
bool CheckTraceVisitor::CheckImplicitCastExpr(CallExpr* call,
ImplicitCastExpr* expr) {
DeclRefExpr* sub_expr = dyn_cast<DeclRefExpr>(expr->getSubExpr());
if (!sub_expr)
return false;
NestedNameSpecifier* qualifier = sub_expr->getQualifier();
if (!qualifier)
return false;
CXXRecordDecl* class_decl = qualifier->getAsRecordDecl();
if (!class_decl)
return false;
NamedDecl* found_decl = sub_expr->getFoundDecl();
std::string fn_name = found_decl->getNameAsString();
// Check for TraceIfNeeded<T>::trace(visitor, &field) where T can be resolved
if (call->getNumArgs() == 2 && fn_name == kTraceName &&
class_decl->getName() == kTraceIfNeededName) {
FindFieldVisitor finder;
finder.TraverseStmt(call->getArg(1));
if (finder.field())
FoundField(finder.field());
return true;
}
return false;
}
......@@ -41,6 +41,8 @@ class CheckTraceVisitor : public clang::RecursiveASTVisitor<CheckTraceVisitor> {
clang::CXXRecordDecl* callee,
clang::Expr* arg);
bool CheckRegisterWeakMembers(clang::CXXMemberCallExpr* call);
bool CheckImplicitCastExpr(clang::CallExpr* call,
clang::ImplicitCastExpr* expr);
bool IsWeakCallback() const;
......
......@@ -305,7 +305,7 @@ public:
template<typename T>
struct TraceIfNeeded {
static void Trace(Visitor*, T*);
static void Trace(Visitor*, T&);
};
}
......
// Copyright 2020 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 "trace_if_needed_resolved.h"
namespace blink {
void HeapObject::Trace(Visitor* visitor) {
// Using TraceIfNeeded with a non-template type should count as tracing a
// field.
TraceIfNeeded<Member<HeapObject>>::Trace(visitor, m_one);
TraceIfNeeded<int>::Trace(visitor, m_two);
}
} // namespace blink
// Copyright 2020 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.
#ifndef TRACE_IF_NEEDED_RESOLVED_H_
#define TRACE_IF_NEEDED_RESOLVED_H_
#include "heap/stubs.h"
namespace blink {
class HeapObject : public GarbageCollected<HeapObject> {
public:
virtual void Trace(Visitor*);
private:
Member<HeapObject> m_one;
int m_two;
};
} // namespace blink
#endif
......@@ -68,6 +68,7 @@ class ClangPluginTest(object):
pass
cmd.append(test)
print("cmd", cmd)
failure_message = self.RunOneTest(test_name, cmd)
if failure_message:
print('failed: %s' % failure_message)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment