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
This commit is contained in:
parent
3c072c6ba2
commit
ff284b4bbe
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2009-03-17 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/39475
|
||||
* g++.dg/ext/unary_trait_incomplete.C: New.
|
||||
|
||||
2009-03-17 Jing Yu <jingyu@google.com>
|
||||
|
||||
PR middle-end/39378
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
// PR c++/39475
|
||||
|
||||
struct I;
|
||||
struct C { };
|
||||
|
||||
bool nas1 = __has_nothrow_assign(I); // { dg-error "incomplete type" }
|
||||
bool nas2 = __has_nothrow_assign(C[]);
|
||||
bool nas3 = __has_nothrow_assign(I[]);
|
||||
bool nas4 = __has_nothrow_assign(void);
|
||||
bool nas5 = __has_nothrow_assign(const void);
|
||||
|
||||
bool tas1 = __has_trivial_assign(I); // { dg-error "incomplete type" }
|
||||
bool tas2 = __has_trivial_assign(C[]);
|
||||
bool tas3 = __has_trivial_assign(I[]);
|
||||
bool tas4 = __has_trivial_assign(void);
|
||||
bool tas5 = __has_trivial_assign(const void);
|
||||
|
||||
bool nco1 = __has_nothrow_constructor(I); // { dg-error "incomplete type" }
|
||||
bool nco2 = __has_nothrow_constructor(C[]);
|
||||
bool nco3 = __has_nothrow_constructor(I[]);
|
||||
bool nco4 = __has_nothrow_constructor(void);
|
||||
bool nco5 = __has_nothrow_constructor(const void);
|
||||
|
||||
bool tco1 = __has_trivial_constructor(I); // { dg-error "incomplete type" }
|
||||
bool tco2 = __has_trivial_constructor(C[]);
|
||||
bool tco3 = __has_trivial_constructor(I[]);
|
||||
bool tco4 = __has_trivial_constructor(void);
|
||||
bool tco5 = __has_trivial_constructor(const void);
|
||||
|
||||
bool ncp1 = __has_nothrow_copy(I); // { dg-error "incomplete type" }
|
||||
bool ncp2 = __has_nothrow_copy(C[]);
|
||||
bool ncp3 = __has_nothrow_copy(I[]);
|
||||
bool ncp4 = __has_nothrow_copy(void);
|
||||
bool ncp5 = __has_nothrow_copy(const void);
|
||||
|
||||
bool tcp1 = __has_trivial_copy(I); // { dg-error "incomplete type" }
|
||||
bool tcp2 = __has_trivial_copy(C[]);
|
||||
bool tcp3 = __has_trivial_copy(I[]);
|
||||
bool tcp4 = __has_trivial_copy(void);
|
||||
bool tcp5 = __has_trivial_copy(const void);
|
||||
|
||||
bool vde1 = __has_virtual_destructor(I); // { dg-error "incomplete type" }
|
||||
bool vde2 = __has_virtual_destructor(C[]);
|
||||
bool vde3 = __has_virtual_destructor(I[]);
|
||||
bool vde4 = __has_virtual_destructor(void);
|
||||
bool vde5 = __has_virtual_destructor(const void);
|
||||
|
||||
bool tde1 = __has_trivial_destructor(I); // { dg-error "incomplete type" }
|
||||
bool tde2 = __has_trivial_destructor(C[]);
|
||||
bool tde3 = __has_trivial_destructor(I[]);
|
||||
bool tde4 = __has_trivial_destructor(void);
|
||||
bool tde5 = __has_trivial_destructor(const void);
|
||||
|
||||
bool abs1 = __is_abstract(I); // { dg-error "incomplete type" }
|
||||
bool abs2 = __is_abstract(C[]);
|
||||
bool abs3 = __is_abstract(I[]);
|
||||
bool abs4 = __is_abstract(void);
|
||||
bool abs5 = __is_abstract(const void);
|
||||
|
||||
bool pod1 = __is_pod(I); // { dg-error "incomplete type" }
|
||||
bool pod2 = __is_pod(C[]);
|
||||
bool pod3 = __is_pod(I[]);
|
||||
bool pod4 = __is_pod(void);
|
||||
bool pod5 = __is_pod(const void);
|
||||
|
||||
bool emp1 = __is_empty(I); // { dg-error "incomplete type" }
|
||||
bool emp2 = __is_empty(C[]);
|
||||
bool emp3 = __is_empty(I[]);
|
||||
bool emp4 = __is_empty(void);
|
||||
bool emp5 = __is_empty(const void);
|
||||
|
||||
bool pol1 = __is_polymorphic(I); // { dg-error "incomplete type" }
|
||||
bool pol2 = __is_polymorphic(C[]);
|
||||
bool pol3 = __is_polymorphic(I[]);
|
||||
bool pol4 = __is_polymorphic(void);
|
||||
bool pol5 = __is_polymorphic(const void);
|
Loading…
Reference in New Issue