+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.
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);
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);
}
&& ! (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
/* 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. */
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;
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,
- ¶meter_declarator->decl_specifiers,
- PARM, /*initialized=*/0,
- /*attrlist=*/NULL)));
+ parm = grokdeclarator (parameter_declarator->declarator,
+ ¶meter_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.
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
--- /dev/null
+// 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 "" }
+};
+
--- /dev/null
+// 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)>
+{
+};
--- /dev/null
+// PR c++/13268
+
+template<operator< struct A {}; // { dg-error "" }