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

Reply via email to