Commit 1e2e9f54 by Mark Mitchell Committed by Mark Mitchell

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
parent 79bba51c
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> 2004-05-22 Roger Sayle <roger@eyesopen.com>
* name-lookup.c (check_for_out_of_scope_variable): Avoid ICE by * name-lookup.c (check_for_out_of_scope_variable): Avoid ICE by
......
...@@ -3502,14 +3502,14 @@ layout_nonempty_base_or_field (record_layout_info rli, ...@@ -3502,14 +3502,14 @@ layout_nonempty_base_or_field (record_layout_info rli,
/* Place this field. */ /* Place this field. */
place_field (rli, decl); place_field (rli, decl);
offset = byte_position (decl); offset = byte_position (decl);
/* We have to check to see whether or not there is already /* 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. something of the same type at the offset we're about to use.
For example: For example, consider:
struct S {}; struct S {};
struct T : public S { int i; }; struct T : public S { int i; };
struct U : public S, public T {}; struct U : public S, public T {};
Here, we put S at offset zero in U. Then, we can't put T at 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 offset zero -- its S component would be at the same address
...@@ -3518,6 +3518,10 @@ layout_nonempty_base_or_field (record_layout_info rli, ...@@ -3518,6 +3518,10 @@ layout_nonempty_base_or_field (record_layout_info rli,
empty class, have nonzero size, any overlap can happen only empty class, have nonzero size, any overlap can happen only
with a direct or indirect base-class -- it can't happen with with a direct or indirect base-class -- it can't happen with
a data member. */ 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 /* G++ 3.2 did not check for overlaps when placing a non-empty
virtual base. */ virtual base. */
if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo)) if (!abi_version_at_least (2) && binfo && TREE_VIA_VIRTUAL (binfo))
......
...@@ -127,7 +127,7 @@ complete_type (tree type) ...@@ -127,7 +127,7 @@ complete_type (tree type)
else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type)) else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
{ {
tree t = complete_type (TREE_TYPE (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); layout_type (type);
TYPE_NEEDS_CONSTRUCTING (type) TYPE_NEEDS_CONSTRUCTING (type)
= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t)); = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
...@@ -3527,12 +3527,18 @@ build_x_unary_op (enum tree_code code, tree xarg) ...@@ -3527,12 +3527,18 @@ build_x_unary_op (enum tree_code code, tree xarg)
exp = NULL_TREE; exp = NULL_TREE;
/* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an /* [expr.unary.op] says:
error message. */
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 if (code == ADDR_EXPR
&& TREE_CODE (xarg) != TEMPLATE_ID_EXPR && TREE_CODE (xarg) != TEMPLATE_ID_EXPR
&& ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg))) && ((CLASS_TYPE_P (TREE_TYPE (xarg))
&& !COMPLETE_TYPE_P (TREE_TYPE (xarg))) && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (xarg))))
|| (TREE_CODE (xarg) == OFFSET_REF))) || (TREE_CODE (xarg) == OFFSET_REF)))
/* Don't look for a function. */; /* Don't look for a function. */;
else else
...@@ -3927,8 +3933,12 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) ...@@ -3927,8 +3933,12 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
return arg; return arg;
} }
/* For &x[y], return x+y. */ /* For &x[y], return x+y. But, in a template, ARG may be an
if (TREE_CODE (arg) == ARRAY_REF) 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))) if (!cxx_mark_addressable (TREE_OPERAND (arg, 0)))
return error_mark_node; return error_mark_node;
......
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> 2004-05-22 Wolfgang Bangerth <bangerth@dealii.org>
Roger Sayle <roger@eyesopen.com> Roger Sayle <roger@eyesopen.com>
......
// PR c++/15507
struct A {
// empty
};
struct B : A {
int b;
};
union U {
A a;
B b;
};
// 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);
}
// PR c++/15427
template<class T>
struct A
{
T foo;
};
template<class T>
struct B
{
A<int> _squares[2];
};
// 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)();
}
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