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

            Bug ID: 106355
           Summary: Linux s390x -O2 argument passing miscompile
           Product: gcc
           Version: 12.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: other
          Assignee: unassigned at gcc dot gnu.org
          Reporter: sbergman at redhat dot com
  Target Milestone: ---

(I ran into this when trying to build recent LibreOffice 7.5 master on Fedora
36 on s390x causing a crash in one of the executables generated during the
build.  I tracked that down to a member function S::f2(arg1,args2,arg3) calling
S::f1(arg1,arg2,arg3,std::nullopt) but within
S::f1(arg1,arg2,arg3,std::optional<unsigned short> x) then x.has_value()
evaluates to true, or even to some random non-zero value like 163:)

At least with gcc-c++-12.1.1-1.fc36.s390x:

> $ cat test.cc
> #include <cstdlib>
> #include <optional>
> int f1(int, int, int, int, std::optional<unsigned short> x) {
>   if (x) std::abort();
>   return 0;
> }
> int f2(int a, int b, int c, int d) {
>   return f1(a, b, c, d, std::nullopt);
> }

> $ g++ -std=c++17 -O2 -fpic -S test.cc

> $ cat test.s
>         .file   "test.cc"
>         .machinemode zarch
>         .machine "zEC12"
> .text
>         .align  8
>         .align  16
> .globl _Z2f1iiiiSt8optionalItE
>         .type   _Z2f1iiiiSt8optionalItE, @function
> _Z2f1iiiiSt8optionalItE:
> .LFB284:
>         .cfi_startproc
>         tmll    %r6,65280
>         jne     .L7
>         lghi    %r2,0
>         br      %r14
> .L7:
>         stmg    %r14,%r15,112(%r15)
>         .cfi_offset 14, -48
>         .cfi_offset 15, -40
>         lay     %r15,-168(%r15)
>         .cfi_def_cfa_offset 328
>         brasl   %r14,abort@PLT
>         .cfi_endproc
> .LFE284:
>         .size   _Z2f1iiiiSt8optionalItE, .-_Z2f1iiiiSt8optionalItE
>         .align  8
>         .align  16
> .globl _Z2f2iiii
>         .type   _Z2f2iiii, @function
> _Z2f2iiii:
> .LFB287:
>         .cfi_startproc
>         ldgr    %f0,%r15
>         .cfi_register 15, 16
>         lay     %r15,-168(%r15)
>         .cfi_def_cfa_offset 328
>         mvi     166(%r15),0
>         lgdr    %r15,%f0
>         .cfi_restore 15
>         .cfi_def_cfa_offset 160
>         jg      _Z2f1iiiiSt8optionalItE@PLT
>         .cfi_endproc
> .LFE287:
>         .size   _Z2f2iiii, .-_Z2f2iiii
>         .ident  "GCC: (GNU) 12.1.1 20220507 (Red Hat 12.1.1-1)"
>         .section        .note.GNU-stack,"",@progbits

With my limited understanding of s390x assembly, f2 sets the optional's bool
_M_engaged flag byte to 0 on the stack with

        lay     %r15,-168(%r15)
        mvi     166(%r15),0

but then f1 expects to test that byte in %r6 with

        tmll    %r6,65280

Reply via email to