aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2015-01-16 18:24:52 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2015-01-16 18:24:52 +0000
commit68e2914e6a4e2ba2b3fd00551552073519921bee (patch)
tree14c4ae7a85b5cb0d0f7d8fcfd35bffcf207f2e45
parent1005e8371773fbdce86232862694912c03ace88e (diff)
downloadgcc-68e2914e6a4e2ba2b3fd00551552073519921bee.zip
gcc-68e2914e6a4e2ba2b3fd00551552073519921bee.tar.gz
gcc-68e2914e6a4e2ba2b3fd00551552073519921bee.tar.bz2
re PR c++/62134 ([C++11] ICE with template alias)
2015-01-16 Paolo Carlini <paolo.carlini@oracle.com> PR c++/62134 * g++.dg/cpp0x/alias-decl-46.C: New. From-SVN: r219766
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-46.C114
2 files changed, 119 insertions, 0 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fa76e0c..c2e957f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2015-01-16 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/62134
+ * g++.dg/cpp0x/alias-decl-46.C: New.
+
2015-01-16 Christophe Lyon <christophe.lyon@linaro.org>
* gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h (CHECK):
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-46.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-46.C
new file mode 100644
index 0000000..19595ea
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-46.C
@@ -0,0 +1,114 @@
+// PR c++/62134
+// { dg-do compile { target c++11 } }
+
+template<typename... T> struct tuple;
+template<__SIZE_TYPE__, typename U> struct tuple_element;
+
+template<bool, typename T = void> struct enable_if { };
+template<typename T> struct enable_if<true, T> { typedef T type; };
+
+template <int V> struct int_t { static constexpr int value = V; };
+template <int V> int constexpr int_t<V>::value;
+
+template <class A, class Val, int i=0>
+struct Index
+{
+ static int const value = -1;
+};
+
+template <class ... A, class Val, int i>
+struct Index<tuple<Val, A ...>, Val, i>
+{
+ static int const value = i;
+};
+
+template <class A0, class ... A, class Val, int i>
+struct Index<tuple<A0, A ...>, Val, i>
+{
+ static int const value = Index<tuple<A ...>, Val, i+1>::value;
+};
+
+template <class C, class R> struct PermutationSign;
+
+template <int w, class C, class R>
+struct PermutationSignIfFound
+{
+ static int const value = 0;
+};
+
+template <class C, class R>
+struct PermutationSignIfFound<-1, C, R>
+{
+ static int const value = 0;
+};
+
+template <>
+struct PermutationSign<tuple<>, tuple<>>
+{
+ static int const value = 1;
+};
+
+template <class C>
+struct PermutationSign<C, tuple<>>
+{
+ static int const value = 0;
+};
+
+template <class R>
+struct PermutationSign<tuple<>, R>
+{
+ static int const value = 0;
+};
+
+template <class C, class Org>
+struct PermutationSign
+{
+ static int const value
+ = PermutationSignIfFound
+ <Index<C, typename tuple_element<0, Org>::type>::value,
+ C, Org>::value;
+};
+
+template <class A, template <class> class Pred, int i=0, class Enable=void>
+struct IndexIf
+{
+ static int const value = -1;
+ using type = tuple<>;
+};
+
+template <class A0, class ... A, template <class> class Pred, int i>
+struct IndexIf<tuple<A0, A ...>, Pred, i,
+ typename enable_if<Pred<A0>::value>::type>
+{
+ using type = A0;
+ static int const value = i;
+};
+
+template <class A0, class ... A, template <class> class Pred, int i>
+struct IndexIf<tuple<A0, A ...>, Pred, i,
+ typename enable_if<!Pred<A0>::value>::type>
+{
+ using next = IndexIf<tuple<A ...>, Pred, i+1>;
+ using type = typename next::type;
+ static int const value = next::value;
+};
+
+template <class P>
+struct MatchPermutationP
+{
+ template <class A> using type = PermutationSign<P, A>;
+};
+
+template <class P, class Plist> struct FindCombination
+{
+ using type = IndexIf<Plist, MatchPermutationP<P>::template type>;
+ static int const where = type::value;
+ static int const sign
+ = (where>=0) ? PermutationSign<P, typename type::type>::value : 0;
+};
+
+int main()
+{
+ using finder = FindCombination<tuple<>, tuple<tuple<>>>;
+ static_assert(finder::where==0 && finder::sign==+1, "bad");
+}