llvm-project/clang/test/Parser/objc-try-catch-1.m

71 lines
1.5 KiB
Mathematica
Raw Normal View History

Reapply "[Parse] Use CapturedStmt for @finally on MSVC" This reapplies r334224 and adds explicit triples to some tests to fix them on Windows (where otherwise they would have run with the default windows-msvc triple, which I'm changing the behavior for). Original commit message: The body of a `@finally` needs to be executed on both exceptional and non-exceptional paths. On landingpad platforms, this is straightforward: the `@finally` body is emitted as a normal (non-exceptional) cleanup, and then a catch-all is emitted which branches to that cleanup (the cleanup has code to conditionally re-throw based on a flag which is set by the catch-all). Unfortunately, we can't use the same approach for MSVC exceptions, where the catch-all will be emitted as a catchpad. We can't just branch to the cleanup from within the catchpad, since we can only exit it via a catchret, at which point the exception is destroyed and we can't rethrow. We could potentially emit the finally body inside the catchpad and have the normal cleanup path somehow branch into it, but that would require some new IR construct that could branch into a catchpad. Instead, after discussing it with Reid Kleckner, we decided that frontend outlining was the best approach, similar to how SEH `__finally` works today. We decided to use CapturedStmt (which was also suggested by Reid) rather than CaptureFinder (which is what `__finally` uses) since the latter doesn't handle a lot of cases we care about, e.g. self accesses, property accesses, block captures, etc. Extending CaptureFinder to handle those additional cases proved unwieldy, whereas CapturedStmt already took care of all of those. In theory `__finally` could also be moved over to CapturedStmt, which would remove some existing limitations (e.g. the inability to capture this), although CaptureFinder would still be needed for SEH filters. The one case supported by `@finally` but not CapturedStmt (or CaptureFinder for that matter) is arbitrary control flow out of the `@finally`, e.g. having a return statement inside a `@finally`. We can add that support as a follow-up, but in practice we've found it to be used very rarely anyway. Differential Revision: https://reviews.llvm.org/D47564 llvm-svn: 334251
2018-06-08 08:30:00 +08:00
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -fsyntax-only -verify -fobjc-exceptions %s
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -fsyntax-only -verify -fobjc-exceptions -x objective-c++ %s
void * proc();
@interface NSConstantString
@end
@interface Frob
@end
@interface Frob1
@end
void * foo()
{
@try {
return proc();
}
@catch (Frob* ex) {
@throw;
}
@catch (Frob1* ex) {
@throw proc();
}
@finally {
@try {
return proc();
}
@catch (Frob* ex) {
@throw 1,2; // expected-error {{@throw requires an Objective-C object type ('int' invalid)}} \
// expected-warning {{expression result unused}}
}
@catch (float x) { // expected-error {{@catch parameter is not a pointer to an interface type}}
}
@catch(...) {
@throw (4,3,proc()); // expected-warning {{expression result unused}} \
// expected-warning {{expression result unused}}
}
}
2008-05-23 19:19:39 +08:00
@try { // expected-error {{@try statement without a @catch and @finally clause}}
return proc();
}
}
void bar()
{
2008-05-23 19:19:39 +08:00
@try {}// expected-error {{@try statement without a @catch and @finally clause}}
@"s"; // expected-warning {{result unused}}
}
void baz()
{
2008-05-23 19:19:39 +08:00
@try {}// expected-error {{@try statement without a @catch and @finally clause}}
@try {}
@finally {}
}
void noTwoTokenLookAheadRequiresABitOfFancyFootworkInTheParser() {
@try {
// Do something
} @catch (...) {}
@try {
// Do something
} @catch (...) {}
return;
}