re PR c++/11547 (ICE with const temporaries)

PR c++/11547
	* cp-tree.h (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P): New
	macro.
	(DECL_PRETTY_FUNCTION_P): Use VAR_DECL_CHECK.
	* decl.c (duplicate_decls): Merge
	DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
	* parser.c (cp_parser_postfix_expression): Adjust call to
	cp_parser_initializer_list and
	cp_parser_parenthesized_expression_list.
	(cp_parser_parenthesized_expression_list): Add non_constant_p.
	(cp_parser_new_placement): Adjust call to
	cp_parser_parenthesized_expression_list.
	(cp_parser_direct_new_declarator): Likewise.
	(cp_parser_conditional_expression): Remove.
	(cp_parser_constant_expression): Parse an assignment-expression,
	not a conditional-expression.
	(cp_parser_simple_declaration): Resolve expression/declaration
	ambiguity more quickly.
	(cp_parser_mem_initializer): Adjust call to
	cp_parser_parenthesized_expression_list.
	(cp_parser_init_declarator): Keep track of whether or not the
	initializer is a constant-expression.
	(cp_parser_initializer): Add non_constant_p parameter.
	(cp_parser_initializer_clause): Likewise.
	(cp_parser_initializer_list): Likewise.
	(cp_parser_attribute_list): Adjust call to
	cp_parser_parenthesized_expression_list.
	(cp_parser_functional_cast): Likewise.
	* pt.c (tsubst_decl): Copy
	DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
	(tsubst_expr): Tweak use of DECL_PRETTY_FUNCTION_P.
	* semantics.c (finish_id_expression): Use
	DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.

	PR c++/11547
	* g++.dg/parse/constant3.C: New test.
	* g++.dg/parse/crash7.C: Likewise.

From-SVN: r69493
This commit is contained in:
Mark Mitchell 2003-07-17 04:31:42 +00:00 committed by Mark Mitchell
parent db5eed1873
commit 39703eb9e2
9 changed files with 200 additions and 93 deletions

View File

@ -1,3 +1,39 @@
2003-07-16 Mark Mitchell <mark@codesourcery.com>
PR c++/11547
* cp-tree.h (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P): New
macro.
(DECL_PRETTY_FUNCTION_P): Use VAR_DECL_CHECK.
* decl.c (duplicate_decls): Merge
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
* parser.c (cp_parser_postfix_expression): Adjust call to
cp_parser_initializer_list and
cp_parser_parenthesized_expression_list.
(cp_parser_parenthesized_expression_list): Add non_constant_p.
(cp_parser_new_placement): Adjust call to
cp_parser_parenthesized_expression_list.
(cp_parser_direct_new_declarator): Likewise.
(cp_parser_conditional_expression): Remove.
(cp_parser_constant_expression): Parse an assignment-expression,
not a conditional-expression.
(cp_parser_simple_declaration): Resolve expression/declaration
ambiguity more quickly.
(cp_parser_mem_initializer): Adjust call to
cp_parser_parenthesized_expression_list.
(cp_parser_init_declarator): Keep track of whether or not the
initializer is a constant-expression.
(cp_parser_initializer): Add non_constant_p parameter.
(cp_parser_initializer_clause): Likewise.
(cp_parser_initializer_list): Likewise.
(cp_parser_attribute_list): Adjust call to
cp_parser_parenthesized_expression_list.
(cp_parser_functional_cast): Likewise.
* pt.c (tsubst_decl): Copy
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
(tsubst_expr): Tweak use of DECL_PRETTY_FUNCTION_P.
* semantics.c (finish_id_expression): Use
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P.
2003-07-16 Neil Booth <neil@daikokuya.co.uk>
* lang-options.h: Remove.

View File

@ -45,6 +45,7 @@ struct diagnostic_context;
AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF)
PARMLIST_ELLIPSIS_P (in PARMLIST)
DECL_PRETTY_FUNCTION_P (in VAR_DECL)
1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@ -59,6 +60,7 @@ struct diagnostic_context;
ICS_THIS_FLAG (in _CONV)
BINFO_LOST_PRIMARY_P (in BINFO)
TREE_PARMLIST (in TREE_LIST)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (in VAR_DECL)
3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE).
BINFO_VTABLE_PATH_MARKED.
BINFO_PUSHDECLS_MARKED.
@ -1926,6 +1928,11 @@ struct lang_decl GTY(())
#define DECL_INITIALIZED_P(NODE) \
(TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE)))
/* Nonzero for a VAR_DECL that was initialized with a
constant-expression. */
#define DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(NODE) \
(TREE_LANG_FLAG_2 (VAR_DECL_CHECK (NODE)))
/* Nonzero if the DECL was initialized in the class definition itself,
rather than outside the class. This is used for both static member
VAR_DECLS, and FUNTION_DECLS that are defined in the class. */
@ -2033,7 +2040,7 @@ struct lang_decl GTY(())
/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
template function. */
#define DECL_PRETTY_FUNCTION_P(NODE) \
(TREE_LANG_FLAG_0 (NODE))
(TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE)))
/* The _TYPE context in which this _DECL appears. This field holds the
class where a virtual function instance is actually defined. */

