[gcc r9-8323] c++: Allow parm of empty class type in constexpr.
Jason Merrill
jason@gcc.gnu.org
Mon Mar 2 21:25:00 GMT 2020
https://gcc.gnu.org/g:b4e53e9b3c963b1c0fe9637618dec8042764f599
commit r9-8323-gb4e53e9b3c963b1c0fe9637618dec8042764f599
Author: Jason Merrill <jason@redhat.com>
Date: Mon Mar 2 14:42:47 2020 -0500
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.
gcc/cp/ChangeLog
2020-03-02 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.
Diff:
---
gcc/cp/ChangeLog | 8 ++++++++
gcc/cp/constexpr.c | 19 +++++++++++++++----
gcc/testsuite/g++.dg/cpp0x/constexpr-empty14.C | 10 ++++++++++
gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C | 3 ++-
4 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5a90824..7692a8f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,13 @@
2020-03-02 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-03-02 Jason Merrill <jason@redhat.com>
+
PR c++/88256
* cp-gimplify.c (predeclare_vla): New.
(cp_genericize_r) [NOP_EXPR]: Call it.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index bc2476f..2006ad9 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -5996,8 +5996,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;
@@ -6238,10 +6243,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
@@ -6250,6 +6252,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:
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-empty14.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty14.C
new file mode 100644
index 0000000..ca4f9a5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-empty14.C
@@ -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;
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C
index f21a989..005aa80 100644
--- a/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if12.C
@@ -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;
More information about the Gcc-cvs
mailing list