[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