On 30 January 2015 at 21:59, Ville Voutilainen <ville.voutilai...@gmail.com> wrote: > So, a new patch attached. The only change to the previous one is the change > to the trivial1.C test.
Oops. The No-template was borken and there was remnants of the macros in commented code. Let's try that again, shall we? :) Attached.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 1273064..ca01e5a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3727,6 +3727,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/semantics.c b/gcc/cp/semantics.c index 915048d..d376a09 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -7477,7 +7477,7 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) case CPTK_HAS_TRIVIAL_DESTRUCTOR: type1 = strip_array_types (type1); - return (trivial_type_p (type1) || type_code1 == REFERENCE_TYPE + return (scalarish_type_p (type1) || type_code1 == REFERENCE_TYPE || (CLASS_TYPE_P (type1) && TYPE_HAS_TRIVIAL_DESTRUCTOR (type1))); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index afb57a3..7f84f00 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); } @@ -3228,7 +3229,7 @@ trivial_type_p (const_tree t) return (TYPE_HAS_TRIVIAL_DFLT (t) && trivially_copyable_p (t)); else - return scalarish_type_p (t); + return !CP_TYPE_VOLATILE_P (t) && scalarish_type_p (t); } /* Returns 1 iff type T is a POD type, as defined in [basic.types]. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/trivial1.C b/gcc/testsuite/g++.dg/cpp0x/trivial1.C index 3fed570..49dc26b 100644 --- a/gcc/testsuite/g++.dg/cpp0x/trivial1.C +++ b/gcc/testsuite/g++.dg/cpp0x/trivial1.C @@ -15,31 +15,38 @@ #include <type_traits> -#define TRY(expr) static_assert (expr, #expr) -#define YES(type) TRY(std::is_trivial<type>::value); \ - TRY(std::is_trivial<type[]>::value); \ - TRY(std::is_trivial<const volatile type>::value) -#define NO(type) TRY(!std::is_trivial<type>::value); \ - TRY(!std::is_trivial<type[]>::value); \ - TRY(!std::is_trivial<const volatile type>::value) + +template <class T> struct Yes +{ + static constexpr bool value = std::is_trivial<T>::value + && std::is_trivial<T[]>::value + && !std::is_trivial<const volatile T>::value; +}; + +template <class T> struct No +{ + static constexpr bool value = !std::is_trivial<T>::value + && !std::is_trivial<T[]>::value + && !std::is_trivial<const volatile T>::value; +}; struct A; -YES(int); -YES(__complex int); -YES(void *); -YES(int A::*); +static_assert(Yes<int>::value, ""); +static_assert(Yes<__complex int>::value, ""); +static_assert(Yes<void *>::value, ""); +static_assert(Yes<int A::*>::value, ""); typedef int (A::*pmf)(); -YES(pmf); +static_assert(Yes<pmf>::value, ""); struct A { ~A(); }; -NO(A); +static_assert(No<A>::value, ""); struct F: public A { int i; }; -NO(F); +static_assert(No<F>::value, ""); struct G: public A { A a; }; -NO(G); +static_assert(No<G>::value, ""); struct M { A a; }; -NO(M); +static_assert(No<M>::value, ""); class B { @@ -50,15 +57,15 @@ class B int A::* pm; int (A::*pmf)(); }; -YES(B); +static_assert(Yes<B>::value, ""); struct D: public B { }; -YES(D); +static_assert(Yes<D>::value, ""); struct E: public B { int q; }; -YES(E); +static_assert(Yes<E>::value, ""); struct D2: public B { }; -YES(D2); +static_assert(Yes<D2>::value, ""); struct I: public D, public D2 { }; -YES(I); +static_assert(Yes<I>::value, ""); struct C { @@ -66,21 +73,21 @@ struct C private: int j; }; -YES(C); +static_assert(Yes<C>::value, ""); struct H: public C { }; -YES(H); +static_assert(Yes<H>::value, ""); struct N { C c; }; -YES(N); +static_assert(Yes<N>::value, ""); struct J { virtual void f(); }; struct J2: J { }; -NO(J); -NO(J2); +static_assert(No<J>::value, ""); +static_assert(No<J2>::value, ""); struct K { }; struct L: virtual K {}; -YES(K); -NO(L); +static_assert(Yes<K>::value, ""); +static_assert(No<L>::value, ""); // PR c++/41421 struct O { O(int); }; -NO(O); +static_assert(No<O>::value, ""); 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)); diff --git a/libstdc++-v3/testsuite/20_util/has_trivial_copy_constructor/value.cc b/libstdc++-v3/testsuite/20_util/has_trivial_copy_constructor/value.cc index ea58a22..ab88c3a 100644 --- a/libstdc++-v3/testsuite/20_util/has_trivial_copy_constructor/value.cc +++ b/libstdc++-v3/testsuite/20_util/has_trivial_copy_constructor/value.cc @@ -31,30 +31,31 @@ void test01() using namespace __gnu_test; // Positive tests. - static_assert(test_category<has_trivial_copy_constructor, int>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, float>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - EnumType>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, int*>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - int(*)(int)>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - int (ClassType::*)>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - int (ClassType::*) (int)>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, int[2]>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - float[][3]>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - EnumType[2][3][4]>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, int*[3]>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - int(*[][2])(int)>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - int (ClassType::*[2][3])>(true), ""); - static_assert(test_category<has_trivial_copy_constructor, - int (ClassType::*[][2][3]) (int)>(true), ""); - - // Negative tests. - static_assert(test_category<has_trivial_copy_constructor, void>(false), ""); + static_assert(has_trivial_copy_constructor<int>::value, ""); + static_assert(has_trivial_copy_constructor<const int>::value, ""); + static_assert(has_trivial_copy_constructor<float>::value, ""); + static_assert(has_trivial_copy_constructor<const float>::value, ""); + static_assert(has_trivial_copy_constructor<EnumType>::value, ""); + static_assert(has_trivial_copy_constructor<int*>::value, ""); + static_assert(has_trivial_copy_constructor<int(*)(int)>::value, ""); + static_assert(has_trivial_copy_constructor<int (ClassType::*)>::value, ""); + static_assert(has_trivial_copy_constructor<int (ClassType::*) (int)> + ::value, ""); + static_assert(has_trivial_copy_constructor<int[2]>::value, ""); + static_assert(has_trivial_copy_constructor<float[][3]>::value, ""); + static_assert(has_trivial_copy_constructor<EnumType[2][3][4]>::value, ""); + static_assert(has_trivial_copy_constructor<int*[3]>::value, ""); + static_assert(has_trivial_copy_constructor<int(*[][2])(int)>::value, ""); + static_assert(has_trivial_copy_constructor<int (ClassType::*[2][3])> + ::value, ""); + static_assert(has_trivial_copy_constructor< + int (ClassType::*[][2][3]) (int)>::value, ""); + static_assert(test_category<has_trivial_copy_constructor, + ClassType>(true), ""); + // Negative tests. + static_assert(test_category<has_trivial_copy_constructor, + void>(false), ""); + static_assert(!has_trivial_copy_constructor<volatile int>::value, ""); + static_assert(!has_trivial_copy_constructor<const volatile int> + ::value, ""); } diff --git a/libstdc++-v3/testsuite/20_util/has_trivial_default_constructor/value.cc b/libstdc++-v3/testsuite/20_util/has_trivial_default_constructor/value.cc index 7111274..766a792 100644 --- a/libstdc++-v3/testsuite/20_util/has_trivial_default_constructor/value.cc +++ b/libstdc++-v3/testsuite/20_util/has_trivial_default_constructor/value.cc @@ -31,36 +31,31 @@ void test01() using namespace __gnu_test; // Positive tests. - static_assert(test_category<has_trivial_default_constructor, int>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - float>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - EnumType>(true), ""); - static_assert(test_category<has_trivial_default_constructor, int*>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - int(*)(int)>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - int (ClassType::*)>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - int (ClassType::*) (int)>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - int[2]>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - float[][3]>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - EnumType[2][3][4]>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - int*[3]>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - int(*[][2])(int)>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - int (ClassType::*[2][3])>(true), ""); - static_assert(test_category<has_trivial_default_constructor, - int (ClassType::*[][2][3]) (int)>(true), ""); + static_assert(has_trivial_default_constructor<int>::value, ""); + static_assert(has_trivial_default_constructor<const int>::value, ""); + static_assert(has_trivial_default_constructor<float>::value, ""); + static_assert(has_trivial_default_constructor<const float>::value, ""); + static_assert(has_trivial_default_constructor<EnumType>::value, ""); + static_assert(has_trivial_default_constructor<int*>::value, ""); + static_assert(has_trivial_default_constructor<int(*)(int)>::value, ""); + static_assert(has_trivial_default_constructor<int (ClassType::*)>::value, ""); + static_assert(has_trivial_default_constructor<int (ClassType::*) (int)> + ::value, ""); + static_assert(has_trivial_default_constructor<int[2]>::value, ""); + static_assert(has_trivial_default_constructor<float[][3]>::value, ""); + static_assert(has_trivial_default_constructor<EnumType[2][3][4]>::value, ""); + static_assert(has_trivial_default_constructor<int*[3]>::value, ""); + static_assert(has_trivial_default_constructor<int(*[][2])(int)>::value, ""); + static_assert(has_trivial_default_constructor<int (ClassType::*[2][3])> + ::value, ""); + static_assert(has_trivial_default_constructor< + int (ClassType::*[][2][3]) (int)>::value, ""); static_assert(test_category<has_trivial_default_constructor, ClassType>(true), ""); - // Negative tests. static_assert(test_category<has_trivial_default_constructor, void>(false), ""); + static_assert(!has_trivial_default_constructor<volatile int>::value, ""); + static_assert(!has_trivial_default_constructor<const volatile int> + ::value, ""); } diff --git a/libstdc++-v3/testsuite/20_util/is_pod/value.cc b/libstdc++-v3/testsuite/20_util/is_pod/value.cc index 8e0237e..5beba46 100644 --- a/libstdc++-v3/testsuite/20_util/is_pod/value.cc +++ b/libstdc++-v3/testsuite/20_util/is_pod/value.cc @@ -43,9 +43,14 @@ void test01() static_assert(test_category<is_pod, int (ClassType::*[2][3])>(true), ""); static_assert(test_category<is_pod, int (ClassType::*[][2][3]) (int)>(true), ""); - static_assert(test_category<is_pod, ClassType>(true), ""); - static_assert(test_category<is_pod, PODType>(true), ""); - + static_assert(is_pod<ClassType>::value, ""); + static_assert(is_pod<const ClassType>::value, ""); + static_assert(!is_pod<const volatile ClassType>::value, ""); + static_assert(!is_pod<volatile ClassType>::value, ""); + static_assert(is_pod<PODType>::value, ""); + static_assert(is_pod<const PODType>::value, ""); + static_assert(!is_pod<const volatile PODType>::value, ""); + static_assert(!is_pod<volatile PODType>::value, ""); static_assert(test_category<is_pod, void>(false), ""); static_assert(test_category<is_pod, NType>(false), ""); static_assert(test_category<is_pod, TType>(false), ""); diff --git a/libstdc++-v3/testsuite/20_util/is_trivial/value.cc b/libstdc++-v3/testsuite/20_util/is_trivial/value.cc index ffc8acb..bb193bd 100644 --- a/libstdc++-v3/testsuite/20_util/is_trivial/value.cc +++ b/libstdc++-v3/testsuite/20_util/is_trivial/value.cc @@ -28,9 +28,14 @@ void test01() using std::is_trivial; using namespace __gnu_test; - static_assert(test_category<is_trivial, TType>(true), ""); - static_assert(test_category<is_trivial, PODType>(true), ""); - + static_assert(is_trivial<TType>::value, ""); + static_assert(is_trivial<const TType>::value, ""); + static_assert(!is_trivial<volatile TType>::value, ""); + static_assert(!is_trivial<const volatile TType>::value, ""); + static_assert(is_trivial<PODType>::value, ""); + static_assert(is_trivial<const PODType>::value, ""); + static_assert(!is_trivial<volatile PODType>::value, ""); + static_assert(!is_trivial<const volatile PODType>::value, ""); static_assert(test_category<is_trivial, NType>(false), ""); static_assert(test_category<is_trivial, SLType>(false), ""); }