[clang] [alpha.webkit.UncountedLocalVarsChecker] Warn the use of a raw pointer/reference when the guardian variable gets mutated. (PR #113859)
Rashmi Mudduluru via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 28 16:24:12 PDT 2024
================
@@ -48,6 +48,64 @@ bool isRefcountedStringsHack(const VarDecl *V) {
return false;
}
+struct GuardianVisitor : public RecursiveASTVisitor<GuardianVisitor> {
+ using Base = RecursiveASTVisitor<GuardianVisitor>;
+
+ const VarDecl *Guardian{nullptr};
+
+public:
+ explicit GuardianVisitor(const VarDecl *Guardian) : Guardian(Guardian) {
+ assert(Guardian);
+ }
+
+ bool VisitBinaryOperator(const BinaryOperator *BO) {
+ if (BO->isAssignmentOp()) {
+ if (auto *VarRef = dyn_cast<DeclRefExpr>(BO->getLHS())) {
+ if (VarRef->getDecl() == Guardian)
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool VisitCXXConstructExpr(const CXXConstructExpr *CE) {
+ if (auto *Ctor = CE->getConstructor()) {
+ if (Ctor->isMoveConstructor() && CE->getNumArgs() == 1) {
+ auto *Arg = CE->getArg(0)->IgnoreParenCasts();
+ if (auto *VarRef = dyn_cast<DeclRefExpr>(Arg)) {
+ if (VarRef->getDecl() == Guardian)
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ bool VisitCXXMemberCallExpr(const CXXMemberCallExpr *MCE) {
+ auto MethodName = safeGetName(MCE->getMethodDecl());
+ if (MethodName == "swap" || MethodName == "leakRef" ||
+ MethodName == "releaseNonNull") {
+ auto *ThisArg = MCE->getImplicitObjectArgument()->IgnoreParenCasts();
+ if (auto *VarRef = dyn_cast<DeclRefExpr>(ThisArg)) {
+ if (VarRef->getDecl() == Guardian)
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE) {
+ if (OCE->isAssignmentOp() && OCE->getNumArgs() == 2) {
----------------
t-rasmud wrote:
Is the check `OCE->getNumArgs() == 2` necessary here? What are the cases in which `CXXOperatorCallExpr` is an assignment op but has a different number of args?
https://github.com/llvm/llvm-project/pull/113859
More information about the cfe-commits
mailing list