forked from OSchip/llvm-project
Implement P1937 consteval in unevaluated contexts
In an unevaluated contexts, consteval functions should not be immediately evaluated.
This commit is contained in:
parent
3c8e94bc20
commit
131b4620ee
|
@ -16641,7 +16641,8 @@ void Sema::CheckUnusedVolatileAssignment(Expr *E) {
|
|||
}
|
||||
|
||||
ExprResult Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
|
||||
if (!E.isUsable() || !Decl || !Decl->isConsteval() || isConstantEvaluated() ||
|
||||
if (isUnevaluatedContext() || !E.isUsable() || !Decl ||
|
||||
!Decl->isConsteval() || isConstantEvaluated() ||
|
||||
RebuildingImmediateInvocation)
|
||||
return E;
|
||||
|
||||
|
@ -18758,8 +18759,8 @@ void Sema::MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base) {
|
|||
OdrUse = false;
|
||||
|
||||
if (auto *FD = dyn_cast<FunctionDecl>(E->getDecl()))
|
||||
if (!isConstantEvaluated() && FD->isConsteval() &&
|
||||
!RebuildingImmediateInvocation)
|
||||
if (!isUnevaluatedContext() && !isConstantEvaluated() &&
|
||||
FD->isConsteval() && !RebuildingImmediateInvocation)
|
||||
ExprEvalContexts.back().ReferenceToConsteval.insert(E);
|
||||
MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E, OdrUse,
|
||||
RefsMinusAssignments);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s
|
||||
|
||||
// C++ [basic.def.odr]p2:
|
||||
// An expression is potentially evaluated unless it [...] is the
|
||||
|
@ -16,7 +17,7 @@ struct Poly {
|
|||
|
||||
struct NonPoly { };
|
||||
|
||||
template<typename T, typename Result = T>
|
||||
template<typename T, typename Result = T>
|
||||
struct X {
|
||||
Result f(T t) { return t + t; } // expected-error{{invalid operands}}
|
||||
|
||||
|
@ -34,3 +35,33 @@ void test(X<Poly> xp, X<Poly, Poly&> xpr, X<NonPoly> xnp, X<NonPoly, NonPoly&> x
|
|||
// Triggers an error (as it should);
|
||||
xpr.g(Poly()); // expected-note{{instantiation of member function}}
|
||||
}
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
|
||||
namespace unevaluated {
|
||||
|
||||
struct S {
|
||||
void f();
|
||||
};
|
||||
struct T {
|
||||
virtual void f();
|
||||
};
|
||||
|
||||
consteval S *null_s() { return nullptr; }
|
||||
consteval S *make_s() { return new S; }
|
||||
consteval T *null_t() { return nullptr; }
|
||||
consteval T *make_t() { return new T; } // #alloc
|
||||
|
||||
void func() {
|
||||
(void)typeid(*null_s());
|
||||
(void)typeid(*make_s());
|
||||
(void)typeid(*null_t()); // expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
|
||||
(void)typeid(*make_t()); // expected-error {{call to consteval function 'unevaluated::make_t' is not a constant expression}} \
|
||||
expected-note {{pointer to heap-allocated object is not a constant expression}} \
|
||||
expected-note@#alloc {{heap allocation performed here}} \
|
||||
expected-warning {{expression with side effects will be evaluated despite being used as an operand to 'typeid'}}
|
||||
}
|
||||
|
||||
} // namespace unevaluated
|
||||
|
||||
#endif
|
||||
|
|
|
@ -594,3 +594,21 @@ void test() {
|
|||
}
|
||||
|
||||
} // namespace special_ctor
|
||||
|
||||
namespace unevaluated {
|
||||
|
||||
template <typename T, typename U> struct is_same { static const bool value = false; };
|
||||
template <typename T> struct is_same<T, T> { static const bool value = true; };
|
||||
|
||||
long f(); // expected-note {{declared here}}
|
||||
auto consteval g(auto a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
auto e = g(f()); // expected-error {{is not a constant expression}}
|
||||
// expected-note@-1 {{non-constexpr function 'f' cannot be used in a constant expression}}
|
||||
|
||||
using T = decltype(g(f()));
|
||||
static_assert(is_same<long, T>::value);
|
||||
|
||||
} // namespace unevaluated
|
||||
|
|
|
@ -1105,10 +1105,11 @@ code. This issue is expected to be rectified soon.
|
|||
<tr>
|
||||
<td rowspan=2>Immediate functions (<tt>consteval</tt>)</td>
|
||||
<td><a href="https://wg21.link/p1073r3">P1073R3</a></td>
|
||||
<td rowspan=2 class="none" align="center">No</td>
|
||||
<td class="partial" align="center">Partial</td>
|
||||
</tr>
|
||||
<tr> <!-- from Prague -->
|
||||
<td><a href="https://wg21.link/p1937r2">P1937R2</a></td>
|
||||
<td class="unreleased" align="center">Clang 14</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>std::is_constant_evaluated</tt></td>
|
||||
|
|
Loading…
Reference in New Issue