Commit 943e3ede by Mark Mitchell Committed by Mark Mitchell

re PR c++/18378 (ICE when returning a copy of a packed member)

	PR c++/18378
	* call.c (convert_like_real): Do not permit the use of a copy
	constructor to copy a packed field.

	PR c++/17413
	* decl.c (grokdeclarator): Return error_mark_node, not
	void_type_node, to indicate errors.
	* parser.c (cp_parser_template_parameter_list): Robustify.
	(cp_parser_template_parameter): Likewise.

	PR c++/19034
	* tree.c (cp_tree_equal): Handle OVERLOAD.

	PR c++/18378
	* g++.dg/ext/packed8.C: New test.

	PR c++/13268
	* g++.dg/template/crash31.C: New test.

	PR c++/19034
	* g++.dg/template/crash30.C: New test.

From-SVN: r92486
parent be99edf8
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.
PR c++/17413
* decl.c (grokdeclarator): Return error_mark_node, not
void_type_node, to indicate errors.
* parser.c (cp_parser_template_parameter_list): Robustify.
(cp_parser_template_parameter): Likewise.
PR c++/19034
* tree.c (cp_tree_equal): Handle OVERLOAD.
2004-12-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
* decl.c (define_label): Use POP_TIMEVAR_AND_RETURN.
......
......@@ -4288,13 +4288,12 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
if (convs->need_temporary_p || !lvalue_p (expr))
{
tree type = convs->u.next->type;
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 %qE to %qT",
expr, ref_type);
......@@ -4305,6 +4304,20 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
error ("cannot bind rvalue %qE to %qT", 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 %qE to %qT",
expr, ref_type);
return error_mark_node;
}
expr = build_target_expr_with_type (expr, type);
}
......
......@@ -6745,7 +6745,7 @@ grokdeclarator (const cp_declarator *declarator,
&& ! (ctype && !declspecs->any_specifiers_p))
{
error ("declaration of %qD as non-function", dname);
return void_type_node;
return error_mark_node;
}
/* Anything declared one level down from the top level
......
......@@ -8016,9 +8016,10 @@ cp_parser_template_parameter_list (cp_parser* parser)
/* Parse the template-parameter. */
parameter = cp_parser_template_parameter (parser, &is_non_type);
/* Add it to the list. */
parameter_list = process_template_parm (parameter_list,
parameter,
is_non_type);
if (parameter != error_mark_node)
parameter_list = process_template_parm (parameter_list,
parameter,
is_non_type);
/* Peek at the next token. */
token = cp_lexer_peek_token (parser->lexer);
/* If it's not a `,', we're done. */
......@@ -8037,15 +8038,17 @@ cp_parser_template_parameter_list (cp_parser* parser)
type-parameter
parameter-declaration
Returns a TREE_LIST. The TREE_VALUE represents the parameter. The
TREE_PURPOSE is the default value, if any. *IS_NON_TYPE is set to
true iff this parameter is a non-type parameter. */
If all goes well, returns a TREE_LIST. The TREE_VALUE represents
the parameter. The TREE_PURPOSE is the default value, if any.
Returns ERROR_MARK_NODE on failure. *IS_NON_TYPE is set to true
iff this parameter is a non-type parameter. */
static tree
cp_parser_template_parameter (cp_parser* parser, bool *is_non_type)
{
cp_token *token;
cp_parameter_declarator *parameter_declarator;
tree parm;
/* Assume it is a type parameter or a template parameter. */
*is_non_type = false;
......@@ -8094,12 +8097,13 @@ cp_parser_template_parameter (cp_parser* parser, bool *is_non_type)
parameter_declarator
= cp_parser_parameter_declaration (parser, /*template_parm_p=*/true,
/*parenthesized_p=*/NULL);
return (build_tree_list
(parameter_declarator->default_argument,
grokdeclarator (parameter_declarator->declarator,
&parameter_declarator->decl_specifiers,
PARM, /*initialized=*/0,
/*attrlist=*/NULL)));
parm = grokdeclarator (parameter_declarator->declarator,
&parameter_declarator->decl_specifiers,
PARM, /*initialized=*/0,
/*attrlist=*/NULL);
if (parm == error_mark_node)
return error_mark_node;
return build_tree_list (parameter_declarator->default_argument, parm);
}
/* Parse a type-parameter.
......
......@@ -1544,6 +1544,11 @@ cp_tree_equal (tree t1, tree t2)
return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));
case OVERLOAD:
if (OVL_FUNCTION (t1) != OVL_FUNCTION (t2))
return false;
return cp_tree_equal (OVL_CHAIN (t1), OVL_CHAIN (t2));
default:
break;
}
......
2004-12-21 Mark Mitchell <mark@codesourcery.com>
PR c++/18378
* g++.dg/ext/packed8.C: New test.
PR c++/13268
* g++.dg/template/crash31.C: New test.
PR c++/19034
* g++.dg/template/crash30.C: New test.
2004-12-21 Andrew Pinski <pinskia@physics.uc.edu>
PR C++/18984
......
// PR c++/18378
class A
{
public:
int i;
A() {}
A(const A& a) { i = a.i; }
};
class B
{
A a __attribute__((packed));
public:
B() {}
A GetA() { return a; } // { dg-error "" }
};
// PR c++/19034
template< bool C > struct B
{
};
template<typename S> int foo();
template<typename S> int foo1();
template<typename T> struct bar : public B <(sizeof(foo<T>()) == 1)>
{
};
template<typename T> struct bar1 : public B <(sizeof(foo1<T>()) == 1)>
{
};
// PR c++/13268
template<operator< struct A {}; // { 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