* 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
+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
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, ...);
/* 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;
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))
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)
{
(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
+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
--- /dev/null
+// 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;
+ }
+}
--- /dev/null
+// 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);
+}