1 1.6 rillig /* $NetBSD: expr_cast.c,v 1.6 2024/06/08 13:50:47 rillig Exp $ */ 2 1.1 rillig # 3 "expr_cast.c" 3 1.1 rillig 4 1.1 rillig /* 5 1.1 rillig * Tests for value conversion using a cast-expression. 6 1.1 rillig * 7 1.1 rillig * K&R C does not mention any restrictions on the target type. 8 1.1 rillig * C90 requires both the source type and the target type to be scalar. 9 1.2 rillig * 10 1.2 rillig * GCC allows casting to a struct type but there is no documentation about 11 1.2 rillig * it at https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html. See 12 1.2 rillig * c-typeck.c, function build_c_cast, RECORD_OR_UNION_TYPE_P. 13 1.1 rillig */ 14 1.1 rillig 15 1.4 rillig /* lint1-flags: -Sw -X 351 */ 16 1.2 rillig 17 1.1 rillig struct S { 18 1.1 rillig int member; 19 1.1 rillig }; 20 1.1 rillig 21 1.1 rillig struct S 22 1.1 rillig cast(void) 23 1.1 rillig { 24 1.1 rillig struct S { 25 1.1 rillig double incompatible; 26 1.1 rillig } local = { 27 1.1 rillig 0.0 28 1.1 rillig }; 29 1.1 rillig 30 1.2 rillig /* expect+2: error: invalid cast from 'struct S' to 'struct S' [147] */ 31 1.5 rillig /* expect+1: error: function 'cast' expects to return value [214] */ 32 1.1 rillig return (struct S)local; 33 1.1 rillig } 34 1.6 rillig 35 1.6 rillig /* 36 1.6 rillig * https://gnats.netbsd.org/22119 37 1.6 rillig * 38 1.6 rillig * Before 2021-02-28, lint crashed in cast() since the target type of the 39 1.6 rillig * cast is NULL. 40 1.6 rillig */ 41 1.6 rillig void 42 1.6 rillig cast_from_error(void) 43 1.6 rillig { 44 1.6 rillig void (*f1)(void); 45 1.6 rillig 46 1.6 rillig /* expect+1: error: 'p' undefined [99] */ 47 1.6 rillig f1 = (void (*)(void))p; 48 1.6 rillig /* expect+2: error: function returns illegal type 'function(void) returning pointer to void' [15] */ 49 1.6 rillig /* expect+1: error: invalid cast from 'int' to 'function() returning pointer to function(void) returning pointer to void' [147] */ 50 1.6 rillig f1 = (void *()(void))p; /* crash before 2021-02-28 */ 51 1.6 rillig } 52 1.6 rillig 53 1.6 rillig /* 54 1.6 rillig * Pointer casts had been valid lvalues in GCC before 4.0. 55 1.6 rillig * 56 1.6 rillig * https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Lvalues.html#Lvalues 57 1.6 rillig * 58 1.6 rillig * C99 6.5.4 "Cast operators" footnote 85 says "A cast does not yield an 59 1.6 rillig * lvalue". 60 1.6 rillig */ 61 1.6 rillig 62 1.6 rillig void take_ptr(const void *); 63 1.6 rillig 64 1.6 rillig void * 65 1.6 rillig lvalue_cast(void *p) 66 1.6 rillig { 67 1.6 rillig struct str { 68 1.6 rillig int member; 69 1.6 rillig }; 70 1.6 rillig 71 1.6 rillig /* expect+2: error: a cast does not yield an lvalue [163] */ 72 1.6 rillig /* expect+1: error: left operand of '=' must be lvalue [114] */ 73 1.6 rillig ((struct str *)p) = 0; 74 1.6 rillig 75 1.6 rillig /* expect+2: error: a cast does not yield an lvalue [163] */ 76 1.6 rillig /* expect+1: error: operand of '&' must be lvalue [114] */ 77 1.6 rillig take_ptr(&(const void *)p); 78 1.6 rillig 79 1.6 rillig return p; 80 1.6 rillig } 81