aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2013-06-06 22:49:34 -0400
committerJason Merrill <jason@gcc.gnu.org>2013-06-06 22:49:34 -0400
commite765a228a54752519e75bf6b799ae4ad4bfa72e9 (patch)
tree5227fce1bac62466fe47f51072fd44a5cf33a72a /gcc
parent73310b0e7016e8e126f6371cce8dea81882b832f (diff)
downloadgcc-e765a228a54752519e75bf6b799ae4ad4bfa72e9.zip
gcc-e765a228a54752519e75bf6b799ae4ad4bfa72e9.tar.gz
gcc-e765a228a54752519e75bf6b799ae4ad4bfa72e9.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/class.c4
-rw-r--r--gcc/cp/decl.c16
-rw-r--r--gcc/cp/decl2.c8
-rw-r--r--gcc/cp/pt.c9
-rw-r--r--gcc/cp/typeck2.c2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept15.C4
-rw-r--r--gcc/testsuite/g++.dg/init/array26.C2
-rw-r--r--gcc/testsuite/g++.dg/template/error2.C5
-rw-r--r--gcc/testsuite/g++.dg/template/instantiate3.C2
10 files changed, 33 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f8bacf5..c53a9ff 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 40e6d3e..286164d 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 c37b4fe..7825c73 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 373f883..1573ced 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 d9a14cc..dcdde00 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 e0ebae9..401904d 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 c735b9e..db5b5c7 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 83c4e0c..f8f3c37 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 96f0bca..be5ab1d 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 0e9fd70..c0754da 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" }
};