aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMatt Austern <austern@apple.com>2005-02-03 00:02:10 +0000
committerMatt Austern <austern@gcc.gnu.org>2005-02-03 00:02:10 +0000
commit100d337a9d06bbc8f367e37debbe69610b04e72f (patch)
tree54f1d79812354b990fbbfe75895aedd5f2372e9c /gcc
parent89d12f5d49829d3dbf9a78040b88df833923c0df (diff)
downloadgcc-100d337a9d06bbc8f367e37debbe69610b04e72f.zip
gcc-100d337a9d06bbc8f367e37debbe69610b04e72f.tar.gz
gcc-100d337a9d06bbc8f367e37debbe69610b04e72f.tar.bz2
re PR c++/19628 (g++ no longer accepts __builtin_constant_p in constant-expressions)
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. * g++/ext/builtin7.C: New. * g++/ext/builtin8.C: New. From-SVN: r94635
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog13
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/parser.c5
-rw-r--r--gcc/cp/pt.c30
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/cp/tree.c13
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/ext/builtin7.C14
-rw-r--r--gcc/testsuite/g++.dg/ext/builtin8.C16
9 files changed, 98 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 0aca2e0..230e710 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index fa4c630..58e0fa8 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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, ...);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 7450f18..e89fd85 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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;
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 0e6ce13..d0cd229 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -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))
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index c0e68d1..ebc213d 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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)
{
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 0a0b3ec..8a264d7 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 06a18e4..68c973a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..dae658a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin7.C
@@ -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
index 0000000..dd49977
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin8.C
@@ -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);
+}