From: Martin Sebor Date: Tue, 24 May 2016 20:29:36 +0000 (+0000) Subject: PR c++/71147 - [6 Regression] Flexible array member wrongly rejected in template X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f65e97fd3dc83bdbe6a1415f9527e68c35b841b3;p=gcc.git PR c++/71147 - [6 Regression] Flexible array member wrongly rejected in template gcc/ChangeLog: 2016-05-24 Martin Sebor PR c++/71147 * gcc/tree.h (complete_or_array_type_p): New inline function. gcc/testsuite/ChangeLog: 2016-05-24 Martin Sebor PR c++/71147 * g++.dg/ext/flexary16.C: New test. gcc/cp/ChangeLog: 2016-05-24 Martin Sebor PR c++/71147 * decl.c (layout_var_decl, grokdeclarator): Use complete_or_array_type_p. * pt.c (instantiate_class_template_1): Try to complete the element type of a flexible array member. (can_complete_type_without_circularity): Handle arrays of unknown bound. * typeck.c (complete_type): Also complete the type of the elements of arrays with an unspecified bound. From-SVN: r236664 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8c61f1d1539..b07aa808891 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-05-24 Martin Sebor + + PR c++/71147 + * gcc/tree.h (complete_or_array_type_p): New inline function. + 2016-05-24 Jakub Jelinek * config/i386/i386.h (TARGET_AVOID_4BYTE_PREFIXES): Define. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 4e06a71e7ca..5e7eb3d0e4c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2016-05-24 Martin Sebor + + PR c++/71147 + * decl.c (layout_var_decl, grokdeclarator): Use complete_or_array_type_p. + * pt.c (instantiate_class_template_1): Try to complete the element + type of a flexible array member. + (can_complete_type_without_circularity): Handle arrays of unknown bound. + * typeck.c (complete_type): Also complete the type of the elements of + arrays with an unspecified bound. + 2016-05-24 Paolo Carlini PR c++/69872 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 7a69711bdb1..ef5fd665b46 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -5305,10 +5305,7 @@ layout_var_decl (tree decl) complete_type (type); if (!DECL_SIZE (decl) && TREE_TYPE (decl) != error_mark_node - && (COMPLETE_TYPE_P (type) - || (TREE_CODE (type) == ARRAY_TYPE - && !TYPE_DOMAIN (type) - && COMPLETE_TYPE_P (TREE_TYPE (type))))) + && complete_or_array_type_p (type)) layout_decl (decl, 0); if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE) @@ -11165,8 +11162,7 @@ grokdeclarator (const cp_declarator *declarator, } else if (!staticp && !dependent_type_p (type) && !COMPLETE_TYPE_P (complete_type (type)) - && (TREE_CODE (type) != ARRAY_TYPE - || !COMPLETE_TYPE_P (TREE_TYPE (type)) + && (!complete_or_array_type_p (type) || initialized == 0)) { if (TREE_CODE (type) != ARRAY_TYPE diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3e07fb0b6e0..df3d634687d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -9555,7 +9555,7 @@ can_complete_type_without_circularity (tree type) return 0; else if (COMPLETE_TYPE_P (type)) return 1; - else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type)) + else if (TREE_CODE (type) == ARRAY_TYPE) return can_complete_type_without_circularity (TREE_TYPE (type)); else if (CLASS_TYPE_P (type) && TYPE_BEING_DEFINED (TYPE_MAIN_VARIANT (type))) @@ -10120,17 +10120,12 @@ instantiate_class_template_1 (tree type) if (can_complete_type_without_circularity (rtype)) complete_type (rtype); - if (TREE_CODE (r) == FIELD_DECL - && TREE_CODE (rtype) == ARRAY_TYPE - && COMPLETE_TYPE_P (TREE_TYPE (rtype)) - && !COMPLETE_TYPE_P (rtype)) - { - /* Flexible array mmembers of elements - of complete type have an incomplete type - and that's okay. */ - } - else if (!COMPLETE_TYPE_P (rtype)) + if (!complete_or_array_type_p (rtype)) { + /* If R's type couldn't be completed and + it isn't a flexible array member (whose + type is incomplete by definition) give + an error. */ cxx_incomplete_type_error (r, rtype); TREE_TYPE (r) = error_mark_node; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 8b3fec66250..f68c2a34024 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -112,7 +112,7 @@ complete_type (tree type) if (type == error_mark_node || COMPLETE_TYPE_P (type)) ; - else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type)) + else if (TREE_CODE (type) == ARRAY_TYPE) { tree t = complete_type (TREE_TYPE (type)); unsigned int needs_constructing, has_nontrivial_dtor; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d88618eebb2..6c03e26718b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-05-24 Martin Sebor + + PR c++/71147 + * g++.dg/ext/flexary16.C: New test. + 2016-05-24 Ilya Verbin * gcc.target/i386/avx-ceil-sfix-2-vec.c: Define __NO_MATH_INLINES before diff --git a/gcc/testsuite/g++.dg/ext/flexary16.C b/gcc/testsuite/g++.dg/ext/flexary16.C new file mode 100644 index 00000000000..a3e040d7c1b --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/flexary16.C @@ -0,0 +1,37 @@ +// PR c++/71147 - [6 Regression] Flexible array member wrongly rejected +// in template +// { dg-do compile } + +template +struct container +{ + struct elem { + unsigned u; + }; + + struct incomplete { + int x; + elem array[]; + }; +}; + +unsigned f (container::incomplete* i) +{ + return i->array [0].u; +} + + +template +struct D: container +{ + struct S { + int x; + typename container::elem array[]; + }; +}; + + +unsigned g (D::S *s) +{ + return s->array [0].u; +} diff --git a/gcc/tree.h b/gcc/tree.h index 2510d166ea6..90413fcf209 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4753,6 +4753,17 @@ ptrofftype_p (tree type) && TYPE_UNSIGNED (type) == TYPE_UNSIGNED (sizetype)); } +/* Return true if the argument is a complete type or an array + of unknown bound (whose type is incomplete but) whose elements + have complete type. */ +static inline bool +complete_or_array_type_p (const_tree type) +{ + return COMPLETE_TYPE_P (type) + || (TREE_CODE (type) == ARRAY_TYPE + && COMPLETE_TYPE_P (TREE_TYPE (type))); +} + extern tree strip_float_extensions (tree); extern int really_constant_p (const_tree); extern bool decl_address_invariant_p (const_tree);