]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PR 89209] Avoid segfault in a peculiar corner case in SRA
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Feb 2019 08:59:04 +0000 (08:59 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 18 Feb 2019 08:59:04 +0000 (08:59 +0000)
2019-02-18  Martin Jambor  <mjambor@suse.cz>

PR tree-optimization/89209
* tree-sra.c (create_access_replacement): New optional parameter
reg_tree.  Use it as a type if non-NULL and access type is not of
a register type.
(get_repl_default_def_ssa_name): New parameter REG_TYPE, pass it
to create_access_replacement.
(sra_modify_assign): Pass LHS type to get_repl_default_def_ssa_name.
Check lacc is non-NULL before attempting to re-create it on the RHS.

testsuite/
* gcc.dg/tree-ssa/pr89209.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@268980 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr89209.c [new file with mode: 0644]
gcc/tree-sra.c

index 9370f013f07fd02780c88026389a51fe7a37e37c..e5a6922e59d7e881f530f38dedb9e171092eaf39 100644 (file)
@@ -1,3 +1,14 @@
+2019-02-18  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/89209
+       * tree-sra.c (create_access_replacement): New optional parameter
+       reg_tree.  Use it as a type if non-NULL and access type is not of
+       a register type.
+       (get_repl_default_def_ssa_name): New parameter REG_TYPE, pass it
+       to create_access_replacement.
+       (sra_modify_assign): Pass LHS type to get_repl_default_def_ssa_name.
+       Check lacc is non-NULL before attempting to re-create it on the RHS.
+
 2019-02-18  Martin Liska  <mliska@suse.cz>
 
        PR ipa/89306
index a09997c87fe2b110a67c3b6c1e6c2600cb296baa..9e274acbbd1ea58245b204b44f19e1b72df86b68 100644 (file)
@@ -1,3 +1,8 @@
+2019-02-18  Martin Jambor  <mjambor@suse.cz>
+
+       PR tree-optimization/89209
+       * gcc.dg/tree-ssa/pr89209.c: New test.
+
 2019-02-18  Martin Liska  <mliska@suse.cz>
 
        * gfortran.dg/simd-builtins-7.f90: New test.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr89209.c b/gcc/testsuite/gcc.dg/tree-ssa/pr89209.c
new file mode 100644 (file)
index 0000000..f01bda9
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct S {
+  short a, b;
+};
+struct T {
+  int c;
+  struct S s;
+};
+int f ()
+{
+  struct T t;
+  t.c = t.s.a || t.s.b;
+  return t.c;
+}
index e4851daaa3fe179b548ce65186843485ec5ae952..eeef31ba496018ca81baa14ea49b7c9327c11657 100644 (file)
@@ -2195,13 +2195,20 @@ sort_and_splice_var_accesses (tree var)
 
 /* Create a variable for the given ACCESS which determines the type, name and a
    few other properties.  Return the variable declaration and store it also to
-   ACCESS->replacement.  */
+   ACCESS->replacement.  REG_TREE is used when creating a declaration to base a
+   default-definition SSA name on on in order to facilitate an uninitialized
+   warning.  It is used instead of the actual ACCESS type if that is not of a
+   gimple register type.  */
 
 static tree
-create_access_replacement (struct access *access)
+create_access_replacement (struct access *access, tree reg_type = NULL_TREE)
 {
   tree repl;
 
+  tree type = access->type;
+  if (reg_type && !is_gimple_reg_type (type))
+    type = reg_type;
+
   if (access->grp_to_be_debug_replaced)
     {
       repl = create_tmp_var_raw (access->type);
@@ -2210,17 +2217,16 @@ create_access_replacement (struct access *access)
   else
     /* Drop any special alignment on the type if it's not on the main
        variant.  This avoids issues with weirdo ABIs like AAPCS.  */
-    repl = create_tmp_var (build_qualified_type
-                            (TYPE_MAIN_VARIANT (access->type),
-                             TYPE_QUALS (access->type)), "SR");
-  if (TREE_CODE (access->type) == COMPLEX_TYPE
-      || TREE_CODE (access->type) == VECTOR_TYPE)
+    repl = create_tmp_var (build_qualified_type (TYPE_MAIN_VARIANT (type),
+                                                TYPE_QUALS (type)), "SR");
+  if (TREE_CODE (type) == COMPLEX_TYPE
+      || TREE_CODE (type) == VECTOR_TYPE)
     {
       if (!access->grp_partial_lhs)
        DECL_GIMPLE_REG_P (repl) = 1;
     }
   else if (access->grp_partial_lhs
-          && is_gimple_reg_type (access->type))
+          && is_gimple_reg_type (type))
     TREE_ADDRESSABLE (repl) = 1;
 
   DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
@@ -3450,15 +3456,16 @@ sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
 
 /* Create and return a new suitable default definition SSA_NAME for RACC which
    is an access describing an uninitialized part of an aggregate that is being
-   loaded.  */
+   loaded.  REG_TREE is used instead of the actual RACC type if that is not of
+   a gimple register type.  */
 
 static tree
-get_repl_default_def_ssa_name (struct access *racc)
+get_repl_default_def_ssa_name (struct access *racc, tree reg_type)
 {
   gcc_checking_assert (!racc->grp_to_be_replaced
                       && !racc->grp_to_be_debug_replaced);
   if (!racc->replacement_decl)
-    racc->replacement_decl = create_access_replacement (racc);
+    racc->replacement_decl = create_access_replacement (racc, reg_type);
   return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
 }
 
@@ -3530,7 +3537,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
           && TREE_CODE (lhs) == SSA_NAME
           && !access_has_replacements_p (racc))
     {
-      rhs = get_repl_default_def_ssa_name (racc);
+      rhs = get_repl_default_def_ssa_name (racc, TREE_TYPE (lhs));
       modify_this_stmt = true;
       sra_stats.exprs++;
     }
@@ -3548,7 +3555,8 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
              lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
              gimple_assign_set_lhs (stmt, lhs);
            }
-         else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
+         else if (lacc
+                  && AGGREGATE_TYPE_P (TREE_TYPE (rhs))
                   && !contains_vce_or_bfcref_p (rhs))
            rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);