diff options
Diffstat (limited to 'test/SemaCXX/return-noreturn.cpp')
-rw-r--r-- | test/SemaCXX/return-noreturn.cpp | 99 |
1 files changed, 85 insertions, 14 deletions
diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp index 53ed0d724527..e06ba403efec 100644 --- a/test/SemaCXX/return-noreturn.cpp +++ b/test/SemaCXX/return-noreturn.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code +// RUN: %clang_cc1 %s -fsyntax-only -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code // A destructor may be marked noreturn and should still influence the CFG. void pr6884_abort() __attribute__((noreturn)); @@ -8,23 +9,93 @@ struct pr6884_abort_struct { ~pr6884_abort_struct() __attribute__((noreturn)) { pr6884_abort(); } }; -int pr6884_f(int x) { - switch (x) { default: pr6884_abort(); } -} +struct other { ~other() {} }; -int pr6884_g(int x) { - switch (x) { default: pr6884_abort_struct(); } -} +// Ensure that destructors from objects are properly modeled in the CFG despite +// the presence of switches, case statements, labels, and blocks. These tests +// try to cover bugs reported in both PR6884 and PR10063. +namespace abort_struct_complex_cfgs { + int basic(int x) { + switch (x) { default: pr6884_abort(); } + } + int f1(int x) { + switch (x) default: pr6884_abort_struct(); + } + int f2(int x) { + switch (x) { default: pr6884_abort_struct(); } + } + int f2_positive(int x) { + switch (x) { default: ; } + } // expected-warning {{control reaches end of non-void function}} + int f3(int x) { + switch (x) { default: { pr6884_abort_struct(); } } + } + int f4(int x) { + switch (x) default: L1: L2: case 4: pr6884_abort_struct(); + } + int f5(int x) { + switch (x) default: L1: { L2: case 4: pr6884_abort_struct(); } + } + int f6(int x) { + switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); } + } -int pr6884_g_positive(int x) { - switch (x) { default: ; } -} // expected-warning {{control reaches end of non-void function}} + // Test that these constructs work even when extraneous blocks are created + // before and after the switch due to implicit destructors. + int g1(int x) { + other o; + switch (x) default: pr6884_abort_struct(); + } + int g2(int x) { + other o; + switch (x) { default: pr6884_abort_struct(); } + } + int g2_positive(int x) { + other o; + switch (x) { default: ; } + } // expected-warning {{control reaches end of non-void function}} + int g3(int x) { + other o; + switch (x) { default: { pr6884_abort_struct(); } } + } + int g4(int x) { + other o; + switch (x) default: L1: L2: case 4: pr6884_abort_struct(); + } + int g5(int x) { + other o; + switch (x) default: L1: { L2: case 4: pr6884_abort_struct(); } + } + int g6(int x) { + other o; + switch (x) default: L1: L2: case 4: { pr6884_abort_struct(); } + } -int pr6884_h(int x) { - switch (x) { - default: { - pr6884_abort_struct a; - } + // Test that these constructs work even with variables carrying the no-return + // destructor instead of temporaries. + int h1(int x) { + other o; + switch (x) default: pr6884_abort_struct a; + } + int h2(int x) { + other o; + switch (x) { default: pr6884_abort_struct a; } + } + int h3(int x) { + other o; + switch (x) { default: { pr6884_abort_struct a; } } + } + int h4(int x) { + other o; + switch (x) default: L1: L2: case 4: pr6884_abort_struct a; + } + int h5(int x) { + other o; + switch (x) default: L1: { L2: case 4: pr6884_abort_struct a; } + } + int h6(int x) { + other o; + switch (x) default: L1: L2: case 4: { pr6884_abort_struct a; } } } |