From: Martin Jambor Date: Mon, 18 Feb 2019 08:59:04 +0000 (+0100) Subject: [PR 89209] Avoid segfault in a peculiar corner case in SRA X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=469b4adb4fec2b61caee16ed982f5fab333e784b;p=gcc.git [PR 89209] Avoid segfault in a peculiar corner case in SRA 2019-02-18 Martin Jambor 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. From-SVN: r268980 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9370f013f07..e5a6922e59d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2019-02-18 Martin Jambor + + 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 PR ipa/89306 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a09997c87fe..9e274acbbd1 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-02-18 Martin Jambor + + PR tree-optimization/89209 + * gcc.dg/tree-ssa/pr89209.c: New test. + 2019-02-18 Martin Liska * 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 index 00000000000..f01bda9ae5c --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr89209.c @@ -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; +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index e4851daaa3f..eeef31ba496 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -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);