diff options
author | Nico Weber <nicolasweber@gmx.de> | 2017-08-23 15:33:16 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2017-08-23 15:33:16 +0000 |
commit | 7ed95d923631f84fd6679c8b9e32d7d6aca24c8b (patch) | |
tree | 11e46f6eb256ba887adb4a12a65f7230cc352f7d /test/Sema/warn-unreachable-ms.c | |
parent | d2a520ee9ed8f9f67f561bd8e074781cef7a202c (diff) | |
download | clang-7ed95d923631f84fd6679c8b9e32d7d6aca24c8b.tar.gz |
Implement CFG construction for __try / __except / __leave.
This makes -Wunreachable-code work for programs containing SEH (except for
__finally, which is still missing for now).
__try is modeled like try (but simpler since it can only have a single __except
or __finally), __except is fairly similar to catch (but simpler, since it can't
contain declarations). __leave is implemented similarly to break / continue.
Use the existing addTryDispatchBlock infrastructure (which
FindUnreachableCode() in ReachableCode.cpp uses via cfg->try_blocks_begin()) to
mark things in the __except blocks as reachable.
Re-use TryTerminatedBlock. This means we add EH edges from calls to the __try
block, but not from all other statements. While this is incomplete, it matches
LLVM's SEH codegen support. Also, in practice, BuildOpts.AddEHEdges is always
false in practice from what I can tell, so we never even insert the call EH
edges either.
https://reviews.llvm.org/D36914
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@311561 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Sema/warn-unreachable-ms.c')
-rw-r--r-- | test/Sema/warn-unreachable-ms.c | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/test/Sema/warn-unreachable-ms.c b/test/Sema/warn-unreachable-ms.c new file mode 100644 index 0000000000..421415e932 --- /dev/null +++ b/test/Sema/warn-unreachable-ms.c @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fsyntax-only -verify -fms-extensions -Wunreachable-code + +void f(); + +void g1() { + __try { + f(); + __leave; + f(); // expected-warning{{will never be executed}} + } __except(1) { + f(); + } + + // Completely empty. + __try { + } __except(1) { + } + + __try { + f(); + return; + } __except(1) { // Filter expression should not be marked as unreachable. + // Empty __except body. + } +} + +void g2() { + __try { + // Nested __try. + __try { + f(); + __leave; + f(); // expected-warning{{will never be executed}} + } __except(2) { + } + f(); + __leave; + f(); // expected-warning{{will never be executed}} + } __except(1) { + f(); + } +} + +void g3() { + __try { + __try { + f(); + } __except (1) { + __leave; // should exit outer try + } + __leave; + f(); // expected-warning{{never be executed}} + } __except (1) { + } +} |