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
This commit is contained in:
parent
89d12f5d49
commit
100d337a9d
|
@ -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>
|
2005-02-02 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||||
|
|
||||||
PR c++/17413
|
PR c++/17413
|
||||||
|
|
|
@ -4205,6 +4205,7 @@ extern tree copy_binfo (tree, tree, tree,
|
||||||
tree *, int);
|
tree *, int);
|
||||||
extern int member_p (tree);
|
extern int member_p (tree);
|
||||||
extern cp_lvalue_kind real_lvalue_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 (enum tree_code, tree, ...);
|
||||||
extern tree build_min_nt (enum tree_code, ...);
|
extern tree build_min_nt (enum tree_code, ...);
|
||||||
extern tree build_min_non_dep (enum tree_code, tree, ...);
|
extern tree build_min_non_dep (enum tree_code, tree, ...);
|
||||||
|
|
|
@ -4037,8 +4037,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p)
|
||||||
|
|
||||||
/* Function calls are not permitted in
|
/* Function calls are not permitted in
|
||||||
constant-expressions. */
|
constant-expressions. */
|
||||||
if (cp_parser_non_integral_constant_expression (parser,
|
if (! builtin_valid_in_constant_expr_p (postfix_expression)
|
||||||
"a function call"))
|
&& cp_parser_non_integral_constant_expression (parser,
|
||||||
|
"a function call"))
|
||||||
{
|
{
|
||||||
postfix_expression = error_mark_node;
|
postfix_expression = error_mark_node;
|
||||||
break;
|
break;
|
||||||
|
|
30
gcc/cp/pt.c
30
gcc/cp/pt.c
|
@ -12020,6 +12020,36 @@ value_dependent_expression_p (tree expression)
|
||||||
if (TREE_CODE (expression) == COMPONENT_REF)
|
if (TREE_CODE (expression) == COMPONENT_REF)
|
||||||
return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
|
return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
|
||||||
|| value_dependent_expression_p (TREE_OPERAND (expression, 1)));
|
|| 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
|
/* A constant expression is value-dependent if any subexpression is
|
||||||
value-dependent. */
|
value-dependent. */
|
||||||
if (EXPR_P (expression))
|
if (EXPR_P (expression))
|
||||||
|
|
|
@ -2663,7 +2663,8 @@ finish_id_expression (tree id_expression,
|
||||||
expression. Enumerators and template parameters have already
|
expression. Enumerators and template parameters have already
|
||||||
been handled above. */
|
been handled above. */
|
||||||
if (integral_constant_expression_p
|
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)
|
if (!allow_non_integral_constant_expression_p)
|
||||||
{
|
{
|
||||||
|
|
|
@ -215,6 +215,19 @@ lvalue_p (tree ref)
|
||||||
(lvalue_p_1 (ref, /*class rvalue ok*/ 1) != clk_none);
|
(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. */
|
/* Build a TARGET_EXPR, initializing the DECL with the VALUE. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
|
|
|
@ -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>
|
2005-02-02 Joseph S. Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
PR c/18502
|
PR c/18502
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue