[cfe-dev] Found a bug - maybe?
Chris Lattner
clattner at apple.com
Mon Jun 7 09:07:00 PDT 2010
On Jun 7, 2010, at 8:33 AM, Jeffrey Yasskin wrote:
> (buffer - 4) causes undefined behavior, per [expr.add]: "if the
> expression P points to the i-th element of an array ob ject, the
> expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the
> value n) point to, respectively, the i + n-th and i - n-th elements of
> the array object, provided they exist."
Right, a portable way to do this is to do the comparison on "(uintptr_t)P" instead of on P.
-Chris
>
> Instcombine actually does the damage here, turning
>
> define i32 @main() {
> entry:
> %retval = alloca i32, align 4 ; <i32*> [#uses=2]
> store i32 0, i32* %retval
> br i1 icmp ugt (i8* getelementptr inbounds ([2 x i8]*
> @_ZZ4mainE6buffer, i32 0, i32 0), i8* getelementptr inbounds ([2 x
> i8]* @_ZZ4mainE6buffer, i32 0, i32 -4)), label %if.then, label
> %if.else
>
> if.then: ; preds = %entry
> %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([10
> x i8]* @.str, i32 0, i32 0)) ; <i32> [#uses=0]
> br label %if.end
>
> if.else: ; preds = %entry
> %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
> ([10 x i8]* @.str1, i32 0, i32 0)) ; <i32> [#uses=0]
> br label %if.end
>
> if.end: ; preds = %if.else, %if.then
> %0 = load i32* %retval ; <i32> [#uses=1]
> ret i32 %0
> }
>
>
> into
>
>
>
> define i32 @main() {
> entry:
> %retval = alloca i32, align 4 ; <i32*> [#uses=2]
> store i32 0, i32* %retval
> br i1 false, label %if.then, label %if.else
>
> if.then: ; preds = %entry
> br label %if.end
>
> if.else: ; preds = %entry
> %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds
> ([10 x i8]* @.str1, i32 0, i32 0)) ; <i32> [#uses=0]
> br label %if.end
>
> if.end: ; preds = %if.else, %if.then
> %0 = load i32* %retval ; <i32> [#uses=1]
> ret i32 %0
> }
>
>
> On Sun, Jun 6, 2010 at 9:09 PM, Clark Gaebel <cg.wowus.cg at gmail.com> wrote:
>> Here's a reduced test case. Strangely enough, if I change buffer to be of
>> size 1, this code works fine.
>>
>> clark at clark-server ~/test $ clang++ --version
>> clang version 1.1 (branches/release_27)
>> Target: x86_64-pc-linux-gnu
>> Thread model: posix
>> clark at clark-server ~/test $ cat foo.cpp
>> #include <cstdio> // For printf.
>>
>> int main()
>> {
>> const char buffer[] = {
>> 0x00, 0x11
>> };
>>
>> if(buffer > (buffer - 4))
>> printf("SUCCESS!\n");
>> else
>> printf("FAILURE!\n");
>> }
>>
>> clark at clark-server ~/test $ clang++ -O0 foo.cpp && ./a.out
>> SUCCESS!
>> clark at clark-server ~/test $ clang++ -O2 foo.cpp && ./a.out
>> FAILURE!
>>
>>
>> On 06/07/10 00:03, Clark Gaebel wrote:
>>
>> A picture is worth a thousand words (and by picture, I mean shell
>> output). This is with
>>
>> clark at clark-server ~/test $ clang++ --version
>> clang version 1.1 (branches/release_27)
>> Target: x86_64-pc-linux-gnu
>> Thread model: posix
>> clark at clark-server ~/test $ cat foo.cpp
>> #include <cstdlib>
>> #include <cstdio>
>>
>> struct ParseFailed {};
>>
>> int main()
>> {
>> bool succeeded = false;
>>
>> const char buffer[] = {
>> 0x00, 0x11
>> };
>>
>> try {
>> if(buffer > (buffer - 4))
>> throw ParseFailed();
>>
>> succeeded = false;
>> } catch(ParseFailed) {
>> succeeded = true;
>> }
>>
>> if(succeeded)
>> printf("SUCCESS!\n");
>> else
>> printf("FAILURE!\n");
>> }
>>
>> clark at clark-server ~/test $ clang++ -O0 foo.cpp && ./a.out
>> SUCCESS!
>> clark at clark-server ~/test $ clang++ -O2 foo.cpp && ./a.out
>> FAILURE!
>>
>> What should I do? This little oddity popped up in one of my unit tests
>> while running my codebase through clang.
>>
>>
>>
>> --
>> Regards,
>> -Clark
>>
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>>
>>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
More information about the cfe-dev
mailing list