https://github.com/ak1932 created 
https://github.com/llvm/llvm-project/pull/181550

This PR continues the work of @AaronBallman PR #129772 in adding diagnostic to 
a potential confusion when using a later function parameter as the size bound 
for a variable length array. The confusion would arise when using a later 
parameter of the same name as outer scoped variable as the bound, in which case 
the compiler should recognize the outer scoped variable as the bound and warn 
the user of the confusion.

I have resolved the comments received on that PR with the following additions:
1. refactor the code to a seperate function and only invoke it when 
bounds-safety is enabled
2. move to ConstDynamicRecursiveASTVisitor instead of RecursiveASTVisitor
3. add a constexpr test for member function

>From 1bf8c21cd9080012f81ee8c796378c58ac65dc61 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <[email protected]>
Date: Tue, 4 Mar 2025 15:52:19 -0500
Subject: [PATCH 1/5] Diagnose potential size confusion with VLA params

With Clang starting to support bounds safety checking annotations,
we've begun to dabble in late parsing of function parameters so that
an earlier parameter can refer to a later parameter by name. However,
one situation where this can cause a problem is if the earlier
parameter is actually referencing a variable from an outer scope.

To help identify those situations, this introduces a new diagnostic
-Wvla-potential-size-confusion (grouped under -Wvla). This diagnoses
code like:

  int n;
  void func(int array[n], int n);

