gcc version 4.5.0 20090825 (experimental) (GCC)

I found this bug while working on static analysis tools for Mozilla (using the
plugin framework), where we access |tree| structures in the cfg. (For
reference, this is also filed as
https://bugzilla.mozilla.org/show_bug.cgi?id=511261.)

Consider testcase.c:

typedef struct  { int i; } foo_t;
typedef const foo_t bar_t;
bar_t func() { bar_t b; return b; }

Invoked via:
cc1 testcase.c

Then the |bar_t| return type of |func()| will have a null TYPE_NAME(). I proved
this by introducing a syntax error in the body of |func()| and breaking in
lhd_print_error_function() in gcc/langhooks.c:

Breakpoint 3, lhd_print_error_function (context=0x8ac2760, 
    file=0xbffff542
"/home/dwitte/builds/gcc-dehydra/dehydra/test/test_c_typedef_bug.c",
diagnostic=0xbfffeee4)
    at ../../src/gcc/langhooks.c:349
349     {
(gdb) p current_function_decl->common.type->base.code
$21 = FUNCTION_TYPE
(gdb) p current_function_decl->common.type->common.type->base.code
$22 = RECORD_TYPE
(gdb) p current_function_decl->common.type->common.type->type.name
$23 = (tree) 0x0

If the |const| is removed from the definition of bar_t, things work fine:
(gdb) p
current_function_decl->common.type->common.type->type.name->decl_minimal.name.identifier.id.str
$25 = (const unsigned char *) 0xb7d6bc00 "bar_t"

If the return type of |func()| is instead |foo_t|, things also work:
(gdb) p
current_function_decl->common.type->common.type->type.name->decl_minimal.name.identifier.id.str
$26 = (const unsigned char *) 0xb7d6bbf8 "foo_t"

In addition, it's worth noting that the variant chain of the return type (in
the testcase as written) does include |bar_t|, as well as |foo_t| (twice), but
interspersed with null-named trees. This may or may not be relevant.

(gdb) p $rt = current_function_decl->common.type->common.type
$47 = (tree) 0xb7d7d7e0
(gdb) p $variant = $rt->type.main_variant
$48 = (tree) 0xb7d7d5b0
(gdb) p $variant->type.name
$49 = (tree) 0x0
(gdb) p $variant = $variant->type.next_variant
$50 = (tree) 0xb7d7d8c0
(gdb) p $variant->type.name
$51 = (tree) 0xb7d7d850
(gdb) p $variant->type.name->decl_minimal.name.identifier.id.str
$52 = (const unsigned char *) 0xb7d6bc00 "bar_t"
(gdb) p $variant = $variant->type.next_variant
$53 = (tree) 0xb7d7d7e0
(gdb) p $variant->type.name
$54 = (tree) 0x0
(gdb) p $variant = $variant->type.next_variant
$55 = (tree) 0xb7d7d770
(gdb) p $variant->type.name
$56 = (tree) 0xb7d7d690
(gdb) p $variant->type.name->decl_minimal.name.identifier.id.str
$57 = (const unsigned char *) 0xb7d6bbf8 "foo_t"
(gdb) p $variant = $variant->type.next_variant
$58 = (tree) 0xb7d7d700
(gdb) p $variant->type.name
$59 = (tree) 0xb7d7d690
(gdb) p $variant->type.name->decl_minimal.name.identifier.id.str
$60 = (const unsigned char *) 0xb7d6bbf8 "foo_t"
(gdb) p $variant = $variant->type.next_variant
$61 = (tree) 0x0

Note that the C++ FE gets this right. I'm guessing that there's something wrong
with variant type creation involving qualifiers.

gcc -v:
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../src/configure --without-libstdcxx
--prefix=/home/dwitte/builds/gcc-trunk/obj/../installed
--enable-languages=c,c++
Thread model: posix
gcc version 4.5.0 20090825 (experimental) (GCC)


-- 
           Summary: C frontend botches type.name for typedef chains
           Product: gcc
           Version: 4.5.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: dwitte at mozilla dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41172

Reply via email to