aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/bitfield.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGenCXX/bitfield.cpp')
-rw-r--r--test/CodeGenCXX/bitfield.cpp58
1 files changed, 55 insertions, 3 deletions
diff --git a/test/CodeGenCXX/bitfield.cpp b/test/CodeGenCXX/bitfield.cpp
index 2c454b0c072c..fafeffe1ed23 100644
--- a/test/CodeGenCXX/bitfield.cpp
+++ b/test/CodeGenCXX/bitfield.cpp
@@ -298,7 +298,7 @@ namespace N4 {
#endif
unsigned read(Base* s) {
// FIXME: We should widen this load as long as the function isn't being
- // instrumented by thread-sanitizer.
+ // instrumented by ThreadSanitizer.
//
// CHECK-X86-64-LABEL: define i32 @_ZN2N44read
// CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
@@ -378,8 +378,8 @@ namespace N6 {
// Zero-length bitfields partition the memory locations of bitfields for the
// purposes of the memory model. That means stores must not span zero-length
// bitfields and loads may only span them when we are not instrumenting with
- // thread sanitizer.
- // FIXME: We currently don't widen loads even without thread sanitizer, even
+ // ThreadSanitizer.
+ // FIXME: We currently don't widen loads even without ThreadSanitizer, even
// though we could.
struct S {
unsigned b1 : 24;
@@ -426,3 +426,55 @@ namespace N6 {
s->b2 = x;
}
}
+
+namespace N7 {
+ // Similar to N4 except that this adds a virtual base to the picture. (PR18430)
+ // Do NOT widen loads and stores to bitfields into padding at the end of
+ // a class which might end up with members inside of it when inside a derived
+ // class.
+ struct B1 {
+ virtual void f();
+ unsigned b1 : 24;
+ };
+ struct B2 : virtual B1 {
+ virtual ~B2();
+ unsigned b : 24;
+ };
+ // Imagine some other translation unit introduces:
+#if 0
+ struct Derived : public B2 {
+ char c;
+ };
+#endif
+ unsigned read(B2* s) {
+ // FIXME: We should widen this load as long as the function isn't being
+ // instrumented by ThreadSanitizer.
+ //
+ // CHECK-X86-64-LABEL: define i32 @_ZN2N74read
+ // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-X86-64: %[[val:.*]] = load i24* %[[ptr]]
+ // CHECK-X86-64: %[[ext:.*]] = zext i24 %[[val]] to i32
+ // CHECK-X86-64: ret i32 %[[ext]]
+ // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N74read
+ // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-PPC64: %[[val:.*]] = load i24* %[[ptr]]
+ // CHECK-PPC64: %[[ext:.*]] = zext i24 %[[val]] to i32
+ // CHECK-PPC64: ret i32 %[[ext]]
+ return s->b;
+ }
+ void write(B2* s, unsigned x) {
+ // CHECK-X86-64-LABEL: define void @_ZN2N75write
+ // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-X86-64: %[[new:.*]] = trunc i32 %{{.*}} to i24
+ // CHECK-X86-64: store i24 %[[new]], i24* %[[ptr]]
+ // CHECK-PPC64-LABEL: define void @_ZN2N75write
+ // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1
+ // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24*
+ // CHECK-PPC64: %[[new:.*]] = trunc i32 %{{.*}} to i24
+ // CHECK-PPC64: store i24 %[[new]], i24* %[[ptr]]
+ s->b = x;
+ }
+}