[clang] c5e1b5e - [Clang][Sema] Do not evaluate value-dependent immediate invocations
Corentin Jabot via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 25 08:23:45 PST 2022
Author: Evgeny Shulgin
Date: 2022-02-25T17:23:36+01:00
New Revision: c5e1b5e6a99f1ab78dafb54262d8f1fff998cb26
URL: https://github.com/llvm/llvm-project/commit/c5e1b5e6a99f1ab78dafb54262d8f1fff998cb26
DIFF: https://github.com/llvm/llvm-project/commit/c5e1b5e6a99f1ab78dafb54262d8f1fff998cb26.diff
LOG: [Clang][Sema] Do not evaluate value-dependent immediate invocations
Value-dependent ConstantExprs are not meant to be evaluated.
There is an assert in Expr::EvaluateAsConstantExpr that ensures this condition.
But before this patch the method was called without prior check.
Fixes https://github.com/llvm/llvm-project/issues/52768
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D119375
Added:
Modified:
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/cxx2a-consteval.cpp
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 454e21ecfa2d9..b24caa56a38ad 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -16817,7 +16817,10 @@ ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
ConstantExpr::getStorageKind(Decl->getReturnType().getTypePtr(),
getASTContext()),
/*IsImmediateInvocation*/ true);
- ExprEvalContexts.back().ImmediateInvocationCandidates.emplace_back(Res, 0);
+ /// Value-dependent constant expressions should not be immediately
+ /// evaluated until they are instantiated.
+ if (!Res->isValueDependent())
+ ExprEvalContexts.back().ImmediateInvocationCandidates.emplace_back(Res, 0);
return Res;
}
diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp
index e909f2f303764..941d47dcb055e 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -613,6 +613,32 @@ static_assert(is_same<long, T>::value);
} // namespace unevaluated
+namespace value_dependent {
+
+consteval int foo(int x) {
+ return x;
+}
+
+template <int X> constexpr int bar() {
+ // Previously this call was rejected as value-dependent constant expressions
+ // can't be immediately evaluated. Now we show that we don't immediately
+ // evaluate them until they are instantiated.
+ return foo(X);
+}
+
+template <typename T> constexpr int baz() {
+ constexpr int t = sizeof(T);
+ // Previously this call was rejected as `t` is value-dependent and its value
+ // is unknown until the function is instantiated. Now we show that we don't
+ // reject such calls.
+ return foo(t);
+}
+
+static_assert(bar<15>() == 15);
+static_assert(baz<int>() == sizeof(int));
+
+} // namespace value_dependent
+
namespace PR50779 {
struct derp {
int b = 0;
More information about the cfe-commits
mailing list