http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45771

           Summary: Source operands for conditional moves
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassig...@gcc.gnu.org
        ReportedBy: rmansfi...@qnx.com
              Host: x86_64-linux-gnu
            Target: x86_64-linux-gnu
             Build: x86_64-linux-gnu


$ ./xgcc -v
Using built-in specs.
COLLECT_GCC=./xgcc
Target: x86_64-linux-gnu
Configured with: ../configure --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.6.0 20100923 (experimental) [trunk revision 164569] (GCC) 

#define NULL 0

typedef struct List List;
struct List {
    List *next;
    int  stuff;
};
extern List Ignore;
extern List *pending, **tail;
extern void process(List *);

void
proc_all()
{
    List *irp;
    for( ;; ) {
        irp = pending;
        pending = NULL;
        if(irp == &Ignore) {
            irp = irp->next;
        }
        if(irp == NULL) break;
        pending = irp->next;
        process(irp);
    }
}

-O2 generates

        movq    pending(%rip), %rdi   
        movq    $0, pending(%rip)
        cmpq    $Ignore, %rdi
        cmove   (%rdi), %rdi
        testq   %rdi, %rdi


Since cmove always references the source operand regardless of the result of
the condition, and (%idi) can be null which will cause the program to crash.

The pseudo code for cmove:

cmove(condition, SRC, DEST)
{
       TEMP = SRC
       if (condition)
             DST = TEMP
}

-- 
Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.

Reply via email to