summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2018-01-19 15:14:51 +0000
committerSanjay Patel <spatel@rotateright.com>2018-01-19 15:14:51 +0000
commit372c3f1f99dd98627c0bf0e2a1d2c0f2ed8a6ce9 (patch)
tree2d289703abc66c72b4647149e5d303cc28240735 /clang/test
parenteb74ab8633d63fefceb9c1ab5b7fbf2b8d9779de (diff)
downloadbcm5719-llvm-372c3f1f99dd98627c0bf0e2a1d2c0f2ed8a6ce9.tar.gz
bcm5719-llvm-372c3f1f99dd98627c0bf0e2a1d2c0f2ed8a6ce9.zip
[CodeGenCXX] annotate a GEP to a derived class with 'inbounds' (PR35909)
The standard says: [expr.static.cast] p11: "If the prvalue of type “pointer to cv1 B” points to a B that is actually a subobject of an object of type D, the resulting pointer points to the enclosing object of type D. Otherwise, the behavior is undefined." Therefore, the GEP must be inbounds. This should solve the failure to optimize away a null check shown in PR35909: https://bugs.llvm.org/show_bug.cgi?id=35909 Differential Revision: https://reviews.llvm.org/D42249 llvm-svn: 322950
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CodeGenCXX/catch-undef-behavior.cpp4
-rw-r--r--clang/test/CodeGenCXX/derived-cast.cpp27
2 files changed, 29 insertions, 2 deletions
diff --git a/clang/test/CodeGenCXX/catch-undef-behavior.cpp b/clang/test/CodeGenCXX/catch-undef-behavior.cpp
index e8287538982..786c6da21a1 100644
--- a/clang/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/clang/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -371,7 +371,7 @@ class C : public A, public B // align=16
void downcast_pointer(B *b) {
(void) static_cast<C*>(b);
// Alignment check from EmitTypeCheck(TCK_DowncastPointer, ...)
- // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr i8, i8* {{.*}}, i64 -16
+ // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, i8* {{.*}}, i64 -16
// CHECK-NEXT: [[C:%.+]] = bitcast i8* [[SUB]] to %class.C*
// null check goes here
// CHECK: [[FROM_PHI:%.+]] = phi %class.C* [ [[C]], {{.*}} ], {{.*}}
@@ -388,7 +388,7 @@ void downcast_pointer(B *b) {
void downcast_reference(B &b) {
(void) static_cast<C&>(b);
// Alignment check from EmitTypeCheck(TCK_DowncastReference, ...)
- // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr i8, i8* {{.*}}, i64 -16
+ // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr inbounds i8, i8* {{.*}}, i64 -16
// CHECK-NEXT: [[C:%.+]] = bitcast i8* [[SUB]] to %class.C*
// Objectsize check goes here
// CHECK: [[C_INT:%.+]] = ptrtoint %class.C* [[C]] to i64
diff --git a/clang/test/CodeGenCXX/derived-cast.cpp b/clang/test/CodeGenCXX/derived-cast.cpp
new file mode 100644
index 00000000000..bf2b258c5e9
--- /dev/null
+++ b/clang/test/CodeGenCXX/derived-cast.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+class A {
+ int a;
+};
+
+class B {
+ int b;
+public:
+ A *getAsA();
+};
+
+class X : public A, public B {
+ int x;
+};
+
+// PR35909 - https://bugs.llvm.org/show_bug.cgi?id=35909
+
+A *B::getAsA() {
+ return static_cast<X*>(this);
+
+ // CHECK-LABEL: define %class.A* @_ZN1B6getAsAEv
+ // CHECK: %[[THIS:.*]] = load %class.B*, %class.B**
+ // CHECK-NEXT: %[[BC:.*]] = bitcast %class.B* %[[THIS]] to i8*
+ // CHECK-NEXT: getelementptr inbounds i8, i8* %[[BC]], i64 -4
+}
+
OpenPOWER on IntegriCloud