[RFA, patch] Add missing source location info to thunks

Cary Coutant ccoutant@google.com
Fri Aug 3 23:38:00 GMT 2012


GCC generates non-virtual thunks directly to assembly code, which
causes a couple of problems. First, it doesn't add source location
information to the thunk, so the thunk simply inherits the random
location from the end of the function in front of it (the function
it's a thunk for). In two different compilation units compiled
with different options, this could result in two different locations
for the same thunk, and gold will give a false positive ODR
violation warning.

Second, if you try to compile with -S -dA, GCC crashes in final(),
where it's trying to build a mapping from insn to bb, because the
function has no cfg, and FOR_EACH_BB_REVERSE tries to dereference
cfun->cfg without checking for non-NULL.

I've fixed the first problem by adding a direct call to
(*debug_hooks->source_line) in assemble_thunk. This seems to work,
but I'm not at all sure if it's the right way to fix it. Advice
is appreciated.

I've fixed the second problem by adding a check for cfun->cfg != NULL
to guard the FOR_EACH_BB_REVERSE loop in final().

Do these changes look OK?

-cary

2012-08-03  Cary Coutant  <ccoutant@google.com>

	* gcc/cgraphunit.c (assemble_thunk): Add source line info.
	* gcc/final.c (final): Check for non-null cfg pointer.


diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 89765b5..1558b4d 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1382,6 +1382,10 @@ assemble_thunk (struct cgraph_node *node)
       init_function_start (thunk_fndecl);
       cfun->is_thunk = 1;
       assemble_start_function (thunk_fndecl, fnname);
+      (*debug_hooks->source_line) (DECL_SOURCE_LINE (thunk_fndecl),
+                                  DECL_SOURCE_FILE (thunk_fndecl),
+                                  /* discriminator */ 0,
+                                  /* is_stmt */ 1);

       targetm.asm_out.output_mi_thunk (asm_out_file, thunk_fndecl,
                                       fixed_offset, virtual_value, alias);
diff --git a/gcc/final.c b/gcc/final.c
index 095d608..d22130f 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -1863,11 +1863,12 @@ final (rtx first, FILE *file, int optimize_p)
       start_to_bb = XCNEWVEC (basic_block, bb_map_size);
       end_to_bb = XCNEWVEC (basic_block, bb_map_size);

-      FOR_EACH_BB_REVERSE (bb)
-       {
-         start_to_bb[INSN_UID (BB_HEAD (bb))] = bb;
-         end_to_bb[INSN_UID (BB_END (bb))] = bb;
-       }
+      if (cfun->cfg != NULL)
+       FOR_EACH_BB_REVERSE (bb)
+         {
+           start_to_bb[INSN_UID (BB_HEAD (bb))] = bb;
+           end_to_bb[INSN_UID (BB_END (bb))] = bb;
+         }
     }

   /* Output the insns.  */



More information about the Gcc-patches mailing list