[PATCH] D113859: [Sema] Fix consteval function calls with value-dependent args
Léo Lam via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 14 12:20:24 PST 2021
leoetlino created this revision.
leoetlino added a reviewer: rsmith.
Herald added a subscriber: kristof.beyls.
leoetlino requested review of this revision.
Herald added a project: clang.
If any arguments of a consteval function call are value-dependent,
the call cannot be evaluated until instantiation.
This patch fixes Sema::CheckForImmediateInvocation so we don't attempt
to evaluate consteval function calls too early (before instantiation).
This fixes things like:
consteval int f(int n) { return n; }
template <int M>
constexpr int broken() {
return f(M);
}
Without the value-dependency checks, what happens is that the constant
expression evaluation engine is called on the following expression:
ConstantExpr 'int'
`-CallExpr 'int'
|-ImplicitCastExpr 'int (*)(int)' <FunctionToPointerDecay>
| `-DeclRefExpr 'int (int)' lvalue Function 'f' 'int (int)'
`-DeclRefExpr 'int' NonTypeTemplateParm 'M' 'int'
which obviously fails when it tries to evaluate M.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D113859
Files:
clang/lib/Sema/SemaExpr.cpp
clang/test/SemaCXX/cxx2a-consteval.cpp
Index: clang/test/SemaCXX/cxx2a-consteval.cpp
===================================================================
--- clang/test/SemaCXX/cxx2a-consteval.cpp
+++ clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -61,6 +61,20 @@
struct E : C {
consteval ~E() {} // expected-error {{cannot be declared consteval}}
};
+
+template <int X>
+constexpr int callConstevalWithNameDependentArg() {
+ return f1(X);
+}
+
+template <int X>
+constexpr int callConstevalWithNameDependentArgAsVariable() {
+ constexpr int x = X;
+ return f1(x);
+}
+
+auto foo = callConstevalWithNameDependentArg<42>();
+
}
consteval int main() { // expected-error {{'main' is not allowed to be declared consteval}}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -16654,11 +16654,22 @@
/// It's OK if this fails; we'll also remove this in
/// HandleImmediateInvocations, but catching it here allows us to avoid
/// walking the AST looking for it in simple cases.
- if (auto *Call = dyn_cast<CallExpr>(E.get()->IgnoreImplicit()))
+ if (auto *Call = dyn_cast<CallExpr>(E.get()->IgnoreImplicit())) {
if (auto *DeclRef =
dyn_cast<DeclRefExpr>(Call->getCallee()->IgnoreImplicit()))
ExprEvalContexts.back().ReferenceToConsteval.erase(DeclRef);
+ // If any arguments are value-dependent, we will not be able to evaluate
+ // the function call until instantiation.
+ if (Call->isValueDependent())
+ return E;
+
+ for (Expr *Arg : Call->arguments()) {
+ if (Arg->isValueDependent())
+ return E;
+ }
+ }
+
E = MaybeCreateExprWithCleanups(E);
ConstantExpr *Res = ConstantExpr::Create(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D113859.387123.patch
Type: text/x-patch
Size: 1746 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20211114/16c2a619/attachment.bin>
More information about the cfe-commits
mailing list