to let the user know that the 'n' in 'array[n]' references the file
scope variable and not the parameter.
---
 clang/docs/ReleaseNotes.rst                   |  4 ++
 clang/include/clang/Basic/DiagnosticGroups.td |  3 +-
 .../clang/Basic/DiagnosticSemaKinds.td        |  7 ++
 clang/lib/Sema/SemaDecl.cpp                   | 70 +++++++++++++++++++
 .../test/Sema/vla-potential-size-confusion.c  | 68 ++++++++++++++++++
 5 files changed, 151 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Sema/vla-potential-size-confusion.c

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c648e8b0ec6fa..9ac78d610e04d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -244,6 +244,10 @@ Improvements to Clang's diagnostics
 
 - The ``-Wloop-analysis`` warning has been extended to catch more cases of
   variable modification inside lambda expressions (#GH132038).
+- Added the ``-Wvla-potential-size-confusion`` diagnostic, which is grouped
+  under ``-Wvla`` to diagnose when a variably-modified type in a function
+  parameter list is using a variable from an outer scope as opposed to a
+  variable declared later in the parameter list.
 
 Improvements to Clang's time-trace
 ----------------------------------
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index 0372cf062ec67..0572327d60ae3 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1114,7 +1114,8 @@ def VexingParse : DiagGroup<"vexing-parse">;
 def VLAUseStaticAssert : DiagGroup<"vla-extension-static-assert">;
 def VLACxxExtension : DiagGroup<"vla-cxx-extension", [VLAUseStaticAssert]>;
 def VLAExtension : DiagGroup<"vla-extension", [VLACxxExtension]>;
-def VLA : DiagGroup<"vla", [VLAExtension]>;
+def VLASizeConfusion : DiagGroup<"vla-potential-size-confusion">;
+def VLA : DiagGroup<"vla", [VLAExtension, VLASizeConfusion]>;
 def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
 def Visibility : DiagGroup<"visibility">;
 def ZeroLengthArray : DiagGroup<"zero-length-array">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 85a023435ba23..4b1fd1d635e9a 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -229,6 +229,13 @@ def err_vla_in_coroutine_unsupported : Error<
   "variable length arrays in a coroutine are not supported">;
 def note_vla_unsupported : Note<
   "variable length arrays are not supported for the current target">;
+def warn_vla_size_expr_shadow : Warning<
+  "variable length array size expression refers to declaration from an outer "
+  "scope">, InGroup<VLASizeConfusion>;
+def note_vla_size_expr_shadow_param : Note<
+  "does not refer to this declaration">;
+def note_vla_size_expr_shadow_actual : Note<
+  "refers to this declaration instead">;
 
 // C99 variably modified types
 def err_variably_modified_template_arg : Error<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4dfde4bf8cedf..a2b2216e9b112 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -26,6 +26,7 @@
 #include "clang/AST/MangleNumberingContext.h"
 #include "clang/AST/NonTrivialTypeVisitor.h"
 #include "clang/AST/Randstruct.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/Builtins.h"
@@ -10566,6 +10567,75 @@ 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();
+
+      // An array type is always decayed to a pointer, so we need to get the
+      // original type in that case.
+      if (const auto *DT = QT->getAs<DecayedType>())
+        QT = DT->getOriginalType();
+
+      // Now we can see if it's a VLA type with a size expression.
+      // FIXME: it would be nice to handle constant-sized arrays as well,
+      // e.g., constexpr int n = 12; void foo(int array[n], int n);
+      // however, the constant expression is replaced by its value at the time
+      // we form the type, so we've lost that information here.
+      if (!QT->hasSizedVLAType())
+        return;
+
+      const VariableArrayType *VAT = 
getASTContext().getAsVariableArrayType(QT);
+      if (!VAT)
+        return;
+
+      class DeclRefFinder : public RecursiveASTVisitor<DeclRefFinder> {
+        SmallVectorImpl<const DeclRefExpr *> &Found;
+
+      public:
+        DeclRefFinder(SmallVectorImpl<const DeclRefExpr *> &Found)
+            : Found(Found) {}
+        bool VisitDeclRefExpr(const DeclRefExpr *DRE) {
+          Found.push_back(DRE);
+          return true;
+        }
+      } Finder(DRESizeExprs);
+      Finder.TraverseStmt(VAT->getSizeExpr());
+    });
+
     if (!getLangOpts().CPlusPlus) {
       // In C, find all the tag declarations from the prototype and move them
       // into the function DeclContext. Remove them from the surrounding tag
diff --git a/clang/test/Sema/vla-potential-size-confusion.c 
b/clang/test/Sema/vla-potential-size-confusion.c
new file mode 100644
index 0000000000000..de9560483e5f3
--- /dev/null
+++ b/clang/test/Sema/vla-potential-size-confusion.c
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 %s -std=c23 -verify=expected,c -fsyntax-only
+// RUN: %clang_cc1 %s -std=c23 -verify=good -fsyntax-only -Wno-vla
+// RUN: %clang_cc1 -x c++ %s -verify -fsyntax-only
+// RUN: %clang_cc1 -DCARET -fsyntax-only -std=c23 
-fno-diagnostics-show-line-numbers -fcaret-diagnostics-max-lines=1 %s 2>&1 | 
FileCheck %s -strict-whitespace
+
+// good-no-diagnostics
+
+int n, m;      // #decl
+int size(int);
+
+void foo(int vla[n], int n); // expected-warning {{variable length array size 
expression refers to declaration from an outer scope}} \
+                                expected-note {{does not refer to this 
declaration}} \
+                                expected-note@#decl {{refers to this 
declaration instead}}
+
+void bar(int (*vla)[n], int n); // expected-warning {{variable length array 
size expression refers to declaration from an outer scope}} \
+                                   expected-note {{does not refer to this 
declaration}} \
+                                   expected-note@#decl {{refers to this 
declaration instead}}
+
+void baz(int n, int vla[n]); // no diagnostic expected
+
+void quux(int vla[n + 12], int n); // expected-warning {{variable length array 
size expression refers to declaration from an outer scope}} \
+                                      expected-note {{does not refer to this 
declaration}} \
+                                      expected-note@#decl {{refers to this 
declaration instead}}
+
+void quibble(int vla[size(n)], int n);  // expected-warning {{variable length 
array size expression refers to declaration from an outer scope}} \
+                                           expected-note {{does not refer to 
this declaration}} \
+                                           expected-note@#decl {{refers to 
this declaration instead}}
+
+void quobble(int vla[n + m], int n, int m);  // expected-warning 2 {{variable 
length array size expression refers to declaration from an outer scope}} \
+                                                expected-note 2 {{does not 
refer to this declaration}} \
+                                                expected-note@#decl 2 {{refers 
to this declaration instead}}
+
+// For const int, we still treat the function as having a variably-modified
+// type, but only in C.
+const int x = 12; // #other-decl
+void quorble(int vla[x], int x); // c-warning {{variable length array size 
expression refers to declaration from an outer scope}} \
+                                    c-note {{does not refer to this 
declaration}} \
+                                    c-note@#other-decl {{refers to this 
declaration instead}}
+
+// For constexpr int, the function has a constant array type. It would be nice
+// to diagnose this case as well, but the type system replaces the expression
+// with the constant value, and so the information about the name of the
+// variable used in the size expression is lost.
+constexpr int y = 12;
+void quuble(int vla[y], int y); // no diagnostic expected
+
+#ifdef __cplusplus
+struct S {
+  static int v; // #mem-var
+  
+  void member_function(int vla[v], int v);  // expected-warning {{variable 
length array size expression refers to declaration from an outer scope}} \
+                                               expected-note {{does not refer 
to this declaration}} \
+                                               expected-note@#mem-var {{refers 
to this declaration instead}}
+};
+#endif
+
+#ifdef CARET
+// Test that caret locations make sense.
+int w;
+void quable(int vla[w], int w);
+
+// CHECK: void quable(int vla[w], int w);
+// CHECK:                     ^
+// CHECK: void quable(int vla[w], int w);
+// CHECK:                             ^
+// CHECK: int w;
+// CHECK:     ^
+#endif

