diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2016-11-23 18:21:42 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2016-11-23 18:21:42 +0000 |
commit | e8d54d1380b7882d7aad84edd2c7b94585125fb6 (patch) | |
tree | c7dfc1bc5f41477c59f9bdd3cbe4bf9d61e5c6b1 /test | |
parent | d0024e5b25235eb27ef668e1933c289864e008c4 (diff) |
Merging r281797:
------------------------------------------------------------------------
r281797 | richard-llvm | 2016-09-16 16:30:39 -0700 (Fri, 16 Sep 2016) | 10 lines
Fix a couple of wrong-code bugs in switch-on-constant optimization:
* recurse through intermediate LabelStmts and AttributedStmts when checking
whether a statement inside a switch declares a variable
* if the end of a compound statement is reachable from the chosen case label,
and the compound statement contains a variable declaration, it's not valid
to just emit the contents of the compound statement -- we must emit the
statement itself or we lose the scope (and thus end lifetimes at the wrong
point)
------------------------------------------------------------------------
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_39@287790 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/CodeGenCXX/switch-case-folding-2.cpp | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/test/CodeGenCXX/switch-case-folding-2.cpp b/test/CodeGenCXX/switch-case-folding-2.cpp index 558ca3c87d..cfb8447ee3 100644 --- a/test/CodeGenCXX/switch-case-folding-2.cpp +++ b/test/CodeGenCXX/switch-case-folding-2.cpp @@ -1,12 +1,14 @@ // RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s -// CHECK that we don't crash. extern int printf(const char*, ...); + +// CHECK-LABEL: @_Z4testi( int test(int val){ switch (val) { case 4: do { switch (6) { + // CHECK: call i32 (i8*, ...) @_Z6printfPKcz case 6: do { case 5: printf("bad\n"); } while (0); }; } while (0); @@ -18,6 +20,7 @@ int main(void) { return test(5); } +// CHECK-LABEL: @_Z10other_testv( void other_test() { switch(0) { case 0: @@ -27,4 +30,79 @@ void other_test() { } } -// CHECK: call i32 (i8*, ...) @_Z6printfPKcz +struct X { X(); ~X(); }; + +void dont_call(); +void foo(); + +// CHECK-LABEL: @_Z13nested_scopesv( +void nested_scopes() { + switch (1) { + case 0: + // CHECK-NOT: @_Z9dont_callv( + dont_call(); + break; + + default: + // CHECK: call {{.*}} @_ZN1XC1Ev( + // CHECK: call {{.*}} @_Z3foov( + // CHECK-NOT: call {{.*}} @_Z3foov( + // CHECK: call {{.*}} @_ZN1XD1Ev( + { X x; foo(); } + + // CHECK: call {{.*}} @_ZN1XC1Ev( + // CHECK: call {{.*}} @_Z3foov( + // CHECK: call {{.*}} @_ZN1XD1Ev( + { X x; foo(); } + + // CHECK: call {{.*}} @_ZN1XC1Ev( + // CHECK: call {{.*}} @_Z3foov( + // CHECK: call {{.*}} @_ZN1XD1Ev( + { X x; foo(); } + break; + } +} + +// CHECK-LABEL: @_Z17scope_fallthroughv( +void scope_fallthrough() { + switch (1) { + // CHECK: call {{.*}} @_ZN1XC1Ev( + // CHECK-NOT: call {{.*}} @_Z3foov( + // CHECK: call {{.*}} @_ZN1XD1Ev( + { default: X x; } + // CHECK: call {{.*}} @_Z3foov( + foo(); + break; + } +} + +// CHECK-LABEL: @_Z12hidden_breakb( +void hidden_break(bool b) { + switch (1) { + default: + // CHECK: br + if (b) + break; + // CHECK: call {{.*}} @_Z3foov( + foo(); + break; + } +} + +// CHECK-LABEL: @_Z10hidden_varv( +int hidden_var() { + switch (1) { + // CHECK: %[[N:.*]] = alloca i32 + case 0: int n; + // CHECK: store i32 0, i32* %[[N]] + // CHECK: load i32, i32* %[[N]] + // CHECK: ret + default: n = 0; return n; + } +} + +// CHECK-LABEL: @_Z13case_in_labelv( +void case_in_label() { + // CHECK: br label % + switch (1) case 1: foo: case 0: goto foo; +} |