llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-static-analyzer-1 Author: Ryosuke Niwa (rniwa) <details> <summary>Changes</summary> This PR adds support for treating WTF::move like std::move in various WebKit checkers. --- Full diff: https://github.com/llvm/llvm-project/pull/170820.diff 11 Files Affected: - (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp (+5-5) - (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp (+1-2) - (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp (+9) - (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h (+3) - (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp (+2-5) - (modified) clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp (+1) - (modified) clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm (+3) - (modified) clang/test/Analysis/Checkers/WebKit/mock-types.h (+6) - (modified) clang/test/Analysis/Checkers/WebKit/objc-mock-types.h (+8-2) - (modified) clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp (+8) - (modified) clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp (+1) ``````````diff diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index 84adbf318e9f8..8f104feffa66b 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -132,11 +132,6 @@ bool tryToFindPtrOrigin( } } - if (call->isCallToStdMove() && call->getNumArgs() == 1) { - E = call->getArg(0)->IgnoreParenCasts(); - continue; - } - if (auto *callee = call->getDirectCallee()) { if (isCtorOfSafePtr(callee)) { if (StopAtFirstRefCountedObj) @@ -146,6 +141,11 @@ bool tryToFindPtrOrigin( continue; } + if (isStdOrWTFMove(callee) && call->getNumArgs() == 1) { + E = call->getArg(0)->IgnoreParenCasts(); + continue; + } + if (isSafePtrType(callee->getReturnType())) return callback(E, true); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp index 1d4e6dd572749..59336328a2823 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp @@ -267,8 +267,7 @@ class ForwardDeclChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> { ArgExpr = ArgExpr->IgnoreParenCasts(); if (auto *InnerCE = dyn_cast<CallExpr>(ArgExpr)) { auto *InnerCallee = InnerCE->getDirectCallee(); - if (InnerCallee && InnerCallee->isInStdNamespace() && - safeGetName(InnerCallee) == "move" && InnerCE->getNumArgs() == 1) { + if (isStdOrWTFMove(InnerCallee) && InnerCE->getNumArgs() == 1) { ArgExpr = InnerCE->getArg(0); continue; } diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp index 5cd894af1fd65..3636b37dea632 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp @@ -185,6 +185,15 @@ bool isCtorOfSafePtr(const clang::FunctionDecl *F) { isCtorOfRetainPtrOrOSPtr(F); } +bool isStdOrWTFMove(const clang::FunctionDecl *F) { + auto FnName = safeGetName(F); + auto *Namespace = F->getParent(); + if (!Namespace) + return false; + auto NsName = safeGetName(Namespace); + return (NsName == "WTF" || NsName == "std") && FnName == "move"; +} + template <typename Predicate> static bool isPtrOfType(const clang::QualType T, Predicate Pred) { QualType type = T; diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h index 12e2e2d75b75d..96250f7f851e9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h @@ -134,6 +134,9 @@ bool isCtorOfCheckedPtr(const clang::FunctionDecl *F); /// uncounted parameter, false if not. bool isCtorOfSafePtr(const clang::FunctionDecl *F); +/// \returns true if \p F is std::move or WTF::move. +bool isStdOrWTFMove(const clang::FunctionDecl *F); + /// \returns true if \p Name is RefPtr, Ref, or its variant, false if not. bool isRefType(const std::string &Name); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp index f60d1936b7584..d9b5261612a36 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLambdaCapturesChecker.cpp @@ -416,12 +416,9 @@ class RawPtrRefLambdaCapturesChecker return false; } if (auto *CE = dyn_cast<CallExpr>(Arg)) { - if (CE->isCallToStdMove() && CE->getNumArgs() == 1) { - Arg = CE->getArg(0)->IgnoreParenCasts(); - continue; - } if (auto *Callee = CE->getDirectCallee()) { - if (isCtorOfSafePtr(Callee) && CE->getNumArgs() == 1) { + if ((isStdOrWTFMove(Callee) || isCtorOfSafePtr(Callee)) && + CE->getNumArgs() == 1) { Arg = CE->getArg(0)->IgnoreParenCasts(); continue; } diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp index e9f01c8ed7540..b257d09236c07 100644 --- a/clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp +++ b/clang/test/Analysis/Checkers/WebKit/call-args-checked.cpp @@ -80,6 +80,7 @@ namespace call_with_std_move { void consume(CheckedObj&&); void foo(CheckedObj&& obj) { consume(std::move(obj)); + consume(WTF::move(obj)); } } diff --git a/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm b/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm index 8aad838b71b35..1f0a0281eaf7a 100644 --- a/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm +++ b/clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm @@ -44,6 +44,7 @@ void opaque_call_arg(Obj* obj, Obj&& otherObj, const RefPtr<Obj>& safeObj, WeakP receive_obj_ref(*obj); receive_obj_ptr(&*obj); receive_obj_rref(std::move(otherObj)); + receive_obj_rref(WTF::move(otherObj)); receive_obj_ref(*safeObj.get()); receive_obj_ptr(weakObj.get()); // expected-warning@-1{{Call argument for parameter 'p' uses a forward declared type 'Obj *'}} @@ -59,6 +60,7 @@ void rval(Obj&& arg) { auto &&obj = provide_obj_rval(); // expected-warning@-1{{Local variable 'obj' uses a forward declared type 'Obj &&'}} receive_obj_rval(std::move(arg)); + receive_obj_rval(WTF::move(arg)); } ObjCObj *provide_objcobj(); @@ -84,6 +86,7 @@ void construct_ptr(Obj&& arg) { WrapperObj wrapper2(provide_obj_ref()); // expected-warning@-1{{Call argument for parameter 'obj' uses a forward declared type 'Obj &'}} WrapperObj wrapper3(std::move(arg)); + WrapperObj wrapper4(WTF::move(arg)); } JSStringRef provide_opaque_ptr(); diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h index 7055a94753a37..8a24a3c64e0e4 100644 --- a/clang/test/Analysis/Checkers/WebKit/mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h @@ -17,6 +17,12 @@ template<typename T> typename remove_reference<T>::type&& move(T&& t); #endif +namespace WTF { + +template<typename T> typename std::remove_reference<T>::type&& move(T&& t); + +} + #ifndef mock_types_1103988513531 #define mock_types_1103988513531 diff --git a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h index edf40115afa19..124821a8ded55 100644 --- a/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/objc-mock-types.h @@ -17,6 +17,12 @@ template<typename T> typename remove_reference<T>::type&& move(T&& t); #endif +namespace WTF { + +template<typename T> typename std::remove_reference<T>::type&& move(T&& t); + +} + namespace std { template <bool, typename U = void> struct enable_if { @@ -453,7 +459,7 @@ template<typename T> class OSObjectPtr { } OSObjectPtr(T ptr) - : m_ptr(std::move(ptr)) + : m_ptr(WTF::move(ptr)) { if (m_ptr) retainOSObject(m_ptr); @@ -483,7 +489,7 @@ template<typename T> class OSObjectPtr { OSObjectPtr& operator=(T other) { - OSObjectPtr ptr = std::move(other); + OSObjectPtr ptr = WTF::move(other); swap(ptr); return *this; } diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp index fd1eecdda64fd..8eb15f4f77973 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp @@ -437,6 +437,14 @@ struct RefCountableWithLambdaCapturingThis { }); }); } + + void method_nested_lambda4() { + callAsync([this, protectedThis = RefPtr { this }] { + callAsync([this, protectedThis = WTF::move(*protectedThis)] { + nonTrivial(); + }); + }); + } }; struct NonRefCountableWithLambdaCapturingThis { diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp index a9cd77c066f6f..b83eaedf264e4 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp @@ -387,6 +387,7 @@ class RefCounted { unsigned trivial69() { return offsetof(OtherObj, children); } DerivedNumber* trivial70() { [[clang::suppress]] return static_cast<DerivedNumber*>(number); } unsigned trivial71() { return std::bit_cast<unsigned>(nullptr); } + unsigned trivial72() { Number n { 5 }; return WTF::move(n).value(); } static RefCounted& singleton() { static RefCounted s_RefCounted; `````````` </details> https://github.com/llvm/llvm-project/pull/170820 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