>From 14c11e83a01a96cc26e7e6c81c1345c0e00fb08d Mon Sep 17 00:00:00 2001
From: Aaron Ballman <[email protected]>
Date: Tue, 4 Mar 2025 16:03:02 -0500
Subject: [PATCH 2/5] clang-format fix

---
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 15 ++++++++-------
 clang/lib/Sema/SemaDecl.cpp                      |  1 -
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4b1fd1d635e9a..5ec88da7c878e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -229,13 +229,14 @@ def err_vla_in_coroutine_unsupported : Error<
   "variable length arrays in a coroutine are not supported">;
 def note_vla_unsupported : Note<
   "variable length arrays are not supported for the current target">;
-def warn_vla_size_expr_shadow : Warning<
-  "variable length array size expression refers to declaration from an outer "
-  "scope">, InGroup<VLASizeConfusion>;
-def note_vla_size_expr_shadow_param : Note<
-  "does not refer to this declaration">;
-def note_vla_size_expr_shadow_actual : Note<
-  "refers to this declaration instead">;
+def warn_vla_size_expr_shadow : Warning<"variable length array size expression 
"
+                                        "refers to declaration from an outer "
+                                        "scope">,
+                                InGroup<VLASizeConfusion>;
+def note_vla_size_expr_shadow_param
+    : Note<"does not refer to this declaration">;
+def note_vla_size_expr_shadow_actual
+    : Note<"refers to this declaration instead">;
 
 // C99 variably modified types
 def err_variably_modified_template_arg : Error<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a2b2216e9b112..ee52c2b76e049 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10592,7 +10592,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, 
DeclContext *DC,
             // Note the DeclRefExpr that's actually being used.
             Diag(DRE->getDecl()->getLocation(),
                  diag::note_vla_size_expr_shadow_actual);
-            
           }
         }
       }

>From 41893312638486a18048ea9f64130bf2a856a598 Mon Sep 17 00:00:00 2001
From: ak1932 <[email protected]>
Date: Sun, 15 Feb 2026 17:13:52 +0530
Subject: [PATCH 3/5] [clang][bounds-safety] diagnose vla size parameter only
 when bounds-safety is enabled

