Commit bdb5a9a3 by Paolo Carlini Committed by Paolo Carlini

re PR c++/58664 ([c++11] ICE initializing array of incomplete type within union)

/cp
2014-05-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58664
	* typeck2.c (cxx_incomplete_type_inform): New.
	(cxx_incomplete_type_diagnostic): Use it.
	* decl.c (grokdeclarator): Check the element type of an
	incomplete array type; call the above.
	* cp-tree.h (cxx_incomplete_type_inform): Declare.

/testsuite
2014-05-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58664
	* g++.dg/cpp0x/nsdmi-union6.C: New.
	* g++.dg/parse/pr58664.C: Likewise.
	* g++.dg/cpp0x/nsdmi6.C: Tweak.
	* g++.dg/parse/crash31.C: Likewise.
	* g++.dg/template/error2.C: Likewise.
	* g++.dg/template/inherit8.C: Likewise.
	* g++.dg/template/offsetof2.C: Likewise.

From-SVN: r210642
parent e9ea5185
2014-05-20 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58664
* typeck2.c (cxx_incomplete_type_inform): New.
(cxx_incomplete_type_diagnostic): Use it.
* decl.c (grokdeclarator): Check the element type of an
incomplete array type; call the above.
* cp-tree.h (cxx_incomplete_type_inform): Declare.
2014-05-19 Jason Merrill <jason@redhat.com>
PR c++/58761
......
......@@ -6158,6 +6158,7 @@ extern void cxx_incomplete_type_diagnostic (const_tree, const_tree, diagnostic_t
extern void cxx_incomplete_type_error (const_tree, const_tree);
#define cxx_incomplete_type_error(V,T) \
(cxx_incomplete_type_diagnostic ((V), (T), DK_ERROR))
extern void cxx_incomplete_type_inform (const_tree);
extern tree error_not_base_type (tree, tree);
extern tree binfo_or_else (tree, tree);
extern void cxx_readonly_error (tree, enum lvalue_use);
......
......@@ -10586,11 +10586,16 @@ 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);
{
error ("field %qD has incomplete type %qT",
unqualified_id, type);
cxx_incomplete_type_inform (strip_array_types (type));
}
else
error ("name %qT has incomplete type", type);
......
......@@ -429,6 +429,25 @@ abstract_virtuals_error (abstract_class_use use, tree type)
return abstract_virtuals_error_sfinae (use, type, tf_warning_or_error);
}
/* Print an inform about the declaration of the incomplete type TYPE. */
void
cxx_incomplete_type_inform (const_tree type)
{
location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type));
tree ptype = strip_top_quals (CONST_CAST_TREE (type));
if (current_class_type
&& TYPE_BEING_DEFINED (current_class_type)
&& same_type_p (ptype, current_class_type))
inform (loc, "definition of %q#T is not complete until "
"the closing brace", ptype);
else if (!TYPE_TEMPLATE_INFO (ptype))
inform (loc, "forward declaration of %q#T", ptype);
else
inform (loc, "declaration of %q#T", ptype);
}
/* 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, const_tree type,
"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:
......
2014-05-20 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58664
* g++.dg/cpp0x/nsdmi-union6.C: New.
* g++.dg/parse/pr58664.C: Likewise.
* g++.dg/cpp0x/nsdmi6.C: Tweak.
* g++.dg/parse/crash31.C: Likewise.
* g++.dg/template/error2.C: Likewise.
* g++.dg/template/inherit8.C: Likewise.
* g++.dg/template/offsetof2.C: Likewise.
2014-05-19 Paolo Carlini <paolo.carlini@oracle.com>
* c-c++-common/gomp/simd4.c: Adjust for inform.
......
// 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>;
......@@ -4,5 +4,5 @@
struct A
{
typedef int int T; // { dg-error "two or more data types in declaration" }
struct T x[1] = { 0 }; // { dg-error "invalid|forward" }
struct T x[1] = { 0 }; // { dg-error "incomplete type|forward" }
};
struct A // { dg-message "forward declaration" }
struct A // { dg-message "not complete" }
{
A : A; // { dg-error "expected|incomplete" }
A : B; // { dg-error "not declared|incomplete" }
......
// 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 "field 'u' has incomplete type 'U'" }
};
union CU // { dg-message "not complete" }
{
const CU 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 "field 'u' has incomplete type 'F'" }
};
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 "field 's' has incomplete type 'S'" }
};
struct VS // { dg-message "not complete" }
{
volatile VS 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 "field 's' has incomplete type 'F'" }
};
template<typename T>
struct SFT
{
F s; // { dg-error "incomplete type" }
};
template class SFT<int>;
......@@ -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" }
{
......
// PR c++/49085
template <class T>
struct A // { dg-message "declaration" }
struct A // { dg-message "not complete" }
{
int i, j;
int ar[__builtin_offsetof(A,j)]; // { 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