1 /* PR c/80731 - poor -Woverflow warnings, missing detail 2 { dg-do compile } 3 { dg-options "-Wconversion -Woverflow -Wno-override-init -std=c99" } 4 { dg-require-effective-target int32plus } */ 5 6 #include <limits.h> 7 8 struct Types 9 { 10 signed char sc; 11 unsigned char uc; 12 signed short ss; 13 unsigned short us; 14 signed int si; 15 unsigned int ui; 16 signed long sl; 17 unsigned long ul; 18 signed long long sll; 19 unsigned long long ull; 20 }; 21 22 const struct Types t1 = { 23 /* According to 6.3.1.3 of C11: 24 -2- Otherwise, if the new type is unsigned, the value is converted 25 by repeatedly adding or subtracting one more than the maximum 26 value that can be represented in the new type until the value 27 is in the range of the new type. 28 29 These conversions are diagnosed by -Wsign-conversion and -Wconversion, 30 respectively, by mentioning "unsigned conversion" if the conversion 31 results in sign change, and just "conversion" otherwise, as follows: */ 32 33 .uc = SCHAR_MIN, /* { dg-warning "unsigned conversion from .int. to .unsigned char. changes value from .-128. to .128." } */ 34 .uc = -1, /* { dg-warning "unsigned conversion from .int. to .unsigned char. changes value from .-1. to .255." } */ 35 36 .uc = UCHAR_MAX + 1, /* { dg-warning "conversion from 'int' to 'unsigned char' changes value from .256. to .0." } */ 37 .uc = UCHAR_MAX * 2, /* { dg-warning "conversion from 'int' to 'unsigned char' changes value from .510. to .254." } */ 38 39 /* According to 6.3.1.3 of C11: 40 -3- Otherwise, the new type is signed and the value cannot be 41 represented in it; either the result is implementation-defined 42 or an implementation-defined signal is raised. 43 44 In GCC such conversions wrap and are diagnosed by mentioning "overflow" 45 if the absolute value of the operand is in excess of the maximum of 46 the destination of type, and "conversion" otherwise, as follows: */ 47 48 .sc = SCHAR_MAX + 1, /* { dg-warning "conversion from .int. to .signed char. changes value from .128. to .-128." } */ 49 .sc = SCHAR_MAX + 2, /* { dg-warning "conversion from .int. to .signed char. changes value from .129. to .-127." } */ 50 .sc = SCHAR_MAX * 2, /* { dg-warning "conversion from .int. to .signed char. changes value from .254. to .-2." } */ 51 .sc = SCHAR_MAX * 2 + 3, /* { dg-warning "conversion from .int. to .signed char. changes value from .257. to .1." } */ 52 .sc = SCHAR_MAX * 3 + 3, /* { dg-warning "conversion from .int. to .signed char. changes value from .384. to .-128." } */ 53 54 55 .ss = SHRT_MAX + 1, /* { dg-warning "conversion from 'int' to 'short int' changes value from .32768. to .-32768." } */ 56 .us = USHRT_MAX + 1, /* { dg-warning "unsigned conversion from .int. to .short unsigned int. changes value from .65536. to .0." } */ 57 58 .si = INT_MAX + 1LU, /* { dg-warning "signed conversion from 'long unsigned int. to 'int' changes value from .2147483648. to .-2147483648." } */ 59 .ui = UINT_MAX + 1L, /* { dg-warning "signed conversion from .long int. to .unsigned int. changes value from .4294967296. to .0." "lp64" { target lp64 } } */ 60 .ui = UINT_MAX + 1LU, /* { dg-warning "conversion from .long unsigned int. to .unsigned int. changes value from .4294967296. to .0." "lp64" { target lp64 } } */ 61 62 .sl = LONG_MAX + 1LU, /* { dg-warning "signed conversion from .long unsigned int. to .long int. changes value from .9223372036854775808. to .-9223372036854775808." "lp64" { target lp64 } } */ 63 /* { dg-warning "signed conversion from .long unsigned int. to .long int. changes value from .2147483648. to .-2147483648." "ilp32" { target ilp32 } .-1 } */ 64 .ul = ULONG_MAX + 1LU /* there should be some warning here */ 65 }; 66