diff mbox series

[committed,nvptx] Fix UB in nvptx_assemble_value

Message ID 784148b2-8a3c-5c6f-08cc-957c6e13df1d@suse.de
State New
Headers show
Series [committed,nvptx] Fix UB in nvptx_assemble_value | expand

Commit Message

Tom de Vries Sept. 11, 2020, 5:33 a.m. UTC
[ was: Re: [committed][nvptx] Fix printing of 128-bit constant ]

On 9/10/20 10:26 PM, Jakub Jelinek wrote:
> On Thu, Sep 10, 2020 at 09:31:33PM +0200, Tom de Vries wrote:
>> Currently, for this code from c-c++-common/spec-barrier-1.c:
>> ...
>> __int128 g = 9;
>> ...
>> we generate:
>> ...
>> // BEGIN GLOBAL VAR DEF: g
>> .visible .global .align 8 .u64 g[2] = { 9, 9 };
>> ...
>> and consequently the test-case fails in execution.
>>
>> The problem is caused by a shift in nvptx_assemble_value:
>> ...
>>       val >>= part * BITS_PER_UNIT;
>> ...
>> where the shift amount is equal to the number of bits in val, which is
>> undefined behaviour.
>>
>> Fix this by detecting the situation and setting val to 0.
> 
> Actually, looking more at it, is nvptx_assemble_value called from
> nvptx_assemble_integer with the CONST_INT and size of 16?
> Then
>   val &= ((unsigned  HOST_WIDE_INT)2 << (size * BITS_PER_UNIT - 1)) - 1;
> will invoke UB too (perhaps it can just do:
>   if (size * BITS_PER_UNIT < HOST_BITS_PER_WIDE_INT)
>     val &= HOST_WIDE_INT_1U << (size * BITS_PER_UNIT);
> ?),

Done in patch attached below, committed.

Thanks,
-Tom
diff mbox series

Patch

[nvptx] Fix UB in nvptx_assemble_value

When nvptx_assemble_value is called with size == 16, this bitshift runs
into UB:
...
  val &= ((unsigned  HOST_WIDE_INT)2 << (size * BITS_PER_UNIT - 1)) - 1;
...

Fix this by checking the shift amount.

Tested on nvptx.

gcc/ChangeLog:

	* config/nvptx/nvptx.c (nvptx_assemble_value): Fix undefined
	behaviour.

---
 gcc/config/nvptx/nvptx.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index 4fca0ed76d9..0c590d8d1f6 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -2053,7 +2053,9 @@  nvptx_assemble_value (unsigned HOST_WIDE_INT val, unsigned size)
   bool negative_p
     = val & (HOST_WIDE_INT_1U << (HOST_BITS_PER_WIDE_INT - 1));
 
-  val &= ((unsigned  HOST_WIDE_INT)2 << (size * BITS_PER_UNIT - 1)) - 1;
+  /* Avoid undefined behaviour.  */
+  if (size * BITS_PER_UNIT < HOST_BITS_PER_WIDE_INT)
+    val &= (HOST_WIDE_INT_1U << (size * BITS_PER_UNIT)) - 1;
 
   for (unsigned part = 0; size; size -= part)
     {