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