https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/142793
Rename isConstexpr to isValid, the former was always a bad name. Save a constexpr bit in Function so we don't have to access the decl in CheckCallable. >From f5dbb8228c19e5dd95bd4da65fe4c6f394df32c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Wed, 4 Jun 2025 14:32:39 +0200 Subject: [PATCH] [clang][bytecode] Save Constexpr bit in Function Rename isConstexpr to isValid, the former was always a bad name. Save a constexpr bit in Function so we don't have to access the decl in CheckCallable. --- clang/lib/AST/ByteCode/Context.cpp | 2 +- clang/lib/AST/ByteCode/Function.cpp | 2 ++ clang/lib/AST/ByteCode/Function.h | 7 +++++-- clang/lib/AST/ByteCode/Interp.cpp | 18 +++++++++--------- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp index d73705b6126fe..971eb7fd58876 100644 --- a/clang/lib/AST/ByteCode/Context.cpp +++ b/clang/lib/AST/ByteCode/Context.cpp @@ -49,7 +49,7 @@ bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { if (!Run(Parent, Func)) return false; - return Func->isConstexpr(); + return Func->isValid(); } bool Context::evaluateAsRValue(State &Parent, const Expr *E, APValue &Result) { diff --git a/clang/lib/AST/ByteCode/Function.cpp b/clang/lib/AST/ByteCode/Function.cpp index e421dad062817..9eb6744ea47ad 100644 --- a/clang/lib/AST/ByteCode/Function.cpp +++ b/clang/lib/AST/ByteCode/Function.cpp @@ -27,6 +27,7 @@ Function::Function(Program &P, FunctionDeclTy Source, unsigned ArgSize, if (const auto *F = dyn_cast<const FunctionDecl *>(Source)) { Variadic = F->isVariadic(); Immediate = F->isImmediateFunction(); + Constexpr = F->isConstexpr() || F->hasAttr<MSConstexprAttr>(); if (const auto *CD = dyn_cast<CXXConstructorDecl>(F)) { Virtual = CD->isVirtual(); Kind = FunctionKind::Ctor; @@ -48,6 +49,7 @@ Function::Function(Program &P, FunctionDeclTy Source, unsigned ArgSize, Variadic = false; Virtual = false; Immediate = false; + Constexpr = false; } } diff --git a/clang/lib/AST/ByteCode/Function.h b/clang/lib/AST/ByteCode/Function.h index 8b577858474af..de88f3ded34dc 100644 --- a/clang/lib/AST/ByteCode/Function.h +++ b/clang/lib/AST/ByteCode/Function.h @@ -150,12 +150,13 @@ class Function final { /// Returns the source information at a given PC. SourceInfo getSource(CodePtr PC) const; - /// Checks if the function is valid to call in constexpr. - bool isConstexpr() const { return IsValid || isLambdaStaticInvoker(); } + /// Checks if the function is valid to call. + bool isValid() const { return IsValid || isLambdaStaticInvoker(); } /// Checks if the function is virtual. bool isVirtual() const { return Virtual; }; bool isImmediate() const { return Immediate; } + bool isConstexpr() const { return Constexpr; } /// Checks if the function is a constructor. bool isConstructor() const { return Kind == FunctionKind::Ctor; } @@ -303,6 +304,8 @@ class Function final { unsigned Virtual : 1; LLVM_PREFERRED_TYPE(bool) unsigned Immediate : 1; + LLVM_PREFERRED_TYPE(bool) + unsigned Constexpr : 1; public: /// Dumps the disassembled bytecode to \c llvm::errs(). diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index db91e5e328485..5c8abffb3a99d 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -857,23 +857,22 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { return false; } - // Bail out if the function declaration itself is invalid. We will - // have produced a relevant diagnostic while parsing it, so just - // note the problematic sub-expression. - if (F->getDecl()->isInvalidDecl()) - return Invalid(S, OpPC); - if (S.checkingPotentialConstantExpression() && S.Current->getDepth() != 0) return false; - if (F->isConstexpr() && F->hasBody() && - (F->getDecl()->isConstexpr() || F->getDecl()->hasAttr<MSConstexprAttr>())) + if (F->isValid() && F->hasBody() && F->isConstexpr()) return true; // Implicitly constexpr. if (F->isLambdaStaticInvoker()) return true; + // Bail out if the function declaration itself is invalid. We will + // have produced a relevant diagnostic while parsing it, so just + // note the problematic sub-expression. + if (F->getDecl()->isInvalidDecl()) + return Invalid(S, OpPC); + // Diagnose failed assertions specially. if (S.Current->getLocation(OpPC).isMacroID() && F->getDecl()->getIdentifier()) { @@ -923,7 +922,8 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { // for a constant expression. It might be defined at the point we're // actually calling it. bool IsExtern = DiagDecl->getStorageClass() == SC_Extern; - if (!DiagDecl->isDefined() && !IsExtern && DiagDecl->isConstexpr() && + bool IsDefined = F->isDefined(); + if (!IsDefined && !IsExtern && DiagDecl->isConstexpr() && S.checkingPotentialConstantExpression()) return false; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits