507 lines
11 KiB
C++
507 lines
11 KiB
C++
|
// RUN: %clang_cc1 -verify -std=c++11 %s
|
||
|
// RUN: %clang_cc1 -verify -std=c++11 -fdelayed-template-parsing %s
|
||
|
|
||
|
template<typename T>
|
||
|
void f0() {
|
||
|
struct X;
|
||
|
typedef struct Y {
|
||
|
T (X::* f1())(int) { return 0; }
|
||
|
} Y2;
|
||
|
|
||
|
Y2 y = Y();
|
||
|
}
|
||
|
|
||
|
template void f0<int>();
|
||
|
|
||
|
// PR5764
|
||
|
namespace PR5764 {
|
||
|
struct X {
|
||
|
template <typename T>
|
||
|
void Bar() {
|
||
|
typedef T ValueType;
|
||
|
struct Y {
|
||
|
Y() { V = ValueType(); }
|
||
|
|
||
|
ValueType V;
|
||
|
};
|
||
|
|
||
|
Y y;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void test(X x) {
|
||
|
x.Bar<int>();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Instantiation of local classes with virtual functions.
|
||
|
namespace local_class_with_virtual_functions {
|
||
|
template <typename T> struct X { };
|
||
|
template <typename T> struct Y { };
|
||
|
|
||
|
template <typename T>
|
||
|
void f() {
|
||
|
struct Z : public X<Y<T>*> {
|
||
|
virtual void g(Y<T>* y) { }
|
||
|
void g2(int x) {(void)x;}
|
||
|
};
|
||
|
Z z;
|
||
|
(void)z;
|
||
|
}
|
||
|
|
||
|
struct S { };
|
||
|
void test() { f<S>(); }
|
||
|
}
|
||
|
|
||
|
namespace PR8801 {
|
||
|
template<typename T>
|
||
|
void foo() {
|
||
|
class X;
|
||
|
typedef int (X::*pmf_type)();
|
||
|
class X : public T { };
|
||
|
|
||
|
pmf_type pmf = &T::foo;
|
||
|
}
|
||
|
|
||
|
struct Y { int foo(); };
|
||
|
|
||
|
template void foo<Y>();
|
||
|
}
|
||
|
|
||
|
namespace TemplatePacksAndLambdas {
|
||
|
template <typename ...T> int g(T...);
|
||
|
struct S {
|
||
|
template <typename ...T> static void f(int f = g([]{ static T t; return ++t; }()...)) {}
|
||
|
};
|
||
|
void h() { S::f<int, int, int>(); }
|
||
|
}
|
||
|
|
||
|
namespace PR9685 {
|
||
|
template <class Thing> void forEach(Thing t) { t.func(); }
|
||
|
|
||
|
template <typename T> void doIt() {
|
||
|
struct Functor {
|
||
|
void func() { (void)i; }
|
||
|
int i;
|
||
|
};
|
||
|
|
||
|
forEach(Functor());
|
||
|
}
|
||
|
|
||
|
void call() {
|
||
|
doIt<int>();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace PR12702 {
|
||
|
struct S {
|
||
|
template <typename F> bool apply(F f) { return f(); }
|
||
|
};
|
||
|
|
||
|
template <typename> struct T {
|
||
|
void foo() {
|
||
|
struct F {
|
||
|
int x;
|
||
|
|
||
|
bool operator()() { return x == 0; }
|
||
|
};
|
||
|
|
||
|
S().apply(F());
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void call() { T<int>().foo(); }
|
||
|
}
|
||
|
|
||
|
namespace PR17139 {
|
||
|
template <class T> void foo(const T &t) { t.foo(); }
|
||
|
|
||
|
template <class F> void bar(F *f) {
|
||
|
struct B {
|
||
|
F *fn;
|
||
|
void foo() const { fn(); }
|
||
|
} b = { f };
|
||
|
foo(b);
|
||
|
}
|
||
|
|
||
|
void go() {}
|
||
|
|
||
|
void test() { bar(go); }
|
||
|
}
|
||
|
|
||
|
namespace PR17740 {
|
||
|
class C {
|
||
|
public:
|
||
|
template <typename T> static void foo(T function);
|
||
|
template <typename T> static void bar(T function);
|
||
|
template <typename T> static void func(T function);
|
||
|
};
|
||
|
|
||
|
template <typename T> void C::foo(T function) { function(); }
|
||
|
|
||
|
template <typename T> void C::bar(T function) {
|
||
|
foo([&function]() { function(); });
|
||
|
}
|
||
|
|
||
|
template <typename T> void C::func(T function) {
|
||
|
struct Struct {
|
||
|
T mFunction;
|
||
|
|
||
|
Struct(T function) : mFunction(function) {};
|
||
|
|
||
|
void operator()() {
|
||
|
mFunction();
|
||
|
};
|
||
|
};
|
||
|
|
||
|
bar(Struct(function));
|
||
|
}
|
||
|
|
||
|
void call() {
|
||
|
C::func([]() {});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace PR14373 {
|
||
|
struct function {
|
||
|
template <typename _Functor> function(_Functor __f) { __f(); }
|
||
|
};
|
||
|
template <typename Func> function exec_func(Func f) {
|
||
|
struct functor {
|
||
|
functor(Func f) : func(f) {}
|
||
|
void operator()() const { func(); }
|
||
|
Func func;
|
||
|
};
|
||
|
return functor(f);
|
||
|
}
|
||
|
struct Type {
|
||
|
void operator()() const {}
|
||
|
};
|
||
|
int call() {
|
||
|
exec_func(Type());
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace PR18907 {
|
||
|
template <typename>
|
||
|
class C : public C<int> {}; // expected-error{{within its own definition}}
|
||
|
|
||
|
template <typename X>
|
||
|
void F() {
|
||
|
struct A : C<X> {};
|
||
|
}
|
||
|
|
||
|
struct B {
|
||
|
void f() { F<int>(); }
|
||
|
};
|
||
|
}
|
||
|
|
||
|
namespace PR23194 {
|
||
|
struct X {
|
||
|
int operator()() const { return 0; }
|
||
|
};
|
||
|
struct Y {
|
||
|
Y(int) {}
|
||
|
};
|
||
|
template <bool = true> int make_seed_pair() noexcept {
|
||
|
struct state_t {
|
||
|
X x;
|
||
|
Y y{x()};
|
||
|
};
|
||
|
return 0;
|
||
|
}
|
||
|
int func() {
|
||
|
return make_seed_pair();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
namespace PR18653 {
|
||
|
// Forward declarations
|
||
|
|
||
|
template<typename T> void f1() {
|
||
|
void g1(struct x1);
|
||
|
struct x1 {};
|
||
|
}
|
||
|
template void f1<int>();
|
||
|
|
||
|
template<typename T> void f1a() {
|
||
|
void g1(union x1);
|
||
|
union x1 {};
|
||
|
}
|
||
|
template void f1a<int>();
|
||
|
|
||
|
template<typename T> void f2() {
|
||
|
void g2(enum x2); // expected-error{{ISO C++ forbids forward references to 'enum' types}}
|
||
|
enum x2 { nothing };
|
||
|
}
|
||
|
template void f2<int>();
|
||
|
|
||
|
template<typename T> void f3() {
|
||
|
enum class x3;
|
||
|
void g3(enum x3);
|
||
|
enum class x3 { nothing };
|
||
|
}
|
||
|
template void f3<int>();
|
||
|
|
||
|
|
||
|
template<typename T> void f4() {
|
||
|
void g4(struct x4 {} x); // expected-error{{'x4' cannot be defined in a parameter type}}
|
||
|
}
|
||
|
template void f4<int>();
|
||
|
|
||
|
template<typename T> void f4a() {
|
||
|
void g4(union x4 {} x); // expected-error{{'x4' cannot be defined in a parameter type}}
|
||
|
}
|
||
|
template void f4a<int>();
|
||
|
|
||
|
|
||
|
template <class T> void f();
|
||
|
template <class T> struct S1 {
|
||
|
void m() {
|
||
|
f<class newclass>();
|
||
|
f<union newunion>();
|
||
|
}
|
||
|
};
|
||
|
template struct S1<int>;
|
||
|
|
||
|
template <class T> struct S2 {
|
||
|
void m() {
|
||
|
f<enum new_enum>(); // expected-error{{ISO C++ forbids forward references to 'enum' types}}
|
||
|
}
|
||
|
};
|
||
|
template struct S2<int>;
|
||
|
|
||
|
template <class T> struct S3 {
|
||
|
void m() {
|
||
|
enum class new_enum;
|
||
|
f<enum new_enum>();
|
||
|
}
|
||
|
};
|
||
|
template struct S3<int>;
|
||
|
|
||
|
template <class T> struct S4 {
|
||
|
struct local {};
|
||
|
void m() {
|
||
|
f<local>();
|
||
|
}
|
||
|
};
|
||
|
template struct S4<int>;
|
||
|
|
||
|
template <class T> struct S4a {
|
||
|
union local {};
|
||
|
void m() {
|
||
|
f<local>();
|
||
|
}
|
||
|
};
|
||
|
template struct S4a<int>;
|
||
|
|
||
|
template <class T> struct S5 {
|
||
|
enum local { nothing };
|
||
|
void m() {
|
||
|
f<local>();
|
||
|
}
|
||
|
};
|
||
|
template struct S5<int>;
|
||
|
|
||
|
template <class T> struct S7 {
|
||
|
enum class local { nothing };
|
||
|
void m() {
|
||
|
f<local>();
|
||
|
}
|
||
|
};
|
||
|
template struct S7<int>;
|
||
|
|
||
|
|
||
|
template <class T> void fff(T *x);
|
||
|
template <class T> struct S01 {
|
||
|
struct local { };
|
||
|
void m() {
|
||
|
local x;
|
||
|
fff(&x);
|
||
|
}
|
||
|
};
|
||
|
template struct S01<int>;
|
||
|
|
||
|
template <class T> struct S01a {
|
||
|
union local { };
|
||
|
void m() {
|
||
|
local x;
|
||
|
fff(&x);
|
||
|
}
|
||
|
};
|
||
|
template struct S01a<int>;
|
||
|
|
||
|
template <class T> struct S02 {
|
||
|
enum local { nothing };
|
||
|
void m() {
|
||
|
local x;
|
||
|
fff(&x);
|
||
|
}
|
||
|
};
|
||
|
template struct S02<int>;
|
||
|
|
||
|
template <class T> struct S03 {
|
||
|
enum class local { nothing };
|
||
|
void m() {
|
||
|
local x;
|
||
|
fff(&x);
|
||
|
}
|
||
|
};
|
||
|
template struct S03<int>;
|
||
|
|
||
|
|
||
|
template <class T> struct S04 {
|
||
|
void m() {
|
||
|
struct { } x;
|
||
|
fff(&x);
|
||
|
}
|
||
|
};
|
||
|
template struct S04<int>;
|
||
|
|
||
|
template <class T> struct S04a {
|
||
|
void m() {
|
||
|
union { } x;
|
||
|
fff(&x);
|
||
|
}
|
||
|
};
|
||
|
template struct S04a<int>;
|
||
|
|
||
|
template <class T> struct S05 {
|
||
|
void m() {
|
||
|
enum { nothing } x;
|
||
|
fff(&x);
|
||
|
}
|
||
|
};
|
||
|
template struct S05<int>;
|
||
|
|
||
|
template <class T> struct S06 {
|
||
|
void m() {
|
||
|
class { virtual void mmm() {} } x;
|
||
|
fff(&x);
|
||
|
}
|
||
|
};
|
||
|
template struct S06<int>;
|
||
|
}
|
||
|
|
||
|
namespace PR20625 {
|
||
|
template <typename T>
|
||
|
void f() {
|
||
|
struct N {
|
||
|
static constexpr int get() { return 42; }
|
||
|
};
|
||
|
constexpr int n = N::get();
|
||
|
static_assert(n == 42, "n == 42");
|
||
|
}
|
||
|
|
||
|
void g() { f<void>(); }
|
||
|
}
|
||
|
|
||
|
|
||
|
namespace PR21332 {
|
||
|
template<typename T> void f1() {
|
||
|
struct S { // expected-note{{in instantiation of member class 'S' requested here}}
|
||
|
void g1(int n = T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
|
||
|
};
|
||
|
}
|
||
|
template void f1<int>(); // expected-note{{in instantiation of function template specialization 'PR21332::f1<int>' requested here}}
|
||
|
|
||
|
template<typename T> void f2() {
|
||
|
struct S { // expected-note{{in instantiation of member class 'S' requested here}}
|
||
|
void g2() noexcept(T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
|
||
|
};
|
||
|
}
|
||
|
template void f2<int>(); // expected-note{{in instantiation of function template specialization 'PR21332::f2<int>' requested here}}
|
||
|
|
||
|
template<typename T> void f3() {
|
||
|
enum S {
|
||
|
val = T::error; // expected-error{{expected '}' or ','}} expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
|
||
|
};
|
||
|
}
|
||
|
template void f3<int>(); //expected-note{{in instantiation of function template specialization 'PR21332::f3<int>' requested here}}
|
||
|
|
||
|
template<typename T> void f4() {
|
||
|
enum class S {
|
||
|
val = T::error; // expected-error{{expected '}' or ','}} expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
|
||
|
};
|
||
|
}
|
||
|
template void f4<int>(); // expected-note{{in instantiation of function template specialization 'PR21332::f4<int>' requested here}}
|
||
|
|
||
|
template<typename T> void f5() {
|
||
|
class S { // expected-note {{in instantiation of default member initializer 'PR21332::f5()::S::val' requested here}}
|
||
|
int val = T::error; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
|
||
|
};
|
||
|
}
|
||
|
template void f5<int>(); // expected-note {{in instantiation of function template specialization 'PR21332::f5<int>' requested here}}
|
||
|
|
||
|
template<typename T> void f6() {
|
||
|
class S { // expected-note {{in instantiation of member function 'PR21332::f6()::S::get' requested here}}
|
||
|
void get() {
|
||
|
class S2 { // expected-note {{in instantiation of member class 'S2' requested here}}
|
||
|
void g1(int n = T::error); // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
|
||
|
};
|
||
|
}
|
||
|
};
|
||
|
}
|
||
|
template void f6<int>(); // expected-note{{in instantiation of function template specialization 'PR21332::f6<int>' requested here}}
|
||
|
|
||
|
template<typename T> void f7() {
|
||
|
struct S { void g() noexcept(undefined_val); }; // expected-error{{use of undeclared identifier 'undefined_val'}}
|
||
|
}
|
||
|
template void f7<int>();
|
||
|
}
|
||
|
|
||
|
// rdar://23721638: Ensure that we correctly perform implicit
|
||
|
// conversions when instantiating the default arguments of local functions.
|
||
|
namespace rdar23721638 {
|
||
|
struct A {
|
||
|
A(const char *) = delete; // expected-note 2 {{explicitly marked deleted here}}
|
||
|
};
|
||
|
|
||
|
template <typename T> void foo() {
|
||
|
struct Inner { // expected-note {{in instantiation}}
|
||
|
void operator()(T a = "") {} // expected-error {{conversion function from 'const char [1]' to 'rdar23721638::A' invokes a deleted function}}
|
||
|
// expected-note@-1 {{passing argument to parameter 'a' here}}
|
||
|
};
|
||
|
Inner()(); // expected-error {{type 'Inner' does not provide a call operator}}
|
||
|
}
|
||
|
template void foo<A>(); // expected-note 2 {{in instantiation}}
|
||
|
|
||
|
template <typename T> void bar() {
|
||
|
auto lambda = [](T a = "") {}; // expected-error {{conversion function from 'const char [1]' to 'rdar23721638::A' invokes a deleted function}}
|
||
|
// expected-note@-1 {{passing argument to parameter 'a' here}}
|
||
|
lambda();
|
||
|
}
|
||
|
template void bar<A>(); // expected-note {{in instantiation}}
|
||
|
}
|
||
|
|
||
|
namespace anon_union_default_member_init {
|
||
|
template<typename T> void f() {
|
||
|
struct S {
|
||
|
union {
|
||
|
int i = 0;
|
||
|
};
|
||
|
};
|
||
|
}
|
||
|
void g() { f<int>(); }
|
||
|
}
|
||
|
|
||
|
namespace PR45000 {
|
||
|
template <typename T>
|
||
|
void f(int x = [](T x = nullptr) -> int { return x; }());
|
||
|
// expected-error@-1 {{cannot initialize a parameter of type 'int' with an rvalue of type 'nullptr_t'}}
|
||
|
// expected-note@-2 {{passing argument to parameter 'x' here}}
|
||
|
|
||
|
void g() { f<int>(); }
|
||
|
// expected-note@-1 {{in instantiation of default function argument expression for 'f<int>' required here}}
|
||
|
}
|
||
|
|
||
|
namespace LambdaInDefaultMemberInitializer {
|
||
|
template<typename T> void f() {
|
||
|
struct S {
|
||
|
void *p = [this] { return &p; }();
|
||
|
};
|
||
|
}
|
||
|
template void f<int>();
|
||
|
}
|