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));