66 lines
3.7 KiB
C
66 lines
3.7 KiB
C
/* PR c/80731 - poor -Woverflow warnings, missing detail
|
|
{ dg-do compile }
|
|
{ dg-options "-Wconversion -Woverflow -Wno-override-init -std=c99" }
|
|
{ dg-require-effective-target int32plus } */
|
|
|
|
#include <limits.h>
|
|
|
|
struct Types
|
|
{
|
|
signed char sc;
|
|
unsigned char uc;
|
|
signed short ss;
|
|
unsigned short us;
|
|
signed int si;
|
|
unsigned int ui;
|
|
signed long sl;
|
|
unsigned long ul;
|
|
signed long long sll;
|
|
unsigned long long ull;
|
|
};
|
|
|
|
const struct Types t1 = {
|
|
/* According to 6.3.1.3 of C11:
|
|
-2- Otherwise, if the new type is unsigned, the value is converted
|
|
by repeatedly adding or subtracting one more than the maximum
|
|
value that can be represented in the new type until the value
|
|
is in the range of the new type.
|
|
|
|
These conversions are diagnosed by -Wsign-conversion and -Wconversion,
|
|
respectively, by mentioning "unsigned conversion" if the conversion
|
|
results in sign change, and just "conversion" otherwise, as follows: */
|
|
|
|
.uc = SCHAR_MIN, /* { dg-warning "unsigned conversion from .int. to .unsigned char. changes value from .-128. to .128." } */
|
|
.uc = -1, /* { dg-warning "unsigned conversion from .int. to .unsigned char. changes value from .-1. to .255." } */
|
|
|
|
.uc = UCHAR_MAX + 1, /* { dg-warning "conversion from 'int' to 'unsigned char' changes value from .256. to .0." } */
|
|
.uc = UCHAR_MAX * 2, /* { dg-warning "conversion from 'int' to 'unsigned char' changes value from .510. to .254." } */
|
|
|
|
/* According to 6.3.1.3 of C11:
|
|
-3- Otherwise, the new type is signed and the value cannot be
|
|
represented in it; either the result is implementation-defined
|
|
or an implementation-defined signal is raised.
|
|
|
|
In GCC such conversions wrap and are diagnosed by mentioning "overflow"
|
|
if the absolute value of the operand is in excess of the maximum of
|
|
the destination of type, and "conversion" otherwise, as follows: */
|
|
|
|
.sc = SCHAR_MAX + 1, /* { dg-warning "conversion from .int. to .signed char. changes value from .128. to .-128." } */
|
|
.sc = SCHAR_MAX + 2, /* { dg-warning "conversion from .int. to .signed char. changes value from .129. to .-127." } */
|
|
.sc = SCHAR_MAX * 2, /* { dg-warning "conversion from .int. to .signed char. changes value from .254. to .-2." } */
|
|
.sc = SCHAR_MAX * 2 + 3, /* { dg-warning "conversion from .int. to .signed char. changes value from .257. to .1." } */
|
|
.sc = SCHAR_MAX * 3 + 3, /* { dg-warning "conversion from .int. to .signed char. changes value from .384. to .-128." } */
|
|
|
|
|
|
.ss = SHRT_MAX + 1, /* { dg-warning "conversion from 'int' to 'short int' changes value from .32768. to .-32768." } */
|
|
.us = USHRT_MAX + 1, /* { dg-warning "unsigned conversion from .int. to .short unsigned int. changes value from .65536. to .0." } */
|
|
|
|
.si = INT_MAX + 1LU, /* { dg-warning "signed conversion from 'long unsigned int. to 'int' changes value from .2147483648. to .-2147483648." } */
|
|
.ui = UINT_MAX + 1L, /* { dg-warning "signed conversion from .long int. to .unsigned int. changes value from .4294967296. to .0." "lp64" { target lp64 } } */
|
|
.ui = UINT_MAX + 1LU, /* { dg-warning "conversion from .long unsigned int. to .unsigned int. changes value from .4294967296. to .0." "lp64" { target lp64 } } */
|
|
|
|
.sl = LONG_MAX + 1LU, /* { dg-warning "signed conversion from .long unsigned int. to .long int. changes value from .9223372036854775808. to .-9223372036854775808." "lp64" { target lp64 } } */
|
|
/* { dg-warning "signed conversion from .long unsigned int. to .long int. changes value from .2147483648. to .-2147483648." "ilp32" { target ilp32 } .-1 } */
|
|
.ul = ULONG_MAX + 1LU /* there should be some warning here */
|
|
};
|