18e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels// RUN: %clang_cc1 -fsyntax-only -verify %s
28e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
38e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels// Make sure that copy constructors and assignment operators are properly
48e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels// generated when there is a matching
58e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
68e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels// PR5072
78e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstemplate<typename T>
88e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstruct X {
98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  template<typename U>
108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  X(const X<U>& other)
118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    : value(other.value + 1) { } // expected-error{{binary expression}}
128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  template<typename U>
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  X& operator=(const X<U>& other)  {
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    value = other.value + 1; // expected-error{{binary expression}}
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return *this;
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  T value;
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstruct Y {};
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas EckelsX<int Y::*> test0(X<int Y::*> x) { return x; }
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas EckelsX<int> test1(X<long> x) { return x; }
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas EckelsX<int> test2(X<int Y::*> x) {
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return x; // expected-note{{instantiation}}
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid test3(X<int> &x, X<int> xi, X<long> xl, X<int Y::*> xmptr) {
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  x = xi;
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  x = xl;
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  x = xmptr; // expected-note{{instantiation}}
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstruct X1 {
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  X1 &operator=(const X1&);
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstemplate<typename T>
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstruct X2 : X1 {
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  template<typename U> X2 &operator=(const U&);
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstruct X3 : X2<int> {
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid test_X2(X3 &to, X3 from) {
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  to = from;
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels