* C++ PATCH for CWG 2096, constraints on literal unions
@ 2019-05-13 22:07 Marek Polacek
2019-05-15 20:38 ` Jason Merrill
0 siblings, 1 reply; 2+ messages in thread
From: Marek Polacek @ 2019-05-13 22:07 UTC (permalink / raw)
To: GCC Patches, Jason Merrill
This patch implements CWG 2096 which relaxes the constraints for literal unions.
[basic.types]/p10 now says: A type is a literal type if...
-- it is a union, at least one of its non-static data members is of non-volatile literal type,
[...]
check_field_decls is called with CLASSTYPE_LITERAL_P set to true, so we can
re-set it after we've processed all fields.
Bootstrapped/regtested on x86_64-linux, ok for trunk?
2019-05-13 Marek Polacek <polacek@redhat.com>
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.
diff --git gcc/cp/class.c gcc/cp/class.c
index a47777cdd9e..ed885a5a2c1 100644
--- gcc/cp/class.c
+++ 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 gcc/testsuite/g++.dg/cpp0x/literal-type1.C gcc/testsuite/g++.dg/cpp0x/literal-type1.C
new file mode 100644
index 00000000000..7b5d4288923
--- /dev/null
+++ 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{};
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: C++ PATCH for CWG 2096, constraints on literal unions
2019-05-13 22:07 C++ PATCH for CWG 2096, constraints on literal unions Marek Polacek
@ 2019-05-15 20:38 ` Jason Merrill
0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2019-05-15 20:38 UTC (permalink / raw)
To: Marek Polacek, GCC Patches
On 5/13/19 6:07 PM, Marek Polacek wrote:
> This patch implements CWG 2096 which relaxes the constraints for literal unions.
>
> [basic.types]/p10 now says: A type is a literal type if...
> -- it is a union, at least one of its non-static data members is of non-volatile literal type,
> [...]
>
> check_field_decls is called with CLASSTYPE_LITERAL_P set to true, so we can
> re-set it after we've processed all fields.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2019-05-13 Marek Polacek <polacek@redhat.com>
>
> 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.
OK, thanks.
Jason
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2019-05-15 20:38 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-13 22:07 C++ PATCH for CWG 2096, constraints on literal unions Marek Polacek
2019-05-15 20:38 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).