Commit b5af3133 by Mark Mitchell Committed by Mark Mitchell

re PR c++/20142 (implicit assignment operator with multi-dimensional array is broken)

	PR c++/20142
	* cp-tree.h (target_type): Remove.
	* decl.c (layout_var_decl): Remove #if 0'd code.
	(cp_finish_decl): Remove dead code.
	* init.c (build_vec_init): When determining whether or not the
	element type has an asignment operator, look through all array
	dimensions.
	* typeck.c (target_type): Remove.

	PR c++/20142
	* g++.dg/init/array18.C: New test.

From-SVN: r96170
parent e140d617
2005-03-08 Mark Mitchell <mark@codesourcery.com>
PR c++/20142
* cp-tree.h (target_type): Remove.
* decl.c (layout_var_decl): Remove #if 0'd code.
(cp_finish_decl): Remove dead code.
* init.c (build_vec_init): When determining whether or not the
element type has an asignment operator, look through all array
dimensions.
* typeck.c (target_type): Remove.
2005-03-07 Mark Mitchell <mark@codesourcery.com> 2005-03-07 Mark Mitchell <mark@codesourcery.com>
* class.c (finish_struct_1): Do not warn about non-virtual * class.c (finish_struct_1): Do not warn about non-virtual
......
...@@ -4267,7 +4267,6 @@ extern tree fold_if_not_in_template (tree); ...@@ -4267,7 +4267,6 @@ extern tree fold_if_not_in_template (tree);
extern int string_conv_p (tree, tree, int); extern int string_conv_p (tree, tree, int);
extern tree cp_truthvalue_conversion (tree); extern tree cp_truthvalue_conversion (tree);
extern tree condition_conversion (tree); extern tree condition_conversion (tree);
extern tree target_type (tree);
extern tree require_complete_type (tree); extern tree require_complete_type (tree);
extern tree complete_type (tree); extern tree complete_type (tree);
extern tree complete_type_or_else (tree, tree); extern tree complete_type_or_else (tree, tree);
......
...@@ -3940,9 +3940,6 @@ static void ...@@ -3940,9 +3940,6 @@ static void
layout_var_decl (tree decl) layout_var_decl (tree decl)
{ {
tree type = TREE_TYPE (decl); tree type = TREE_TYPE (decl);
#if 0
tree ttype = target_type (type);
#endif
/* If we haven't already layed out this declaration, do so now. /* If we haven't already layed out this declaration, do so now.
Note that we must not call complete type for an external object Note that we must not call complete type for an external object
...@@ -4710,7 +4707,6 @@ void ...@@ -4710,7 +4707,6 @@ void
cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
{ {
tree type; tree type;
tree ttype = NULL_TREE;
tree cleanup; tree cleanup;
const char *asmspec = NULL; const char *asmspec = NULL;
int was_readonly = 0; int was_readonly = 0;
...@@ -4795,10 +4791,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) ...@@ -4795,10 +4791,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
goto finish_end; goto finish_end;
} }
if (TREE_CODE (decl) != FUNCTION_DECL)
ttype = target_type (type);
/* A reference will be modified here, as it is initialized. */ /* A reference will be modified here, as it is initialized. */
if (! DECL_EXTERNAL (decl) if (! DECL_EXTERNAL (decl)
&& TREE_READONLY (decl) && TREE_READONLY (decl)
......
...@@ -2388,6 +2388,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) ...@@ -2388,6 +2388,9 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
tree atype = TREE_TYPE (base); tree atype = TREE_TYPE (base);
/* The type of an element in the array. */ /* The type of an element in the array. */
tree type = TREE_TYPE (atype); tree type = TREE_TYPE (atype);
/* The element type reached after removing all outer array
types. */
tree inner_elt_type;
/* The type of a pointer to an element in the array. */ /* The type of a pointer to an element in the array. */
tree ptype; tree ptype;
tree stmt_expr; tree stmt_expr;
...@@ -2403,15 +2406,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) ...@@ -2403,15 +2406,17 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
if (maxindex == NULL_TREE || maxindex == error_mark_node) if (maxindex == NULL_TREE || maxindex == error_mark_node)
return error_mark_node; return error_mark_node;
inner_elt_type = strip_array_types (atype);
if (init if (init
&& (from_array == 2 && (from_array == 2
? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type)) ? (!CLASS_TYPE_P (inner_elt_type)
|| !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type))
: !TYPE_NEEDS_CONSTRUCTING (type)) : !TYPE_NEEDS_CONSTRUCTING (type))
&& ((TREE_CODE (init) == CONSTRUCTOR && ((TREE_CODE (init) == CONSTRUCTOR
/* Don't do this if the CONSTRUCTOR might contain something /* Don't do this if the CONSTRUCTOR might contain something
that might throw and require us to clean up. */ that might throw and require us to clean up. */
&& (CONSTRUCTOR_ELTS (init) == NULL_TREE && (CONSTRUCTOR_ELTS (init) == NULL_TREE
|| ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (target_type (type)))) || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
|| from_array)) || from_array))
{ {
/* Do non-default initialization of POD arrays resulting from /* Do non-default initialization of POD arrays resulting from
...@@ -2602,14 +2607,12 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array) ...@@ -2602,14 +2607,12 @@ build_vec_init (tree base, tree maxindex, tree init, int from_array)
/* Flatten multi-dimensional array since build_vec_delete only /* Flatten multi-dimensional array since build_vec_delete only
expects one-dimensional array. */ expects one-dimensional array. */
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
{
m = cp_build_binary_op (MULT_EXPR, m, m = cp_build_binary_op (MULT_EXPR, m,
array_type_nelts_total (type)); array_type_nelts_total (type));
type = strip_array_types (type);
}
finish_cleanup_try_block (try_block); finish_cleanup_try_block (try_block);
e = build_vec_delete_1 (rval, m, type, sfk_base_destructor, e = build_vec_delete_1 (rval, m,
inner_elt_type, sfk_base_destructor,
/*use_global_delete=*/0); /*use_global_delete=*/0);
finish_cleanup (e, try_block); finish_cleanup (e, try_block);
} }
......
...@@ -4644,6 +4644,9 @@ pushtag (tree name, tree type, int globalize) ...@@ -4644,6 +4644,9 @@ pushtag (tree name, tree type, int globalize)
else else
d = pushdecl_with_scope (d, b); d = pushdecl_with_scope (d, b);
if (d == error_mark_node)
POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
/* FIXME what if it gets a name from typedef? */ /* FIXME what if it gets a name from typedef? */
if (ANON_AGGRNAME_P (name)) if (ANON_AGGRNAME_P (name))
DECL_IGNORED_P (d) = 1; DECL_IGNORED_P (d) = 1;
......
...@@ -59,22 +59,6 @@ static void maybe_warn_about_returning_address_of_local (tree); ...@@ -59,22 +59,6 @@ static void maybe_warn_about_returning_address_of_local (tree);
static tree lookup_destructor (tree, tree, tree); static tree lookup_destructor (tree, tree, tree);
static tree convert_arguments (tree, tree, tree, int); static tree convert_arguments (tree, tree, tree, int);
/* Return the target type of TYPE, which means return T for:
T*, T&, T[], T (...), and otherwise, just T. */
tree
target_type (tree type)
{
type = non_reference (type);
while (TREE_CODE (type) == POINTER_TYPE
|| TREE_CODE (type) == ARRAY_TYPE
|| TREE_CODE (type) == FUNCTION_TYPE
|| TREE_CODE (type) == METHOD_TYPE
|| TYPE_PTRMEM_P (type))
type = TREE_TYPE (type);
return type;
}
/* Do `exp = require_complete_type (exp);' to make sure exp /* Do `exp = require_complete_type (exp);' to make sure exp
does not have an incomplete type. (That includes void types.) does not have an incomplete type. (That includes void types.)
Returns the error_mark_node if the VALUE does not have Returns the error_mark_node if the VALUE does not have
......
2005-03-08 Mark Mitchell <mark@codesourcery.com>
PR c++/20142
* g++.dg/init/array18.C: New test.
2005-03-09 Ben Elliston <bje@au.ibm.com> 2005-03-09 Ben Elliston <bje@au.ibm.com>
* consistency.vlad/vlad.exp: Remove trailing semicolons. * consistency.vlad/vlad.exp: Remove trailing semicolons.
......
// PR c++/20142
int n=4;
struct A
{
A() {}
A& operator= (const A&) { --n; return *this; }
};
struct B
{
A x[2][2];
};
int main()
{
B b;
b = b;
return n;
}
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