[LLVMbugs] [Bug 21327] New: Invalid optimization for "==" on pointers

bugzilla-daemon at llvm.org bugzilla-daemon at llvm.org
Tue Oct 21 12:22:15 PDT 2014


http://llvm.org/bugs/show_bug.cgi?id=21327

            Bug ID: 21327
           Summary: Invalid optimization for "==" on pointers
           Product: clang
           Version: unspecified
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: -New Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: Keith.S.Thompson at gmail.com
                CC: llvmbugs at cs.uiuc.edu
    Classification: Unclassified

"clang --version" says
Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)
Target: x86_64-pc-linux-gnu
Thread model: posix

"uname -a" says
Linux bomb20 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014
x86_64 x86_64 x86_64 GNU/Linux
(The system is Linux Mint 17, based on Ubuntu 14.04.1 LTS.)

I've created a Gist at
https://gist.github.com/Keith-S-Thompson/60dc069f4823fb1c3209
but of course I'll include the information here.

The C standard's definition of "==" for pointers (N1570 6.5.9 paragraph 6)
says:

> Two pointers compare equal if and only if both are null pointers,
> both are pointers to the same object (including a pointer to an
> object and a subobject at its beginning) or function, both are
> pointers to one past the last element of the same array object,
> or one is a pointer to one past the end of one array object and
> the other is a pointer to the start of a different array object
> that happens to immediately follow the first array object in the
> address space.

which implies that the test program below should print (among other output)
one of the following:
- "y immediately follows x" followed by "ok";
- "x immediately follows y" followed by "ok"; or
- "x and y are not adjacent"

Instead, when compiled with clang, it prints "inconsistent behavior: ...".

It appears that clang is assuming that a pointer just past the end of one
declared object cannot be equal to a pointer to the beginning of another
object, when the two objects are not subobjects of the same containing
object. Examining an assembly listing indicates that the code to print
"ok" is not even generated, implying that this is an optimization bug
(that occurs even at "-O0".

I don't expect that this is a common use case, but the compiled program
does behave in a manner inconsistent with the standard's requirements.

I see similar behavior with gcc 4.8.2 and 4.9.1, but with the order of
x and y reversed.  That's not directly relevant to this bug report,
but it's mildly interesting.  The gcc bug report is at
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63611

The command line used to compile and execute the program is:

$ clang -std=c11 -pedantic -Wall -Wextra pointer_equality_bug.c -o
pointer_equality_bug && ./pointer_equality_bug

The output on my system is:

x  = 0x7fff7905f820
x0 = 0x7fff7905f820
x1 = 0x7fff7905f8a0
y  = 0x7fff7905f7a0
y0 = 0x7fff7905f7a0
y1 = 0x7fff7905f820
x immediately follows y
inconsistent behavior:
    0x7fff7905f820 !=
    0x7fff7905f820

And the program itself (73 lines, making up the remainder of this description)
is:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
    typedef struct {
        int arr[32];
    } element;
    element x[1];
    element y[1];
    element *const x0 = x;
    element *const x1 = x0 + 1;
    element *const y0 = y;
    element *const y1 = y0 + 1;

    /*
     * x and y will typically be adjacent in memory.
     * x0 points to x; x1 points just past it.
     * y0 points to y; y1 points just past it.
     * We should have x1 == y0 if and only if y immediately follows x.
     * We should have y1 == x0 if and only if x immediately follows y.
     */

    printf("x  = %p\nx0 = %p\nx1 = %p\ny  = %p\ny0 = %p\ny1 = %p\n",
           (void*)x, (void*)x0, (void*)x1,
           (void*)y, (void*)y0, (void*)y1);

    if (x1 == y0) {
        puts("y immediately follows x");
        if (x + 1 == y) {
            puts("ok");
        }
        else if (x + 1 != y) {
            printf("inconsistent behavior:\n"
                   "    %p !=\n"
                   "    %p\n",
                   (void*)(x + 1),
                   (void*)y);
            exit(EXIT_FAILURE);
        }
        else {
            printf("inconsistent behavior:\n"
                   "    %p !=\n"
                   "    %p\n",
                   (void*)(x + 1),
                   (void*)y);
            exit(EXIT_FAILURE);
        }
    }
    else if (y1 == x0) {
        puts("x immediately follows y");
        if (y + 1 == x) {
            puts("ok");
        }
        else if (y + 1 != x) {
            printf("inconsistent behavior:\n"
                   "    %p !=\n"
                   "    %p\n",
                   (void*)(y + 1),
                   (void*)x);
            exit(EXIT_FAILURE);
        }
        else {
            printf("inconsistent behavior:\n"
                   "    %p !=\n"
                   "    %p\n",
                   (void*)(y + 1),
                   (void*)x);
            exit(EXIT_FAILURE);
        }
    }
    else {
        puts("x and y are not adjacent");
    }
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20141021/cd44fe85/attachment.html>


More information about the llvm-bugs mailing list