mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 03:40:26 +08:00
c++: Allow parm of empty class type in constexpr.
Since copying a class object is defined in terms of the copy constructor, copying an empty class is OK even if it would otherwise not be usable in a constant expression. Relatedly, using a parameter as an lvalue is no more problematic than a local variable, and calling a member function uses the object as an lvalue. PR c++/91953 * constexpr.c (potential_constant_expression_1) [PARM_DECL]: Allow empty class type. [COMPONENT_REF]: A member function reference doesn't use the object as an rvalue.
This commit is contained in:
parent
19e43cbce3
commit
8fda2c274a
@ -1,3 +1,11 @@
|
||||
2020-02-03 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/91953
|
||||
* constexpr.c (potential_constant_expression_1) [PARM_DECL]: Allow
|
||||
empty class type.
|
||||
[COMPONENT_REF]: A member function reference doesn't use the object
|
||||
as an rvalue.
|
||||
|
||||
2020-02-03 Iain Sandoe <iain@sandoe.co.uk>
|
||||
|
||||
PR c++/93458
|
||||
|
@ -7013,8 +7013,13 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
|
||||
return true;
|
||||
|
||||
case PARM_DECL:
|
||||
if (now)
|
||||
if (now && want_rval)
|
||||
{
|
||||
tree type = TREE_TYPE (t);
|
||||
if (dependent_type_p (type)
|
||||
|| is_really_empty_class (type, /*ignore_vptr*/false))
|
||||
/* An empty class has no data to read. */
|
||||
return true;
|
||||
if (flags & tf_error)
|
||||
error ("%qE is not a constant expression", t);
|
||||
return false;
|
||||
@ -7270,10 +7275,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
|
||||
#endif
|
||||
return RECUR (t, any);
|
||||
|
||||
case REALPART_EXPR:
|
||||
case IMAGPART_EXPR:
|
||||
case COMPONENT_REF:
|
||||
case BIT_FIELD_REF:
|
||||
case ARROW_EXPR:
|
||||
case OFFSET_REF:
|
||||
/* -- a class member access unless its postfix-expression is
|
||||
@ -7282,6 +7284,15 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
|
||||
postfix-expression being a potential constant expression. */
|
||||
if (type_unknown_p (t))
|
||||
return true;
|
||||
if (is_overloaded_fn (t))
|
||||
/* In a template, a COMPONENT_REF of a function expresses ob.fn(),
|
||||
which uses ob as an lvalue. */
|
||||
want_rval = false;
|
||||
gcc_fallthrough ();
|
||||
|
||||
case REALPART_EXPR:
|
||||
case IMAGPART_EXPR:
|
||||
case BIT_FIELD_REF:
|
||||
return RECUR (TREE_OPERAND (t, 0), want_rval);
|
||||
|
||||
case EXPR_PACK_EXPANSION:
|
||||
|
10
gcc/testsuite/g++.dg/cpp0x/constexpr-empty14.C
Normal file
10
gcc/testsuite/g++.dg/cpp0x/constexpr-empty14.C
Normal file
@ -0,0 +1,10 @@
|
||||
// PR c++/91953
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
struct S {};
|
||||
|
||||
template <class T> void
|
||||
foo (S s)
|
||||
{
|
||||
constexpr S x = s;
|
||||
}
|
@ -2,12 +2,13 @@
|
||||
// { dg-do compile { target c++17 } }
|
||||
|
||||
struct T {
|
||||
int i;
|
||||
constexpr auto foo() { return false; }
|
||||
};
|
||||
|
||||
template <class MustBeTemplate>
|
||||
constexpr auto bf(T t) {
|
||||
if constexpr(t.foo()) { // { dg-error "constant expression" }
|
||||
if constexpr(t.foo()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user