aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-03-15 16:16:18 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-03-15 16:16:18 +0000
commit625cbf9318915e406776ab23a21fbb7093889c7a (patch)
tree6ca3ec63bda60cceb911971973b8af475954de44
parent983e64842fe8236e78dc11f6d0f569a224f0767f (diff)
downloadgcc-625cbf9318915e406776ab23a21fbb7093889c7a.zip
gcc-625cbf9318915e406776ab23a21fbb7093889c7a.tar.gz
gcc-625cbf9318915e406776ab23a21fbb7093889c7a.tar.bz2
re PR c++/14550 (trouble with pointers in templates)
PR c++/14550 * parser.c (cp_parser_non_integral_constant_expression): Encode more of the idiom that surrounded calls to this function within the function itself (cp_parser_primary_expression): Adjust accordingly. (cp_parser_postfix_expression): Likewise. (cp_parser_unary_expression): Likewise. (cp_parser_cast_expression): Likewise. (cp_parser_assignment_expression): Likewise. (cp_parser_expression): Likewise. (cp_parser_new_expression): Note that new-expressions are not allowed in integral constant expressions. (cp_parser_delete_expression): Likewise. PR c++/14550 * g++.dg/parse/template14.C: New test. From-SVN: r79498
-rw-r--r--gcc/cp/ChangeLog16
-rw-r--r--gcc/cp/parser.c170
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/parse/template14.C17
4 files changed, 114 insertions, 94 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index fc34864..5dc9e76 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,19 @@
+2004-03-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14550
+ * parser.c (cp_parser_non_integral_constant_expression): Encode
+ more of the idiom that surrounded calls to this function within
+ the function itself
+ (cp_parser_primary_expression): Adjust accordingly.
+ (cp_parser_postfix_expression): Likewise.
+ (cp_parser_unary_expression): Likewise.
+ (cp_parser_cast_expression): Likewise.
+ (cp_parser_assignment_expression): Likewise.
+ (cp_parser_expression): Likewise.
+ (cp_parser_new_expression): Note that new-expressions are not
+ allowed in integral constant expressions.
+ (cp_parser_delete_expression): Likewise.
+
2004-03-12 Matt Austern <austern@apple.com>
* decl2.c (maybe_make_one_only): Look at
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 0691c96..20588b0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -1719,8 +1719,8 @@ static void cp_parser_check_for_definition_in_return_type
(tree, int);
static void cp_parser_check_for_invalid_template_id
(cp_parser *, tree);
-static tree cp_parser_non_integral_constant_expression
- (const char *);
+static bool cp_parser_non_integral_constant_expression
+ (cp_parser *, const char *);
static void cp_parser_diagnose_invalid_type_name
(cp_parser *, tree, tree);
static bool cp_parser_parse_and_diagnose_invalid_type_name
@@ -1922,14 +1922,24 @@ cp_parser_check_for_invalid_template_id (cp_parser* parser,
}
}
-/* Issue an error message about the fact that THING appeared in a
- constant-expression. Returns ERROR_MARK_NODE. */
+/* If parsing an integral constant-expression, issue an error message
+ about the fact that THING appeared and return true. Otherwise,
+ return false, marking the current expression as non-constant. */
-static tree
-cp_parser_non_integral_constant_expression (const char *thing)
+static bool
+cp_parser_non_integral_constant_expression (cp_parser *parser,
+ const char *thing)
{
- error ("%s cannot appear in a constant-expression", thing);
- return error_mark_node;
+ if (parser->integral_constant_expression_p)
+ {
+ if (!parser->allow_non_integral_constant_expression_p)
+ {
+ error ("%s cannot appear in a constant-expression", thing);
+ return true;
+ }
+ parser->non_integral_constant_expression_p = true;
+ }
+ return false;
}
/* Emit a diagnostic for an invalid type name. Consider also if it is
@@ -2542,12 +2552,9 @@ cp_parser_primary_expression (cp_parser *parser,
return error_mark_node;
}
/* Pointers cannot appear in constant-expressions. */
- if (parser->integral_constant_expression_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- return cp_parser_non_integral_constant_expression ("`this'");
- parser->non_integral_constant_expression_p = true;
- }
+ if (cp_parser_non_integral_constant_expression (parser,
+ "`this'"))
+ return error_mark_node;
return finish_this_expr ();
/* The `operator' keyword can be the beginning of an
@@ -2589,12 +2596,9 @@ cp_parser_primary_expression (cp_parser *parser,
cp_parser_require (parser, CPP_CLOSE_PAREN, "`)'");
/* Using `va_arg' in a constant-expression is not
allowed. */
- if (parser->integral_constant_expression_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- return cp_parser_non_integral_constant_expression ("`va_arg'");
- parser->non_integral_constant_expression_p = true;
- }
+ if (cp_parser_non_integral_constant_expression (parser,
+ "`va_arg'"))
+ return error_mark_node;
return build_x_va_arg (expression, type);
}
@@ -3518,14 +3522,12 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
&& !INTEGRAL_OR_ENUMERATION_TYPE_P (type)
/* A cast to pointer or reference type is allowed in the
implementation of "offsetof". */
- && !(parser->in_offsetof_p && POINTER_TYPE_P (type)))
- {
- if (!parser->allow_non_integral_constant_expression_p)
- return (cp_parser_non_integral_constant_expression
- ("a cast to a type other than an integral or "
- "enumeration type"));
- parser->non_integral_constant_expression_p = true;
- }
+ && !(parser->in_offsetof_p && POINTER_TYPE_P (type))
+ && (cp_parser_non_integral_constant_expression
+ (parser,
+ "a cast to a type other than an integral or "
+ "enumeration type")))
+ return error_mark_node;
switch (keyword)
{
@@ -3771,13 +3773,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
idk = CP_ID_KIND_NONE;
/* Array references are not permitted in
constant-expressions. */
- if (parser->integral_constant_expression_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- postfix_expression
- = cp_parser_non_integral_constant_expression ("an array reference");
- parser->non_integral_constant_expression_p = true;
- }
+ if (cp_parser_non_integral_constant_expression
+ (parser, "an array reference"))
+ postfix_expression = error_mark_node;
}
break;
@@ -3796,15 +3794,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* Function calls are not permitted in
constant-expressions. */
- if (parser->integral_constant_expression_p)
+ if (cp_parser_non_integral_constant_expression (parser,
+ "a function call"))
{
- if (!parser->allow_non_integral_constant_expression_p)
- {
- postfix_expression
- = cp_parser_non_integral_constant_expression ("a function call");
- break;
- }
- parser->non_integral_constant_expression_p = true;
+ postfix_expression = error_mark_node;
+ break;
}
koenig_p = false;
@@ -3999,18 +3993,14 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
operator. */
parser->context->object_type = NULL_TREE;
/* These operators may not appear in constant-expressions. */
- if (parser->integral_constant_expression_p
- /* The "->" operator is allowed in the implementation
+ if (/* The "->" operator is allowed in the implementation
of "offsetof". The "." operator may appear in the
name of the member. */
- && !parser->in_offsetof_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- postfix_expression
- = (cp_parser_non_integral_constant_expression
- (token_type == CPP_DEREF ? "'->'" : "`.'"));
- parser->non_integral_constant_expression_p = true;
- }
+ !parser->in_offsetof_p
+ && (cp_parser_non_integral_constant_expression
+ (parser,
+ token_type == CPP_DEREF ? "'->'" : "`.'")))
+ postfix_expression = error_mark_node;
}
break;
@@ -4023,13 +4013,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
= finish_increment_expr (postfix_expression,
POSTINCREMENT_EXPR);
/* Increments may not appear in constant-expressions. */
- if (parser->integral_constant_expression_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- postfix_expression
- = cp_parser_non_integral_constant_expression ("an increment");
- parser->non_integral_constant_expression_p = true;
- }
+ if (cp_parser_non_integral_constant_expression (parser,
+ "an increment"))
+ postfix_expression = error_mark_node;
idk = CP_ID_KIND_NONE;
break;
@@ -4042,13 +4028,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
= finish_increment_expr (postfix_expression,
POSTDECREMENT_EXPR);
/* Decrements may not appear in constant-expressions. */
- if (parser->integral_constant_expression_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- postfix_expression
- = cp_parser_non_integral_constant_expression ("a decrement");
- parser->non_integral_constant_expression_p = true;
- }
+ if (cp_parser_non_integral_constant_expression (parser,
+ "a decrement"))
+ postfix_expression = error_mark_node;
idk = CP_ID_KIND_NONE;
break;
@@ -4447,12 +4429,10 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
abort ();
}
- if (non_constant_p && parser->integral_constant_expression_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- return cp_parser_non_integral_constant_expression (non_constant_p);
- parser->non_integral_constant_expression_p = true;
- }
+ if (non_constant_p
+ && cp_parser_non_integral_constant_expression (parser,
+ non_constant_p))
+ expression = error_mark_node;
return expression;
}
@@ -4553,6 +4533,11 @@ cp_parser_new_expression (cp_parser* parser)
else
initializer = NULL_TREE;
+ /* A new-expression may not appear in an integral constant
+ expression. */
+ if (cp_parser_non_integral_constant_expression (parser, "`new'"))
+ return error_mark_node;
+
/* Create a representation of the new-expression. */
return build_new (placement, type, initializer, global_scope_p);
}
@@ -4781,6 +4766,11 @@ cp_parser_delete_expression (cp_parser* parser)
/* Parse the cast-expression. */
expression = cp_parser_simple_cast_expression (parser);
+ /* A delete-expression may not appear in an integral constant
+ expression. */
+ if (cp_parser_non_integral_constant_expression (parser, "`delete'"))
+ return error_mark_node;
+
return delete_sanity (expression, NULL_TREE, array_p, global_scope_p);
}
@@ -4878,14 +4868,13 @@ cp_parser_cast_expression (cp_parser *parser, bool address_p)
can be used in constant-expressions. */
if (parser->integral_constant_expression_p
&& !dependent_type_p (type)
- && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
- {
- if (!parser->allow_non_integral_constant_expression_p)
- return (cp_parser_non_integral_constant_expression
- ("a casts to a type other than an integral or "
- "enumeration type"));
- parser->non_integral_constant_expression_p = true;
- }
+ && !INTEGRAL_OR_ENUMERATION_TYPE_P (type)
+ && (cp_parser_non_integral_constant_expression
+ (parser,
+ "a cast to a type other than an integral or "
+ "enumeration type")))
+ return error_mark_node;
+
/* Perform the cast. */
expr = build_c_cast (type, expr);
return expr;
@@ -5238,12 +5227,9 @@ cp_parser_assignment_expression (cp_parser* parser)
rhs = cp_parser_assignment_expression (parser);
/* An assignment may not appear in a
constant-expression. */
- if (parser->integral_constant_expression_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- return cp_parser_non_integral_constant_expression ("an assignment");
- parser->non_integral_constant_expression_p = true;
- }
+ if (cp_parser_non_integral_constant_expression (parser,
+ "an assignment"))
+ return error_mark_node;
/* Build the assignment expression. */
expr = build_x_modify_expr (expr,
assignment_operator,
@@ -5381,13 +5367,9 @@ cp_parser_expression (cp_parser* parser)
/* Consume the `,'. */
cp_lexer_consume_token (parser->lexer);
/* A comma operator cannot appear in a constant-expression. */
- if (parser->integral_constant_expression_p)
- {
- if (!parser->allow_non_integral_constant_expression_p)
- expression
- = cp_parser_non_integral_constant_expression ("a comma operator");
- parser->non_integral_constant_expression_p = true;
- }
+ if (cp_parser_non_integral_constant_expression (parser,
+ "a comma operator"))
+ expression = error_mark_node;
}
return expression;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7a113af..7d1450f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-03-13 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/14550
+ * g++.dg/parse/template14.C: New test.
+
2004-03-13 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/execute/20040313-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/parse/template14.C b/gcc/testsuite/g++.dg/parse/template14.C
new file mode 100644
index 0000000..ada8752
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/template14.C
@@ -0,0 +1,17 @@
+// PR c++/14550
+
+struct A {
+ A();
+};
+
+template <int> void foo()
+{
+ A *p = new A;
+}
+
+void bar()
+{
+ foo<0>();
+}
+
+