aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorJeff Law <law@gcc.gnu.org>2018-09-25 16:17:45 -0600
committerJeff Law <law@gcc.gnu.org>2018-09-25 16:17:45 -0600
commitc7813484bc9fe2c578d7538d0a9e286bf2e64599 (patch)
tree9e120ff490c0f193509af127eb4cae401e944f54 /gcc/expr.c
parenta9f6e019d15819f52b312e1b10cd460b59b57780 (diff)
downloadgcc-c7813484bc9fe2c578d7538d0a9e286bf2e64599.zip
gcc-c7813484bc9fe2c578d7538d0a9e286bf2e64599.tar.gz
gcc-c7813484bc9fe2c578d7538d0a9e286bf2e64599.tar.bz2
re PR c/87387 (trunk/gcc/builtins.c:585:7: warning: -Wself-assign problem)
PR c/87387 * builtins.c (unterminated_array): Simplify. * expr.c (string_constant): Handle SSA_NAME. Add more exceptions where pointer arithmetic is safe. * gcc.dg/warn-stpcpy-no-nul.c: Drop unnecessary xfails. * gcc.dg/warn-stplen-no-nul.c: Likewise. From-SVN: r264585
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c37
1 files changed, 36 insertions, 1 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index b8782b9..583c7f0 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -11372,7 +11372,10 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
/* Avoid pointers to arrays (see bug 86622). */
if (POINTER_TYPE_P (TREE_TYPE (arg))
&& TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == ARRAY_TYPE
- && TREE_CODE (TREE_OPERAND (arg0, 0)) == ARRAY_REF)
+ && !(decl && !*decl)
+ && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
+ && mem_size && tree_fits_uhwi_p (*mem_size)
+ && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
return NULL_TREE;
tree type = TREE_TYPE (arg1);
@@ -11381,6 +11384,38 @@ string_constant (tree arg, tree *ptr_offset, tree *mem_size, tree *decl)
}
return NULL_TREE;
}
+ else if (TREE_CODE (arg) == SSA_NAME)
+ {
+ gimple *stmt = SSA_NAME_DEF_STMT (arg);
+ if (!is_gimple_assign (stmt))
+ return NULL_TREE;
+
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ tree_code code = gimple_assign_rhs_code (stmt);
+ if (code == ADDR_EXPR)
+ return string_constant (rhs1, ptr_offset, mem_size, decl);
+ else if (code != POINTER_PLUS_EXPR)
+ return NULL_TREE;
+
+ tree offset;
+ if (tree str = string_constant (rhs1, &offset, mem_size, decl))
+ {
+ /* Avoid pointers to arrays (see bug 86622). */
+ if (POINTER_TYPE_P (TREE_TYPE (rhs1))
+ && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs1))) == ARRAY_TYPE
+ && !(decl && !*decl)
+ && !(decl && tree_fits_uhwi_p (DECL_SIZE_UNIT (*decl))
+ && mem_size && tree_fits_uhwi_p (*mem_size)
+ && tree_int_cst_equal (*mem_size, DECL_SIZE_UNIT (*decl))))
+ return NULL_TREE;
+
+ tree rhs2 = gimple_assign_rhs2 (stmt);
+ tree type = TREE_TYPE (rhs2);
+ *ptr_offset = fold_build2 (PLUS_EXPR, type, offset, rhs2);
+ return str;
+ }
+ return NULL_TREE;
+ }
else if (DECL_P (arg))
array = arg;
else