Here we ICE because get_range_strlen's result might not be an array of two integer constants -- for a VLA the array might contain a non-constant. So beef up the check before converting to wide_int.
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2018-02-06 Marek Polacek <pola...@redhat.com> PR tree-optimization/84238 * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Verify the result of get_range_strlen. * gcc.dg/Wstringop-overflow-3.c: New test. diff --git gcc/testsuite/gcc.dg/Wstringop-overflow-3.c gcc/testsuite/gcc.dg/Wstringop-overflow-3.c index e69de29bb2d..8e2531f6b4e 100644 --- gcc/testsuite/gcc.dg/Wstringop-overflow-3.c +++ gcc/testsuite/gcc.dg/Wstringop-overflow-3.c @@ -0,0 +1,13 @@ +/* PR tree-optimization/84238 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +char a[1]; +int b; +char *strncpy (char *, char *, __SIZE_TYPE__); +void +c () +{ + char d[b]; + strncpy (a, &d[3], 3); /* { dg-warning "writing 3 bytes into a region of size 1" } */ +} diff --git gcc/tree-ssa-strlen.c gcc/tree-ssa-strlen.c index f0f6535017b..94ed2bedc03 100644 --- gcc/tree-ssa-strlen.c +++ gcc/tree-ssa-strlen.c @@ -1899,7 +1899,10 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt) { tree range[2]; get_range_strlen (src, range); - if (range[0]) + if (range[0] != NULL_TREE + && TREE_CODE (range[0]) == INTEGER_CST + && range[1] != NULL_TREE + && TREE_CODE (range[1]) == INTEGER_CST) { lenrange[0] = wi::to_wide (range[0], prec); lenrange[1] = wi::to_wide (range[1], prec); Marek