The following gets rid of __builtin_constant_p earlier to avoid
array-bound diagnostics on dead code.  There's been enough optimization
on the fully inlined bodies so we can do that at the time of
array-bound diagnostics.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2019-09-11  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/90387
        * vr-values.c (vr_values::extract_range_basic): After inlining
        simplify non-constant __builtin_constant_p to false.

        * gcc.dg/Warray-bounds-44.c: New testcase.

Index: gcc/vr-values.c
===================================================================
--- gcc/vr-values.c     (revision 275638)
+++ gcc/vr-values.c     (working copy)
@@ -1124,15 +1124,8 @@ vr_values::extract_range_basic (value_ra
       switch (cfn)
        {
        case CFN_BUILT_IN_CONSTANT_P:
-         /* If the call is __builtin_constant_p and the argument is a
-            function parameter resolve it to false.  This avoids bogus
-            array bound warnings.
-            ???  We could do this as early as inlining is finished.  */
-         arg = gimple_call_arg (stmt, 0);
-         if (TREE_CODE (arg) == SSA_NAME
-             && SSA_NAME_IS_DEFAULT_DEF (arg)
-             && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL
-             && cfun->after_inlining)
+         /* Resolve calls to __builtin_constant_p after inlining.  */
+         if (cfun->after_inlining)
            {
              vr->set_zero (type);
              vr->equiv_clear ();
Index: gcc/testsuite/gcc.dg/Warray-bounds-44.c
===================================================================
--- gcc/testsuite/gcc.dg/Warray-bounds-44.c     (nonexistent)
+++ gcc/testsuite/gcc.dg/Warray-bounds-44.c     (working copy)
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Warray-bounds" } */
+
+int foo(unsigned int state, unsigned char * p, unsigned int p_len)
+{
+    static char const pattern[] = "abcd";
+    static unsigned const pattern_length = sizeof(pattern) - 1;
+
+    if (p_len == 1) {
+        return state;
+    }
+
+    if (state < pattern_length &&
+        p_len == (pattern_length - state) &&
+       (!__builtin_constant_p(p_len) ?
+         __builtin_memcmp(p, pattern + state, p_len) :
+         ((unsigned char*)p)[6] == ((unsigned char*)pattern + state)[6] /* { 
dg-bogus "array bounds" } */
+        )) {
+
+        return 4;
+    }
+    return 1;
+}

Reply via email to