re PR debug/53927 (wrong value for DW_AT_static_link)
authorEric Botcazou <ebotcazou@adacore.com>
Fri, 6 Jun 2014 08:13:24 +0000 (08:13 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 6 Jun 2014 08:13:24 +0000 (08:13 +0000)
PR debug/53927
* function.c (instantiate_decls): Process the saved static chain.
(expand_function_start): If not optimizing, save the static chain
onto the stack.
* tree-nested.c (convert_all_function_calls): Always create the static
chain for nested functions if not optimizing.

From-SVN: r211308

gcc/ChangeLog
gcc/function.c
gcc/tree-nested.c

index 7cb049ca9b0b2d5776969a26a7d91bab7c96bfde..e6cfb2d851502e33340c0bec8ca5b5362790179c 100644 (file)
@@ -1,3 +1,12 @@
+2014-06-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR debug/53927
+       * function.c (instantiate_decls): Process the saved static chain.
+       (expand_function_start): If not optimizing, save the static chain
+       onto the stack.
+       * tree-nested.c (convert_all_function_calls): Always create the static
+       chain for nested functions if not optimizing.
+
 2014-06-06  Eric Botcazou  <ebotcazou@adacore.com>
 
        * tree-cfg.c (make_edges) <GIMPLE_RETURN>: Put a location on the edge.
index a85ad462a7d087fddd198a6c035867fbba24a7cf..441289e84bc1cc39da22785912cf53d9ec93f320 100644 (file)
@@ -1877,6 +1877,11 @@ instantiate_decls (tree fndecl)
        }
     }
 
+  /* Process the saved static chain if it exists.  */
+  decl = DECL_STRUCT_FUNCTION (fndecl)->static_chain_decl;
+  if (decl && DECL_HAS_VALUE_EXPR_P (decl))
+    instantiate_decl_rtl (DECL_RTL (DECL_VALUE_EXPR (decl)));
+
   /* Now process all variables defined in the function or its subblocks.  */
   instantiate_decls_1 (DECL_INITIAL (fndecl));
 
@@ -4811,6 +4816,20 @@ expand_function_start (tree subr)
       if (MEM_P (chain)
          && reg_mentioned_p (arg_pointer_rtx, XEXP (chain, 0)))
        set_dst_reg_note (insn, REG_EQUIV, chain, local);
+
+      /* If we aren't optimizing, save the static chain onto the stack.  */
+      if (!optimize)
+       {
+         tree saved_static_chain_decl
+           = build_decl (DECL_SOURCE_LOCATION (parm), VAR_DECL,
+                         DECL_NAME (parm), TREE_TYPE (parm));
+         rtx saved_static_chain_rtx
+           = assign_stack_local (Pmode, GET_MODE_SIZE (Pmode), 0);
+         SET_DECL_RTL (saved_static_chain_decl, saved_static_chain_rtx);
+         emit_move_insn (saved_static_chain_rtx, chain);
+         SET_DECL_VALUE_EXPR (parm, saved_static_chain_decl);
+         DECL_HAS_VALUE_EXPR_P (parm) = 1;
+       }
     }
 
   /* If the function receives a non-local goto, then store the
index ba2cc7657098910fe5242e0feeef5b9fa6adf7f6..85c6a03f73743871381328241af62a630eef21e2 100644 (file)
@@ -2220,11 +2220,21 @@ convert_all_function_calls (struct nesting_info *root)
   struct nesting_info *n;
 
   /* First, optimistically clear static_chain for all decls that haven't
-     used the static chain already for variable access.  */
+     used the static chain already for variable access.  But always create
+     it if not optimizing.  This makes it possible to reconstruct the static
+     nesting tree at run time and thus to resolve up-level references from
+     within the debugger.  */
   FOR_EACH_NEST_INFO (n, root)
     {
       tree decl = n->context;
-      if (!n->outer || (!n->chain_decl && !n->chain_field))
+      if (!optimize)
+       {
+         if (n->inner)
+           (void) get_frame_type (n);
+         if (n->outer)
+           (void) get_chain_decl (n);
+       }
+      else if (!n->outer || (!n->chain_decl && !n->chain_field))
        {
          DECL_STATIC_CHAIN (decl) = 0;
          if (dump_file && (dump_flags & TDF_DETAILS))