* [C++ Patch] for c++/51214 @ 2012-02-28 20:57 Fabien Chêne 2012-02-28 22:06 ` Paolo Carlini 2012-02-28 23:22 ` Jason Merrill 0 siblings, 2 replies; 17+ messages in thread From: Fabien Chêne @ 2012-02-28 20:57 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches [-- Attachment #1: Type: text/plain, Size: 919 bytes --] Hi, The problem in this PR is that the CLASSTYPE_SORTED_FIELDS is created too early (in finish_struct_1) to handle those "late" unscoped enum definitions. Consequently, I propose to lately add those names in CLASSTYPE_SORTED_FIELDS when they are encountered, in build_enumerator. Tested x86_64-unknown-linux-gnu, OK for 4.7 ? gcc/testsuite/ChangeLog 2012-02-27 Fabien Chêne <fabien@gcc.gnu.org> * g++.dg/cpp0x/forw_enum11.C: New. gcc/cp/ChangeLog 2012-02-27 Fabien Chêne <fabien@gcc.gnu.org> * cp-tree.h (insert_into_classtype_sorted_fields): Declare. * class.c (finish_struct_1): Move the code into insert_into_classtype_sorted_fields, and call it. (insert_into_classtype_sorted_fields): Define. * decl.c (build_enumerator): Call insert_into_classtype_sorted_fields if an enumerator-definition referring to a class scope opaque enum has been encountered. -- Fabien [-- Attachment #2: 51214.patch --] [-- Type: application/octet-stream, Size: 3562 bytes --] Index: gcc/testsuite/g++.dg/cpp0x/forw_enum11.C =================================================================== --- gcc/testsuite/g++.dg/cpp0x/forw_enum11.C (revision 0) +++ gcc/testsuite/g++.dg/cpp0x/forw_enum11.C (revision 0) @@ -0,0 +1,12 @@ +// { dg-do compile { target c++11 } } + +enum { A = 1 }; +struct T +{ + int i1, i2, i3, i4, i5, i6, i7; + enum E2 : int; +}; + +enum T::E2 : int { A1 = A, A2 = 23 }; +int i = T::A1; +int j = T::A2; Index: gcc/cp/class.c =================================================================== --- gcc/cp/class.c (revision 184327) +++ gcc/cp/class.c (working copy) @@ -5954,7 +5954,6 @@ finish_struct_1 (tree t) tree x; /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */ tree virtuals = NULL_TREE; - int n_fields = 0; if (COMPLETE_TYPE_P (t)) { @@ -6071,16 +6070,7 @@ finish_struct_1 (tree t) We use a small number because most searches fail (succeeding ultimately as the search bores through the inheritance hierarchy), and we want this failure to occur quickly. */ - - n_fields = count_fields (TYPE_FIELDS (t)); - if (n_fields > 7) - { - struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); - add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0); - qsort (field_vec->elts, n_fields, sizeof (tree), - field_decl_cmp); - CLASSTYPE_SORTED_FIELDS (t) = field_vec; - } + insert_into_classtype_sorted_fields (TYPE_FIELDS (t), t, 8); /* Complain if one of the field types requires lower visibility. */ constrain_class_visibility (t); @@ -6153,6 +6143,22 @@ finish_struct_1 (tree t) } } +/* Insert FIELDS into T for the sorted case if the FIELDS count is + equal to THREASHOLD or greater than THREASHOLD. */ + +void insert_into_classtype_sorted_fields (tree fields, tree t, int threashold) +{ + int n_fields = count_fields (fields); + if (n_fields >= threashold) + { + struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); + add_fields_to_record_type (fields, field_vec, 0); + qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); + CLASSTYPE_SORTED_FIELDS (t) = field_vec; + } +} + + /* When T was built up, the member declarations were added in reverse order. Rearrange them to declaration order. */ Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 184328) +++ gcc/cp/decl.c (working copy) @@ -12517,7 +12517,12 @@ incremented enumerator value is too larg /* In something like `struct S { enum E { i = 7 }; };' we put `i' on the TYPE_FIELDS list for `S'. (That's so that you can say things like `S::i' later.) */ - finish_member_declaration (decl); + { + finish_member_declaration (decl); + if (COMPLETE_TYPE_P (current_class_type) + && UNSCOPED_ENUM_P (enumtype)) + insert_into_classtype_sorted_fields (decl, current_class_type, 0); + } else pushdecl (decl); Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 184327) +++ gcc/cp/cp-tree.h (working copy) @@ -4969,6 +4969,7 @@ extern void fixup_attribute_variants (t extern tree* decl_cloned_function_p (const_tree, bool); extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); +extern void insert_into_classtype_sorted_fields (tree, tree, int); /* in cvt.c */ extern tree convert_to_reference (tree, tree, int, int, tree); ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-02-28 20:57 [C++ Patch] for c++/51214 Fabien Chêne @ 2012-02-28 22:06 ` Paolo Carlini 2012-02-28 23:22 ` Jason Merrill 1 sibling, 0 replies; 17+ messages in thread From: Paolo Carlini @ 2012-02-28 22:06 UTC (permalink / raw) To: Fabien Chêne; +Cc: Jason Merrill, GCC Patches Minor nit: the correct spelling is threshold, not threashold. Thanks, Paolo. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-02-28 20:57 [C++ Patch] for c++/51214 Fabien Chêne 2012-02-28 22:06 ` Paolo Carlini @ 2012-02-28 23:22 ` Jason Merrill 2012-02-28 23:28 ` Fabien Chêne 1 sibling, 1 reply; 17+ messages in thread From: Jason Merrill @ 2012-02-28 23:22 UTC (permalink / raw) To: Fabien Chêne; +Cc: GCC Patches On 02/28/2012 03:36 PM, Fabien Chêne wrote: > * decl.c (build_enumerator): Call > insert_into_classtype_sorted_fields if an enumerator-definition referring > to a class scope opaque enum has been encountered. This will insert and sort the vector again for each enumerator; we should wait and sort after we've seen all of them. Will unqualified lookup work because we're in the enumeration scope, or do we need to make lookup in the class work? > + equal to THREASHOLD or greater than THREASHOLD. */ No 'a' in "threshold". Jason ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-02-28 23:22 ` Jason Merrill @ 2012-02-28 23:28 ` Fabien Chêne 2012-02-29 7:56 ` Fabien Chêne 2012-02-29 15:31 ` Jason Merrill 0 siblings, 2 replies; 17+ messages in thread From: Fabien Chêne @ 2012-02-28 23:28 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches 2012/2/28 Jason Merrill <jason@redhat.com>: > On 02/28/2012 03:36 PM, Fabien Chêne wrote: >> >> * decl.c (build_enumerator): Call >> insert_into_classtype_sorted_fields if an enumerator-definition >> referring >> to a class scope opaque enum has been encountered. > > > This will insert and sort the vector again for each enumerator; we should > wait and sort after we've seen all of them. I agree, this is not efficient but I didn't find a better place. perhaps in cp_parser_enumerator_list, that would require adding an additional parameter to keep track of all the enum DECLs. Is it what you have in mind ? > Will unqualified lookup work > because we're in the enumeration scope, or do we need to make lookup in the > class work? Sorry, could you specify what you mean ? -- Fabien ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-02-28 23:28 ` Fabien Chêne @ 2012-02-29 7:56 ` Fabien Chêne 2012-02-29 15:31 ` Jason Merrill 1 sibling, 0 replies; 17+ messages in thread From: Fabien Chêne @ 2012-02-29 7:56 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches 2012/2/28 Fabien Chêne <fabien.chene@gmail.com>: > 2012/2/28 Jason Merrill <jason@redhat.com>: >> On 02/28/2012 03:36 PM, Fabien Chêne wrote: [...] >> Will unqualified lookup work >> because we're in the enumeration scope, or do we need to make lookup in the >> class work? Unqualified lookup works because when the type is not complete, the lookup uses the non sorted case, which always works. -- Fabien ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-02-28 23:28 ` Fabien Chêne 2012-02-29 7:56 ` Fabien Chêne @ 2012-02-29 15:31 ` Jason Merrill 2012-05-06 20:07 ` Fabien Chêne 1 sibling, 1 reply; 17+ messages in thread From: Jason Merrill @ 2012-02-29 15:31 UTC (permalink / raw) To: Fabien Chêne; +Cc: GCC Patches On 02/28/2012 05:06 PM, Fabien Chêne wrote: > I agree, this is not efficient but I didn't find a better place. > perhaps in cp_parser_enumerator_list, that would require adding an > additional parameter to keep track of all the enum DECLs. Is it what > you have in mind ? I was thinking of finish_enum_value_list. > Unqualified lookup works because when the type is not complete, the > lookup uses the non sorted case, which always works. OK, just make sure we have a test for that. Jason ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-02-29 15:31 ` Jason Merrill @ 2012-05-06 20:07 ` Fabien Chêne 2012-05-07 14:41 ` Jason Merrill 0 siblings, 1 reply; 17+ messages in thread From: Fabien Chêne @ 2012-05-06 20:07 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches [-- Attachment #1: Type: text/plain, Size: 1954 bytes --] 2012/2/29 Jason Merrill <jason@redhat.com>: > On 02/28/2012 05:06 PM, Fabien Chêne wrote: >> >> I agree, this is not efficient but I didn't find a better place. >> perhaps in cp_parser_enumerator_list, that would require adding an >> additional parameter to keep track of all the enum DECLs. Is it what >> you have in mind ? > > I was thinking of finish_enum_value_list. OK great. I have tried to reuse the existing infrastructure to extend the CLASSTYPE_SORTED_FIELDS, unfortunately, it does not seem possible because the code uses a tree chain (chained with DECL_CHAIN), and this field is already used for enum values to store the enum type. Among various possibilities, in the end, I think it is clearer to handle the lately defined enum case separately. That is what I have done in the attached patch. >> Unqualified lookup works because when the type is not complete, the >> lookup uses the non sorted case, which always works. > > OK, just make sure we have a test for that. I have added a check in forw_enum11.C for that. Boostrapped and tested on x86_64-unknown-linux-gnu, OK to commit ? gcc/testsuite/ChangeLog 2012-05-06 Fabien Chêne <fabien@gcc.gnu.org> PR c++/51214 * g++.dg/cpp0x/forw_enum11.C: New. gcc/cp/ChangeLog 2012-05-06 Fabien Chêne <fabien@gcc.gnu.org> PR c++/51214 * cp-tree.h (insert_late_enum_def_into_classtype_sorted_fields): Declare. * class.c (insert_into_classtype_sorted_fields): New. (add_enum_fields_to_record_type): New. (count_fields): Adjust the comment. (add_fields_to_record_type): Likewise. (finish_struct_1): Move the code that inserts the fields for the sorted case, into insert_into_classtype_sorted_fields, and call it. (insert_late_enum_def_into_classtype_sorted_fields): Define. * decl.c (finish_enum_value_list): Call insert_late_enum_def_into_classtype_sorted_fields if a late enum definition is encountered. -- Fabien [-- Attachment #2: pr51214.patch --] [-- Type: application/octet-stream, Size: 7473 bytes --] Index: testsuite/g++.dg/cpp0x/forw_enum11.C =================================================================== --- testsuite/g++.dg/cpp0x/forw_enum11.C (revision 0) +++ testsuite/g++.dg/cpp0x/forw_enum11.C (revision 0) @@ -0,0 +1,23 @@ +// { dg-do compile { target c++11 } } + +enum { A = 1 }; +struct T +{ + int i1, i2, i3, i4, i5, i6, i7; + enum E2 : int; + + void f(); +}; + +enum T::E2 : int { A1 = A, A2 = 23 }; + +static_assert(int(T::A1) == 1, "error"); +static_assert(int(T::A2) == 23, "error"); + +void T::f() +{ + static_assert(int(T::A1) == 1, "error"); + static_assert(int(T::A2) == 23, "error"); + static_assert(int(A1) == 1, "error"); + static_assert(int(A2) == 23, "error"); +} Index: cp/class.c =================================================================== --- cp/class.c (revision 186674) +++ cp/class.c (working copy) @@ -139,6 +139,7 @@ static void build_vtbl_initializer (tree VEC(constructor_elt,gc) **); static int count_fields (tree); static int add_fields_to_record_type (tree, struct sorted_fields_type*, int); +static void insert_into_classtype_sorted_fields (tree, tree, int); static bool check_bitfield_decl (tree); static void check_field_decl (tree, tree, int *, int *, int *); static void check_field_decls (tree, tree *, int *, int *); @@ -2832,8 +2833,9 @@ add_implicitly_declared_members (tree t, declare_virt_assop_and_dtor (t); } -/* Subroutine of finish_struct_1. Recursively count the number of fields - in TYPE, including anonymous union members. */ +/* Subroutine of insert_into_classtype_sorted_fields. Recursively + count the number of fields in TYPE, including anonymous union + members. */ static int count_fields (tree fields) @@ -2850,8 +2852,9 @@ count_fields (tree fields) return n_fields; } -/* Subroutine of finish_struct_1. Recursively add all the fields in the - TREE_LIST FIELDS to the SORTED_FIELDS_TYPE elts, starting at offset IDX. */ +/* Subroutine of insert_into_classtype_sorted_fields. Recursively add + all the fields in the TREE_LIST FIELDS to the SORTED_FIELDS_TYPE + elts, starting at offset IDX. */ static int add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx) @@ -2867,6 +2870,20 @@ add_fields_to_record_type (tree fields, return idx; } +/* Add all the fields in the ENUM_FIELDS to the FIELD_VEC elts, + starting at offset IDX. */ + +static int +add_enum_fields_to_record_type (VEC(tree,gc)* enum_fields, + struct sorted_fields_type *field_vec, int idx) +{ + tree enum_field; + int i; + for (i = 0; VEC_iterate(tree, enum_fields, i, enum_field); ++i) + field_vec->elts[idx++] = enum_field; + return idx; +} + /* FIELD is a bit-field. We are finishing the processing for its enclosing type. Issue any appropriate messages and set appropriate flags. Returns false if an error has been diagnosed. */ @@ -5998,7 +6015,6 @@ finish_struct_1 (tree t) tree x; /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */ tree virtuals = NULL_TREE; - int n_fields = 0; if (COMPLETE_TYPE_P (t)) { @@ -6116,15 +6132,7 @@ finish_struct_1 (tree t) ultimately as the search bores through the inheritance hierarchy), and we want this failure to occur quickly. */ - n_fields = count_fields (TYPE_FIELDS (t)); - if (n_fields > 7) - { - struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); - add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0); - qsort (field_vec->elts, n_fields, sizeof (tree), - field_decl_cmp); - CLASSTYPE_SORTED_FIELDS (t) = field_vec; - } + insert_into_classtype_sorted_fields (TYPE_FIELDS (t), t, 8); /* Complain if one of the field types requires lower visibility. */ constrain_class_visibility (t); @@ -6197,6 +6205,44 @@ finish_struct_1 (tree t) } } +/* Insert FIELDS into T for the sorted case if the FIELDS count is + equal to THRESHOLD or greater than THRESHOLD. */ + +static void +insert_into_classtype_sorted_fields (tree fields, tree t, int threshold) +{ + int n_fields = count_fields (fields); + if (n_fields >= threshold) + { + struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); + add_fields_to_record_type (fields, field_vec, 0); + qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); + CLASSTYPE_SORTED_FIELDS (t) = field_vec; + } +} + +/* Insert lately defined ENUM_FIELDS into T for the sorted case. */ + +void +insert_late_enum_def_into_classtype_sorted_fields (VEC(tree,gc) *enum_fields, + tree t) +{ + struct sorted_fields_type *sorted_fields = CLASSTYPE_SORTED_FIELDS (t); + if (sorted_fields) + { + int i; + int n_fields = VEC_length (tree, enum_fields) + sorted_fields->len; + struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); + + for (i = 0; i < sorted_fields->len; ++i) + field_vec->elts[i] = sorted_fields->elts[i]; + + add_enum_fields_to_record_type (enum_fields, field_vec, sorted_fields->len); + qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); + CLASSTYPE_SORTED_FIELDS (t) = field_vec; + } +} + /* When T was built up, the member declarations were added in reverse order. Rearrange them to declaration order. */ Index: cp/decl.c =================================================================== --- cp/decl.c (revision 186674) +++ cp/decl.c (working copy) @@ -12200,6 +12200,7 @@ finish_enum_value_list (tree enumtype) tree value; tree minnode, maxnode; tree t; + VEC(tree,gc) *late_enum_values = NULL; bool fixed_underlying_type_p = ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE; @@ -12355,6 +12356,11 @@ finish_enum_value_list (tree enumtype) else underlying_type = ENUM_UNDERLYING_TYPE (enumtype); + if (current_class_type + && COMPLETE_TYPE_P (current_class_type) + && UNSCOPED_ENUM_P (enumtype)) + late_enum_values = make_tree_vector(); + /* Convert each of the enumerators to the type of the underlying type of the enumeration. */ for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values)) @@ -12379,12 +12385,22 @@ finish_enum_value_list (tree enumtype) TREE_TYPE (value) = enumtype; DECL_INITIAL (decl) = value; + + if (late_enum_values) + VEC_safe_push (tree, gc, late_enum_values, decl); } /* Fix up all variant types of this enum type. */ for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t)) TYPE_VALUES (t) = TYPE_VALUES (enumtype); + if (late_enum_values) + { + insert_late_enum_def_into_classtype_sorted_fields (late_enum_values, + current_class_type); + release_tree_vector (late_enum_values); + } + /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, namespace_bindings_p ()); } Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 186674) +++ cp/cp-tree.h (working copy) @@ -4979,6 +4979,8 @@ extern tree* decl_cloned_function_p (co extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); extern void deduce_noexcept_on_destructor (tree); +extern void insert_late_enum_def_into_classtype_sorted_fields (VEC(tree,gc) *, + tree); /* in cvt.c */ extern tree convert_to_reference (tree, tree, int, int, tree); ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-05-06 20:07 ` Fabien Chêne @ 2012-05-07 14:41 ` Jason Merrill 2012-05-23 20:38 ` Fabien Chêne 0 siblings, 1 reply; 17+ messages in thread From: Jason Merrill @ 2012-05-07 14:41 UTC (permalink / raw) To: Fabien Chêne; +Cc: GCC Patches On 05/06/2012 04:06 PM, Fabien Chêne wrote: > + if (late_enum_values) > + VEC_safe_push (tree, gc, late_enum_values, decl); I would think you could walk the TYPE_VALUES list directly, rather than copy it into a temporary VEC. Jason ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-05-07 14:41 ` Jason Merrill @ 2012-05-23 20:38 ` Fabien Chêne 2012-05-24 13:18 ` Jason Merrill 0 siblings, 1 reply; 17+ messages in thread From: Fabien Chêne @ 2012-05-23 20:38 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches [-- Attachment #1: Type: text/plain, Size: 1230 bytes --] 2012/5/7 Jason Merrill <jason@redhat.com>: > On 05/06/2012 04:06 PM, Fabien Chêne wrote: >> >> + if (late_enum_values) >> + VEC_safe_push (tree, gc, late_enum_values, decl); > > I would think you could walk the TYPE_VALUES list directly, rather than copy > it into a temporary VEC. Indeed, let's use good old tree lists. Tested x86_64-unknown-linux-gnu, OK for trunk and 4.7 ? gcc/testsuite/ChangeLog 2012-05-23 Fabien Chêne <fabien@gcc.gnu.org> PR c++/51214 * g++.dg/cpp0x/forw_enum11.C: New. gcc/cp/ChangeLog 2012-05-23 Fabien Chêne <fabien@gcc.gnu.org> PR c++/51214 * cp-tree.h (insert_late_enum_def_into_classtype_sorted_fields): Declare. * class.c (insert_into_classtype_sorted_fields): New. (add_enum_fields_to_record_type): New. (count_fields): Adjust the comment. (add_fields_to_record_type): Likewise. (finish_struct_1): Move the code that inserts the fields for the sorted case, into insert_into_classtype_sorted_fields, and call it. (insert_late_enum_def_into_classtype_sorted_fields): Define. * decl.c (finish_enum_value_list): Call insert_late_enum_def_into_classtype_sorted_fields if a late enum definition is encountered. -- Fabien [-- Attachment #2: 51214.patch --] [-- Type: application/octet-stream, Size: 6580 bytes --] Index: gcc/testsuite/g++.dg/cpp0x/forw_enum11.C =================================================================== --- gcc/testsuite/g++.dg/cpp0x/forw_enum11.C (revision 0) +++ gcc/testsuite/g++.dg/cpp0x/forw_enum11.C (revision 0) @@ -0,0 +1,23 @@ +// { dg-do compile { target c++11 } } + +enum { A = 1 }; +struct T +{ + int i1, i2, i3, i4, i5, i6, i7; + enum E2 : int; + + void f(); +}; + +enum T::E2 : int { A1 = A, A2 = 23 }; + +static_assert(int(T::A1) == 1, "error"); +static_assert(int(T::A2) == 23, "error"); + +void T::f() +{ + static_assert(int(T::A1) == 1, "error"); + static_assert(int(T::A2) == 23, "error"); + static_assert(int(A1) == 1, "error"); + static_assert(int(A2) == 23, "error"); +} Index: gcc/cp/class.c =================================================================== --- gcc/cp/class.c (revision 186674) +++ gcc/cp/class.c (working copy) @@ -139,6 +139,7 @@ static void build_vtbl_initializer (tree VEC(constructor_elt,gc) **); static int count_fields (tree); static int add_fields_to_record_type (tree, struct sorted_fields_type*, int); +static void insert_into_classtype_sorted_fields (tree, tree, int); static bool check_bitfield_decl (tree); static void check_field_decl (tree, tree, int *, int *, int *); static void check_field_decls (tree, tree *, int *, int *); @@ -2832,8 +2833,9 @@ add_implicitly_declared_members (tree t, declare_virt_assop_and_dtor (t); } -/* Subroutine of finish_struct_1. Recursively count the number of fields - in TYPE, including anonymous union members. */ +/* Subroutine of insert_into_classtype_sorted_fields. Recursively + count the number of fields in TYPE, including anonymous union + members. */ static int count_fields (tree fields) @@ -2850,8 +2852,9 @@ count_fields (tree fields) return n_fields; } -/* Subroutine of finish_struct_1. Recursively add all the fields in the - TREE_LIST FIELDS to the SORTED_FIELDS_TYPE elts, starting at offset IDX. */ +/* Subroutine of insert_into_classtype_sorted_fields. Recursively add + all the fields in the TREE_LIST FIELDS to the SORTED_FIELDS_TYPE + elts, starting at offset IDX. */ static int add_fields_to_record_type (tree fields, struct sorted_fields_type *field_vec, int idx) @@ -2867,6 +2870,20 @@ add_fields_to_record_type (tree fields, return idx; } +/* Add all of the enum values of ENUMTYPE, to the FIELD_VEC elts, + starting at offset IDX. */ + +static int +add_enum_fields_to_record_type (tree enumtype, + struct sorted_fields_type *field_vec, + int idx) +{ + tree values; + for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values)) + field_vec->elts[idx++] = TREE_VALUE (values); + return idx; +} + /* FIELD is a bit-field. We are finishing the processing for its enclosing type. Issue any appropriate messages and set appropriate flags. Returns false if an error has been diagnosed. */ @@ -5998,7 +6015,6 @@ finish_struct_1 (tree t) tree x; /* A TREE_LIST. The TREE_VALUE of each node is a FUNCTION_DECL. */ tree virtuals = NULL_TREE; - int n_fields = 0; if (COMPLETE_TYPE_P (t)) { @@ -6116,15 +6132,7 @@ finish_struct_1 (tree t) ultimately as the search bores through the inheritance hierarchy), and we want this failure to occur quickly. */ - n_fields = count_fields (TYPE_FIELDS (t)); - if (n_fields > 7) - { - struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); - add_fields_to_record_type (TYPE_FIELDS (t), field_vec, 0); - qsort (field_vec->elts, n_fields, sizeof (tree), - field_decl_cmp); - CLASSTYPE_SORTED_FIELDS (t) = field_vec; - } + insert_into_classtype_sorted_fields (TYPE_FIELDS (t), t, 8); /* Complain if one of the field types requires lower visibility. */ constrain_class_visibility (t); @@ -6197,6 +6205,45 @@ finish_struct_1 (tree t) } } +/* Insert FIELDS into T for the sorted case if the FIELDS count is + equal to THRESHOLD or greater than THRESHOLD. */ + +static void +insert_into_classtype_sorted_fields (tree fields, tree t, int threshold) +{ + int n_fields = count_fields (fields); + if (n_fields >= threshold) + { + struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); + add_fields_to_record_type (fields, field_vec, 0); + qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); + CLASSTYPE_SORTED_FIELDS (t) = field_vec; + } +} + +/* Insert lately defined enum ENUMTYPE into T for the sorted case. */ + +void +insert_late_enum_def_into_classtype_sorted_fields (tree enumtype, tree t) +{ + struct sorted_fields_type *sorted_fields = CLASSTYPE_SORTED_FIELDS (t); + if (sorted_fields) + { + int i; + int n_fields + = list_length (TYPE_VALUES (enumtype)) + sorted_fields->len; + struct sorted_fields_type *field_vec = sorted_fields_type_new (n_fields); + + for (i = 0; i < sorted_fields->len; ++i) + field_vec->elts[i] = sorted_fields->elts[i]; + + add_enum_fields_to_record_type (enumtype, field_vec, + sorted_fields->len); + qsort (field_vec->elts, n_fields, sizeof (tree), field_decl_cmp); + CLASSTYPE_SORTED_FIELDS (t) = field_vec; + } +} + /* When T was built up, the member declarations were added in reverse order. Rearrange them to declaration order. */ Index: gcc/cp/decl.c =================================================================== --- gcc/cp/decl.c (revision 186674) +++ gcc/cp/decl.c (working copy) @@ -12385,6 +12385,12 @@ finish_enum_value_list (tree enumtype) for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t)) TYPE_VALUES (t) = TYPE_VALUES (enumtype); + if (current_class_type + && COMPLETE_TYPE_P (current_class_type) + && UNSCOPED_ENUM_P (enumtype)) + insert_late_enum_def_into_classtype_sorted_fields (enumtype, + current_class_type); + /* Finish debugging output for this type. */ rest_of_type_compilation (enumtype, namespace_bindings_p ()); } Index: gcc/cp/cp-tree.h =================================================================== --- gcc/cp/cp-tree.h (revision 186674) +++ gcc/cp/cp-tree.h (working copy) @@ -4979,6 +4979,7 @@ extern tree* decl_cloned_function_p (co extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); extern void deduce_noexcept_on_destructor (tree); +extern void insert_late_enum_def_into_classtype_sorted_fields (tree, tree); /* in cvt.c */ extern tree convert_to_reference (tree, tree, int, int, tree); ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-05-23 20:38 ` Fabien Chêne @ 2012-05-24 13:18 ` Jason Merrill 2012-06-03 4:47 ` Jason Merrill 0 siblings, 1 reply; 17+ messages in thread From: Jason Merrill @ 2012-05-24 13:18 UTC (permalink / raw) To: Fabien Chêne; +Cc: GCC Patches OK, thanks. Jason ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-05-24 13:18 ` Jason Merrill @ 2012-06-03 4:47 ` Jason Merrill 2012-06-03 15:56 ` Fabien Chêne 0 siblings, 1 reply; 17+ messages in thread From: Jason Merrill @ 2012-06-03 4:47 UTC (permalink / raw) To: Fabien Chêne; +Cc: GCC Patches On 05/24/2012 09:18 AM, Jason Merrill wrote: > OK, thanks. I notice you haven't checked the patch in yet, is there a problem? Jason ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-06-03 4:47 ` Jason Merrill @ 2012-06-03 15:56 ` Fabien Chêne 2012-06-03 17:06 ` Gabriel Dos Reis 2012-06-07 5:40 ` Fabien Chêne 0 siblings, 2 replies; 17+ messages in thread From: Fabien Chêne @ 2012-06-03 15:56 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches 2012/6/3 Jason Merrill <jason@redhat.com>: > On 05/24/2012 09:18 AM, Jason Merrill wrote: >> >> OK, thanks. > > > I notice you haven't checked the patch in yet, is there a problem? Not at all, just lack of time, so many problems/holidays to tackle at the moment... That is May month in France ;-) I'll be checking in it the next few days. -- Fabien ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-06-03 15:56 ` Fabien Chêne @ 2012-06-03 17:06 ` Gabriel Dos Reis 2012-06-04 12:41 ` Fabien Chêne 2012-06-07 5:40 ` Fabien Chêne 1 sibling, 1 reply; 17+ messages in thread From: Gabriel Dos Reis @ 2012-06-03 17:06 UTC (permalink / raw) To: Fabien Chêne; +Cc: Jason Merrill, GCC Patches On Sun, Jun 3, 2012 at 10:56 AM, Fabien Chêne <fabien.chene@gmail.com> wrote: > 2012/6/3 Jason Merrill <jason@redhat.com>: >> On 05/24/2012 09:18 AM, Jason Merrill wrote: >>> >>> OK, thanks. >> >> >> I notice you haven't checked the patch in yet, is there a problem? > > Not at all, just lack of time, so many problems/holidays to tackle at > the moment... That is May month in France ;-) It must be distressing to make up for those 35 hours ;-p -- Gaby ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-06-03 17:06 ` Gabriel Dos Reis @ 2012-06-04 12:41 ` Fabien Chêne 0 siblings, 0 replies; 17+ messages in thread From: Fabien Chêne @ 2012-06-04 12:41 UTC (permalink / raw) To: Gabriel Dos Reis; +Cc: GCC Patches 2012/6/3 Gabriel Dos Reis <gdr@integrable-solutions.net>: > On Sun, Jun 3, 2012 at 10:56 AM, Fabien Chêne <fabien.chene@gmail.com> wrote: >> 2012/6/3 Jason Merrill <jason@redhat.com>: >>> On 05/24/2012 09:18 AM, Jason Merrill wrote: >>>> >>>> OK, thanks. >>> >>> >>> I notice you haven't checked the patch in yet, is there a problem? >> >> Not at all, just lack of time, so many problems/holidays to tackle at >> the moment... That is May month in France ;-) > > It must be distressing to make up for those 35 hours ;-p Provided we do not respond as an ideal gas (P = nRT/V), it should be fine ;-) -- Fabien ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-06-03 15:56 ` Fabien Chêne 2012-06-03 17:06 ` Gabriel Dos Reis @ 2012-06-07 5:40 ` Fabien Chêne 2012-06-27 18:26 ` Fabien Chêne 1 sibling, 1 reply; 17+ messages in thread From: Fabien Chêne @ 2012-06-07 5:40 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches 2012/6/3 Fabien Chêne <fabien.chene@gmail.com>: > 2012/6/3 Jason Merrill <jason@redhat.com>: >> On 05/24/2012 09:18 AM, Jason Merrill wrote: >>> >>> OK, thanks. >> >> >> I notice you haven't checked the patch in yet, is there a problem? > > Not at all, just lack of time, so many problems/holidays to tackle at > the moment... That is May month in France ;-) > I'll be checking in it the next few days. ... committed as rev 188294. I will backport it to 4.7 when it unfreezes. -- Fabien ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-06-07 5:40 ` Fabien Chêne @ 2012-06-27 18:26 ` Fabien Chêne 2012-07-17 11:57 ` Richard Guenther 0 siblings, 1 reply; 17+ messages in thread From: Fabien Chêne @ 2012-06-27 18:26 UTC (permalink / raw) To: Jason Merrill; +Cc: GCC Patches 2012/6/7 Fabien Chêne <fabien.chene@gmail.com>: [...] > ... committed as rev 188294. > I will backport it to 4.7 when it unfreezes. ... Eventually backported as rev 189021. -- Fabien ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [C++ Patch] for c++/51214 2012-06-27 18:26 ` Fabien Chêne @ 2012-07-17 11:57 ` Richard Guenther 0 siblings, 0 replies; 17+ messages in thread From: Richard Guenther @ 2012-07-17 11:57 UTC (permalink / raw) To: Fabien Chêne; +Cc: Jason Merrill, GCC Patches On Wed, Jun 27, 2012 at 7:38 PM, Fabien Chêne <fabien.chene@gmail.com> wrote: > 2012/6/7 Fabien Chêne <fabien.chene@gmail.com>: > [...] >> ... committed as rev 188294. >> I will backport it to 4.7 when it unfreezes. > > ... Eventually backported as rev 189021. This causes PR53995. Richard. > -- > Fabien ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2012-07-17 11:57 UTC | newest] Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-02-28 20:57 [C++ Patch] for c++/51214 Fabien Chêne 2012-02-28 22:06 ` Paolo Carlini 2012-02-28 23:22 ` Jason Merrill 2012-02-28 23:28 ` Fabien Chêne 2012-02-29 7:56 ` Fabien Chêne 2012-02-29 15:31 ` Jason Merrill 2012-05-06 20:07 ` Fabien Chêne 2012-05-07 14:41 ` Jason Merrill 2012-05-23 20:38 ` Fabien Chêne 2012-05-24 13:18 ` Jason Merrill 2012-06-03 4:47 ` Jason Merrill 2012-06-03 15:56 ` Fabien Chêne 2012-06-03 17:06 ` Gabriel Dos Reis 2012-06-04 12:41 ` Fabien Chêne 2012-06-07 5:40 ` Fabien Chêne 2012-06-27 18:26 ` Fabien Chêne 2012-07-17 11:57 ` Richard Guenther
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).