[clang] [clang][CodeGen] Fix a crash when calling some builtin functions on AVR (PR #222922)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 11 04:08:59 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Ben Shi (benshi001)
<details>
<summary>Changes</summary>
The argument of `__builtin_frame_address` and `__builtin_return_address` should always
be `uint32_t`. But on some targets such as AVR and MSP430, `unsigned int` is `uint16_t`.
fixes https://github.com/llvm/llvm-project/issues/222910
---
Full diff: https://github.com/llvm/llvm-project/pull/222922.diff
2 Files Affected:
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+4-4)
- (added) clang/test/CodeGen/avr/builtin-frame-return-address.c (+22)
``````````diff
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 1e65a6a30c35e..d40292fd656a2 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -5139,8 +5139,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
llvm::ConstantInt::get(Int32Ty, Offset)));
}
case Builtin::BI__builtin_return_address: {
- Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
- getContext().UnsignedIntTy);
+ Value *Depth = ConstantEmitter(*this).emitAbstract(
+ E->getArg(0), getContext().getIntTypeForBitwidth(32, 0));
Function *F =
CGM.getIntrinsic(Intrinsic::returnaddress, {CGM.ProgramPtrTy});
return RValue::get(Builder.CreateCall(F, Depth));
@@ -5151,8 +5151,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
return RValue::get(Builder.CreateCall(F, Builder.getInt32(0)));
}
case Builtin::BI__builtin_frame_address: {
- Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
- getContext().UnsignedIntTy);
+ Value *Depth = ConstantEmitter(*this).emitAbstract(
+ E->getArg(0), getContext().getIntTypeForBitwidth(32, 0));
Function *F = CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy);
return RValue::get(Builder.CreateCall(F, Depth));
}
diff --git a/clang/test/CodeGen/avr/builtin-frame-return-address.c b/clang/test/CodeGen/avr/builtin-frame-return-address.c
new file mode 100644
index 0000000000000..7736f9b04682d
--- /dev/null
+++ b/clang/test/CodeGen/avr/builtin-frame-return-address.c
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple avr-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// The depth argument of llvm.frameaddress and llvm.returnaddress is always a
+// 32-bit integer. It used to be emitted with the type of 'unsigned int', which
+// is only 16 bits wide on AVR, producing an intrinsic call with a bad
+// signature and crashing clang.
+
+// CHECK-LABEL: define{{.*}} ptr @frame_address_zero(
+// CHECK: call{{.*}}@llvm.frameaddress.p0(i32 0)
+void *frame_address_zero(void) { return __builtin_frame_address(0); }
+
+// CHECK-LABEL: define{{.*}} ptr @return_address_zero(
+// CHECK: call{{.*}}@llvm.returnaddress.p1(i32 0)
+void *return_address_zero(void) { return __builtin_return_address(0); }
+
+// CHECK-LABEL: define{{.*}} ptr @frame_address_depth(
+// CHECK: call{{.*}}@llvm.frameaddress.p0(i32 2)
+void *frame_address_depth(void) { return __builtin_frame_address(2); }
+
+// CHECK-LABEL: define{{.*}} ptr @return_address_depth(
+// CHECK: call{{.*}}@llvm.returnaddress.p1(i32 2)
+void *return_address_depth(void) { return __builtin_return_address(2); }
``````````
</details>
https://github.com/llvm/llvm-project/pull/222922
More information about the cfe-commits
mailing list