/* True iff class TYPE has a non-deleted trivial default
constructor. */
-bool type_has_non_deleted_trivial_default_ctor (tree type)
+bool
+type_has_non_deleted_trivial_default_ctor (tree type)
{
return TYPE_HAS_TRIVIAL_DFLT (type) && locate_ctor (type);
}
t = strip_array_types (CONST_CAST_TREE (t));
if (CLASS_TYPE_P (t))
- return (TYPE_HAS_TRIVIAL_DFLT (t)
+ /* A trivial class is a class that is trivially copyable and has one or
+ more eligible default constructors, all of which are trivial. */
+ return (type_has_non_deleted_trivial_default_ctor (CONST_CAST_TREE (t))
&& trivially_copyable_p (t));
else
return scalarish_type_p (t);
--- /dev/null
+// PR c++/108769
+// { dg-do compile { target c++20 } }
+
+template <class T>
+struct S {
+ S() requires false = default;
+};
+static_assert(!__is_trivial(S<int>));
+
+template <class T>
+struct R {
+ R() requires true = default;
+};
+static_assert(__is_trivial(R<int>));
--- /dev/null
+// PR c++/58074
+// { dg-do compile { target c++11 } }
+
+struct Trivial
+{
+ Trivial() = delete;
+};
+
+struct NonTrivial
+{
+ NonTrivial() = default;
+ NonTrivial(NonTrivial&) = default;
+ NonTrivial& operator=(NonTrivial&) = default;
+};
+
+// As it happens, 58074 was originally asking for the opposite result
+// of __is_trivial than we're checking here, so what was non-trivial
+// was supposed to be trivial and vice versa. But here we are.
+static_assert(!__is_trivial(Trivial), "Ouch");
+static_assert(__is_trivial(NonTrivial), "Ouch");
--- /dev/null
+// PR c++/115522
+// { dg-do compile { target c++11 } }
+
+// Not default constructible.
+struct S {
+ const int i;
+};
+
+static_assert(!__is_trivial(S), "");
+
+struct R {
+ int &r;
+};
+
+static_assert(!__is_trivial(R), "");
--- /dev/null
+// CWG 1363
+// PR c++/85723
+// { dg-do compile { target c++11 } }
+
+struct A {
+ A() = default;
+ A(int i = 0) { }
+};
+
+static_assert(!__is_trivial(A), "");
--- /dev/null
+// CWG 1496
+// PR c++/85723
+// { dg-do compile { target c++11 } }
+
+struct NonTrivial {
+ NonTrivial() = delete;
+};
+static_assert(!__is_trivial (NonTrivial), "NonTrivial is trivial");
--- /dev/null
+// PR c++/85723
+// { dg-do compile { target c++20 } }
+
+template<typename T>
+struct A {
+ A() = delete;
+ A() requires(sizeof(T) == 1) = default;
+ A() requires(sizeof(T) != 1) = delete;
+};
+static_assert(!__is_trivial(A<int>));
+static_assert(__is_trivial(A<char>));
+
+template<typename T>
+struct B {
+ B() = default;
+ B() requires(sizeof(T) == 1) = default;
+ B() requires(sizeof(T) != 1) = delete;
+};
+static_assert(__is_trivial(B<int>));
+static_assert(__is_trivial(B<char>));
+
+template<typename T>
+struct C {
+ C() = default;
+ C() requires(sizeof(T) == 1) = delete;
+ C() requires(sizeof(T) != 1) = default;
+};
+static_assert(__is_trivial(C<int>));
+static_assert(__is_trivial(C<char>));
+
+template<typename T>
+struct D {
+ D() = default;
+ D(int = 42) {}
+ D() requires(sizeof(T) == 1) = delete;
+ D() requires(sizeof(T) != 1) = default;
+};
+static_assert(!__is_trivial(D<int>));
+static_assert(!__is_trivial(D<char>));
+
+
+template<typename T>
+struct E {
+ E() = delete;
+ E() requires(sizeof(T) == 1) = default;
+ E() requires(sizeof(T) != 1) = delete;
+};
+static_assert(!__is_trivial(E<int>));
+static_assert(__is_trivial(E<char>));
// Reallocating is not diagnosed except in C++ 98 due to a bug.
T (q = realloc, (p, 1)); // { dg-warning "moving an object of non-trivially copyable type .struct HasConstData.; use .new. and .delete. instead" "c++98" { target { c++98_only } } }
+// { dg-warning "moving an object of non-trivial type" "" { target c++11 } .-1 }
T (q = realloc, (p, n)); // { dg-warning "realloc" "c++98" { target { c++98_only } } }
T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" "c++98" { target { c++98_only } } }
}
// in C++ 98 because of a bug, but it seems like it should be
// diagnosed in all modes.
T (q = realloc, (p, 1)); // { dg-warning "realloc" "c++ 98" { target { c++98_only } } }
+// { dg-warning "moving an object of non-trivial type" "" { target c++11 } .-1 }
T (q = realloc, (p, n)); // { dg-warning "realloc" "c++ 98" { target { c++98_only } } }
T (q = realloc, (p, sizeof *p)); // { dg-warning "realloc" "c++ 98" { target { c++98_only } } }
}