+2005-07-28 Giovanni Bajo <giovannibajo@gcc.gnu.org>
+
+ Backport:
+
+ 2004-09-16 Mark Mitchell <mark@codesourcery.com>
+ PR c++/16002
+ * parser.c (cp_parser_simple_declaration): Commit to tentative
+ parses after seeing a decl-specifier.
+ (cp_parser_simple_declaration): Eliminate spurious message.
+ (cp_parser_init_declarator): Adjust error message.
+
+ 2005-06-17 Geoffrey Keating <geoffk@apple.com>
+ PR c++/17413
+ * pt.c (type_unification_real): Apply template type deduction even
+ to procedure parameters that are not dependent on a template
+ parameter.
+
+ 2004-11-02 Mark Mitchell <mark@codesourcery.com>
+ PR c++/18124
+ * parser.c (cp_parser_type_parameter): Robustify.
+ PR c++/18155
+ * parser.c (cp_parser_single_declaration): Disallow template
+ typedefs.
+ (cp_parser_typedef_p): New function.
+
+ 2004-12-21 Mark Mitchell <mark@codesourcery.com>
+ PR c++/18378
+ * call.c (convert_like_real): Do not permit the use of a copy
+ constructor to copy a packed field.
+
2005-07-25 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/19208
if (NEED_TEMPORARY_P (convs) || !lvalue_p (expr))
{
tree type = TREE_TYPE (TREE_OPERAND (convs, 0));
+ cp_lvalue_kind lvalue = real_lvalue_p (expr);
if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (ref_type)))
{
/* If the reference is volatile or non-const, we
cannot create a temporary. */
- cp_lvalue_kind lvalue = real_lvalue_p (expr);
-
if (lvalue & clk_bitfield)
error ("cannot bind bitfield `%E' to `%T'",
expr, ref_type);
error ("cannot bind rvalue `%E' to `%T'", expr, ref_type);
return error_mark_node;
}
+ /* If the source is a packed field, and we must use a copy
+ constructor, then building the target expr will require
+ binding the field to the reference parameter to the
+ copy constructor, and we'll end up with an infinite
+ loop. If we can use a bitwise copy, then we'll be
+ OK. */
+ if ((lvalue & clk_packed)
+ && CLASS_TYPE_P (type)
+ && !TYPE_HAS_TRIVIAL_INIT_REF (type))
+ {
+ error ("cannot bind packed field `%E' to `%T'",
+ expr, ref_type);
+ return error_mark_node;
+ }
expr = build_target_expr_with_type (expr, type);
}
(cp_parser *);
static bool cp_parser_friend_p
(tree);
+static bool cp_parser_typedef_p
+ (tree);
static cp_token *cp_parser_require
(cp_parser *, enum cpp_ttype, const char *);
static cp_token *cp_parser_require_keyword
/* Give up. */
goto done;
}
+
+ /* If we have seen at least one decl-specifier, and the next token
+ is not a parenthesis, then we must be looking at a declaration.
+ (After "int (" we might be looking at a functional cast.) */
+ if (decl_specifiers
+ && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
+ cp_parser_commit_to_tentative_parse (parser);
/* Keep going until we hit the `;' at the end of the simple
declaration. */
/* Anything else is an error. */
else
{
- cp_parser_error (parser, "expected `,' or `;'");
+ /* If we have already issued an error message we don't need
+ to issue another one. */
+ if (decl != error_mark_node
+ || (cp_parser_parsing_tentatively (parser)
+ && !cp_parser_committed_to_tentative_parse (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);
/* If the next token is now a `;', consume it. */
if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
- identifier = cp_parser_identifier (parser);
+ {
+ identifier = cp_parser_identifier (parser);
+ /* Treat invalid names as if the parameter were nameless. */
+ if (identifier == error_mark_node)
+ identifier = NULL_TREE;
+ }
else
identifier = NULL_TREE;
+
/* Create the template parameter. */
parameter = finish_template_template_parm (class_type_node,
identifier);
/* Create the combined representation of the parameter and the
default argument. */
- parameter = build_tree_list (default_argument, parameter);
+ parameter = build_tree_list (default_argument, parameter);
}
break;
default:
- /* Anything else is an error. */
- cp_parser_error (parser,
- "expected `class', `typename', or `template'");
- parameter = error_mark_node;
+ abort ();
+ break;
}
return parameter;
&& token->type != CPP_COMMA
&& token->type != CPP_SEMICOLON)
{
- cp_parser_error (parser, "expected init-declarator");
+ cp_parser_error (parser, "expected initializer");
return error_mark_node;
}
tree attributes;
bool function_definition_p = false;
+ /* This function is only used when processing a template
+ declaration. */
+ if (innermost_scope_kind () != sk_template_parms
+ && innermost_scope_kind () != sk_template_spec)
+ abort ();
+
/* Defer access checks until we know what is being declared. */
push_deferring_access_checks (dk_deferred);
&declares_class_or_enum);
if (friend_p)
*friend_p = cp_parser_friend_p (decl_specifiers);
+
+ /* There are no template typedefs. */
+ if (cp_parser_typedef_p (decl_specifiers))
+ {
+ error ("template declaration of `typedef'");
+ decl = error_mark_node;
+ }
+
/* Gather up the access checks that occurred the
decl-specifier-seq. */
stop_deferring_access_checks ();
decl = error_mark_node;
}
}
- else
- decl = NULL_TREE;
/* If it's not a template class, try for a template function. If
the next token is a `;', then this declaration does not declare
anything. But, if there were errors in the decl-specifiers, then
parser->object_scope = NULL_TREE;
/* Look for a trailing `;' after the declaration. */
if (!function_definition_p
- && !cp_parser_require (parser, CPP_SEMICOLON, "`;'"))
+ && (decl == error_mark_node
+ || !cp_parser_require (parser, CPP_SEMICOLON, "`;'")))
cp_parser_skip_to_end_of_block_or_statement (parser);
return decl;
return false;
}
+/* DECL_SPECIFIERS is the representation of a decl-specifier-seq.
+ Returns TRUE iff `typedef' appears among the DECL_SPECIFIERS. */
+
+static bool
+cp_parser_typedef_p (tree decl_specifiers)
+{
+ while (decl_specifiers)
+ {
+ /* See if this decl-specifier is `typedef'. */
+ if (TREE_CODE (TREE_VALUE (decl_specifiers)) == IDENTIFIER_NODE
+ && C_RID_CODE (TREE_VALUE (decl_specifiers)) == RID_TYPEDEF)
+ return true;
+
+ /* Go on to the next decl-specifier. */
+ decl_specifiers = TREE_CHAIN (decl_specifiers);
+ }
+
+ return false;
+}
+
+
/* If the next token is of the indicated TYPE, consume it. Otherwise,
issue an error message indicating that TOKEN_DESC was expected.