-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[alpha.webkit.UncountedCallArgsChecker] A return value can be erroneously treated as unsafe if it's a template parameter #157993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…usly treated as unsafe if it's a template parameter 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.
@llvm/pr-subscribers-clang-static-analyzer-1 @llvm/pr-subscribers-clang Author: Ryosuke Niwa (rniwa) ChangesWhen 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:
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();
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
…a callee, not any member call type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
…usly treated as unsafe if it's a template parameter (llvm#157993) 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.
…usly treated as unsafe if it's a template parameter (llvm#157993) 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.
…usly treated as unsafe if it's a template parameter (llvm#157993) 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.
When a template class takes Ref 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 to T. Workaround this problem by avoid emitting a warning when the original, non-canonical type is a safe pointer type.