-
Notifications
You must be signed in to change notification settings - Fork 15k
[clang][bytecode] Pass initializer along in evaluateAsInitializer()
#158056
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ChuanqiXu9 Is it okay to add this line?
|
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesWe just called Full diff: https://github.com/llvm/llvm-project/pull/158056.diff 9 Files Affected:
diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.h b/clang/lib/AST/ByteCode/ByteCodeEmitter.h
index d29db66325412..c050b299d8f61 100644
--- a/clang/lib/AST/ByteCode/ByteCodeEmitter.h
+++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.h
@@ -46,7 +46,8 @@ class ByteCodeEmitter {
/// Methods implemented by the compiler.
virtual bool visitFunc(const FunctionDecl *E) = 0;
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
- virtual bool visitDeclAndReturn(const VarDecl *E, bool ConstantContext) = 0;
+ virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
+ bool ConstantContext) = 0;
virtual bool visit(const Expr *E) = 0;
virtual bool emitBool(bool V, const Expr *E) = 0;
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 3f7db39281358..78b74acc3789d 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4714,7 +4714,8 @@ template <class Emitter>
VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
bool IsConstexprUnknown) {
- auto R = this->visitVarDecl(VD, /*Toplevel=*/true, IsConstexprUnknown);
+ auto R = this->visitVarDecl(VD, VD->getInit(), /*Toplevel=*/true,
+ IsConstexprUnknown);
if (R.notCreated())
return R;
@@ -4740,14 +4741,12 @@ VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
/// We get here from evaluateAsInitializer().
/// We need to evaluate the initializer and return its value.
template <class Emitter>
-bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
+bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
bool ConstantContext) {
-
// We only create variables if we're evaluating in a constant context.
// Otherwise, just evaluate the initializer and return it.
if (!ConstantContext) {
DeclScope<Emitter> LS(this, VD);
- const Expr *Init = VD->getInit();
if (!this->visit(Init))
return false;
return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
@@ -4755,7 +4754,7 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
}
LocalScope<Emitter> VDScope(this, VD);
- if (!this->visitVarDecl(VD, /*Toplevel=*/true))
+ if (!this->visitVarDecl(VD, Init, /*Toplevel=*/true))
return false;
OptPrimType VarT = classify(VD->getType());
@@ -4802,9 +4801,9 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
}
template <class Emitter>
-VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
- bool Toplevel,
- bool IsConstexprUnknown) {
+VarCreationState
+Compiler<Emitter>::visitVarDecl(const VarDecl *VD, const Expr *Init,
+ bool Toplevel, bool IsConstexprUnknown) {
// We don't know what to do with these, so just return false.
if (VD->getType().isNull())
return false;
@@ -4814,7 +4813,6 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
if (!this->isActive())
return VarCreationState::NotCreated();
- const Expr *Init = VD->getInit();
OptPrimType VarT = classify(VD->getType());
if (Init && Init->isValueDependent())
@@ -5488,7 +5486,8 @@ template <class Emitter>
bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
for (auto *BD : DD->flat_bindings())
- if (auto *KD = BD->getHoldingVar(); KD && !this->visitVarDecl(KD))
+ if (auto *KD = BD->getHoldingVar();
+ KD && !this->visitVarDecl(KD, KD->getInit()))
return false;
}
return true;
@@ -5552,7 +5551,7 @@ bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS,
const auto *VD = dyn_cast<VarDecl>(D);
if (!VD)
return false;
- if (!this->visitVarDecl(VD))
+ if (!this->visitVarDecl(VD, VD->getInit()))
return false;
// Register decomposition decl holding vars.
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index c97dc18656ce4..5f392964c076a 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -251,7 +251,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override;
bool visitFunc(const FunctionDecl *F) override;
- bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override;
+ bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
+ bool ConstantContext) override;
protected:
/// Emits scope cleanup instructions.
@@ -303,7 +304,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
/// intact.
bool delegate(const Expr *E);
/// Creates and initializes a variable from the given decl.
- VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel = false,
+ VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init,
+ bool Toplevel = false,
bool IsConstexprUnknown = false);
VarCreationState visitDecl(const VarDecl *VD,
bool IsConstexprUnknown = false);
diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp
index 8598996681466..de3191bfcff55 100644
--- a/clang/lib/AST/ByteCode/Context.cpp
+++ b/clang/lib/AST/ByteCode/Context.cpp
@@ -135,7 +135,7 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
bool CheckGlobalInitialized =
shouldBeGloballyIndexed(VD) &&
(VD->getType()->isRecordType() || VD->getType()->isArrayType());
- auto Res = C.interpretDecl(VD, CheckGlobalInitialized);
+ auto Res = C.interpretDecl(VD, Init, CheckGlobalInitialized);
if (Res.isInvalid()) {
C.cleanup();
Stk.clearTo(StackSizeBefore);
diff --git a/clang/lib/AST/ByteCode/Context.h b/clang/lib/AST/ByteCode/Context.h
index fa98498dbe8fa..280a31725555f 100644
--- a/clang/lib/AST/ByteCode/Context.h
+++ b/clang/lib/AST/ByteCode/Context.h
@@ -59,7 +59,8 @@ class Context final {
ConstantExprKind Kind);
/// Evaluates a toplevel initializer.
- bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result);
+ bool evaluateAsInitializer(State &Parent, const VarDecl *VD, const Expr *Init,
+ APValue &Result);
bool evaluateCharRange(State &Parent, const Expr *SizeExpr,
const Expr *PtrExpr, APValue &Result);
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index e349397078aa3..1d73f0e247aa2 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -49,14 +49,15 @@ EvaluationResult EvalEmitter::interpretExpr(const Expr *E,
return std::move(this->EvalResult);
}
-EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
+EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, const Expr *Init,
bool CheckFullyInitialized) {
this->CheckFullyInitialized = CheckFullyInitialized;
S.EvaluatingDecl = VD;
S.setEvalLocation(VD->getLocation());
EvalResult.setSource(VD);
- if (const Expr *Init = VD->getAnyInitializer()) {
+ // FIXME: I think Init is never null.
+ if (Init) {
QualType T = VD->getType();
this->ConvertResultToRValue = !Init->isGLValue() && !T->isPointerType() &&
!T->isObjCObjectPointerType();
@@ -65,7 +66,7 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
EvalResult.setSource(VD);
- if (!this->visitDeclAndReturn(VD, S.inConstantContext()))
+ if (!this->visitDeclAndReturn(VD, Init, S.inConstantContext()))
EvalResult.setInvalid();
S.EvaluatingDecl = nullptr;
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.h b/clang/lib/AST/ByteCode/EvalEmitter.h
index 85a0a99fbb4b0..e81ea67adf97a 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.h
+++ b/clang/lib/AST/ByteCode/EvalEmitter.h
@@ -37,7 +37,8 @@ class EvalEmitter : public SourceMapper {
EvaluationResult interpretExpr(const Expr *E,
bool ConvertResultToRValue = false,
bool DestroyToplevelScope = false);
- EvaluationResult interpretDecl(const VarDecl *VD, bool CheckFullyInitialized);
+ EvaluationResult interpretDecl(const VarDecl *VD, const Expr *Init,
+ bool CheckFullyInitialized);
/// Interpret the given Expr to a Pointer.
EvaluationResult interpretAsPointer(const Expr *E, PtrCallback PtrCB);
/// Interpret the given expression as if it was in the body of the given
@@ -59,7 +60,8 @@ class EvalEmitter : public SourceMapper {
/// Methods implemented by the compiler.
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
- virtual bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) = 0;
+ virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
+ bool ConstantContext) = 0;
virtual bool visitFunc(const FunctionDecl *F) = 0;
virtual bool visit(const Expr *E) = 0;
virtual bool emitBool(bool V, const Expr *E) = 0;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5145896930153..820b053057067 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -17755,7 +17755,7 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
if (Info.EnableNewConstInterp) {
auto &InterpCtx = const_cast<ASTContext &>(Ctx).getInterpContext();
- if (!InterpCtx.evaluateAsInitializer(Info, VD, Value))
+ if (!InterpCtx.evaluateAsInitializer(Info, VD, this, Value))
return false;
return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
diff --git a/clang/test/Modules/added-visible-decls.cppm b/clang/test/Modules/added-visible-decls.cppm
index 2f387db452905..28df3bf6f8543 100644
--- a/clang/test/Modules/added-visible-decls.cppm
+++ b/clang/test/Modules/added-visible-decls.cppm
@@ -5,6 +5,7 @@
// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-reduced-module-interface -o %t/b.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/c.cppm -emit-reduced-module-interface -o %t/c.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
+// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify -fexperimental-new-constant-interpreter
//--- a.h
template <typename T>
|
|
@llvm/pr-subscribers-clang-modules Author: Timm Baeder (tbaederr) ChangesWe just called Full diff: https://github.com/llvm/llvm-project/pull/158056.diff 9 Files Affected:
diff --git a/clang/lib/AST/ByteCode/ByteCodeEmitter.h b/clang/lib/AST/ByteCode/ByteCodeEmitter.h
index d29db66325412..c050b299d8f61 100644
--- a/clang/lib/AST/ByteCode/ByteCodeEmitter.h
+++ b/clang/lib/AST/ByteCode/ByteCodeEmitter.h
@@ -46,7 +46,8 @@ class ByteCodeEmitter {
/// Methods implemented by the compiler.
virtual bool visitFunc(const FunctionDecl *E) = 0;
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
- virtual bool visitDeclAndReturn(const VarDecl *E, bool ConstantContext) = 0;
+ virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
+ bool ConstantContext) = 0;
virtual bool visit(const Expr *E) = 0;
virtual bool emitBool(bool V, const Expr *E) = 0;
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 3f7db39281358..78b74acc3789d 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -4714,7 +4714,8 @@ template <class Emitter>
VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
bool IsConstexprUnknown) {
- auto R = this->visitVarDecl(VD, /*Toplevel=*/true, IsConstexprUnknown);
+ auto R = this->visitVarDecl(VD, VD->getInit(), /*Toplevel=*/true,
+ IsConstexprUnknown);
if (R.notCreated())
return R;
@@ -4740,14 +4741,12 @@ VarCreationState Compiler<Emitter>::visitDecl(const VarDecl *VD,
/// We get here from evaluateAsInitializer().
/// We need to evaluate the initializer and return its value.
template <class Emitter>
-bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
+bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
bool ConstantContext) {
-
// We only create variables if we're evaluating in a constant context.
// Otherwise, just evaluate the initializer and return it.
if (!ConstantContext) {
DeclScope<Emitter> LS(this, VD);
- const Expr *Init = VD->getInit();
if (!this->visit(Init))
return false;
return this->emitRet(classify(Init).value_or(PT_Ptr), VD) &&
@@ -4755,7 +4754,7 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
}
LocalScope<Emitter> VDScope(this, VD);
- if (!this->visitVarDecl(VD, /*Toplevel=*/true))
+ if (!this->visitVarDecl(VD, Init, /*Toplevel=*/true))
return false;
OptPrimType VarT = classify(VD->getType());
@@ -4802,9 +4801,9 @@ bool Compiler<Emitter>::visitDeclAndReturn(const VarDecl *VD,
}
template <class Emitter>
-VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
- bool Toplevel,
- bool IsConstexprUnknown) {
+VarCreationState
+Compiler<Emitter>::visitVarDecl(const VarDecl *VD, const Expr *Init,
+ bool Toplevel, bool IsConstexprUnknown) {
// We don't know what to do with these, so just return false.
if (VD->getType().isNull())
return false;
@@ -4814,7 +4813,6 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
if (!this->isActive())
return VarCreationState::NotCreated();
- const Expr *Init = VD->getInit();
OptPrimType VarT = classify(VD->getType());
if (Init && Init->isValueDependent())
@@ -5488,7 +5486,8 @@ template <class Emitter>
bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) {
if (auto *DD = dyn_cast_if_present<DecompositionDecl>(VD)) {
for (auto *BD : DD->flat_bindings())
- if (auto *KD = BD->getHoldingVar(); KD && !this->visitVarDecl(KD))
+ if (auto *KD = BD->getHoldingVar();
+ KD && !this->visitVarDecl(KD, KD->getInit()))
return false;
}
return true;
@@ -5552,7 +5551,7 @@ bool Compiler<Emitter>::visitDeclStmt(const DeclStmt *DS,
const auto *VD = dyn_cast<VarDecl>(D);
if (!VD)
return false;
- if (!this->visitVarDecl(VD))
+ if (!this->visitVarDecl(VD, VD->getInit()))
return false;
// Register decomposition decl holding vars.
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index c97dc18656ce4..5f392964c076a 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -251,7 +251,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool visitExpr(const Expr *E, bool DestroyToplevelScope) override;
bool visitFunc(const FunctionDecl *F) override;
- bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) override;
+ bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
+ bool ConstantContext) override;
protected:
/// Emits scope cleanup instructions.
@@ -303,7 +304,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
/// intact.
bool delegate(const Expr *E);
/// Creates and initializes a variable from the given decl.
- VarCreationState visitVarDecl(const VarDecl *VD, bool Toplevel = false,
+ VarCreationState visitVarDecl(const VarDecl *VD, const Expr *Init,
+ bool Toplevel = false,
bool IsConstexprUnknown = false);
VarCreationState visitDecl(const VarDecl *VD,
bool IsConstexprUnknown = false);
diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp
index 8598996681466..de3191bfcff55 100644
--- a/clang/lib/AST/ByteCode/Context.cpp
+++ b/clang/lib/AST/ByteCode/Context.cpp
@@ -135,7 +135,7 @@ bool Context::evaluateAsInitializer(State &Parent, const VarDecl *VD,
bool CheckGlobalInitialized =
shouldBeGloballyIndexed(VD) &&
(VD->getType()->isRecordType() || VD->getType()->isArrayType());
- auto Res = C.interpretDecl(VD, CheckGlobalInitialized);
+ auto Res = C.interpretDecl(VD, Init, CheckGlobalInitialized);
if (Res.isInvalid()) {
C.cleanup();
Stk.clearTo(StackSizeBefore);
diff --git a/clang/lib/AST/ByteCode/Context.h b/clang/lib/AST/ByteCode/Context.h
index fa98498dbe8fa..280a31725555f 100644
--- a/clang/lib/AST/ByteCode/Context.h
+++ b/clang/lib/AST/ByteCode/Context.h
@@ -59,7 +59,8 @@ class Context final {
ConstantExprKind Kind);
/// Evaluates a toplevel initializer.
- bool evaluateAsInitializer(State &Parent, const VarDecl *VD, APValue &Result);
+ bool evaluateAsInitializer(State &Parent, const VarDecl *VD, const Expr *Init,
+ APValue &Result);
bool evaluateCharRange(State &Parent, const Expr *SizeExpr,
const Expr *PtrExpr, APValue &Result);
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.cpp b/clang/lib/AST/ByteCode/EvalEmitter.cpp
index e349397078aa3..1d73f0e247aa2 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.cpp
+++ b/clang/lib/AST/ByteCode/EvalEmitter.cpp
@@ -49,14 +49,15 @@ EvaluationResult EvalEmitter::interpretExpr(const Expr *E,
return std::move(this->EvalResult);
}
-EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
+EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD, const Expr *Init,
bool CheckFullyInitialized) {
this->CheckFullyInitialized = CheckFullyInitialized;
S.EvaluatingDecl = VD;
S.setEvalLocation(VD->getLocation());
EvalResult.setSource(VD);
- if (const Expr *Init = VD->getAnyInitializer()) {
+ // FIXME: I think Init is never null.
+ if (Init) {
QualType T = VD->getType();
this->ConvertResultToRValue = !Init->isGLValue() && !T->isPointerType() &&
!T->isObjCObjectPointerType();
@@ -65,7 +66,7 @@ EvaluationResult EvalEmitter::interpretDecl(const VarDecl *VD,
EvalResult.setSource(VD);
- if (!this->visitDeclAndReturn(VD, S.inConstantContext()))
+ if (!this->visitDeclAndReturn(VD, Init, S.inConstantContext()))
EvalResult.setInvalid();
S.EvaluatingDecl = nullptr;
diff --git a/clang/lib/AST/ByteCode/EvalEmitter.h b/clang/lib/AST/ByteCode/EvalEmitter.h
index 85a0a99fbb4b0..e81ea67adf97a 100644
--- a/clang/lib/AST/ByteCode/EvalEmitter.h
+++ b/clang/lib/AST/ByteCode/EvalEmitter.h
@@ -37,7 +37,8 @@ class EvalEmitter : public SourceMapper {
EvaluationResult interpretExpr(const Expr *E,
bool ConvertResultToRValue = false,
bool DestroyToplevelScope = false);
- EvaluationResult interpretDecl(const VarDecl *VD, bool CheckFullyInitialized);
+ EvaluationResult interpretDecl(const VarDecl *VD, const Expr *Init,
+ bool CheckFullyInitialized);
/// Interpret the given Expr to a Pointer.
EvaluationResult interpretAsPointer(const Expr *E, PtrCallback PtrCB);
/// Interpret the given expression as if it was in the body of the given
@@ -59,7 +60,8 @@ class EvalEmitter : public SourceMapper {
/// Methods implemented by the compiler.
virtual bool visitExpr(const Expr *E, bool DestroyToplevelScope) = 0;
- virtual bool visitDeclAndReturn(const VarDecl *VD, bool ConstantContext) = 0;
+ virtual bool visitDeclAndReturn(const VarDecl *VD, const Expr *Init,
+ bool ConstantContext) = 0;
virtual bool visitFunc(const FunctionDecl *F) = 0;
virtual bool visit(const Expr *E) = 0;
virtual bool emitBool(bool V, const Expr *E) = 0;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5145896930153..820b053057067 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -17755,7 +17755,7 @@ bool Expr::EvaluateAsInitializer(APValue &Value, const ASTContext &Ctx,
if (Info.EnableNewConstInterp) {
auto &InterpCtx = const_cast<ASTContext &>(Ctx).getInterpContext();
- if (!InterpCtx.evaluateAsInitializer(Info, VD, Value))
+ if (!InterpCtx.evaluateAsInitializer(Info, VD, this, Value))
return false;
return CheckConstantExpression(Info, DeclLoc, DeclTy, Value,
diff --git a/clang/test/Modules/added-visible-decls.cppm b/clang/test/Modules/added-visible-decls.cppm
index 2f387db452905..28df3bf6f8543 100644
--- a/clang/test/Modules/added-visible-decls.cppm
+++ b/clang/test/Modules/added-visible-decls.cppm
@@ -5,6 +5,7 @@
// RUN: %clang_cc1 -std=c++20 %t/b.cppm -emit-reduced-module-interface -o %t/b.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/c.cppm -emit-reduced-module-interface -o %t/c.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
+// RUN: %clang_cc1 -std=c++20 %t/d.cpp -fprebuilt-module-path=%t -fsyntax-only -verify -fexperimental-new-constant-interpreter
//--- a.h
template <typename T>
|
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/51/builds/23452 Here is the relevant piece of the build log for the reference |
[clang][bytecode] Pass initializer along in `evaluateAsInitializer()` (llvm#158056) We just called `getInit()`, which isn't always correct and used the wrong initializer in the module test case.
|
|
||
| if (const Expr *Init = VD->getAnyInitializer()) { | ||
| // FIXME: I think Init is never null. | ||
| if (Init) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could add an assert and if it crashes, then this is incorrect, it does not prove it but it could show the negative and then you have a test case.
We just called
getInit(), which isn't always correct and used the wrong initializer in the module test case.