Origami404 updated this revision to Diff 483796.
Origami404 added a comment.

[clang] add -Wvla-stack-allocation and divide different VLA warning

New behaviors:

-Wvla-stack-allocation

  warns on use of a VLA that involves a stack allocation

-Wvla-portability

  warns on any use of a VM type, even if -Wvla-stack-allocation is
  given.

-Wvla

  groups together -Wvla-stack-allocation and -Wvla-portability

Fixes: https://github.com/llvm/llvm-project/issues/57098
Link: https://reviews.llvm.org/D132952

Co-authored-by: YingChi Long <m...@inclyc.cn>

Differential Revision: https://reviews.llvm.org/D137343


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D137343/new/

https://reviews.llvm.org/D137343

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/C/drs/dr3xx.c
  clang/test/Sema/cast.c
  clang/test/Sema/warn-vla.c
  clang/test/SemaCXX/warn-vla.cpp

Index: clang/test/SemaCXX/warn-vla.cpp
===================================================================
--- clang/test/SemaCXX/warn-vla.cpp
+++ clang/test/SemaCXX/warn-vla.cpp
@@ -1,7 +1,10 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wvla %s
 
 void test1(int n) { // expected-note {{here}}
-  int v[n]; // expected-warning {{variable length array}} expected-note {{parameter 'n'}}
+  int v[n]; /* expected-warning {{variable length array}} 
+               expected-note {{parameter 'n'}}
+               expected-warning {{variable length array that may require stack allocation used}}
+            */
 }
 
 void test2(int n, int v[n]) { // expected-warning {{variable length array}} expected-note {{parameter 'n'}} expected-note {{here}}
@@ -11,7 +14,10 @@
 
 template<typename T>
 void test4(int n) { // expected-note {{here}}
-  int v[n]; // expected-warning {{variable length array}} expected-note {{parameter 'n'}}
+  int v[n]; /* expected-warning {{variable length array}} 
+               expected-note {{parameter 'n'}}
+               expected-warning {{variable length array that may require stack allocation used}}
+            */
 }
 
 template<typename T>
Index: clang/test/Sema/warn-vla.c
===================================================================
--- clang/test/Sema/warn-vla.c
+++ clang/test/Sema/warn-vla.c
@@ -1,12 +1,59 @@
-// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify -Wvla %s
-// RUN: %clang_cc1 -std=c89 -fsyntax-only -verify -Wvla %s
+// RUN: %clang_cc1 -std=c89 -fsyntax-only -verify=expected,c89 -Wvla %s
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify=expected,c99 -Wvla %s
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify=expected,only-stack-allocation -Wvla-stack-alloc -Wno-vla-portability %s
 
 void test1(int n) {
-  int v[n]; // expected-warning {{variable length array}}
+  int v[n]; /* 
+    c89-warning {{variable length arrays are a C99 feature}}
+    c89-warning {{variable length array that may require stack allocation used}}
+    c99-warning {{variable length array used}}
+    c99-warning {{variable length array that may require stack allocation used}}
+    only-stack-allocation-warning {{variable length array that may require stack allocation used}}
+  */
 }
 
-void test2(int n, int v[n]) { // expected-warning {{variable length array}}
+void test2(int n, int v[n]) { /* 
+  c89-warning {{variable length arrays are a C99 feature}}
+  c99-warning {{variable length array used}}
+*/
 }
 
-void test3(int n, int v[n]); // expected-warning {{variable length array}}
+void test3(int n, int v[n]); /* 
+  c89-warning {{variable length arrays are a C99 feature}}
+  c99-warning {{variable length array used}}
+*/
 
+int test4_num;
+typedef int Test4[test4_num]; /* 
+  c89-warning {{variable length arrays are a C99 feature}} 
+  c99-warning {{variable length array used}}
+  expected-error {{variable length array declaration not allowed at file scope}}
+*/
+
+void func() {
+  typedef int test5[test4_num]; /* 
+    c89-warning {{variable length arrays are a C99 feature}} 
+    c99-warning {{variable length array used}} 
+  */
+
+  int test6[test4_num]; /*  
+    c89-warning {{variable length arrays are a C99 feature}}
+    c89-warning {{variable length array that may require stack allocation used}}
+    c99-warning {{variable length array used}}
+    c99-warning {{variable length array that may require stack allocation used}}
+    only-stack-allocation-warning {{variable length array that may require stack allocation used}}
+  */
+
+  // FIXME: warn twice
+  (void)sizeof(int[test4_num]); /* 
+    c89-warning {{variable length arrays are a C99 feature}}
+    c89-warning {{variable length arrays are a C99 feature}}
+    c99-warning {{variable length array used}}
+    c99-warning {{variable length array used}}
+  */
+
+  int (*test7)[test4_num]; /*
+    c89-warning {{variable length arrays are a C99 feature}}
+    c99-warning {{variable length array used}}
+  */
+}
Index: clang/test/Sema/cast.c
===================================================================
--- clang/test/Sema/cast.c
+++ clang/test/Sema/cast.c
@@ -2,7 +2,8 @@
 
 int array[(long)(char *)0]; // expected-warning {{variable length array used}} \
                             // expected-warning {{variable length array folded to constant array as an extension}} \
-                            // expected-note {{this conversion is not allowed in a constant expression}}
+                            // expected-note {{this conversion is not allowed in a constant expression}} \
+                            // expected-warning {{variable length array that may require stack allocation used}}
 
 typedef struct { unsigned long bits[(((1) + (64) - 1) / (64))]; } cpumask_t;
 cpumask_t x;
Index: clang/test/C/drs/dr3xx.c
===================================================================
--- clang/test/C/drs/dr3xx.c
+++ clang/test/C/drs/dr3xx.c
@@ -86,7 +86,9 @@
   /* Ensure that a constant array of variable-length arrays are still
    * considered a variable-length array.
    */
-  vla y[3]; /* expected-warning {{variable length array}} */
+  vla y[3]; /* expected-warning {{variable length array}} 
+               expected-warning {{variable length array that may require stack allocation used}}
+            */
 }
 
 /* WG14 DR313: yes
@@ -153,10 +155,14 @@
   typedef int type[dr320_v]; /* c89only-warning {{variable length arrays are a C99 feature}}
                                 c99andup-warning {{variable length array used}}
                               */
-  extern type bad;  /* expected-error {{variable length array declaration cannot have 'extern' linkage}} */
+  extern type bad;  /* expected-error {{variable length array declaration cannot have 'extern' linkage}} 
+                       expected-warning {{variable length array that may require stack allocation used}}
+                    */
 
   /* C99 6.7.5.2p2, second sentence. */
-  static type fine; /* expected-error {{variable length array declaration cannot have 'static' storage duration}} */
+  static type fine; /* expected-error {{variable length array declaration cannot have 'static' storage duration}} 
+                       expected-warning {{variable length array that may require stack allocation used}}
+                    */
 }
 
 /* WG14 DR321: yes
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -2538,7 +2538,7 @@
     VLADiag = diag::err_opencl_vla;
     VLAIsError = true;
   } else if (getLangOpts().C99) {
-    VLADiag = diag::warn_vla_used;
+    VLADiag = diag::warn_vla_portability;
     VLAIsError = false;
   } else if (isSFINAEContext()) {
     VLADiag = diag::err_vla_in_sfinae;
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -7477,6 +7477,9 @@
     }
   }
 
+  if (R->isVariableArrayType())
+    Diag(D.getIdentifierLoc(), diag::warn_vla_stack_alloc);
+
   // If this variable has a VLA type and an initializer, try to
   // fold to a constant-sized type. This is otherwise invalid.
   if (D.hasInitializer() && R->isVariableArrayType())
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -131,8 +131,10 @@
 // C99 variable-length arrays
 def ext_vla : Extension<"variable length arrays are a C99 feature">,
   InGroup<VLAExtension>;
-def warn_vla_used : Warning<"variable length array used">,
-  InGroup<VLA>, DefaultIgnore;
+def warn_vla_portability : Warning<"variable length array used">,
+  InGroup<VLAPortability>, DefaultIgnore;
+def warn_vla_stack_alloc : Warning<"variable length array that may require stack allocation used">,
+  InGroup<VLAStackAlloc>, DefaultIgnore;
 def err_vla_in_sfinae : Error<
   "variable length array cannot be formed during template argument deduction">;
 def err_array_star_in_function_definition : Error<
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -827,7 +827,9 @@
 def VectorConversion : DiagGroup<"vector-conversion">;      // clang specific
 def VexingParse : DiagGroup<"vexing-parse">;
 def VLAExtension : DiagGroup<"vla-extension">;
-def VLA : DiagGroup<"vla", [VLAExtension]>;
+def VLAPortability : DiagGroup<"vla-portability">;
+def VLAStackAlloc : DiagGroup<"vla-stack-alloc">;
+def VLA : DiagGroup<"vla", [VLAExtension, VLAPortability, VLAStackAlloc]>;
 def VolatileRegisterVar : DiagGroup<"volatile-register-var">;
 def Visibility : DiagGroup<"visibility">;
 def ZeroLengthArray : DiagGroup<"zero-length-array">;
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -425,6 +425,16 @@
   ``#pragma clang __debug sloc_usage`` can also be used to request this report.
 - Clang no longer permits the keyword 'bool' in a concept declaration as a
   concepts-ts compatibility extension.
+- Added ``-Wvla-stack-allocation`` to only give warnings about VLA that need 
+  stack allocation.
+
+  .. code-block:: C
+
+    void f(int n) {
+      int a[n]; // VLA that needs stack allocation
+    }
+
+    void g(int n, int a[n]) {} // VLA that don't need stack allocation
 
 Non-comprehensive list of changes in this release
 -------------------------------------------------
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to