-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
Bugzilla Link | 8927 |
Resolution | FIXED |
Resolved on | Jan 16, 2011 12:23 |
Version | trunk |
OS | All |
Blocks | #9279 |
Reporter | LLVM Bugzilla Contributor |
CC | @lattner |
Extended Description
The C standard says that
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.
With -O0 and some cleanup passes clang compiles
struct foobar {
int x;
};
static const struct foobar* foo() {
static const struct foobar d = { 0 };
return &d;
}
static const struct foobar* bar() {
static const struct foobar d = { 0 };
return &d;
}
int zed(const struct foobar *a, const struct foobar *b);
int main() {
zed(foo(), bar());
}
to
%struct.foobar = type { i32 }
@bar.d = internal constant %struct.foobar zeroinitializer, align 4
@foo.d = internal constant %struct.foobar zeroinitializer, align 4
define i32 @main() nounwind ssp {
entry:
%call2 = tail call i32 @zed(%struct.foobar* @foo.d, %struct.foobar* @bar.d) nounwind
ret i32 0
}
declare i32 @zed(%struct.foobar*, %struct.foobar*)
but constmerge (which is included in -O2) transforms it to
%struct.foobar = type { i32 }
@bar.d = internal constant %struct.foobar zeroinitializer, align 4
define i32 @main() nounwind ssp {
entry:
%call2 = tail call i32 @zed(%struct.foobar* @bar.d, %struct.foobar* @bar.d) nounwind
ret i32 0
}
declare i32 @zed(%struct.foobar*, %struct.foobar*)
Since the function zed in unknown, it might compare the pointers and now it will get a different result.