aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhikai Zeng <backlight.zzk@gmail.com>2024-07-06 16:28:23 +0800
committerGitHub <noreply@github.com>2024-07-06 16:28:23 +0800
commit874ca08645420413e525054a47caf039bebde28b (patch)
tree64cb1781b46bc4ef55ce83c4a081d7c942f5c148
parentacd7a688fcd26ce4d72cecbddeddef788482e17e (diff)
downloadllvm-874ca08645420413e525054a47caf039bebde28b.zip
llvm-874ca08645420413e525054a47caf039bebde28b.tar.gz
llvm-874ca08645420413e525054a47caf039bebde28b.tar.bz2
[Clang][ExprConstant] fix constant expression did not evaluate to integer (#97146)
fixes https://github.com/llvm/llvm-project/issues/96670 The cause is that we might return a lvalue here at https://github.com/llvm/llvm-project/blob/3e53c97d33210db68188e731e93ee48dbaeeae32/clang/lib/AST/ExprConstant.cpp#L15861-L15865 This PR will make sure we return a rvalue in `FastEvaluateAsRValue`.
-rw-r--r--clang/docs/ReleaseNotes.rst2
-rw-r--r--clang/lib/AST/ExprConstant.cpp9
-rw-r--r--clang/test/SemaCXX/eval-crashes.cpp10
3 files changed, 18 insertions, 3 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f6431a7..d60c6fb 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -967,6 +967,8 @@ Bug Fixes to C++ Support
- Fixed an assertion failure about invalid conversion when calling lambda. (#GH96205).
- Fixed a bug where the first operand of binary ``operator&`` would be transformed as if it was the operand
of the address of operator. (#GH97483).
+- Fixed an assertion failure about a constant expression which is a known integer but is not
+ evaluated to an integer. (#GH96670).
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 374a3acf..e0c9ef6 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -15859,9 +15859,12 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
if (const auto *CE = dyn_cast<ConstantExpr>(Exp)) {
if (CE->hasAPValueResult()) {
- Result.Val = CE->getAPValueResult();
- IsConst = true;
- return true;
+ APValue APV = CE->getAPValueResult();
+ if (!APV.isLValue()) {
+ Result.Val = std::move(APV);
+ IsConst = true;
+ return true;
+ }
}
// The SubExpr is usually just an IntegerLiteral.
diff --git a/clang/test/SemaCXX/eval-crashes.cpp b/clang/test/SemaCXX/eval-crashes.cpp
index 017df97..0865daf 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;
+}