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
This commit is contained in:
Mark Mitchell 2004-12-22 03:34:55 +00:00 committed by Mark Mitchell
parent be99edf883
commit 943e3eded2
9 changed files with 102 additions and 15 deletions

View File

@ -1,3 +1,18 @@
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.

View File

@ -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);
}

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -1,3 +1,14 @@
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

View File

@ -0,0 +1,20 @@
// 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 "" }
};

View File

@ -0,0 +1,16 @@
// 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)>
{
};

View File

@ -0,0 +1,3 @@
// PR c++/13268
template<operator< struct A {}; // { dg-error "" }