258 lines
5.4 KiB
C
258 lines
5.4 KiB
C
// RUN: %clang %s -fsyntax-only -Wignored-qualifiers -Wreturn-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
|