diff options
author | Martin Sebor <msebor@redhat.com> | 2018-10-05 16:43:11 +0000 |
---|---|---|
committer | Martin Sebor <msebor@gcc.gnu.org> | 2018-10-05 10:43:11 -0600 |
commit | f343165275ab5a22546f82f75351a876449309a7 (patch) | |
tree | 8f20c275050047b78af765ced840e7a2f5e38a6b /gcc/builtins.c | |
parent | e0b9bc230ac50c67c63f303b70e72b34a7c516fb (diff) | |
download | gcc-f343165275ab5a22546f82f75351a876449309a7.zip gcc-f343165275ab5a22546f82f75351a876449309a7.tar.gz gcc-f343165275ab5a22546f82f75351a876449309a7.tar.bz2 |
PR tree-optimization/87490 - ICE in expand_builtin_strnlen with a constant argument and non-constant bound
gcc/ChangeLog:
PR tree-optimization/87490
* builtins.c (expand_builtin_strnlen): Handle a null data.decl
consistently.
gcc/testsuite/ChangeLog:
PR tree-optimization/87490
* gcc.dg/pr87490.c: New test.
* gcc.dg/warn-strnlen-no-nul-2.c: Same.
From-SVN: r264876
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r-- | gcc/builtins.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c index 2cb1996..25e01e4 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -3151,21 +3151,39 @@ expand_builtin_strnlen (tree exp, rtx target, machine_mode target_mode) exp, func, min.to_uhwi (), max.to_uhwi (), maxobjsize)) TREE_NO_WARNING (exp) = true; + bool exact = true; if (!len || TREE_CODE (len) != INTEGER_CST) - return NULL_RTX; + { + data.decl = unterminated_array (src, &len, &exact); + if (!data.decl) + return NULL_RTX; + } - if (!TREE_NO_WARNING (exp) - && wi::ltu_p (wi::to_wide (len), min) - && warning_at (loc, OPT_Wstringop_overflow_, - "%K%qD specified bound [%wu, %wu] " - "exceeds the size %E of unterminated array", - exp, func, min.to_uhwi (), max.to_uhwi (), len)) + if (data.decl + && !TREE_NO_WARNING (exp) + && (wi::ltu_p (wi::to_wide (len), min) + || !exact)) { - inform (DECL_SOURCE_LOCATION (data.decl), - "referenced argument declared here"); - TREE_NO_WARNING (exp) = true; + location_t warnloc + = expansion_point_location_if_in_system_header (loc); + + if (warning_at (warnloc, OPT_Wstringop_overflow_, + exact + ? G_("%K%qD specified bound [%wu, %wu] exceeds " + "the size %E of unterminated array") + : G_("%K%qD specified bound [%wu, %wu] may exceed " + "the size of at most %E of unterminated array"), + exp, func, min.to_uhwi (), max.to_uhwi (), len)) + { + inform (DECL_SOURCE_LOCATION (data.decl), + "referenced argument declared here"); + TREE_NO_WARNING (exp) = true; + } } + if (data.decl) + return NULL_RTX; + if (wi::gtu_p (min, wi::to_wide (len))) return expand_expr (len, target, target_mode, EXPAND_NORMAL); |