summaryrefslogtreecommitdiffstats
path: root/test/CXX/temp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CXX/temp')
-rw-r--r--test/CXX/temp/temp.decls/p3.cpp7
-rw-r--r--test/CXX/temp/temp.decls/temp.alias/p1.cpp8
-rw-r--r--test/CXX/temp/temp.decls/temp.alias/p2.cpp45
-rw-r--r--test/CXX/temp/temp.decls/temp.alias/p3.cpp13
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p3.cpp2
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp7
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp41
-rw-r--r--test/CXX/temp/temp.param/p10-0x.cpp13
-rw-r--r--test/CXX/temp/temp.param/p11-0x.cpp31
-rw-r--r--test/CXX/temp/temp.param/p9-0x.cpp9
-rw-r--r--test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp30
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp209
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp11
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp14
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp5
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp34
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p2.cpp4
-rw-r--r--test/CXX/temp/temp.type/p1-0x.cpp23
18 files changed, 493 insertions, 13 deletions
diff --git a/test/CXX/temp/temp.decls/p3.cpp b/test/CXX/temp/temp.decls/p3.cpp
new file mode 100644
index 0000000..54800e4
--- /dev/null
+++ b/test/CXX/temp/temp.decls/p3.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T> using A = int;
+template<typename T> using A<T*> = char; // expected-error {{partial specialization of alias templates is not permitted}}
+template<> using A<char> = char; // expected-error {{explicit specialization of alias templates is not permitted}}
+template using A<char> = char; // expected-error {{explicit instantiation of alias templates is not permitted}}
+using A<char> = char; // expected-error {{name defined in alias declaration must be an identifier}}
diff --git a/test/CXX/temp/temp.decls/temp.alias/p1.cpp b/test/CXX/temp/temp.decls/temp.alias/p1.cpp
new file mode 100644
index 0000000..80079b3
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.alias/p1.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T> using U = T;
+
+// The name of the alias template is a template-name.
+U<char> x;
+void f(U<int>);
+typedef U<U<U<U<int>>>> I;
diff --git a/test/CXX/temp/temp.decls/temp.alias/p2.cpp b/test/CXX/temp/temp.decls/temp.alias/p2.cpp
new file mode 100644
index 0000000..e145727
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.alias/p2.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T> using U = T;
+
+using I = U<U<U<U<int>>>>;
+using I = int;
+
+template<typename A, typename B> using Fst = A;
+template<typename A, typename B> using Snd = B;
+
+using I = Fst<Snd<char,int>,double>;
+
+namespace StdExample {
+ // Prerequisites for example.
+ template<class T, class A> struct vector { /* ... */ };
+
+
+ template<class T> struct Alloc {};
+ template<class T> using Vec = vector<T, Alloc<T>>;
+ Vec<int> v;
+
+ template<class T>
+ void process(Vec<T>& v) // expected-note {{previous definition is here}}
+ { /* ... */ }
+
+ template<class T>
+ void process(vector<T, Alloc<T>>& w) // expected-error {{redefinition of 'process'}}
+ { /* ... */ }
+
+ template<template<class> class TT>
+ void f(TT<int>); // expected-note {{candidate template ignored}}
+
+ template<template<class,class> class TT>
+ void g(TT<int, Alloc<int>>);
+
+ int h() {
+ f(v); // expected-error {{no matching function for call to 'f'}}
+ g(v); // OK: TT = vector
+ }
+
+
+ // v's type is same as vector<int, Alloc<int>>.
+ using VTest = vector<int, Alloc<int>>;
+ using VTest = decltype(v);
+}
diff --git a/test/CXX/temp/temp.decls/temp.alias/p3.cpp b/test/CXX/temp/temp.decls/temp.alias/p3.cpp
new file mode 100644
index 0000000..2e9e55c
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.alias/p3.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// The example given in the standard (this is rejected for other reasons anyway).
+template<class T> struct A;
+template<class T> using B = typename A<T>::U; // expected-error {{no type named 'U' in 'A<T>'}}
+template<class T> struct A {
+ typedef B<T> U; // expected-note {{in instantiation of template type alias 'B' requested here}}
+};
+B<short> b;
+
+template<typename T> using U = int;
+// FIXME: This is illegal, but probably only because CWG1044 missed this paragraph.
+template<typename T> using U = U<T>;
diff --git a/test/CXX/temp/temp.decls/temp.friend/p3.cpp b/test/CXX/temp/temp.decls/temp.friend/p3.cpp
index d116e01..0b2a25e 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p3.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p3.cpp
@@ -8,5 +8,5 @@ class B {
template <class T> friend class A;
template <class T> friend class Undeclared;
- template <class T> friend typename A<T>::Member; // expected-warning {{non-class type 'typename A<T>::Member' cannot be a friend}}
+ template <class T> friend typename A<T>::Member; // expected-error {{friend type templates must use an elaborated type}}
};
diff --git a/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp b/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp
index 62cf429..7375f98 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp
@@ -37,3 +37,10 @@ int f3(Args ...args) {
}
template int f3(const char*, int, float, double);
+
+template<typename ...Args>
+int PR9953(Args ...args) {
+ return ^(Args *...block_args) {
+ return f1(block_args); // expected-error{{expression contains unexpanded parameter pack 'block_args'}}
+ }(&args...);
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp
new file mode 100644
index 0000000..d3af0d4
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+#if !__has_feature(cxx_access_control_sfinae)
+# error No support for access control as part of SFINAE?
+#endif
+
+typedef char yes_type;
+typedef char (&no_type)[2];
+
+template<unsigned N> struct unsigned_c { };
+
+template<typename T>
+class has_copy_constructor {
+ static T t;
+
+ template<typename U> static yes_type check(unsigned_c<sizeof(U(t))> * = 0);
+ template<typename U> static no_type check(...);
+
+public:
+ static const bool value = (sizeof(check<T>(0)) == sizeof(yes_type));
+};
+
+struct HasCopy { };
+
+struct HasNonConstCopy {
+ HasNonConstCopy(HasNonConstCopy&);
+};
+
+struct HasDeletedCopy {
+ HasDeletedCopy(const HasDeletedCopy&) = delete;
+};
+
+struct HasPrivateCopy {
+private:
+ HasPrivateCopy(const HasPrivateCopy&);
+};
+
+int check0[has_copy_constructor<HasCopy>::value? 1 : -1];
+int check1[has_copy_constructor<HasNonConstCopy>::value? 1 : -1];
+int check2[has_copy_constructor<HasDeletedCopy>::value? -1 : 1];
+int check3[has_copy_constructor<HasPrivateCopy>::value? -1 : 1];
diff --git a/test/CXX/temp/temp.param/p10-0x.cpp b/test/CXX/temp/temp.param/p10-0x.cpp
new file mode 100644
index 0000000..bc7e616
--- /dev/null
+++ b/test/CXX/temp/temp.param/p10-0x.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+template<typename> struct Y1;
+template<typename, int> struct Y2;
+
+template<class T1, class T2 = int> using B2 = T1;
+template<class T1 = int, class T2> using B2 = T1;
+
+template<template<class> class F, template<class> class G = Y1> using B2t = F<G<int>>;
+template<template<class> class F = Y2, template<class> class G> using B2t = F<G<int>>;
+
+template<int N, int M = 5> using B2n = Y2<int, N + M>;
+template<int N = 5, int M> using B2n = Y2<int, N + M>;
diff --git a/test/CXX/temp/temp.param/p11-0x.cpp b/test/CXX/temp/temp.param/p11-0x.cpp
index 0bf4341..10a4438 100644
--- a/test/CXX/temp/temp.param/p11-0x.cpp
+++ b/test/CXX/temp/temp.param/p11-0x.cpp
@@ -1,29 +1,48 @@
// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
-// If a template-parameter of a class template has a default
-// template-argument, each subsequent template-parameter shall either
-// have a default template-argument supplied or be a template
-// parameter pack.
+// If a template-parameter of a class template or alias template has a default
+// template-argument, each subsequent template-parameter shall either have a
+// default template-argument supplied or be a template parameter pack.
template<typename> struct vector;
+template<typename T = int, typename> struct X3t; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<typename T = int, typename> using A3t = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<int V = 0, int> struct X3nt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<int V = 0, int> using A3nt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<template<class> class M = vector, template<class> class> struct X3tt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<template<class> class M = vector, template<class> class> using A3tt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+
template<typename T = int, typename ...Types> struct X2t;
+template<typename T = int, typename ...Types> using A2t = X2t<T, Types...>;
template<int V = 0, int ...Values> struct X2nt;
+template<int V = 0, int ...Values> using A2nt = X2nt<V, Values...>;
template<template<class> class M = vector, template<class> class... Metas>
struct X2tt;
+template<template<class> class M = vector, template<class> class... Metas>
+ using A2tt = X2tt<M, Metas...>;
-// If a template-parameter of a primary class template is a template
-// parameter pack, it shall be the last template-parameter .
+// If a template-parameter of a primary class template or alias template is a
+// template parameter pack, it shall be the last template-parameter.
template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
int After>
struct X0t;
+template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+using A0t = int;
template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}}
int After>
struct X0nt;
+template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+using A0nt = int;
template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}}
int After>
struct X0tt;
+template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+using A0tt = int;
// [ Note: These are not requirements for function templates or class
// template partial specializations because template arguments can be
diff --git a/test/CXX/temp/temp.param/p9-0x.cpp b/test/CXX/temp/temp.param/p9-0x.cpp
index 17eca7f..1dc6640 100644
--- a/test/CXX/temp/temp.param/p9-0x.cpp
+++ b/test/CXX/temp/temp.param/p9-0x.cpp
@@ -50,3 +50,12 @@ namespace PR8748 {
template<typename T = int> struct Inner::X3 { };
template<typename T = int> void Inner::f2() {}
}
+
+namespace PR10069 {
+ template<typename T, T a, T b=0, T c=1>
+ T f(T x);
+
+ void g() {
+ f<unsigned int, 0>(0);
+ }
+}
diff --git a/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp b/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
new file mode 100644
index 0000000..1d1d350
--- /dev/null
+++ b/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// Examples from CWG1056.
+namespace Example1 {
+ template<class T> struct A;
+ template<class T> using B = A<T>;
+
+ template<class T> struct A {
+ struct C {};
+ B<T>::C bc; // ok, B<T> is the current instantiation.
+ };
+
+ template<class T> struct A<A<T>> {
+ struct C {};
+ B<B<T>>::C bc; // ok, B<B<T>> is the current instantiation.
+ };
+
+ template<class T> struct A<A<A<T>>> {
+ struct C {};
+ B<B<T>>::C bc; // expected-error {{missing 'typename'}}
+ };
+}
+
+namespace Example2 {
+ template<class T> struct A {
+ void g();
+ };
+ template<class T> using B = A<T>;
+ template<class T> void B<T>::g() {} // ok.
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
new file mode 100644
index 0000000..f04c544
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
@@ -0,0 +1,209 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR5907 {
+ template<typename T> struct identity { typedef T type; };
+ struct A { A(); };
+ identity<A>::type::A() { }
+
+ struct B { void f(); };
+ template<typename T> struct C { typedef B type; };
+
+ void C<int>::type::f() { }
+}
+
+namespace PR9421 {
+ namespace N { template<typename T> struct S { void f(); }; }
+ typedef N::S<int> T;
+ namespace N { template<> void T::f() {} }
+}
+
+namespace PR8277 {
+ template< typename S >
+ struct C
+ {
+ template< int >
+ void F( void )
+ {
+ }
+ };
+
+ template< typename S >
+ struct D
+ {
+ typedef C< int > A;
+ };
+
+ typedef D< int >::A A;
+
+ template<>
+ template<>
+ void A::F< 0 >( void )
+ {
+ }
+}
+
+namespace PR8277b {
+ template<typename S> struct C {
+ void f();
+ };
+ template<typename S> struct D {
+ typedef C<int> A;
+ };
+ template<> void D<int>::A::f() {
+ }
+}
+
+namespace PR8708 {
+ template<typename T> struct A {
+ template<typename U> struct B {
+ // #2
+ void f();
+ };
+ };
+
+ // #A specialize the member template for
+ // implicit instantiation of A<int>,
+ // leaving the member template "unspecialized"
+ // (14.7.3/16). Specialization uses the syntax
+ // for explicit specialization (14.7.3/14)
+ template<> template<typename U>
+ struct A<int>::B {
+ // #1
+ void g();
+ };
+
+ // #1 define its function g. There is an enclosing
+ // class template, so we write template<> for each
+ // specialized template (14.7.3/15).
+ template<> template<typename U>
+ void A<int>::B<U>::g() { }
+
+ // #2 define the unspecialized member template's
+ // f
+ template<typename T> template<typename U>
+ void A<T>::B<U>::f() { }
+
+
+ // specialize the member template again, now
+ // specializing the member too. This specializes
+ // #A
+ template<> template<>
+ struct A<int>::B<int> {
+ // #3
+ void h();
+ };
+
+ // defines #3. There is no enclosing class template, so
+ // we write no "template<>".
+ void A<int>::B<int>::h() { }
+
+ void test() {
+ // calls #1
+ A<int>::B<float> a; a.g();
+
+ // calls #2
+ A<float>::B<int> b; b.f();
+
+ // calls #3
+ A<int>::B<int> c; c.h();
+ }
+}
+
+namespace PR9482 {
+ namespace N1 {
+ template <typename T> struct S {
+ void foo() {}
+ };
+ }
+
+ namespace N2 {
+ typedef N1::S<int> X;
+ }
+
+ namespace N1 {
+ template<> void N2::X::foo() {}
+ }
+}
+
+namespace PR9668 {
+ namespace First
+ {
+ template<class T>
+ class Bar
+ {
+ protected:
+
+ static const bool static_bool;
+ };
+ }
+
+ namespace Second
+ {
+ class Foo;
+ }
+
+ typedef First::Bar<Second::Foo> Special;
+
+ namespace
+ First
+ {
+ template<>
+ const bool Special::static_bool(false);
+ }
+}
+
+namespace PR9877 {
+ template<int>
+ struct X
+ {
+ struct Y;
+ };
+
+ template<> struct X<0>::Y { static const int Z = 1; };
+ template<> struct X<1>::Y { static const int Z = 1; };
+
+ const int X<0>::Y::Z;
+ template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}}
+}
+
+namespace PR9913 {
+ template<class,class=int>struct S;
+ template<class X>struct S<X> {
+ template<class T> class F;
+ };
+
+ template<class A>
+ template<class B>
+ class S<A>::F{};
+}
+
+namespace template_class_spec_perClassDecl_nested
+{
+ template <typename T1> struct A {
+ template <typename T2> struct B {
+ template <typename T3> struct C {
+ static void foo();
+ };
+ };
+ };
+
+ template <> struct A<int> {
+ template <typename T2> struct B {
+ template <typename T3> struct C {
+ static void foo();
+ };
+ };
+ };
+
+ template <> template <typename T3> struct A<int>::B<int>::C {
+ static void foo();
+ };
+
+ template <> template <> struct A<int>::B<int>::C<int> {
+ static void foo();
+ };
+
+ template <> template<> template <typename T2> struct A<bool>::B<bool>::C {
+ static void foo();
+ };
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp
index a5ecf5fc..72f33df 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp
@@ -20,3 +20,14 @@ NonDefaultConstructible &test(bool b) {
return b? X<NonDefaultConstructible, int>::member // expected-note{{instantiation}}
: X<NonDefaultConstructible, long>::member;
}
+
+namespace rdar9422013 {
+ template<int>
+ struct X {
+ struct Inner {
+ static unsigned array[17];
+ };
+ };
+
+ template<> unsigned X<1>::Inner::array[]; // okay
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
index 2f9a3cb..c7597e9 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
template<class T> struct A {
void f(T);
template<class X1> void g1(T, X1);
@@ -24,3 +24,15 @@ template<> template<>
// member specialization even if defined in class definition
template<> void A<int>::h(int) { }
+
+namespace PR10024 {
+ template <typename T>
+ struct Test{
+ template <typename U>
+ void get(U i) {}
+ };
+
+ template <typename T>
+ template <>
+ void Test<T>::get<double>(double i) {} // expected-error{{cannot specialize (with 'template<>') a member of an unspecialized template}}
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
index 88cfc5d..56231e2 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
@@ -24,12 +24,11 @@ namespace test1 {
template <> class A<double> {
public:
- static int foo; // expected-note{{attempt to specialize}}
+ static int foo;
static int bar;
};
typedef A<double> AB;
- template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}} \
- // expected-error{{does not specialize}}
+ template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}}
int AB::bar = 1;
}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp
new file mode 100644
index 0000000..f49190e
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T> struct A {
+ struct B { };
+ template<class U> struct C { };
+};
+ template<> struct A<int> {
+ void f(int);
+};
+void h() {
+ A<int> a;
+ a.f(16);
+}
+// A<int>::f must be defined somewhere
+// template<> not used for a member of an // explicitly specialized class template
+void A<int>::f(int) { /* ... */ }
+ template<> struct A<char>::B {
+ void f();
+};
+// template<> also not used when defining a member of // an explicitly specialized member class
+void A<char>::B::f() { /* ... */ }
+ template<> template<class U> struct A<char>::C {
+ void f();
+};
+
+template<>
+template<class U> void A<char>::C<U>::f() { /* ... */ }
+ template<> struct A<short>::B {
+ void f();
+};
+template<> void A<short>::B::f() { /* ... */ } // expected-error{{no function template matches function template specialization 'f'}}
+ template<> template<class U> struct A<short>::C {
+ void f();
+};
+template<class U> void A<short>::C<U>::f() { /* ... */ } // expected-error{{template parameter list matching the non-templated nested type 'A<short>' should be empty ('template<>')}}
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
index 70d338b..822f881 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
// Example from the standard
template<class T> class Array { void mf() { } };
@@ -35,7 +35,7 @@ namespace N {
};
template<typename T>
- void f1(T) {}; // expected-note{{explicit instantiation refers here}}
+ void f1(T) {} // expected-note{{explicit instantiation refers here}}
}
using namespace N;
diff --git a/test/CXX/temp/temp.type/p1-0x.cpp b/test/CXX/temp/temp.type/p1-0x.cpp
new file mode 100644
index 0000000..c22af22
--- /dev/null
+++ b/test/CXX/temp/temp.type/p1-0x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+namespace Old {
+ template<template<class> class TT> struct X { };
+ template<class> struct Y { };
+ template<class T> using Z = Y<T>;
+ X<Y> y;
+ X<Z> z;
+
+ using SameType = decltype(y); // expected-note {{here}}
+ using SameType = decltype(z); // expected-error {{different types}}
+}
+
+namespace New {
+ template<class T> struct X { };
+ template<class> struct Y { };
+ template<class T> using Z = Y<T>;
+ X<Y<int>> y;
+ X<Z<int>> z;
+
+ using SameType = decltype(y);
+ using SameType = decltype(z); // ok
+}
OpenPOWER on IntegriCloud