diff mbox

[C++,RFC] PR c++/63959, continued

Message ID CAFk2RUYhAnLjFc8mcTfiheJAr4R6E1mdx32PTqZJ5EpPt8=4aQ@mail.gmail.com
State New
Headers show

Commit Message

Ville Voutilainen Jan. 19, 2015, 4:28 p.m. UTC
When I patched the triviality test for volatile types, I missed two cases:
1) volatile members in a class should make the class non-trivial.
2) a volatile class type should itself be non-trivial.
(based on [basic.types]/9, [class]/6, [class.copy]/12 and [class.copy]/25)

I haven't completed testing this yet, I still need to run the full testsuite
to make sure there are no regressions. I'm not sure whether this
can go into gcc5, since we're at stage 4.

/cp
2015-01-19  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR c++/63959
    * class.c (check_field_decls): If any field is volatile, make
    the class type have complex copy/move operations.
    * tree.c (trivially_copyable_p): Check CP_TYPE_VOLATILE_P for
    class types too.

/testsuite
2015-01-19  Ville Voutilainen  <ville.voutilainen@gmail.com>

    PR c++/63959
    * g++.dg/ext/is_trivially_constructible1.C: Adjust.

Comments

Ville Voutilainen Jan. 19, 2015, 7:12 p.m. UTC | #1
On 19 January 2015 at 18:28, Ville Voutilainen
<ville.voutilainen@gmail.com> wrote:
> When I patched the triviality test for volatile types, I missed two cases:
> 1) volatile members in a class should make the class non-trivial.
> 2) a volatile class type should itself be non-trivial.
> (based on [basic.types]/9, [class]/6, [class.copy]/12 and [class.copy]/25)
>
> I haven't completed testing this yet, I still need to run the full testsuite
> to make sure there are no regressions. I'm not sure whether this
> can go into gcc5, since we're at stage 4.


Not quite done yet, some tests need adjusting, I will fix them shortly.
Jason Merrill March 6, 2015, 9:58 p.m. UTC | #2
On 01/19/2015 11:28 AM, Ville Voutilainen wrote:
>      * class.c (check_field_decls): If any field is volatile, make
>      the class type have complex copy/move operations.

Discussion on the cxx-abi list points out that this breaks ABI 
compatibility between C and C++, and is therefore unacceptable.

Jason
Ville Voutilainen March 6, 2015, 11:03 p.m. UTC | #3
On 6 March 2015 at 23:58, Jason Merrill <jason@redhat.com> wrote:
> On 01/19/2015 11:28 AM, Ville Voutilainen wrote:
>>
>>      * class.c (check_field_decls): If any field is volatile, make
>>      the class type have complex copy/move operations.
>
>
> Discussion on the cxx-abi list points out that this breaks ABI compatibility
> between C and C++, and is therefore unacceptable.


So.. just to clarify that we're on the same page.. making volatile-qualified
types non-trivially copyable is ok, but making wrappers of volatile-qualified
types non-trivially copyable is not ok? That's easily doable
implementation-wise,
but it makes me question the overall approach and its consistency.

Is there a way to indicate that from the point of C++ a type is not trivially
copyable without changing the "complexness" of a copy operation,
ultimately without changing ABI?
Jason Merrill March 10, 2015, 2:49 a.m. UTC | #4
On 03/06/2015 06:03 PM, Ville Voutilainen wrote:
> So.. just to clarify that we're on the same page.. making volatile-qualified
> types non-trivially copyable is ok, but making wrappers of volatile-qualified
> types non-trivially copyable is not ok? That's easily doable implementation-wise,
> but it makes me question the overall approach and its consistency.

Indeed.  This is a question for CWG; we may want to reconsider the first 
point as well.

> Is there a way to indicate that from the point of C++ a type is not trivially
> copyable without changing the "complexness" of a copy operation,
> ultimately without changing ABI?

There are various hacks I can imagine, but I think I'd prefer to resolve 
the standard issue before trying to implement it.

Jason
diff mbox

Patch

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index edb87fe..529a2bf 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -3717,6 +3717,16 @@  check_field_decls (tree t, tree *access_decls,
       if (DECL_INITIAL (x) && cxx_dialect < cxx14)
 	CLASSTYPE_NON_AGGREGATE (t) = true;
 
+      /* If any field is volatile, the structure type has complex copy
+	 and move operations.  */
+      if (CP_TYPE_VOLATILE_P (type))
+	{
+	  TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = 1;
+	  TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = 1;
+	  TYPE_HAS_COMPLEX_COPY_CTOR (t) = 1;
+	  TYPE_HAS_COMPLEX_MOVE_CTOR (t) = 1;
+	}
+
       /* If any field is const, the structure type is pseudo-const.  */
       if (CP_TYPE_CONST_P (type))
 	{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 80f2ce6..169b796 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3211,7 +3211,8 @@  trivially_copyable_p (const_tree t)
 	    && (!TYPE_HAS_COPY_ASSIGN (t)
 		|| !TYPE_HAS_COMPLEX_COPY_ASSIGN (t))
 	    && !TYPE_HAS_COMPLEX_MOVE_ASSIGN (t)
-	    && TYPE_HAS_TRIVIAL_DESTRUCTOR (t));
+	    && TYPE_HAS_TRIVIAL_DESTRUCTOR (t)
+	    && !CP_TYPE_VOLATILE_P (t));
   else
     return !CP_TYPE_VOLATILE_P (t) && scalarish_type_p (t);
 }
diff --git a/gcc/testsuite/g++.dg/ext/is_trivially_constructible1.C b/gcc/testsuite/g++.dg/ext/is_trivially_constructible1.C
index a5bac7b..35ef1f1 100644
--- a/gcc/testsuite/g++.dg/ext/is_trivially_constructible1.C
+++ b/gcc/testsuite/g++.dg/ext/is_trivially_constructible1.C
@@ -39,5 +39,16 @@  SA(!__is_trivially_copyable(volatile int));
 
 struct E1 {const int val;};
 SA(__is_trivially_copyable(E1));
+SA(!__is_trivially_copyable(volatile E1));
 struct E2 {int& val;};
 SA(__is_trivially_copyable(E2));
+struct E3 {volatile int val;};
+SA(!__is_trivially_copyable(E3));
+struct E4 {A a;};
+SA(!__is_trivially_copyable(volatile E4));
+struct E5 {volatile A a;};
+SA(!__is_trivially_copyable(E5));
+SA(!__is_trivially_copyable(volatile E5));
+struct E6 : A {};
+SA(__is_trivially_copyable(E6));
+SA(!__is_trivially_copyable(volatile E6));