From 23bee8f4f1c78abc6d2cfad600424d7b37f60557 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 21 May 2008 21:56:03 +0200 Subject: [PATCH] re PR c++/36023 (ICE with cast to variable-sized object) PR c++/36023 * cp-tree.h (check_array_initializer): New prototype. * decl.c (check_array_initializer): New function. (check_initializer): Call it. * semantics.c (finish_compound_literal): Call it for ARRAY_TYPEs. * g++.dg/ext/complit10.C: New test. From-SVN: r135734 --- gcc/ChangeLog | 8 +++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 52 ++++++++++++++++++---------- gcc/cp/semantics.c | 3 ++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/ext/complit10.C | 20 +++++++++++ 6 files changed, 71 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/complit10.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b71520e4550..f87d30c73a2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2008-05-21 Jakub Jelinek + + PR c++/36023 + * cp-tree.h (check_array_initializer): New prototype. + * decl.c (check_array_initializer): New function. + (check_initializer): Call it. + * semantics.c (finish_compound_literal): Call it for ARRAY_TYPEs. + 2008-05-21 Kai Tietz PR/36280 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 8d223bc6f27..0c3d0dd21aa 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4211,6 +4211,7 @@ extern tree shadow_tag (cp_decl_specifier_seq *); extern tree groktypename (cp_decl_specifier_seq *, const cp_declarator *); extern tree start_decl (const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree, tree *); extern void start_decl_1 (tree, bool); +extern bool check_array_initializer (tree, tree, tree); extern void cp_finish_decl (tree, tree, bool, tree, int); extern void finish_decl (tree, tree, tree); extern int cp_complete_array_type (tree *, tree, bool); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 8b9b2114417..0898d5d7fd2 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4894,6 +4894,38 @@ reshape_init (tree type, tree init) return new_init; } +/* Verify array initializer. Returns true if errors have been reported. */ + +bool +check_array_initializer (tree decl, tree type, tree init) +{ + tree element_type = TREE_TYPE (type); + + /* The array type itself need not be complete, because the + initializer may tell us how many elements are in the array. + But, the elements of the array must be complete. */ + if (!COMPLETE_TYPE_P (complete_type (element_type))) + { + if (decl) + error ("elements of array %q#D have incomplete type", decl); + else + error ("elements of array %q#T have incomplete type", type); + return true; + } + /* It is not valid to initialize a VLA. */ + if (init + && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type))) + || !TREE_CONSTANT (TYPE_SIZE (element_type)))) + { + if (decl) + error ("variable-sized object %qD may not be initialized", decl); + else + error ("variable-sized compound literal"); + return true; + } + return false; +} + /* Verify INIT (the initializer for DECL), and record the initialization in DECL_INITIAL, if appropriate. CLEANUP is as for grok_reference_init. @@ -4917,24 +4949,8 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup) if (TREE_CODE (type) == ARRAY_TYPE) { - tree element_type = TREE_TYPE (type); - - /* The array type itself need not be complete, because the - initializer may tell us how many elements are in the array. - But, the elements of the array must be complete. */ - if (!COMPLETE_TYPE_P (complete_type (element_type))) - { - error ("elements of array %q#D have incomplete type", decl); - return NULL_TREE; - } - /* It is not valid to initialize a VLA. */ - if (init - && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type))) - || !TREE_CONSTANT (TYPE_SIZE (element_type)))) - { - error ("variable-sized object %qD may not be initialized", decl); - return NULL_TREE; - } + if (check_array_initializer (decl, type, init)) + return NULL_TREE; } else if (!COMPLETE_TYPE_P (type)) { diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 192cfa64197..d35319e7207 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2123,6 +2123,9 @@ finish_compound_literal (tree type, VEC(constructor_elt,gc) *initializer_list) } type = complete_type (type); + if (TREE_CODE (type) == ARRAY_TYPE + && check_array_initializer (NULL_TREE, type, compound_literal)) + return error_mark_node; compound_literal = reshape_init (type, compound_literal); if (TREE_CODE (type) == ARRAY_TYPE) cp_complete_array_type (&type, compound_literal, false); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5142bdf4dcc..11f44b99e7e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-05-21 Jakub Jelinek + + PR c++/36023 + * g++.dg/ext/complit10.C: New test. + 2008-05-21 Janis Johnson * gfortran.dg/nint_2.f90: XFAIL only when using -O0. diff --git a/gcc/testsuite/g++.dg/ext/complit10.C b/gcc/testsuite/g++.dg/ext/complit10.C new file mode 100644 index 00000000000..7f159f0f707 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/complit10.C @@ -0,0 +1,20 @@ +// PR c++/36023 +// { dg-do compile } +// { dg-options "" } + +struct A; + +void +f1 (int i) +{ + (int[i]) { 1 }; // { dg-error "variable-sized compound literal" } + (A[5]) { 1 }; // { dg-error "have incomplete type" } + (A[i]) { 1 }; // { dg-error "have incomplete type" } +} + +void +f2 () +{ + (int[]) { 1 }; + (int[1]) { 1 }; +} -- 2.30.2