PR libstdc++/71579 assert that type traits are not misused with incomplete types
authorAntony Polukhin <antoshkka@gmail.com>
Fri, 31 May 2019 10:35:03 +0000 (10:35 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 31 May 2019 10:35:03 +0000 (11:35 +0100)
commit608a080c3f6e5a8338ff99658b27e226cbba7a67
treede5f6c1cbbc45c5383532c6088dce9fa44f24b70
parentaeedf0770557f01e46b95c220496e1b6d8b96149
PR libstdc++/71579 assert that type traits are not misused with incomplete types

This patch adds static asserts for type traits misuse with incomplete
classes and unions. This gives a nice readable error message instead
of an UB and odr-violations.

Some features of the patch:
* each type trait has it's own static_assert inside. This gives better
diagnostics than the approach with putting the assert into a helper
structure and using it in each trait.
* the result of completeness check is not memorized by the compiler.
This gives no false positive after the first failed check.
* some of the compiler builtins already implement the check. But not
all of them! So the asserts are in all the type_traits that may
benefit from the check. This also makes the behavior of libstdc++ more
consistent across different (non GCC) compilers.
* std::is_base_of does not have the assert as it works well in many
cases with incomplete types

2019-05-31  Antony Polukhin  <antoshkka@gmail.com>

PR libstdc++/71579
* include/std/type_traits __type_identity, __is_complete_or_unbounded):
New helpers for checking preconditions in traits.
(is_trivial, is_trivially_copyable, is_standard_layout, is_pod)
(is_literal_type, is_empty, is_polymorphic, is_final, is_abstract)
(is_destructible, is_nothrow_destructible, is_constructible)
(is_default_constructible, is_copy_constructible)
(is_move_constructible, is_nothrow_default_constructible)
(is_nothrow_constructible, is_nothrow_copy_constructible)
(is_nothrow_move_constructible, is_copy_assignable, is_move_assignable)
(is_nothrow_assignable, is_nothrow_copy_assignable)
(is_nothrow_move_assignable, is_trivially_constructible)
(is_trivially_copy_constructible, is_trivially_move_constructible)
is_trivially_assignable, is_trivially_copy_assignable)
(is_trivially_move_assignable, is_trivially_destructible)
(alignment_of, is_swappable, is_nothrow_swappable, is_invocable)
(is_invocable_r, is_nothrow_invocable)
(has_unique_object_representations, is_aggregate): Add static_asserts
to make sure that type traits are not misused with incomplete types.
(__is_constructible_impl, __is_nothrow_default_constructible_impl)
(__is_nothrow_constructible_impl, __is_nothrow_assignable_impl): New
base characteristics without assertions that can be reused in other
traits.
* testsuite/20_util/is_complete_or_unbounded/memoization.cc: New test.
* testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc: New
test.
* testsuite/20_util/is_complete_or_unbounded/value.cc: New test.
* testsuite/20_util/is_abstract/incomplete_neg.cc: New test.
* testsuite/20_util/is_aggregate/incomplete_neg.cc: New test.
* testsuite/20_util/is_class/value.cc: Check incomplete type.
* testsuite/20_util/is_function/value.cc: Likewise.
* testsuite/20_util/is_move_constructible/incomplete_neg.cc: New test.
* testsuite/20_util/is_nothrow_move_assignable/incomplete_neg.cc: New
test.
* testsuite/20_util/is_polymorphic/incomplete_neg.cc: New test.
* testsuite/20_util/is_reference/value.cc: Check incomplete types.
* testsuite/20_util/is_unbounded_array/value.cc: Likewise.
* testsuite/20_util/is_union/value.cc: Likewise.
* testsuite/20_util/is_void/value.cc: Likewise.
* testsuite/util/testsuite_tr1.h: Add incomplete union type.

From-SVN: r271806
17 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/include/std/type_traits
libstdc++-v3/testsuite/20_util/is_abstract/incomplete_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_aggregate/incomplete_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_class/value.cc
libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/memoization_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_complete_or_unbounded/value.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_function/value.cc
libstdc++-v3/testsuite/20_util/is_move_constructible/incomplete_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_nothrow_move_assignable/incomplete_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_polymorphic/incomplete_neg.cc [new file with mode: 0644]
libstdc++-v3/testsuite/20_util/is_reference/value.cc
libstdc++-v3/testsuite/20_util/is_unbounded_array/value.cc
libstdc++-v3/testsuite/20_util/is_union/value.cc
libstdc++-v3/testsuite/20_util/is_void/value.cc
libstdc++-v3/testsuite/util/testsuite_tr1.h