diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-25 15:41:13 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-25 15:41:13 +0000 |
commit | 96f3d2bd011bb553a1abacbab37401bb254b13a7 (patch) | |
tree | 76d50c31b3560da79c45b8bb6aa780199758bad9 | |
parent | b15fd65af485f8939a4172ff04d5027868055d06 (diff) | |
download | gcc-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/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 13 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-tuple.C | 106 |
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 (); +} |