new file mode 100644
@@ -0,0 +1,26 @@
+/* { dg-lto-do link } */
+/* { dg-require-effective-target mpx } */
+/* { dg-lto-options { { -flto -flto-partition=max -fcheck-pointer-bounds -mmpx } } } */
+
+const 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]);
+}
@@ -1873,33 +1873,6 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
gimple_call_set_with_bounds (new_call, true);
}
-/* Return constant static bounds var with specified LB and UB
- if such var exists in varpool. Return NULL otherwise. */
-static tree
-chkp_find_const_bounds_var (HOST_WIDE_INT lb,
- HOST_WIDE_INT ub)
-{
- tree val = targetm.chkp_make_bounds_constant (lb, ub);
- struct varpool_node *node;
-
- /* We expect bounds constant is represented as a complex value
- of two pointer sized integers. */
- gcc_assert (TREE_CODE (val) == COMPLEX_CST);
-
- FOR_EACH_VARIABLE (node)
- if (POINTER_BOUNDS_P (node->decl)
- && TREE_READONLY (node->decl)
- && DECL_INITIAL (node->decl)
- && TREE_CODE (DECL_INITIAL (node->decl)) == COMPLEX_CST
- && tree_int_cst_equal (TREE_REALPART (DECL_INITIAL (node->decl)),
- TREE_REALPART (val))
- && tree_int_cst_equal (TREE_IMAGPART (DECL_INITIAL (node->decl)),
- TREE_IMAGPART (val)))
- return node->decl;
-
- return NULL;
-}
-
/* Return constant static bounds var with specified bounds LB and UB.
If such var does not exists then new var is created with specified NAME. */
static tree
@@ -1907,37 +1880,38 @@ chkp_make_static_const_bounds (HOST_WIDE_INT lb,
HOST_WIDE_INT ub,
const char *name)
{
+ tree id = get_identifier (name);
tree var;
+ varpool_node *node;
+ symtab_node *snode;
+
+ var = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
+ pointer_bounds_type_node);
+ TREE_STATIC (var) = 1;
/* With LTO we may have constant bounds already in varpool.
Try to find it. */
- var = chkp_find_const_bounds_var (lb, ub);
-
- if (var)
- return var;
-
- var = build_decl (UNKNOWN_LOCATION, VAR_DECL,
- get_identifier (name), pointer_bounds_type_node);
+ if ((snode = symtab_node::get_for_asmname (DECL_ASSEMBLER_NAME (var))))
+ {
+ /* We don't allow this symbol usage for non bounds. */
+ gcc_assert (snode->type == SYMTAB_VARIABLE);
+ gcc_assert (POINTER_BOUNDS_P (snode->decl));
+ return snode->decl;
+ }
- TREE_PUBLIC (var) = 1;
TREE_USED (var) = 1;
TREE_READONLY (var) = 1;
- TREE_STATIC (var) = 1;
TREE_ADDRESSABLE (var) = 0;
DECL_ARTIFICIAL (var) = 1;
DECL_READ_P (var) = 1;
+ DECL_INITIAL (var) = targetm.chkp_make_bounds_constant (lb, ub);
+ make_decl_one_only (var, DECL_ASSEMBLER_NAME (var));
/* 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->force_output = 1;
+
varpool_node::finalize_decl (var);
return var;