public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c/108580] New: gcc treats shifts as signed operation, does wrong promotion
@ 2023-01-28  7:42 postmaster at raasu dot org
  2023-01-28  7:53 ` [Bug c/108580] " pinskia at gcc dot gnu.org
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: postmaster at raasu dot org @ 2023-01-28  7:42 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108580

            Bug ID: 108580
           Summary: gcc treats shifts as signed operation, does wrong
                    promotion
           Product: gcc
           Version: 12.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: postmaster at raasu dot org
  Target Milestone: ---

I have a simple program that fails to compile correctly on any common compiler:

int main()
{
   int bits = 8;
   char* a = (char*)malloc(1 << bits);
   char* b = (char*)malloc(1 << bits);
   memcpy(b, a, 1 << bits);
   return 0;
}

when assembled with "gcc -S", the result is

main:
.LFB6:
        .cfi_startproc
        endbr64
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $32, %rsp
        movl    $8, -20(%rbp)
        movl    -20(%rbp), %eax
        movl    $1, %edx
        movl    %eax, %ecx
        sall    %cl, %edx
        movl    %edx, %eax
        cltq
        movq    %rax, %rdi
        call    malloc@PLT
        movq    %rax, -16(%rbp)
        movl    -20(%rbp), %eax
        movl    $1, %edx
        movl    %eax, %ecx
        sall    %cl, %edx
        movl    %edx, %eax
        cltq
        movq    %rax, %rdi
        call    malloc@PLT
        movq    %rax, -8(%rbp)
        movl    -20(%rbp), %eax
        movl    $1, %edx
        movl    %eax, %ecx
        sall    %cl, %edx
        movl    %edx, %eax
        movslq  %eax, %rdx
        movq    -16(%rbp), %rcx
        movq    -8(%rbp), %rax
        movq    %rcx, %rsi
        movq    %rax, %rdi
        call    memcpy@PLT
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc

The part that is incorrect is:

        sall    %cl, %edx
        movl    %edx, %eax
        cltq
        movq    %rax, %rdi

It should zero-extend before the shift, but instead it sign-extends after the
shift... Bit shifting is always unsigned operation. It correctly determines the
function requires 64-bit parameter, but fails to determine it's unsigned.
Integer promotion rules say that unsigned type in expression must be promoted
to larger unsigned type if it can hold the result. As bit shift is unsigned
operation, the temporary should also be unsigned.

Stock gcc headers don't have UINTPTR_C() macro which could be used to
explicitly cast the constant "1" to pointer size to give hint that the shift is
indeed unsigned operation.

gcc version is: gcc (Ubuntu 12.2.0-3ubuntu1) 12.2.0

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-01-28 15:36 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-28  7:42 [Bug c/108580] New: gcc treats shifts as signed operation, does wrong promotion postmaster at raasu dot org
2023-01-28  7:53 ` [Bug c/108580] " pinskia at gcc dot gnu.org
2023-01-28  8:04 ` postmaster at raasu dot org
2023-01-28  8:09 ` pinskia at gcc dot gnu.org
2023-01-28  8:55 ` postmaster at raasu dot org
2023-01-28  9:21 ` pinskia at gcc dot gnu.org
2023-01-28 12:21 ` postmaster at raasu dot org
2023-01-28 13:22 ` pinskia at gcc dot gnu.org
2023-01-28 15:36 ` postmaster at raasu dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).