diff options
Diffstat (limited to 'clang/test/CXX/temp/temp.spec/temp.explicit')
16 files changed, 689 insertions, 0 deletions
| 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<typename T> +struct X { +  void f() {} +}; + +template inline void X<int>::f(); // expected-error{{explicit instantiation cannot be 'inline'}} + +template<typename T> +struct Y { +  constexpr int f() { return 0; } +}; + +template constexpr int Y<int>::f(); // expected-error{{explicit instantiation cannot be 'constexpr'}} + +template<typename T> +struct Z { +  enum E : T { e1, e2 }; +  T t; // expected-note {{refers here}} +}; + +template enum Z<int>::E; // expected-error {{enumerations cannot be explicitly instantiated}} +template int Z<int>::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<typename T> +struct X { +  static T member1; +  static T member2; +  static T member3; +}; + +template<typename T> +T X<T>::member1; + +template<typename T> +T X<T>::member2 = 17; + +// CHECK: @_ZN1XIiE7member1E = weak_odr global i32 0 +template int X<int>::member1; + +// CHECK: @_ZN1XIiE7member2E = weak_odr global i32 17 +template int X<int>::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<long>::member1  +       : Cond2? X<long>::member2 +              : X<long>::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<typename T> +struct X0 { +  T value; // expected-error{{incomplete}} +}; + +// Explicitly instantiate a class template specialization +template struct X0<int>; +template struct X0<void>; // expected-note{{instantiation}} + +// Explicitly instantiate a function template specialization +template<typename T> +void f0(T t) { +  ++t; // expected-error{{cannot increment}} +} + +template void f0(int); +template void f0<long>(long); +template void f0<>(unsigned); +template void f0(int C::*); // expected-note{{instantiation}} + +// Explicitly instantiate a member template specialization +template<typename T> +struct X1 { +  template<typename U> +  struct Inner { +    T member1; +    U member2; // expected-error{{incomplete}} +  }; +   +  template<typename U> +  void f(T& t, U u) { +    t = u; // expected-error{{incompatible}} +  } +}; + +template struct X1<int>::Inner<float>; +template struct X1<int>::Inner<double>; +template struct X1<int>::Inner<void>; // expected-note{{instantiation}} + +template void X1<int>::f(int&, float); +template void X1<int>::f<long>(int&, long); +template void X1<int>::f<>(int&, double); +template void X1<int>::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<typename T, typename U> +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<typename T, typename U> +T X2<T, U>::static_member1 = 17; // expected-error{{cannot initialize}} + +template<typename T, typename U> +U X2<T, U>::static_member2; // expected-error{{no matching}} + +template void X2<int, float>::f(int &, float); +template void X2<int, float>::f(int &, double); // expected-error{{does not refer}} +template void X2<int, int*>::f(int&, int*); // expected-note{{instantiation}} + +template struct X2<int, float>::Inner; +template struct X2<int, Incomplete>::Inner; // expected-note{{instantiation}} + +template int X2<int, float>::static_member1; +template int* X2<int*, float>::static_member1; // expected-note{{instantiation}} +template  +  NonDefaultConstructible X2<NonDefaultConstructible, int>::static_member1; + +template  +  NonDefaultConstructible X2<int, NonDefaultConstructible>::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<typename T> +struct X0 { +  void f(T&); +   +  struct Inner; +   +  static T static_var; +}; + +template<typename T> +void X0<T>::f(T& t) {  +  t = 1; // expected-error{{incompatible type}} +} + +template<typename T> +struct X0<T>::Inner { +  T member; +}; + +template<typename T> +T X0<T>::static_var = 1; // expected-error{{cannot initialize}} + +extern template struct X0<void*>; +template struct X0<void*>; // expected-note 2{{instantiation}} + +template struct X0<int>; // expected-note 4{{explicit instantiation definition is here}} + +extern template void X0<int>::f(int&); // expected-error{{follows explicit instantiation definition}} +extern template struct X0<int>::Inner; // expected-error{{follows explicit instantiation definition}} +extern template int X0<int>::static_var; // expected-error{{follows explicit instantiation definition}} +extern template struct X0<int>; // 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 <typename T> 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<A::B>; + +// As an extension, this rule is applied to explicit specializations as well. +template <> class X::Y<A::C> {}; 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<class T> T g(T x = &p) { return x; } +template int g<int>(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 T> class Array { void mf() { } };  + +template class Array<char>;  +template void Array<int>::mf(); +template<class T> void sort(Array<T>& v) { /* ... */ } +template void sort(Array<char>&); +namespace N {  +  template<class T> void f(T&) { } +}  +template void N::f<int>(int&); + + +template<typename T> +struct X0 { +  struct Inner {}; +  void f() { } +  static T value; +}; + +template<typename T> +T X0<T>::value = 17; + +typedef X0<int> 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<typename T> +  struct X1 { // expected-note{{explicit instantiation refers here}} +  }; +   +  template<typename T> +  void f1(T) {} // expected-note{{explicit instantiation refers here}} +} +using namespace N; + +template struct X1<int>; // 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<class T> void f(T&) {} + +    template<class T>  +    struct X0 { +      struct MemberClass {}; + +      void mem_func() {} + +      template<typename U> +      struct MemberClassTemplate {}; + +      template<typename U> +      void mem_func_template(U&) {} + +      static int value; +    }; +  } + +  template<typename T> int X0<T>::value = 17; + +  struct X1 {}; +  struct X2 {}; + +  template void f(X1&); +  template void f<X2>(X2&); + +  template struct X0<X1>; + +  template struct X0<X2>::MemberClass; + +  template void X0<X2>::mem_func(); + +  template struct X0<X2>::MemberClassTemplate<X1>; + +  template void X0<X2>::mem_func_template(X1&); + +  template int X0<X2>::value; +} + +struct X3; +struct X4; + +template void has_inline_namespaces::f(X3&); +template void has_inline_namespaces::f<X4>(X4&); + +template struct has_inline_namespaces::X0<X3>; + +template struct has_inline_namespaces::X0<X4>::MemberClass; + +template void has_inline_namespaces::X0<X4>::mem_func(); + +template  +struct has_inline_namespaces::X0<X4>::MemberClassTemplate<X3>; + +template +void has_inline_namespaces::X0<X4>::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<typename T> void f0(T); +template void f0(int); // okay +template<typename T> 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<typename> struct X1; // expected-note 5{{declared here}} + +template void X0::f0<int>(int); // expected-error {{incomplete type}} +template void X1<int>::f0<int>(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<float>; // expected-error{{explicit instantiation of undefined template}} + +template<typename T> +struct X2 { // expected-note 4{{refers here}} +  template<typename U> +  struct Inner; // expected-note{{declared here}} +   +  struct InnerClass; // expected-note{{forward declaration}} +}; + +template struct X2<int>::Inner<float>; // 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<int>::f1(int); // expected-error {{undefined template}} +template void X1<int>::f1<int>(int); // expected-error {{undefined template}} + +template int X1<int>::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<float>::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<int>::X2(); // expected-error{{not an instantiation}} +template X2<int>::X2(const X2&); // expected-error{{not an instantiation}} +template X2<int>::~X2(); // expected-error{{not an instantiation}} +template X2<int> &X2<int>::operator=(const X2<int>&); // 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 <typename T> struct S { +    void f(); +    static void g(); +    static int i; +    struct S2 { +      void h(); +    }; +  }; + +  template void S<int>::f(); +  template void S<int>::g(); +  template int S<int>::i; +  template void S<int>::S2::h(); + +  template <typename T> void S<T>::f() {} +  template <typename T> void S<T>::g() {} +  template <typename T> int S<T>::i; +  template <typename T> void S<T>::S2::h() {} +} + +namespace PR11599 { +  template <typename STRING_TYPE> class BasicStringPiece;  // expected-note {{template is declared here}} + +  extern template class BasicStringPiece<int>;  // expected-error{{explicit instantiation of undefined template 'PR11599::BasicStringPiece<int>}} +  template class BasicStringPiece<int>; +} 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<typename T> void f0(T); // expected-note{{here}} +template void f0(int); // expected-error{{explicit instantiation of undefined function template}} + +template<typename T> +struct X0 { +  struct Inner; +   +  void f1(); // expected-note{{here}} +   +  static T value; // expected-note{{here}} +}; + +template void X0<int>::f1(); // expected-error{{explicit instantiation of undefined member function}} + +template int X0<int>::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<long>' that occurs after an explicit specialization will be ignored}} + +template<> void X0<long>::f1(); // expected-note{{previous template specialization is here}} +template void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization will be ignored}} + +template<> struct X0<long>::Inner; // expected-note{{previous template specialization is here}} +template struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization will be ignored}} + +template<> long X0<long>::value; // expected-note{{previous template specialization is here}} +template long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization will be ignored}} + +template<> struct X0<double>; // expected-note{{previous template specialization is here}} +template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization will be ignored}} + +// PR 6458 +namespace test0 { +  template <class T> class foo { +    int compare(T x, T y); +  }; + +  template <> int foo<char>::compare(char x, char y); +  template <class T> int foo<T>::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<char>; // expected-warning {{extern templates are a C++11 extension}} +  template class foo<char>; +} 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 T> class Y { // expected-note{{explicit instantiation refers here}} +    void mf() { }  +  }; +} + +template class Z<int>; // 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<int>; // expected-warning{{must occur in}} + +template class N::Y<char*>;  +template void N::Y<double>::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 T> class Array { /* ... */ };  +template<class T> void sort(Array<T>& v) { } + +// instantiate sort(Array<int>&) - template-argument deduced +template void sort<>(Array<int>&); + +template void sort(Array<long>&); + +template<typename T, typename U> void f0(T, U*) { } + +template void f0<int>(int, float*); +template void f0<>(double, float*); + +template<typename T> struct hash { }; +struct S { +  bool operator==(const S&) const { return false; } +}; + +template<typename T> struct Hash_map { +  void Method(const T& x) { h(x); } +  hash<T> h; +}; + +Hash_map<S> *x; +const Hash_map<S> *foo() { +  return x; +} + +template<> struct hash<S> { +  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<typename T> +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<typename T> +T* X0<T>::static_member = ((T*)0) + 1; // expected-error{{pointer to the function}} + +template class X0<int>; // okay + +template class X0<int(int)>; // expected-note 3{{requested here}} + +// Specialize everything, so that the explicit instantiation does not trigger +// any diagnostics. +template<> +struct X0<int(long)>::MemberClass { }; + +typedef int int_long_func(long); +template<> +int_long_func *X0<int_long_func>::f0(int_long_func *) { return 0; } + +template<> +int_long_func *X0<int(long)>::static_member; + +template class X0<int(long)>; + 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<typename T> +struct X0 { +  struct MemberClass; + +  T* f0(T* ptr); + +  static T* static_member; +}; + +template class X0<int(int)>; // ok; nothing gets instantiated. + +template<typename T> +struct X0<T>::MemberClass { +  T member; +}; + +template<typename T> +T* X0<T>::f0(T* ptr) { +  return ptr + 1; +} + +template<typename T> +T* X0<T>::static_member = 0; + +template class X0<int>; // ok + + +template<typename T> +struct X1 { +  enum class E { +    e = T::error // expected-error 2{{no members}} +  }; +}; +template struct X1<int>; // expected-note {{here}} + +extern template struct X1<char>; // ok + +template struct X1<char>; // 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<typename T> +struct X0 { +  void f(T &t) { +    t = 0; +  } +   +  void g(T &t); +   +  void h(T &t); +   +  static T static_var; +}; + +template<typename T> +inline void X0<T>::g(T & t) { +  t = 0; +} + +template<typename T> +void X0<T>::h(T & t) { +  t = 0; +} + +template<typename T> +T X0<T>::static_var = 0; + +extern template struct X0<int*>; + +int *&test(X0<int*> 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<int*>::static_var; +} + +template<typename T> +void f0(T& t) { +  t = 0; +} + +template<typename T> +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<typename T> +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<typename T> +inline void X0<T>::g(T & t) { +  t = 1; // expected-error{{incompatible type}} +} + +template<typename T> +void X0<T>::h(T & t) { +  t = 1; +} + +template<typename T> +T X0<T>::static_var = 1; + +extern template struct X0<int*>; + +int *&test(X0<int*> xi, int *ip) { +  xi.f(ip); // expected-note{{instantiation}} +  xi.g(ip); // expected-note{{instantiation}} +  xi.h(ip); +  return X0<int*>::static_var; +} + +template<typename T> +void f0(T& t) { +  t = 1; // expected-error{{incompatible type}} +} + +template<typename T> +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}} +} | 
