diff --git a/gcc/ChangeLog b/gcc/ChangeLog index baf0ab727f3..b75ac74e73a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2020-03-25 Martin Sebor + + PR tree-optimization/94131 + * gimple-fold.c (get_range_strlen_tree): Fail for variable-length + types and decls. + * tree-ssa-strlen.c (get_range_strlen_dynamic): Avoid assuming + types have constant sizes. + 2020-03-25 Martin Liska PR lto/94259 diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index c5939f19f59..55b78fa284f 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -1378,7 +1378,9 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind, /* Fail when the array bound is unknown or zero. */ val = TYPE_SIZE_UNIT (optype); - if (!val || integer_zerop (val)) + if (!val + || TREE_CODE (val) != INTEGER_CST + || integer_zerop (val)) return false; val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val, @@ -1412,7 +1414,9 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind, /* Fail when the array bound is unknown or zero. */ val = TYPE_SIZE_UNIT (optype); - if (!val || integer_zerop (val)) + if (!val + || TREE_CODE (val) != INTEGER_CST + || integer_zerop (val)) return false; val = fold_build2 (MINUS_EXPR, TREE_TYPE (val), val, integer_one_node); @@ -1448,7 +1452,9 @@ get_range_strlen_tree (tree arg, bitmap *visited, strlen_range_kind rkind, /* Fail if the offset is out of bounds. Such accesses should be diagnosed at some point. */ val = DECL_SIZE_UNIT (ref); - if (!val || integer_zerop (val)) + if (!val + || TREE_CODE (val) != INTEGER_CST + || integer_zerop (val)) return false; poly_offset_int psiz = wi::to_offset (val); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5fa61f94349..7f2d5908713 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2020-03-25 Martin Sebor + + PR tree-optimization/94131 + * gcc.dg/pr94131.c: New test. + 2020-03-25 Sandra Loosemore * gcc.dg/pr92301.c (main): Allow argc to be 0 to support diff --git a/gcc/testsuite/gcc.dg/pr84131.c b/gcc/testsuite/gcc.dg/pr84131.c new file mode 100644 index 00000000000..0ba96516fe3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr84131.c @@ -0,0 +1,29 @@ +/* PR 94131 - ICE on printf with a VLA string and -fno-tree-ccp + -fno-tree-forwprop + { dg-do compile } + { dg-options "-O1 -fno-tree-ccp -fno-tree-forwprop" } */ + +void rv1 (int n) +{ + char a[n]; + __INTPTR_TYPE__ i = (__INTPTR_TYPE__ )&a[0]; + i &= 3; + + __builtin_memset (a, '\0', sizeof a); + __builtin_printf ("%s", i ? &a[0] : ""); +} + + +void sink (void*); + +void rv2 (int n) +{ + char a[n]; + __INTPTR_TYPE__ i = (__INTPTR_TYPE__)&a[0]; + i &= 3; + + __builtin_memset (a, '\0', sizeof a); + __builtin_printf ("%s", i ? &a[0] : ""); + + sink (a); +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index 6dd37fb0b78..93d095e1896 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1140,10 +1140,16 @@ get_range_strlen_dynamic (tree src, c_strlen_data *pdata, bitmap *visited, { tree basetype = TREE_TYPE (base); tree size = TYPE_SIZE_UNIT (basetype); - ++off; /* Increment for the terminating nul. */ - pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size, - build_int_cst (size_type_node, off)); - pdata->maxbound = pdata->maxlen; + if (TREE_CODE (size) == INTEGER_CST) + { + ++off; /* Increment for the terminating nul. */ + tree toffset = build_int_cst (size_type_node, off); + pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size, + toffset); + pdata->maxbound = pdata->maxlen; + } + else + pdata->maxlen = build_all_ones_cst (size_type_node); } else pdata->maxlen = build_all_ones_cst (size_type_node);