+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
/* 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
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))
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));
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
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;
+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>
--- /dev/null
+// PR c++/15507
+
+struct A {
+ // empty
+};
+
+struct B : A {
+ int b;
+};
+
+union U {
+ A a;
+ B b;
+};
--- /dev/null
+// 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);
+}
--- /dev/null
+// PR c++/15427
+
+template<class T>
+struct A
+{
+ T foo;
+};
+
+template<class T>
+struct B
+{
+ A<int> _squares[2];
+};
+
--- /dev/null
+// 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)();
+}