diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-05-22 19:28:31 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-05-22 19:28:31 +0000 |
commit | 1e2e9f544cc5a52838b868514b42f8c1016efac0 (patch) | |
tree | e082af0b49a7dd245825f7a8bc7b9ca8cd7b23eb /gcc | |
parent | 79bba51c2833a33d574533bf16ea63d97d201736 (diff) | |
download | gcc-1e2e9f544cc5a52838b868514b42f8c1016efac0.zip gcc-1e2e9f544cc5a52838b868514b42f8c1016efac0.tar.gz gcc-1e2e9f544cc5a52838b868514b42f8c1016efac0.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 18 | ||||
-rw-r--r-- | gcc/cp/class.c | 14 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/inherit/union1.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/addr1.C | 12 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/array5.C | 14 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/array6.C | 13 |
8 files changed, 111 insertions, 12 deletions
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 <mark@codesourcery.com> + + 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 <roger@eyesopen.com> * 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 <mark@codesourcery.com> + + 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 <bangerth@dealii.org> Roger Sayle <roger@eyesopen.com> 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 <typename> struct S_T { + const char** operator & (); +}; + +template <class T> void foo(T **) {} + +template <typename> void templateTest() { + S_T<const char> 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<class T> +struct A +{ + T foo; +}; + +template<class T> +struct B +{ + A<int> _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 <int> void foo() { + (array[0].*mem_fun_ptr)(); +} |