DWARF: no location for non-definition DECLs with non-trivial DECL_VALUE_EXPR
authorPierre-Marie de Rodat <derodat@adacore.com>
Fri, 9 Feb 2018 14:02:37 +0000 (14:02 +0000)
committerPierre-Marie de Rodat <pmderodat@gcc.gnu.org>
Fri, 9 Feb 2018 14:02:37 +0000 (14:02 +0000)
This patch restricts the set of cases in which we allow the generation of
location attributes for variables that are not defined in the current unit.
For such variables with complex DECL_VALUE_EXPR trees, generating a location
attribute can end up creating relocations to text symbols in the debug section
of LTO object files, which is not valid.

gcc/
PR lto/84213
* dwarf2out.c (is_trivial_indirect_ref): New function.
(dwarf2out_late_global_decl): Do not generate a location
attribute for variables that have a non-trivial DECL_VALUE_EXPR
and that are not defined in the current unit.

From-SVN: r257526

gcc/ChangeLog
gcc/dwarf2out.c

index 858ad9dd9db135b10ace442b45a12dfb9e8935e1..1d4a3eed64406a94d0ea86ed2dd793a3d2b038de 100644 (file)
@@ -1,3 +1,11 @@
+2018-02-09  Pierre-Marie de Rodat  <derodat@adacore.com>
+
+       PR lto/84213
+       * dwarf2out.c (is_trivial_indirect_ref): New function.
+       (dwarf2out_late_global_decl): Do not generate a location
+       attribute for variables that have a non-trivial DECL_VALUE_EXPR
+       and that are not defined in the current unit.
+
 2018-02-09  Eric Botcazou  <ebotcazou@adacore.com>
 
        * optabs.c (prepare_cmp_insn): Try harder to emit a direct comparison
index 749c7e3b9bbcd114a5b8698cd65a51464e72a224..984df9fe4e9adf8febf9cfc7f72af67af961f946 100644 (file)
@@ -26235,6 +26235,23 @@ dwarf2out_early_global_decl (tree decl)
   symtab->global_info_ready = save;
 }
 
+/* Return whether EXPR is an expression with the following pattern:
+   INDIRECT_REF (NOP_EXPR (INTEGER_CST)).  */
+
+static bool
+is_trivial_indirect_ref (tree expr)
+{
+  if (expr == NULL_TREE || TREE_CODE (expr) != INDIRECT_REF)
+    return false;
+
+  tree nop = TREE_OPERAND (expr, 0);
+  if (nop == NULL_TREE || TREE_CODE (nop) != NOP_EXPR)
+    return false;
+
+  tree int_cst = TREE_OPERAND (nop, 0);
+  return int_cst != NULL_TREE && TREE_CODE (int_cst) == INTEGER_CST;
+}
+
 /* Output debug information for global decl DECL.  Called from
    toplev.c after compilation proper has finished.  */
 
@@ -26259,11 +26276,17 @@ dwarf2out_late_global_decl (tree decl)
       if (die)
        {
          /* We get called via the symtab code invoking late_global_decl
-            for symbols that are optimized out.  Do not add locations
-            for those, except if they have a DECL_VALUE_EXPR, in which case
-            they are relevant for debuggers.  */
+            for symbols that are optimized out.
+
+            Do not add locations for those, except if they have a
+            DECL_VALUE_EXPR, in which case they are relevant for debuggers.
+            Still don't add a location if the DECL_VALUE_EXPR is not a trivial
+            INDIRECT_REF expression, as this could generate relocations to
+            text symbols in LTO object files, which is invalid.  */
          varpool_node *node = varpool_node::get (decl);
-         if ((! node || ! node->definition) && ! DECL_HAS_VALUE_EXPR_P (decl))
+         if ((! node || ! node->definition)
+             && ! (DECL_HAS_VALUE_EXPR_P (decl)
+                   && is_trivial_indirect_ref (DECL_VALUE_EXPR (decl))))
            tree_add_const_value_attribute_for_decl (die, decl);
          else
            add_location_or_const_value_attribute (die, decl, false);