Home | History | Annotate | Line # | Download | only in lint1
gcc_cast_union.c revision 1.2
      1 /*	$NetBSD: gcc_cast_union.c,v 1.2 2021/08/03 21:09:26 rillig Exp $	*/
      2 # 3 "gcc_cast_union.c"
      3 
      4 /*
      5  * Test the GCC extension for casting to a union type.
      6  *
      7  * As of GCC 10.3.0, GCC only prints a generic warning without any details:
      8  *	error: cast to union type from type not present in union
      9  * No idea why it neither mentions the union type nor the actual type.
     10  *
     11  * https://gcc.gnu.org/onlinedocs/gcc/Cast-to-Union.html
     12  */
     13 
     14 /* lint1-extra-flags: -e */
     15 
     16 union anything {
     17 	_Bool m_bool;
     18 	char m_char;
     19 	signed char m_signed_char;
     20 	unsigned char m_unsigned_char;
     21 	short m_short;
     22 	unsigned short m_unsigned_short;
     23 	int m_int;
     24 	unsigned int m_unsigned_int;
     25 	long m_long;
     26 	unsigned long m_unsigned_long;
     27 	long long m_long_long;
     28 	unsigned long long m_unsigned_long_long;
     29 	/* skip __int128_t and __uint128_t for now */
     30 	float m_float;
     31 	double m_double;
     32 	long double m_long_double;
     33 
     34 	struct m_struct {
     35 		int member;
     36 	} m_struct;
     37 	union m_union {
     38 		int member;
     39 	} m_union;
     40 	enum m_enum1 {
     41 		E1
     42 	} m_enum1;
     43 	enum m_enum2 {
     44 		E2
     45 	} m_enum2;
     46 	const char *m_const_char_pointer;
     47 	double m_double_array[5];
     48 	void (*m_function)(void *);
     49 	void (*m_function_varargs)(void *, ...);
     50 	float _Complex m_float_complex;
     51 	double _Complex m_double_complex;
     52 	long double _Complex m_long_double_complex;
     53 };
     54 
     55 enum other_enum {
     56 	OTHER
     57 };
     58 
     59 void
     60 test(void)
     61 {
     62 	union anything any;
     63 
     64 	any = (union anything)(_Bool)0;
     65 	any = (union anything)(char)'\0';
     66 	any = (union anything)(signed char)'\0';
     67 	any = (union anything)(unsigned char)'\0';
     68 	any = (union anything)(short)'\0';
     69 	any = (union anything)(unsigned short)'\0';
     70 	any = (union anything)(int)'\0';
     71 	any = (union anything)(unsigned int)'\0';
     72 	any = (union anything)(long)'\0';
     73 	any = (union anything)(unsigned long)'\0';
     74 	any = (union anything)(long long)'\0';
     75 	any = (union anything)(unsigned long long)'\0';
     76 	any = (union anything)0.0F;
     77 	any = (union anything)0.0;
     78 	any = (union anything)0.0L;
     79 	any = (union anything)(struct m_struct){ 0 };
     80 	any = (union anything)(union m_union){ 0 };
     81 	any = (union anything)E1;
     82 	any = (union anything)E2;
     83 	/* GCC allows enum mismatch even with -Wenum-conversion */
     84 	/* XXX: Lint should warn about enum type mismatch */
     85 	any = (union anything)OTHER;
     86 	/* expect+1: error: type 'pointer to char' is not a member of 'union anything' [329] */
     87 	any = (union anything)"char *";
     88 	any = (union anything)(const char *)"char *";
     89 	/* expect+1: error: type 'pointer to double' is not a member of 'union anything' [329] */
     90 	any = (union anything)(double[5]){ 0.0, 1.0, 2.0, 3.0, 4.0 };
     91 	/* expect+1: error: type 'pointer to double' is not a member of 'union anything' [329] */
     92 	any = (union anything)(double[4]){ 0.0, 1.0, 2.0, 3.0 };
     93 	/* expect+1: error: type 'pointer to int' is not a member of 'union anything' [329] */
     94 	any = (union anything)(int[5]){ 0, 1, 2, 3, 4 };
     95 	any = (union anything)(float _Complex)0.0F;
     96 	any = (union anything)(double _Complex)0.0;
     97 	any = (union anything)(long double _Complex)0.0L;
     98 
     99 	any = any;
    100 }
    101