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
This commit is contained in:
Mark Mitchell 2004-05-22 19:28:31 +00:00 committed by Mark Mitchell
parent 79bba51c28
commit 1e2e9f544c
8 changed files with 111 additions and 12 deletions

View File

@ -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

View File

@ -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))

View File

@ -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;

View File

@ -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>

View File

@ -0,0 +1,14 @@
// PR c++/15507
struct A {
// empty
};
struct B : A {
int b;
};
union U {
A a;
B b;
};

View File

@ -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);
}

View File

@ -0,0 +1,14 @@
// PR c++/15427
template<class T>
struct A
{
T foo;
};
template<class T>
struct B
{
A<int> _squares[2];
};

View File

@ -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)();
}