diff options
author | Paolo Carlini <paolo.carlini@oracle.com> | 2014-05-20 13:30:40 +0000 |
---|---|---|
committer | Paolo Carlini <paolo@gcc.gnu.org> | 2014-05-20 13:30:40 +0000 |
commit | bdb5a9a30cf2074db776dc282ebdb135f25c36f0 (patch) | |
tree | d29484697370877d0d243dce67d839ba214c6e9a /gcc | |
parent | e9ea51852552d10fda782a2892f735a85d183368 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 11 | ||||
-rw-r--r-- | gcc/cp/typeck2.c | 28 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/nsdmi-union6.C | 56 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/nsdmi6.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/crash31.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/parse/pr58664.C | 66 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/error2.C | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/inherit8.C | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/offsetof2.C | 2 |
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" } |