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

Side by Side Diff: tools/clang/blink_gc_plugin/BlinkGCPlugin.cpp

Issue 975683003: GCPlugin: Recognize templated registerWeakMembers() call. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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 unified diff | Download patch
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/tests/heap/stubs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This clang plugin checks various invariants of the Blink garbage 5 // This clang plugin checks various invariants of the Blink garbage
6 // collection infrastructure. 6 // collection infrastructure.
7 // 7 //
8 // Errors are described at: 8 // Errors are described at:
9 // http://www.chromium.org/developers/blink-gc-plugin-errors 9 // http://www.chromium.org/developers/blink-gc-plugin-errors
10 10
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 if (call->getNumArgs() != 1) 381 if (call->getNumArgs() != 1)
382 return true; 382 return true;
383 Expr* arg = call->getArg(0); 383 Expr* arg = call->getArg(0);
384 384
385 if (UnresolvedMemberExpr* expr = dyn_cast<UnresolvedMemberExpr>(callee)) { 385 if (UnresolvedMemberExpr* expr = dyn_cast<UnresolvedMemberExpr>(callee)) {
386 // This could be a trace call of a base class, as explained in the 386 // This could be a trace call of a base class, as explained in the
387 // comments of CheckTraceBaseCall(). 387 // comments of CheckTraceBaseCall().
388 if (CheckTraceBaseCall(call)) 388 if (CheckTraceBaseCall(call))
389 return true; 389 return true;
390 390
391 // If we find a call to registerWeakMembers which is unresolved we 391 if (expr->getMemberName().getAsString() == kRegisterWeakMembersName)
392 // unsoundly consider all weak members as traced. 392 MarkAllWeakMembersTraced();
393 // TODO: Find out how to validate weak member tracing for unresolved call.
394 if (expr->getMemberName().getAsString() == kRegisterWeakMembersName) {
395 for (RecordInfo::Fields::iterator it = info_->GetFields().begin();
396 it != info_->GetFields().end();
397 ++it) {
398 if (it->second.edge()->IsWeakMember())
399 it->second.MarkTraced();
400 }
401 }
402 393
403 QualType base = expr->getBaseType(); 394 QualType base = expr->getBaseType();
404 if (!base->isPointerType()) 395 if (!base->isPointerType())
405 return true; 396 return true;
406 CXXRecordDecl* decl = base->getPointeeType()->getAsCXXRecordDecl(); 397 CXXRecordDecl* decl = base->getPointeeType()->getAsCXXRecordDecl();
407 if (decl) 398 if (decl)
408 CheckTraceFieldCall(expr->getMemberName().getAsString(), decl, arg); 399 CheckTraceFieldCall(expr->getMemberName().getAsString(), decl, arg);
409 if (Config::IsTraceImplName(expr->getMemberName().getAsString())) 400 if (Config::IsTraceImplName(expr->getMemberName().getAsString()))
410 delegates_to_traceimpl_ = true; 401 delegates_to_traceimpl_ = true;
411 return true; 402 return true;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 if (!type) 438 if (!type)
448 return 0; 439 return 0;
449 440
450 return RecordInfo::GetDependentTemplatedDecl(*type); 441 return RecordInfo::GetDependentTemplatedDecl(*type);
451 } 442 }
452 443
453 void CheckCXXDependentScopeMemberExpr(CallExpr* call, 444 void CheckCXXDependentScopeMemberExpr(CallExpr* call,
454 CXXDependentScopeMemberExpr* expr) { 445 CXXDependentScopeMemberExpr* expr) {
455 string fn_name = expr->getMember().getAsString(); 446 string fn_name = expr->getMember().getAsString();
456 447
457 // Check for VisitorDispatcher::trace(field) 448 // Check for VisitorDispatcher::trace(field) and
449 // VisitorDispatcher::registerWeakMembers.
458 if (!expr->isImplicitAccess()) { 450 if (!expr->isImplicitAccess()) {
459 if (clang::DeclRefExpr* base_decl = 451 if (clang::DeclRefExpr* base_decl =
460 clang::dyn_cast<clang::DeclRefExpr>(expr->getBase())) { 452 clang::dyn_cast<clang::DeclRefExpr>(expr->getBase())) {
461 if (Config::IsVisitorDispatcherType(base_decl->getType()) && 453 if (Config::IsVisitorDispatcherType(base_decl->getType())) {
462 call->getNumArgs() == 1 && fn_name == kTraceName) { 454 if (call->getNumArgs() == 1 && fn_name == kTraceName) {
463 FindFieldVisitor finder; 455 FindFieldVisitor finder;
464 finder.TraverseStmt(call->getArg(0)); 456 finder.TraverseStmt(call->getArg(0));
465 if (finder.field()) 457 if (finder.field())
466 FoundField(finder.field()); 458 FoundField(finder.field());
467 459
468 return; 460 return;
461 } else if (call->getNumArgs() == 1 &&
462 fn_name == kRegisterWeakMembersName) {
463 MarkAllWeakMembersTraced();
464 }
469 } 465 }
470 } 466 }
471 } 467 }
472 468
473 CXXRecordDecl* tmpl = GetDependentTemplatedDecl(expr); 469 CXXRecordDecl* tmpl = GetDependentTemplatedDecl(expr);
474 if (!tmpl) 470 if (!tmpl)
475 return; 471 return;
476 472
477 // Check for Super<T>::trace(visitor) 473 // Check for Super<T>::trace(visitor)
478 if (call->getNumArgs() == 1 && IsTraceCallName(fn_name)) { 474 if (call->getNumArgs() == 1 && IsTraceCallName(fn_name)) {
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
689 break; 685 break;
690 } 686 }
691 } 687 }
692 } else { 688 } else {
693 RecordInfo::Fields::iterator it = info_->GetFields().find(field); 689 RecordInfo::Fields::iterator it = info_->GetFields().find(field);
694 if (it != info_->GetFields().end()) 690 if (it != info_->GetFields().end())
695 MarkTraced(it); 691 MarkTraced(it);
696 } 692 }
697 } 693 }
698 694
695 void MarkAllWeakMembersTraced() {
696 // If we find a call to registerWeakMembers which is unresolved we
697 // unsoundly consider all weak members as traced.
698 // TODO: Find out how to validate weak member tracing for unresolved call.
699 for (auto& field : info_->GetFields()) {
700 if (field.second.edge()->IsWeakMember())
701 field.second.MarkTraced();
702 }
703 }
704
699 CXXMethodDecl* trace_; 705 CXXMethodDecl* trace_;
700 RecordInfo* info_; 706 RecordInfo* info_;
701 RecordCache* cache_; 707 RecordCache* cache_;
702 bool delegates_to_traceimpl_; 708 bool delegates_to_traceimpl_;
703 }; 709 };
704 710
705 // This visitor checks that the fields of a class and the fields of 711 // This visitor checks that the fields of a class and the fields of
706 // its part objects don't define GC roots. 712 // its part objects don't define GC roots.
707 class CheckGCRootsVisitor : public RecursiveEdgeVisitor { 713 class CheckGCRootsVisitor : public RecursiveEdgeVisitor {
708 public: 714 public:
(...skipping 1338 matching lines...) Expand 10 before | Expand all | Expand 10 after
2047 2053
2048 private: 2054 private:
2049 BlinkGCPluginOptions options_; 2055 BlinkGCPluginOptions options_;
2050 }; 2056 };
2051 2057
2052 } // namespace 2058 } // namespace
2053 2059
2054 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X( 2060 static FrontendPluginRegistry::Add<BlinkGCPluginAction> X(
2055 "blink-gc-plugin", 2061 "blink-gc-plugin",
2056 "Check Blink GC invariants"); 2062 "Check Blink GC invariants");
OLDNEW
« no previous file with comments | « no previous file | tools/clang/blink_gc_plugin/tests/heap/stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698