295 lines · cpp
1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify=expected,precxx17 %std_cxx98-14 %s2// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %std_cxx17- %s3 4struct A; // expected-note 4 {{forward declaration of 'A'}}5 6struct Abstract { virtual void f() = 0; }; // expected-note {{unimplemented pure virtual method 'f'}}7 8void trys() {9 int k = 42;10 try {11 } catch(int i) { // expected-note {{previous definition}}12 int j = i;13 int i; // expected-error {{redefinition of 'i'}}14 } catch(float i) {15 } catch(void v) { // expected-error {{cannot catch incomplete type 'void'}}16 } catch(A a) { // expected-error {{cannot catch incomplete type 'A'}}17 } catch(A *a) { // expected-error {{cannot catch pointer to incomplete type 'A'}}18 } catch(A &a) { // expected-error {{cannot catch reference to incomplete type 'A'}}19 } catch(Abstract) { // expected-error {{variable type 'Abstract' is an abstract class}}20 } catch(...) {21 int ref = k;22 {23 int ref = k;24 }25 int j = i; // expected-error {{use of undeclared identifier 'i'}}26 }27 28 try {29 } catch(...) { // expected-error {{catch-all handler must come last}}30 } catch(int) {31 }32}33 34void throws() {35 throw;36 throw 0;37 throw throw; // expected-error {{cannot throw object of incomplete type 'void'}}38 throw (A*)0; // expected-error {{cannot throw pointer to object of incomplete type 'A'}}39}40 41void jumps() {42l1:43 goto l5;44 goto l4; // expected-error {{cannot jump}}45 goto l3; // expected-error {{cannot jump}}46 goto l2; // expected-error {{cannot jump}}47 goto l1;48 try { // expected-note 4 {{jump bypasses initialization of try block}}49 l2:50 goto l5;51 goto l4; // expected-error {{cannot jump}}52 goto l3; // expected-error {{cannot jump}}53 goto l2;54 goto l1;55 } catch(int) { // expected-note 4 {{jump bypasses initialization of catch block}}56 l3:57 goto l5;58 goto l4; // expected-error {{cannot jump}}59 goto l3;60 goto l2; // expected-error {{cannot jump}}61 goto l1;62 } catch(...) { // expected-note 4 {{jump bypasses initialization of catch block}}63 l4:64 goto l5;65 goto l4;66 goto l3; // expected-error {{cannot jump}}67 goto l2; // expected-error {{cannot jump}}68 goto l1;69 }70l5:71 goto l5;72 goto l4; // expected-error {{cannot jump}}73 goto l3; // expected-error {{cannot jump}}74 goto l2; // expected-error {{cannot jump}}75 goto l1;76}77 78struct BadReturn {79 BadReturn() try {80 } catch(...) {81 // Try to hide82 try {83 } catch(...) {84 {85 if (0)86 return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}87 }88 }89 }90 BadReturn(int);91};92 93BadReturn::BadReturn(int) try {94} catch(...) {95 // Try to hide96 try {97 } catch(int) {98 return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}99 } catch(...) {100 {101 if (0)102 return; // expected-error {{return in the catch of a function try block of a constructor is illegal}}103 }104 }105}106 107// Cannot throw an abstract type.108class foo {109public:110 foo() {}111 void bar () {112 throw *this; // expected-error{{cannot throw an object of abstract type 'foo'}}113 }114 virtual void test () = 0; // expected-note{{unimplemented pure virtual method 'test'}}115};116 117namespace PR6831 {118 namespace NA { struct S; }119 namespace NB { struct S; }120 121 void f() {122 using namespace NA;123 using namespace NB;124 try {125 } catch (int S) {126 }127 }128}129 130#if __cplusplus < 201703L131namespace Decay {132 struct A {133 void f() throw (A[10]);134 };135 136 template<typename T> struct B {137 void f() throw (B[10]);138 };139 template struct B<int>;140 141 void f() throw (int[10], int(*)());142 void f() throw (int*, int());143 144 template<typename T> struct C {145 void f() throw (T);146#if __cplusplus <= 199711L147 // expected-error@-2 {{pointer to incomplete type 'Decay::E' is not allowed in exception specification}}148#endif149 };150 struct D {151 C<D[10]> c;152 };153 struct E;154#if __cplusplus <= 199711L155 // expected-note@-2 {{forward declaration of 'Decay::E'}}156#endif157 158 C<E[10]> e;159#if __cplusplus <= 199711L160 // expected-note@-2 {{in instantiation of template class 'Decay::C<Decay::E[10]>' requested here}}161#endif162}163 164void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}}165#if __cplusplus <= 199711L166// expected-warning@-2 {{rvalue references are a C++11 extension}}167#endif168#endif169 170namespace HandlerInversion {171struct B {};172struct D : B {};173struct D2 : D {};174 175void f1() {176 try {177 } catch (B &b) { // expected-note {{for type 'B &'}}178 } catch (D &d) { // expected-warning {{exception of type 'D &' will be caught by earlier handler}}179 }180}181 182void f2() {183 try {184 } catch (B *b) { // expected-note {{for type 'B *'}}185 } catch (D *d) { // expected-warning {{exception of type 'D *' will be caught by earlier handler}}186 }187}188 189void f3() {190 try {191 } catch (D &d) { // Ok192 } catch (B &b) {193 }194}195 196void f4() {197 try {198 } catch (B &b) { // Ok199 }200}201 202void f5() {203 try {204 } catch (int) {205 } catch (float) {206 }207}208 209void f6() {210 try {211 } catch (B &b) { // expected-note {{for type 'B &'}}212 } catch (D2 &d) { // expected-warning {{exception of type 'D2 &' will be caught by earlier handler}}213 }214}215 216void f7() {217 try {218 } catch (B *b) { // Ok219 } catch (D &d) { // Ok220 }221 222 try {223 } catch (B b) { // Ok224 } catch (D *d) { // Ok225 }226}227 228void f8() {229 try {230 } catch (const B &b) { // expected-note {{for type 'const B &'}}231 } catch (D2 &d) { // expected-warning {{exception of type 'D2 &' will be caught by earlier handler}}232 }233 234 try {235 } catch (B &b) { // expected-note {{for type 'B &'}}236 } catch (const D2 &d) { // expected-warning {{exception of type 'const D2 &' will be caught by earlier handler}}237 }238 239 try {240 } catch (B b) { // expected-note {{for type 'B'}}241 } catch (D &d) { // expected-warning {{exception of type 'D &' will be caught by earlier handler}}242 }243}244}245 246namespace ConstVolatileThrow {247struct S {248 S() {} // precxx17-note{{candidate constructor not viable}}249 S(const S &s); // precxx17-note{{candidate constructor not viable}}250};251 252typedef const volatile S CVS;253 254void f() {255 throw CVS(); // precxx17-error{{no matching constructor for initialization}}256}257}258 259namespace ConstVolatileCatch {260struct S {261 S() {}262 S(const volatile S &s);263 264private:265 S(const S &s); // expected-note {{declared private here}}266};267 268void f();269 270void g() {271 try {272 f();273 } catch (volatile S s) { // expected-error {{calling a private constructor}}274 }275}276}277 278namespace PR28047 {279void test1(int i) { // expected-note {{declared here}}280 try {281 } catch (int(*)[i]) { // expected-error{{cannot catch variably modified type}} \282 expected-warning {{variable length arrays in C++ are a Clang extension}} \283 expected-note {{function parameter 'i' with unknown value cannot be used in a constant expression}}284 }285}286void test2() {287 int i; // expected-note {{declared here}}288 try {289 } catch (int(*)[i]) { // expected-error{{cannot catch variably modified type}} \290 expected-warning {{variable length arrays in C++ are a Clang extension}} \291 expected-note {{read of non-const variable 'i' is not allowed in a constant expression}}292 }293}294}295