diff options
author | Matt Austern <austern@apple.com> | 2005-02-03 00:02:10 +0000 |
---|---|---|
committer | Matt Austern <austern@gcc.gnu.org> | 2005-02-03 00:02:10 +0000 |
commit | 100d337a9d06bbc8f367e37debbe69610b04e72f (patch) | |
tree | 54f1d79812354b990fbbfe75895aedd5f2372e9c /gcc | |
parent | 89d12f5d49829d3dbf9a78040b88df833923c0df (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/parser.c | 5 | ||||
-rw-r--r-- | gcc/cp/pt.c | 30 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 3 | ||||
-rw-r--r-- | gcc/cp/tree.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/builtin7.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/builtin8.C | 16 |
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); +} |