Skip to content

[Clang][ExprConstant] fix constant expression did not evaluate to integer #97146

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 2 commits into from
Jul 6, 2024

Conversation

Backl1ght
Copy link
Member

fixes #96670

The cause is that we might return a lvalue here at

if (CE->hasAPValueResult()) {
Result.Val = CE->getAPValueResult();
IsConst = true;
return true;
}

This PR will make sure we return a rvalue in FastEvaluateAsRValue.

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

llvmbot commented Jun 29, 2024

@llvm/pr-subscribers-clang

Author: Zhikai Zeng (Backl1ght)

Changes

fixes #96670

The cause is that we might return a lvalue here at

if (CE->hasAPValueResult()) {
Result.Val = CE->getAPValueResult();
IsConst = true;
return true;
}

This PR will make sure we return a rvalue in FastEvaluateAsRValue.


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

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+1)
  • (modified) clang/lib/AST/ExprConstant.cpp (+1-1)
  • (modified) clang/test/SemaCXX/eval-crashes.cpp (+10)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index feba3c7ba8d77..8ec1c105cef9f 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -936,6 +936,7 @@ Bug Fixes to C++ Support
   forward-declared class. (#GH93512).
 - Fixed a bug in access checking inside return-type-requirement of compound requirements. (#GH93788).
 - Fixed an assertion failure about invalid conversion when calling lambda. (#GH96205).
+- Fixed an assertion failure about constant expression did not evaluate to integer. (#GH96670).
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 374a3acf7aa26..0ccdc5eaabeef 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15858,7 +15858,7 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
   }
 
   if (const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
-    if (CE->hasAPValueResult()) {
+    if (CE->hasAPValueResult() && !CE->getAPValueResult().isLValue()) {
       Result.Val = CE->getAPValueResult();
       IsConst = true;
       return true;
diff --git a/clang/test/SemaCXX/eval-crashes.cpp b/clang/test/SemaCXX/eval-crashes.cpp
index 017df977b26b7..0865dafe4bf92 100644
--- a/clang/test/SemaCXX/eval-crashes.cpp
+++ b/clang/test/SemaCXX/eval-crashes.cpp
@@ -61,3 +61,13 @@ struct array {
   array() : data(*new int[1][2]) {}
 };
 }
+
+namespace GH96670 {
+inline constexpr long ullNil = -1;
+
+template<typename T = long, const T &Nil = ullNil>
+struct Test {};
+
+inline constexpr long lNil = -1;
+Test<long, lNil> c;
+}

Copy link
Member

@Sirraide Sirraide left a comment

Choose a reason for hiding this comment

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

LGTM after rewording the release note a bit and addressing @tbaederr’s comment.

@efriedma-quic
Copy link
Collaborator

I'm concerned that we're calling EvaluateKnownConstInt on an lvalue; that might indicate there's something wrong with the AST. Usually there should be an lvalue-to-rvalue cast somewhere.

@Backl1ght
Copy link
Member Author

I'm concerned that we're calling EvaluateKnownConstInt on an lvalue; that might indicate there's something wrong with the AST. Usually there should be an lvalue-to-rvalue cast somewhere.

@efriedma-quic lvalue-to-rvalue cast is done here at

// Implicit lvalue-to-rvalue cast.
if (E->isGLValue()) {
LValue LV;
LV.setFrom(Info.Ctx, Result);
if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result))
return false;
}

@Sirraide
Copy link
Member

Sirraide commented Jul 1, 2024

I'm concerned that we're calling EvaluateKnownConstInt on an lvalue; that might indicate there's something wrong with the AST. Usually there should be an lvalue-to-rvalue cast somewhere.

Yeah, I also remember finding that strange, but after looking into it I figured it made sense, but I don’t remmeber why exactly...

@Sirraide
Copy link
Member

Sirraide commented Jul 1, 2024

Actually, where are we calling EvaluateKnownConstInt here; am I missing something obvious?

@Sirraide
Copy link
Member

Sirraide commented Jul 1, 2024

Ah, that was in the original stack trace, I see. The fix here makes sense to me because it’s in FastEvaluateAsRValue, so it makes sense that that can fail since it’s just supposed to be a fast path.

@efriedma-quic
Copy link
Collaborator

To the extent that EvaluateAsRValue handles LValues, FastEvaluateAsRValue should also handle them, sure. I'm suspicious of the fact that EvaluateAsRValue is doing this conversion in the first place, but I guess this pull request isn't the place to address that.

Given that, this patch LGTM

@Backl1ght Backl1ght force-pushed the fix_const_eval_int branch from 7950d95 to 247ea9d Compare July 6, 2024 07:57
@Backl1ght Backl1ght force-pushed the fix_const_eval_int branch from 247ea9d to f72cad6 Compare July 6, 2024 08:28
@Backl1ght Backl1ght merged commit 874ca08 into llvm:main Jul 6, 2024
5 of 8 checks passed
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.

template parameter comparison against default value doesn't handle LValue
5 participants