* [C++ Patch] PR 58664
@ 2014-05-19 22:45 Paolo Carlini
2014-05-20 0:11 ` Paolo Carlini
2014-05-20 3:21 ` Jason Merrill
0 siblings, 2 replies; 5+ messages in thread
From: Paolo Carlini @ 2014-05-19 22:45 UTC (permalink / raw)
To: gcc-patches; +Cc: Jason Merrill
[-- Attachment #1: Type: text/plain, Size: 1033 bytes --]
Hi,
first blush, this is just an ICE on invalid for a quite special case.
However, comparing the union case to the struct case (on which we don't
ICE):
struct S
{
S s[1] = { 0 };
};
xxx.C:3:16: error: could not convert ‘0’ from ‘int’ to ‘S’
S s[1] = { 0 };
shows that in this area there is definitely room for improvement,
diagnostic-wise.
The core issue turns out to be pretty straightforward: grokdeclarator
doesn't check whether the element-type is incomplete. Then, uniformly
calling cxx_incomplete_type_error (as *already* happens for the template
version of these snippets) almost works, modulo a detail: the function
doesn't tell incomplete types from types being defined. Thus I added
some code for that (hopefully, a more general improvement).
Note that there are some (minor, IMHO) subtleties: for example,
uniformly calling cxx_incomplete_type_error means that we don't talk
anymore about *field*, thus the tweak to parse/struct-4.C.
Tested x86_64-linux.
Thanks!
Paolo.
/////////////////////////
[-- Attachment #2: CL_58664 --]
[-- Type: text/plain, Size: 547 bytes --]
/cp
2014-05-20 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58664
* decl.c (grokdeclarator): Check the element type of an incomplete
array type; call cxx_incomplete_type_error.
* typeck2.c (cxx_incomplete_type_inform): New.
(cxx_incomplete_type_diagnostic): Use it.
/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/parse/struct-4.C: Tweak.
* g++.dg/template/error2.C: Likewise.
* g++.dg/template/inherit8.C: Likewise.
[-- Attachment #3: patch_58664 --]
[-- Type: text/plain, Size: 6342 bytes --]
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 210622)
+++ cp/decl.c (working copy)
@@ -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);
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c (revision 210623)
+++ cp/typeck2.c (working copy)
@@ -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:
Index: testsuite/g++.dg/cpp0x/nsdmi-union6.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi-union6.C (revision 0)
+++ testsuite/g++.dg/cpp0x/nsdmi-union6.C (working copy)
@@ -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>;
Index: testsuite/g++.dg/parse/pr58664.C
===================================================================
--- testsuite/g++.dg/parse/pr58664.C (revision 0)
+++ testsuite/g++.dg/parse/pr58664.C (working copy)
@@ -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>;
Index: testsuite/g++.dg/parse/struct-4.C
===================================================================
--- testsuite/g++.dg/parse/struct-4.C (revision 210624)
+++ testsuite/g++.dg/parse/struct-4.C (working copy)
@@ -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()
Index: testsuite/g++.dg/template/error2.C
===================================================================
--- testsuite/g++.dg/template/error2.C (revision 210624)
+++ testsuite/g++.dg/template/error2.C (working copy)
@@ -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 >
Index: testsuite/g++.dg/template/inherit8.C
===================================================================
--- testsuite/g++.dg/template/inherit8.C (revision 210624)
+++ testsuite/g++.dg/template/inherit8.C (working copy)
@@ -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" }
{
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [C++ Patch] PR 58664
2014-05-19 22:45 [C++ Patch] PR 58664 Paolo Carlini
@ 2014-05-20 0:11 ` Paolo Carlini
2014-05-20 3:21 ` Jason Merrill
1 sibling, 0 replies; 5+ messages in thread
From: Paolo Carlini @ 2014-05-20 0:11 UTC (permalink / raw)
To: gcc-patches; +Cc: Jason Merrill
[-- Attachment #1: Type: text/plain, Size: 264 bytes --]
... in fact, I need to be more careful when comparing the types, also
because of cv-qualifiers, eg, for:
struct S
{
const S s[1] = { 0 };
};
the trees for S and const S are definitely different. Done in the attached.
Thanks,
Paolo.
///////////////////////
[-- Attachment #2: CL_58664_b --]
[-- Type: text/plain, Size: 626 bytes --]
/cp
2014-05-20 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/58664
* decl.c (grokdeclarator): Check the element type of an incomplete
array type; call cxx_incomplete_type_error.
* typeck2.c (cxx_incomplete_type_inform): New.
(cxx_incomplete_type_diagnostic): Use it.
/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/parse/crash31.C: Tweak.
* g++.dg/parse/struct-4.C: Likewise.
* g++.dg/template/error2.C: Likewise.
* g++.dg/template/inherit8.C: Likewise.
* g++.dg/template/offsetof2.C: Likewise.
[-- Attachment #3: patch_58664_b --]
[-- Type: text/plain, Size: 7474 bytes --]
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 210622)
+++ cp/decl.c (working copy)
@@ -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);
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c (revision 210623)
+++ cp/typeck2.c (working copy)
@@ -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)
+{
+ 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,
"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:
Index: testsuite/g++.dg/cpp0x/nsdmi-union6.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi-union6.C (revision 0)
+++ testsuite/g++.dg/cpp0x/nsdmi-union6.C (working copy)
@@ -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>;
Index: testsuite/g++.dg/parse/crash31.C
===================================================================
--- testsuite/g++.dg/parse/crash31.C (revision 210624)
+++ testsuite/g++.dg/parse/crash31.C (working copy)
@@ -1,4 +1,4 @@
-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" }
Index: testsuite/g++.dg/parse/pr58664.C
===================================================================
--- testsuite/g++.dg/parse/pr58664.C (revision 0)
+++ testsuite/g++.dg/parse/pr58664.C (working copy)
@@ -0,0 +1,66 @@
+// 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" }
+};
+
+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 "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" }
+};
+
+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 "incomplete type" }
+};
+
+template<typename T>
+struct SFT
+{
+ F s; // { dg-error "incomplete type" }
+};
+
+template class SFT<int>;
Index: testsuite/g++.dg/parse/struct-4.C
===================================================================
--- testsuite/g++.dg/parse/struct-4.C (revision 210624)
+++ testsuite/g++.dg/parse/struct-4.C (working copy)
@@ -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()
Index: testsuite/g++.dg/template/error2.C
===================================================================
--- testsuite/g++.dg/template/error2.C (revision 210624)
+++ testsuite/g++.dg/template/error2.C (working copy)
@@ -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 >
Index: testsuite/g++.dg/template/inherit8.C
===================================================================
--- testsuite/g++.dg/template/inherit8.C (revision 210624)
+++ testsuite/g++.dg/template/inherit8.C (working copy)
@@ -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" }
{
Index: testsuite/g++.dg/template/offsetof2.C
===================================================================
--- testsuite/g++.dg/template/offsetof2.C (revision 210624)
+++ testsuite/g++.dg/template/offsetof2.C (working copy)
@@ -1,7 +1,7 @@
// 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" }
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [C++ Patch] PR 58664
2014-05-19 22:45 [C++ Patch] PR 58664 Paolo Carlini
2014-05-20 0:11 ` Paolo Carlini
@ 2014-05-20 3:21 ` Jason Merrill
2014-05-20 8:47 ` Paolo Carlini
1 sibling, 1 reply; 5+ messages in thread
From: Jason Merrill @ 2014-05-20 3:21 UTC (permalink / raw)
To: Paolo Carlini, gcc-patches
On 05/19/2014 06:43 PM, Paolo Carlini wrote:
> 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);
Why not use cxx_incomplete_type_error in both cases?
Jason
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [C++ Patch] PR 58664
2014-05-20 3:21 ` Jason Merrill
@ 2014-05-20 8:47 ` Paolo Carlini
2014-05-20 13:02 ` Jason Merrill
0 siblings, 1 reply; 5+ messages in thread
From: Paolo Carlini @ 2014-05-20 8:47 UTC (permalink / raw)
To: Jason Merrill, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1483 bytes --]
Hi,
On 05/20/2014 04:50 AM, Jason Merrill wrote:
> On 05/19/2014 06:43 PM, Paolo Carlini wrote:
>> 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);
>
> Why not use cxx_incomplete_type_error in both cases?
In fact, my patch has a rather serious issue: the use of
cxx_incomplete_type_error means that we don't print anymore the name of
the field in the non-template case because we don't have yet a
FIELD_DECL yet, we have an IDENTIFIER_NODE. I think this is a
regression, in particular as long as our locations aren't always perfect
or the user decides to disable the caret.
Then, about your specific point, I don't think the additional inform
facility automatically provided by cxx_incomplete_type_error is normally
useful in the !unqualified_id case: if you consider, for example,
parse/crash31.C below, clang++ also doesn't print any notes in such
cases. Then I think we can as well leave that error alone (and
consistent with the other error)
Thanks,
Paolo.
PS: note that initialized doesn't play any role in the unqualified_id
case: either we don't have an array at all or its element-type is
incomplete, eg:
struct S
{
int a[];
};
is simply accepted of course (COMPLETE_TYPE_P (complete_type (type)) is
true).
//////////////////////
[-- Attachment #2: CL_58664_c --]
[-- Type: text/plain, Size: 608 bytes --]
/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.
/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.
[-- Attachment #3: patch_58664_c --]
[-- Type: text/plain, Size: 8320 bytes --]
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 210625)
+++ cp/cp-tree.h (working copy)
@@ -6158,6 +6158,7 @@ extern void cxx_incomplete_type_diagnostic (const_
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);
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 210622)
+++ cp/decl.c (working copy)
@@ -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);
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c (revision 210623)
+++ cp/typeck2.c (working copy)
@@ -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. */
+
+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,
"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:
Index: testsuite/g++.dg/cpp0x/nsdmi-union6.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi-union6.C (revision 0)
+++ testsuite/g++.dg/cpp0x/nsdmi-union6.C (working copy)
@@ -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>;
Index: testsuite/g++.dg/cpp0x/nsdmi6.C
===================================================================
--- testsuite/g++.dg/cpp0x/nsdmi6.C (revision 210622)
+++ testsuite/g++.dg/cpp0x/nsdmi6.C (working copy)
@@ -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" }
};
Index: testsuite/g++.dg/parse/crash31.C
===================================================================
--- testsuite/g++.dg/parse/crash31.C (revision 210624)
+++ testsuite/g++.dg/parse/crash31.C (working copy)
@@ -1,4 +1,4 @@
-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" }
Index: testsuite/g++.dg/parse/pr58664.C
===================================================================
--- testsuite/g++.dg/parse/pr58664.C (revision 0)
+++ testsuite/g++.dg/parse/pr58664.C (working copy)
@@ -0,0 +1,66 @@
+// 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>;
Index: testsuite/g++.dg/template/error2.C
===================================================================
--- testsuite/g++.dg/template/error2.C (revision 210624)
+++ testsuite/g++.dg/template/error2.C (working copy)
@@ -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 >
Index: testsuite/g++.dg/template/inherit8.C
===================================================================
--- testsuite/g++.dg/template/inherit8.C (revision 210624)
+++ testsuite/g++.dg/template/inherit8.C (working copy)
@@ -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" }
{
Index: testsuite/g++.dg/template/offsetof2.C
===================================================================
--- testsuite/g++.dg/template/offsetof2.C (revision 210624)
+++ testsuite/g++.dg/template/offsetof2.C (working copy)
@@ -1,7 +1,7 @@
// 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" }
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [C++ Patch] PR 58664
2014-05-20 8:47 ` Paolo Carlini
@ 2014-05-20 13:02 ` Jason Merrill
0 siblings, 0 replies; 5+ messages in thread
From: Jason Merrill @ 2014-05-20 13:02 UTC (permalink / raw)
To: Paolo Carlini, gcc-patches
OK.
Jason
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2014-05-20 13:02 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-19 22:45 [C++ Patch] PR 58664 Paolo Carlini
2014-05-20 0:11 ` Paolo Carlini
2014-05-20 3:21 ` Jason Merrill
2014-05-20 8:47 ` Paolo Carlini
2014-05-20 13:02 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).