diff mbox

Disable size optimizations of -gdwarf-2 DW_AT_data_member_location DW_OP_plus_uconst

Message ID 20110727214039.GI2687@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek July 27, 2011, 9:40 p.m. UTC
Hi!

Apparently gdb (and not very unlikely other consumers) weren't able to
handle arbitrary location descriptions in DW_AT_data_member_location,
and my recent optimization to try to optimize e.g. DW_OP_plus_uconst
into equivalent, but shorter sequence of more operations apparently
doesn't work there.  While GDB is being fixed (or has it been already?),
this affects just -gdwarf-2 and there it could be considered a fixed idiom.

We should IMHO change the default DWARF level to -gdwarf-3 at least for now,
except for targets with broken tools (that aren't able to cope properly even
with DWARF 2, like Apple).  DWARF 3 has been released more than 5 years
ago...

So, the following patch just disables the size optimization when
DW_AT_data_member_location -gdwarf-2 only op is DW_OP_plus_uconst.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-07-27  Jakub Jelinek  <jakub@redhat.com>

	* dwarf2out.c (resolve_addr): For -gdwarf-2 don't
	optimize DW_AT_data_member_location containing just
	DW_OP_plus_uconst.



	Jakub

Comments

Jason Merrill July 28, 2011, 3:42 p.m. UTC | #1
I'd find the logic easier to read if it were inverted, but OK.

Jason
diff mbox

Patch

--- gcc/dwarf2out.c.jj	2011-07-27 18:55:11.000000000 +0200
+++ gcc/dwarf2out.c	2011-07-27 20:53:55.000000000 +0200
@@ -21808,13 +21808,26 @@  resolve_addr (dw_die_ref die)
 	  }
 	break;
       case dw_val_class_loc:
-	if (!resolve_addr_in_expr (AT_loc (a)))
-	  {
-	    remove_AT (die, a->dw_attr);
-	    ix--;
-	  }
-	else
-	  mark_base_types (AT_loc (a));
+	{
+	  dw_loc_descr_ref l = AT_loc (a);
+	  /* For -gdwarf-2 don't attempt to optimize
+	     DW_AT_data_member_location containing
+	     DW_OP_plus_uconst - older consumers might
+	     rely on it being that op instead of a more complex,
+	     but shorter, location description.  */
+	  if ((dwarf_version > 2
+	       || a->dw_attr != DW_AT_data_member_location
+	       || l == NULL
+	       || l->dw_loc_opc != DW_OP_plus_uconst
+	       || l->dw_loc_next != NULL)
+	      && !resolve_addr_in_expr (l))
+	    {
+	      remove_AT (die, a->dw_attr);
+	      ix--;
+	    }
+	  else
+	    mark_base_types (l);
+	}
 	break;
       case dw_val_class_addr:
 	if (a->dw_attr == DW_AT_const_value