From 88a7beb769bd14c1affeb7c801842058e3071ab6 Mon Sep 17 00:00:00 2001
From: Mark Mitchell <mark@codesourcery.com>
Date: Sun, 5 Jun 2005 16:33:43 +0000
Subject: [PATCH] re PR c++/21619 (__builtin_constant_p(&"Hello"[0])?1:-1 not
 compile-time constant)

	PR c++/21619
	* cp-tree.h (DECL_IS_BUILTIN_CONSTANT_P): New macro.
	* parser.c (cp_parser_postfix_expression): Allow non-constant
	expressions as arguments to __builtin_constant_p.
	* tree.c (builtin_valid_in_constant_expr_p): Use
	DECL_IS_BUILTIN_CONSTANT_P.

	PR c++/21619
	* g++.dg/ext/builtin9.C: New test.

From-SVN: r100626
---
 gcc/cp/ChangeLog                    |  9 ++++++++
 gcc/cp/cp-tree.h                    |  6 ++++++
 gcc/cp/parser.c                     | 32 +++++++++++++++++++++++++----
 gcc/cp/tree.c                       |  4 +---
 gcc/testsuite/ChangeLog             |  5 +++++
 gcc/testsuite/g++.dg/ext/builtin9.C |  3 +++
 6 files changed, 52 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/ext/builtin9.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1f8b27013660..3c6f25a1c149 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2005-06-05  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/21619
+	* cp-tree.h (DECL_IS_BUILTIN_CONSTANT_P): New macro.
+	* parser.c (cp_parser_postfix_expression): Allow non-constant
+	expressions as arguments to __builtin_constant_p.
+	* tree.c (builtin_valid_in_constant_expr_p): Use
+	DECL_IS_BUILTIN_CONSTANT_P. 
+
 2005-06-03  Mark Mitchell  <mark@codesourcery.com>
 
 	PR c++/21853
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0f3dfa5c8904..bcc6b3fc3ede 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1787,6 +1787,12 @@ struct lang_decl GTY(())
 #define DECL_HAS_IN_CHARGE_PARM_P(NODE) \
   (DECL_LANG_SPECIFIC (NODE)->decl_flags.has_in_charge_parm_p)
 
+/* Nonzero if DECL is a declaration of __builtin_constant_p.  */
+#define DECL_IS_BUILTIN_CONSTANT_P(NODE)		\
+ (TREE_CODE (NODE) == FUNCTION_DECL			\
+  && DECL_BUILT_IN_CLASS (NODE) == BUILT_IN_NORMAL	\
+  && DECL_FUNCTION_CODE (NODE) == BUILT_IN_CONSTANT_P)
+
 /* Nonzero for _DECL means that this decl appears in (or will appear
    in) as a member in a RECORD_TYPE or UNION_TYPE node.  It is also for
    detecting circularity in case members are multiply defined.  In the
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 27c1751cb02a..65442c769d0e 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -4121,10 +4121,34 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
 	  /* postfix-expression ( expression-list [opt] ) */
 	  {
 	    bool koenig_p;
-	    tree args = (cp_parser_parenthesized_expression_list
-			 (parser, false, 
-			  /*cast_p=*/false,
-			  /*non_constant_p=*/NULL));
+	    bool is_builtin_constant_p;
+	    bool saved_integral_constant_expression_p = false;
+	    bool saved_non_integral_constant_expression_p = false;
+	    tree args;
+
+	    is_builtin_constant_p 
+	      = DECL_IS_BUILTIN_CONSTANT_P (postfix_expression);
+	    if (is_builtin_constant_p)
+	      {
+		/* The whole point of __builtin_constant_p is to allow
+		   non-constant expressions to appear as arguments.  */
+		saved_integral_constant_expression_p
+		  = parser->integral_constant_expression_p;
+		saved_non_integral_constant_expression_p
+		  = parser->non_integral_constant_expression_p;
+		parser->integral_constant_expression_p = false;
+	      }
+	    args = (cp_parser_parenthesized_expression_list
+		    (parser, /*is_attribute_list=*/false, 
+		     /*cast_p=*/false,
+		     /*non_constant_p=*/NULL));
+	    if (is_builtin_constant_p)
+	      {
+		parser->integral_constant_expression_p
+		  = saved_integral_constant_expression_p;
+		parser->non_integral_constant_expression_p
+		  = saved_non_integral_constant_expression_p;
+	      }
 
 	    if (args == error_mark_node)
 	      {
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 8ef383c30eea..321988a1a205 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -225,9 +225,7 @@ builtin_valid_in_constant_expr_p (tree decl)
 {
   /* At present BUILT_IN_CONSTANT_P is the only builtin we're allowing
      in constant-expressions.  We may want to add other builtins later. */
-  return TREE_CODE (decl) == FUNCTION_DECL
-    && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
-    && DECL_FUNCTION_CODE (decl) == BUILT_IN_CONSTANT_P;
+  return DECL_IS_BUILTIN_CONSTANT_P (decl);
 }
 
 /* Build a TARGET_EXPR, initializing the DECL with the VALUE.  */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 737245c99c52..0fa5e70056f2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-06-05  Mark Mitchell  <mark@codesourcery.com>
+
+	PR c++/21619
+	* g++.dg/ext/builtin9.C: New test.
+
 2005-06-05  Dale Johannesen  <dalej@apple.com>
 
 	* gcc.c-torture/execute/20050603-1.c:  Move to gcc.dg.
diff --git a/gcc/testsuite/g++.dg/ext/builtin9.C b/gcc/testsuite/g++.dg/ext/builtin9.C
new file mode 100644
index 000000000000..6b2b712deab4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin9.C
@@ -0,0 +1,3 @@
+// PR c++/21619
+// { dg-options "" }
+int f[__builtin_constant_p(&"Hello"[0])?1:-1];
-- 
GitLab