aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2004-05-22 19:28:31 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2004-05-22 19:28:31 +0000
commit1e2e9f544cc5a52838b868514b42f8c1016efac0 (patch)
treee082af0b49a7dd245825f7a8bc7b9ca8cd7b23eb /gcc
parent79bba51c2833a33d574533bf16ea63d97d201736 (diff)
downloadgcc-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/ChangeLog18
-rw-r--r--gcc/cp/class.c14
-rw-r--r--gcc/cp/typeck.c24
-rw-r--r--gcc/testsuite/ChangeLog14
-rw-r--r--gcc/testsuite/g++.dg/inherit/union1.C14
-rw-r--r--gcc/testsuite/g++.dg/template/addr1.C12
-rw-r--r--gcc/testsuite/g++.dg/template/array5.C14
-rw-r--r--gcc/testsuite/g++.dg/template/array6.C13
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)();
+}