diff options
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/constexpr-hana1.C | 76 |
3 files changed, 80 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b159c9b..ad7a246 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2016-04-15 Jason Merrill <jason@redhat.com> + PR c++/70685 + * constexpr.c (get_fundef_copy): Handle null *slot. + PR c++/70505 * pt.c (tsubst_baselink): Give the new TEMPLATE_ID_EXPR unknown_type_node, too. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index d9b9a28..ae0c973 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -998,7 +998,7 @@ get_fundef_copy (tree fun) tree copy; tree *slot = fundef_copies_table->get (fun); - if (slot == NULL) + if (slot == NULL || *slot == NULL_TREE) { copy = build_tree_list (NULL, NULL); /* PURPOSE is body, VALUE is parms, TYPE is result. */ diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-hana1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-hana1.C new file mode 100644 index 0000000..f8a9aa0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-hana1.C @@ -0,0 +1,76 @@ +// PR c++/70685 +// { dg-do compile { target c++14 } } + +namespace std { +template <typename _Tp, _Tp __v> struct A { static constexpr _Tp value = __v; +}; +typedef A<bool, false> false_type; +template <bool, typename _Iftrue, typename> using conditional_t = _Iftrue; +namespace hana { +template <typename> struct is_default : false_type {}; +template <typename> struct tag_of; +struct deleted_implementation; +namespace detail { +namespace operators { +template <typename> struct adl {}; +} +} +template <typename> struct B; +template <int v> struct G : std::A<int, v> {}; +template <typename T, T v> G<v> integral_c; +template <int i> using int_ = G<i>; +template <int i> int_<i> int_c; +template <typename> struct C; +template <typename Tag> struct D { + template <typename... X> auto operator()(X... x) { + return C<Tag>::apply(x...); + } +}; +template <typename Tag> D<Tag> make; +template <typename> struct unpack_impl; +struct Foldable { + using Tag = int; + static constexpr int value = is_default<unpack_impl<Tag>>::value; +}; +struct range_tag; +auto make_range = make<range_tag>; +template <typename> struct sum_impl; +template <typename> struct F; +template <typename M = B<int>> F<M> sum; +template <typename T, T, T To> +struct range : detail::operators::adl<range<T, 0, To>> {}; +template <typename T, T From, T To> struct tag_of<range<T, From, To>> { + using type = range_tag; +}; +template <> struct C<range_tag> { + template <typename From, typename To> static auto apply(From, To) { + using T = int; + constexpr T from(From::value); + constexpr T to(To::value); + return range<T, from, to>{}; + } +}; +template <> struct sum_impl<range_tag> { + template <typename I> static constexpr I sum_helper(I m, I n) { + if (m == n) + return 0; + return sum_helper(0, 0); + } + template <typename T, T from, T to> static auto apply(range<T, from, to>) { + integral_c<T, sum_helper(from, to - 1)>; + } +}; +template <typename> struct F { + template <typename Xs> auto operator()(Xs xs) { + using S = typename tag_of<Xs>::type; + using Sum = + conditional_t<Foldable::value, sum_impl<S>, deleted_implementation>; + Sum::apply(xs); + } +}; +} +auto __hana_tmp_22 = + (hana::sum<>(hana::make_range(hana::int_c<-3>, hana::int_c<-2>)), + hana::sum<>(hana::make_range(hana::int_c<3>, hana::int_c<7>)), + hana::int_c<6>); +} |