llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Bruno Cardoso Lopes (bcardosolopes)

<details>
<summary>Changes</summary>

emitStaticVarDecl bailed with errorNYI whenever a `static` local had a variably 
modified type -- in practice a pointer to a VLA, since the static itself can't 
be one. CIRGenFunction::emitVariablyModifiedType already exists and already 
handles this walk, so this is the same one-liner classic CodeGen uses in 
CodeGenFunction::EmitStaticVarDecl.

Found when building binutils. This is autoconf's AC_C_VARARRAYS probe, so the 
NYI was quietly changing what configure-based projects build: the probe failed 
under -fclangir, config.h came out with HAVE_C_VARARRAYS undefined and 
__STDC_NO_VLA__ defined, and gnulib took its non-VLA fallback paths. Nothing 
errored -- the CIR build just compiled different source than the baseline.

---
Full diff: https://github.com/llvm/llvm-project/pull/214926.diff


2 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenDecl.cpp (+2-4) 
- (added) clang/test/CIR/CodeGen/static-vla-pointer.c (+57) 


``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp 
b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index e17550a8c1668..d2fa07b3afa9a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -725,10 +725,8 @@ void CIRGenFunction::emitStaticVarDecl(const VarDecl &d,
   // We can't have a VLA here, but we can have a pointer to a VLA,
   // even though that doesn't really make any sense.
   // Make sure to evaluate VLA bounds now so that we have them for later.
-  if (d.getType()->isVariablyModifiedType()) {
-    cgm.errorNYI(d.getSourceRange(),
-                 "emitStaticVarDecl: variably modified type");
-  }
+  if (d.getType()->isVariablyModifiedType())
+    emitVariablyModifiedType(d.getType());
 
   // Save the type in case adding the initializer forces a type change.
   mlir::Type expectedType = addr.getType();
diff --git a/clang/test/CIR/CodeGen/static-vla-pointer.c 
b/clang/test/CIR/CodeGen/static-vla-pointer.c
new file mode 100644
index 0000000000000..1342d46ffcade
--- /dev/null
+++ b/clang/test/CIR/CodeGen/static-vla-pointer.c
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -Wno-error=incompatible-pointer-types -triple 
x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -Wno-error=incompatible-pointer-types -triple 
x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -Wno-error=incompatible-pointer-types -triple 
x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+// A `static` local can't be a VLA, but it can have a variably modified type --
+// a pointer to a VLA. The variable itself is an ordinary global; the VLA bound
+// still has to be evaluated in the enclosing function, for its side effects.
+
+int bound(void);
+int buf[100];
+
+// The two static locals are ordinary globals initialized to &buf. Both
+// functions emit their globals into the same module prologue, so check them
+// together and out of order.
+
+// CIR-DAG: cir.global "private" internal dso_local @side_effecting_bound.p = 
#cir.global_view<@buf> : !cir.ptr<!s32i>
+// CIR-DAG: cir.global "private" internal dso_local @vararrays_probe.q = 
#cir.global_view<@buf> : !cir.ptr<!s32i>
+
+// LLVM-DAG: @side_effecting_bound.p = internal global ptr @buf
+// LLVM-DAG: @vararrays_probe.q = internal global ptr @buf
+
+// OGCG-DAG: @side_effecting_bound.p = internal global ptr @buf
+// OGCG-DAG: @vararrays_probe.q = internal global ptr @buf
+
+void side_effecting_bound(void) {
+  static int (*p)[bound()] = &buf;
+  (void)p;
+}
+
+// CIR-LABEL: cir.func{{.*}} @side_effecting_bound()
+// CIR:         cir.call @bound() : () -> !s32i
+
+// LLVM-LABEL: define {{.*}} void @side_effecting_bound()
+// LLVM:         call i32 @bound()
+
+// OGCG-LABEL: define {{.*}} void @side_effecting_bound()
+// OGCG:         call i32 @bound()
+
+// This is autoconf's AC_C_VARARRAYS probe. It mainly has to compile at all; a
+// failure here silently flips HAVE_C_VARARRAYS in every configure-based 
project.
+
+int vararrays_probe(int m, int c[m][m]) {
+  static int (*q)[m] = &buf;
+  return c && q != 0;
+}
+
+// CIR-LABEL: cir.func{{.*}} @vararrays_probe(
+// CIR:         cir.get_global @vararrays_probe.q : !cir.ptr<!cir.ptr<!s32i>>
+
+// LLVM-LABEL: define {{.*}} i32 @vararrays_probe(
+// LLVM:         load ptr, ptr @vararrays_probe.q
+
+// OGCG-LABEL: define {{.*}} i32 @vararrays_probe(
+// OGCG:         load ptr, ptr @vararrays_probe.q

``````````

</details>


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

Reply via email to