aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2010-12-13 15:46:58 -0500
committerJason Merrill <jason@gcc.gnu.org>2010-12-13 15:46:58 -0500
commit0e5dcad1a4b8e68567fda31ec66c9f31b8d60a0a (patch)
tree7f03957e92cf5c6030a63a28e3871aa07a9ed1bc
parent42aa5ada5f8cad29ee89c1d3766f45ded0f0a524 (diff)
downloadgcc-0e5dcad1a4b8e68567fda31ec66c9f31b8d60a0a.zip
gcc-0e5dcad1a4b8e68567fda31ec66c9f31b8d60a0a.tar.gz
gcc-0e5dcad1a4b8e68567fda31ec66c9f31b8d60a0a.tar.bz2
re PR c++/46873 ([C++0x] ICE: in build_data_member_initialization, at cp/semantics.c:5489)
PR c++/46873 PR c++/46877 * semantics.c (build_data_member_initialization): Handle cv-qualified data member. From-SVN: r167770
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/semantics.c58
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ctor4.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ctor5.C30
5 files changed, 85 insertions, 32 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index caea47e..3ca2697 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2010-12-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/46873
+ PR c++/46877
+ * semantics.c (build_data_member_initialization): Handle
+ cv-qualified data member.
+
2010-12-13 Jan Hubicka <jh@suse.cz>
PR middle-end/45388
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 1b3bfa3..27e2982 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5483,49 +5483,43 @@ build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
{
member = TREE_OPERAND (t, 0);
init = unshare_expr (TREE_OPERAND (t, 1));
- if (TREE_CODE (member) == INDIRECT_REF)
- {
- tree op = TREE_OPERAND (member, 0);
- STRIP_NOPS (op);
- gcc_assert (TREE_CODE (op) == ADDR_EXPR);
- op = TREE_OPERAND (op, 0);
- if (TREE_CODE (op) == COMPONENT_REF)
- /* Initializing a cv-qualified member; we just looked through
- the const_cast. */
- member = op;
- else
- {
- /* Initializing an empty base; just skip it. */
- gcc_assert (is_empty_class (TREE_TYPE (member)));
- return true;
- }
- }
}
else
{
- tree memtype;
gcc_assert (TREE_CODE (t) == CALL_EXPR);
member = CALL_EXPR_ARG (t, 0);
- memtype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (member)));
- if (TREE_CODE (member) == NOP_EXPR)
+ /* We don't use build_cplus_new here because it complains about
+ abstract bases. Leaving the call unwrapped means that it has the
+ wrong type, but cxx_eval_constant_expression doesn't care. */
+ init = unshare_expr (t);
+ }
+ if (TREE_CODE (member) == INDIRECT_REF)
+ member = TREE_OPERAND (member, 0);
+ if (TREE_CODE (member) == NOP_EXPR)
+ {
+ tree op = member;
+ STRIP_NOPS (op);
+ if (TREE_CODE (op) == ADDR_EXPR)
{
- /* We don't put out anything for an empty base. */
- gcc_assert (is_empty_class (memtype));
- /* But if the constructor used isn't constexpr, leave in the call
- so we complain later. */
- if (potential_constant_expression (t, tf_none))
- return true;
+ gcc_assert (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (TREE_TYPE (op)),
+ TREE_TYPE (TREE_TYPE (member))));
+ /* Initializing a cv-qualified member; we need to look through
+ the const_cast. */
+ member = op;
}
else
{
- gcc_assert (TREE_CODE (member) == ADDR_EXPR);
- member = TREE_OPERAND (member, 0);
+ /* We don't put out anything for an empty base. */
+ gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
+ /* But if the initializer isn't constexpr, leave it in so we
+ complain later. */
+ if (potential_constant_expression (init, tf_none))
+ return true;
}
- /* We don't use build_cplus_new here because it complains about
- abstract bases. T has the wrong type, but
- cxx_eval_constant_expression doesn't care. */
- init = unshare_expr (t);
}
+ if (TREE_CODE (member) == ADDR_EXPR)
+ member = TREE_OPERAND (member, 0);
if (TREE_CODE (member) == COMPONENT_REF)
member = TREE_OPERAND (member, 1);
CONSTRUCTOR_APPEND_ELT (*vec, member, init);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 165be16..a9ed2f8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2010-12-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/46873
+ PR c++/46877
+ * g++.dg/cpp0x/constexpr-ctor4.C: New.
+ * g++.dg/cpp0x/constexpr-ctor5.C: New.
+
2010-12-13 Janus Weil <janus@gcc.gnu.org>
PR fortran/46201
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor4.C
new file mode 100644
index 0000000..397b4b0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor4.C
@@ -0,0 +1,15 @@
+// PR c++/46873
+// { dg-options -std=c++0x }
+
+struct S
+{
+ int i:1;
+};
+
+struct T
+{
+ const S s;
+ constexpr T (S a = S ()) : s (a) { }
+};
+
+T t;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor5.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor5.C
new file mode 100644
index 0000000..36b0178
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor5.C
@@ -0,0 +1,30 @@
+// PR c++/46877
+// { dg-options -std=c++0x }
+
+struct new_allocator
+{
+ constexpr new_allocator ();
+};
+
+struct string
+{
+ constexpr string ()
+ {
+ }
+ new_allocator a;
+};
+
+struct pair
+{
+ const string first;
+ constexpr pair ()
+ {
+ }
+};
+
+constexpr
+new_allocator::new_allocator ()
+{
+}
+
+pair p;