summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-22 19:28:31 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>2004-05-22 19:28:31 +0000
commit550bbfa8d896a7207e889bd05f37e28679f7e333 (patch)
treee082af0b49a7dd245825f7a8bc7b9ca8cd7b23eb
parentb6c9b3052d946a21dac0062a224edc5e6cb86d88 (diff)
downloadppe42-gcc-550bbfa8d896a7207e889bd05f37e28679f7e333.tar.gz
ppe42-gcc-550bbfa8d896a7207e889bd05f37e28679f7e333.zip
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@82144 138bc75d-0d04-0410-961f-82ee72b054a4
-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 03cc5a86755..063ea63f819 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 33cbdb64746..73828a854e8 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 3e9c2cf590e..603f655c832 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 13b309c02ff..2d7c928f9d0 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 00000000000..da46096c8c8
--- /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 00000000000..dd5e3870fc5
--- /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 00000000000..a5435806747
--- /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 00000000000..0dc5161b2b2
--- /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)();
+}
OpenPOWER on IntegriCloud