---
 clang/include/clang/Sema/Sema.h               |   4 +
 clang/lib/Sema/SemaDecl.cpp                   | 140 +++++++++---------
 .../test/Sema/vla-potential-size-confusion.c  |   9 +-
 3 files changed, 82 insertions(+), 71 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 9424b80d5cdb6..fa3bbd473f1aa 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -4239,6 +4239,10 @@ class Sema final : public SemaBase {
   /// ParmVarDecl pointers.
   void DiagnoseUnusedParameters(ArrayRef<ParmVarDecl *> Parameters);
 
+  /// Diagnose vla size declaration confusion between file scope variables
+  /// and function parameters
+  void DiagnoseVlaSizeParameter(const SmallVector<ParmVarDecl *, 16> &Params);
+
   /// Diagnose whether the size of parameters or return value of a
   /// function or obj-c method definition is pass-by-value and larger than a
   /// specified threshold.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ee52c2b76e049..655420b368eed 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -10058,6 +10058,76 @@ static bool isStdBuiltin(ASTContext &Ctx, FunctionDecl 
*FD,
   }
 }
 
+void Sema::DiagnoseVlaSizeParameter(
+    const SmallVector<ParmVarDecl *, 16> &Params) {
+  // 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());
+          SizeExprND && 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();
+
+    // An array type is always decayed to a pointer, so we need to get the
+    // original type in that case.
+    if (const auto *DT = QT->getAs<DecayedType>())
+      QT = DT->getOriginalType();
+
+    // Now we can see if it's a VLA type with a size expression.
+    // FIXME: it would be nice to handle constant-sized arrays as well,
+    // e.g., constexpr int n = 12; void foo(int array[n], int n);
+    // however, the constant expression is replaced by its value at the time
+    // we form the type, so we've lost that information here.
+    if (!QT->hasSizedVLAType())
+      return;
+
+    const VariableArrayType *VAT = getASTContext().getAsVariableArrayType(QT);
+    if (!VAT)
+      return;
+
+    class DeclRefFinder : public RecursiveASTVisitor<DeclRefFinder> {
+      SmallVectorImpl<const DeclRefExpr *> &Found;
+
+    public:
+      DeclRefFinder(SmallVectorImpl<const DeclRefExpr *> &Found)
+          : Found(Found) {}
+      bool VisitDeclRefExpr(const DeclRefExpr *DRE) {
+        Found.push_back(DRE);
+        return true;
+      }
+    } Finder(DRESizeExprs);
+    Finder.TraverseStmt(VAT->getSizeExpr());
+  });
+}
+
 NamedDecl*
 Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
                               TypeSourceInfo *TInfo, LookupResult &Previous,
