problem with signedness of PSEUDO_VALs

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

 



PSEUDO_VALs have no associated signedness (and more generally, no
type associated with them). This is generally not a problem but
in some circonstances it is.

Add a description of the problem and a testcase.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 Documentation/Problems.txt  | 32 ++++++++++++++++++++++++++++++++
 validation/shift-negative.c | 18 ++++++++++++++++++
 2 files changed, 50 insertions(+)
 create mode 100644 Documentation/Problems.txt
 create mode 100644 validation/shift-negative.c

diff --git a/Documentation/Problems.txt b/Documentation/Problems.txt
new file mode 100644
index 000000000..f9fbbd28c
--- /dev/null
+++ b/Documentation/Problems.txt
@@ -0,0 +1,32 @@
+signedness (and type) of PSEUDO_VAL
+-----------------------------------
+It is currently impossible, after linearization, to determine
+if a constant is negative or not.
+
+Before linearization, these values are handled as expressions
+which always have a type associated with them. It is thus easy
+to get the corresponding size & signedness.
+
+This is not true anymore after linearization. PSEUDO_VALs are
+created from EXPR_VALs without any conversion (sign-extension)
+and have no type directly attached to them. If a type is needed
+it must be retrieved from some context, like the type of the
+instruction using them. This is fine for most instructions,
+for example OP_ADD, where the type of both operands and of
+the result must all be the same but this is not the case for:
+* comparison instructions:
+	both operands should have the same type but the type
+	of the result is independent of the operands' type.
+* shift instructions:
+	the type of the result must be the same as the type
+	of the left operand but the type of the right operand
+	is independent.
+
+
+A possible solution for the signedness would be, during
+linearization and simplification, to keep values fully sign-
+extended (currently, '(int) -1' is stored as 0x00000000ffffffff,
+not 0xffffffffffffffff) but the consequences must be investigated.
+
+Another solution would be to add to struct instruction a field for
+the type of these now-untyped operands (like 'orig_type' for casts).
diff --git a/validation/shift-negative.c b/validation/shift-negative.c
new file mode 100644
index 000000000..033a51a85
--- /dev/null
+++ b/validation/shift-negative.c
@@ -0,0 +1,18 @@
+unsigned char fn1(unsigned char a) { return a >> -1; }
+unsigned char fn2(unsigned char a) { return a >> ~0; }
+
+unsigned char fo1(unsigned char a) { return a >> ((a & 0) | -1); }
+unsigned char fo2(unsigned char a) { return a >> ((a & 0) ^ ~0); }
+
+/*
+ * check-name: shift-negative
+ * check-command: sparse -Wno-decl $file
+ * check-known-to-fail
+ *
+ * check-error-start
+shift-negative.c:1:47: warning: shift is negative (-1)
+shift-negative.c:2:47: warning: shift is negative (-1)
+shift-negative.c:4:61: warning: shift is negative (-1)
+shift-negative.c:5:61: warning: shift is negative (-1)
+ * check-error-end
+ */
-- 
2.18.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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