summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-25 15:41:13 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2012-06-25 15:41:13 +0000
commit96f3d2bd011bb553a1abacbab37401bb254b13a7 (patch)
tree76d50c31b3560da79c45b8bb6aa780199758bad9
parentb15fd65af485f8939a4172ff04d5027868055d06 (diff)
downloadgcc-96f3d2bd011bb553a1abacbab37401bb254b13a7.tar.gz
PR c++/53202
* semantics.c (build_data_member_initialization): Always keep initializer for empty base. (cxx_eval_bare_aggregate): Discard it here. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@188941 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/semantics.c13
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-tuple.C106
4 files changed, 126 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index db74b682eb5..1517a53ee46 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2012-06-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/53202
+ * semantics.c (build_data_member_initialization): Always keep
+ initializer for empty base.
+ (cxx_eval_bare_aggregate): Discard it here.
+
2012-06-25 Jakub Jelinek <jakub@redhat.com>
PR c++/53594
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 3e9c61c724c..b8019e2cf33 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -5817,12 +5817,9 @@ build_data_member_initialization (tree t, VEC(constructor_elt,gc) **vec)
member = op;
else
{
- /* We don't put out anything for an empty base. */
+ /* This is an initializer for an empty base; keep it for now so
+ we can check it in cxx_eval_bare_aggregate. */
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))
- return true;
}
}
if (TREE_CODE (member) == ADDR_EXPR)
@@ -7037,6 +7034,12 @@ cxx_eval_bare_aggregate (const constexpr_call *call, tree t,
constructor_elt *inner = base_field_constructor_elt (n, ce->index);
inner->value = elt;
}
+ else if (TREE_CODE (ce->index) == NOP_EXPR)
+ {
+ /* This is an initializer for an empty base; now that we've
+ checked that it's constant, we can ignore it. */
+ gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (ce->index))));
+ }
else
CONSTRUCTOR_APPEND_ELT (n, ce->index, elt);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5a96ecfb440..163950d32be 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2012-06-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/53202
+ * g++.dg/cpp0x/constexpr-tuple.C: New.
+
2012-06-25 Jakub Jelinek <jakub@redhat.com>
PR target/53759
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-tuple.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-tuple.C
new file mode 100644
index 00000000000..f59cd845304
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-tuple.C
@@ -0,0 +1,106 @@
+// PR c++/53202
+// { dg-do run { target c++11 } }
+
+#include <tuple>
+
+template<typename Callable>
+ struct Bind_simple
+ {
+ explicit
+ Bind_simple(const Callable& callable)
+ : _M_bound(callable)
+ { }
+
+ Bind_simple(const Bind_simple&) = default;
+ Bind_simple(Bind_simple&&) = default;
+
+ auto operator()() -> decltype((*(Callable*)0)())
+ {
+ return std::get<0>(_M_bound)();
+ }
+
+ private:
+
+ std::tuple<Callable> _M_bound;
+ };
+
+template<typename Callable>
+ Bind_simple<Callable>
+ bind_simple(Callable& callable)
+ {
+ return Bind_simple<Callable>(callable);
+ }
+
+struct thread
+{
+ struct ImplBase { };
+
+ template<typename T>
+ struct Impl : ImplBase {
+ T t;
+ Impl(T&& t) : t(std::move(t)) { }
+ };
+
+ template<typename T>
+ thread(T& t)
+ {
+ auto p = make_routine(bind_simple(t));
+
+ p->t();
+
+ delete p;
+ }
+
+ template<typename Callable>
+ Impl<Callable>*
+ make_routine(Callable&& f)
+ {
+ return new Impl<Callable>(std::forward<Callable>(f));
+ }
+};
+
+
+int c;
+class background_hello
+{
+public:
+ background_hello()
+ {
+ __builtin_printf("default ctor called, this=%p\n", this);
+ ++c;
+ }
+
+ background_hello(const background_hello &)
+ {
+ __builtin_printf("copy ctor called\n");
+ ++c;
+ }
+
+ background_hello(background_hello &&)
+ {
+ __builtin_printf("move ctor called\n");
+ ++c;
+ }
+
+ void operator ()() const
+ {
+ __builtin_printf("void background_hello::operator()() called, this=%p\n", this);
+ }
+
+ ~background_hello()
+ {
+ __builtin_printf("destructor called, this=%p\n", this);
+ --c;
+ }
+
+};
+
+int main()
+{
+ {
+ background_hello bh;
+ thread t(bh);
+ }
+ if (c != 0)
+ __builtin_abort ();
+}