From: Jason Merrill Date: Mon, 2 Mar 2020 19:42:47 +0000 (-0500) Subject: c++: Allow parm of empty class type in constexpr. X-Git-Tag: releases/gcc-9.3.0~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b4e53e9b3c963b1c0fe9637618dec8042764f599;p=thirdparty%2Fgcc.git 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 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 --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5a908241c6ac..7692a8f1903f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2020-03-02 Jason Merrill + + 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 PR c++/88256 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index bc2476f94f92..2006ad9f45ee 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 000000000000..ca4f9a55e5f9 --- /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 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 f21a9896ff28..005aa80fc093 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 constexpr auto bf(T t) { - if constexpr(t.foo()) { // { dg-error "constant expression" } + if constexpr(t.foo()) { return false; } return true;