Pointer type information lost in 4.5 debuginfo

Bug #662324 reported by Michael Hope
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Linaro GCC
Fix Released
Low
Ulrich Weigand
4.5
Fix Released
Low
Ulrich Weigand
Linaro GCC Tracking
Fix Released
Undecided
Unassigned
gcc
Fix Released
Medium

Bug Description

Split from LP: #649067

Running the GDB test suite against Linaro GCC 4.5 shows more failures than against 4.4.

The following regressions remain; as mentioned in the bug report, these are due to bug PR 45088:
FAIL: gdb.cp/class2.exp: p acp->c1
FAIL: gdb.cp/class2.exp: p acp->c2
If you prefer, we can open a second bug to track these. (There is no fix available upstream yet.)

In addition, I'm now seeing yet another failure:
FAIL: gdb.cp/temargs.exp: test value of P in inner_m
Not sure yet what causes this one.

Related branches

Revision history for this message
In , Jakub-gcc (jakub-gcc) wrote :

So, to add c1's type, we call gen_typedef_with_usage with A typedef variant.
19880 /* If TYPE is a typedef type variant, let's generate debug info
19881 for the parent typedef which TYPE is a type of. */
19882 if (typedef_variant_p (type))
19883 {
19884 if (TREE_ASM_WRITTEN (type))
19885 return;
19886
19887 /* Prevent broken recursion; we can't hand off to the same type. */
19888 gcc_assert (DECL_ORIGINAL_TYPE (TYPE_NAME (type)) != type);
19889
19890 /* Use the DIE of the containing namespace as the parent DIE of
19891 the type description DIE we want to generate. */
19892 if (DECL_CONTEXT (TYPE_NAME (type))
19893 && TREE_CODE (DECL_CONTEXT (TYPE_NAME (type))) == NAMESPACE_DECL)
19894 context_die = get_context_die (DECL_CONTEXT (TYPE_NAME (type)));
19895
19896 TREE_ASM_WRITTEN (type) = 1;
19897
19898 gen_decl_die (TYPE_NAME (type), NULL, context_die);
19899 return;

TREE_ASM_WRITTEN is not set on type originally, we compute context_die. Then set TREE_ASM_WRITTEN and call gen_decl_die. TYPE_NAME (type) is a redundant typedef though, so in gen_decl_die:
20544 if (is_redundant_typedef (decl))
20545 gen_type_die (TREE_TYPE (decl), context_die);
and TREE_TYPE (decl) here is the type on which we've just set TREE_ASM_WRITTEN, so gen_type_die_with_usage is recursed with the same type and as TREE_ASM_WRITTEN is now already set, it returns immediately, without creating any type. So, I think we need to special case is_redundant_typedef (TYPE_NAME (type))) in gen_type_die_with_usage in the typedef_variant_p (type) handling and ensure we actually create the DECL_ORIGINAL_TYPE in that case and equate that also to the underlying type. Or this could be a bug in the FE.

Revision history for this message
In , Uweigand-gcc (uweigand-gcc) wrote :

Any update on this bug? I'm seeing this in 4.5 as well ...

Revision history for this message
In , Redi (redi) wrote :

is this another dup of PR 43628? should be fixed if it is

Revision history for this message
In , Uweigand-gcc (uweigand-gcc) wrote :

(In reply to comment #3)
> is this another dup of PR 43628? should be fixed if it is

No, unfortunately it's not. In mainline and 4.5 (which have the 43628) fix, all other GDB C++ test suite regressions over 4.4 are fixed, *except* for the one described in this bug report.

Revision history for this message
Michael Hope (michaelh1) wrote :

Split from LP: #649067

Running the GDB test suite against Linaro GCC 4.5 shows more failures than against 4.4.

The following regressions remain; as mentioned in the bug report, these are due to bug PR 45088:
FAIL: gdb.cp/class2.exp: p acp->c1
FAIL: gdb.cp/class2.exp: p acp->c2
If you prefer, we can open a second bug to track these. (There is no fix available upstream yet.)

In addition, I'm now seeing yet another failure:
FAIL: gdb.cp/temargs.exp: test value of P in inner_m
Not sure yet what causes this one.

Revision history for this message
In , Dodji-gcc (dodji-gcc) wrote :

Following the (IMHO correect) analysis of Jakub, an interesting
question would be:

  Why is the type of *c1 a typedef variant of "A" instead
  of being just "A"?

It's actually the "self reference type" of A. In struct A, the
standard asks to inject the name A into the struct A itself, so that
looking up A::A or C::A succeeds. G++ creates a special typedef of A
(named self reference type in G++ speak) and injects that typedef into
A.

So from inside struct C, when considering "A *c1", the lookup of A
returns the self reference type of A. I think after the lookup
succeeds, G++ should retain A as the type of *c1; not the self
reference. Otherwise that confuses the debug info emitter as this bug
suggests.

I am about to test the patch below that hopefully does what I would
want. It's actually the second hunk that fixes this case because it
does what I am saying for the simple-type-specifier production.

The first hunk is something I noticed while looking at this issue. The
initial code in check_elaborated_type_specifier actually tries to do
what I am saying (for the elaborated-type-specifier production) but I
believe it fails in doing so, probably because the way self references
are represented has changed since the code was written.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fb5ca7f..feba130 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -10902,7 +10902,7 @@ check_elaborated_type_specifier (enum tag_types tag_code,
      name lookup will find the TYPE_DECL for the implicit "S::S"
      typedef. Adjust for that here. */
   if (DECL_SELF_REFERENCE_P (decl))
- decl = TYPE_NAME (TREE_TYPE (decl));
+ decl = TYPE_NAME (DECL_ORIGINAL_TYPE (decl));

   type = TREE_TYPE (decl);

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 6a9e4d7..d70c621 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -12791,6 +12791,11 @@ cp_parser_simple_type_specifier (cp_parser* parser,
       /* Otherwise, look for a type-name. */
       else
  type = cp_parser_type_name (parser);
+
+ if (type && TREE_CODE (type) == TYPE_DECL
+ && DECL_SELF_REFERENCE_P (type))
+ type = TYPE_NAME (DECL_ORIGINAL_TYPE (type));
+
       /* Keep track of all name-lookups performed in class scopes. */
       if (type
    && !global_p

Revision history for this message
In , Dodji-gcc (dodji-gcc) wrote :

I believe this is a smaller reproducer (the type of *a1 is not present
in debug info):

struct A
{
    virtual ~A();
};

struct B : public A
{
    virtual ~B(){}
};

struct C : public B
{
    A* a1;
};

int
main()
{
    C c;
    c.a1 = 0;
    return 0;
}

Revision history for this message
In , Dodji-gcc (dodji-gcc) wrote :

Finally the patch I pasted earlier wasn't good enough. I modified it
and proposed it to
http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01277.html

Revision history for this message
In , Dodji-gcc (dodji-gcc) wrote :

Author: dodji
Date: Fri Dec 17 10:39:21 2010
New Revision: 167976

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=167976
Log:
Fix for PR debug/45088

gcc/

 * dwarf2out.c (gen_type_die_with_usage): Do not try to emit debug
 info for a redundant typedef that has DECL_ORIGINAL_TYPE set. Use
 that underlying type instead.

gcc/testsuite/

 * g++.dg/debug/dwarf2/self-ref-1.C: New test.
 * g++.dg/debug/dwarf2/self-ref-2.C: Likewise.

Added:
    trunk/gcc/testsuite/g++.dg/debug/dwarf2/self-ref-1.C
    trunk/gcc/testsuite/g++.dg/debug/dwarf2/self-ref-2.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dwarf2out.c
    trunk/gcc/testsuite/ChangeLog

Revision history for this message
Ulrich Weigand (uweigand) wrote :

Mainline fix has now been committed:
http://gcc.gnu.org/ml/gcc-patches/2010-12/msg01311.html

I'll work on a backport to Linaro GCC 4.5.

Revision history for this message
Andrew Stubbs (ams-codesourcery) wrote :
Changed in gcc-linaro-tracking:
milestone: none → 4.6.0
status: New → Fix Committed
Changed in gcc:
importance: Unknown → Medium
status: Unknown → In Progress
Revision history for this message
In , Dodji-gcc (dodji-gcc) wrote :

Fixed in 4.6

Changed in gcc:
status: In Progress → Fix Released
Changed in gcc-linaro-tracking:
status: Fix Committed → Fix Released
Revision history for this message
In , Pluto-7 (pluto-7) wrote :

what about 4.7 branch?

Revision history for this message
In , Jason-gcc (jason-gcc) wrote :

(In reply to comment #10)
> what about 4.7 branch?

The fix was on the trunk before 4.7 branched, so yes.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.