Skip to content

[clang] Use new interpreter in EvaluateAsConstantExpr if requested #70763

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
Nov 15, 2023

Conversation

tbaederr
Copy link
Contributor

EvaluateAsConstantExpr() uses ::EvaluateInPlace() directly, which does not use the new interpreter if requested. Do it here, which is the same pattern we use in EvaluateAsInitializer.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Oct 31, 2023
@llvmbot
Copy link
Member

llvmbot commented Oct 31, 2023

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

EvaluateAsConstantExpr() uses ::EvaluateInPlace() directly, which does not use the new interpreter if requested. Do it here, which is the same pattern we use in EvaluateAsInitializer.


Full diff: https://github.com/llvm/llvm-project/pull/70763.diff

3 Files Affected:

  • (modified) clang/lib/AST/ExprConstant.cpp (+9-7)
  • (modified) clang/lib/AST/Interp/ByteCodeExprGen.h (+7-1)
  • (modified) clang/test/AST/Interp/literals.cpp (+1-3)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 5947805f9576ff8..2a8b81c12555e94 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15561,12 +15561,14 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
   // this doesn't escape.
   MaterializeTemporaryExpr BaseMTE(T, const_cast<Expr*>(this), true);
   APValue::LValueBase Base(&BaseMTE);
-
   Info.setEvaluatingDecl(Base, Result.Val);
-  LValue LVal;
-  LVal.set(Base);
 
-  {
+  if (Info.EnableNewConstInterp) {
+    if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, this, Result.Val))
+      return false;
+  } else {
+    LValue LVal;
+    LVal.set(Base);
     // C++23 [intro.execution]/p5
     // A full-expression is [...] a constant-expression
     // So we need to make sure temporary objects are destroyed after having
@@ -15575,10 +15577,10 @@ bool Expr::EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx,
     if (!::EvaluateInPlace(Result.Val, Info, LVal, this) ||
         Result.HasSideEffects || !Scope.destroy())
       return false;
-  }
 
-  if (!Info.discardCleanups())
-    llvm_unreachable("Unhandled cleanup; missing full expression marker?");
+    if (!Info.discardCleanups())
+      llvm_unreachable("Unhandled cleanup; missing full expression marker?");
+  }
 
   if (!CheckConstantExpression(Info, getExprLoc(), getStorageType(Ctx, this),
                                Result.Val, Kind))
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 83986d3dd579ed6..f40eb104f128da8 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -129,7 +129,13 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
 
   /// Classifies a type.
   std::optional<PrimType> classify(const Expr *E) const {
-    return E->isGLValue() ? PT_Ptr : classify(E->getType());
+    if (E->isGLValue()) {
+      if (E->getType()->isFunctionType())
+        return PT_FnPtr;
+      return PT_Ptr;
+    }
+
+    return classify(E->getType());
   }
   std::optional<PrimType> classify(QualType Ty) const {
     return Ctx.classify(Ty);
diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index ba24955d14503be..3ff4d4364c27314 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -261,15 +261,13 @@ namespace SizeOf {
 #if __cplusplus >= 202002L
   /// FIXME: The following code should be accepted.
   consteval int foo(int n) { // ref-error {{consteval function never produces a constant expression}}
-    return sizeof(int[n]); // ref-note 3{{not valid in a constant expression}} \
-                           // expected-note {{not valid in a constant expression}}
+    return sizeof(int[n]); // ref-note 3{{not valid in a constant expression}}
   }
   constinit int var = foo(5); // ref-error {{not a constant expression}} \
                               // ref-note 2{{in call to}} \
                               // ref-error {{does not have a constant initializer}} \
                               // ref-note {{required by 'constinit' specifier}} \
                               // expected-error  {{is not a constant expression}} \
-                              // expected-note {{in call to}} \
                               // expected-error {{does not have a constant initializer}} \
                               // expected-note {{required by 'constinit' specifier}} \
 

@github-actions
Copy link

github-actions bot commented Oct 31, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

@tbaederr
Copy link
Contributor Author

Bot complains about lines I haven't touched 🤷

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a good idea how a release note could be phrased here, but if you could try one, it would be appreciated and I think it is worth doing.

Side note: it would be really cool if at the end of the release cycle, you did a section in the release-notes with a 'status' of the new interpreter. Basically a 'things that don't work', or a 'percent of tests we have that work', etc?

@tbaederr
Copy link
Contributor Author

tbaederr commented Nov 6, 2023

I don't have a good idea how a release note could be phrased here, but if you could try one, it would be appreciated and I think it is worth doing.

You mean about this change specifically?

Side note: it would be really cool if at the end of the release cycle, you did a section in the release-notes with a 'status' of the new interpreter. Basically a 'things that don't work', or a 'percent of tests we have that work', etc?

I could force the new interpreter and run the test suite, but that would only be a very rough estimate.

@tbaederr
Copy link
Contributor Author

Ping

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with unrelated changes pulled; I'm fine landing this PR after landing the fix for the function pointer classification changes if necessary.

tbaederr added a commit that referenced this pull request Nov 14, 2023
This can't be tested right now but will show up once we use the new
interpreter in evaluateAsConstantExpression() as well.

Pulled out from #70763
EvaluateAsConstantExpr() uses ::EvaluateInPlace() directly, which does
not use the new interpreter if requested. Do it here, which is the same
pattern we use in EvaluateAsInitializer.
@tbaederr tbaederr force-pushed the evaluate-as-constant-expression branch from e71ed49 to 95db809 Compare November 14, 2023 18:43
@tbaederr tbaederr merged commit f5b378b into llvm:main Nov 15, 2023
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
This can't be tested right now but will show up once we use the new
interpreter in evaluateAsConstantExpression() as well.

Pulled out from llvm#70763
zahiraam pushed a commit to zahiraam/llvm-project that referenced this pull request Nov 20, 2023
…lvm#70763)

EvaluateAsConstantExpr() uses ::EvaluateInPlace() directly, which does
not use the new interpreter if requested. Do it here, which is the same
pattern we use in EvaluateAsInitializer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants