[clang] [clang][bytecode][NFC] Move some opcode impls to the source file (PR #177543)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 23 00:10:24 PST 2026
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/177543
They aren't templated, so move them to Interp.cpp to make the header file a bit shorter.
>From 56e0586dbb6f6ae82f4b69a9176430e4ae37bde9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Fri, 23 Jan 2026 09:03:51 +0100
Subject: [PATCH] [clang][bytecode][NFC] Move some opcode impls to the source
file
They aren't templated, so move them to Interp.cpp to make the header
file a bit shorter.
---
clang/lib/AST/ByteCode/Interp.cpp | 96 +++++++++++++++++++++++++++
clang/lib/AST/ByteCode/Interp.h | 104 ++----------------------------
2 files changed, 102 insertions(+), 98 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 49c23e59cb0e0..8e5e382414c00 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1196,6 +1196,21 @@ bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR) {
return diagnoseUnknownDecl(S, OpPC, D);
}
+bool InvalidDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR,
+ bool InitializerFailed) {
+ assert(DR);
+
+ if (InitializerFailed) {
+ const SourceInfo &Loc = S.Current->getSource(OpPC);
+ const auto *VD = cast<VarDecl>(DR->getDecl());
+ S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
+ S.Note(VD->getLocation(), diag::note_declared_at);
+ return false;
+ }
+
+ return CheckDeclRef(S, OpPC, DR);
+}
+
bool CheckDummy(InterpState &S, CodePtr OpPC, const Block *B, AccessKinds AK) {
if (!B->isDummy())
return true;
@@ -1557,6 +1572,52 @@ bool CheckFunctionDecl(InterpState &S, CodePtr OpPC, const FunctionDecl *FD) {
return diagnoseCallableDecl(S, OpPC, FD);
}
+bool CheckBitCast(InterpState &S, CodePtr OpPC, const Type *TargetType,
+ bool SrcIsVoidPtr) {
+ const auto &Ptr = S.Stk.peek<Pointer>();
+ if (Ptr.isZero())
+ return true;
+ if (!Ptr.isBlockPointer())
+ return true;
+
+ if (TargetType->isIntegerType())
+ return true;
+
+ if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) {
+ bool HasValidResult = !Ptr.isZero();
+
+ if (HasValidResult) {
+ if (S.getStdAllocatorCaller("allocate"))
+ return true;
+
+ const auto &E = cast<CastExpr>(S.Current->getExpr(OpPC));
+ if (S.getLangOpts().CPlusPlus26 &&
+ S.getASTContext().hasSimilarType(Ptr.getType(),
+ QualType(TargetType, 0)))
+ return true;
+
+ S.CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
+ << E->getSubExpr()->getType() << S.getLangOpts().CPlusPlus26
+ << Ptr.getType().getCanonicalType() << E->getType()->getPointeeType();
+ } else if (!S.getLangOpts().CPlusPlus26) {
+ const SourceInfo &E = S.Current->getSource(OpPC);
+ S.CCEDiag(E, diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::CastFrom << "'void *'"
+ << S.Current->getRange(OpPC);
+ }
+ }
+
+ QualType PtrType = Ptr.getType();
+ if (PtrType->isRecordType() &&
+ PtrType->getAsRecordDecl() != TargetType->getAsRecordDecl()) {
+ S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
+ << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
+ return false;
+ }
+ return true;
+}
+
static void compileFunction(InterpState &S, const Function *Func) {
const FunctionDecl *Definition = Func->getDecl()->getDefinition();
if (!Definition)
@@ -2361,6 +2422,41 @@ bool FinishInitGlobal(InterpState &S, CodePtr OpPC) {
return true;
}
+bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind, bool Fatal) {
+ const SourceLocation &Loc = S.Current->getLocation(OpPC);
+
+ switch (Kind) {
+ case CastKind::Reinterpret:
+ S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::Reinterpret
+ << S.Current->getRange(OpPC);
+ return !Fatal;
+ case CastKind::ReinterpretLike:
+ S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
+ << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
+ return !Fatal;
+ case CastKind::Volatile:
+ if (!S.checkingPotentialConstantExpression()) {
+ const auto *E = cast<CastExpr>(S.Current->getExpr(OpPC));
+ if (S.getLangOpts().CPlusPlus)
+ S.FFDiag(E, diag::note_constexpr_access_volatile_type)
+ << AK_Read << E->getSubExpr()->getType();
+ else
+ S.FFDiag(E);
+ }
+
+ return false;
+ case CastKind::Dynamic:
+ assert(!S.getLangOpts().CPlusPlus20);
+ S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::Dynamic;
+ return true;
+ }
+ llvm_unreachable("Unhandled CastKind");
+ return false;
+}
+
bool Destroy(InterpState &S, CodePtr OpPC, uint32_t I) {
assert(S.Current->getFunction());
// FIXME: We iterate the scope once here and then again in the destroy() call
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 92e8266aa172b..f6b7d96e6a192 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -118,6 +118,9 @@ bool CheckBitCast(InterpState &S, CodePtr OpPC, bool HasIndeterminateBits,
bool CheckBCPResult(InterpState &S, const Pointer &Ptr);
bool CheckDestructor(InterpState &S, CodePtr OpPC, const Pointer &Ptr);
bool CheckFunctionDecl(InterpState &S, CodePtr OpPC, const FunctionDecl *FD);
+bool CheckBitCast(InterpState &S, CodePtr OpPC, const Type *TargetType,
+ bool SrcIsVoidPtr);
+bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind, bool Fatal);
bool handleFixedPointOverflow(InterpState &S, CodePtr OpPC,
const FixedPoint &FP);
@@ -211,6 +214,8 @@ bool CheckFloatResult(InterpState &S, CodePtr OpPC, const Floating &Result,
/// Checks why the given DeclRefExpr is invalid.
bool CheckDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR);
+bool InvalidDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR,
+ bool InitializerFailed);
enum class ArithOp { Add, Sub };
@@ -3271,6 +3276,7 @@ inline bool StartSpeculation(InterpState &S, CodePtr OpPC) {
S.getEvalStatus().Diag = nullptr;
return true;
}
+
inline bool EndSpeculation(InterpState &S, CodePtr OpPC) {
assert(S.SpeculationDepth != 0);
--S.SpeculationDepth;
@@ -3307,89 +3313,6 @@ inline bool CtorCheck(InterpState &S, CodePtr OpPC) {
return true;
}
-inline bool CheckBitCast(InterpState &S, CodePtr OpPC, const Type *TargetType,
- bool SrcIsVoidPtr) {
- const auto &Ptr = S.Stk.peek<Pointer>();
- if (Ptr.isZero())
- return true;
- if (!Ptr.isBlockPointer())
- return true;
-
- if (TargetType->isIntegerType())
- return true;
-
- if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) {
- bool HasValidResult = !Ptr.isZero();
-
- if (HasValidResult) {
- if (S.getStdAllocatorCaller("allocate"))
- return true;
-
- const auto &E = cast<CastExpr>(S.Current->getExpr(OpPC));
- if (S.getLangOpts().CPlusPlus26 &&
- S.getASTContext().hasSimilarType(Ptr.getType(),
- QualType(TargetType, 0)))
- return true;
-
- S.CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
- << E->getSubExpr()->getType() << S.getLangOpts().CPlusPlus26
- << Ptr.getType().getCanonicalType() << E->getType()->getPointeeType();
- } else if (!S.getLangOpts().CPlusPlus26) {
- const SourceInfo &E = S.Current->getSource(OpPC);
- S.CCEDiag(E, diag::note_constexpr_invalid_cast)
- << diag::ConstexprInvalidCastKind::CastFrom << "'void *'"
- << S.Current->getRange(OpPC);
- }
- }
-
- QualType PtrType = Ptr.getType();
- if (PtrType->isRecordType() &&
- PtrType->getAsRecordDecl() != TargetType->getAsRecordDecl()) {
- S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_cast)
- << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
- << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
- return false;
- }
- return true;
-}
-
-/// Same here, but only for casts.
-inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind,
- bool Fatal) {
- const SourceLocation &Loc = S.Current->getLocation(OpPC);
-
- switch (Kind) {
- case CastKind::Reinterpret:
- S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)
- << diag::ConstexprInvalidCastKind::Reinterpret
- << S.Current->getRange(OpPC);
- return !Fatal;
- case CastKind::ReinterpretLike:
- S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)
- << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
- << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
- return !Fatal;
- case CastKind::Volatile:
- if (!S.checkingPotentialConstantExpression()) {
- const auto *E = cast<CastExpr>(S.Current->getExpr(OpPC));
- if (S.getLangOpts().CPlusPlus)
- S.FFDiag(E, diag::note_constexpr_access_volatile_type)
- << AK_Read << E->getSubExpr()->getType();
- else
- S.FFDiag(E);
- }
-
- return false;
- case CastKind::Dynamic:
- assert(!S.getLangOpts().CPlusPlus20);
- S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)
- << diag::ConstexprInvalidCastKind::Dynamic;
- return true;
- }
- llvm_unreachable("Unhandled CastKind");
- return false;
-}
-
inline bool InvalidStore(InterpState &S, CodePtr OpPC, const Type *T) {
if (S.getLangOpts().CPlusPlus) {
QualType VolatileType = QualType(T, 0).withVolatile();
@@ -3402,21 +3325,6 @@ inline bool InvalidStore(InterpState &S, CodePtr OpPC, const Type *T) {
return false;
}
-inline bool InvalidDeclRef(InterpState &S, CodePtr OpPC, const DeclRefExpr *DR,
- bool InitializerFailed) {
- assert(DR);
-
- if (InitializerFailed) {
- const SourceInfo &Loc = S.Current->getSource(OpPC);
- const auto *VD = cast<VarDecl>(DR->getDecl());
- S.FFDiag(Loc, diag::note_constexpr_var_init_non_constant, 1) << VD;
- S.Note(VD->getLocation(), diag::note_declared_at);
- return false;
- }
-
- return CheckDeclRef(S, OpPC, DR);
-}
-
inline bool SizelessVectorElementSize(InterpState &S, CodePtr OpPC) {
if (S.inConstantContext()) {
const SourceRange &ArgRange = S.Current->getRange(OpPC);
More information about the cfe-commits
mailing list