Hello,
this lets alias analysis handle the implicit 'this' parameter in C++
constructors as if it was restrict.
Bootstrap+regtest on powerpc64le-unknown-linux-gnu.
2018-05-18 Marc Glisse <[email protected]>
PR c++/82899
gcc/
* tree-ssa-structalias.c (create_variable_info_for_1): Extra argument.
(intra_create_variable_infos): Handle C++ constructors.
gcc/testsuite/
* g++.dg/pr82899.C: New testcase.
--
Marc GlisseIndex: gcc/testsuite/g++.dg/pr82899.C
===================================================================
--- gcc/testsuite/g++.dg/pr82899.C (nonexistent)
+++ gcc/testsuite/g++.dg/pr82899.C (working copy)
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+struct A {
+ int i;
+ A(A&);
+};
+int X;
+A::A(A&a):i(42){
+ a.i=0;
+ X=i;
+}
+
+/* { dg-final { scan-tree-dump "X = 42;" "optimized" } } */
Index: gcc/tree-ssa-structalias.c
===================================================================
--- gcc/tree-ssa-structalias.c (revision 260347)
+++ gcc/tree-ssa-structalias.c (working copy)
@@ -5928,25 +5928,28 @@ check_for_overlaps (vec<fieldoff_s> fiel
return true;
lastoffset = fo->offset;
}
return false;
}
/* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
This will also create any varinfo structures necessary for fields
of DECL. DECL is a function parameter if HANDLE_PARAM is set.
HANDLED_STRUCT_TYPE is used to register struct types reached by following
- restrict pointers. This is needed to prevent infinite recursion. */
+ restrict pointers. This is needed to prevent infinite recursion.
+ If ADD_RESTRICT, pretend that the pointer NAME is restrict even if DECL
+ does not advertise it. */
static varinfo_t
create_variable_info_for_1 (tree decl, const char *name, bool add_id,
- bool handle_param, bitmap handled_struct_type)
+ bool handle_param, bitmap handled_struct_type,
+ bool add_restrict = false)
{
varinfo_t vi, newvi;
tree decl_type = TREE_TYPE (decl);
tree declsize = DECL_P (decl) ? DECL_SIZE (decl) : TYPE_SIZE (decl_type);
auto_vec<fieldoff_s> fieldstack;
fieldoff_s *fo;
unsigned int i;
if (!declsize
|| !tree_fits_uhwi_p (declsize))
@@ -6006,21 +6009,21 @@ create_variable_info_for_1 (tree decl, c
if (fieldstack.length () == 0
|| fieldstack.length () > MAX_FIELDS_FOR_FIELD_SENSITIVE)
{
vi = new_var_info (decl, name, add_id);
vi->offset = 0;
vi->may_have_pointers = true;
vi->fullsize = tree_to_uhwi (declsize);
vi->size = vi->fullsize;
vi->is_full_var = true;
if (POINTER_TYPE_P (decl_type)
- && TYPE_RESTRICT (decl_type))
+ && (TYPE_RESTRICT (decl_type) || add_restrict))
vi->only_restrict_pointers = 1;
if (vi->only_restrict_pointers
&& !type_contains_placeholder_p (TREE_TYPE (decl_type))
&& handle_param
&& !bitmap_bit_p (handled_struct_type,
TYPE_UID (TREE_TYPE (decl_type))))
{
varinfo_t rvi;
tree heapvar = build_fake_var_decl (TREE_TYPE (decl_type));
DECL_EXTERNAL (heapvar) = 1;
@@ -6235,35 +6238,38 @@ make_param_constraints (varinfo_t vi)
}
/* Create varinfo structures for all of the variables in the
function for intraprocedural mode. */
static void
intra_create_variable_infos (struct function *fn)
{
tree t;
bitmap handled_struct_type = NULL;
+ bool this_parm_in_ctor = DECL_CXX_CONSTRUCTOR_P (fn->decl);
/* For each incoming pointer argument arg, create the constraint ARG
= NONLOCAL or a dummy variable if it is a restrict qualified
passed-by-reference argument. */
for (t = DECL_ARGUMENTS (fn->decl); t; t = DECL_CHAIN (t))
{
if (handled_struct_type == NULL)
handled_struct_type = BITMAP_ALLOC (NULL);
varinfo_t p
= create_variable_info_for_1 (t, alias_get_name (t), false, true,
- handled_struct_type);
+ handled_struct_type, this_parm_in_ctor);
insert_vi_for_tree (t, p);
make_param_constraints (p);
+
+ this_parm_in_ctor = false;
}
if (handled_struct_type != NULL)
BITMAP_FREE (handled_struct_type);
/* Add a constraint for a result decl that is passed by reference. */
if (DECL_RESULT (fn->decl)
&& DECL_BY_REFERENCE (DECL_RESULT (fn->decl)))
{
varinfo_t p, result_vi = get_vi_for_tree (DECL_RESULT (fn->decl));