Skip to content

[clang][bytecode] Save Constexpr bit in Function #142793

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/lib/AST/ByteCode/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/AST/ByteCode/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -48,6 +49,7 @@ Function::Function(Program &P, FunctionDeclTy Source, unsigned ArgSize,
Variadic = false;
Virtual = false;
Immediate = false;
Constexpr = false;
}
}

Expand Down
7 changes: 5 additions & 2 deletions clang/lib/AST/ByteCode/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -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().
Expand Down
18 changes: 9 additions & 9 deletions clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down Expand Up @@ -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;

Expand Down
Loading