diff options
Diffstat (limited to 'clang/test/Sema/return.c')
-rw-r--r-- | clang/test/Sema/return.c | 266 |
1 files changed, 266 insertions, 0 deletions
diff --git a/clang/test/Sema/return.c b/clang/test/Sema/return.c new file mode 100644 index 0000000..77bd3f6 --- /dev/null +++ b/clang/test/Sema/return.c @@ -0,0 +1,266 @@ +// RUN: %clang %s -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -Xclang -verify -fblocks -Wno-unreachable-code -Wno-unused-value + +// clang emits the following warning by default. +// With GCC, -pedantic, -Wreturn-type or -Wall are required to produce the +// following warning. +int t14() { + return; // expected-warning {{non-void function 't14' should return a value}} +} + +void t15() { + return 1; // expected-warning {{void function 't15' should not return a value}} +} + +int unknown(); + +void test0() { +} + +int test1() { +} // expected-warning {{control reaches end of non-void function}} + +int test2() { + a: goto a; +} + +int test3() { + goto a; + a: ; +} // expected-warning {{control reaches end of non-void function}} + + +void halt() { + a: goto a; +} + +void halt2() __attribute__((noreturn)); + +int test4() { + halt2(); +} + +int test5() { + halt2(), (void)1; +} + +int test6() { + 1, halt2(); +} + +int j; +int unknown_nohalt() { + return j; +} + +int test7() { + unknown(); +} // expected-warning {{control reaches end of non-void function}} + +int test8() { + (void)(1 + unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int halt3() __attribute__((noreturn)); + +int test9() { + (void)(halt3() + unknown()); +} + +int test10() { + (void)(unknown() || halt3()); +} // expected-warning {{control may reach end of non-void function}} + +int test11() { + (void)(unknown() && halt3()); +} // expected-warning {{control may reach end of non-void function}} + +int test12() { + (void)(halt3() || unknown()); +} + +int test13() { + (void)(halt3() && unknown()); +} + +int test14() { + (void)(1 || unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test15() { + (void)(0 || unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test16() { + (void)(0 && unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test17() { + (void)(1 && unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test18() { + (void)(unknown_nohalt() && halt3()); +} // expected-warning {{control may reach end of non-void function}} + +int test19() { + (void)(unknown_nohalt() && unknown()); +} // expected-warning {{control reaches end of non-void function}} + +int test20() { + int i; + if (i) + return 0; + else if (0) + return 2; +} // expected-warning {{control may reach end of non-void function}} + +int test21() { + int i; + if (i) + return 0; + else if (1) + return 2; +} + +int test22() { + int i; + switch (i) default: ; +} // expected-warning {{control reaches end of non-void function}} + +int test23() { + int i; + switch (i) { + case 0: + return 0; + case 2: + return 2; + } +} // expected-warning {{control may reach end of non-void function}} + +int test24() { + int i; + switch (i) { + case 0: + return 0; + case 2: + return 2; + default: + return -1; + } +} + +int test25() { + 1 ? halt3() : unknown(); +} + +int test26() { + 0 ? halt3() : unknown(); +} // expected-warning {{control reaches end of non-void function}} + +int j; +void (*fptr)() __attribute__((noreturn)); +int test27() { + switch (j) { + case 1: + do { } while (1); + break; + case 2: + for (;;) ; + break; + case 3: + for (;1;) ; + for (;0;) { + goto done; + } + return 1; + case 4: + while (0) { goto done; } + return 1; + case 5: + while (1) { return 1; } + break; + case 6: + fptr(); + break; + default: + return 1; + } + done: ; +} + +// PR4624 +void test28() __attribute__((noreturn)); +void test28(x) { while (1) { } } + +void exit(int); +int test29() { + exit(1); +} + +#include <setjmp.h> +jmp_buf test30_j; +int test30() { + if (j) + longjmp(test30_j, 1); + else +#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) + longjmp(test30_j, 2); +#else + _longjmp(test30_j, 1); +#endif +} + +typedef void test31_t(int status); +void test31(test31_t *callback __attribute__((noreturn))); + +void test32() { + ^ (void) { while (1) { } }(); + ^ (void) { if (j) while (1) { } }(); + while (1) { } +} + +void test33() { + if (j) while (1) { } +} + +// Test that 'static inline' functions are only analyzed for CFG-based warnings +// when they are used. +static inline int si_has_missing_return() {} // expected-warning{{control reaches end of non-void function}} +static inline int si_has_missing_return_2() {}; // expected-warning{{control reaches end of non-void function}} +static inline int si_forward(); +static inline int si_has_missing_return_3(int x) { + if (x) + return si_has_missing_return_3(x+1); +} // expected-warning{{control may reach end of non-void function}} + +int test_static_inline(int x) { + si_forward(); + return x ? si_has_missing_return_2() : si_has_missing_return_3(x); +} +static inline int si_forward() {} // expected-warning{{control reaches end of non-void function}} + +// Test warnings on ignored qualifiers on return types. +const int ignored_c_quals(); // expected-warning{{'const' type qualifier on return type has no effect}} +const volatile int ignored_cv_quals(); // expected-warning{{'const volatile' type qualifiers on return type have no effect}} +char* const volatile restrict ignored_cvr_quals(); // expected-warning{{'const volatile restrict' type qualifiers on return type have no effect}} + +// Test that for switch(enum) that if the switch statement covers all the cases +// that we don't consider that for -Wreturn-type. +enum Cases { C1, C2, C3, C4 }; +int test_enum_cases(enum Cases C) { + switch (C) { + case C1: return 1; + case C2: return 2; + case C4: return 3; + case C3: return 4; + } +} // no-warning + +// PR12318 - Don't give a may reach end of non-void function warning. +int test34(int x) { + if (x == 1) { + return 3; + } else if ( x == 2 || 1) { + return 5; + } +} |