diff mbox

[c++] : Fix for PR c++/51344 - cc1plus hangs when compiling

Message ID CAEwic4Zoeeyz6qo3ctCJ6AHDQ8r0mcgUN4SWaCBwdsZp+tJBLA@mail.gmail.com
State New
Headers show

Commit Message

Kai Tietz Jan. 17, 2012, 7:10 p.m. UTC
Hello,

this hang is caused by an end-less loop in private_lookup_attribute
caused by double-chaining of attributes in decl2.c's
save_template_attributes function.  In save_template_attributes we
need to check that attribute-list isn't equal to late_attrs before
chaining them.

ChangeLog gcc/cp

2012-01-17  Kai Tietz  <ktietz@redhat.com>

        PR c++/51344
        * decl2.c (save_template_attributes): Don't chain late-attributes with
        attribute-list, if they are same.

ChangeLog gcc/cp

2012-01-17  Kai Tietz  <ktietz@redhat.com>

        g++.dg/torture/pr51344.C: New test.

Bootstrapped and regression tested for x86_64-unknown-linux-gnu,
x86_64-w64-mingw32, and i686-w64-mingw32. Ok for apply?

Regards,
Kai

Comments

Jason Merrill Jan. 17, 2012, 7:26 p.m. UTC | #1
How does this happen?  Are we setting DECL_ATTRIBUTES twice?

Jason
Kai Tietz Jan. 17, 2012, 7:30 p.m. UTC | #2
2012/1/17 Jason Merrill <jason@redhat.com>:
> How does this happen?  Are we setting DECL_ATTRIBUTES twice?
>
> Jason

Yes, we call it for this example twice.  One time in
'begin_class_definition'. and second time in 'do_friend'.

Kai
Jason Merrill Jan. 17, 2012, 7:34 p.m. UTC | #3
On 01/17/2012 02:30 PM, Kai Tietz wrote:
> 2012/1/17 Jason Merrill<jason@redhat.com>:
>> How does this happen?  Are we setting DECL_ATTRIBUTES twice?
>
> Yes, we call it for this example twice.  One time in
> 'begin_class_definition'. and second time in 'do_friend'.

Surely the call from begin_class_definition isn't for the function 
declaration, though.

Jason
Kai Tietz Jan. 17, 2012, 7:41 p.m. UTC | #4
2012/1/17 Jason Merrill <jason@redhat.com>:
> On 01/17/2012 02:30 PM, Kai Tietz wrote:
>>
>> 2012/1/17 Jason Merrill<jason@redhat.com>:
>>>
>>> How does this happen?  Are we setting DECL_ATTRIBUTES twice?
>>
>>
>> Yes, we call it for this example twice.  One time in
>> 'begin_class_definition'. and second time in 'do_friend'.
>
>
> Surely the call from begin_class_definition isn't for the function
> declaration, though.
>
> Jason

Right, but in second call we get for cplus_decl_attributes's
late_attrs (as result of splice_template_attributes) the same value as
already stored in decl_p's attributes.  By this we chain up an
endless-recusion.

Kai
Jason Merrill Jan. 17, 2012, 8:34 p.m. UTC | #5
On 01/17/2012 02:41 PM, Kai Tietz wrote:
> Right, but in second call we get for cplus_decl_attributes's
> late_attrs (as result of splice_template_attributes) the same value as
> already stored in decl_p's attributes.

Right, but why is it already stored there?

Jason
Kai Tietz Jan. 18, 2012, 8:29 a.m. UTC | #6
2012/1/17 Jason Merrill <jason@redhat.com>:
> On 01/17/2012 02:41 PM, Kai Tietz wrote:
>>
>> Right, but in second call we get for cplus_decl_attributes's
>> late_attrs (as result of splice_template_attributes) the same value as
>> already stored in decl_p's attributes.
>
>
> Right, but why is it already stored there?
>
> Jason

The approach to disable cplus_decl_attributes call in do_friend (as we
assume that prior grok* function it is calling it already) doesn't
work.
Eg the tests in g++.dg/ext/attribute-test-[34].C are failing for
c++11.  do_friend is called here via grokdeclarator for 'fTest' (test
3) and the attributes weren't applied before.  So removing here in
do_friend the call of cplus_decl_attributes seems wrong.
With my orginal patch those tests are passing.

Regards,
Kai
diff mbox

Patch

Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c      (revision 183106)
+++ gcc/cp/decl2.c      (working copy)
@@ -1202,7 +1202,8 @@ 

   /* Place the late attributes at the beginning of the attribute
      list.  */
-  TREE_CHAIN (tree_last (late_attrs)) = *q;
+  if (late_attrs != *q)
+    TREE_CHAIN (tree_last (late_attrs)) = *q;
   *q = late_attrs;

   if (!DECL_P (*decl_p) && *decl_p == TYPE_MAIN_VARIANT (*decl_p))

Index: gcc/gcc/testsuite/g++.dg/torture/pr51344.C
===================================================================
--- /dev/null
+++ gcc/gcc/testsuite/g++.dg/torture/pr51344.C
@@ -0,0 +1,9 @@ 
+/* { dg-do compile } */
+template <class T>
+class B
+{
+  friend __attribute__((cdecl)) A& operator >>(A& a, B& b)
+  {
+    return a;
+  }
+};