1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace dr500 { // dr500: dup 372
6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class D;
7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class A {
8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    class B;
9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    class C;
10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    friend class D;
11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class A::B {};
13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class A::C : public A::B {};
14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  class D : public A::B {};
15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr501 { // dr501: yes
186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct A {
196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    friend void f() {}
206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    void g() {
216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      void (*p)() = &f; // expected-error {{undeclared identifier}}
226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  };
246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr502 { // dr502: yes
276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct Q {};
286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> struct A {
296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    enum E { e = 1 };
306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    void q1() { f(e); }
316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    void q2() { Q arr[sizeof(E)]; f(arr); }
326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    void q3() { Q arr[e]; f(arr); }
336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    void sanity() { Q arr[1]; f(arr); } // expected-error {{undeclared identifier 'f'}}
346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  };
356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  int f(A<int>::E);
366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<int N> int f(Q (&)[N]);
376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template struct A<int>;
386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr505 { // dr505: yes
416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  const char *exts = "\e\(\{\[\%"; // expected-error 5{{use of non-standard escape}}
426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  const char *unknown = "\Q"; // expected-error {{unknown escape sequence}}
436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr506 { // dr506: yes
466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct NonPod { ~NonPod(); };
476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void f(...);
486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void g(NonPod np) { f(np); } // expected-error {{cannot pass}}
496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// FIXME: Add tests here once DR260 is resolved.
526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// dr507: dup 260
536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// dr508: na
556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// dr509: na
566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// dr510: na
576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr512 { // dr512: yes
596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct A {
606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    A(int);
616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  };
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  union U { A a; };
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#if __cplusplus < 201103L
646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // expected-error@-2 {{has a non-trivial constructor}}
656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // expected-note@-6 {{no default constructor}}
666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // expected-note@-6 {{suppressed by user-declared constructor}}
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif
686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// dr513: na
716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr514 { // dr514: yes
736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  namespace A { extern int x, y; }
746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  int A::x = y;
756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr515 { // dr515: sup 1017
786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // FIXME: dr1017 reverses the wording of dr515, but the current draft has
796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // dr515's wording, with a different fix for dr1017.
806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct X { int n; };
826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> struct Y : T {
836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    int f() { return X::n; }
846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  };
856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  int k = Y<X>().f();
866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct A { int a; };
886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct B { void f() { int k = sizeof(A::a); } };
896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#if __cplusplus < 201103L
906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // expected-error@-2 {{invalid use of non-static data member}}
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif
926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// dr516: na
956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr517 { // dr517: no
976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // This is NDR, but we should diagnose it anyway.
986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> struct S {};
996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> int v = 0; // expected-error 0-1{{extension}}
1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template struct S<int*>;
1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template int v<int*>;
1036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  S<char&> s;
1056bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  int k = v<char&>;
1066bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1076bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // FIXME: These are both ill-formed.
1086bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> struct S<T*> {};
1096bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> int v<T*> = 0; // expected-error 0-1{{extension}}
1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1116bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // FIXME: These are both ill-formed.
1126bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> struct S<T&> {};
1136bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> int v<T&> = 0; // expected-error 0-1{{extension}}
1146bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1156bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr518 { // dr518: yes c++11
1176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  enum E { e, };
1186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#if __cplusplus < 201103L
1196bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // expected-error@-2 {{C++11 extension}}
1206bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif
1216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1236bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr519 { // dr519: yes
1246bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// FIXME: Add a codegen test.
1256bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#if __cplusplus >= 201103L
1266bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#define fold(x) (__builtin_constant_p(x) ? (x) : (x))
1276bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  int test[fold((int*)(void*)0) ? -1 : 1];
1286bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#undef fold
1296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#endif
1306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// dr520: na
1336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// dr521: no
1356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// FIXME: The wording here is broken. It's not reasonable to expect a
1366bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// diagnostic here. Once the relevant DR gets a number, mark this as a dup.
1376bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr522 { // dr522: yes
1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct S {};
1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> void b1(volatile T &);
1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> void b2(volatile T * const *);
1426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> void b2(volatile T * const S::*);
1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> void b2(volatile T * const S::* const *);
1446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  // FIXME: This diagnostic isn't very good. The problem is not substitution failure.
1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> void b2a(volatile T *S::* const *); // expected-note {{substitution failure}}
1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> struct Base {};
1486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct Derived : Base<int> {};
1496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> void b3(Base<T>);
1506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> void b3(Base<T> *);
1516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void test(int n, const int cn, int **p, int *S::*pm) {
1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    int *a[3], *S::*am[3];
1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    const Derived cd = Derived();
1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    Derived d[3];
1566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b1(n);
1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b1(cn);
1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b2(p);
1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b2(pm);
1616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b2(a);
1626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b2(am);
1636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b2a(am); // expected-error {{no matching function}}
1646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b3(d);
1656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    b3(cd);
1666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr524 { // dr524: yes
1706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template<typename T> void f(T a, T b) { operator+(a, b); } // expected-error {{call}}
1716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  struct S {};
1736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void operator+(S, S);
1746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template void f(S, S);
1756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  namespace N { struct S {}; }
1776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void operator+(N::S, N::S); // expected-note {{should be declared}}
1786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  template void f(N::S, N::S); // expected-note {{instantiation}}
1796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
1806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesnamespace dr525 { // dr525: yes
1826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  namespace before {
1836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // Note, the example was correct prior to the change; instantiation is
1846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    // required for cases like this:
1856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    template <class T> struct D { operator T*(); };
1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    void g(D<double> ppp) {
1876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      delete ppp;
1886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
1896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  namespace after {
1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    template <class T> struct D { typename T::error e; }; // expected-error {{prior to '::'}}
1926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    void g(D<double> *ppp) {
1936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      delete ppp; // expected-note {{instantiation of}}
1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    }
1956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  }
1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines}
197ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
198ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// PR8130
199ef8225444452a1486bd721f3285301fe84643b00Stephen Hinesnamespace dr532 { // dr532: 3.5
200ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  struct A { };
201ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
202ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  template<class T> struct B {
203ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    template<class R> int &operator*(R&);
204ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  };
205ef8225444452a1486bd721f3285301fe84643b00Stephen Hines
206ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  template<class T, class R> float &operator*(T&, R&);
207ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  void test() {
208ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    A a;
209ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    B<A> b;
210ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    int &ir = b * a;
211ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  }
212ef8225444452a1486bd721f3285301fe84643b00Stephen Hines}
213