debug/6436: dwarf2out ICE with typedef using attributes

Daniel Berlin dberlin@dberlin.org
Mon Apr 29 11:09:00 GMT 2002


This one is fun.  Not playing beach volley ball fun, more like 
burning yourself on hot coals fun.
Here's what happens:

We go to output a type die for A *with* alignment, because it's the type 
of a decl.

In gen_type_die, we first get the main variant of A, which is an A 
*without* the user set alignment.

We then hit this test near the top:

if (TYPE_NAME (decl) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && 
	DECL_ORIGINAL_TYPE (TYPE_NAME (type)))

and it succeeds, causing us to do:

{
<type is now a without alignment, type_name (type) is a with alignment>
	TREE_ASM_WRITTEN (type) = 1;
	gen_decl_die (TYPE_NAME (type), context_die);
	return;
}

So we mark the A *without* alignment as written, then proceed to try to 
gen a decl die for the type_name of A, which is just like A, only *with* 
the alignment. (you should already smell trouble brewing here, since this 
whole thing started when we were trying to output a type die for A *with* 
alignment, and surely, gen_decl_die will try to do this as well)

is_redundant_typedef on it says no, so we go to gen a typedef die for the 
A with alignment, to the A without alignment.

In gen_typedef_die, first we mark the A with alignment type as written, 
then proceed to get the original type, A *without* alignment, and ask 
modified_type_die for a type die with the qualifiers in front of it, if 
any.  
In the portion of modified_type_die labeled "Handle C typedef types", we 
pass the main test, but qualified_type != dtype because one is the one 
with alignment, one is the one without ailgnment, thus, they are 
different trees, and the pointer comparison fails.  Even though, going 
by qualifications, they *are* the same type.

After failing that, we fail the other tests, getting us to the else which 
calls gen_type_die, with the type passed in (This is the A without 
alignment type, once again).
Which of course, sees it's written the type (since we set the written flag 
on that one at the beginning of this godawful trip through hell), and 
returns.

The lookup, which should succeed, and would, had we actually ever written 
the original type, instead of us taking this trip to the 9th circle, 
fails, and we abort.

To be more concise, here's what happens:

gen_type_die (A with alignment)
        |
get main variant, A *without* alignment, see it's got a type name, 
therefore, so mark A *without* alignment as written, and call
	|
gen_decl_die (TYPE_NAME (A without alignment), which is A with alignment)
        |
is_redundant == no, so
        |
gen_typedef (A with alignment) 
	|
Mark A with alignment as written.
        |
Notice A with alignment has an original type, get original type, A 
*without* alignment.
	|
modified_type_die (A *without* alignment)
	|
fail test saying it's equal to existing qualified type, causing us to:
	|
gen_type_die (A *without* alignment)
	|
Sees it's marked as written, so it just returns.
	|
lookup fails, since we really haven't written it (we are in the process of 
trying to write it, we will when we get back up to the top of the 
recursion chain), and we abort.


My head hurts.

I'm not sure what the right thing to do in this case is, so i'm not sure i 
can point out a stage and say "That's where it all went wrong".  But 
someone who *does* understand what we should do, should be able to use 
this analysis to fix the problem.

--Dan
 yet. On 29 Apr 2002 jakub@gcc.gnu.org 
wrote:

> Old Synopsis: 
> New Synopsis: dwarf2out ICE with typedef using attributes
> 
> State-Changed-From-To: open->analyzed
> State-Changed-By: jakub
> State-Changed-When: Mon Apr 29 05:31:49 2002
> State-Changed-Why:
>     Simplified into:
>     --- gcc/testsuite/g++.dg/debug/debug6.C.jj      Thu Aug 30 22:30:55 2001
>     +++ gcc/testsuite/g++.dg/debug/debug6.C Mon Apr 29 14:41:05 2002
>     @@ -0,0 +1,17 @@
>     +// PR debug/6436
>     +// { dg-do compile }
>     +
>     +typedef struct
>     +{
>     +  unsigned int a0, a1;
>     +} A __attribute__ ((aligned(8)));
>     +
>     +typedef struct
>     +{
>     +  A a;
>     +} B;
>     +
>     +struct C
>     +{
>     +  B *bp;
>     +};
>     
>     Regression from 2.9x (even with -gdwarf-2).
> 
> http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=6436
> 



More information about the Gcc-bugs mailing list