================
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -w -fclangir -emit-cir %s
-o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+// Because LLVM IR uses opaque pointers, nothing in this test would be worth
+// checking there, so LLVM and OGCG checks are omitted.
+
+// Exercise replacing a no-prototype declaration with a prototyped definition
+// when a global struct initializer already took the address of that function.
+// The initializer must use the struct field's function-pointer type (not the
+// FuncOp's no-prototype type) so CIR stays valid after the replacement.
+
+// CHECK: !{{[^ ]+}} = !cir.record<struct "S1" {!cir.ptr<!cir.func<()>>,
!s32i, !s32i}>
+// CHECK: !{{[^ ]+}} = !cir.record<struct "S2" {!cir.ptr<!cir.func<(...)>>,
!s32i, !s32i}>
----------------
andykaylor wrote:
I'm really not sure in this case. I tried to find something in the standard to
say how a non-prototype function type in a structure is supposed to be handled.
In the case of a function declaration without a prototype, we use `(....)` as a
placeholder for the parameters and it gets replaced when we see the function
definition. When the non-prototype declaration is a pointer in a structure,
there's really no function definition to resolve what it is.
Clang tells me that the structure definition for S2, S3, and S4 is deprecated
in all versions of C, but it will let me assign pointers with different sets of
parameters to this pointer (unless I use `-std=c23`, in which case this is
treated as `(*f)(void)`. GCC always treats it as `(*f)(void)`.
https://godbolt.org/z/rGMM6xezr
https://github.com/llvm/llvm-project/pull/189741
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits