From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- .../CXX/temp/temp.spec/temp.explicit/p1-0x.cpp | 24 ++++++ .../CXX/temp/temp.spec/temp.explicit/p1-emit.cpp | 29 +++++++ clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp | 89 ++++++++++++++++++++++ .../test/CXX/temp/temp.spec/temp.explicit/p10.cpp | 33 ++++++++ .../test/CXX/temp/temp.spec/temp.explicit/p11.cpp | 18 +++++ .../test/CXX/temp/temp.spec/temp.explicit/p12.cpp | 6 ++ clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp | 43 +++++++++++ .../CXX/temp/temp.spec/temp.explicit/p3-0x.cpp | 65 ++++++++++++++++ clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp | 81 ++++++++++++++++++++ clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp | 48 ++++++++++++ clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp | 17 +++++ clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp | 35 +++++++++ clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp | 36 +++++++++ clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp | 40 ++++++++++ .../temp/temp.spec/temp.explicit/p9-linkage.cpp | 66 ++++++++++++++++ clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp | 59 ++++++++++++++ 16 files changed, 689 insertions(+) create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp create mode 100644 clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp (limited to 'clang/test/CXX/temp/temp.spec/temp.explicit') diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp new file mode 100644 index 0000000..80f0598 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +template +struct X { + void f() {} +}; + +template inline void X::f(); // expected-error{{explicit instantiation cannot be 'inline'}} + +template +struct Y { + constexpr int f() { return 0; } +}; + +template constexpr int Y::f(); // expected-error{{explicit instantiation cannot be 'constexpr'}} + +template +struct Z { + enum E : T { e1, e2 }; + T t; // expected-note {{refers here}} +}; + +template enum Z::E; // expected-error {{enumerations cannot be explicitly instantiated}} +template int Z::t; // expected-error {{explicit instantiation of 't' does not refer to}} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp new file mode 100644 index 0000000..d0df305 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -o - %s | FileCheck %s +template +struct X { + static T member1; + static T member2; + static T member3; +}; + +template +T X::member1; + +template +T X::member2 = 17; + +// CHECK: @_ZN1XIiE7member1E = weak_odr global i32 0 +template int X::member1; + +// CHECK: @_ZN1XIiE7member2E = weak_odr global i32 17 +template int X::member2; + +// For implicit instantiation of +long& get(bool Cond1, bool Cond2) { + // CHECK: @_ZN1XIlE7member1E = weak_odr global i64 0 + // CHECK: @_ZN1XIlE7member2E = weak_odr global i64 17 + // CHECK: @_ZN1XIlE7member3E = external global i64 + return Cond1? X::member1 + : Cond2? X::member2 + : X::member3; +} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp new file mode 100644 index 0000000..b426339 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp @@ -0,0 +1,89 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +struct C { }; + +template +struct X0 { + T value; // expected-error{{incomplete}} +}; + +// Explicitly instantiate a class template specialization +template struct X0; +template struct X0; // expected-note{{instantiation}} + +// Explicitly instantiate a function template specialization +template +void f0(T t) { + ++t; // expected-error{{cannot increment}} +} + +template void f0(int); +template void f0(long); +template void f0<>(unsigned); +template void f0(int C::*); // expected-note{{instantiation}} + +// Explicitly instantiate a member template specialization +template +struct X1 { + template + struct Inner { + T member1; + U member2; // expected-error{{incomplete}} + }; + + template + void f(T& t, U u) { + t = u; // expected-error{{incompatible}} + } +}; + +template struct X1::Inner; +template struct X1::Inner; +template struct X1::Inner; // expected-note{{instantiation}} + +template void X1::f(int&, float); +template void X1::f(int&, long); +template void X1::f<>(int&, double); +template void X1::f<>(int&, int*); // expected-note{{instantiation}} + +// Explicitly instantiate members of a class template +struct Incomplete; // expected-note{{forward declaration}} +struct NonDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor) not viable}} + NonDefaultConstructible(int); // expected-note{{candidate constructor}} +}; + +template +struct X2 { + void f(T &t, U u) { + t = u; // expected-error{{incompatible}} + } + + struct Inner { + T member1; + U member2; // expected-error{{incomplete}} + }; + + static T static_member1; + static U static_member2; +}; + +template +T X2::static_member1 = 17; // expected-error{{cannot initialize}} + +template +U X2::static_member2; // expected-error{{no matching}} + +template void X2::f(int &, float); +template void X2::f(int &, double); // expected-error{{does not refer}} +template void X2::f(int&, int*); // expected-note{{instantiation}} + +template struct X2::Inner; +template struct X2::Inner; // expected-note{{instantiation}} + +template int X2::static_member1; +template int* X2::static_member1; // expected-note{{instantiation}} +template + NonDefaultConstructible X2::static_member1; + +template + NonDefaultConstructible X2::static_member2; // expected-note{{instantiation}} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp new file mode 100644 index 0000000..290a874 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template +struct X0 { + void f(T&); + + struct Inner; + + static T static_var; +}; + +template +void X0::f(T& t) { + t = 1; // expected-error{{incompatible type}} +} + +template +struct X0::Inner { + T member; +}; + +template +T X0::static_var = 1; // expected-error{{cannot initialize}} + +extern template struct X0; +template struct X0; // expected-note 2{{instantiation}} + +template struct X0; // expected-note 4{{explicit instantiation definition is here}} + +extern template void X0::f(int&); // expected-error{{follows explicit instantiation definition}} +extern template struct X0::Inner; // expected-error{{follows explicit instantiation definition}} +extern template int X0::static_var; // expected-error{{follows explicit instantiation definition}} +extern template struct X0; // expected-error{{follows explicit instantiation definition}} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp new file mode 100644 index 0000000..4ca5428 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +class X { + template class Y {}; +}; + +class A { + class B {}; + class C {}; +}; + +// C++0x [temp.explicit] 14.7.2/11: +// The usual access checking rules do not apply to names used to specify +// explicit instantiations. +template class X::Y; + +// As an extension, this rule is applied to explicit specializations as well. +template <> class X::Y {}; diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp new file mode 100644 index 0000000..c756486 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +char* p = 0; +template T g(T x = &p) { return x; } +template int g(int); // OK even though &p isn't an int. + diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp new file mode 100644 index 0000000..1dfcf0c --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s + +// Example from the standard +template class Array { void mf() { } }; + +template class Array; +template void Array::mf(); +template void sort(Array& v) { /* ... */ } +template void sort(Array&); +namespace N { + template void f(T&) { } +} +template void N::f(int&); + + +template +struct X0 { + struct Inner {}; + void f() { } + static T value; +}; + +template +T X0::value = 17; + +typedef X0 XInt; + +template struct XInt::Inner; // expected-warning{{template-id}} +template void XInt::f(); // expected-warning{{template-id}} +template int XInt::value; // expected-warning{{template-id}} + +namespace N { + template + struct X1 { // expected-note{{explicit instantiation refers here}} + }; + + template + void f1(T) {} // expected-note{{explicit instantiation refers here}} +} +using namespace N; + +template struct X1; // expected-warning{{must occur in}} +template void f1(int); // expected-warning{{must occur in}} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp new file mode 100644 index 0000000..1028830 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +// If the name declared in the explicit instantiation is an +// unqualified name, the explicit instantiation shall appear in the +// namespace where its template is declared or, if that namespace is +// inline (7.3.1), any namespace from its enclosing namespace set. + +namespace has_inline_namespaces { + inline namespace inner { + template void f(T&) {} + + template + struct X0 { + struct MemberClass {}; + + void mem_func() {} + + template + struct MemberClassTemplate {}; + + template + void mem_func_template(U&) {} + + static int value; + }; + } + + template int X0::value = 17; + + struct X1 {}; + struct X2 {}; + + template void f(X1&); + template void f(X2&); + + template struct X0; + + template struct X0::MemberClass; + + template void X0::mem_func(); + + template struct X0::MemberClassTemplate; + + template void X0::mem_func_template(X1&); + + template int X0::value; +} + +struct X3; +struct X4; + +template void has_inline_namespaces::f(X3&); +template void has_inline_namespaces::f(X4&); + +template struct has_inline_namespaces::X0; + +template struct has_inline_namespaces::X0::MemberClass; + +template void has_inline_namespaces::X0::mem_func(); + +template +struct has_inline_namespaces::X0::MemberClassTemplate; + +template +void has_inline_namespaces::X0::mem_func_template(X3&); diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp new file mode 100644 index 0000000..38ae768 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp @@ -0,0 +1,81 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s + +// A declaration of a function template shall be in scope at the point of the +// explicit instantiation of the function template. +template void f0(T); +template void f0(int); // okay +template void f0(T) { } + +// A definition of the class or class template containing a member function +// template shall be in scope at the point of the explicit instantiation of +// the member function template. +struct X0; // expected-note {{forward declaration}} +template struct X1; // expected-note 5{{declared here}} + +template void X0::f0(int); // expected-error {{incomplete type}} +template void X1::f0(int); // expected-error {{implicit instantiation of undefined template}} + +// A definition of a class template or class member template shall be in scope +// at the point of the explicit instantiation of the class template or class +// member template. +template struct X1; // expected-error{{explicit instantiation of undefined template}} + +template +struct X2 { // expected-note 4{{refers here}} + template + struct Inner; // expected-note{{declared here}} + + struct InnerClass; // expected-note{{forward declaration}} +}; + +template struct X2::Inner; // expected-error{{explicit instantiation of undefined template}} + +// A definition of a class template shall be in scope at the point of an +// explicit instantiation of a member function or a static data member of the +// class template. +template void X1::f1(int); // expected-error {{undefined template}} +template void X1::f1(int); // expected-error {{undefined template}} + +template int X1::member; // expected-error {{undefined template}} + +// A definition of a member class of a class template shall be in scope at the +// point of an explicit instantiation of the member class. +template struct X2::InnerClass; // expected-error{{undefined member}} + +// If the declaration of the explicit instantiation names an implicitly-declared +// special member function (Clause 12), the program is ill-formed. +template X2::X2(); // expected-error{{not an instantiation}} +template X2::X2(const X2&); // expected-error{{not an instantiation}} +template X2::~X2(); // expected-error{{not an instantiation}} +template X2 &X2::operator=(const X2&); // expected-error{{not an instantiation}} + + +// A definition of a class template is sufficient to explicitly +// instantiate a member of the class template which itself is not yet defined. +namespace PR7979 { + template struct S { + void f(); + static void g(); + static int i; + struct S2 { + void h(); + }; + }; + + template void S::f(); + template void S::g(); + template int S::i; + template void S::S2::h(); + + template void S::f() {} + template void S::g() {} + template int S::i; + template void S::S2::h() {} +} + +namespace PR11599 { + template class BasicStringPiece; // expected-note {{template is declared here}} + + extern template class BasicStringPiece; // expected-error{{explicit instantiation of undefined template 'PR11599::BasicStringPiece}} + template class BasicStringPiece; +} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp new file mode 100644 index 0000000..09c428e --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp @@ -0,0 +1,48 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s + +template void f0(T); // expected-note{{here}} +template void f0(int); // expected-error{{explicit instantiation of undefined function template}} + +template +struct X0 { + struct Inner; + + void f1(); // expected-note{{here}} + + static T value; // expected-note{{here}} +}; + +template void X0::f1(); // expected-error{{explicit instantiation of undefined member function}} + +template int X0::value; // expected-error{{explicit instantiation of undefined static data member}} + +template<> void f0(long); // expected-note{{previous template specialization is here}} +template void f0(long); // expected-warning{{explicit instantiation of 'f0' that occurs after an explicit specialization will be ignored}} + +template<> void X0::f1(); // expected-note{{previous template specialization is here}} +template void X0::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization will be ignored}} + +template<> struct X0::Inner; // expected-note{{previous template specialization is here}} +template struct X0::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization will be ignored}} + +template<> long X0::value; // expected-note{{previous template specialization is here}} +template long X0::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization will be ignored}} + +template<> struct X0; // expected-note{{previous template specialization is here}} +template struct X0; // expected-warning{{explicit instantiation of 'X0' that occurs after an explicit specialization will be ignored}} + +// PR 6458 +namespace test0 { + template class foo { + int compare(T x, T y); + }; + + template <> int foo::compare(char x, char y); + template int foo::compare(T x, T y) { + // invalid at T=char; if we get a diagnostic here, we're + // inappropriately instantiating this template. + void *ptr = x; + } + extern template class foo; // expected-warning {{extern templates are a C++11 extension}} + template class foo; +} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp new file mode 100644 index 0000000..8422c51 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s + +namespace N { + template class Y { // expected-note{{explicit instantiation refers here}} + void mf() { } + }; +} + +template class Z; // expected-error{{explicit instantiation of non-template class 'Z'}} + +// FIXME: This example from the standard is wrong; note posted to CWG reflector +// on 10/27/2009 +using N::Y; +template class Y; // expected-warning{{must occur in}} + +template class N::Y; +template void N::Y::mf(); diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp new file mode 100644 index 0000000..1382272 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template class Array { /* ... */ }; +template void sort(Array& v) { } + +// instantiate sort(Array&) - template-argument deduced +template void sort<>(Array&); + +template void sort(Array&); + +template void f0(T, U*) { } + +template void f0(int, float*); +template void f0<>(double, float*); + +template struct hash { }; +struct S { + bool operator==(const S&) const { return false; } +}; + +template struct Hash_map { + void Method(const T& x) { h(x); } + hash h; +}; + +Hash_map *x; +const Hash_map *foo() { + return x; +} + +template<> struct hash { + int operator()(const S& k) const { + return 0; + } +}; diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp new file mode 100644 index 0000000..7398dca --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template +struct X0 { + struct MemberClass { + T member; // expected-error{{with function type}} + }; + + T* f0(T* ptr) { + return ptr + 1; // expected-error{{pointer to the function}} + } + + static T* static_member; +}; + +template +T* X0::static_member = ((T*)0) + 1; // expected-error{{pointer to the function}} + +template class X0; // okay + +template class X0; // expected-note 3{{requested here}} + +// Specialize everything, so that the explicit instantiation does not trigger +// any diagnostics. +template<> +struct X0::MemberClass { }; + +typedef int int_long_func(long); +template<> +int_long_func *X0::f0(int_long_func *) { return 0; } + +template<> +int_long_func *X0::static_member; + +template class X0; + diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp new file mode 100644 index 0000000..550078a --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +template +struct X0 { + struct MemberClass; + + T* f0(T* ptr); + + static T* static_member; +}; + +template class X0; // ok; nothing gets instantiated. + +template +struct X0::MemberClass { + T member; +}; + +template +T* X0::f0(T* ptr) { + return ptr + 1; +} + +template +T* X0::static_member = 0; + +template class X0; // ok + + +template +struct X1 { + enum class E { + e = T::error // expected-error 2{{no members}} + }; +}; +template struct X1; // expected-note {{here}} + +extern template struct X1; // ok + +template struct X1; // expected-note {{here}} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp new file mode 100644 index 0000000..04e7df5 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 -O1 -emit-llvm -std=c++11 -o - %s | FileCheck %s + +template +struct X0 { + void f(T &t) { + t = 0; + } + + void g(T &t); + + void h(T &t); + + static T static_var; +}; + +template +inline void X0::g(T & t) { + t = 0; +} + +template +void X0::h(T & t) { + t = 0; +} + +template +T X0::static_var = 0; + +extern template struct X0; + +int *&test(X0 xi, int *ip) { + // CHECK: define available_externally void @_ZN2X0IPiE1fERS0_ + xi.f(ip); + // CHECK: define available_externally void @_ZN2X0IPiE1gERS0_ + xi.g(ip); + // CHECK: declare void @_ZN2X0IPiE1hERS0_ + xi.h(ip); + return X0::static_var; +} + +template +void f0(T& t) { + t = 0; +} + +template +inline void f1(T& t) { + t = 0; +} + +extern template void f0<>(int *&); +extern template void f1<>(int *&); + +void test_f0(int *ip, float *fp) { + // CHECK: declare void @_Z2f0IPiEvRT_ + f0(ip); + // CHECK: define linkonce_odr void @_Z2f0IPfEvRT_ + f0(fp); +} + +void test_f1(int *ip, float *fp) { + // CHECK: define available_externally void @_Z2f1IPiEvRT_ + f1(ip); + // CHECK: define linkonce_odr void @_Z2f1IPfEvRT_ + f1(fp); +} diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp new file mode 100644 index 0000000..8649017 --- /dev/null +++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s + +template +struct X0 { + void f(T &t) { + t = 1; // expected-error{{incompatible type}} + } + + void g(T &t); + + void h(T &t); + + static T static_var; +}; + +template +inline void X0::g(T & t) { + t = 1; // expected-error{{incompatible type}} +} + +template +void X0::h(T & t) { + t = 1; +} + +template +T X0::static_var = 1; + +extern template struct X0; + +int *&test(X0 xi, int *ip) { + xi.f(ip); // expected-note{{instantiation}} + xi.g(ip); // expected-note{{instantiation}} + xi.h(ip); + return X0::static_var; +} + +template +void f0(T& t) { + t = 1; // expected-error{{incompatible type}} +} + +template +inline void f1(T& t) { + t = 1; // expected-error 2{{incompatible type}} +} + +extern template void f0<>(int *&); +extern template void f1<>(int *&); + +void test_f0(int *ip, float *fp) { + f0(ip); + f0(fp); // expected-note{{instantiation}} +} + +void test_f1(int *ip, float *fp) { + f1(ip); // expected-note{{instantiation}} + f1(fp); // expected-note{{instantiation}} +} -- cgit v1.2.3