llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-static-analyzer-1 @llvm/pr-subscribers-clang Author: Ryosuke Niwa (rniwa) <details> <summary>Changes</summary> When a template class takes Ref<T> as a template parameter and this template parameter is used as the return value of a member function, the return value can be treated as unsafe (i.e. emits a false positive). The issue was caused by getCanonicalType sometimes converting Ref<T> to T. Workaround this problem by avoid emitting a warning when the original, non-canonical type is a safe pointer type. --- Full diff: https://github.com/llvm/llvm-project/pull/157993.diff 2 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp (+15-2) - (added) clang/test/Analysis/Checkers/WebKit/template-wrapper-call-arg.cpp (+21) ``````````diff diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp index e80f1749d595b..47bd13bea4abb 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp @@ -122,9 +122,22 @@ class RawPtrRefCallArgsChecker return; } auto *E = MemberCallExpr->getImplicitObjectArgument(); - QualType ArgType = MemberCallExpr->getObjectType().getCanonicalType(); + auto MemberCallQT = MemberCallExpr->getObjectType(); + QualType ArgType = MemberCallQT.getCanonicalType(); std::optional<bool> IsUnsafe = isUnsafeType(ArgType); - if (IsUnsafe && *IsUnsafe && !isPtrOriginSafe(E)) + + // Sometimes, canonical type erroneously turns Ref<T> into T. + // Workaround this problem by checking again if the original type was + // a SubstTemplateTypeParmType of a safe smart pointer type (e.g. Ref). + bool IsSafePtr = false; + if (auto *Subst = dyn_cast<SubstTemplateTypeParmType>(MemberCallQT)) { + if (auto *Decl = Subst->getAssociatedDecl()) { + if (auto *CXXRD = dyn_cast<CXXRecordDecl>(Decl)) + IsSafePtr = isSafePtr(CXXRD); + } + } + + if (IsUnsafe && *IsUnsafe && !IsSafePtr && !isPtrOriginSafe(E)) reportBugOnThis(E, D); } 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<typename T> class Wrapper { +public: + T obj(); +}; + +static void foo(Wrapper<Ref<Obj>>&& wrapper) +{ + wrapper.obj()->someFunction(); +} `````````` </details> https://github.com/llvm/llvm-project/pull/157993 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits