[PATCH] constant: add -Wconstant-suffix warning

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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>
---
 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
+ */
+
-- 
2.19.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux