p1.cpp revision 7ad650f88ecbbe659f10f9f6b34a1f29ea9cf8f9
1// RUN: %clang_cc1 -faccess-control -verify -emit-llvm-only %s
2
3template <typename T> struct Num {
4  T value_;
5
6public:
7  Num(T value) : value_(value) {}
8  T get() const { return value_; }
9
10  template <typename U> struct Rep {
11    U count_;
12    Rep(U count) : count_(count) {}
13
14    friend Num operator*(const Num &a, const Rep &n) {
15      Num x = 0;
16      for (U count = n.count_; count; --count)
17        x += a;
18      return x;
19    }
20  };
21
22  friend Num operator+(const Num &a, const Num &b) {
23    return a.value_ + b.value_;
24  }
25
26  Num& operator+=(const Num& b) {
27    value_ += b.value_;
28    return *this;
29  }
30
31  class Representation {};
32  friend class Representation;
33};
34
35class A {
36  template <typename T> friend bool iszero(const A &a) throw();
37};
38
39template <class T> class B_iterator;
40template <class T> class B {
41  friend class B_iterator<T>;
42};
43
44int calc1() {
45  Num<int> left = -1;
46  Num<int> right = 1;
47  Num<int> result = left + right;
48  return result.get();
49}
50
51int calc2() {
52  Num<int> x = 3;
53  Num<int>::Rep<char> n = (char) 10;
54  Num<int> result = x * n;
55  return result.get();
56}
57
58// Reduced from GNU <locale>
59namespace test1 {
60  class A {
61    bool b; // expected-note {{declared private here}}
62    template <typename T> friend bool has(const A&);
63  };
64  template <typename T> bool has(const A &x) {
65    return x.b;
66  }
67  template <typename T> bool hasnot(const A &x) {
68    return x.b; // expected-error {{'b' is a private member of 'test1::A'}}
69  }
70}
71
72namespace test2 {
73  class A {
74    bool b; // expected-note {{declared private here}}
75    template <typename T> friend class HasChecker;
76  };
77  template <typename T> class HasChecker {
78    bool check(A *a) {
79      return a->b;
80    }
81  };
82  template <typename T> class HasNotChecker {
83    bool check(A *a) {
84      return a->b; // expected-error {{'b' is a private member of 'test2::A'}}
85    }
86  };
87}
88
89namespace test3 {
90  class Bool;
91  template <class T> class User;
92  template <class T> T transform(class Bool, T);
93
94  class Bool {
95    friend class User<bool>;
96    friend bool transform<>(Bool, bool);
97
98    bool value; // expected-note 2 {{declared private here}}
99  };
100
101  template <class T> class User {
102    static T compute(Bool b) {
103      return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}}
104    }
105  };
106
107  template <class T> T transform(Bool b, T value) {
108    if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}}
109      return value;
110    return value + 1;
111  }
112
113  template bool transform(Bool, bool);
114  template int transform(Bool, int); // expected-note {{requested here}}
115
116  template class User<bool>;
117  template class User<int>; // expected-note {{requested here}}
118
119}
120