diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2009-03-17 20:49:23 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2009-03-17 20:49:23 +0000 |
commit | ff284b4bbe69a4d7675c1519bb304c3ed819f796 (patch) | |
tree | 530b60fa39eabec19f05295b7fc6ca70fc1ed1f4 /gcc/cp | |
parent | 3c072c6ba27f5f8c18688bd3816523ee8b2e7e16 (diff) | |
download | gcc-ff284b4bbe69a4d7675c1519bb304c3ed819f796.zip gcc-ff284b4bbe69a4d7675c1519bb304c3ed819f796.tar.gz gcc-ff284b4bbe69a4d7675c1519bb304c3ed819f796.tar.bz2 |
re PR c++/39475 (c++0x type-traits should error out in case of incompleteness)
/cp
2009-03-17 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/39475
* semantics.c (check_trait_type): New.
(finish_trait_expr): Use it.
/testsuite
2009-03-17 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/39475
* g++.dg/ext/unary_trait_incomplete.C: New.
From-SVN: r144919
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 63 |
2 files changed, 62 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f948a6e..172d121 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2009-03-17 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/39475 + * semantics.c (check_trait_type): New. + (finish_trait_expr): Use it. + 2009-03-17 Jakub Jelinek <jakub@redhat.com> * name-lookup.c (cp_emit_debug_info_for_using): Emit USING_STMTs diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index eb5d25a..82a6797 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4902,6 +4902,24 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2) } } +/* Returns true if TYPE is a complete type, an array of unknown bound, + or (possibly cv-qualified) void, returns false otherwise. */ + +static bool +check_trait_type (tree type) +{ + if (COMPLETE_TYPE_P (type)) + return true; + + if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) + return true; + + if (VOID_TYPE_P (type)) + return true; + + return false; +} + /* Process a trait expression. */ tree @@ -4950,14 +4968,45 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2) if (type2) complete_type (type2); - /* The only required diagnostic. */ - if (kind == CPTK_IS_BASE_OF - && NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2) - && !same_type_ignoring_top_level_qualifiers_p (type1, type2) - && !COMPLETE_TYPE_P (type2)) + switch (kind) { - error ("incomplete type %qT not allowed", type2); - return error_mark_node; + case CPTK_HAS_NOTHROW_ASSIGN: + case CPTK_HAS_TRIVIAL_ASSIGN: + case CPTK_HAS_NOTHROW_CONSTRUCTOR: + case CPTK_HAS_TRIVIAL_CONSTRUCTOR: + case CPTK_HAS_NOTHROW_COPY: + case CPTK_HAS_TRIVIAL_COPY: + case CPTK_HAS_TRIVIAL_DESTRUCTOR: + case CPTK_HAS_VIRTUAL_DESTRUCTOR: + case CPTK_IS_ABSTRACT: + case CPTK_IS_EMPTY: + case CPTK_IS_POD: + case CPTK_IS_POLYMORPHIC: + if (!check_trait_type (type1)) + { + error ("incomplete type %qT not allowed", type1); + return error_mark_node; + } + break; + + case CPTK_IS_BASE_OF: + if (NON_UNION_CLASS_TYPE_P (type1) && NON_UNION_CLASS_TYPE_P (type2) + && !same_type_ignoring_top_level_qualifiers_p (type1, type2) + && !COMPLETE_TYPE_P (type2)) + { + error ("incomplete type %qT not allowed", type2); + return error_mark_node; + } + break; + + case CPTK_IS_CLASS: + case CPTK_IS_ENUM: + case CPTK_IS_UNION: + break; + + case CPTK_IS_CONVERTIBLE_TO: + default: + gcc_unreachable (); } return (trait_expr_value (kind, type1, type2) |