From: Matt Austern Date: Thu, 3 Feb 2005 00:02:10 +0000 (+0000) Subject: re PR c++/19628 (g++ no longer accepts __builtin_constant_p in constant-expressions) X-Git-Tag: releases/gcc-4.0.0~1080 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=100d337a9d06bbc8f367e37debbe69610b04e72f;p=thirdparty%2Fgcc.git 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 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 0aca2e0136e9..230e710f5916 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +2005-02-02 Matt Austern + + 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 PR c++/17413 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index fa4c630d4959..58e0fa8066c3 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 7450f1838d46..e89fd85c0346 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 0e6ce130f8d3..d0cd2297db38 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 c0e68d1d0e8d..ebc213d7812c 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 0a0b3ec33a06..8a264d7afa94 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 06a18e4e1f65..68c973ace7d6 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2005-02-02 Matt Austern + + PR c++/19628 + * g++/ext/builtin7.C: New. + * g++/ext/builtin8.C: New. + 2005-02-02 Joseph S. Myers 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 000000000000..dae658abc4a5 --- /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 000000000000..dd49977255da --- /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 f(int x[__builtin_constant_p(I)]) +{ + return x[0]; +} + +int g() +{ + int a[1] = { 7 }; + return f<32>(a); +}