On 22/11/2018 13:44, Luc Van Oostenryck wrote: > From: Ramsay Jones <ramsay@xxxxxxxxxxxxxxxxxxxx> > > Currently, when used on the kernel, sparse issues a bunch > of warnings like: > warning: constant 0x100000000 is so big it is long > > These warning are issued because when there is a discrepancy > between the type as indicated by the suffix (or the absence > of a suffix) and the real type as selected by the type > suffix *and* the value of the constant. > > Since there is nothing incorrect with this discrepancy, > (no bits are lost) these warnings are more annoying than useful. > So, make them depending on a new warning flag -Wconstant-suffix > and make it off by default. > > Signed-off-by: Ramsay Jones <ramsay@xxxxxxxxxxxxxxxxxxxx> > Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> Looks *very* good to me! :-D Thanks for doing that. ATB, Ramsay Jones > --- > cgcc | 2 +- > expression.c | 2 +- > lib.c | 2 ++ > lib.h | 1 + > sparse.1 | 12 ++++++++++++ > validation/constant-suffix-32.c | 15 +++++++++++++++ > validation/constant-suffix-64.c | 15 +++++++++++++++ > 7 files changed, 47 insertions(+), 2 deletions(-) > create mode 100644 validation/constant-suffix-32.c > create mode 100644 validation/constant-suffix-64.c > > diff --git a/cgcc b/cgcc > index 7611dc9ff..736cb704c 100755 > --- a/cgcc > +++ b/cgcc > @@ -101,7 +101,7 @@ exit 0; > > sub check_only_option { > my ($arg) = @_; > - return 1 if $arg =~ /^-W(no-?)?(address-space|bitwise|cast-to-as|cast-truncate|context|decl|default-bitfield-sign|designated-init|do-while|enum-mismatch|init-cstring|memcpy-max-count|non-pointer-null|old-initializer|one-bit-signed-bitfield|override-init-all|paren-string|ptr-subtraction-blows|return-void|sizeof-bool|sparse-all|sparse-error|transparent-union|typesign|undef|unknown-attribute)$/; > + return 1 if $arg =~ /^-W(no-?)?(address-space|bitwise|cast-to-as|cast-truncate|constant-suffix|context|decl|default-bitfield-sign|designated-init|do-while|enum-mismatch|init-cstring|memcpy-max-count|non-pointer-null|old-initializer|one-bit-signed-bitfield|override-init-all|paren-string|ptr-subtraction-blows|return-void|sizeof-bool|sparse-all|sparse-error|transparent-union|typesign|undef|unknown-attribute)$/; > return 1 if $arg =~ /^-v(no-?)?(entry|dead)$/; > return 1 if $arg =~ /^-f(dump-ir|memcpy-max-count|diagnostic-prefix)(=\S*)?$/; > return 1 if $arg =~ /^-f(mem2reg|optim)(-enable|-disable|=last)?$/; > diff --git a/expression.c b/expression.c > index 6f4300b9a..f955fb159 100644 > --- a/expression.c > +++ b/expression.c > @@ -324,7 +324,7 @@ static void get_number_value(struct expression *expr, struct token *token) > show_token(token)); > want_unsigned = 1; > got_it: > - if (do_warn) > + if (do_warn && Wconstant_suffix) > warning(expr->pos, "constant %s is so big it is%s%s%s", > show_token(token), > want_unsigned ? " unsigned":"", > diff --git a/lib.c b/lib.c > index 07a5b9cda..5c2059f23 100644 > --- a/lib.c > +++ b/lib.c > @@ -251,6 +251,7 @@ int Wbitwise = 1; > int Wcast_from_as = 0; > int Wcast_to_as = 0; > int Wcast_truncate = 1; > +int Wconstant_suffix = 0; > int Wconstexpr_not_const = 0; > int Wcontext = 1; > int Wdecl = 1; > @@ -686,6 +687,7 @@ static const struct flag warnings[] = { > { "cast-from-as", &Wcast_from_as }, > { "cast-to-as", &Wcast_to_as }, > { "cast-truncate", &Wcast_truncate }, > + { "constant-suffix", &Wconstant_suffix }, > { "constexpr-not-const", &Wconstexpr_not_const}, > { "context", &Wcontext }, > { "decl", &Wdecl }, > diff --git a/lib.h b/lib.h > index cd1af9c4a..cde74e93e 100644 > --- a/lib.h > +++ b/lib.h > @@ -141,6 +141,7 @@ extern int Wbitwise; > extern int Wcast_from_as; > extern int Wcast_to_as; > extern int Wcast_truncate; > +extern int Wconstant_suffix; > extern int Wconstexpr_not_const; > extern int Wcontext; > extern int Wdecl; > diff --git a/sparse.1 b/sparse.1 > index 3e1352352..64323222b 100644 > --- a/sparse.1 > +++ b/sparse.1 > @@ -101,6 +101,18 @@ Sparse issues these warnings by default. To turn them off, use > \fB\-Wno\-cast\-truncate\fR. > . > .TP > +.B \-Wconstant\-suffix > +Warn if an integer constant is larger than the maximum representable value > +of the type indicated by its type suffix (if any). For example, on a > +system where ints are 32-bit and longs 64-bit, the constant \fB0x100000000U\fR > +is larger than can be represented by an \fBunsigned int\fR but fits in an > +\fBunsigned long\fR. So its type is \fBunsigned long\fR but this is not > +indicated by its suffix. In this case, the warning could be suppressed by > +using the suffix \fBUL\fR: \fB0x100000000UL\fR. > + > +Sparse does not issue these warnings by default. > +. > +.TP > .B \-Wconstexpr-not-const > Warn if a non-constant expression is encountered when really expecting a > constant expression instead. > diff --git a/validation/constant-suffix-32.c b/validation/constant-suffix-32.c > new file mode 100644 > index 000000000..dc063a079 > --- /dev/null > +++ b/validation/constant-suffix-32.c > @@ -0,0 +1,15 @@ > +#define BIGU 0xfffff00000000000U > +#define BIGULL 0xfffff00000000000ULL > + > +static unsigned long long a = BIGU; > +static unsigned long long b = BIGULL; > + > +/* > + * check-name: constant-suffix > + * check-command: sparse -m32 -Wconstant-suffix $file > + * > + * check-error-start > +constant-suffix-32.c:4:31: warning: constant 0xfffff00000000000U is so big it is unsigned long long > + * check-error-end > + */ > + > diff --git a/validation/constant-suffix-64.c b/validation/constant-suffix-64.c > new file mode 100644 > index 000000000..e65706b02 > --- /dev/null > +++ b/validation/constant-suffix-64.c > @@ -0,0 +1,15 @@ > +#define BIGU 0xfffff00000000000U > +#define BIGUL 0xfffff00000000000UL > + > +static unsigned long a = BIGU; > +static unsigned long b = BIGUL; > + > +/* > + * check-name: constant-suffix > + * check-command: sparse -m64 -Wconstant-suffix $file > + * > + * check-error-start > +constant-suffix-64.c:4:26: warning: constant 0xfffff00000000000U is so big it is unsigned long > + * check-error-end > + */ > + >