Home | History | Annotate | Line # | Download | only in lint1
      1 /*	$NetBSD: msg_217.c,v 1.17 2025/04/12 15:49:50 rillig Exp $	*/
      2 # 3 "msg_217.c"
      3 
      4 // Test for message: function '%s' falls off bottom without returning value [217]
      5 
      6 /* lint1-extra-flags: -X 351 */
      7 
      8 int
      9 random(int n)
     10 {
     11 	if (n < 0)
     12 		return -3;
     13 }
     14 /* expect-1: warning: function 'random' falls off bottom without returning value [217] */
     15 
     16 /*
     17  * The pattern 'do { } while (0)' is often used in statement macros.
     18  * Putting a 'return' at the end of such a macro is legitimate, the embracing
     19  * 'do { } while (0)' is probably there to conform to a coding standard or
     20  * to otherwise reduce confusion.
     21  *
     22  * Seen in external/bsd/libevent/dist/event_tagging.c, function
     23  * encode_int_internal.
     24  *
     25  * Before tree.c 1.243 from 2021-03-21, lint wrongly reported that the
     26  * 'while 0' was unreachable.  This has been fixed by allowing the 'while 0'
     27  * in a do-while-false loop to be unreachable.  The same could be useful for a
     28  * do-while-true.
     29  *
     30  * Before func.c 1.83 from 2021-03-21, lint wrongly reported that the function
     31  * would fall off the bottom.
     32  */
     33 int
     34 do_while_return(int i)
     35 {
     36 	do {
     37 		return i;
     38 	} while (0);
     39 }
     40 
     41 /*
     42  * C99 5.1.2.2.3 "Program termination" p1 defines that as a special exception,
     43  * the function 'main' does not have to return a value, reaching the bottom
     44  * is equivalent to returning 0.
     45  *
     46  * Before func.c 1.72 from 2021-02-21, lint had wrongly warned about this.
     47  */
     48 int
     49 main(void)
     50 {
     51 }
     52 
     53 int
     54 reachable_continue_leads_to_endless_loop(void)
     55 {
     56 	for (;;) {
     57 		if (1)
     58 			continue;
     59 		break;
     60 	}
     61 }
     62 
     63 int
     64 unreachable_continue_falls_through(void)
     65 {
     66 	for (;;) {
     67 		if (0)
     68 			/* expect+1: warning: 'continue' statement not reached [193] */
     69 			continue;
     70 		break;
     71 	}
     72 }
     73 /* expect-1: warning: function 'unreachable_continue_falls_through' falls off bottom without returning value [217] */
     74 
     75 
     76 _Noreturn void noreturn_c11(void);
     77 [[noreturn]] void noreturn_c23(void);
     78 __attribute__((__noreturn__)) void noreturn_gnu_prefix(void);
     79 void __attribute__((__noreturn__)) noreturn_gnu_infix(void);
     80 void noreturn_gnu_suffix(void) __attribute__((__noreturn__));
     81 
     82 int
     83 call_noreturn_c11(void)
     84 {
     85 	noreturn_c11();
     86 }
     87 
     88 inline int
     89 call_noreturn_c23(void)
     90 {
     91 	noreturn_c23();
     92 }
     93 
     94 int
     95 call_noreturn_gnu_prefix(void)
     96 {
     97 	noreturn_gnu_prefix();
     98 }
     99 
    100 int
    101 call_noreturn_gnu_infix(void)
    102 {
    103 	noreturn_gnu_infix();
    104 }
    105 
    106 int
    107 call_noreturn_gnu_suffix(void)
    108 {
    109 	noreturn_gnu_suffix();
    110 }
    111 
    112 
    113 double *force_function_attributes_in_diagnostic[] = {
    114 	// Force the word 'noreturn' to occur in a diagnostic.
    115 	/* expect+1: warning: invalid combination of 'pointer to double' and 'pointer to noreturn function(void) returning void', op 'init' [124] */
    116 	noreturn_c23,
    117 	// The 'inline' does affect the type of the function.
    118 	/* expect+1: warning: invalid combination of 'pointer to double' and 'pointer to function(void) returning int', op 'init' [124] */
    119 	call_noreturn_c23,
    120 };
    121