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.voutilai...@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.voutilai...@gmail.com>

    PR c++/63959
    * g++.dg/ext/is_trivially_constructible1.C: Adjust.
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));

Reply via email to