diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-07 02:49:34 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-06-07 02:49:34 +0000 |
commit | 53b567c16985ce349d6bfb0ac087b00e1e96dddc (patch) | |
tree | 5227fce1bac62466fe47f51072fd44a5cf33a72a | |
parent | 556726e1625aaa01cff0323ed058daeeb12e980a (diff) | |
download | gcc-53b567c16985ce349d6bfb0ac087b00e1e96dddc.tar.gz |
* decl.c (grokdeclarator): Keep a decl with error type.
(grokfield, grokbitfield): Likewise.
* pt.c (instantiate_class_template_1): Likewise.
(tsubst_decl): Drop redundant error.
* class.c (walk_subobject_offsets): Handle erroneous fields.
* typeck2.c (process_init_constructor_record): Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199779 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/cp/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/class.c | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 16 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 8 | ||||
-rw-r--r-- | gcc/cp/pt.c | 9 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept15.C | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/array26.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/error2.C | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/instantiate3.C | 2 |
10 files changed, 33 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f8bacf5d42b..c53a9ff0b5a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2013-06-06 Jason Merrill <jason@redhat.com> + + * decl.c (grokdeclarator): Keep a decl with error type. + (grokfield, grokbitfield): Likewise. + * pt.c (instantiate_class_template_1): Likewise. + (tsubst_decl): Drop redundant error. + * class.c (walk_subobject_offsets): Handle erroneous fields. + * typeck2.c (process_init_constructor_record): Likewise. + 2013-06-05 Paolo Carlini <paolo.carlini@oracle.com> PR c++/51908 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 40e6d3eed73..286164d0202 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3779,7 +3779,9 @@ walk_subobject_offsets (tree type, /* Iterate through the fields of TYPE. */ for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) - if (TREE_CODE (field) == FIELD_DECL && !DECL_ARTIFICIAL (field)) + if (TREE_CODE (field) == FIELD_DECL + && TREE_TYPE (field) != error_mark_node + && !DECL_ARTIFICIAL (field)) { tree field_offset; diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index c37b4fe5592..7825c73e0d7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -10530,21 +10530,13 @@ grokdeclarator (const cp_declarator *declarator, && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0)) { if (unqualified_id) - error ("field %qD has incomplete type", unqualified_id); + error ("field %qD has incomplete type %qT", + unqualified_id, type); else error ("name %qT has incomplete type", type); - /* If we're instantiating a template, tell them which - instantiation made the field's type be incomplete. */ - if (current_class_type - && TYPE_NAME (current_class_type) - && IDENTIFIER_TEMPLATE (current_class_name) - && declspecs->type - && declspecs->type == type) - error (" in instantiation of template %qT", - current_class_type); - - return error_mark_node; + type = error_mark_node; + decl = NULL_TREE; } else { diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 373f8831173..1573cede899 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -835,9 +835,11 @@ grokfield (const cp_declarator *declarator, init = NULL_TREE; value = grokdeclarator (declarator, declspecs, FIELD, init != 0, &attrlist); - if (! value || error_operand_p (value)) + if (! value || value == error_mark_node) /* friend or constructor went bad. */ return error_mark_node; + if (TREE_TYPE (value) == error_mark_node) + return value; if (TREE_CODE (value) == TYPE_DECL && init) { @@ -1045,8 +1047,10 @@ grokbitfield (const cp_declarator *declarator, { tree value = grokdeclarator (declarator, declspecs, BITFIELD, 0, &attrlist); - if (value == error_mark_node) + if (value == error_mark_node) return NULL_TREE; /* friends went bad. */ + if (TREE_TYPE (value) == error_mark_node) + return value; /* Pass friendly classes back. */ if (VOID_TYPE_P (value)) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index d9a14cc3cbd..dcdde005cd7 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -8863,9 +8863,8 @@ instantiate_class_template_1 (tree type) else if (TREE_CODE (r) == FIELD_DECL) { /* Determine whether R has a valid type and can be - completed later. If R is invalid, then it is - replaced by error_mark_node so that it will not be - added to TYPE_FIELDS. */ + completed later. If R is invalid, then its type is + replaced by error_mark_node. */ tree rtype = TREE_TYPE (r); if (can_complete_type_without_circularity (rtype)) complete_type (rtype); @@ -8873,7 +8872,7 @@ instantiate_class_template_1 (tree type) if (!COMPLETE_TYPE_P (rtype)) { cxx_incomplete_type_error (r, rtype); - r = error_mark_node; + TREE_TYPE (r) = error_mark_node; } } @@ -10514,8 +10513,6 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) /* We don't have to set DECL_CONTEXT here; it is set by finish_member_declaration. */ DECL_CHAIN (r) = NULL_TREE; - if (VOID_TYPE_P (type)) - error ("instantiation of %q+D as type %qT", r, type); apply_late_template_attributes (&r, DECL_ATTRIBUTES (r), 0, args, complain, in_decl); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index e0ebae95723..401904d8ea4 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -1236,6 +1236,8 @@ process_init_constructor_record (tree type, tree init, type = TREE_TYPE (field); if (DECL_BIT_FIELD_TYPE (field)) type = DECL_BIT_FIELD_TYPE (field); + if (type == error_mark_node) + return PICFLAG_ERRONEOUS; if (idx < vec_safe_length (CONSTRUCTOR_ELTS (init))) { diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept15.C b/gcc/testsuite/g++.dg/cpp0x/noexcept15.C index c735b9e5359..db5b5c7f3d7 100644 --- a/gcc/testsuite/g++.dg/cpp0x/noexcept15.C +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept15.C @@ -9,11 +9,11 @@ template<class Tp> Tp elem; // { dg-error "incomplete type" } constexpr single(const Tp& e) - : elem(e) { } // { dg-error "invalid field" } + : elem(e) { } single(single&& s) noexcept(std::is_nothrow_move_constructible<Tp>::value) - : elem(s.elem) { } // { dg-error "invalid field|no member" } + : elem(s.elem) { } }; template<class Tp> diff --git a/gcc/testsuite/g++.dg/init/array26.C b/gcc/testsuite/g++.dg/init/array26.C index 83c4e0c4a4d..f8f3c3743fc 100644 --- a/gcc/testsuite/g++.dg/init/array26.C +++ b/gcc/testsuite/g++.dg/init/array26.C @@ -8,4 +8,4 @@ struct B A a; // { dg-error "incomplete type" } }; -B b[1] = (B[]) { 0 }; // { dg-error "initializer" } +B b[1] = (B[]) { 0 }; diff --git a/gcc/testsuite/g++.dg/template/error2.C b/gcc/testsuite/g++.dg/template/error2.C index 96f0bcae661..be5ab1d450e 100644 --- a/gcc/testsuite/g++.dg/template/error2.C +++ b/gcc/testsuite/g++.dg/template/error2.C @@ -7,9 +7,8 @@ template<class T> struct X { - T m; // { dg-error "as type 'void'" "void" } - // { dg-error "incomplete type" "incomplate" { target *-*-* } 10 } - // { dg-error "invalid" "invalid" { target *-*-* } 10 } + T m; // { dg-error "void" "void" } + // { dg-error "incomplete type" "incomplete" { target *-*-* } 10 } }; template<class T > diff --git a/gcc/testsuite/g++.dg/template/instantiate3.C b/gcc/testsuite/g++.dg/template/instantiate3.C index 0e9fd706015..c0754da9227 100644 --- a/gcc/testsuite/g++.dg/template/instantiate3.C +++ b/gcc/testsuite/g++.dg/template/instantiate3.C @@ -10,7 +10,7 @@ template <class TYPE> struct ACE_Cleanup_Adapter { TYPE &object () - { return object_; } // { dg-error "invalid" } + { return object_; } TYPE object_; // { dg-error "incomplete type" } }; |