[clang] a0e42c2 - [clang][bytecode] Add new IntegralType for function addresses (#194206)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 25 23:29:19 PDT 2026
Author: Timm Baeder
Date: 2026-04-26T08:29:14+02:00
New Revision: a0e42c2c47080af4c31c43b801b55e8fa7c68db4
URL: https://github.com/llvm/llvm-project/commit/a0e42c2c47080af4c31c43b801b55e8fa7c68db4
DIFF: https://github.com/llvm/llvm-project/commit/a0e42c2c47080af4c31c43b801b55e8fa7c68db4.diff
LOG: [clang][bytecode] Add new IntegralType for function addresses (#194206)
We used to use just `::Address` for functions, which later caused
problems because we casted the pointer to `ValueDecl*` and passed it to
`Program::getOrCreateGlobal()`, which doesn't work of course.
Added:
Modified:
clang/lib/AST/ByteCode/Integral.h
clang/lib/AST/ByteCode/Interp.h
clang/lib/AST/ByteCode/Primitives.h
clang/test/AST/ByteCode/functions.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Integral.h b/clang/lib/AST/ByteCode/Integral.h
index 2cfc2ffa96d1f..170bc8f8f12dd 100644
--- a/clang/lib/AST/ByteCode/Integral.h
+++ b/clang/lib/AST/ByteCode/Integral.h
@@ -218,6 +218,11 @@ template <unsigned Bits, bool Signed> class Integral final {
return APValue(D->asValueDecl(), CharUnits::Zero(),
APValue::NoLValuePath{});
}
+ case IntegralKind::FunctionAddress: {
+ return APValue((const FunctionDecl *)Ptr.P,
+ CharUnits::fromQuantity(Ptr.Offset),
+ APValue::NoLValuePath{});
+ }
case IntegralKind::AddrLabelDiff: {
return APValue(AddrLabelDiff.L1, AddrLabelDiff.L2);
}
@@ -300,6 +305,9 @@ template <unsigned Bits, bool Signed> class Integral final {
break;
case IntegralKind::LabelAddress:
OS << Ptr.P << " + " << Ptr.Offset << " (LabelAddress)";
+ break;
+ case IntegralKind::FunctionAddress:
+ OS << Ptr.P << " + " << Ptr.Offset << " (FunctionAddress)";
}
}
@@ -327,6 +335,7 @@ template <unsigned Bits, bool Signed> class Integral final {
case IntegralKind::Address:
case IntegralKind::BlockAddress:
case IntegralKind::LabelAddress:
+ case IntegralKind::FunctionAddress:
return Integral(V.getKind(), V.getPtr(), V.getOffset());
}
llvm_unreachable("Unhandled IntegralKind");
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 87ee350e9c5b7..b9d69f5be3c00 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2920,7 +2920,7 @@ bool CastPointerIntegral(InterpState &S, CodePtr OpPC) {
S.Stk.push<T>(Kind, PtrVal, /*Offset=*/0);
} else if (Ptr.isFunctionPointer()) {
const void *FuncDecl = Ptr.asFunctionPointer().Func->getDecl();
- S.Stk.push<T>(IntegralKind::Address, FuncDecl, /*Offset=*/0);
+ S.Stk.push<T>(IntegralKind::FunctionAddress, FuncDecl, /*Offset=*/0);
} else {
S.Stk.push<T>(T::from(Ptr.getIntegerRepresentation()));
}
@@ -3514,6 +3514,10 @@ inline bool GetIntPtr(InterpState &S, CodePtr OpPC, const Descriptor *Desc) {
const Block *B = (const Block *)IntVal.getPtr();
S.Stk.push<Pointer>(const_cast<Block *>(B));
+ } else if (IntVal.getKind() == IntegralKind::FunctionAddress) {
+ const Function *F =
+ S.P.getFunction((const FunctionDecl *)IntVal.getPtr());
+ S.Stk.push<Pointer>(F, IntVal.getOffset());
} else {
S.Stk.push<Pointer>(static_cast<uint64_t>(IntVal), Desc);
}
diff --git a/clang/lib/AST/ByteCode/Primitives.h b/clang/lib/AST/ByteCode/Primitives.h
index 0d9015ff5b200..e2d3dacea5726 100644
--- a/clang/lib/AST/ByteCode/Primitives.h
+++ b/clang/lib/AST/ByteCode/Primitives.h
@@ -30,6 +30,8 @@ enum class IntegralKind : uint8_t {
BlockAddress,
/// A pointer to a AddrLabelExpr.
LabelAddress,
+ /// A pointer to a FunctionDecl.
+ FunctionAddress,
/// Difference between two AddrLabelExpr.
AddrLabelDiff
};
diff --git a/clang/test/AST/ByteCode/functions.cpp b/clang/test/AST/ByteCode/functions.cpp
index 05dea564baec7..eacb43b4806a9 100644
--- a/clang/test/AST/ByteCode/functions.cpp
+++ b/clang/test/AST/ByteCode/functions.cpp
@@ -774,3 +774,12 @@ namespace DependentReturnType {
S<float> x;
}
#endif
+
+namespace FuncToIntRoundtrip {
+ void f() {}
+ constexpr int foo() { // both-error {{constexpr function never produces a constant expression}}
+ auto p = (void*)(__UINTPTR_TYPE__)f; // both-note {{cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression}}
+ return 1;
+ }
+ auto a = foo();
+}
More information about the cfe-commits
mailing list