OSDN Git Service

PR c++/19628
authoraustern <austern@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Feb 2005 00:02:10 +0000 (00:02 +0000)
committeraustern <austern@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 3 Feb 2005 00:02:10 +0000 (00:02 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94635 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/cp/tree.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/builtin7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/ext/builtin8.C [new file with mode: 0644]

index 0aca2e0..230e710 100644 (file)
@@ -1,3 +1,16 @@
+2005-02-02  Matt Austern  <austern@apple.com>
+
+       PR c++/19628
+       * 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.
+       
 2005-02-02  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR c++/17413
index fa4c630..58e0fa8 100644 (file)
@@ -4205,6 +4205,7 @@ extern tree copy_binfo                            (tree, tree, tree,
                                                 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 7450f18..e89fd85 100644 (file)
@@ -4037,8 +4037,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
 
            /* Function calls are not permitted in
               constant-expressions.  */
-           if (cp_parser_non_integral_constant_expression (parser,
-                                                           "a function call"))
+           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 0e6ce13..d0cd229 100644 (file)
@@ -12020,6 +12020,36 @@ value_dependent_expression_p (tree expression)
   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.  Why do we have to handle CALL_EXPRs in this
+     function at all?  First, some function calls, those for which
+     value_dependent_expression_p is true, man appear in constant
+     expressions.  Second, there appear to be bugs which result in
+     other CALL_EXPRs reaching this point. */
+  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 c0e68d1..ebc213d 100644 (file)
@@ -2663,7 +2663,8 @@ finish_id_expression (tree id_expression,
          expression.  Enumerators and template parameters have already
          been handled above.  */
       if (integral_constant_expression_p
-         && !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
+         && ! DECL_INTEGRAL_CONSTANT_VAR_P (decl)
+         && ! builtin_valid_in_constant_expr_p (decl))
        {
          if (!allow_non_integral_constant_expression_p)
            {
index 0a0b3ec..8a264d7 100644 (file)
@@ -215,6 +215,19 @@ lvalue_p (tree ref)
     (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 06a18e4..68c973a 100644 (file)
@@ -1,3 +1,9 @@
+2005-02-02  Matt Austern  <austern@apple.com>
+
+       PR c++/19628
+       * g++/ext/builtin7.C: New.
+       * g++/ext/builtin8.C: New.
+       
 2005-02-02  Joseph S. Myers  <joseph@codesourcery.com>
 
        PR c/18502
diff --git a/gcc/testsuite/g++.dg/ext/builtin7.C b/gcc/testsuite/g++.dg/ext/builtin7.C
new file mode 100644 (file)
index 0000000..dae658a
--- /dev/null
@@ -0,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;
+  }
+}
diff --git a/gcc/testsuite/g++.dg/ext/builtin8.C b/gcc/testsuite/g++.dg/ext/builtin8.C
new file mode 100644 (file)
index 0000000..dd49977
--- /dev/null
@@ -0,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);
+}