summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorRamsay Jones <ramsay@ramsayjones.plus.com>2018-11-18 23:52:23 +0000
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-11-23 02:45:45 +0100
commitfdf8252f312a40df9aa51c6e30c0d07fa29ebd12 (patch)
treee77718158645c681cd8fc54bd85da457b446aa29
parentcb777d34218842a12ebc3eac9baba3e6fbbd7e13 (diff)
downloadsparse-fdf8252f312a40df9aa51c6e30c0d07fa29ebd12.tar.gz
constant: add -Wconstant-suffix warning
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 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@ramsayjones.plus.com> Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rwxr-xr-xcgcc2
-rw-r--r--expression.c2
-rw-r--r--lib.c2
-rw-r--r--lib.h1
-rw-r--r--sparse.112
-rw-r--r--validation/constant-suffix-32.c15
-rw-r--r--validation/constant-suffix-64.c15
7 files changed, 47 insertions, 2 deletions
diff --git a/cgcc b/cgcc
index 7611dc9f..736cb704 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 6f4300b9..f955fb15 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 07a5b9cd..5c2059f2 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 cd1af9c4..cde74e93 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 3e135235..64323222 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 00000000..dc063a07
--- /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 00000000..e65706b0
--- /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
+ */
+