This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: PR 21619


This patch mostly fixes PR c++/21619.  When we started correctly
checking integral constant-expressions we became too strict; the
arguments to __builtin_constant_p are allowed to be non-constant, even
if the call appears in a constant expression.  However, the test case
assumes that &"hello"[1] is a constant; the 4.0 branch does not agree,
though 4.1 does.  So, while I put the patch on both branches, the test
case is only on 4.1.

Tested on x86_64-unknown-linux-gnu, applied on the mainline and 4.0
branch. 

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

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-05  Mark Mitchell  <mark@codesourcery.com>

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

Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1140
diff -c -5 -p -r1.1140 cp-tree.h
*** gcc/cp/cp-tree.h	3 Jun 2005 16:16:10 -0000	1.1140
--- gcc/cp/cp-tree.h	5 Jun 2005 16:28:54 -0000
*************** struct lang_decl GTY(())
*** 1785,1794 ****
--- 1785,1800 ----
     constructor or a destructor with an extra in-charge parameter to
     control whether or not virtual bases are constructed.  */
  #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
     case of a VAR_DECL, it is also used to determine how program storage
     should be allocated.  */
Index: gcc/cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.335
diff -c -5 -p -r1.335 parser.c
*** gcc/cp/parser.c	27 May 2005 23:17:14 -0000	1.335
--- gcc/cp/parser.c	5 Jun 2005 16:28:54 -0000
*************** cp_parser_postfix_expression (cp_parser 
*** 4119,4132 ****
  
  	case CPP_OPEN_PAREN:
  	  /* postfix-expression ( expression-list [opt] ) */
  	  {
  	    bool koenig_p;
! 	    tree args = (cp_parser_parenthesized_expression_list
! 			 (parser, false, 
! 			  /*cast_p=*/false,
! 			  /*non_constant_p=*/NULL));
  
  	    if (args == error_mark_node)
  	      {
  		postfix_expression = error_mark_node;
  		break;
--- 4119,4156 ----
  
  	case CPP_OPEN_PAREN:
  	  /* postfix-expression ( expression-list [opt] ) */
  	  {
  	    bool koenig_p;
! 	    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)
  	      {
  		postfix_expression = error_mark_node;
  		break;
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.435
diff -c -5 -p -r1.435 tree.c
*** gcc/cp/tree.c	27 May 2005 23:17:20 -0000	1.435
--- gcc/cp/tree.c	5 Jun 2005 16:28:54 -0000
*************** lvalue_p (tree ref)
*** 223,235 ****
  bool
  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;
  }
  
  /* Build a TARGET_EXPR, initializing the DECL with the VALUE.  */
  
  static tree
--- 223,233 ----
  bool
  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 DECL_IS_BUILTIN_CONSTANT_P (decl);
  }
  
  /* Build a TARGET_EXPR, initializing the DECL with the VALUE.  */
  
  static tree
Index: gcc/testsuite/g++.dg/ext/builtin9.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin9.C
diff -N gcc/testsuite/g++.dg/ext/builtin9.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin9.C	5 Jun 2005 16:28:54 -0000
***************
*** 0 ****
--- 1,3 ----
+ // PR c++/21619
+ // { dg-options "" }
+ int f[__builtin_constant_p(&"Hello"[0])?1:-1];


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]