My yesterday's change to tree-ssa-strlen.c introduced a test for INTEGER_TYPE where INTEGRAL_TYPE_P should have been used, causing a subsequent ICE when the latter was supplied.
The attached patch corrects the test and also makes the subsequent code more robust and be prepared for the test to fail. Since the change also caused a couple pf regressions in the Ada test suite, if there are no objections, I will commit the patch later today to clear up those failures. Retested on x86_64-linux with no regressions (including in the Ada test suite). Martin
PR tree-optimization/86696 - ICE in handle_char_store at gcc/tree-ssa-strlen.c:3332 gcc/ChangeLog: PR tree-optimization/86696 * tree-ssa-strlen.c (get_min_string_length): Handle all integer types, including enums. (handle_char_store): Be prepared for the above function to fail. gcc/testsuite/ChangeLog: PR tree-optimization/86696 * gcc.dg/pr86696.C: New test. Index: gcc/testsuite/g++.dg/pr86696.C =================================================================== --- gcc/testsuite/g++.dg/pr86696.C (nonexistent) +++ gcc/testsuite/g++.dg/pr86696.C (working copy) @@ -0,0 +1,30 @@ +/* PR tree-optimization/86696 - ICE in handle_char_store at + gcc/tree-ssa-strlen.c + { dg-do compile } + { dg-options "-O2 -Wall -std=c++11" } */ + +typedef char a; +template <typename b> struct c { + int d; + b e; +}; +struct f; +class g { +public: + void h(c<f>); +}; +enum i {}; +enum j : a { k, l }; +struct f { + i m; + a n; + a o; + a p; + j family; +}; +void fn1() { + i format{}; + f info{format, a(), 0, 4, l}; + g dest; + dest.h({format, info}); +} Index: gcc/tree-ssa-strlen.c =================================================================== --- gcc/tree-ssa-strlen.c (revision 263030) +++ gcc/tree-ssa-strlen.c (working copy) @@ -3150,7 +3150,7 @@ handle_pointer_plus (gimple_stmt_iterator *gsi) static HOST_WIDE_INT get_min_string_length (tree rhs, bool *full_string_p) { - if (TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE) + if (INTEGRAL_TYPE_P (TREE_TYPE (rhs))) { if (tree_expr_nonzero_p (rhs)) { @@ -3315,9 +3315,16 @@ handle_char_store (gimple_stmt_iterator *gsi) Otherwise, we're storing an unknown value at offset OFFSET, so need to clip the nonzero_chars to OFFSET. */ bool full_string_p = storing_all_zeros_p; - HOST_WIDE_INT len = (storing_nonzero_p - ? get_min_string_length (rhs, &full_string_p) - : 1); + HOST_WIDE_INT len = 1; + if (storing_nonzero_p) + { + /* Try to get the minimum length of the string (or + individual character) being stored. If it fails, + STORING_NONZERO_P guarantees it's at least 1. */ + len = get_min_string_length (rhs, &full_string_p); + if (len < 0) + len = 1; + } location_t loc = gimple_location (stmt); tree oldlen = si->nonzero_chars;