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

            Bug ID: 64119
           Summary: asm triggers local register variable data corruption
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: inline-asm
          Assignee: unassigned at gcc dot gnu.org
          Reporter: adam at consulting dot net.nz

//asm triggers local register variable data corruption
#include <stdio.h>

__attribute__((noinline)) void fn(int inputa, int inputb, int inputc) {
  register int a asm ("rax");
  register int b asm ("rbx");
  register int c asm ("rcx");

  a = inputa; b = inputb; c = inputc;
  printf("The values of a, b and c are %d, %d and %d respectively\n", a, b, c);

  a = inputa; b = inputb; c = inputc;
  printf("The values of a, b and c are %d, %d and %d respectively\n", a, b, c);

  a = inputa; b = inputb; c = inputc;
  asm ("" : "+r" (a), "+r" (b), "+r" (c));
  printf("The values of a, b and c are %d, %d and %d respectively\n", a, b, c);
}

int main(void) {
  fn(1, 2, 3);
  return 0;
}

$ gcc-4.9 -O0 gcc-asm-reg-var-data-corruption.c && ./a.out 
The values of a, b and c are 1, 2 and 3 respectively
The values of a, b and c are 1, 2 and 3 respectively
The values of a, b and c are 1, 2 and 3 respectively

$ gcc-4.9 -O1 gcc-asm-reg-var-data-corruption.c && ./a.out
The values of a, b and c are 1, 2 and 3 respectively
The values of a, b and c are 1, 2 and 3 respectively
The values of a, b and c are 53, 2 and 39 respectively

$ clang-3.6 -O0 gcc-asm-reg-var-data-corruption.c && ./a.out
The values of a, b and c are 1, 2 and 3 respectively
The values of a, b and c are 1, 2 and 3 respectively
The values of a, b and c are 1, 2 and 3 respectively

$ clang-3.6 -O1 gcc-asm-reg-var-data-corruption.c && ./a.out
The values of a, b and c are 1, 2 and 3 respectively
The values of a, b and c are 1, 2 and 3 respectively
The values of a, b and c are 1, 2 and 3 respectively

I think it's unfortunate that gcc allows library routines to clobber local
register variables (does clang save/restore values between library calls?)
Note: This code restores the variable values after each library call.

The asm statement should be harmless. At input it says: make sure rax, rbx and
rcx hold the values of a, b and c respectively. Since the inline assembly is
empty the asm output trivially satisfies the same constraint.

I upped the severity because I don't consider data corruption "normal" and this
kind of data corruption is difficult to isolate.

Reply via email to