[clang] [CIR] Handle FunctionToPointerDecay casts (#153657) (PR #154060)
Justin Riddell via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 18 20:10:22 PDT 2025
================
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s
----------------
Arghnews wrote:
If I change the test file to:
```c
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
void f(void);
void test_call_lvalue_cast() {
(void (*)())f; // Works
(*(void (*)(void))f)(); // Works
(*(void (*)(int))f)(42); // Fails with -fclangir -emit-llvm
}
```
Then it crashes when running `-fclangir -emit-llvm` with `(*(void (*)(int))f)(42);`, top of the crash:
```
dialect-conversion] Legalizing operation : 'cir.call' (0x6480afdaa150) {
[dialect-conversion] "cir.call"(%5, %7) <{side_effect = 0 : i32}> : (!cir.ptr<!cir.func<(!cir.int<s, 32>)>>, !cir.int<s, 32>) -> ()
[dialect-conversion] * Fold {
[dialect-conversion] } -> FAILURE : unable to fold
[dialect-conversion]
[dialect-conversion] * Pattern : 'cir.call -> ()' {
!cir.func<(!cir.int<s, 32>)>
```
> clang: /home/justin/code/llvm-project/mlir/lib/Dialect/LLVMIR/IR/LLVMTypes.cpp:219: static LLVMFunctionType mlir::LLVM::LLVMFunctionType::get(Type, ArrayRef<Type>, bool): Assertion `result && "expected non-null result"' failed.
Have attached the full stack with some debugging turned on - I'm not sure if there's better options, I was just exploring:
[crash.txt](https://github.com/user-attachments/files/21847423/crash.txt)
Is this a bug that hasn't been implemented yet etc.?
What should be done about it?
The [original clangir test](https://github.com/llvm/clangir/blob/main/clang/test/CIR/CodeGen/function-to-pointer-decay.c) only contains:
```c
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s
void f(void);
void test_call_lvalue_cast() {
(*(void (*)(int))f)(42);
}
```
Although if I run this test on clangir with `-fclangir -emit-llvm`, it doesn't crash, and outputs:
```ll
declare void @f()
; Function Attrs: noinline nounwind optnone
define dso_local void @test_call_lvalue_cast() #0 {
call void @f()
call void @f(i32 42)
ret void
}
```
I'm happy to try and fix it if I can be given some pointers as to how/what/where, if that's within the scope of this PR. Or another etc. Or maybe I messed up something on the way.
On a C level, what is the expected behaviour when you cast a function pointer declared as taking no parameters `void f(void)` to one taking one `int` param and call it? [gcc warns](https://godbolt.org/z/6cxo7nqcf)
Let me know what to do on this
https://github.com/llvm/llvm-project/pull/154060
More information about the cfe-commits
mailing list