From 1e2e9f544cc5a52838b868514b42f8c1016efac0 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Sat, 22 May 2004 19:28:31 +0000 Subject: [PATCH] re PR c++/15507 (hang laying out union) PR c++/15507 * class.c (layout_nonempty_base_or_field): Do not try to avoid layout conflicts for unions. PR c++/15542 * typeck.c (build_x_unary_op): Instantiate template class specializations before looking for "operator &". PR c++/15427 * typeck.c (complete_type): Layout non-dependent array types, even in templates. PR c++/15287 * typeck.c (build_unary_op): Do not optimize "&x[y]" when in a template. PR c++/15507 * g++.dg/inherit/union1.C: New test. PR c++/15542 * g++.dg/template/addr1.C: New test. PR c++/15427 * g++.dg/template/array5.C: New test. PR c++/15287 * g++.dg/template/array6.C: New test. From-SVN: r82144 --- gcc/cp/ChangeLog | 18 ++++++++++++++++++ gcc/cp/class.c | 14 +++++++++----- gcc/cp/typeck.c | 24 +++++++++++++++++------- gcc/testsuite/ChangeLog | 14 ++++++++++++++ gcc/testsuite/g++.dg/inherit/union1.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/template/addr1.C | 12 ++++++++++++ gcc/testsuite/g++.dg/template/array5.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/template/array6.C | 13 +++++++++++++ 8 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/g++.dg/inherit/union1.C create mode 100644 gcc/testsuite/g++.dg/template/addr1.C create mode 100644 gcc/testsuite/g++.dg/template/array5.C create mode 100644 gcc/testsuite/g++.dg/template/array6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 03cc5a8..063ea63 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,21 @@ +2004-05-22 Mark Mitchell + + PR c++/15507 + * class.c (layout_nonempty_base_or_field): Do not try to avoid + layout conflicts for unions. + + PR c++/15542 + * typeck.c (build_x_unary_op): Instantiate template class + specializations before looking for "operator &". + + PR c++/15427 + * typeck.c (complete_type): Layout non-dependent array types, even + in templates. + + PR c++/15287 + * typeck.c (build_unary_op): Do not optimize "&x[y]" when in a + template. + 2004-05-22 Roger Sayle * name-lookup.c (check_for_out_of_scope_variable): Avoid ICE by diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 33cbdb6..73828a8 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3502,14 +3502,14 @@ layout_nonempty_base_or_field (record_layout_info rli, /* Place this field. */ place_field (rli, decl); offset = byte_position (decl); - + /* We have to check to see whether or not there is already something of the same type at the offset we're about to use. - For example: + For example, consider: - struct S {}; - struct T : public S { int i; }; - struct U : public S, public T {}; + struct S {}; + struct T : public S { int i; }; + struct U : public S, public T {}; Here, we put S at offset zero in U. Then, we can't put T at offset zero -- its S component would be at the same address @@ -3518,6 +3518,10 @@ layout_nonempty_base_or_field (record_layout_info rli, empty class, have nonzero size, any overlap can happen only with a direct or indirect base-class -- it can't happen with a data member. */ + /* In a union, overlap is permitted; all members are placed at + offset zero. */ + if (TREE_CODE (rli->t) == UNION_TYPE) + break; /* G++ 3.2 did not check for overlaps when placing a non-empty virtual base. */ if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo)) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 3e9c2cf..603f655 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -127,7 +127,7 @@ complete_type (tree type) else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type)) { tree t = complete_type (TREE_TYPE (type)); - if (COMPLETE_TYPE_P (t) && ! processing_template_decl) + if (COMPLETE_TYPE_P (t) && !dependent_type_p (type)) layout_type (type); TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t)); @@ -3527,12 +3527,18 @@ build_x_unary_op (enum tree_code code, tree xarg) exp = NULL_TREE; - /* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an - error message. */ + /* [expr.unary.op] says: + + The address of an object of incomplete type can be taken. + + (And is just the ordinary address operator, not an overloaded + "operator &".) However, if the type is a template + specialization, we must complete the type at this point so that + an overloaded "operator &" will be available if required. */ if (code == ADDR_EXPR && TREE_CODE (xarg) != TEMPLATE_ID_EXPR - && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg))) - && !COMPLETE_TYPE_P (TREE_TYPE (xarg))) + && ((CLASS_TYPE_P (TREE_TYPE (xarg)) + && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg)))) || (TREE_CODE (xarg) == OFFSET_REF))) /* Don't look for a function. */; else @@ -3927,8 +3933,12 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) return arg; } - /* For &x[y], return x+y. */ - if (TREE_CODE (arg) == ARRAY_REF) + /* For &x[y], return x+y. But, in a template, ARG may be an + ARRAY_REF representing a non-dependent expression. In that + case, there may be an overloaded "operator []" that will be + chosen at instantiation time; we must not try to optimize + here. */ + if (TREE_CODE (arg) == ARRAY_REF && !processing_template_decl) { if (!cxx_mark_addressable (TREE_OPERAND (arg, 0))) return error_mark_node; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 13b309c..2d7c928 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,17 @@ +2004-05-22 Mark Mitchell + + PR c++/15507 + * g++.dg/inherit/union1.C: New test. + + PR c++/15542 + * g++.dg/template/addr1.C: New test. + + PR c++/15427 + * g++.dg/template/array5.C: New test. + + PR c++/15287 + * g++.dg/template/array6.C: New test. + 2004-05-22 Wolfgang Bangerth Roger Sayle diff --git a/gcc/testsuite/g++.dg/inherit/union1.C b/gcc/testsuite/g++.dg/inherit/union1.C new file mode 100644 index 0000000..da46096 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/union1.C @@ -0,0 +1,14 @@ +// PR c++/15507 + +struct A { + // empty +}; + +struct B : A { + int b; +}; + +union U { + A a; + B b; +}; diff --git a/gcc/testsuite/g++.dg/template/addr1.C b/gcc/testsuite/g++.dg/template/addr1.C new file mode 100644 index 0000000..dd5e387 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/addr1.C @@ -0,0 +1,12 @@ +// PR c++/15542 + +template struct S_T { + const char** operator & (); +}; + +template void foo(T **) {} + +template void templateTest() { + S_T s_t; + foo(&s_t); +} diff --git a/gcc/testsuite/g++.dg/template/array5.C b/gcc/testsuite/g++.dg/template/array5.C new file mode 100644 index 0000000..a543580 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array5.C @@ -0,0 +1,14 @@ +// PR c++/15427 + +template +struct A +{ + T foo; +}; + +template +struct B +{ + A _squares[2]; +}; + diff --git a/gcc/testsuite/g++.dg/template/array6.C b/gcc/testsuite/g++.dg/template/array6.C new file mode 100644 index 0000000..0dc5161 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array6.C @@ -0,0 +1,13 @@ +// PR c++/15287 + +struct S {}; + +struct Array { + S operator[](int); +} array; + +void (S::*mem_fun_ptr)(); + +template void foo() { + (array[0].*mem_fun_ptr)(); +} -- 2.7.4