2012-05-04 02:27:39 +08:00
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wimplicit-fallthrough %s
int fallthrough ( int n ) {
switch ( n / 10 ) {
if ( n - 1 ) {
n = 100 ;
} else if ( n - 2 ) {
n = 101 ;
} else if ( n - 3 ) {
n = 102 ;
}
2013-01-30 11:49:44 +08:00
case - 1 : // no warning here, ignore fall-through from unreachable code
2012-05-04 02:27:39 +08:00
;
case 0 : { // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
}
case 1 : // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
n + = 100 ;
case 3 : // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
if ( n > 0 )
n + = 200 ;
case 4 : // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
if ( n < 0 )
;
case 5 : // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
switch ( n ) {
case 111 :
break ;
case 112 :
break ;
case 113 :
break ;
}
case 6 : // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
n + = 300 ;
2012-05-26 08:49:15 +08:00
case 66 : // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert 'break;' to avoid fall-through}}
2013-01-25 23:49:34 +08:00
case 67 :
case 68 :
2012-05-26 08:49:15 +08:00
break ;
2012-05-04 02:27:39 +08:00
}
2013-01-26 04:44:56 +08:00
switch ( n / 15 ) {
2013-01-30 11:49:44 +08:00
label_default :
default :
2013-01-26 04:44:56 +08:00
n + = 333 ;
2013-01-30 11:49:44 +08:00
if ( n % 10 )
goto label_default ;
2013-01-26 04:44:56 +08:00
break ;
2013-01-30 11:49:44 +08:00
case 70 :
2013-01-26 04:44:56 +08:00
n + = 335 ;
break ;
}
2012-05-04 02:27:39 +08:00
switch ( n / 20 ) {
case 7 :
n + = 400 ;
[[clang::fallthrough]] ;
case 9 : // no warning here, intended fall-through marked with an attribute
n + = 800 ;
[[clang::fallthrough]] ;
default : { // no warning here, intended fall-through marked with an attribute
if ( n % 2 = = 0 ) {
return 1 ;
} else {
[[clang::fallthrough]] ;
}
}
case 10 : // no warning here, intended fall-through marked with an attribute
if ( n % 3 = = 0 ) {
n % = 3 ;
} else {
[[clang::fallthrough]] ;
}
case 110 : // expected-warning{{unannotated fall-through between switch labels}} but no fix-it hint as we have one fall-through annotation!
n + = 800 ;
}
switch ( n / 30 ) {
case 11 :
case 12 : // no warning here, intended fall-through, no statement between labels
n + = 1600 ;
}
switch ( n / 40 ) {
case 13 :
if ( n % 2 = = 0 ) {
return 1 ;
} else {
return 2 ;
}
case 15 : // no warning here, there's no fall-through
n + = 3200 ;
}
switch ( n / 50 ) {
case 17 : {
if ( n % 2 = = 0 ) {
return 1 ;
} else {
return 2 ;
}
}
case 19 : { // no warning here, there's no fall-through
n + = 6400 ;
return 3 ;
}
case 21 : { // no warning here, there's no fall-through
break ;
}
case 23 : // no warning here, there's no fall-through
n + = 128000 ;
break ;
case 25 : // no warning here, there's no fall-through
break ;
}
return n ;
}
class ClassWithDtor {
public :
~ ClassWithDtor ( ) { }
} ;
void fallthrough2 ( int n ) {
switch ( n ) {
case 0 :
{
ClassWithDtor temp ;
break ;
}
default : // no warning here, there's no fall-through
break ;
}
}
2013-01-30 11:49:44 +08:00
void fallthrough3 ( int n ) {
switch ( n ) {
case 1 :
do {
return ;
} while ( 0 ) ;
case 2 :
do {
ClassWithDtor temp ;
return ;
} while ( 0 ) ;
case 3 :
break ;
}
}
2012-05-04 02:27:39 +08:00
# define MY_SWITCH(X, Y, Z, U, V) switch (X) { case Y: Z; case U: V; }
# define MY_SWITCH2(X, Y, Z) switch (X) { Y; Z; }
# define MY_CASE(X, Y) case X: Y
# define MY_CASE2(X, Y, U, V) case X: Y; case U: V
int fallthrough_macro1 ( int n ) {
MY_SWITCH ( n , 13 , n * = 2 , 14 , break ) // expected-warning{{unannotated fall-through between switch labels}}
switch ( n + 1 ) {
MY_CASE ( 33 , n + = 2 ) ;
MY_CASE ( 44 , break ) ; // expected-warning{{unannotated fall-through between switch labels}}
MY_CASE ( 55 , n + = 3 ) ;
}
switch ( n + 3 ) {
MY_CASE ( 333 , return 333 ) ;
MY_CASE2 ( 444 , n + = 44 , 4444 , break ) ; // expected-warning{{unannotated fall-through between switch labels}}
MY_CASE ( 555 , n + = 33 ) ;
}
MY_SWITCH2 ( n + 4 , MY_CASE ( 17 , n * = 3 ) , MY_CASE ( 19 , break ) ) // expected-warning{{unannotated fall-through between switch labels}}
MY_SWITCH2 ( n + 5 , MY_CASE ( 21 , break ) , MY_CASE2 ( 23 , n * = 7 , 25 , break ) ) // expected-warning{{unannotated fall-through between switch labels}}
return n ;
}
2013-02-01 23:39:20 +08:00
void fallthrough_cfgblock_with_null_successor ( int x ) {
( x & & " " ) ? ( void ) ( 0 ) : ( void ) ( 1 ) ;
switch ( x ) { }
}
2012-05-04 02:27:39 +08:00
int fallthrough_position ( int n ) {
switch ( n ) {
2013-02-07 10:17:19 +08:00
[[clang::fallthrough]] ; // expected-warning{{fallthrough annotation does not directly precede switch label}}
n + = 300 ;
2012-05-04 02:27:39 +08:00
[[clang::fallthrough]] ; // expected-warning{{fallthrough annotation in unreachable code}}
case 221 :
2013-02-07 10:17:19 +08:00
[[clang::fallthrough]] ; // expected-warning{{fallthrough annotation does not directly precede switch label}}
2012-05-04 02:27:39 +08:00
return 1 ;
[[clang::fallthrough]] ; // expected-warning{{fallthrough annotation in unreachable code}}
case 222 :
2013-02-07 10:17:19 +08:00
[[clang::fallthrough]] ; // expected-warning{{fallthrough annotation does not directly precede switch label}}
2012-05-04 02:27:39 +08:00
n + = 400 ;
case 223 : // expected-warning{{unannotated fall-through between switch labels}} expected-note{{insert '[[clang::fallthrough]];' to silence this warning}} expected-note{{insert 'break;' to avoid fall-through}}
[[clang::fallthrough]] ; // expected-warning{{fallthrough annotation does not directly precede switch label}}
}
2012-06-21 05:12:23 +08:00
long p = static_cast < long > ( n ) * n ;
switch ( sizeof ( p ) ) {
2013-02-07 10:17:19 +08:00
case 9 :
2012-06-21 05:12:23 +08:00
n + = static_cast < int > ( p > > 32 ) ;
[[clang::fallthrough]] ; // no warning here
2013-02-07 10:17:19 +08:00
case 5 :
2012-06-21 05:12:23 +08:00
n + = static_cast < int > ( p ) ;
2013-02-07 10:17:19 +08:00
[[clang::fallthrough]] ; // no warning here
2012-06-21 05:12:23 +08:00
default :
2013-02-07 10:17:19 +08:00
n + = 1 ;
break ;
2012-06-21 05:12:23 +08:00
}
2012-05-04 02:27:39 +08:00
return n ;
}
2013-02-07 10:17:19 +08:00
enum Enum {
Value1 , Value2
} ;
int fallthrough_covered_enums ( Enum e ) {
int n = 0 ;
switch ( e ) {
default :
n + = 17 ;
[[clang::fallthrough]] ; // no warning here, this shouldn't be treated as unreachable code
case Value1 :
n + = 19 ;
break ;
case Value2 :
n + = 21 ;
break ;
}
return n ;
}
2012-05-04 02:27:39 +08:00
int fallthrough_targets ( int n ) {
[[clang::fallthrough]] ; // expected-error{{fallthrough annotation is outside switch statement}}
[[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}}
switch ( n ) {
case 121 :
n + = 400 ;
[[clang::fallthrough]] ; // no warning here, correct target
case 123 :
[[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}}
n + = 800 ;
break ;
[[clang::fallthrough]] // expected-error{{fallthrough attribute is only allowed on empty statements}} expected-note{{did you forget ';'?}}
case 125 :
n + = 1600 ;
}
return n ;
}
2013-04-03 01:55:01 +08:00
// Fallthrough annotations in local classes used to generate "fallthrough
// annotation does not directly precede switch label" warning.
void fallthrough_in_local_class ( ) {
class C {
void f ( int x ) {
switch ( x ) {
case 0 :
x + + ;
[[clang::fallthrough]] ; // no diagnostics
case 1 :
x + + ;
break ;
}
}
} ;
}