Hi,

Current in LTO static const bounds are created as external symbol.  It doesn't 
work in case original symbols were removed and privatized.  This patch 
introduces a separate comdat symbol to be used in LTO.   Bootstrapped and 
tested on x86_64-unknown-linux-gnu.  Does this approach look OK?
Thanks,
Ilya
--
gcc/

2015-04-02  Ilya Enkovich  <ilya.enkov...@intel.com>

        * tree-chkp.c (CHKP_LTO_SYMBOL_SUFFIX): New.
        (chkp_make_static_const_bounds): Use another
        symbol in LTO.

gcc/testsuite/

2015-04-02  Ilya Enkovich  <ilya.enkov...@intel.com>

        * gcc.dg/lto/chkp-static-bounds_0.c: New.


diff --git a/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c 
b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
new file mode 100644
index 0000000..e896eb1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/chkp-static-bounds_0.c
@@ -0,0 +1,26 @@
+/* { dg-lto-do link } */
+/* { dg-require-effective-target mpx } */
+/* { dg-lto-options { { -flto -flto-partition=max -fcheck-pointer-bounds -mmpx 
} } } */
+
+char *cc;
+
+int test1 (const char *c)
+{
+  c = __builtin___bnd_init_ptr_bounds (c);
+  cc = c;
+  return c[0] * 2;
+}
+
+struct S
+{
+  int (*fnptr) (const char *);
+} S;
+
+struct S s1 = {test1};
+struct S s2 = {test1};
+struct S s3 = {test1};
+
+int main (int argc, const char **argv)
+{
+  return s1.fnptr (argv[0]) + s2.fnptr (argv[1]);
+}
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index d2df4ba..0578936 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -421,6 +421,7 @@ static bool in_chkp_pass;
 #define CHKP_VAR_BOUNDS_PREFIX "__chkp_var_bounds_"
 #define CHKP_ZERO_BOUNDS_VAR_NAME "__chkp_zero_bounds"
 #define CHKP_NONE_BOUNDS_VAR_NAME "__chkp_none_bounds"
+#define CHKP_LTO_SYMBOL_SUFFIX ".lto"
 
 /* Static checker constructors may become very large and their
    compilation with optimization may take too much time.
@@ -1906,7 +1907,8 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
                               HOST_WIDE_INT ub,
                               const char *name)
 {
-  tree var;
+  tree var, id;
+  varpool_node *node;
 
   /* With LTO we may have constant bounds already in varpool.
      Try to find it.  */
@@ -1915,8 +1917,22 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
   if (var)
     return var;
 
-  var  = build_decl (UNKNOWN_LOCATION, VAR_DECL,
-                    get_identifier (name), pointer_bounds_type_node);
+  /* In LTO we may have symbol with changed visibility, comdat
+     group etc. Therefore we shouldn't recreate the same symbol.
+     Use LTO version instead.  */
+  if (in_lto_p)
+    {
+      int len = strlen (name) + strlen (CHKP_LTO_SYMBOL_SUFFIX) + 1;
+      char *new_name = XALLOCAVEC (char, len);
+      strcpy (new_name, name);
+      strcat (new_name, CHKP_LTO_SYMBOL_SUFFIX);
+      id = get_identifier (new_name);
+    }
+  else
+    id = get_identifier (name);
+
+  var  = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
+                    pointer_bounds_type_node);
 
   TREE_PUBLIC (var) = 1;
   TREE_USED (var) = 1;
@@ -1925,18 +1941,17 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
   TREE_ADDRESSABLE (var) = 0;
   DECL_ARTIFICIAL (var) = 1;
   DECL_READ_P (var) = 1;
+  DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
+  DECL_COMDAT (var) = 1;
+  DECL_WEAK (var) = 1;
   /* We may use this symbol during ctors generation in chkp_finish_file
      when all symbols are emitted.  Force output to avoid undefined
      symbols in ctors.  */
-  if (!in_lto_p)
-    {
-      DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
-      DECL_COMDAT (var) = 1;
-      varpool_node::get_create (var)->set_comdat_group (DECL_ASSEMBLER_NAME 
(var));
-      varpool_node::get_create (var)->force_output = 1;
-    }
-  else
-    DECL_EXTERNAL (var) = 1;
+  node = varpool_node::get_create (var);
+  node->set_comdat_group (DECL_ASSEMBLER_NAME (var));
+  node->force_output = 1;
+  node->externally_visible = 1;
+
   varpool_node::finalize_decl (var);
 
   return var;

Reply via email to