[C++] PATCH c++/19628 (revision 3)

Matt Austern matt@lafstern.org
Wed Feb 2 00:41:00 GMT 2005


My earlier patch caused an ICE in some cases.  This new version fixes 
that problem, and includes a new test case.

OK to commit to mainline?

			--Matt

* cp-tree.h (builtin_valid_in_constant_expr_p): Declare.
* parser.c (cp_parser_postfix_expression): Accept function call in 
constant expression if builtin_valid_in_constant_expr_p is true for 
that function.
* pt.c (value_dependent_expression_p): Handle CALL_EXPRs properly.
* semantics.c (finish_id_expression): Accept function call in constant 
expression if builtin_valid_in_constant_expr_p is true for that 
function.
* tree.c (builtin_valid_in_constant_expr_p): New.

* g++/ext/builtin7.C: New.
* g++/ext/builtin8.C: New.


Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1099
diff -p -r1.1099 cp-tree.h
*** gcc/cp/cp-tree.h	31 Jan 2005 06:16:54 -0000	1.1099
--- gcc/cp/cp-tree.h	2 Feb 2005 00:33:09 -0000
*************** extern tree copy_binfo				(tree, tree, t
*** 4207,4212 ****
--- 4207,4213 ----
   						 tree *, int);
   extern int member_p				(tree);
   extern cp_lvalue_kind real_lvalue_p             (tree);
+ extern bool builtin_valid_in_constant_expr_p    (tree);
   extern tree build_min				(enum tree_code, tree, ...);
   extern tree build_min_nt			(enum tree_code, ...);
   extern tree build_min_non_dep			(enum tree_code, tree, ...);
Index: gcc/cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.309
diff -p -r1.309 parser.c
*** gcc/cp/parser.c	1 Feb 2005 06:58:16 -0000	1.309
--- gcc/cp/parser.c	2 Feb 2005 00:33:10 -0000
*************** cp_parser_postfix_expression (cp_parser
*** 4037,4044 ****

   	    /* Function calls are not permitted in
   	       constant-expressions.  */
! 	    if (cp_parser_non_integral_constant_expression (parser,
! 							    "a function call"))
   	      {
   		postfix_expression = error_mark_node;
   		break;
--- 4037,4045 ----

   	    /* Function calls are not permitted in
   	       constant-expressions.  */
! 	    if (! builtin_valid_in_constant_expr_p (postfix_expression)
! 		&& cp_parser_non_integral_constant_expression (parser,
! 							       "a function call"))
   	      {
   		postfix_expression = error_mark_node;
   		break;
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.971
diff -p -r1.971 pt.c
*** gcc/cp/pt.c	1 Feb 2005 05:56:03 -0000	1.971
--- gcc/cp/pt.c	2 Feb 2005 00:33:10 -0000
*************** value_dependent_expression_p (tree expre
*** 12018,12023 ****
--- 12018,12047 ----
     if (TREE_CODE (expression) == COMPONENT_REF)
       return (value_dependent_expression_p (TREE_OPERAND (expression, 
0))
   	    || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
+   /* A CALL_EXPR is value-dependent if any argument is 
value-dependent. */
+   if (TREE_CODE (expression) == CALL_EXPR)
+     {
+       tree function = TREE_OPERAND (expression, 0);
+       tree args = TREE_OPERAND (expression, 1);
+
+       if (value_dependent_expression_p (function))
+ 	return true;
+       else if (! args)
+ 	return false;
+       else if (TREE_CODE (args) == TREE_LIST)
+ 	{
+ 	  do
+ 	    {
+ 	      if (value_dependent_expression_p (TREE_VALUE (args)))
+ 		return true;
+ 	      args = TREE_CHAIN (args);
+ 	    }
+ 	  while (args);
+ 	  return false;
+ 	}
+       else
+ 	return value_dependent_expression_p (args);
+     }
     /* A constant expression is value-dependent if any subexpression is
        value-dependent.  */
     if (EXPR_P (expression))
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.459
diff -p -r1.459 semantics.c
*** gcc/cp/semantics.c	31 Jan 2005 01:16:58 -0000	1.459
--- gcc/cp/semantics.c	2 Feb 2005 00:33:10 -0000
*************** finish_id_expression (tree id_expression
*** 2663,2669 ****
            expression.  Enumerators and template parameters have already
            been handled above.  */
         if (integral_constant_expression_p
! 	  && !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
   	{
   	  if (!allow_non_integral_constant_expression_p)
   	    {
--- 2663,2670 ----
            expression.  Enumerators and template parameters have already
            been handled above.  */
         if (integral_constant_expression_p
! 	  && ! DECL_INTEGRAL_CONSTANT_VAR_P (decl)
! 	  && ! builtin_valid_in_constant_expr_p (decl))
   	{
   	  if (!allow_non_integral_constant_expression_p)
   	    {
Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.425
diff -p -r1.425 tree.c
*** gcc/cp/tree.c	18 Jan 2005 23:51:26 -0000	1.425
--- gcc/cp/tree.c	2 Feb 2005 00:33:10 -0000
*************** lvalue_p (tree ref)
*** 215,220 ****
--- 215,233 ----
       (lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
   }

+ /* Test whether DECL is a builtin that may appear in a
+    constant-expression. */
+
+ 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
Index: gcc/testsuite/g++.dg/ext/builtin7.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin7.C
diff -N gcc/testsuite/g++.dg/ext/builtin7.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin7.C	2 Feb 2005 00:33:14 -0000
***************
*** 0 ****
--- 1,14 ----
+ // PR c++/19628
+ // Verify that __builtin_constant_p may appear in a 
constant-expression.
+
+ // { dg-do run }
+
+ int main()
+ {
+   switch (3) {
+   case (__builtin_constant_p(7) ? 3 : 8):
+     return 0;
+   default:
+     return 1;
+   }
+ }
Index: gcc/testsuite/g++.dg/ext/builtin8.C
===================================================================
RCS file: gcc/testsuite/g++.dg/ext/builtin8.C
diff -N gcc/testsuite/g++.dg/ext/builtin8.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- gcc/testsuite/g++.dg/ext/builtin8.C	2 Feb 2005 00:33:14 -0000
***************
*** 0 ****
--- 1,16 ----
+ // PR c++/19628
+ // Verify that __builtin_constant_p may appear in a 
constant-expression.
+
+ // { dg-do compile }
+
+ template <int I>
+ int f(int x[__builtin_constant_p(I)])
+ {
+   return x[0];
+ }
+
+ int g()
+ {
+   int a[1] = { 7 };
+   return f<32>(a);
+ }



More information about the Gcc-patches mailing list