diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index dc86c4fcc64b1..58020ec4e084d 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -140,9 +140,14 @@ bool tryToFindPtrOrigin( bool isASafeCallArg(const Expr *E) { assert(E); if (auto *Ref = dyn_cast(E)) { - if (auto *D = dyn_cast_or_null(Ref->getFoundDecl())) { + auto *FoundDecl = Ref->getFoundDecl(); + if (auto *D = dyn_cast_or_null(FoundDecl)) { if (isa(D) || D->isLocalVarDecl()) return true; + } else if (auto *BD = dyn_cast_or_null(FoundDecl)) { + VarDecl *VD = BD->getHoldingVar(); + if (VD && (isa(VD) || VD->isLocalVarDecl())) + return true; } } if (isConstOwnerPtrMemberExpr(E)) diff --git a/clang/test/Analysis/Checkers/WebKit/binding-to-refptr.cpp b/clang/test/Analysis/Checkers/WebKit/binding-to-refptr.cpp new file mode 100644 index 0000000000000..012868fcb329a --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/binding-to-refptr.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s -std=c++2c +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncheckedLocalVarsChecker -verify %s -std=c++2c + +// expected-no-diagnostics + +#include "mock-types.h" + +class Node { +public: + Node* nextSibling() const; + + void ref() const; + void deref() const; +}; + +template struct pair { + A a; + B b; + template requires ( I == 0 ) A& get(); + template requires ( I == 1 ) B& get(); +}; + +namespace std { + template struct tuple_size; + template struct tuple_element; + template struct tuple_size<::pair> { static constexpr int value = 2; }; + template struct tuple_element<0, ::pair> { using type = A; }; + template struct tuple_element<1, ::pair> { using type = B; }; +} + +pair, RefPtr> &getPair(); + +static void testUnpackedAssignment() { + auto [a, b] = getPair(); + a->nextSibling(); +}