From 47805f5712322379e683028df4f9a0b0366075a9 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 15 May 2019 20:42:52 +0000 Subject: [PATCH] CWG 2096 - constraints on literal unions. * class.c (check_field_decls): Initialize booleans directly. A union is literal if at least one of its non-static data members is of non-volatile literal type. * g++.dg/cpp0x/literal-type1.C: New test. From-SVN: r271267 --- gcc/cp/ChangeLog | 7 +++ gcc/cp/class.c | 32 +++++++++---- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/g++.dg/cpp0x/literal-type1.C | 54 ++++++++++++++++++++++ 4 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/literal-type1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7a22c5e039f..3119c0370df 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2019-05-15 Marek Polacek + + CWG 2096 - constraints on literal unions. + * class.c (check_field_decls): Initialize booleans directly. A union + is literal if at least one of its non-static data members is of + non-volatile literal type. + 2019-05-15 Paolo Carlini * cp-tree.h (REFERENCE_VLA_OK): Remove. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index a47777cdd9e..ed885a5a2c1 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3403,18 +3403,19 @@ check_field_decls (tree t, tree *access_decls, { tree *field; tree *next; - bool has_pointers; - bool any_default_members; int cant_pack = 0; int field_access = -1; /* Assume there are no access declarations. */ *access_decls = NULL_TREE; /* Assume this class has no pointer members. */ - has_pointers = false; + bool has_pointers = false; /* Assume none of the members of this class have default initializations. */ - any_default_members = false; + bool any_default_members = false; + /* Assume none of the non-static data members are of non-volatile literal + type. */ + bool found_nv_literal_p = false; for (field = &TYPE_FIELDS (t); *field; field = next) { @@ -3498,13 +3499,19 @@ check_field_decls (tree t, tree *access_decls, if (TREE_PRIVATE (x) || TREE_PROTECTED (x)) CLASSTYPE_NON_AGGREGATE (t) = 1; - /* If at least one non-static data member is non-literal, the whole - class becomes non-literal. Per Core/1453, volatile non-static - data members and base classes are also not allowed. + /* If it is not a union and at least one non-static data member is + non-literal, the whole class becomes non-literal. Per Core/1453, + volatile non-static data members and base classes are also not allowed. + If it is a union, we might set CLASSTYPE_LITERAL_P after we've seen all + members. Note: if the type is incomplete we will complain later on. */ - if (COMPLETE_TYPE_P (type) - && (!literal_type_p (type) || CP_TYPE_VOLATILE_P (type))) - CLASSTYPE_LITERAL_P (t) = false; + if (COMPLETE_TYPE_P (type)) + { + if (!literal_type_p (type) || CP_TYPE_VOLATILE_P (type)) + CLASSTYPE_LITERAL_P (t) = false; + else + found_nv_literal_p = true; + } /* A standard-layout class is a class that: ... @@ -3677,6 +3684,11 @@ check_field_decls (tree t, tree *access_decls, "field %q#D with same name as class", x); } + /* Per CWG 2096, a type is a literal type if it is a union, and at least + one of its non-static data members is of non-volatile literal type. */ + if (TREE_CODE (t) == UNION_TYPE && found_nv_literal_p) + CLASSTYPE_LITERAL_P (t) = true; + /* Effective C++ rule 11: if a class has dynamic memory held by pointers, it should also define a copy constructor and an assignment operator to implement the correct copy semantic (deep vs shallow, etc.). As it is diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ffba7ba3339..8eb8b253a78 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-05-15 Marek Polacek + + CWG 2096 - constraints on literal unions. + * g++.dg/cpp0x/literal-type1.C: New test. + 2019-05-15 Janne Blomqvist PR fortran/90461 diff --git a/gcc/testsuite/g++.dg/cpp0x/literal-type1.C b/gcc/testsuite/g++.dg/cpp0x/literal-type1.C new file mode 100644 index 00000000000..7b5d4288923 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/literal-type1.C @@ -0,0 +1,54 @@ +// CWG 2096 - constraints on literal unions. +// { dg-do compile { target c++11 } } + +struct literal { }; +typedef volatile int nonliteral_v; +struct nonliteral { + nonliteral() {} +}; + +union U { + literal l; + nonliteral n; + + constexpr U() : l{} {} +}; + +constexpr U u{}; + +union U2 { + nonliteral n; + literal l; + + constexpr U2() : l{} {} +}; + +constexpr U2 u2{}; + +union U3 { // { dg-message "not literal" } + nonliteral_v n; // { dg-message "volatile type" } + + constexpr U3() : n{} {} +}; + +constexpr U3 u3{}; // { dg-error "not literal" } + +union U4 { + nonliteral n; + nonliteral_v n2; + literal l; + nonliteral n3; + + constexpr U4() : l{} {} +}; + +constexpr U4 u4{}; + +union U5 { + nonliteral_v n; + literal l; + + constexpr U5() : n{} {} +}; + +constexpr U5 u5{}; -- 2.30.2