Home | History | Annotate | Line # | Download | only in lint1
gcc_cast_union.c revision 1.1
      1 /*	$NetBSD: gcc_cast_union.c,v 1.1 2021/08/03 20:34:23 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 union anything {
     15 	_Bool m_bool;
     16 	char m_char;
     17 	signed char m_signed_char;
     18 	unsigned char m_unsigned_char;
     19 	short m_short;
     20 	unsigned short m_unsigned_short;
     21 	int m_int;
     22 	unsigned int m_unsigned_int;
     23 	long m_long;
     24 	unsigned long m_unsigned_long;
     25 	long long m_long_long;
     26 	unsigned long long m_unsigned_long_long;
     27 	/* skip __int128_t and __uint128_t for now */
     28 	float m_float;
     29 	double m_double;
     30 	long double m_long_double;
     31 
     32 	struct m_struct {
     33 		int member;
     34 	} m_struct;
     35 	union m_union {
     36 		int member;
     37 	} m_union;
     38 	enum m_enum1 {
     39 		E1
     40 	} m_enum1;
     41 	enum m_enum2 {
     42 		E2
     43 	} m_enum2;
     44 	const char *m_const_char_pointer;
     45 	double m_double_array[5];
     46 	void (*m_function)(void *);
     47 	void (*m_function_varargs)(void *, ...);
     48 	float _Complex m_float_complex;
     49 	double _Complex m_double_complex;
     50 	long double _Complex m_long_double_complex;
     51 };
     52 
     53 enum other_enum {
     54 	OTHER
     55 };
     56 
     57 void
     58 test(void)
     59 {
     60 	union anything any;
     61 
     62 	any = (union anything)(_Bool)0;
     63 	any = (union anything)(char)'\0';
     64 	any = (union anything)(signed char)'\0';
     65 	any = (union anything)(unsigned char)'\0';
     66 	any = (union anything)(short)'\0';
     67 	any = (union anything)(unsigned short)'\0';
     68 	any = (union anything)(int)'\0';
     69 	any = (union anything)(unsigned int)'\0';
     70 	any = (union anything)(long)'\0';
     71 	any = (union anything)(unsigned long)'\0';
     72 	any = (union anything)(long long)'\0';
     73 	any = (union anything)(unsigned long long)'\0';
     74 	any = (union anything)0.0F;
     75 	any = (union anything)0.0;
     76 	any = (union anything)0.0L;
     77 	any = (union anything)(struct m_struct){ 0 };
     78 	any = (union anything)(union m_union){ 0 };
     79 	any = (union anything)E1;
     80 	any = (union anything)E2;
     81 	/* GCC allows enum mismatch even with -Wenum-conversion */
     82 	/* expect+1: error: type 'enum other_enum' is not a member of 'union anything' [329] */
     83 	any = (union anything)OTHER;
     84 	/* GCC strictly complains that 'char *' is not in the union. */
     85 	any = (union anything)"char *";
     86 	any = (union anything)(const char *)"char *";
     87 	/* expect+1: error: type 'pointer to double' is not a member of 'union anything' [329] */
     88 	any = (union anything)(double[5]){ 0.0, 1.0, 2.0, 3.0, 4.0 };
     89 	/* expect+1: error: type 'pointer to double' is not a member of 'union anything' [329] */
     90 	any = (union anything)(double[4]){ 0.0, 1.0, 2.0, 3.0 };
     91 	/* expect+1: error: type 'pointer to int' is not a member of 'union anything' [329] */
     92 	any = (union anything)(int[5]){ 0, 1, 2, 3, 4 };
     93 	any = (union anything)(float _Complex)0.0F;
     94 	any = (union anything)(double _Complex)0.0;
     95 	any = (union anything)(long double _Complex)0.0L;
     96 
     97 	any = any;
     98 }
     99