The code here was assuming that get_maxval_strlen returns an INTEGER_CST. As the testcase demonstrates, that is not always true, so check for that before calling compare_tree_int. E.g. gimple_fold_builtin_strncpy already has this check.
Bootstrapped/regtested on x86_64-linux, ok for trunk and 5? 2015-05-31 Marek Polacek <pola...@redhat.com> PR middle-end/66345 * gimple-fold.c (gimple_fold_builtin_snprintf): Return false if get_maxval_strlen does not produce an INTEGER_CST. * gcc.dg/torture/pr66345.c: New test. diff --git gcc/gimple-fold.c gcc/gimple-fold.c index c91f218..b2ce851 100644 --- gcc/gimple-fold.c +++ gcc/gimple-fold.c @@ -2530,7 +2530,7 @@ gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi) return false; tree orig_len = get_maxval_strlen (orig, 0); - if (!orig_len) + if (!orig_len || TREE_CODE (orig_len) != INTEGER_CST) return false; /* We could expand this as diff --git gcc/testsuite/gcc.dg/torture/pr66345.c gcc/testsuite/gcc.dg/torture/pr66345.c index e69de29..1687987 100644 --- gcc/testsuite/gcc.dg/torture/pr66345.c +++ gcc/testsuite/gcc.dg/torture/pr66345.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ + +extern int snprintf (char *, unsigned long, const char *, ...); +const char a[] = ""; +int b; +void +get_bar () +{ + snprintf (0, 0, "%s", &a[b]); +} Marek