aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/access.cpp
blob: 50f2eff87bfb46784932f6d19b127180269ac2d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s

class C {
    struct S; // expected-note {{previously declared 'private' here}}
public:
    
    struct S {}; // expected-error {{'S' redeclared with 'public' access}}
};

struct S {
    class C; // expected-note {{previously declared 'public' here}}
    
private:
    class C { }; // expected-error {{'C' redeclared with 'private' access}}
};

class T {
protected:
    template<typename T> struct A; // expected-note {{previously declared 'protected' here}}
    
private:
    template<typename T> struct A {}; // expected-error {{'A' redeclared with 'private' access}}
};

// PR5573
namespace test1 {
  class A {
  private:
    class X; // expected-note {{previously declared 'private' here}}
  public:
    class X; // expected-error {{'X' redeclared with 'public' access}}
    class X {};
  };
}

// PR15209
namespace PR15209 {
  namespace alias_templates {
    template<typename T1, typename T2> struct U { };
    template<typename T1> using W = U<T1, float>;

    class A {
      typedef int I;
      static constexpr I x = 0; // expected-note {{implicitly declared private here}}
      static constexpr I y = 42; // expected-note {{implicitly declared private here}}
      friend W<int>;
    };

    template<typename T1>
    struct U<T1, float>  {
      int v_;
      // the following will trigger for U<float, float> instantiation, via W<float>
      U() : v_(A::x) { } // expected-error {{'x' is a private member of 'PR15209::alias_templates::A'}}
    };

    template<typename T1>
    struct U<T1, int> {
      int v_;
      U() : v_(A::y) { } // expected-error {{'y' is a private member of 'PR15209::alias_templates::A'}}
    };

    template struct U<int, int>; // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<int, int>::U' requested here}}

    void f()
    {
      W<int>();
      // we should issue diagnostics for the following
      W<float>(); // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<float, float>::U' requested here}}
    }
  }

  namespace templates {
    class A {
      typedef int I;  // expected-note {{implicitly declared private here}}
      static constexpr I x = 0; // expected-note {{implicitly declared private here}}

      template<int> friend struct B;
      template<int> struct C;
      template<template<int> class T> friend struct TT;
      template<typename T> friend void funct(T);
    };
    template<A::I> struct B { };

    template<A::I> struct A::C { };

    template<template<A::I> class T> struct TT {
      T<A::x> t;
    };

    template struct TT<B>;
    template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::templates::A'}}
    template struct TT<D>;

    // function template case
    template<typename T>
    void funct(T)
    {
      (void)A::x;
    }

    template void funct<int>(int);

    void f()
    {
      (void)A::x;  // expected-error {{'x' is a private member of 'PR15209::templates::A'}}
    }
  }
}