aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Stump <mrs@gcc.gnu.org>1995-04-18 19:23:38 +0000
committerMike Stump <mrs@gcc.gnu.org>1995-04-18 19:23:38 +0000
commit44a8d0b35727556fe4a7ac43706a3c233112fa9b (patch)
tree744e3a3465f78ad554e0d859f3f4a6f0f84b74be
parent7b83cfef6d24a23122a20ab7b0d892913cf9baaf (diff)
downloadgcc-44a8d0b35727556fe4a7ac43706a3c233112fa9b.zip
gcc-44a8d0b35727556fe4a7ac43706a3c233112fa9b.tar.gz
gcc-44a8d0b35727556fe4a7ac43706a3c233112fa9b.tar.bz2
65th Cygnus<->FSF merge
From-SVN: r9412
-rw-r--r--gcc/cp/ChangeLog80
-rw-r--r--gcc/cp/Makefile.in2
-rw-r--r--gcc/cp/class.c19
-rw-r--r--gcc/cp/cp-tree.h2
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/cp/decl2.c48
-rw-r--r--gcc/cp/init.c11
-rw-r--r--gcc/cp/parse.y12
-rw-r--r--gcc/cp/pt.c29
-rw-r--r--gcc/cp/repo.c53
-rw-r--r--gcc/cp/search.c3
-rw-r--r--gcc/cp/typeck.c16
12 files changed, 193 insertions, 90 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 719db74..f8268ec 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,83 @@
+Tue Apr 18 03:57:35 1995 Michael Meissner (meissner@cygnus.com)
+
+ * Makefile.in (lex.o): Add dependency on c-pragma.h.
+
+ * lex.c (handle_sysv_pragma): Use NULL_PTR and NULL_TREE as
+ appropriate, instead of 0.
+
+Mon Apr 17 12:28:42 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (pushdecl): Use decls_match, not duplicate_decls, for
+ comparing local and global decls.
+
+Fri Apr 14 01:46:52 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * typeck.c (convert_arguments): Only prohibit passing to ... of
+ types with non-trivial copy constructors.
+
+ * repo.c (repo_template_used): Don't try to mess with no id.
+
+Fri Apr 14 23:32:50 1995 Per Bothner <bothner@rtl.cygnus.com>
+
+ * decl.c (duplicate_decls): Use cp_warning_at for redundant-decls.
+
+Thu Apr 13 15:37:42 1995 Brendan Kehoe (brendan@lisa.cygnus.com)
+
+ * cp-tree.h (current_tinst_level): Delete declaration, since it's
+ static inside pt.c.
+
+ * typeck.c (build_modify_expr): Catch incompatible array assignment.
+
+ * parse.y (attribute_list, attrib): Rewrite actions to feed the
+ right stuff to decl_attributes.
+
+Thu Apr 13 11:24:10 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * search.c (dfs_debug_mark): Check for magic virtual like
+ import_export_vtable.
+
+ * typeck.c (build_binary_op_nodefault): Don't call cp_pedwarn with
+ four args.
+
+Wed Apr 12 12:02:57 1995 Jason Merrill <jason@deneb.cygnus.com>
+
+ * decl2.c (finish_file): Move prevtable pass before needs_messing_up
+ decision.
+
+Tue Apr 11 11:20:27 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * decl.c (finish_decl): If we're writing out a static data member of
+ a class, we want the debug info for that class.
+
+ * gc.c (build_t_desc): Check linkage of a class properly.
+
+ * class.c (finish_struct): Set the 'headof' offset for the main
+ vtable properly.
+ (prepare_fresh_vtable): Fix typeinfo pointer here.
+ (modify_one_vtable): Instead of here.
+
+Mon Apr 10 12:15:59 1995 Jason Merrill <jason@phydeaux.cygnus.com>
+
+ * repo.c (repo_get_id): New function to return the interesting
+ identifier for a repo entity.
+ (repo_template_used): Use it.
+ (repo_template_instantiated): Mark the id as chosen.
+ (init_repo): Record whether or not the id was chosen.
+ (finish_repo): Note if an id was newly chosen.
+
+ * pt.c (do_function_instantiation): Call repo_template_instantiated.
+ (do_type_instantiation): Ditto. Don't diagnose multiple
+ instantiation.
+
+ * decl2.c (finish_file): Use DECL_NOT_REALLY_EXTERN when deciding
+ whether or not to synthesize a method.
+
+ Undo these changes:
+ * class.c (finish_vtbls): build more vtables if flag_rtti is on.
+ * class.c (modify_all_direct_vtables): ditto.
+ * init.c (expand_direct_vtbls_init): expand more vtables if
+ flag_rtti is on.
+
Sat Apr 8 17:45:41 1995 Mike Stump <mrs@cygnus.com>
* gc.c (build_headof): Use ptrdiff_type_node instead of
diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in
index 52f6186..4ef9c0a 100644
--- a/gcc/cp/Makefile.in
+++ b/gcc/cp/Makefile.in
@@ -247,7 +247,7 @@ pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H)
error.o : error.c $(CONFIG_H) $(CXX_TREE_H)
errfn.o : errfn.c $(CONFIG_H) $(CXX_TREE_H)
sig.o : sig.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h
-repo.o : repo.c $(CONFIG.H) $(CXX_TREE_H)
+repo.o : repo.c $(CONFIG_H) $(CXX_TREE_H)
# These exist for maintenance purposes.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index d6e2315..a4d9b6b 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -691,7 +691,7 @@ prepare_fresh_vtable (binfo, for_type)
if (flag_rtti)
TREE_VALUE (BINFO_VIRTUALS (binfo))
= build_vtable_entry (size_binop (MINUS_EXPR, integer_zero_node, offset),
- FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (BINFO_VIRTUALS (binfo))));
+ build_t_desc (for_type, 0));
#ifdef GATHER_STATISTICS
n_vtables += 1;
@@ -2115,7 +2115,7 @@ finish_vtbls (binfo, do_self, t)
{
base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t));
}
- finish_vtbls (base_binfo, (is_not_base_vtable || flag_rtti), t);
+ finish_vtbls (base_binfo, is_not_base_vtable, t);
}
}
@@ -2250,11 +2250,6 @@ modify_one_vtable (binfo, t, fndecl, pfn)
if (! BINFO_NEW_VTABLE_MARKED (binfo))
prepare_fresh_vtable (binfo, t);
}
- old_rtti = get_vtable_entry_n (BINFO_VIRTUALS (binfo), 0);
- if (old_rtti)
- TREE_VALUE (old_rtti) = build_vtable_entry (
- DELTA_FROM_VTABLE_ENTRY (TREE_VALUE (old_rtti)),
- build_t_desc (t, 0));
}
if (fndecl == NULL_TREE) return;
@@ -2343,7 +2338,7 @@ modify_all_direct_vtables (binfo, do_self, t, fndecl, pfn)
int is_not_base_vtable =
i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo));
if (! TREE_VIA_VIRTUAL (base_binfo))
- modify_all_direct_vtables (base_binfo, (is_not_base_vtable || flag_rtti), t, fndecl, pfn);
+ modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl, pfn);
}
}
@@ -3794,8 +3789,12 @@ finish_struct (t, list_of_fieldlists, warn_anon)
/* Update the rtti pointer for this class. */
if (flag_rtti)
- TREE_VALUE (TYPE_BINFO_VIRTUALS (t))
- = build_vtable_entry (integer_zero_node, build_t_desc (t, 0));
+ {
+ tree offset = get_derived_offset (TYPE_BINFO (t), NULL_TREE);
+ offset = size_binop (MINUS_EXPR, integer_zero_node, offset);
+ TREE_VALUE (TYPE_BINFO_VIRTUALS (t))
+ = build_vtable_entry (offset, build_t_desc (t, 0));
+ }
}
/* If this type has basetypes with constructors, then those
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 5dd853a..a5f761b 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -1500,8 +1500,6 @@ struct tinst_level
struct tinst_level *next;
};
-extern struct tinst_level *current_tinst_level;
-
/* in class.c */
extern tree current_class_name;
extern tree current_class_type;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 86534ed..d288048 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2395,7 +2395,7 @@ duplicate_decls (newdecl, olddecl)
&& !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)))
{
cp_warning ("redundant redeclaration of `%D' in same scope", newdecl);
- cp_warning ("previous declaration of `%D'", olddecl);
+ cp_warning_at ("previous declaration of `%D'", olddecl);
}
/* Copy all the DECL_... slots specified in the new decl
@@ -2971,7 +2971,7 @@ pushdecl (x)
&& TREE_CODE (oldglobal) == FUNCTION_DECL)
{
/* We have one. Their types must agree. */
- if (duplicate_decls (x, oldglobal))
+ if (decls_match (x, oldglobal))
/* OK */;
else
{
@@ -6231,6 +6231,10 @@ finish_decl (decl, init, asmspec_tree, need_pop, flags)
/* Let debugger know it should output info for this type. */
note_debug_info_needed (ttype);
+ if (TREE_STATIC (decl) && DECL_CONTEXT (decl)
+ && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (decl))) == 't')
+ note_debug_info_needed (DECL_CONTEXT (decl));
+
if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
&& DECL_SIZE (decl) != NULL_TREE
&& ! TREE_CONSTANT (DECL_SIZE (decl)))
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index bb2bf53..7e3528c 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2794,7 +2794,7 @@ finish_file ()
int start_time, this_time;
tree fnname;
- tree vars = static_aggregates;
+ tree vars;
int needs_cleaning = 0, needs_messing_up = 0;
if (flag_detailed_statistics)
@@ -2810,27 +2810,6 @@ finish_file ()
we'll need here. */
push_lang_context (lang_name_c);
- if (static_ctors || vars || might_have_exceptions_p ())
- needs_messing_up = 1;
- if (static_dtors)
- needs_cleaning = 1;
-
- /* See if we really need the hassle. */
- while (vars && needs_cleaning == 0)
- {
- tree decl = TREE_VALUE (vars);
- tree type = TREE_TYPE (decl);
- if (TYPE_NEEDS_DESTRUCTOR (type))
- {
- needs_cleaning = 1;
- needs_messing_up = 1;
- break;
- }
- else
- needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type);
- vars = TREE_CHAIN (vars);
- }
-
/* Otherwise, GDB can get confused, because in only knows
about source for LINENO-1 lines. */
lineno -= 1;
@@ -2867,6 +2846,29 @@ finish_file ()
that we can pick up any other tdecls that those routines need. */
walk_vtables ((void (*)())0, finish_prevtable_vardecl);
+ vars = static_aggregates;
+
+ if (static_ctors || vars || might_have_exceptions_p ())
+ needs_messing_up = 1;
+ if (static_dtors)
+ needs_cleaning = 1;
+
+ /* See if we really need the hassle. */
+ while (vars && needs_cleaning == 0)
+ {
+ tree decl = TREE_VALUE (vars);
+ tree type = TREE_TYPE (decl);
+ if (TYPE_NEEDS_DESTRUCTOR (type))
+ {
+ needs_cleaning = 1;
+ needs_messing_up = 1;
+ break;
+ }
+ else
+ needs_messing_up |= TYPE_NEEDS_CONSTRUCTING (type);
+ vars = TREE_CHAIN (vars);
+ }
+
if (needs_cleaning == 0)
goto mess_up;
@@ -3101,7 +3103,7 @@ finish_file ()
if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl))
{
if (TREE_USED (decl)
- || (TREE_PUBLIC (decl) && ! DECL_EXTERNAL (decl)))
+ || (TREE_PUBLIC (decl) && DECL_NOT_REALLY_EXTERN (decl)))
synthesize_method (decl);
else
{
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index ee99ba2..b601d3d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -125,7 +125,6 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
tree real_binfos = BINFO_BASETYPES (real_binfo);
tree binfos = BINFO_BASETYPES (binfo);
int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0;
- int has_expanded = 0;
for (i = 0; i < n_baselinks; i++)
{
@@ -134,12 +133,8 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
int is_not_base_vtable =
i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo));
if (! TREE_VIA_VIRTUAL (real_base_binfo))
- {
- expand_direct_vtbls_init (real_base_binfo, base_binfo,
- (is_not_base_vtable || flag_rtti), can_elide, addr);
- if (is_not_base_vtable && flag_rtti)
- has_expanded = 1;
- }
+ expand_direct_vtbls_init (real_base_binfo, base_binfo,
+ is_not_base_vtable, can_elide, addr);
}
#if 0
/* Before turning this on, make sure it is correct. */
@@ -147,7 +142,7 @@ expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr)
return;
#endif
/* Should we use something besides CLASSTYPE_VFIELDS? */
- if (init_self && !has_expanded && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
+ if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo)))
{
tree base_ptr = convert_pointer_to_real (binfo, addr);
expand_virtual_init (real_binfo, base_ptr);
diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y
index b28d9a1..48c2ae8 100644
--- a/gcc/cp/parse.y
+++ b/gcc/cp/parse.y
@@ -2085,22 +2085,22 @@ attribute:
attribute_list:
attrib
- { $$ = build_tree_list (NULL_TREE, $1); }
+ { $$ = $1; }
| attribute_list ',' attrib
- { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
+ { $$ = chainon ($1, $3); }
;
attrib:
/* empty */
{ $$ = NULL_TREE; }
| any_word
- { $$ = $1; }
+ { $$ = build_tree_list ($1, NULL_TREE); }
| any_word '(' IDENTIFIER ')'
- { $$ = tree_cons ($1, NULL_TREE, build_tree_list (NULL_TREE, $3)); }
+ { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); }
| any_word '(' IDENTIFIER ',' nonnull_exprlist ')'
- { $$ = tree_cons ($1, NULL_TREE, tree_cons (NULL_TREE, $3, $5)); }
+ { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); }
| any_word '(' nonnull_exprlist ')'
- { $$ = tree_cons ($1, NULL_TREE, $3); }
+ { $$ = build_tree_list ($1, $3); }
;
/* This still leaves out most reserved keywords,
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 5b5dceb..f7ec05d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2559,6 +2559,7 @@ do_function_instantiation (declspecs, declarator, storage)
cp_error ("storage class `%D' applied to template instantiation",
storage);
mark_function_instantiated (result, extern_p);
+ repo_template_instantiated (result, extern_p);
}
void
@@ -2608,15 +2609,15 @@ do_type_instantiation (name, storage)
}
/* We've already instantiated this. */
- if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t))
- {
- if (! extern_p)
- cp_pedwarn ("multiple explicit instantiation of `%#T'", t);
- return;
- }
+ if (CLASSTYPE_EXPLICIT_INSTANTIATION (t) && ! CLASSTYPE_INTERFACE_ONLY (t)
+ && extern_p)
+ return;
if (! CLASSTYPE_TEMPLATE_SPECIALIZATION (t))
- mark_class_instantiated (t, extern_p);
+ {
+ mark_class_instantiated (t, extern_p);
+ repo_template_instantiated (t, extern_p);
+ }
{
tree tmp;
@@ -2632,18 +2633,8 @@ do_type_instantiation (name, storage)
tmp = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0);
for (; tmp; tmp = TREE_CHAIN (tmp))
{
- if (DECL_TEMPLATE_SPECIALIZATION (tmp)
- || (DECL_USE_TEMPLATE (tmp) == 0
- && CLASSTYPE_TEMPLATE_SPECIALIZATION (t)))
- continue;
-
- SET_DECL_EXPLICIT_INSTANTIATION (tmp);
- TREE_PUBLIC (tmp) = 1;
- if (! extern_p)
- {
- DECL_INTERFACE_KNOWN (tmp) = 1;
- DECL_NOT_REALLY_EXTERN (tmp) = 1;
- }
+ mark_function_instantiated (tmp, extern_p);
+ repo_template_instantiated (tmp, extern_p);
}
#if 0
diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c
index bc27a27..6b5f249 100644
--- a/gcc/cp/repo.c
+++ b/gcc/cp/repo.c
@@ -79,6 +79,19 @@ repo_class_defined (t)
tree t;
{}
+tree
+repo_get_id (t)
+ tree t;
+{
+ if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
+ {
+ t = TYPE_BINFO_VTABLE (t);
+ if (t == NULL_TREE)
+ return t;
+ }
+ return DECL_ASSEMBLER_NAME (t);
+}
+
/* Note that a template has been used. If we can see the definition, offer
to emit it. */
@@ -91,18 +104,17 @@ repo_template_used (t)
if (! flag_use_repository)
return;
+ id = repo_get_id (t);
+ if (id == NULL_TREE)
+ return;
+
if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
{
- id = TYPE_BINFO_VTABLE (t);
- if (id == NULL_TREE)
- return;
- id = DECL_ASSEMBLER_NAME (id);
if (IDENTIFIER_REPO_CHOSEN (id))
mark_class_instantiated (t, 0);
}
else if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd')
{
- id = DECL_ASSEMBLER_NAME (t);
if (IDENTIFIER_REPO_CHOSEN (id))
mark_function_instantiated (t, 0);
}
@@ -157,6 +169,19 @@ repo_tinfo_used (ti)
{
}
+void
+repo_template_instantiated (t, extern_p)
+ tree t;
+ int extern_p;
+{
+ if (! extern_p)
+ {
+ tree id = repo_get_id (t);
+ if (id)
+ IDENTIFIER_REPO_CHOSEN (id) = 1;
+ }
+}
+
static char *
save_string (s, len)
char *s;
@@ -270,15 +295,21 @@ init_repo (filename)
case 'O':
{
char *q;
- tree id;
+ tree id, orig;
for (q = &buf[2]; *q && *q != ' ' && *q != '\n'; ++q) ;
q = save_string (&buf[2], q - &buf[2]);
id = get_identifier (q);
if (buf[0] == 'C')
- IDENTIFIER_REPO_CHOSEN (id) = 1;
- original_repo = perm_tree_cons (NULL_TREE, id, original_repo);
+ {
+ IDENTIFIER_REPO_CHOSEN (id) = 1;
+ orig = integer_one_node;
+ }
+ else
+ orig = NULL_TREE;
+
+ original_repo = perm_tree_cons (orig, id, original_repo);
}
break;
default:
@@ -315,11 +346,13 @@ finish_repo ()
/* Do we have to write out a new info file? */
- /* Are there any old templates that aren't used any longer? */
+ /* Are there any old templates that aren't used any longer or that are
+ newly chosen? */
for (t = original_repo; t; t = TREE_CHAIN (t))
{
- if (! IDENTIFIER_REPO_USED (TREE_VALUE (t)))
+ if (! IDENTIFIER_REPO_USED (TREE_VALUE (t))
+ || (! TREE_PURPOSE (t) && IDENTIFIER_REPO_CHOSEN (TREE_VALUE (t))))
{
repo_changed = 1;
break;
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index c0f2f2f..7d7d2ff 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -2427,8 +2427,7 @@ dfs_debug_mark (binfo)
while (methods)
{
if (DECL_VINDEX (methods)
- && DECL_SAVED_INSNS (methods) == 0
- && DECL_PENDING_INLINE_INFO (methods) == 0
+ && DECL_THIS_INLINE (methods) == 0
&& DECL_ABSTRACT_VIRTUAL_P (methods) == 0)
{
/* Somebody, somewhere is going to have to define this
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index d26be49..0384d7a 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2665,8 +2665,8 @@ convert_arguments (return_loc, typelist, values, fndecl, flags)
/* Convert `float' to `double'. */
result = tree_cons (NULL_TREE, convert (double_type_node, val), result);
else if (TYPE_LANG_SPECIFIC (TREE_TYPE (val))
- && (TYPE_HAS_INIT_REF (TREE_TYPE (val))
- || TYPE_HAS_ASSIGN_REF (TREE_TYPE (val))))
+ && (! TYPE_HAS_INIT_REF (TREE_TYPE (val))
+ || TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (val))))
{
cp_warning ("cannot pass objects of type `%T' through `...'",
TREE_TYPE (val));
@@ -3147,11 +3147,6 @@ build_binary_op_nodefault (code, orig_op0, orig_op1, error_code)
&& tree_int_cst_lt (TYPE_SIZE (type1), TYPE_SIZE (type0)))
pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer");
}
- else if ((TYPE_SIZE (tt0) != 0) != (TYPE_SIZE (tt1) != 0))
- cp_pedwarn ("comparison of %scomplete and %scomplete pointers `%T' and `%T'",
- TYPE_SIZE (tt0) == 0 ? "in" : "",
- TYPE_SIZE (tt1) == 0 ? "in" : "",
- type0, type1);
else
cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast",
type0, type1);
@@ -5931,6 +5926,13 @@ build_modify_expr (lhs, modifycode, rhs)
{
int from_array;
+ if (! comptypes (lhstype, TREE_TYPE (rhs), 0))
+ {
+ cp_error ("incompatible types in assignment of `%T' to `%T'",
+ TREE_TYPE (rhs), lhstype);
+ return error_mark_node;
+ }
+
/* Allow array assignment in compiler-generated code. */
if (pedantic && ! DECL_ARTIFICIAL (current_function_decl))
pedwarn ("ANSI C++ forbids assignment of arrays");