aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/parser.c85
-rw-r--r--gcc/cp/pt.c3
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/template/crash14.C3
-rw-r--r--gcc/testsuite/g++.dg/template/dependent-expr3.C4
6 files changed, 82 insertions, 30 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 93a3719..5e4e824 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13243
+ PR c++/12573
+ * parser.c (cp_parser_postfix_expression): Tighten handling of
+ integral constant expressions.
+ (cp_parser_unary_expression): Likewise.
+ * pt.c (value_dependent_expression_p): Remove handling for
+ COMPONENT_REFs.
+
2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
* class.c (add_method): Disallow destructor for java classes.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4709ccb..a74e33a 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3637,6 +3637,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
postfix_expression
= grok_array_decl (postfix_expression, index);
idk = CP_ID_KIND_NONE;
+ /* Array references are not permitted in
+ constant-expressions. */
+ if (parser->constant_expression_p)
+ {
+ if (!parser->allow_non_constant_expression_p)
+ postfix_expression
+ = cp_parser_non_constant_expression ("an array reference");
+ parser->non_constant_expression_p = true;
+ }
}
break;
@@ -3658,7 +3667,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
if (parser->constant_expression_p)
{
if (!parser->allow_non_constant_expression_p)
- return cp_parser_non_constant_expression ("a function call");
+ {
+ postfix_expression
+ = cp_parser_non_constant_expression ("a function call");
+ break;
+ }
parser->non_constant_expression_p = true;
}
@@ -3737,6 +3750,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
bool dependent_p;
bool template_p;
tree scope = NULL_TREE;
+ enum cpp_ttype token_type = token->type;
/* If this is a `->' operator, dereference the pointer. */
if (token->type == CPP_DEREF)
@@ -3839,6 +3853,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
object on the left-hand side of the `.' or `->'
operator. */
parser->context->object_type = NULL_TREE;
+ /* These operators may not appear in constant-expressions. */
+ if (parser->constant_expression_p)
+ {
+ if (!parser->allow_non_constant_expression_p)
+ postfix_expression
+ = (cp_parser_non_constant_expression
+ (token_type == CPP_DEREF ? "'->'" : "`.'"));
+ parser->non_constant_expression_p = true;
+ }
}
break;
@@ -3846,17 +3869,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* postfix-expression ++ */
/* Consume the `++' token. */
cp_lexer_consume_token (parser->lexer);
+ /* Generate a representation for the complete expression. */
+ postfix_expression
+ = finish_increment_expr (postfix_expression,
+ POSTINCREMENT_EXPR);
/* Increments may not appear in constant-expressions. */
if (parser->constant_expression_p)
{
if (!parser->allow_non_constant_expression_p)
- return cp_parser_non_constant_expression ("an increment");
+ postfix_expression
+ = cp_parser_non_constant_expression ("an increment");
parser->non_constant_expression_p = true;
}
- /* Generate a representation for the complete expression. */
- postfix_expression
- = finish_increment_expr (postfix_expression,
- POSTINCREMENT_EXPR);
idk = CP_ID_KIND_NONE;
break;
@@ -3864,17 +3888,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* postfix-expression -- */
/* Consume the `--' token. */
cp_lexer_consume_token (parser->lexer);
+ /* Generate a representation for the complete expression. */
+ postfix_expression
+ = finish_increment_expr (postfix_expression,
+ POSTDECREMENT_EXPR);
/* Decrements may not appear in constant-expressions. */
if (parser->constant_expression_p)
{
if (!parser->allow_non_constant_expression_p)
- return cp_parser_non_constant_expression ("a decrement");
+ postfix_expression
+ = cp_parser_non_constant_expression ("a decrement");
parser->non_constant_expression_p = true;
}
- /* Generate a representation for the complete expression. */
- postfix_expression
- = finish_increment_expr (postfix_expression,
- POSTDECREMENT_EXPR);
idk = CP_ID_KIND_NONE;
break;
@@ -4217,6 +4242,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
if (unary_operator != ERROR_MARK)
{
tree cast_expression;
+ tree expression = error_mark_node;
+ const char *non_constant_p = NULL;
/* Consume the operator token. */
token = cp_lexer_consume_token (parser->lexer);
@@ -4227,32 +4254,40 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
switch (unary_operator)
{
case INDIRECT_REF:
- return build_x_indirect_ref (cast_expression, "unary *");
-
+ non_constant_p = "`*'";
+ expression = build_x_indirect_ref (cast_expression, "unary *");
+ break;
+
case ADDR_EXPR:
+ non_constant_p = "`&'";
+ /* Fall through. */
case BIT_NOT_EXPR:
- return build_x_unary_op (unary_operator, cast_expression);
-
+ expression = build_x_unary_op (unary_operator, cast_expression);
+ break;
+
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
- if (parser->constant_expression_p)
- {
- if (!parser->allow_non_constant_expression_p)
- return cp_parser_non_constant_expression (PREINCREMENT_EXPR
- ? "an increment"
- : "a decrement");
- parser->non_constant_expression_p = true;
- }
+ non_constant_p = (unary_operator == PREINCREMENT_EXPR
+ ? "`++'" : "`--'");
/* Fall through. */
case CONVERT_EXPR:
case NEGATE_EXPR:
case TRUTH_NOT_EXPR:
- return finish_unary_op_expr (unary_operator, cast_expression);
+ expression = finish_unary_op_expr (unary_operator, cast_expression);
+ break;
default:
abort ();
- return error_mark_node;
}
+
+ if (non_constant_p && parser->constant_expression_p)
+ {
+ if (!parser->allow_non_constant_expression_p)
+ return cp_parser_non_constant_expression (non_constant_p);
+ parser->non_constant_expression_p = true;
+ }
+
+ return expression;
}
return cp_parser_postfix_expression (parser, address_p);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2d31c4d..553d4f7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11714,9 +11714,6 @@ value_dependent_expression_p (tree expression)
}
if (TREE_CODE (expression) == SCOPE_REF)
return dependent_scope_ref_p (expression, value_dependent_expression_p);
- if (TREE_CODE (expression) == COMPONENT_REF)
- return (value_dependent_expression_p (TREE_OPERAND (expression, 0))
- || value_dependent_expression_p (TREE_OPERAND (expression, 1)));
/* A constant expression is value-dependent if any subexpression is
value-dependent. */
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 675122e..dd5e215 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2003-12-15 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/13243
+ PR c++/12573
+ * g++.dg/template/crash14.C: New test.
+ * g++.dg/template/dependent-expr3.C: Add dg-error markers.
+
2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/other/java1.C: New test.
diff --git a/gcc/testsuite/g++.dg/template/crash14.C b/gcc/testsuite/g++.dg/template/crash14.C
new file mode 100644
index 0000000..7b3af04
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash14.C
@@ -0,0 +1,3 @@
+template <int T> class foo { public: foo() { } class Z { };};
+template <int I[2]> void dep7(foo<I[0]> *) { } // { dg-error "" }
+
diff --git a/gcc/testsuite/g++.dg/template/dependent-expr3.C b/gcc/testsuite/g++.dg/template/dependent-expr3.C
index 50673c8..2e8b805 100644
--- a/gcc/testsuite/g++.dg/template/dependent-expr3.C
+++ b/gcc/testsuite/g++.dg/template/dependent-expr3.C
@@ -9,6 +9,6 @@ template <typename K> struct Y : K {
};
template <class T> struct Z {
- S< (bool)(&static_cast<Y<T> *>(0)->x == 0) >
- s;
+ S< (bool)(&static_cast<Y<T> *>(0)->x == 0) > // { dg-error "" }
+ s; // { dg-error "" }
};