This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c++/84322] New: -fstrong-eval-order violated on assignment with function call


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

            Bug ID: 84322
           Summary: -fstrong-eval-order violated on assignment with
                    function call
           Product: gcc
           Version: 7.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: chortos at inbox dot lv
  Target Milestone: ---

The following C++ code:

    extern int a[10];
    int g();
    void f() {
        a[a[1]] = g();
    }

generates the following assembler code on amd64 Darwin with -O3 -std=c++17
(with or without an explicit -fstrong-eval-order, which should be implied if I
understand correctly):

    movq    _a@GOTPCREL(%rip), %rbp
    movslq  4(%rbp), %rbx
    call    __Z1gv
    movl    %eax, 0(%rbp,%rbx,4)

and the following with -O0 -std=c++17:

    movq    _a@GOTPCREL(%rip), %rax
    movl    4(%rax), %ebx
    call    __Z1gv
    movl    %eax, %ecx
    movq    _a@GOTPCREL(%rip), %rax
    movslq  %ebx, %rdx
    movl    %ecx, (%rax,%rdx,4)

In both cases, the a[1] is evaluated before the g() call, which contradicts the
strong right-to-left order of assignment operands guaranteed/required by C++17.
If g() modifies a[1], the program can observe the difference:

    int a[10];
    int g() {
        return a[1] = 2;
    }
    void f();
    int main() {
        f();
        __builtin_printf("%d %d\n", a[1], a[2]);
    }

produces "2 0" when compiled with GCC 7 but "2 2" when compiled with Clang 5,
which (intentionally or not) evaluates the operands in the correct order.

Here are my gcc -v and uname -a, which I doubt will be useful but are requested
on https://gcc.gnu.org/bugs/:

$ g++-7 -v
Using built-in specs.
COLLECT_GCC=g++-7
COLLECT_LTO_WRAPPER=/usr/local/Cellar/gcc/7.3.0/libexec/gcc/x86_64-apple-darwin10.8.0/7.3.0/lto-wrapper
Target: x86_64-apple-darwin10.8.0
Configured with: ../configure --build=x86_64-apple-darwin10.8.0
--prefix=/usr/local/Cellar/gcc/7.3.0
--libdir=/usr/local/Cellar/gcc/7.3.0/lib/gcc/7
--enable-languages=c,c++,objc,obj-c++,fortran --program-suffix=-7
--with-gmp=/usr/local/opt/gmp --with-mpfr=/usr/local/opt/mpfr
--with-mpc=/usr/local/opt/libmpc --with-isl=/usr/local/opt/isl
--with-system-zlib --enable-checking=release --with-pkgversion='Homebrew GCC
7.3.0' --with-bugurl=https://github.com/Homebrew/homebrew-core/issues
--with-dwarf2 --disable-nls
Thread model: posix
gcc version 7.3.0 (Homebrew GCC 7.3.0) 

$ uname -a
Darwin [hostname].local 10.8.0 Darwin Kernel Version 10.8.0: Tue Jun  7
16:33:36 PDT 2011; root:xnu-1504.15.3~1/RELEASE_I386 i386

For reference, I have also tried GCC 6.3.0 and 5.1.0 (which do not understand
-fstrong-eval-order but do understand -std=c++17), and they use the same order
as GCC 7.3.0.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]