summaryrefslogtreecommitdiffstats
path: root/clang/test/CodeGenCXX/arm64.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CodeGenCXX/arm64.cpp')
-rw-r--r--clang/test/CodeGenCXX/arm64.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/arm64.cpp b/clang/test/CodeGenCXX/arm64.cpp
index 19f72726e69..80438397c3f 100644
--- a/clang/test/CodeGenCXX/arm64.cpp
+++ b/clang/test/CodeGenCXX/arm64.cpp
@@ -84,3 +84,39 @@ namespace test2 {
// CHECK-GLOBALS-DAG: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) }
}
+
+// ARM64 reserves the top half of the vtable offset in virtual
+// member pointers.
+namespace test3 {
+ struct A {
+ virtual void foo();
+ virtual void bar();
+ };
+
+ // The offset half of the pointer is still initialized to zero.
+ // CHECK-GLOBALS-DAG: @_ZN5test34mptrE = global { i64, i64 } { i64 0, i64 1 }
+ void (A::*mptr)() = &A::foo;
+
+ // CHECK-LABEL: define void @_ZN5test34testEv()
+ // CHECK: [[TEMP:%.*]] = alloca [[A:.*]], align 8
+ // CHECK: [[MEMPTR:%.*]] = load { i64, i64 }, { i64, i64 }* @_ZN5test34mptrE, align 8
+ // CHECK: [[ADJUST_AND_IS_VIRTUAL:%.*]] = extractvalue { i64, i64 } [[MEMPTR]], 1
+ // CHECK: [[ADJUST:%.*]] = ashr i64 [[ADJUST_AND_IS_VIRTUAL]], 1
+ // CHECK: [[T0:%.*]] = bitcast [[A]]* [[TEMP]] to i8*
+ // CHECK: [[T1:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[ADJUST]]
+ // CHECK: [[ADJUSTED:%.*]] = bitcast i8* [[T1]] to [[A]]*
+ // CHECK: [[MEMBER:%.*]] = extractvalue { i64, i64 } [[MEMPTR]], 0
+ // CHECK: [[T0:%.*]] = and i64 [[ADJUST_AND_IS_VIRTUAL]], 1
+ // CHECK: [[IS_VIRTUAL:%.*]] = icmp ne i64 [[T0]], 0
+ // CHECK: br i1 [[IS_VIRTUAL]],
+ // CHECK: [[T0:%.*]] = bitcast [[A]]* [[ADJUSTED]] to i8**
+ // CHECK: [[VPTR:%.*]] = load i8*, i8** [[T0]], align 8
+ // CHECK: [[TRUNC:%.*]] = trunc i64 [[MEMBER]] to i32
+ // CHECK: [[ZEXT:%.*]] = zext i32 [[TRUNC]] to i64
+ // CHECK: [[T0:%.*]] = getelementptr i8, i8* [[VPTR]], i64 [[ZEXT]]
+ // CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to void ([[A]]*)**
+ // CHECK: load void ([[A]]*)*, void ([[A]]*)** [[T1]],
+ void test() {
+ (A().*mptr)();
+ }
+}
OpenPOWER on IntegriCloud