This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: PR 20142
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 8 Mar 2005 23:42:16 -0800
- Subject: C++ PATCH: PR 20142
- Reply-to: mark at codesourcery dot com
This patch fixes a wrong-code regression; we were forgetting to look
through multiple array dimensions when determining whether or not an
array element defined "operator=".
Tested on x86_64-unknown-linux-gnu, applied on the mainline and on the
3.4 and 4.0 branches. The applications on the branch contain only the
init.c change, to minimize risk.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
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-08 Mark Mitchell <mark@codesourcery.com>
PR c++/20142
* g++.dg/init/array18.C: New test.
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1107
diff -c -5 -p -r1.1107 cp-tree.h
*** cp/cp-tree.h 1 Mar 2005 09:57:38 -0000 1.1107
--- cp/cp-tree.h 9 Mar 2005 07:23:41 -0000
*************** extern tree fold_if_not_in_template
*** 4265,4275 ****
/* in typeck.c */
extern int string_conv_p (tree, tree, int);
extern tree cp_truthvalue_conversion (tree);
extern tree condition_conversion (tree);
- extern tree target_type (tree);
extern tree require_complete_type (tree);
extern tree complete_type (tree);
extern tree complete_type_or_else (tree, tree);
extern int type_unknown_p (tree);
extern tree original_type (tree);
--- 4265,4274 ----
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1374
diff -c -5 -p -r1.1374 decl.c
*** cp/decl.c 2 Mar 2005 19:55:48 -0000 1.1374
--- cp/decl.c 9 Mar 2005 07:23:42 -0000
*************** maybe_deduce_size_from_array_init (tree
*** 3938,3950 ****
static void
layout_var_decl (tree 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.
Note that we must not call complete type for an external object
because it's type might involve templates that we are not
supposed to instantiate yet. (And it's perfectly valid to say
--- 3938,3947 ----
*************** initialize_artificial_var (tree decl, tr
*** 4708,4718 ****
void
cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
{
tree type;
- tree ttype = NULL_TREE;
tree cleanup;
const char *asmspec = NULL;
int was_readonly = 0;
bool var_definition_p = false;
--- 4705,4714 ----
*************** cp_finish_decl (tree decl, tree init, tr
*** 4793,4806 ****
rest_of_decl_compilation (decl, DECL_CONTEXT (decl) == NULL_TREE,
at_eof);
goto finish_end;
}
- if (TREE_CODE (decl) != FUNCTION_DECL)
- ttype = target_type (type);
-
-
/* A reference will be modified here, as it is initialized. */
if (! DECL_EXTERNAL (decl)
&& TREE_READONLY (decl)
&& TREE_CODE (type) == REFERENCE_TYPE)
{
--- 4789,4798 ----
Index: cp/init.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/init.c,v
retrieving revision 1.413
diff -c -5 -p -r1.413 init.c
*** cp/init.c 5 Mar 2005 15:44:19 -0000 1.413
--- cp/init.c 9 Mar 2005 07:23:42 -0000
*************** build_vec_init (tree base, tree maxindex
*** 2386,2395 ****
--- 2386,2398 ----
tree iterator;
/* The type of the array. */
tree atype = TREE_TYPE (base);
/* The type of an element in the array. */
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. */
tree ptype;
tree stmt_expr;
tree compound_stmt;
int destroy_temps;
*************** build_vec_init (tree base, tree maxindex
*** 2401,2419 ****
maxindex = array_type_nelts (atype);
if (maxindex == NULL_TREE || maxindex == error_mark_node)
return error_mark_node;
if (init
&& (from_array == 2
! ? (!CLASS_TYPE_P (type) || !TYPE_HAS_COMPLEX_ASSIGN_REF (type))
: !TYPE_NEEDS_CONSTRUCTING (type))
&& ((TREE_CODE (init) == CONSTRUCTOR
/* Don't do this if the CONSTRUCTOR might contain something
that might throw and require us to clean up. */
&& (CONSTRUCTOR_ELTS (init) == NULL_TREE
! || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (target_type (type))))
|| from_array))
{
/* Do non-default initialization of POD arrays resulting from
brace-enclosed initializers. In this case, digest_init and
store_constructor will handle the semantics for us. */
--- 2404,2424 ----
maxindex = array_type_nelts (atype);
if (maxindex == NULL_TREE || maxindex == error_mark_node)
return error_mark_node;
+ inner_elt_type = strip_array_types (atype);
if (init
&& (from_array == 2
! ? (!CLASS_TYPE_P (inner_elt_type)
! || !TYPE_HAS_COMPLEX_ASSIGN_REF (inner_elt_type))
: !TYPE_NEEDS_CONSTRUCTING (type))
&& ((TREE_CODE (init) == CONSTRUCTOR
/* Don't do this if the CONSTRUCTOR might contain something
that might throw and require us to clean up. */
&& (CONSTRUCTOR_ELTS (init) == NULL_TREE
! || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
|| from_array))
{
/* Do non-default initialization of POD arrays resulting from
brace-enclosed initializers. In this case, digest_init and
store_constructor will handle the semantics for us. */
*************** build_vec_init (tree base, tree maxindex
*** 2600,2617 ****
tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator);
/* Flatten multi-dimensional array since build_vec_delete only
expects one-dimensional array. */
if (TREE_CODE (type) == ARRAY_TYPE)
! {
! m = cp_build_binary_op (MULT_EXPR, m,
! array_type_nelts_total (type));
! type = strip_array_types (type);
! }
finish_cleanup_try_block (try_block);
! e = build_vec_delete_1 (rval, m, type, sfk_base_destructor,
/*use_global_delete=*/0);
finish_cleanup (e, try_block);
}
/* The value of the array initialization is the array itself, RVAL
--- 2605,2620 ----
tree m = cp_build_binary_op (MINUS_EXPR, maxindex, iterator);
/* Flatten multi-dimensional array since build_vec_delete only
expects one-dimensional array. */
if (TREE_CODE (type) == ARRAY_TYPE)
! m = cp_build_binary_op (MULT_EXPR, m,
! array_type_nelts_total (type));
finish_cleanup_try_block (try_block);
! e = build_vec_delete_1 (rval, m,
! inner_elt_type, sfk_base_destructor,
/*use_global_delete=*/0);
finish_cleanup (e, try_block);
}
/* The value of the array initialization is the array itself, RVAL
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.617
diff -c -5 -p -r1.617 typeck.c
*** cp/typeck.c 5 Mar 2005 15:44:20 -0000 1.617
--- cp/typeck.c 9 Mar 2005 07:23:42 -0000
*************** static void casts_away_constness_r (tree
*** 57,82 ****
static bool casts_away_constness (tree, tree);
static void maybe_warn_about_returning_address_of_local (tree);
static tree lookup_destructor (tree, tree, tree);
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
does not have an incomplete type. (That includes void types.)
Returns the error_mark_node if the VALUE does not have
complete type when this function returns. */
--- 57,66 ----
Index: testsuite/g++.dg/init/array18.C
===================================================================
RCS file: testsuite/g++.dg/init/array18.C
diff -N testsuite/g++.dg/init/array18.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/array18.C 9 Mar 2005 07:23:42 -0000
***************
*** 0 ****
--- 1,21 ----
+ // 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;
+ }