2012-02-03 09:49:51 +08:00
|
|
|
// RUN: %clang %s -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -Xclang -verify -fblocks -Wno-unreachable-code -Wno-unused-value
|
2009-05-01 00:01:26 +08:00
|
|
|
|
|
|
|
// 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}}
|
|
|
|
}
|
|
|
|
|
2009-05-01 01:53:16 +08:00
|
|
|
void t15() {
|
|
|
|
return 1; // expected-warning {{void function 't15' should not return a value}}
|
|
|
|
}
|
2009-07-23 07:56:57 +08:00
|
|
|
|
|
|
|
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}}
|
|
|
|
|
2010-09-03 08:25:02 +08:00
|
|
|
int halt3() __attribute__((noreturn));
|
2009-07-23 07:56:57 +08:00
|
|
|
|
|
|
|
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;
|
2009-07-26 05:26:53 +08:00
|
|
|
void (*fptr)() __attribute__((noreturn));
|
2009-07-23 07:56:57 +08:00
|
|
|
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;
|
2009-07-26 05:26:53 +08:00
|
|
|
case 6:
|
|
|
|
fptr();
|
|
|
|
break;
|
2009-07-23 07:56:57 +08:00
|
|
|
default:
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
done: ;
|
|
|
|
}
|
2009-07-27 08:44:23 +08:00
|
|
|
|
2009-07-27 12:49:58 +08:00
|
|
|
// PR4624
|
2009-07-27 08:44:23 +08:00
|
|
|
void test28() __attribute__((noreturn));
|
|
|
|
void test28(x) { while (1) { } }
|
2009-07-28 03:14:18 +08:00
|
|
|
|
|
|
|
void exit(int);
|
|
|
|
int test29() {
|
|
|
|
exit(1);
|
|
|
|
}
|
2009-07-28 05:33:40 +08:00
|
|
|
|
2013-04-17 00:10:38 +08:00
|
|
|
// Include these declarations here explicitly so we don't depend on system headers.
|
|
|
|
typedef struct __jmp_buf_tag{} jmp_buf[1];
|
|
|
|
|
|
|
|
extern void longjmp (struct __jmp_buf_tag __env[1], int __val) __attribute__ ((noreturn));
|
|
|
|
extern void _longjmp (struct __jmp_buf_tag __env[1], int __val) __attribute__ ((noreturn));
|
|
|
|
|
2009-07-28 05:33:40 +08:00
|
|
|
jmp_buf test30_j;
|
2013-04-17 00:10:38 +08:00
|
|
|
|
2009-07-28 05:33:40 +08:00
|
|
|
int test30() {
|
2009-07-28 05:45:16 +08:00
|
|
|
if (j)
|
|
|
|
longjmp(test30_j, 1);
|
|
|
|
else
|
2010-10-19 09:17:08 +08:00
|
|
|
#if defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
|
2009-10-29 08:10:42 +08:00
|
|
|
longjmp(test30_j, 2);
|
|
|
|
#else
|
2009-07-28 05:45:16 +08:00
|
|
|
_longjmp(test30_j, 1);
|
2009-10-29 08:10:42 +08:00
|
|
|
#endif
|
2009-07-28 05:33:40 +08:00
|
|
|
}
|
2009-07-28 06:25:19 +08:00
|
|
|
|
|
|
|
typedef void test31_t(int status);
|
|
|
|
void test31(test31_t *callback __attribute__((noreturn)));
|
2009-07-29 07:11:12 +08:00
|
|
|
|
|
|
|
void test32() {
|
|
|
|
^ (void) { while (1) { } }();
|
|
|
|
^ (void) { if (j) while (1) { } }();
|
|
|
|
while (1) { }
|
|
|
|
}
|
|
|
|
|
|
|
|
void test33() {
|
|
|
|
if (j) while (1) { }
|
|
|
|
}
|
2010-03-23 08:13:23 +08:00
|
|
|
|
|
|
|
// Test that 'static inline' functions are only analyzed for CFG-based warnings
|
|
|
|
// when they are used.
|
2010-04-09 02:51:47 +08:00
|
|
|
static inline int si_has_missing_return() {} // expected-warning{{control reaches end of non-void function}}
|
2010-03-23 08:13:23 +08:00
|
|
|
static inline int si_has_missing_return_2() {}; // expected-warning{{control reaches end of non-void function}}
|
2010-03-23 09:37:12 +08:00
|
|
|
static inline int si_forward();
|
2010-03-23 08:13:23 +08:00
|
|
|
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) {
|
2010-03-23 09:37:12 +08:00
|
|
|
si_forward();
|
2010-03-23 08:13:23 +08:00
|
|
|
return x ? si_has_missing_return_2() : si_has_missing_return_3(x);
|
|
|
|
}
|
2010-03-23 09:37:12 +08:00
|
|
|
static inline int si_forward() {} // expected-warning{{control reaches end of non-void function}}
|
2010-03-23 08:13:23 +08:00
|
|
|
|
2010-07-14 14:36:18 +08:00
|
|
|
// 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}}
|
2011-02-24 02:51:59 +08:00
|
|
|
char* const volatile restrict ignored_cvr_quals(); // expected-warning{{'const volatile restrict' type qualifiers on return type have no effect}}
|
2010-09-09 08:06:07 +08:00
|
|
|
|
2013-03-28 11:27:52 +08:00
|
|
|
typedef const int CI;
|
|
|
|
CI ignored_quals_typedef();
|
|
|
|
|
|
|
|
const CI ignored_quals_typedef_2(); // expected-warning{{'const' type qualifier}}
|
|
|
|
|
2010-09-09 08:06:07 +08:00
|
|
|
// 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
|
2012-03-22 07:30:30 +08:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
}
|