===================================================================
@@ -10586,11 +10586,12 @@ grokdeclarator (const cp_declarator *declarator,
}
else if (!staticp && !dependent_type_p (type)
&& !COMPLETE_TYPE_P (complete_type (type))
- && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0))
+ && (TREE_CODE (type) != ARRAY_TYPE
+ || !COMPLETE_TYPE_P (TREE_TYPE (type))
+ || initialized == 0))
{
if (unqualified_id)
- error ("field %qD has incomplete type %qT",
- unqualified_id, type);
+ cxx_incomplete_type_error (unqualified_id, type);
else
error ("name %qT has incomplete type", type);
===================================================================
@@ -429,6 +429,25 @@ abstract_virtuals_error (abstract_class_use use, t
return abstract_virtuals_error_sfinae (use, type, tf_warning_or_error);
}
+/* Print an inform about the declaration of the incomplete type TYPE. */
+
+static void
+cxx_incomplete_type_inform (const_tree type)
+{
+ if (current_class_type
+ && type == current_class_type
+ && TYPE_BEING_DEFINED (current_class_type))
+ inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+ "definition of %q#T is not complete until "
+ "the closing brace", type);
+ else if (!TYPE_TEMPLATE_INFO (type))
+ inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+ "forward declaration of %q#T", type);
+ else
+ inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
+ "declaration of %q#T", type);
+}
+
/* Print an error message for invalid use of an incomplete type.
VALUE is the expression that was used (or 0 if that isn't known)
and TYPE is the type that was invalid. DIAG_KIND indicates the
@@ -469,14 +488,7 @@ cxx_incomplete_type_diagnostic (const_tree value,
"invalid use of incomplete type %q#T",
type);
if (complained)
- {
- if (!TYPE_TEMPLATE_INFO (type))
- inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
- "forward declaration of %q#T", type);
- else
- inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
- "declaration of %q#T", type);
- }
+ cxx_incomplete_type_inform (type);
break;
case VOID_TYPE:
===================================================================
@@ -0,0 +1,56 @@
+// PR c++/58664
+// { dg-do compile { target c++11 } }
+
+struct F; // { dg-message "forward declaration" }
+
+union U // { dg-message "not complete" }
+{
+ U u[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template<typename T>
+union UT // { dg-message "not complete" }
+{
+ UT u[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template union UT<int>;
+
+union UF
+{
+ F u[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template<typename T>
+union UFT
+{
+ F u[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template union UFT<int>;
+
+struct S // { dg-message "not complete" }
+{
+ S s[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template<typename T>
+struct ST // { dg-message "not complete" }
+{
+ ST s[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template class ST<int>;
+
+struct SF
+{
+ F s[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template<typename T>
+struct SFT
+{
+ F s[1] = { 0 }; // { dg-error "incomplete type" }
+};
+
+template class SFT<int>;
===================================================================
@@ -0,0 +1,56 @@
+// PR c++/58664
+// { dg-do compile { target c++11 } }
+
+struct F; // { dg-message "forward declaration" }
+
+union U // { dg-message "not complete" }
+{
+ U u; // { dg-error "incomplete type" }
+};
+
+template<typename T>
+union UT // { dg-message "not complete" }
+{
+ UT u; // { dg-error "incomplete type" }
+};
+
+template union UT<int>;
+
+union UF
+{
+ F u; // { dg-error "incomplete type" }
+};
+
+template<typename T>
+union UFT
+{
+ F u; // { dg-error "incomplete type" }
+};
+
+template union UFT<int>;
+
+struct S // { dg-message "not complete" }
+{
+ S s; // { dg-error "incomplete type" }
+};
+
+template<typename T>
+struct ST // { dg-message "not complete" }
+{
+ ST s; // { dg-error "incomplete type" }
+};
+
+template class ST<int>;
+
+struct SF
+{
+ F s; // { dg-error "incomplete type" }
+};
+
+template<typename T>
+struct SFT
+{
+ F s; // { dg-error "incomplete type" }
+};
+
+template class SFT<int>;
===================================================================
@@ -4,7 +4,7 @@
struct A
{
int i;
- struct A a; /* { dg-error "has incomplete type" } */
+ struct A a; /* { dg-error "incomplete type" } */
};
void foo()
===================================================================
@@ -7,8 +7,7 @@
template<class T> struct X
{
- T m; // { dg-error "void" "void" }
- // { dg-error "incomplete type" "incomplete" { target *-*-* } 10 }
+ T m; // { dg-error "incomplete type|invalid use" }
};
template<class T >
===================================================================
@@ -4,7 +4,7 @@ template <typename T>
struct A
{
template <typename U>
- struct B : public A <B<U> > // { dg-message "declaration" }
+ struct B : public A <B<U> > // { dg-message "not complete" }
{
struct C : public B<U> // { dg-error "incomplete" }
{