[binutils-gdb] ubsan: cr16: left shift cannot be represented in type 'int'

Alan Modra amodra@sourceware.org
Wed Dec 11 01:13:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=0ef562a4b5da6bc1f16b2ea801b228acafd033d8

commit 0ef562a4b5da6bc1f16b2ea801b228acafd033d8
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Dec 10 23:02:37 2019 +1030

    ubsan: cr16: left shift cannot be represented in type 'int'
    
    This was:
      unsigned long mask = SBM (instruction->match_bits);
    with
      #define SBM(offs)  ((((1 << (32 - offs)) -1) << (offs)))
    
    Well, there are a couple of problems.  Firstly, the expression uses
    int values (1 rather than 1u or 1ul) resulting in the ubsan error, and
    secondly, a zero offs will result in a 32-bit shift which is undefined
    if ints are only 32 bits.
    
    	* cr16-dis.c (EXTRACT, SBM): Rewrite.
    	(cr16_match_opcode): Delete duplicate bcond test.

Diff:
---
 opcodes/ChangeLog  |  5 +++++
 opcodes/cr16-dis.c | 11 ++++-------
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index faa160a..57212f8 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,10 @@
 2019-12-11  Alan Modra  <amodra@gmail.com>
 
+	* cr16-dis.c (EXTRACT, SBM): Rewrite.
+	(cr16_match_opcode): Delete duplicate bcond test.
+
+2019-12-11  Alan Modra  <amodra@gmail.com>
+
 	* bfin-dis.c (HOST_LONG_WORD_SIZE, XFIELD): Delete.
 	(SIGNBIT): New.
 	(MASKBITS, SIGNEXTEND): Rewrite.
diff --git a/opcodes/cr16-dis.c b/opcodes/cr16-dis.c
index 65cf91c..68fbe42 100644
--- a/opcodes/cr16-dis.c
+++ b/opcodes/cr16-dis.c
@@ -30,11 +30,11 @@
 
 /* Extract 'n_bits' from 'a' starting from offset 'offs'.  */
 #define EXTRACT(a, offs, n_bits)                    \
-  (n_bits == 32 ? (((a) >> (offs)) & 0xffffffffL)   \
-  : (((a) >> (offs)) & ((1 << (n_bits)) -1)))
+  (((a) >> (offs)) & ((1ul << ((n_bits) - 1) << 1) - 1))
 
-/* Set Bit Mask - a mask to set all bits starting from offset 'offs'.  */
-#define SBM(offs)  ((((1 << (32 - offs)) -1) << (offs)))
+/* Set Bit Mask - a mask to set all bits in a 32-bit word starting
+   from offset 'offs'.  */
+#define SBM(offs)  ((1ul << 31 << 1) - (1ul << (offs)))
 
 typedef struct
 {
@@ -329,9 +329,6 @@ cr16_match_opcode (void)
   while (instruction >= cr16_instruction)
     {
       mask = build_mask ();
-      /* Adjust mask for bcond with 32-bit size instruction */
-      if ((IS_INSN_MNEMONIC("b") && instruction->size == 2))
-        mask = 0xff0f0000;
 
       if ((doubleWord & mask) == BIN (instruction->match,
                                       instruction->match_bits))



More information about the Binutils-cvs mailing list