aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2010-12-22 03:49:00 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2010-12-22 03:49:00 +0000
commit8dcfef8f2b2ad81873c1d2bb55182125e3190557 (patch)
treeacd635446a64407453a2f7688ccccc3c965f09f8 /gcc
parent16a9afdc664f58ab8ad5e4bd2468cda18375d121 (diff)
downloadgcc-8dcfef8f2b2ad81873c1d2bb55182125e3190557.zip
gcc-8dcfef8f2b2ad81873c1d2bb55182125e3190557.tar.gz
gcc-8dcfef8f2b2ad81873c1d2bb55182125e3190557.tar.bz2
re PR debug/46724 (Wrong debug info: Invalid variable location)
PR debug/46724 * function.c (assign_parms_augmented_arg_list): Name and mark DECL of result address as NAMELESS rather than IGNORED. (assign_parms): Set DECL_VALUE_EXPR for indirect result. * tree.h (tree_decl_common::decl_flag_2): Document RESULT_DECL. (DECL_HAS_VALUE_EXPR_P): Accept RESULT_DECL. * dwarf2out.c (loc_list_from_tree) <RESULT_DECL>: Use DECL_VALUE_EXPR. * dbxout.c (dbxout_expand_expr) <RESULT_DECL>: Likewise. * var-tracking.c (vt_add_function_parameter): New, split out of... (vt_add_function_parameters): ... this. Handle incoming pointer to hold result. From-SVN: r168160
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/dbxout.c2
-rw-r--r--gcc/dwarf2out.c2
-rw-r--r--gcc/function.c16
-rw-r--r--gcc/tree.h6
-rw-r--r--gcc/var-tracking.c199
6 files changed, 142 insertions, 98 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 630eab1..fed571d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2010-12-22 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/46724
+ * function.c (assign_parms_augmented_arg_list): Name and mark
+ DECL of result address as NAMELESS rather than IGNORED.
+ (assign_parms): Set DECL_VALUE_EXPR for indirect result.
+ * tree.h (tree_decl_common::decl_flag_2): Document RESULT_DECL.
+ (DECL_HAS_VALUE_EXPR_P): Accept RESULT_DECL.
+ * dwarf2out.c (loc_list_from_tree) <RESULT_DECL>: Use
+ DECL_VALUE_EXPR.
+ * dbxout.c (dbxout_expand_expr) <RESULT_DECL>: Likewise.
+ * var-tracking.c (vt_add_function_parameter): New, split out of...
+ (vt_add_function_parameters): ... this. Handle incoming
+ pointer to hold result.
+
2010-12-22 Jie Zhang <jie@codesourcery.com>
* config/arm/arm.c (output_move_double): Update the comment
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 89ea0f3..3b0cf34 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -2396,12 +2396,12 @@ dbxout_expand_expr (tree expr)
/* FALLTHRU */
case PARM_DECL:
+ case RESULT_DECL:
if (DECL_HAS_VALUE_EXPR_P (expr))
return dbxout_expand_expr (DECL_VALUE_EXPR (expr));
/* FALLTHRU */
case CONST_DECL:
- case RESULT_DECL:
return DECL_RTL_IF_SET (expr);
case INTEGER_CST:
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 1fa3300..bc21875 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -15446,12 +15446,12 @@ loc_list_from_tree (tree loc, int want_address)
/* FALLTHRU */
case PARM_DECL:
+ case RESULT_DECL:
if (DECL_HAS_VALUE_EXPR_P (loc))
return loc_list_from_tree (DECL_VALUE_EXPR (loc),
want_address);
/* FALLTHRU */
- case RESULT_DECL:
case FUNCTION_DECL:
{
rtx rtl;
diff --git a/gcc/function.c b/gcc/function.c
index 7fa3b0c..0c4d5f8 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2253,10 +2253,11 @@ assign_parms_augmented_arg_list (struct assign_parm_data_all *all)
tree decl;
decl = build_decl (DECL_SOURCE_LOCATION (fndecl),
- PARM_DECL, NULL_TREE, type);
+ PARM_DECL, get_identifier (".result_ptr"), type);
DECL_ARG_TYPE (decl) = type;
DECL_ARTIFICIAL (decl) = 1;
- DECL_IGNORED_P (decl) = 1;
+ DECL_NAMELESS (decl) = 1;
+ TREE_CONSTANT (decl) = 1;
DECL_CHAIN (decl) = all->orig_fnargs;
all->orig_fnargs = decl;
@@ -3418,13 +3419,22 @@ assign_parms (tree fndecl)
rtx x;
if (DECL_BY_REFERENCE (result))
- x = addr;
+ {
+ SET_DECL_VALUE_EXPR (result, all.function_result_decl);
+ x = addr;
+ }
else
{
+ SET_DECL_VALUE_EXPR (result,
+ build1 (INDIRECT_REF, TREE_TYPE (result),
+ all.function_result_decl));
addr = convert_memory_address (Pmode, addr);
x = gen_rtx_MEM (DECL_MODE (result), addr);
set_mem_attributes (x, result, 1);
}
+
+ DECL_HAS_VALUE_EXPR_P (result) = 1;
+
SET_DECL_RTL (result, x);
}
diff --git a/gcc/tree.h b/gcc/tree.h
index 8ba2044..216f3d2 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -2773,7 +2773,8 @@ struct GTY(()) tree_decl_common {
In TYPE_DECL, this is TYPE_DECL_SUPPRESS_DEBUG. */
unsigned decl_flag_1 : 1;
/* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
- In VAR_DECL and PARM_DECL, this is DECL_HAS_VALUE_EXPR_P. */
+ In VAR_DECL, PARM_DECL and RESULT_DECL, this is
+ DECL_HAS_VALUE_EXPR_P. */
unsigned decl_flag_2 : 1;
/* Logically, these two would go in a theoretical base shared by var and
parm decl. */
@@ -2818,7 +2819,8 @@ extern void decl_value_expr_insert (tree, tree);
decl itself. This should only be used for debugging; once this field has
been set, the decl itself may not legitimately appear in the function. */
#define DECL_HAS_VALUE_EXPR_P(NODE) \
- (TREE_CHECK2 (NODE, VAR_DECL, PARM_DECL)->decl_common.decl_flag_2)
+ (TREE_CHECK3 (NODE, VAR_DECL, PARM_DECL, RESULT_DECL) \
+ ->decl_common.decl_flag_2)
#define DECL_VALUE_EXPR(NODE) \
(decl_value_expr_lookup (DECL_WRTL_CHECK (NODE)))
#define SET_DECL_VALUE_EXPR(NODE, VAL) \
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 44701be..58dce1b 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -7999,121 +7999,138 @@ vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
return false;
}
-/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */
+/* Insert function parameter PARM in IN and OUT sets of ENTRY_BLOCK. */
static void
-vt_add_function_parameters (void)
+vt_add_function_parameter (tree parm)
{
- tree parm;
-
- for (parm = DECL_ARGUMENTS (current_function_decl);
- parm; parm = DECL_CHAIN (parm))
- {
- rtx decl_rtl = DECL_RTL_IF_SET (parm);
- rtx incoming = DECL_INCOMING_RTL (parm);
- tree decl;
- enum machine_mode mode;
- HOST_WIDE_INT offset;
- dataflow_set *out;
- decl_or_value dv;
-
- if (TREE_CODE (parm) != PARM_DECL)
- continue;
+ rtx decl_rtl = DECL_RTL_IF_SET (parm);
+ rtx incoming = DECL_INCOMING_RTL (parm);
+ tree decl;
+ enum machine_mode mode;
+ HOST_WIDE_INT offset;
+ dataflow_set *out;
+ decl_or_value dv;
- if (!DECL_NAME (parm))
- continue;
+ if (TREE_CODE (parm) != PARM_DECL)
+ return;
- if (!decl_rtl || !incoming)
- continue;
+ if (!decl_rtl || !incoming)
+ return;
- if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
- continue;
+ if (GET_MODE (decl_rtl) == BLKmode || GET_MODE (incoming) == BLKmode)
+ return;
- if (!vt_get_decl_and_offset (incoming, &decl, &offset))
+ if (!vt_get_decl_and_offset (incoming, &decl, &offset))
+ {
+ if (REG_P (incoming) || MEM_P (incoming))
{
- if (REG_P (incoming) || MEM_P (incoming))
- {
- /* This means argument is passed by invisible reference. */
- offset = 0;
- decl = parm;
- incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
- }
- else
- {
- if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
- continue;
- offset += byte_lowpart_offset (GET_MODE (incoming),
- GET_MODE (decl_rtl));
- }
+ /* This means argument is passed by invisible reference. */
+ offset = 0;
+ decl = parm;
+ incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
}
-
- if (!decl)
- continue;
-
- if (parm != decl)
+ else
{
- /* Assume that DECL_RTL was a pseudo that got spilled to
- memory. The spill slot sharing code will force the
- memory to reference spill_slot_decl (%sfp), so we don't
- match above. That's ok, the pseudo must have referenced
- the entire parameter, so just reset OFFSET. */
- gcc_assert (decl == get_spill_slot_decl (false));
- offset = 0;
+ if (!vt_get_decl_and_offset (decl_rtl, &decl, &offset))
+ return;
+ offset += byte_lowpart_offset (GET_MODE (incoming),
+ GET_MODE (decl_rtl));
}
+ }
- if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
- continue;
+ if (!decl)
+ return;
+
+ if (parm != decl)
+ {
+ /* Assume that DECL_RTL was a pseudo that got spilled to
+ memory. The spill slot sharing code will force the
+ memory to reference spill_slot_decl (%sfp), so we don't
+ match above. That's ok, the pseudo must have referenced
+ the entire parameter, so just reset OFFSET. */
+ gcc_assert (decl == get_spill_slot_decl (false));
+ offset = 0;
+ }
- out = &VTI (ENTRY_BLOCK_PTR)->out;
+ if (!track_loc_p (incoming, parm, offset, false, &mode, &offset))
+ return;
- dv = dv_from_decl (parm);
+ out = &VTI (ENTRY_BLOCK_PTR)->out;
- if (target_for_debug_bind (parm)
- /* We can't deal with these right now, because this kind of
- variable is single-part. ??? We could handle parallels
- that describe multiple locations for the same single
- value, but ATM we don't. */
- && GET_CODE (incoming) != PARALLEL)
- {
- cselib_val *val;
+ dv = dv_from_decl (parm);
- /* ??? We shouldn't ever hit this, but it may happen because
- arguments passed by invisible reference aren't dealt with
- above: incoming-rtl will have Pmode rather than the
- expected mode for the type. */
- if (offset)
- continue;
+ if (target_for_debug_bind (parm)
+ /* We can't deal with these right now, because this kind of
+ variable is single-part. ??? We could handle parallels
+ that describe multiple locations for the same single
+ value, but ATM we don't. */
+ && GET_CODE (incoming) != PARALLEL)
+ {
+ cselib_val *val;
- val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
+ /* ??? We shouldn't ever hit this, but it may happen because
+ arguments passed by invisible reference aren't dealt with
+ above: incoming-rtl will have Pmode rather than the
+ expected mode for the type. */
+ if (offset)
+ return;
- /* ??? Float-typed values in memory are not handled by
- cselib. */
- if (val)
- {
- preserve_value (val);
- set_variable_part (out, val->val_rtx, dv, offset,
- VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
- dv = dv_from_value (val->val_rtx);
- }
- }
+ val = cselib_lookup (var_lowpart (mode, incoming), mode, true);
- if (REG_P (incoming))
+ /* ??? Float-typed values in memory are not handled by
+ cselib. */
+ if (val)
{
- incoming = var_lowpart (mode, incoming);
- gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
- attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
- incoming);
- set_variable_part (out, incoming, dv, offset,
- VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
- }
- else if (MEM_P (incoming))
- {
- incoming = var_lowpart (mode, incoming);
- set_variable_part (out, incoming, dv, offset,
+ preserve_value (val);
+ set_variable_part (out, val->val_rtx, dv, offset,
VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+ dv = dv_from_value (val->val_rtx);
}
}
+ if (REG_P (incoming))
+ {
+ incoming = var_lowpart (mode, incoming);
+ gcc_assert (REGNO (incoming) < FIRST_PSEUDO_REGISTER);
+ attrs_list_insert (&out->regs[REGNO (incoming)], dv, offset,
+ incoming);
+ set_variable_part (out, incoming, dv, offset,
+ VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+ }
+ else if (MEM_P (incoming))
+ {
+ incoming = var_lowpart (mode, incoming);
+ set_variable_part (out, incoming, dv, offset,
+ VAR_INIT_STATUS_INITIALIZED, NULL, INSERT);
+ }
+}
+
+/* Insert function parameters to IN and OUT sets of ENTRY_BLOCK. */
+
+static void
+vt_add_function_parameters (void)
+{
+ tree parm;
+
+ for (parm = DECL_ARGUMENTS (current_function_decl);
+ parm; parm = DECL_CHAIN (parm))
+ vt_add_function_parameter (parm);
+
+ if (DECL_HAS_VALUE_EXPR_P (DECL_RESULT (current_function_decl)))
+ {
+ tree vexpr = DECL_VALUE_EXPR (DECL_RESULT (current_function_decl));
+
+ if (TREE_CODE (vexpr) == INDIRECT_REF)
+ vexpr = TREE_OPERAND (vexpr, 0);
+
+ if (TREE_CODE (vexpr) == PARM_DECL
+ && DECL_ARTIFICIAL (vexpr)
+ && !DECL_IGNORED_P (vexpr)
+ && DECL_NAMELESS (vexpr))
+ vt_add_function_parameter (vexpr);
+ }
+
if (MAY_HAVE_DEBUG_INSNS)
{
cselib_preserve_only_values ();