diff options
author | Zhikai Zeng <backlight.zzk@gmail.com> | 2024-07-06 16:28:23 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-06 16:28:23 +0800 |
commit | 874ca08645420413e525054a47caf039bebde28b (patch) | |
tree | 64cb1781b46bc4ef55ce83c4a081d7c942f5c148 | |
parent | acd7a688fcd26ce4d72cecbddeddef788482e17e (diff) | |
download | llvm-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.rst | 2 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/eval-crashes.cpp | 10 |
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; +} |