diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index 9a7f5b71cae71..f49a6f3b16491 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -154,6 +154,24 @@ bool tryToFindPtrOrigin( Name == "NSClassFromString") return callback(E, true); } + + // Sometimes, canonical type erroneously turns Ref into T. + // Workaround this problem by checking again if the original type was + // a SubstTemplateTypeParmType of a safe smart pointer type (e.g. Ref). + if (auto *CalleeDecl = call->getCalleeDecl()) { + if (auto *FD = dyn_cast(CalleeDecl)) { + auto RetType = FD->getReturnType(); + if (auto *Subst = dyn_cast(RetType)) { + if (auto *SubstType = Subst->desugar().getTypePtr()) { + if (auto *RD = dyn_cast(SubstType)) { + if (auto *CXX = dyn_cast(RD->getOriginalDecl())) + if (isSafePtr(CXX)) + return callback(E, true); + } + } + } + } + } } if (auto *ObjCMsgExpr = dyn_cast(E)) { if (auto *Method = ObjCMsgExpr->getMethodDecl()) { diff --git a/clang/test/Analysis/Checkers/WebKit/template-wrapper-call-arg.cpp b/clang/test/Analysis/Checkers/WebKit/template-wrapper-call-arg.cpp new file mode 100644 index 0000000000000..b0ff210f9415e --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/template-wrapper-call-arg.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.UncountedCallArgsChecker -verify %s +// expected-no-diagnostics + +#include "mock-types.h" + +struct Obj { + void ref() const; + void deref() const; + + void someFunction(); +}; + +template class Wrapper { +public: + T obj(); +}; + +static void foo(Wrapper>&& wrapper) +{ + wrapper.obj()->someFunction(); +}