[clang] Diagnose potential size confusion with VLA params (PR #129772)

via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 5 00:28:10 PST 2025


================
@@ -10333,6 +10334,74 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
       }
     }
 
+    // Loop over the parameters to see if any of the size expressions contains
+    // a DeclRefExpr which refers to a variable from an outer scope that is
+    // also named later in the parameter list.
+    // e.g., int n; void func(int array[n], int n);
+    SmallVector<const DeclRefExpr *, 2> DRESizeExprs;
+    llvm::for_each(Params, [&](const ParmVarDecl *Param) {
+      // If we have any size expressions we need to check against, check them
+      // now.
+      for (const auto *DRE : DRESizeExprs) {
+        // Check to see if this parameter has the same name as one of the
+        // DeclRefExprs we wanted to test against. If so, then we found a
+        // situation where an earlier parameter refers to the name of a later
+        // parameter, which is (currently) only valid if there's a variable
+        // from an outer scope with the same name.
+        if (const auto *SizeExprND = dyn_cast<NamedDecl>(DRE->getDecl())) {
+          if (SizeExprND->getIdentifier() == Param->getIdentifier()) {
+            // Diagnose the DeclRefExpr from the parameter with the size
+            // expression.
+            Diag(DRE->getLocation(), diag::warn_vla_size_expr_shadow);
+            // Note the parameter that a user could be confused into thinking
+            // they're referring to.
+            Diag(Param->getLocation(), diag::note_vla_size_expr_shadow_param);
+            // Note the DeclRefExpr that's actually being used.
+            Diag(DRE->getDecl()->getLocation(),
+                 diag::note_vla_size_expr_shadow_actual);
+          }
+        }
+      }
+
+      // To check whether its size expression is a simple DeclRefExpr, we first
+      // have to walk through pointers or references, but array types always
+      // decay to a pointer, so skip if this is a DecayedType.
+      QualType QT = Param->getType();
+      while (!isa<DecayedType>(QT.getTypePtr()) &&
+             (QT->isPointerType() || QT->isReferenceType()))
+        QT = QT->getPointeeType();
----------------
cor3ntin wrote:

There isn't already a way to do that?

https://github.com/llvm/llvm-project/pull/129772


More information about the cfe-commits mailing list