Commit a5ac3982 by Mark Mitchell Committed by Mark Mitchell

re PR c++/13243 (Segfault on illegal template construct)

	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.

	PR c++/13243
	PR c++/12573
	* g++.dg/template/crash14.C: New test.
	* g++.dg/template/dependent-expr3.C: Add dg-error markers.

From-SVN: r74637
parent ca13fb7f
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> 2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
* class.c (add_method): Disallow destructor for java classes. * class.c (add_method): Disallow destructor for java classes.
......
...@@ -3637,6 +3637,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3637,6 +3637,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
postfix_expression postfix_expression
= grok_array_decl (postfix_expression, index); = grok_array_decl (postfix_expression, index);
idk = CP_ID_KIND_NONE; 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; break;
...@@ -3658,7 +3667,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3658,7 +3667,11 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
if (parser->constant_expression_p) if (parser->constant_expression_p)
{ {
if (!parser->allow_non_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; parser->non_constant_expression_p = true;
} }
...@@ -3737,6 +3750,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3737,6 +3750,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
bool dependent_p; bool dependent_p;
bool template_p; bool template_p;
tree scope = NULL_TREE; tree scope = NULL_TREE;
enum cpp_ttype token_type = token->type;
/* If this is a `->' operator, dereference the pointer. */ /* If this is a `->' operator, dereference the pointer. */
if (token->type == CPP_DEREF) if (token->type == CPP_DEREF)
...@@ -3839,6 +3853,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3839,6 +3853,15 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
object on the left-hand side of the `.' or `->' object on the left-hand side of the `.' or `->'
operator. */ operator. */
parser->context->object_type = NULL_TREE; 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; break;
...@@ -3846,17 +3869,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3846,17 +3869,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* postfix-expression ++ */ /* postfix-expression ++ */
/* Consume the `++' token. */ /* Consume the `++' token. */
cp_lexer_consume_token (parser->lexer); 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. */ /* Increments may not appear in constant-expressions. */
if (parser->constant_expression_p) if (parser->constant_expression_p)
{ {
if (!parser->allow_non_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; 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; idk = CP_ID_KIND_NONE;
break; break;
...@@ -3864,17 +3888,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p) ...@@ -3864,17 +3888,18 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
/* postfix-expression -- */ /* postfix-expression -- */
/* Consume the `--' token. */ /* Consume the `--' token. */
cp_lexer_consume_token (parser->lexer); 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. */ /* Decrements may not appear in constant-expressions. */
if (parser->constant_expression_p) if (parser->constant_expression_p)
{ {
if (!parser->allow_non_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; 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; idk = CP_ID_KIND_NONE;
break; break;
...@@ -4217,6 +4242,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p) ...@@ -4217,6 +4242,8 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
if (unary_operator != ERROR_MARK) if (unary_operator != ERROR_MARK)
{ {
tree cast_expression; tree cast_expression;
tree expression = error_mark_node;
const char *non_constant_p = NULL;
/* Consume the operator token. */ /* Consume the operator token. */
token = cp_lexer_consume_token (parser->lexer); token = cp_lexer_consume_token (parser->lexer);
...@@ -4227,32 +4254,40 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p) ...@@ -4227,32 +4254,40 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p)
switch (unary_operator) switch (unary_operator)
{ {
case INDIRECT_REF: 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: case ADDR_EXPR:
non_constant_p = "`&'";
/* Fall through. */
case BIT_NOT_EXPR: 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 PREINCREMENT_EXPR:
case PREDECREMENT_EXPR: case PREDECREMENT_EXPR:
if (parser->constant_expression_p) non_constant_p = (unary_operator == PREINCREMENT_EXPR
{ ? "`++'" : "`--'");
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;
}
/* Fall through. */ /* Fall through. */
case CONVERT_EXPR: case CONVERT_EXPR:
case NEGATE_EXPR: case NEGATE_EXPR:
case TRUTH_NOT_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: default:
abort (); 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); return cp_parser_postfix_expression (parser, address_p);
......
...@@ -11714,9 +11714,6 @@ value_dependent_expression_p (tree expression) ...@@ -11714,9 +11714,6 @@ value_dependent_expression_p (tree expression)
} }
if (TREE_CODE (expression) == SCOPE_REF) if (TREE_CODE (expression) == SCOPE_REF)
return dependent_scope_ref_p (expression, value_dependent_expression_p); 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 /* A constant expression is value-dependent if any subexpression is
value-dependent. */ value-dependent. */
if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression)))) if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expression))))
......
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> 2003-12-15 Nathan Sidwell <nathan@codesourcery.com>
* g++.dg/other/java1.C: New test. * g++.dg/other/java1.C: New test.
......
template <int T> class foo { public: foo() { } class Z { };};
template <int I[2]> void dep7(foo<I[0]> *) { } // { dg-error "" }
...@@ -9,6 +9,6 @@ template <typename K> struct Y : K { ...@@ -9,6 +9,6 @@ template <typename K> struct Y : K {
}; };
template <class T> struct Z { template <class T> struct Z {
S< (bool)(&static_cast<Y<T> *>(0)->x == 0) > S< (bool)(&static_cast<Y<T> *>(0)->x == 0) > // { dg-error "" }
s; s; // { dg-error "" }
}; };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment