[backport from gcc-4.8/trunk r195103 <mikpe@it.uu.se>]

gcc/

2012-01-11  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/44061
	* tree-vrp.c (extract_range_basic): Compute zero as
	value-range for __builtin_constant_p of function parameters.

gcc/testsuite/

2012-01-11  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/44061
	* gcc.dg/pr44061.c: New testcase.

--- gcc-4.6.3/gcc/testsuite/gcc.dg/pr44061.c.~1~	1970-01-01 01:00:00.000000000 +0100
+++ gcc-4.6.3/gcc/testsuite/gcc.dg/pr44061.c	2013-01-20 13:01:37.503037643 +0100
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+int a[2];
+int foo (int q)
+{
+  if (__builtin_constant_p (q))
+    {
+      if (q == 4)
+	return a[4]; /* { dg-bogus "array subscript is above array bounds" } */
+      else
+	return a[0];
+    }
+  else
+    return a[q];
+}
--- gcc-4.6.3/gcc/tree-vrp.c.~1~	2011-10-12 17:12:58.000000000 +0200
+++ gcc-4.6.3/gcc/tree-vrp.c	2013-01-20 13:01:37.503037643 +0100
@@ -3278,8 +3278,20 @@ extract_range_basic (value_range_t *vr, 
   bool sop = false;
   tree type = gimple_expr_type (stmt);
 
-  if (INTEGRAL_TYPE_P (type)
-      && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
+  /* 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.  */
+  if (gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
+    {
+      tree 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)
+	set_value_range_to_null (vr, type);
+    }
+  else if (INTEGRAL_TYPE_P (type)
+	   && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
     set_value_range_to_nonnegative (vr, type,
 				    sop || stmt_overflow_infinity (stmt));
   else if (vrp_stmt_computes_nonzero (stmt, &sop)
