Commit e765a228 by Jason Merrill Committed by Jason Merrill

decl.c (grokdeclarator): Keep a decl with error type.

	* 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.

From-SVN: r199779
parent 73310b0e
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
......
......@@ -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;
......
......@@ -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
{
......
......@@ -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))
......
......@@ -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);
......
......@@ -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)))
{
......
......@@ -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>
......
......@@ -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 };
......@@ -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 >
......
......@@ -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" }
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment