aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/return-noreturn.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/return-noreturn.cpp')
-rw-r--r--test/SemaCXX/return-noreturn.cpp99
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; }
}
}