xref: /aosp_15_r20/external/clang/test/CXX/class/class.mem/p2.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2*67e74705SXin Li 
3*67e74705SXin Li // C++11 [class.mem]p2:
4*67e74705SXin Li //   A class is considered a completely-defined object type (or
5*67e74705SXin Li //   complete type) at the closing } of the class-specifier. Within
6*67e74705SXin Li //   the class member-specification, the class is regarded as complete
7*67e74705SXin Li //   within function bodies, default arguments,
8*67e74705SXin Li //   exception-specifications, and brace-or-equal-initializers for
9*67e74705SXin Li //   non-static data members (including such things in nested classes).
10*67e74705SXin Li //   Otherwise it is regarded as incomplete within its own class
11*67e74705SXin Li //   member-specification.
12*67e74705SXin Li 
13*67e74705SXin Li namespace test0 {
14*67e74705SXin Li   struct A { // expected-note {{definition of 'test0::A' is not complete until the closing '}'}}
15*67e74705SXin Li     A x; // expected-error {{field has incomplete type 'test0::A'}}
16*67e74705SXin Li   };
17*67e74705SXin Li }
18*67e74705SXin Li 
19*67e74705SXin Li namespace test1 {
20*67e74705SXin Li   template <class T> struct A {
21*67e74705SXin Li     A<int> x; // expected-error {{implicit instantiation of template 'test1::A<int>' within its own definition}}
22*67e74705SXin Li   };
23*67e74705SXin Li }
24*67e74705SXin Li 
25*67e74705SXin Li namespace test2 {
26*67e74705SXin Li   template <class T> struct A;
27*67e74705SXin Li   template <> struct A<int> {};
28*67e74705SXin Li   template <class T> struct A {
29*67e74705SXin Li     A<int> x;
30*67e74705SXin Li   };
31*67e74705SXin Li }
32*67e74705SXin Li 
33*67e74705SXin Li namespace test3 {
34*67e74705SXin Li   struct A {
35*67e74705SXin Li     struct B {
36*67e74705SXin Li       void f() throw(A);
37*67e74705SXin Li       void g() throw(B);
38*67e74705SXin Li     };
39*67e74705SXin Li 
40*67e74705SXin Li     void f() throw(A);
41*67e74705SXin Li     void g() throw(B);
42*67e74705SXin Li   };
43*67e74705SXin Li 
44*67e74705SXin Li   template<typename T>
45*67e74705SXin Li   struct A2 {
46*67e74705SXin Li     struct B {
47*67e74705SXin Li       void f1() throw(A2);
48*67e74705SXin Li       void f2() throw(A2<T>);
49*67e74705SXin Li       void g() throw(B);
50*67e74705SXin Li     };
51*67e74705SXin Li 
52*67e74705SXin Li     void f1() throw(A2);
53*67e74705SXin Li     void f2() throw(A2<T>);
54*67e74705SXin Li     void g() throw(B);
55*67e74705SXin Li   };
56*67e74705SXin Li 
57*67e74705SXin Li   template struct A2<int>;
58*67e74705SXin Li }
59*67e74705SXin Li 
60*67e74705SXin Li namespace PR12629 {
61*67e74705SXin Li   struct S {
62*67e74705SXin Li     static int (f)() throw();
63*67e74705SXin Li     static int ((((((g))))() throw(U)));
64*67e74705SXin Li     int (*h)() noexcept(false);
65*67e74705SXin Li     static int (&i)() noexcept(true);
66*67e74705SXin Li     static int (*j)() throw(U); // expected-error {{unknown type name 'U'}}
67*67e74705SXin Li     static int (k)() throw(U);
68*67e74705SXin Li 
69*67e74705SXin Li     struct U {};
70*67e74705SXin Li   };
71*67e74705SXin Li   static_assert(noexcept(S::f()), "");
72*67e74705SXin Li   static_assert(!noexcept(S::g()), "");
73*67e74705SXin Li   static_assert(!noexcept(S().h()), "");
74*67e74705SXin Li   static_assert(noexcept(S::i()), "");
75*67e74705SXin Li }
76*67e74705SXin Li 
77*67e74705SXin Li namespace PR12688 {
78*67e74705SXin Li   struct S {
79*67e74705SXin Li     // FIXME: Maybe suppress the "constructor cannot have a return type" error
80*67e74705SXin Li     // if the return type is invalid.
81*67e74705SXin Li     nonsense S() throw (more_nonsense); // \
82*67e74705SXin Li     // expected-error {{'nonsense'}} \
83*67e74705SXin Li     // expected-error {{constructor cannot have a return type}}
84*67e74705SXin Li   };
85*67e74705SXin Li }
86