msg_204.c revision 1.8
1/*	$NetBSD: msg_204.c,v 1.8 2023/03/28 14:44:35 rillig Exp $	*/
2# 3 "msg_204.c"
3
4// Test for message: controlling expressions must have scalar type [204]
5
6/* Suppress messages for unused arguments and for 'extern' declarations. */
7/* lint1-extra-flags: -X 231 -X 351 */
8
9extern void
10extern_function(void);
11
12void (*function_pointer)(void);
13
14/*
15 * Since func.c 1.39 from 2020-12-31 18:51:28, lint had produced an error
16 * when a controlling expression was a function.  Pointers to functions were
17 * ok though.
18 */
19void
20bug_between_2020_12_31_and_2021_01_08(void)
21{
22	if (extern_function)
23		extern_function();
24
25	/*
26	 * FIXME: For some reason, the ampersand is discarded in
27	 *  build_address.  This only has a visible effect if the
28	 *  t_spec in check_controlling_expression is evaluated too early,
29	 *  as has been the case before func.c 1.52 from 2021-01-08.
30	 */
31	if (&extern_function)
32		extern_function();
33
34	/* This one has always been ok since pointers are scalar types. */
35	if (function_pointer)
36		function_pointer();
37}
38
39struct s {
40	int member;
41};
42
43union u {
44	int member;
45};
46
47enum e {
48	E
49};
50
51struct arr {
52	int arr[4];
53};
54
55/* C99 6.2.5p2 */
56void if_Bool(_Bool b)			{ if (b) return; }
57
58/* C99 6.2.5p3 */
59void if_char(char c)			{ if (c) return; }
60
61/* C99 6.2.5p4 */
62void if_signed_char(signed char sc)	{ if (sc) return; }
63void if_short_int(short s)		{ if (s) return; }
64void if_int(int i)			{ if (i) return; }
65void if_long_int(long int l)		{ if (l) return; }
66void if_long_long_int(long long int ll)	{ if (ll) return; }
67
68/* C99 6.2.5p6 */
69void if_unsigned_char(unsigned char uc)			{ if (uc) return; }
70void if_unsigned_short_int(unsigned short us)		{ if (us) return; }
71void if_unsigned_int(unsigned int ui)			{ if (ui) return; }
72void if_unsigned_long_int(unsigned long int ul)		{ if (ul) return; }
73void if_unsigned_long_long_int(unsigned long long int ull) { if (ull) return; }
74
75/* C99 6.2.5p10 */
76void if_float(float f)			{ if (f) return; }
77void if_double(double d)		{ if (d) return; }
78void if_long_double(long double ld)	{ if (ld) return; }
79
80/* C99 6.2.5p11 */
81void if_float_Complex(float _Complex fc)		{ if (fc) return; }
82void if_double_Complex(double _Complex dc)		{ if (dc) return; }
83void if_long_double_Complex(long double _Complex ldc)	{ if (ldc) return; }
84
85/* C99 6.2.5p16 */
86void if_enum(enum e e)			{ if (e) return; }
87
88/* C99 6.2.5p20 */
89void if_array(struct arr arr)		{ if (arr.arr) return; }
90/* expect+1: error: controlling expressions must have scalar type [204] */
91void if_struct(struct s s)		{ if (s) return; }
92/* expect+1: error: controlling expressions must have scalar type [204] */
93void if_union(union u u)		{ if (u) return; }
94void if_function(void)			{ if (if_function) return; }
95void if_pointer(void *p)		{ if (p) return; }
96
97/* C99 6.8.5 */
98/* expect+1: error: controlling expressions must have scalar type [204] */
99void while_struct(struct s s)		{ while (s) return; }
100/* expect+2: error: controlling expressions must have scalar type [204] */
101/* expect+1: warning: end-of-loop code not reached [223] */
102void for_struct(struct s s)		{ for (;s;) return; }
103/* expect+1: error: controlling expressions must have scalar type [204] */
104void do_while_struct(struct s s)	{ do { return; } while (s); }
105
106/*
107 * C99 6.5.15 for the '?:' operator does not explicitly mention that the
108 * controlling expression must have a scalar type, curiously.
109 */
110/* expect+2: error: first operand must have scalar type, op ? : [170] */
111/* expect+1: warning: function 'conditional_struct' expects to return value [214] */
112int conditional_struct(struct s s)	{ return s ? 1 : 2; }
113