[cfe-dev] Found a bug - maybe?
Jeffrey Yasskin
jyasskin at google.com
Mon Jun 7 08:33:10 PDT 2010
(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."
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
>
>
More information about the cfe-dev
mailing list