View File

@ -3306,6 +3306,8 @@ duplicate_decls (tree newdecl, tree olddecl)
{
DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl);
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl)
|= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl);
}
/* Do this after calling `merge_types' so that default

View File

@ -1311,7 +1311,7 @@ static tree cp_parser_class_or_namespace_name
static tree cp_parser_postfix_expression
(cp_parser *, bool);
static tree cp_parser_parenthesized_expression_list
(cp_parser *, bool);
(cp_parser *, bool, bool *);
static void cp_parser_pseudo_destructor_name
(cp_parser *, tree *, tree *);
static tree cp_parser_unary_expression
@ -1356,8 +1356,6 @@ static tree cp_parser_logical_and_expression
(cp_parser *);
static tree cp_parser_logical_or_expression
(cp_parser *);
static tree cp_parser_conditional_expression
(cp_parser *);
static tree cp_parser_question_colon_clause
(cp_parser *, tree);
static tree cp_parser_assignment_expression
@ -1479,11 +1477,11 @@ static tree cp_parser_function_definition
static void cp_parser_function_body
(cp_parser *);
static tree cp_parser_initializer
(cp_parser *, bool *);
(cp_parser *, bool *, bool *);
static tree cp_parser_initializer_clause
(cp_parser *);
(cp_parser *, bool *);
static tree cp_parser_initializer_list
(cp_parser *);
(cp_parser *, bool *);
static bool cp_parser_ctor_initializer_opt_and_function_body
(cp_parser *);
@ -3375,9 +3373,10 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
keep going. */
if (!cp_parser_error_occurred (parser))
{
bool non_constant_p;
/* Parse the initializer-list. */
initializer_list
= cp_parser_initializer_list (parser);
= cp_parser_initializer_list (parser, &non_constant_p);
/* Allow a trailing `,'. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer);
@ -3472,7 +3471,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
case CPP_OPEN_PAREN:
/* postfix-expression ( expression-list [opt] ) */
{
tree args = cp_parser_parenthesized_expression_list (parser, false);
tree args = (cp_parser_parenthesized_expression_list
(parser, false, /*non_constant_p=*/NULL));
if (args == error_mark_node)
{
@ -3735,14 +3735,22 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p)
error_mark_node is returned if the ( and or ) are
missing. NULL_TREE is returned on no expressions. The parentheses
are eaten. IS_ATTRIBUTE_LIST is true if this is really an attribute
list being parsed. */
list being parsed. If NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P
indicates whether or not all of the expressions in the list were
constant. */
static tree
cp_parser_parenthesized_expression_list (cp_parser* parser, bool is_attribute_list)
cp_parser_parenthesized_expression_list (cp_parser* parser,
bool is_attribute_list,
bool *non_constant_p)
{
tree expression_list = NULL_TREE;
tree identifier = NULL_TREE;
/* Assume all the expressions will be constant. */
if (non_constant_p)
*non_constant_p = false;
if (!cp_parser_require (parser, CPP_OPEN_PAREN, "`('"))
return error_mark_node;
@ -3767,7 +3775,17 @@ cp_parser_parenthesized_expression_list (cp_parser* parser, bool is_attribute_li
else
{
/* Parse the next assignment-expression. */
expr = cp_parser_assignment_expression (parser);
if (non_constant_p)
{
bool expr_non_constant_p;
expr = (cp_parser_constant_expression
(parser, /*allow_non_constant_p=*/true,
&expr_non_constant_p));
if (expr_non_constant_p)
*non_constant_p = true;
}
else
expr = cp_parser_assignment_expression (parser);
/* Add it to the list. We add error_mark_node
expressions to the list, so that we can still tell if
@ -4177,7 +4195,8 @@ cp_parser_new_placement (cp_parser* parser)
tree expression_list;
/* Parse the expression-list. */
expression_list = cp_parser_parenthesized_expression_list (parser, false);
expression_list = (cp_parser_parenthesized_expression_list
(parser, false, /*non_constant_p=*/NULL));
return expression_list;
}
@ -4341,7 +4360,8 @@ cp_parser_new_initializer (cp_parser* parser)
{
tree expression_list;
expression_list = cp_parser_parenthesized_expression_list (parser, false);
expression_list = (cp_parser_parenthesized_expression_list
(parser, false, /*non_constant_p=*/NULL));
if (!expression_list)
expression_list = void_zero_node;
@ -4755,43 +4775,12 @@ cp_parser_logical_or_expression (cp_parser* parser)
cp_parser_logical_and_expression);
}
/* Parse a conditional-expression.
conditional-expression:
logical-or-expression
logical-or-expression ? expression : assignment-expression
GNU Extensions:
conditional-expression:
logical-or-expression ? : assignment-expression
Returns a representation of the expression. */
static tree
cp_parser_conditional_expression (cp_parser* parser)
{
tree logical_or_expr;
/* Parse the logical-or-expression. */
logical_or_expr = cp_parser_logical_or_expression (parser);
/* If the next token is a `?', then we have a real conditional
expression. */
if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
return cp_parser_question_colon_clause (parser, logical_or_expr);
/* Otherwise, the value is simply the logical-or-expression. */
else
return logical_or_expr;
}
/* Parse the `? expression : assignment-expression' part of a
conditional-expression. The LOGICAL_OR_EXPR is the
logical-or-expression that started the conditional-expression.
Returns a representation of the entire conditional-expression.
This routine exists only so that it can be shared between
cp_parser_conditional_expression and
cp_parser_assignment_expression.
This routine is used by cp_parser_assignment_expression.
? expression : assignment-expression
@ -5071,8 +5060,16 @@ cp_parser_constant_expression (cp_parser* parser,
parser->constant_expression_p = true;
parser->allow_non_constant_expression_p = allow_non_constant_p;
parser->non_constant_expression_p = false;
/* Parse the conditional-expression. */
expression = cp_parser_conditional_expression (parser);
/* Although the grammar says "conditional-expression", we parse an
"assignment-expression", which also permits "throw-expression"
and the use of assignment operators. In the case that
ALLOW_NON_CONSTANT_P is false, we get better errors than we would
otherwise. In the case that ALLOW_NON_CONSTANT_P is true, it is
actually essential that we look for an assignment-expression.
For example, cp_parser_initializer_clauses uses this function to
determine whether a particular assignment-expression is in fact
constant. */
expression = cp_parser_assignment_expression (parser);
/* Restore the old settings. */
parser->constant_expression_p = saved_constant_expression_p;
parser->allow_non_constant_expression_p
@ -6081,6 +6078,15 @@ cp_parser_simple_declaration (cp_parser* parser,
/* We no longer need to defer access checks. */
stop_deferring_access_checks ();
/* In a block scope, a valid declaration must always have a
decl-specifier-seq. By not trying to parse declarators, we can
resolve the declaration/expression ambiguity more quickly. */
if (!function_definition_allowed_p && !decl_specifiers)
{
cp_parser_error (parser, "expected declaration");
goto done;
}
/* If the next two tokens are both identifiers, the code is
erroneous. The usual cause of this situation is code like:
@ -6093,7 +6099,7 @@ cp_parser_simple_declaration (cp_parser* parser,
looking at a declaration. */
cp_parser_commit_to_tentative_parse (parser);
/* Give up. */
return;
goto done;
}
/* Keep going until we hit the `;' at the end of the simple
@ -6116,10 +6122,7 @@ cp_parser_simple_declaration (cp_parser* parser,
statement is treated as a declaration-statement until proven
otherwise.) */
if (cp_parser_error_occurred (parser))
{
pop_deferring_access_checks ();
return;
}
goto done;
/* Handle function definitions specially. */
if (function_definition_p)
{
@ -6152,8 +6155,7 @@ cp_parser_simple_declaration (cp_parser* parser,
cp_parser_error (parser, "expected `,' or `;'");
/* Skip tokens until we reach the end of the statement. */
cp_parser_skip_to_end_of_statement (parser);
pop_deferring_access_checks ();
return;
goto done;
}
/* After the first time around, a function-definition is not
allowed -- even if it was OK at first. For example:
@ -6175,14 +6177,15 @@ cp_parser_simple_declaration (cp_parser* parser,
perform_deferred_access_checks ();
}
pop_deferring_access_checks ();
/* Consume the `;'. */
cp_parser_require (parser, CPP_SEMICOLON, "`;'");
/* Mark all the classes that appeared in the decl-specifier-seq as
having received a `;'. */
note_list_got_semicolon (decl_specifiers);
done:
pop_deferring_access_checks ();
}
/* Parse a decl-specifier-seq.
@ -6774,7 +6777,9 @@ cp_parser_mem_initializer (cp_parser* parser)
if (member && !DECL_P (member))
in_base_initializer = 1;
expression_list = cp_parser_parenthesized_expression_list (parser, false);
expression_list
= cp_parser_parenthesized_expression_list (parser, false,
/*non_constant_p=*/NULL);
if (!expression_list)
expression_list = void_type_node;
@ -9156,6 +9161,7 @@ cp_parser_init_declarator (cp_parser* parser,
tree scope;
bool is_initialized;
bool is_parenthesized_init;
bool is_non_constant_init;
int ctor_dtor_or_conv_p;
bool friend_p;
@ -9325,11 +9331,14 @@ cp_parser_init_declarator (cp_parser* parser,
/* Parse the initializer. */
if (is_initialized)
initializer = cp_parser_initializer (parser, &is_parenthesized_init);
initializer = cp_parser_initializer (parser,
&is_parenthesized_init,
&is_non_constant_init);
else
{
initializer = NULL_TREE;
is_parenthesized_init = false;
is_non_constant_init = true;
}
/* The old parser allows attributes to appear after a parenthesized
@ -9371,6 +9380,12 @@ cp_parser_init_declarator (cp_parser* parser,
((is_parenthesized_init || !is_initialized)
? 0 : LOOKUP_ONLYCONVERTING));
/* Remember whether or not variables were initialized by
constant-expressions. */
if (decl && TREE_CODE (decl) == VAR_DECL
&& is_initialized && !is_non_constant_init)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
return decl;
}
@ -10729,10 +10744,13 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser)
*IS_PARENTHESIZED_INIT is set to TRUE if the `( expression-list )'
production is used, and zero otherwise. *IS_PARENTHESIZED_INIT is
set to FALSE if there is no initializer present. */
set to FALSE if there is no initializer present. If there is an
initializer, and it is not a constant-expression, *NON_CONSTANT_P
is set to true; otherwise it is set to false. */
static tree
cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init)
cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init,
bool* non_constant_p)
{
cp_token *token;
tree init;
@ -10743,16 +10761,19 @@ cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init)
/* Let our caller know whether or not this initializer was
parenthesized. */
*is_parenthesized_init = (token->type == CPP_OPEN_PAREN);
/* Assume that the initializer is constant. */
*non_constant_p = false;
if (token->type == CPP_EQ)
{
/* Consume the `='. */
cp_lexer_consume_token (parser->lexer);
/* Parse the initializer-clause. */
init = cp_parser_initializer_clause (parser);
init = cp_parser_initializer_clause (parser, non_constant_p);
}
else if (token->type == CPP_OPEN_PAREN)
init = cp_parser_parenthesized_expression_list (parser, false);
init = cp_parser_parenthesized_expression_list (parser, false,
non_constant_p);
else
{
/* Anything else is an error. */
@ -10779,17 +10800,21 @@ cp_parser_initializer (cp_parser* parser, bool* is_parenthesized_init)
the elements of the initializer-list (or NULL_TREE, if the last
production is used). The TREE_TYPE for the CONSTRUCTOR will be
NULL_TREE. There is no way to detect whether or not the optional
trailing `,' was provided. */
trailing `,' was provided. NON_CONSTANT_P is as for
cp_parser_initializer. */
static tree
cp_parser_initializer_clause (cp_parser* parser)
cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
{
tree initializer;
/* If it is not a `{', then we are looking at an
assignment-expression. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
initializer = cp_parser_assignment_expression (parser);
initializer
= cp_parser_constant_expression (parser,
/*allow_non_constant_p=*/true,
non_constant_p);
else
{
/* Consume the `{' token. */
@ -10805,12 +10830,11 @@ cp_parser_initializer_clause (cp_parser* parser)
{
/* Parse the initializer list. */
CONSTRUCTOR_ELTS (initializer)
= cp_parser_initializer_list (parser);
= cp_parser_initializer_list (parser, non_constant_p);
/* A trailing `,' token is allowed. */
if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
cp_lexer_consume_token (parser->lexer);
}
/* Now, there should be a trailing `}'. */
cp_parser_require (parser, CPP_CLOSE_BRACE, "`}'");
}
@ -10832,20 +10856,25 @@ cp_parser_initializer_clause (cp_parser* parser)
Returns a TREE_LIST. The TREE_VALUE of each node is an expression
for the initializer. If the TREE_PURPOSE is non-NULL, it is the
IDENTIFIER_NODE naming the field to initialize. */
IDENTIFIER_NODE naming the field to initialize. NON_CONSTANT_P is
as for cp_parser_initializer. */
static tree
cp_parser_initializer_list (cp_parser* parser)
cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
{
tree initializers = NULL_TREE;
/* Assume all of the expressions are constant. */
*non_constant_p = false;
/* Parse the rest of the list. */
while (true)
{
cp_token *token;
tree identifier;
tree initializer;
bool clause_non_constant_p;
/* If the next token is an identifier and the following one is a
colon, we are looking at the GNU designated-initializer
syntax. */
@ -10862,8 +10891,11 @@ cp_parser_initializer_list (cp_parser* parser)
identifier = NULL_TREE;
/* Parse the initializer. */
initializer = cp_parser_initializer_clause (parser);
initializer = cp_parser_initializer_clause (parser,
&clause_non_constant_p);
/* If any clause is non-constant, so is the entire initializer. */
if (clause_non_constant_p)
*non_constant_p = true;
/* Add it to the list. */
initializers = tree_cons (identifier, initializer, initializers);
@ -11821,12 +11853,18 @@ cp_parser_member_declaration (cp_parser* parser)
(cp_lexer_peek_token (parser->lexer)))
decl = error_mark_node;
else
/* Create the declaration. */
decl = grokfield (declarator,
decl_specifiers,
initializer,
asm_specification,
attributes);
{
/* Create the declaration. */
decl = grokfield (declarator,
decl_specifiers,
initializer,
asm_specification,
attributes);
/* Any initialization must have been from a
constant-expression. */
if (decl && TREE_CODE (decl) == VAR_DECL && initializer)
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
}
}
/* Reset PREFIX_ATTRIBUTES. */
@ -12616,8 +12654,8 @@ cp_parser_attribute_list (cp_parser* parser)
{
tree arguments;
arguments = cp_parser_parenthesized_expression_list (parser, true);
arguments = (cp_parser_parenthesized_expression_list
(parser, true, /*non_constant_p=*/NULL));
/* Save the identifier and arguments away. */
TREE_VALUE (attribute) = arguments;
}
@ -13583,7 +13621,9 @@ cp_parser_functional_cast (cp_parser* parser, tree type)
{
tree expression_list;
expression_list = cp_parser_parenthesized_expression_list (parser, false);
expression_list
= cp_parser_parenthesized_expression_list (parser, false,
/*non_constant_p=*/NULL);
return build_functional_cast (type, expression_list);
}

View File

@ -6190,7 +6190,11 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
r = copy_decl (t);
if (TREE_CODE (r) == VAR_DECL)
type = complete_type (type);
{
type = complete_type (type);
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r)
= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t);
}
else if (DECL_SELF_REFERENCE_P (t))
SET_DECL_SELF_REFERENCE_P (r);
TREE_TYPE (r) = type;
@ -7620,7 +7624,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else
{
maybe_push_decl (decl);
if (DECL_PRETTY_FUNCTION_P (decl))
if (TREE_CODE (decl) == VAR_DECL
&& DECL_PRETTY_FUNCTION_P (decl))
{
/* For __PRETTY_FUNCTION__ we have to adjust the
initializer. */

View File

@ -2478,17 +2478,11 @@ finish_id_expression (tree id_expression,
;
/* Const variables or static data members of integral or
enumeration types initialized with constant expressions
are OK. We also accept dependent initializers; they may
turn out to be constant at instantiation-time. */
are OK. */
else if (TREE_CODE (decl) == VAR_DECL
&& CP_TYPE_CONST_P (TREE_TYPE (decl))
&& INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
&& DECL_INITIAL (decl)
&& (TREE_CONSTANT (DECL_INITIAL (decl))
|| type_dependent_expression_p (DECL_INITIAL
(decl))
|| value_dependent_expression_p (DECL_INITIAL
(decl))))
&& DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
;
else
{

View File

@ -1,3 +1,9 @@
2003-07-16 Mark Mitchell <mark@codesourcery.com>
PR c++/11547
* g++.dg/parse/constant3.C: New test.
* g++.dg/parse/crash7.C: Likewise.
2003-07-16 Andrew Pinski <pinskia@physics.uc.edu>
PR target/11008

View File

@ -0,0 +1,7 @@
const int i = 1;
const int j (2);
const int k = { 3 };
enum { a = i, b = j, c = k };

View File

@ -0,0 +1,10 @@
struct A
{
int foo () const { return 0; }
};
template <typename> void bar (int x[], const A &a)
{
const int i=a.foo();
x[i]=0;
}