aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2014-05-20 13:30:40 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2014-05-20 13:30:40 +0000
commitbdb5a9a30cf2074db776dc282ebdb135f25c36f0 (patch)
treed29484697370877d0d243dce67d839ba214c6e9a /gcc
parente9ea51852552d10fda782a2892f735a85d183368 (diff)
downloadgcc-bdb5a9a30cf2074db776dc282ebdb135f25c36f0.zip
gcc-bdb5a9a30cf2074db776dc282ebdb135f25c36f0.tar.gz
gcc-bdb5a9a30cf2074db776dc282ebdb135f25c36f0.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/decl.c11
-rw-r--r--gcc/cp/typeck2.c28
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-union6.C56
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi6.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/crash31.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/pr58664.C66
-rw-r--r--gcc/testsuite/g++.dg/template/error2.C3
-rw-r--r--gcc/testsuite/g++.dg/template/inherit8.C2
-rw-r--r--gcc/testsuite/g++.dg/template/offsetof2.C2
12 files changed, 176 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 822f79b..b15a9c9 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index d13d71d..32a8afb 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index a29e3e3..81f12731 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index fb1546f..72995e9 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -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:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f4c9995..95ceb39 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,14 @@
+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.
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-union6.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-union6.C
new file mode 100644
index 0000000..764fe21
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-union6.C
@@ -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>;
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi6.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi6.C
index e78f500..f88a347 100644
--- a/gcc/testsuite/g++.dg/cpp0x/nsdmi6.C
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi6.C
@@ -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" }
};
diff --git a/gcc/testsuite/g++.dg/parse/crash31.C b/gcc/testsuite/g++.dg/parse/crash31.C
index c22ad5e..e7d6bdc 100644
--- a/gcc/testsuite/g++.dg/parse/crash31.C
+++ b/gcc/testsuite/g++.dg/parse/crash31.C
@@ -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" }
diff --git a/gcc/testsuite/g++.dg/parse/pr58664.C b/gcc/testsuite/g++.dg/parse/pr58664.C
new file mode 100644
index 0000000..489259a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/pr58664.C
@@ -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>;
diff --git a/gcc/testsuite/g++.dg/template/error2.C b/gcc/testsuite/g++.dg/template/error2.C
index be5ab1d..a7f199e 100644
--- a/gcc/testsuite/g++.dg/template/error2.C
+++ b/gcc/testsuite/g++.dg/template/error2.C
@@ -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 >
diff --git a/gcc/testsuite/g++.dg/template/inherit8.C b/gcc/testsuite/g++.dg/template/inherit8.C
index f2ebd5c..62a0f1d 100644
--- a/gcc/testsuite/g++.dg/template/inherit8.C
+++ b/gcc/testsuite/g++.dg/template/inherit8.C
@@ -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" }
{
diff --git a/gcc/testsuite/g++.dg/template/offsetof2.C b/gcc/testsuite/g++.dg/template/offsetof2.C
index 6f741a9..3f08f9b 100644
--- a/gcc/testsuite/g++.dg/template/offsetof2.C
+++ b/gcc/testsuite/g++.dg/template/offsetof2.C
@@ -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" }