@@ -10567,73 +10637,9 @@ 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();
-
-      // An array type is always decayed to a pointer, so we need to get the
-      // original type in that case.
-      if (const auto *DT = QT->getAs<DecayedType>())
-        QT = DT->getOriginalType();
-
-      // Now we can see if it's a VLA type with a size expression.
-      // FIXME: it would be nice to handle constant-sized arrays as well,
-      // e.g., constexpr int n = 12; void foo(int array[n], int n);
-      // however, the constant expression is replaced by its value at the time
-      // we form the type, so we've lost that information here.
-      if (!QT->hasSizedVLAType())
-        return;
-
-      const VariableArrayType *VAT = 
getASTContext().getAsVariableArrayType(QT);
-      if (!VAT)
-        return;
-
-      class DeclRefFinder : public RecursiveASTVisitor<DeclRefFinder> {
-        SmallVectorImpl<const DeclRefExpr *> &Found;
-
-      public:
-        DeclRefFinder(SmallVectorImpl<const DeclRefExpr *> &Found)
-            : Found(Found) {}
-        bool VisitDeclRefExpr(const DeclRefExpr *DRE) {
-          Found.push_back(DRE);
-          return true;
-        }
-      } Finder(DRESizeExprs);
-      Finder.TraverseStmt(VAT->getSizeExpr());
-    });
+    if (getLangOpts().BoundsSafety) {
+      DiagnoseVlaSizeParameter(Params);
+    }
 
     if (!getLangOpts().CPlusPlus) {
       // In C, find all the tag declarations from the prototype and move them
diff --git a/clang/test/Sema/vla-potential-size-confusion.c 
b/clang/test/Sema/vla-potential-size-confusion.c
index de9560483e5f3..84d7067719ca2 100644
--- a/clang/test/Sema/vla-potential-size-confusion.c
+++ b/clang/test/Sema/vla-potential-size-confusion.c
@@ -1,7 +1,8 @@
-// RUN: %clang_cc1 %s -std=c23 -verify=expected,c -fsyntax-only
-// RUN: %clang_cc1 %s -std=c23 -verify=good -fsyntax-only -Wno-vla
-// RUN: %clang_cc1 -x c++ %s -verify -fsyntax-only
-// RUN: %clang_cc1 -DCARET -fsyntax-only -std=c23 
-fno-diagnostics-show-line-numbers -fcaret-diagnostics-max-lines=1 %s 2>&1 | 
FileCheck %s -strict-whitespace
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 6
+// RUN: %clang_cc1 -fexperimental-bounds-safety %s -std=c23 -verify=expected,c 
-fsyntax-only
+// RUN: %clang_cc1 -fexperimental-bounds-safety %s -std=c23 -verify=good 
-fsyntax-only -Wno-vla
+// RUN: %clang_cc1 -fexperimental-bounds-safety -x c++ %s -verify -fsyntax-only
+// RUN: %clang_cc1 -fexperimental-bounds-safety -DCARET -fsyntax-only -std=c23 
-fno-diagnostics-show-line-numbers -fcaret-diagnostics-max-lines=1 %s
 
 // good-no-diagnostics
 

>From ebe9c285eab0ec4d500a24d03fe47c27759e8a87 Mon Sep 17 00:00:00 2001
From: ak1932 <[email protected]>
Date: Sun, 15 Feb 2026 17:15:59 +0530
Subject: [PATCH 4/5] [clang][bounds-safety] add constexpr test for member
 function

---
 clang/test/Sema/vla-potential-size-confusion.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/test/Sema/vla-potential-size-confusion.c 
b/clang/test/Sema/vla-potential-size-confusion.c
index 84d7067719ca2..85f9e2ae09540 100644
--- a/clang/test/Sema/vla-potential-size-confusion.c
+++ b/clang/test/Sema/vla-potential-size-confusion.c
@@ -48,10 +48,13 @@ void quuble(int vla[y], int y); // no diagnostic expected
 #ifdef __cplusplus
 struct S {
   static int v; // #mem-var
-  
+  constexpr static int y = 12;
+
   void member_function(int vla[v], int v);  // expected-warning {{variable 
length array size expression refers to declaration from an outer scope}} \
                                                expected-note {{does not refer 
to this declaration}} \
                                                expected-note@#mem-var {{refers 
to this declaration instead}}
+
+  void member_function_with_const_arr(int cla[y], int y); // no diagnostic 
expected
 };
 #endif
 

>From cad59f390081d4a643db92542d7e297d8a2e2ebd Mon Sep 17 00:00:00 2001
From: ak1932 <[email protected]>
Date: Sun, 15 Feb 2026 18:50:59 +0530
Subject: [PATCH 5/5] [clang][bounds-safety] move to
 ConstDynamicRecursiveASTVistor from RecursiveASTVistor

---
 clang/lib/Sema/SemaDecl.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 655420b368eed..ed2e2606a91af 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -20,13 +20,13 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/DynamicRecursiveASTVisitor.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/MangleNumberingContext.h"
 #include "clang/AST/NonTrivialTypeVisitor.h"
 #include "clang/AST/Randstruct.h"
-#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/Builtins.h"
@@ -10113,13 +10113,13 @@ void Sema::DiagnoseVlaSizeParameter(
     if (!VAT)
       return;
 
-    class DeclRefFinder : public RecursiveASTVisitor<DeclRefFinder> {
+    class DeclRefFinder : public ConstDynamicRecursiveASTVisitor {
       SmallVectorImpl<const DeclRefExpr *> &Found;
 
     public:
       DeclRefFinder(SmallVectorImpl<const DeclRefExpr *> &Found)
           : Found(Found) {}
-      bool VisitDeclRefExpr(const DeclRefExpr *DRE) {
+      bool VisitDeclRefExpr(const DeclRefExpr *DRE) override {
         Found.push_back(DRE);
         return true;
       }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to