summaryrefslogtreecommitdiffstats
path: root/test/CXX/dcl.dcl/dcl.spec/dcl.typedef/p2-0x.cpp
blob: 0ff40bccef9f0f128d46cd84f172ff04e67406a6 (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// RUN: %clang_cc1 -verify -std=c++11 %s

namespace RedeclAliasTypedef {
  typedef int T;
  using T = int;
  using T = int;
  typedef T T;
  using T = T;
  typedef int T;
}

namespace IllegalTypeIds {
  using A = void(int n = 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}}
  using B = inline void(int n); // expected-error {{type name does not allow function specifier}}
  using C = virtual void(int n); // expected-error {{type name does not allow function specifier}}
  using D = explicit void(int n); // expected-error {{type name does not allow function specifier}}
  using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}}
  // FIXME: this is illegal; we incorrectly accept it for typedefs too.
  using F = void(*)(int n) &&; // expected-err
  using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}}

  using H = void(int n); // ok
  using I = void(int n) &&; // ok
}

namespace IllegalSyntax {
  using ::T = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
  using operator int = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
  using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}}
  using typename ::V = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
  using typename ::operator bool = void(int n); // expected-error {{name defined in alias declaration must be an identifier}}
}

namespace VariableLengthArrays {
  using T = int[42]; // ok

  int n = 32;
  using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}}

  const int m = 42;
  using U = int[m]; // expected-note {{previous definition}}
  using U = int[42]; // ok
  using U = int; // expected-error {{type alias redefinition with different types ('int' vs 'int [42]')}}

  void f() {
    int n = 42;
    goto foo; // expected-error {{goto into protected scope}}
    using T = int[n]; // expected-note {{bypasses initialization of VLA type alias}}
  foo: ;
  }
}

namespace RedeclFunc {
  int f(int, char**);
  using T = int;
  T f(int, char **); // ok
}

namespace LookupFilter {
  namespace N { struct S; }
  using namespace N;
  using S = S*; // ok
}

namespace InFunctions {
  template<typename...T> void f0() {
    using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
    U u;
  }
  template void f0<int, char>();

  void f1() {
    using T = int;
  }
  void f2() {
    using T = int[-1]; // expected-error {{array size is negative}}
  }

  template<typename...T> void f3() { // expected-note {{template parameter is declared here}}
    using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
  }
}

namespace ClassNameRedecl {
  class C0 {
    // FIXME: this diagnostic is pretty poor
    using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}}
  };
  class C1 {
    // FIXME: this diagnostic is pretty poor
    using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}}
  };
  class C2 {
    using C0 = C1; // ok
  };
  template<typename...T> class C3 {
    using f = T; // expected-error {{declaration type contains unexpanded parameter pack 'T'}}
  };
  template<typename T> class C4 { // expected-note {{template parameter is declared here}}
    using T = int; // expected-error {{declaration of 'T' shadows template parameter}}
  };
  class C5 {
    class c; // expected-note {{previous definition}}
    using c = int; // expected-error {{typedef redefinition with different types}}
    class d;
    using d = d; // ok
  };
  class C6 {
    class c { using C6 = int; }; // ok
  };
}

class CtorDtorName {
  using X = CtorDtorName;
  X(); // expected-error {{expected member name}}
  ~X(); // expected-error {{destructor cannot be declared using a type alias}}
};

namespace TagName {
  using S = struct { int n; };
  using T = class { int n; };
  using U = enum { a, b, c };
  using V = struct V { int n; };
}

namespace CWG1044 {
  // FIXME: this is terrible. one error is plenty.
  using T = T; // expected-error {{type name requires a specifier}} \
                  expected-error {{C++ requires a type specifier}} \
                  expected-error {{expected ';' after alias declaration}}
}

namespace StdExample {
  template<typename T, typename U> struct pair;

  using handler_t = void (*)(int);
  extern handler_t ignore;
  extern void (*ignore)(int);
  // FIXME: we know we're parsing a type here; don't recover as if we were
  // using operator*.
  using cell = pair<void*, cell*>; // expected-error {{use of undeclared identifier 'cell'}} \
                                      expected-error {{expected expression}}
}

namespace Access {
  class C0 {
    using U = int; // expected-note {{declared private here}}
  };
  C0::U v; // expected-error {{'U' is a private member}}
  class C1 {
  public:
    using U = int;
  };
  C1::U w; // ok
}

namespace VoidArg {
  using V = void;
  V f(int); // ok
  V g(V); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}}
}