public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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).