manojgupta updated this revision to Diff 154895.
manojgupta added a comment.
Do not generate calls with "nonnull" attribute with
"-fno-delete-null-pointer-checks".
The warnings are still generated when nullptr is passed to a function with
nonnull
attribute.
Repository:
rC Clang
https://reviews.llvm.org/D47894
Files:
docs/ClangCommandLineReference.rst
include/clang/Driver/Options.td
include/clang/Frontend/CodeGenOptions.def
lib/CodeGen/CGCall.cpp
lib/Driver/ToolChains/Clang.cpp
lib/Frontend/CompilerInvocation.cpp
test/CodeGen/delete-null-pointer-checks.c
test/CodeGen/nonnull.c
test/CodeGen/vla.c
test/CodeGenCXX/address-space-ref.cpp
test/CodeGenCXX/constructors.cpp
test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
test/CodeGenCXX/temporaries.cpp
test/Driver/clang_f_opts.c
test/Sema/nonnull.c
Index: test/Sema/nonnull.c
===================================================================
--- test/Sema/nonnull.c
+++ test/Sema/nonnull.c
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fno-delete-null-pointer-checks -verify %s
// rdar://9584012
typedef struct {
Index: test/Driver/clang_f_opts.c
===================================================================
--- test/Driver/clang_f_opts.c
+++ test/Driver/clang_f_opts.c
@@ -348,7 +348,6 @@
// RUN: -fwhole-program \
// RUN: -fcaller-saves \
// RUN: -freorder-blocks \
-// RUN: -fdelete-null-pointer-checks \
// RUN: -ffat-lto-objects \
// RUN: -fmerge-constants \
// RUN: -finline-small-functions \
@@ -414,7 +413,6 @@
// CHECK-WARNING-DAG: optimization flag '-fwhole-program' is not supported
// CHECK-WARNING-DAG: optimization flag '-fcaller-saves' is not supported
// CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported
-// CHECK-WARNING-DAG: optimization flag '-fdelete-null-pointer-checks' is not supported
// CHECK-WARNING-DAG: optimization flag '-ffat-lto-objects' is not supported
// CHECK-WARNING-DAG: optimization flag '-fmerge-constants' is not supported
// CHECK-WARNING-DAG: optimization flag '-finline-small-functions' is not supported
@@ -526,3 +524,10 @@
// RUN: %clang -### -S -fno-merge-all-constants -fmerge-all-constants %s 2>&1 | FileCheck -check-prefix=CHECK-MERGE-ALL-CONSTANTS %s
// CHECK-NO-MERGE-ALL-CONSTANTS-NOT: "-fmerge-all-constants"
// CHECK-MERGE-ALL-CONSTANTS: "-fmerge-all-constants"
+
+// RUN: %clang -### -S -fdelete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NULL-POINTER-CHECKS %s
+// RUN: %clang -### -S -fno-delete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NO-NULL-POINTER-CHECKS %s
+// RUN: %clang -### -S -fdelete-null-pointer-checks -fno-delete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NO-NULL-POINTER-CHECKS %s
+// RUN: %clang -### -S -fno-delete-null-pointer-checks -fdelete-null-pointer-checks %s 2>&1 | FileCheck -check-prefix=CHECK-NULL-POINTER-CHECKS %s
+// CHECK-NO-NULL-POINTER-CHECKS: "-fno-delete-null-pointer-checks"
+// CHECK-NULL-POINTER-CHECKS-NOT: "-fno-delete-null-pointer-checks"
Index: test/CodeGenCXX/temporaries.cpp
===================================================================
--- test/CodeGenCXX/temporaries.cpp
+++ test/CodeGenCXX/temporaries.cpp
@@ -1,52 +1,53 @@
-// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s -check-prefixes=CHECK-COMMON,CHECK-NONNULL
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 -fno-delete-null-pointer-checks | FileCheck %s -check-prefixes=CHECK-COMMON,CHECK-NO-NULL
namespace PR16263 {
const unsigned int n = 1234;
extern const int &r = (const int&)n;
- // CHECK: @_ZGRN7PR162631rE_ = internal constant i32 1234,
- // CHECK: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE_,
+ // CHECK-COMMON: @_ZGRN7PR162631rE_ = internal constant i32 1234,
+ // CHECK-COMMON: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE_,
extern const int &s = reinterpret_cast<const int&>(n);
- // CHECK: @_ZN7PR16263L1nE = internal constant i32 1234, align 4
- // CHECK: @_ZN7PR162631sE = constant i32* @_ZN7PR16263L1nE, align 8
+ // CHECK-COMMON: @_ZN7PR16263L1nE = internal constant i32 1234, align 4
+ // CHECK-COMMON: @_ZN7PR162631sE = constant i32* @_ZN7PR16263L1nE, align 8
struct A { int n; };
struct B { int n; };
struct C : A, B {};
extern const A &&a = (A&&)(A&&)(C&&)(C{});
- // CHECK: @_ZGRN7PR162631aE_ = internal global {{.*}} zeroinitializer,
- // CHECK: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE_ to
+ // CHECK-COMMON: @_ZGRN7PR162631aE_ = internal global {{.*}} zeroinitializer,
+ // CHECK-COMMON: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE_ to
extern const int &&t = ((B&&)C{}).n;
- // CHECK: @_ZGRN7PR162631tE_ = internal global {{.*}} zeroinitializer,
- // CHECK: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE_ {{.*}} 4
+ // CHECK-COMMON: @_ZGRN7PR162631tE_ = internal global {{.*}} zeroinitializer,
+ // CHECK-COMMON: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE_ {{.*}} 4
struct D { double d; C c; };
extern const int &&u = (123, static_cast<B&&>(0, ((D&&)D{}).*&D::c).n);
- // CHECK: @_ZGRN7PR162631uE_ = internal global {{.*}} zeroinitializer
- // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12
+ // CHECK-COMMON: @_ZGRN7PR162631uE_ = internal global {{.*}} zeroinitializer
+ // CHECK-COMMON: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12
}
namespace PR20227 {
struct A { ~A(); };
struct B { virtual ~B(); };
struct C : B {};
A &&a = dynamic_cast<A&&>(A{});
- // CHECK: @_ZGRN7PR202271aE_ = internal global
+ // CHECK-COMMON: @_ZGRN7PR202271aE_ = internal global
B &&b = dynamic_cast<C&&>(dynamic_cast<B&&>(C{}));
- // CHECK: @_ZGRN7PR202271bE_ = internal global
+ // CHECK-COMMON: @_ZGRN7PR202271bE_ = internal global
B &&c = static_cast<C&&>(static_cast<B&&>(C{}));
- // CHECK: @_ZGRN7PR202271cE_ = internal global
+ // CHECK-COMMON: @_ZGRN7PR202271cE_ = internal global
}
namespace BraceInit {
typedef const int &CIR;
CIR x = CIR{3};
- // CHECK: @_ZGRN9BraceInit1xE_ = internal constant i32 3
- // CHECK: @_ZN9BraceInit1xE = constant i32* @_ZGRN9BraceInit1xE_
+ // CHECK-COMMON: @_ZGRN9BraceInit1xE_ = internal constant i32 3
+ // CHECK-COMMON: @_ZN9BraceInit1xE = constant i32* @_ZGRN9BraceInit1xE_
}
struct A {
@@ -56,12 +57,12 @@
};
void f1() {
- // CHECK: call void @_ZN1AC1Ev
- // CHECK: call void @_ZN1AD1Ev
+ // CHECK-COMMON: call void @_ZN1AC1Ev
+ // CHECK-COMMON: call void @_ZN1AD1Ev
(void)A();
- // CHECK: call void @_ZN1AC1Ev
- // CHECK: call void @_ZN1AD1Ev
+ // CHECK-COMMON: call void @_ZN1AC1Ev
+ // CHECK-COMMON: call void @_ZN1AD1Ev
A().f();
}
@@ -74,8 +75,8 @@
B g();
void f2() {
- // CHECK-NOT: call void @_ZN1BC1Ev
- // CHECK: call void @_ZN1BD1Ev
+ // CHECK-COMMON-NOT: call void @_ZN1BC1Ev
+ // CHECK-COMMON: call void @_ZN1BD1Ev
(void)g();
}
@@ -88,9 +89,9 @@
};
void f3() {
- // CHECK: call void @_ZN1CC1Ev
- // CHECK: call void @_ZN1CD1Ev
- // CHECK: call void @_ZN1CD1Ev
+ // CHECK-COMMON: call void @_ZN1CC1Ev
+ // CHECK-COMMON: call void @_ZN1CD1Ev
+ // CHECK-COMMON: call void @_ZN1CD1Ev
C().f();
}
@@ -103,9 +104,9 @@
};
void f4() {
- // CHECK: call void @_ZN1DC1Ev
- // CHECK: call void @_ZN1DD1Ev
- // CHECK: call void @_ZN1DD1Ev
+ // CHECK-COMMON: call void @_ZN1DC1Ev
+ // CHECK-COMMON: call void @_ZN1DD1Ev
+ // CHECK-COMMON: call void @_ZN1DD1Ev
D()();
}
@@ -118,16 +119,16 @@
};
void f5() {
- // CHECK: call void @_ZN1EC1Ev
- // CHECK: call void @_ZN1EC1Ev
- // CHECK: call void @_ZN1ED1Ev
- // CHECK: call void @_ZN1ED1Ev
- // CHECK: call void @_ZN1ED1Ev
+ // CHECK-COMMON: call void @_ZN1EC1Ev
+ // CHECK-COMMON: call void @_ZN1EC1Ev
+ // CHECK-COMMON: call void @_ZN1ED1Ev
+ // CHECK-COMMON: call void @_ZN1ED1Ev
+ // CHECK-COMMON: call void @_ZN1ED1Ev
E() + E();
- // CHECK: call void @_ZN1EC1Ev
- // CHECK: call void @_ZN1ED1Ev
- // CHECK: call void @_ZN1ED1Ev
+ // CHECK-COMMON: call void @_ZN1EC1Ev
+ // CHECK-COMMON: call void @_ZN1ED1Ev
+ // CHECK-COMMON: call void @_ZN1ED1Ev
!E();
}
@@ -138,8 +139,8 @@
};
void f6() {
- // CHECK: call void @_ZN1FC1Ev
- // CHECK: call void @_ZN1FD1Ev
+ // CHECK-COMMON: call void @_ZN1FC1Ev
+ // CHECK-COMMON: call void @_ZN1FD1Ev
F().f();
}
@@ -153,16 +154,16 @@
void a(const A&);
void f7() {
- // CHECK: call void @_ZN1AC1Ev
- // CHECK: call void @_Z1aRK1A
- // CHECK: call void @_ZN1AD1Ev
+ // CHECK-COMMON: call void @_ZN1AC1Ev
+ // CHECK-COMMON: call void @_Z1aRK1A
+ // CHECK-COMMON: call void @_ZN1AD1Ev
a(A());
- // CHECK: call void @_ZN1GC1Ev
- // CHECK: call void @_ZN1Gcv1AEv
- // CHECK: call void @_Z1aRK1A
- // CHECK: call void @_ZN1AD1Ev
- // CHECK: call void @_ZN1GD1Ev
+ // CHECK-COMMON: call void @_ZN1GC1Ev
+ // CHECK-COMMON: call void @_ZN1Gcv1AEv
+ // CHECK-COMMON: call void @_Z1aRK1A
+ // CHECK-COMMON: call void @_ZN1AD1Ev
+ // CHECK-COMMON: call void @_ZN1GD1Ev
a(G());
}
@@ -185,16 +186,16 @@
};
B::B()
- // CHECK: call void @_ZN6PR50771AC1Ev
- // CHECK: call i32 @_ZN6PR50771A1fEv
- // CHECK: call void @_ZN6PR50771AD1Ev
+ // CHECK-COMMON: call void @_ZN6PR50771AC1Ev
+ // CHECK-COMMON: call i32 @_ZN6PR50771A1fEv
+ // CHECK-COMMON: call void @_ZN6PR50771AD1Ev
: a1(A().f())
- // CHECK: call void @_ZN6PR50771AC1Ev
- // CHECK: call i32 @_ZN6PR50771gERKNS_1AE
- // CHECK: call void @_ZN6PR50771AD1Ev
+ // CHECK-COMMON: call void @_ZN6PR50771AC1Ev
+ // CHECK-COMMON: call i32 @_ZN6PR50771gERKNS_1AE
+ // CHECK-COMMON: call void @_ZN6PR50771AD1Ev
, a2(g(A()))
{
- // CHECK: call void @_ZN6PR50771fEv
+ // CHECK-COMMON: call void @_ZN6PR50771fEv
f();
}
@@ -205,20 +206,20 @@
};
C::C()
- // CHECK: call void @_ZN6PR50771BC1Ev
+ // CHECK-COMMON: call void @_ZN6PR50771BC1Ev
: b(B()) {
- // CHECK: call void @_ZN6PR50771fEv
+ // CHECK-COMMON: call void @_ZN6PR50771fEv
f();
- // CHECK: call void @_ZN6PR50771BD1Ev
+ // CHECK-COMMON: call void @_ZN6PR50771BD1Ev
}
}
A f8() {
- // CHECK: call void @_ZN1AC1Ev
- // CHECK-NOT: call void @_ZN1AD1Ev
+ // CHECK-COMMON: call void @_ZN1AC1Ev
+ // CHECK-COMMON-NOT: call void @_ZN1AD1Ev
return A();
- // CHECK: ret void
+ // CHECK-COMMON: ret void
}
struct H {
@@ -228,28 +229,28 @@
};
void f9(H h) {
- // CHECK: call void @_ZN1HC1Ev
- // CHECK: call void @_Z2f91H
- // CHECK: call void @_ZN1HD1Ev
+ // CHECK-COMMON: call void @_ZN1HC1Ev
+ // CHECK-COMMON: call void @_Z2f91H
+ // CHECK-COMMON: call void @_ZN1HD1Ev
f9(H());
- // CHECK: call void @_ZN1HC1ERKS_
- // CHECK: call void @_Z2f91H
- // CHECK: call void @_ZN1HD1Ev
+ // CHECK-COMMON: call void @_ZN1HC1ERKS_
+ // CHECK-COMMON: call void @_Z2f91H
+ // CHECK-COMMON: call void @_ZN1HD1Ev
f9(h);
}
void f10(const H&);
void f11(H h) {
- // CHECK: call void @_ZN1HC1Ev
- // CHECK: call void @_Z3f10RK1H
- // CHECK: call void @_ZN1HD1Ev
+ // CHECK-COMMON: call void @_ZN1HC1Ev
+ // CHECK-COMMON: call void @_Z3f10RK1H
+ // CHECK-COMMON: call void @_ZN1HD1Ev
f10(H());
- // CHECK: call void @_Z3f10RK1H
- // CHECK-NOT: call void @_ZN1HD1Ev
- // CHECK: ret void
+ // CHECK-COMMON: call void @_Z3f10RK1H
+ // CHECK-COMMON-NOT: call void @_ZN1HD1Ev
+ // CHECK-COMMON: ret void
f10(h);
}
@@ -259,11 +260,11 @@
~I();
};
-// CHECK: _Z3f12v
+// CHECK-COMMON: _Z3f12v
I f12() {
- // CHECK: call void @_ZN1IC1EPKc
- // CHECK-NOT: call void @_ZN1ID1Ev
- // CHECK: ret void
+ // CHECK-COMMON: call void @_ZN1IC1EPKc
+ // CHECK-COMMON-NOT: call void @_ZN1ID1Ev
+ // CHECK-COMMON: ret void
return "Hello";
}
@@ -276,22 +277,22 @@
};
void f(S, int);
- // CHECK-LABEL: define void @_ZN6PR58671gEv
+ // CHECK-COMMON-LABEL: define void @_ZN6PR58671gEv
void g() {
- // CHECK: call void @_ZN6PR58671SC1Ev
- // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
- // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
- // CHECK-NEXT: ret void
+ // CHECK-COMMON: call void @_ZN6PR58671SC1Ev
+ // CHECK-COMMON-NEXT: call void @_ZN6PR58671fENS_1SEi
+ // CHECK-COMMON-NEXT: call void @_ZN6PR58671SD1Ev
+ // CHECK-COMMON-NEXT: ret void
(f)(S(), 0);
}
- // CHECK-LABEL: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
+ // CHECK-COMMON-LABEL: define linkonce_odr void @_ZN6PR58672g2IiEEvT_
template<typename T>
void g2(T) {
- // CHECK: call void @_ZN6PR58671SC1Ev
- // CHECK-NEXT: call void @_ZN6PR58671fENS_1SEi
- // CHECK-NEXT: call void @_ZN6PR58671SD1Ev
- // CHECK-NEXT: ret void
+ // CHECK-COMMON: call void @_ZN6PR58671SC1Ev
+ // CHECK-COMMON-NEXT: call void @_ZN6PR58671fENS_1SEi
+ // CHECK-COMMON-NEXT: call void @_ZN6PR58671SD1Ev
+ // CHECK-COMMON-NEXT: ret void
(f)(S(), 0);
}
@@ -306,11 +307,11 @@
struct B { operator A(); };
- // CHECK-LABEL: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_
+ // CHECK-COMMON-LABEL: define weak_odr void @_ZN6PR61992f2IiEENS_1AET_
template<typename T> A f2(T) {
B b;
- // CHECK: call void @_ZN6PR61991BcvNS_1AEEv
- // CHECK-NEXT: ret void
+ // CHECK-COMMON: call void @_ZN6PR61991BcvNS_1AEEv
+ // CHECK-COMMON-NEXT: ret void
return b;
}
@@ -328,12 +329,12 @@
int& f(int);
-// CHECK-LABEL: define void @_ZN3T121gEv
+// CHECK-COMMON-LABEL: define void @_ZN3T121gEv
void g() {
- // CHECK: call void @_ZN3T121AC1Ev
- // CHECK-NEXT: call i32 @_ZN3T121A1fEv(
- // CHECK-NEXT: call dereferenceable({{[0-9]+}}) i32* @_ZN3T121fEi(
- // CHECK-NEXT: call void @_ZN3T121AD1Ev(
+ // CHECK-COMMON: call void @_ZN3T121AC1Ev
+ // CHECK-COMMON-NEXT: call i32 @_ZN3T121A1fEv(
+ // CHECK-COMMON-NEXT: call dereferenceable({{[0-9]+}}) i32* @_ZN3T121fEi(
+ // CHECK-COMMON-NEXT: call void @_ZN3T121AD1Ev(
int& i = f(A().f());
}
@@ -347,7 +348,8 @@
struct D;
D& zed(B);
void foobar() {
- // CHECK: call nonnull %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
+ // CHECK-NONNULL: call nonnull %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
+ // CHECK-NO-NULL: call %"struct.PR6648::D"* @_ZN6PR66483zedENS_1BE
zed(foo);
}
}
@@ -361,31 +363,31 @@
void f(X);
- // CHECK: void @_ZN18UserConvertToValue1gEv()
+ // CHECK-COMMON: void @_ZN18UserConvertToValue1gEv()
void g() {
- // CHECK: call void @_ZN18UserConvertToValue1XC1Ei
- // CHECK: call void @_ZN18UserConvertToValue1fENS_1XE
- // CHECK: call void @_ZN18UserConvertToValue1XD1Ev
- // CHECK: ret void
+ // CHECK-COMMON: call void @_ZN18UserConvertToValue1XC1Ei
+ // CHECK-COMMON: call void @_ZN18UserConvertToValue1fENS_1XE
+ // CHECK-COMMON: call void @_ZN18UserConvertToValue1XD1Ev
+ // CHECK-COMMON: ret void
f(1);
}
}
namespace PR7556 {
struct A { ~A(); };
struct B { int i; ~B(); };
struct C { int C::*pm; ~C(); };
- // CHECK-LABEL: define void @_ZN6PR75563fooEv()
+ // CHECK-COMMON-LABEL: define void @_ZN6PR75563fooEv()
void foo() {
- // CHECK: call void @_ZN6PR75561AD1Ev
+ // CHECK-COMMON: call void @_ZN6PR75561AD1Ev
A();
- // CHECK: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR75561BD1Ev
+ // CHECK-COMMON: call void @llvm.memset.p0i8.i64
+ // CHECK-COMMON: call void @_ZN6PR75561BD1Ev
B();
- // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
- // CHECK: call void @_ZN6PR75561CD1Ev
+ // CHECK-COMMON: call void @llvm.memcpy.p0i8.p0i8.i64
+ // CHECK-COMMON: call void @_ZN6PR75561CD1Ev
C();
- // CHECK-NEXT: ret void
+ // CHECK-COMMON-NEXT: ret void
}
}
@@ -400,213 +402,213 @@
A fooA();
void takeA(A a);
- // CHECK-LABEL: define void @_ZN7Elision5test0Ev()
+ // CHECK-COMMON-LABEL: define void @_ZN7Elision5test0Ev()
void test0() {
- // CHECK: [[I:%.*]] = alloca [[A:%.*]], align 8
- // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[T0:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[K:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[T1:%.*]] = alloca [[A]], align 8
-
- // CHECK-NEXT: call void @_ZN7Elision3fooEv()
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
+ // CHECK-COMMON: [[I:%.*]] = alloca [[A:%.*]], align 8
+ // CHECK-COMMON-NEXT: [[J:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON-NEXT: [[T0:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON-NEXT: [[K:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON-NEXT: [[T1:%.*]] = alloca [[A]], align 8
+
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision3fooEv()
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
A i = (foo(), A());
- // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]])
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[T0]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
A j = (fooA(), A());
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]])
- // CHECK-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[T1]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision4fooAEv([[A]]* sret [[K]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T1]])
A k = (A(), fooA());
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[K]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
}
- // CHECK-LABEL: define void @_ZN7Elision5test1EbNS_1AE(
+ // CHECK-COMMON-LABEL: define void @_ZN7Elision5test1EbNS_1AE(
void test1(bool c, A x) {
- // CHECK: [[I:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[J:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON: [[I:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON-NEXT: [[J:%.*]] = alloca [[A]], align 8
- // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
- // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]])
+ // CHECK-COMMON: call void @_ZN7Elision1AC1Ev([[A]]* [[I]])
+ // CHECK-COMMON: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[I]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]])
A i = (c ? A() : x);
- // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
- // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
+ // CHECK-COMMON: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[J]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
+ // CHECK-COMMON: call void @_ZN7Elision1AC1Ev([[A]]* [[J]])
A j = (c ? x : A());
- // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
+ // CHECK-COMMON: call void @_ZN7Elision1AD1Ev([[A]]* [[J]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]])
}
- // CHECK: define void @_ZN7Elision5test2Ev([[A]]* noalias sret
+ // CHECK-COMMON: define void @_ZN7Elision5test2Ev([[A]]* noalias sret
A test2() {
- // CHECK: call void @_ZN7Elision3fooEv()
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
- // CHECK-NEXT: ret void
+ // CHECK-COMMON: call void @_ZN7Elision3fooEv()
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
+ // CHECK-COMMON-NEXT: ret void
return (foo(), A());
}
- // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* noalias sret
+ // CHECK-COMMON: define void @_ZN7Elision5test3EiNS_1AE([[A]]* noalias sret
A test3(int v, A x) {
if (v < 5)
- // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
- // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]])
+ // CHECK-COMMON: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]])
+ // CHECK-COMMON: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X:%.*]])
return (v < 0 ? A() : x);
else
- // CHECK: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
- // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
+ // CHECK-COMMON: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
+ // CHECK-COMMON: call void @_ZN7Elision1AC1Ev([[A]]* [[RET]])
return (v > 10 ? x : A());
- // CHECK: ret void
+ // CHECK-COMMON: ret void
}
- // CHECK-LABEL: define void @_ZN7Elision5test4Ev()
+ // CHECK-COMMON-LABEL: define void @_ZN7Elision5test4Ev()
void test4() {
- // CHECK: [[X:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
+ // CHECK-COMMON: [[X:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
A x;
- // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i64 0, i64 0
- // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
- // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[XS0]], i64 1
- // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
+ // CHECK-COMMON-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i64 0, i64 0
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
+ // CHECK-COMMON-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[XS0]], i64 1
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* dereferenceable({{[0-9]+}}) [[X]])
A xs[] = { A(), x };
- // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i32 0, i32 0
- // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 2
- // CHECK-NEXT: br label
- // CHECK: [[AFTER:%.*]] = phi [[A]]*
- // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]])
- // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
- // CHECK-NEXT: br i1 [[T0]],
+ // CHECK-COMMON-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i32 0, i32 0
+ // CHECK-COMMON-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 2
+ // CHECK-COMMON-NEXT: br label
+ // CHECK-COMMON: [[AFTER:%.*]] = phi [[A]]*
+ // CHECK-COMMON-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]])
+ // CHECK-COMMON-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK-COMMON-NEXT: br i1 [[T0]],
- // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
+ // CHECK-COMMON: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
}
// rdar://problem/8433352
- // CHECK: define void @_ZN7Elision5test5Ev([[A]]* noalias sret
+ // CHECK-COMMON: define void @_ZN7Elision5test5Ev([[A]]* noalias sret
struct B { A a; B(); };
A test5() {
- // CHECK: [[AT0:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8
- // CHECK-NEXT: [[X:%.*]] = alloca [[A]], align 8
- // CHECK-NEXT: [[BT1:%.*]] = alloca [[B]], align 8
- // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8
-
- // CHECK: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
- // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT0]], i32 0, i32 0
- // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
- // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
- // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
+ // CHECK-COMMON: [[AT0:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON-NEXT: [[BT0:%.*]] = alloca [[B:%.*]], align 8
+ // CHECK-COMMON-NEXT: [[X:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON-NEXT: [[BT1:%.*]] = alloca [[B]], align 8
+ // CHECK-COMMON-NEXT: [[BT2:%.*]] = alloca [[B]], align 8
+
+ // CHECK-COMMON: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]])
+ // CHECK-COMMON-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT0]], i32 0, i32 0
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT0]])
takeA(B().a);
- // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
- // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT1]], i32 0, i32 0
- // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
- // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]])
+ // CHECK-COMMON-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT1]], i32 0, i32 0
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]])
A x = B().a;
- // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
- // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT2]], i32 0, i32 0
- // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
- // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]])
+ // CHECK-COMMON-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT2]], i32 0, i32 0
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]])
return B().a;
- // CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
+ // CHECK-COMMON: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
}
// Reduced from webkit.
- // CHECK: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]*
+ // CHECK-COMMON: define void @_ZN7Elision5test6EPKNS_1CE([[C:%.*]]*
struct C { operator A() const; };
void test6(const C *x) {
- // CHECK: [[T0:%.*]] = alloca [[A]], align 8
- // CHECK: [[X:%.*]] = load [[C]]*, [[C]]** {{%.*}}, align 8
- // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]])
- // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]])
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
- // CHECK-NEXT: ret void
+ // CHECK-COMMON: [[T0:%.*]] = alloca [[A]], align 8
+ // CHECK-COMMON: [[X:%.*]] = load [[C]]*, [[C]]** {{%.*}}, align 8
+ // CHECK-COMMON-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]])
+ // CHECK-COMMON-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]])
+ // CHECK-COMMON-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]])
+ // CHECK-COMMON-NEXT: ret void
A(*x).foo();
}
}
namespace PR8623 {
struct A { A(int); ~A(); };
- // CHECK-LABEL: define void @_ZN6PR86233fooEb(
+ // CHECK-COMMON-LABEL: define void @_ZN6PR86233fooEb(
void foo(bool b) {
- // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
- // CHECK-NEXT: [[LCONS:%.*]] = alloca i1
- // CHECK-NEXT: [[RCONS:%.*]] = alloca i1
- // CHECK: store i1 false, i1* [[LCONS]]
- // CHECK-NEXT: store i1 false, i1* [[RCONS]]
- // CHECK-NEXT: br i1
- // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2)
- // CHECK-NEXT: store i1 true, i1* [[LCONS]]
- // CHECK-NEXT: br label
- // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3)
- // CHECK-NEXT: store i1 true, i1* [[RCONS]]
- // CHECK-NEXT: br label
- // CHECK: load i1, i1* [[RCONS]]
- // CHECK-NEXT: br i1
- // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
- // CHECK-NEXT: br label
- // CHECK: load i1, i1* [[LCONS]]
- // CHECK-NEXT: br i1
- // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
- // CHECK-NEXT: br label
- // CHECK: ret void
+ // CHECK-COMMON: [[TMP:%.*]] = alloca [[A:%.*]], align 1
+ // CHECK-COMMON-NEXT: [[LCONS:%.*]] = alloca i1
+ // CHECK-COMMON-NEXT: [[RCONS:%.*]] = alloca i1
+ // CHECK-COMMON: store i1 false, i1* [[LCONS]]
+ // CHECK-COMMON-NEXT: store i1 false, i1* [[RCONS]]
+ // CHECK-COMMON-NEXT: br i1
+ // CHECK-COMMON: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 2)
+ // CHECK-COMMON-NEXT: store i1 true, i1* [[LCONS]]
+ // CHECK-COMMON-NEXT: br label
+ // CHECK-COMMON: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3)
+ // CHECK-COMMON-NEXT: store i1 true, i1* [[RCONS]]
+ // CHECK-COMMON-NEXT: br label
+ // CHECK-COMMON: load i1, i1* [[RCONS]]
+ // CHECK-COMMON-NEXT: br i1
+ // CHECK-COMMON: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
+ // CHECK-COMMON-NEXT: br label
+ // CHECK-COMMON: load i1, i1* [[LCONS]]
+ // CHECK-COMMON-NEXT: br i1
+ // CHECK-COMMON: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]])
+ // CHECK-COMMON-NEXT: br label
+ // CHECK-COMMON: ret void
b ? A(2) : A(3);
}
}
namespace PR11365 {
struct A { A(); ~A(); };
- // CHECK-LABEL: define void @_ZN7PR113653fooEv(
+ // CHECK-COMMON-LABEL: define void @_ZN7PR113653fooEv(
void foo() {
- // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]], [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0
- // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 3
- // CHECK-NEXT: br label
-
- // CHECK: [[PHI:%.*]] = phi
- // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PHI]], i64 -1
- // CHECK-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]])
- // CHECK-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]]
- // CHECK-NEXT: br i1
+ // CHECK-COMMON: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]], [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0
+ // CHECK-COMMON-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 3
+ // CHECK-COMMON-NEXT: br label
+
+ // CHECK-COMMON: [[PHI:%.*]] = phi
+ // CHECK-COMMON-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PHI]], i64 -1
+ // CHECK-COMMON-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]])
+ // CHECK-COMMON-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]]
+ // CHECK-COMMON-NEXT: br i1
(void) (A [3]) {};
}
}
namespace AssignmentOp {
struct A { ~A(); };
struct B { A operator=(const B&); };
struct C : B { B b1, b2; };
- // CHECK-LABEL: define void @_ZN12AssignmentOp1fE
+ // CHECK-COMMON-LABEL: define void @_ZN12AssignmentOp1fE
void f(C &c1, const C &c2) {
- // CHECK: call {{.*}} @_ZN12AssignmentOp1CaSERKS0_(
+ // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1CaSERKS0_(
c1 = c2;
}
// Ensure that each 'A' temporary is destroyed before the next subobject is
// copied.
- // CHECK: define {{.*}} @_ZN12AssignmentOp1CaSERKS0_(
- // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS
- // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
- // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS
- // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
- // CHECK: call {{.*}} @_ZN12AssignmentOp1BaSERKS
- // CHECK: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
+ // CHECK-COMMON: define {{.*}} @_ZN12AssignmentOp1CaSERKS0_(
+ // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1BaSERKS
+ // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
+ // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1BaSERKS
+ // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
+ // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1BaSERKS
+ // CHECK-COMMON: call {{.*}} @_ZN12AssignmentOp1AD1Ev(
}
namespace BindToSubobject {
@@ -618,50 +620,50 @@
void f(), g();
- // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE_)
- // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1aE_ to i8*), i8* @__dso_handle)
- // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1aE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1aE, align 8
+ // CHECK-COMMON: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1aE_)
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1aE_ to i8*), i8* @__dso_handle)
+ // CHECK-COMMON: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1aE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1aE, align 8
int &&a = A().a;
- // CHECK: call void @_ZN15BindToSubobject1fEv()
- // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE_)
- // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1bE_ to i8*), i8* @__dso_handle)
- // CHECK: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1bE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1bE, align 8
+ // CHECK-COMMON: call void @_ZN15BindToSubobject1fEv()
+ // CHECK-COMMON: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1bE_)
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1bE_ to i8*), i8* @__dso_handle)
+ // CHECK-COMMON: store i32* getelementptr inbounds ({{.*}} @_ZGRN15BindToSubobject1bE_, i32 0, i32 0), i32** @_ZN15BindToSubobject1bE, align 8
int &&b = (f(), A().a);
int A::*h();
- // CHECK: call void @_ZN15BindToSubobject1fEv()
- // CHECK: call void @_ZN15BindToSubobject1gEv()
- // CHECK: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE_)
- // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE_ to i8*), i8* @__dso_handle)
- // CHECK: call {{.*}} @_ZN15BindToSubobject1hE
- // CHECK: getelementptr
- // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1cE, align 8
+ // CHECK-COMMON: call void @_ZN15BindToSubobject1fEv()
+ // CHECK-COMMON: call void @_ZN15BindToSubobject1gEv()
+ // CHECK-COMMON: call void @_ZN15BindToSubobject1AC1Ev({{.*}} @_ZGRN15BindToSubobject1cE_)
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1AD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1cE_ to i8*), i8* @__dso_handle)
+ // CHECK-COMMON: call {{.*}} @_ZN15BindToSubobject1hE
+ // CHECK-COMMON: getelementptr
+ // CHECK-COMMON: store i32* {{.*}}, i32** @_ZN15BindToSubobject1cE, align 8
int &&c = (f(), (g(), A().*h()));
struct B {
int padding;
A a;
};
- // CHECK: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE_)
- // CHECK: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE_ to i8*), i8* @__dso_handle)
- // CHECK: call {{.*}} @_ZN15BindToSubobject1hE
- // CHECK: getelementptr {{.*}} getelementptr
- // CHECK: store i32* {{.*}}, i32** @_ZN15BindToSubobject1dE, align 8
+ // CHECK-COMMON: call void @_ZN15BindToSubobject1BC1Ev({{.*}} @_ZGRN15BindToSubobject1dE_)
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} bitcast ({{.*}} @_ZN15BindToSubobject1BD1Ev to void (i8*)*), i8* bitcast ({{.*}} @_ZGRN15BindToSubobject1dE_ to i8*), i8* @__dso_handle)
+ // CHECK-COMMON: call {{.*}} @_ZN15BindToSubobject1hE
+ // CHECK-COMMON: getelementptr {{.*}} getelementptr
+ // CHECK-COMMON: store i32* {{.*}}, i32** @_ZN15BindToSubobject1dE, align 8
int &&d = (B().a).*h();
}
namespace Bitfield {
struct S { int a : 5; ~S(); };
// Do not lifetime extend the S() temporary here.
- // CHECK: alloca
- // CHECK: call {{.*}}memset
- // CHECK: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE_
- // CHECK: call void @_ZN8Bitfield1SD1
- // CHECK: store i32* @_ZGRN8Bitfield1rE_, i32** @_ZN8Bitfield1rE, align 8
+ // CHECK-COMMON: alloca
+ // CHECK-COMMON: call {{.*}}memset
+ // CHECK-COMMON: store i32 {{.*}}, i32* @_ZGRN8Bitfield1rE_
+ // CHECK-COMMON: call void @_ZN8Bitfield1SD1
+ // CHECK-COMMON: store i32* @_ZGRN8Bitfield1rE_, i32** @_ZN8Bitfield1rE, align 8
int &&r = S().a;
}
@@ -672,16 +674,16 @@
vi4a v;
vi4b w;
};
- // CHECK: alloca
- // CHECK: extractelement
- // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1rE_
- // CHECK: store i32* @_ZGRN6Vector1rE_, i32** @_ZN6Vector1rE,
+ // CHECK-COMMON: alloca
+ // CHECK-COMMON: extractelement
+ // CHECK-COMMON: store i32 {{.*}}, i32* @_ZGRN6Vector1rE_
+ // CHECK-COMMON: store i32* @_ZGRN6Vector1rE_, i32** @_ZN6Vector1rE,
int &&r = S().v[1];
- // CHECK: alloca
- // CHECK: extractelement
- // CHECK: store i32 {{.*}}, i32* @_ZGRN6Vector1sE_
- // CHECK: store i32* @_ZGRN6Vector1sE_, i32** @_ZN6Vector1sE,
+ // CHECK-COMMON: alloca
+ // CHECK-COMMON: extractelement
+ // CHECK-COMMON: store i32 {{.*}}, i32* @_ZGRN6Vector1sE_
+ // CHECK-COMMON: store i32* @_ZGRN6Vector1sE_, i32** @_ZN6Vector1sE,
int &&s = S().w[1];
// FIXME PR16204: The following code leads to an assertion in Sema.
//int &&s = S().w.y;
@@ -691,15 +693,15 @@
struct A { A(int); ~A(); };
void g();
- // CHECK-LABEL: define void @_ZN24ImplicitTemporaryCleanup1fEv(
+ // CHECK-COMMON-LABEL: define void @_ZN24ImplicitTemporaryCleanup1fEv(
void f() {
- // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AC1Ei(
+ // CHECK-COMMON: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AC1Ei(
A &&a = 0;
- // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1gEv(
+ // CHECK-COMMON: call {{.*}} @_ZN24ImplicitTemporaryCleanup1gEv(
g();
- // CHECK: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AD1Ev(
+ // CHECK-COMMON: call {{.*}} @_ZN24ImplicitTemporaryCleanup1AD1Ev(
}
}
@@ -712,70 +714,70 @@
E &&e1 = { A(), B(), D().c };
- // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e1E.*]])
- // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]]
- // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]], i32 0, i32 0)
+ // CHECK-COMMON: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e1E.*]])
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]]
+ // CHECK-COMMON: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE:_ZGRN17MultipleExtension2e1E.*]], i32 0, i32 0)
- // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 1))
+ // CHECK-COMMON: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 1))
- // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]])
- // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]]
- // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 2)
- // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[TEMPE]]
- // CHECK: store {{.*}} @[[TEMPE]], %"struct.MultipleExtension::E"** @_ZN17MultipleExtension2e1E, align 8
+ // CHECK-COMMON: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e1E.*]])
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]]
+ // CHECK-COMMON: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[TEMPE]], i32 0, i32 2)
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[TEMPE]]
+ // CHECK-COMMON: store {{.*}} @[[TEMPE]], %"struct.MultipleExtension::E"** @_ZN17MultipleExtension2e1E, align 8
E e2 = { A(), B(), D().c };
- // CHECK: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e2E.*]])
- // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]]
- // CHECK: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[E:_ZN17MultipleExtension2e2E]], i32 0, i32 0)
+ // CHECK-COMMON: call void @_ZN17MultipleExtension1AC1Ev({{.*}} @[[TEMPA:_ZGRN17MultipleExtension2e2E.*]])
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1AD1Ev {{.*}} @[[TEMPA]]
+ // CHECK-COMMON: store {{.*}} @[[TEMPA]], {{.*}} getelementptr inbounds ({{.*}} @[[E:_ZN17MultipleExtension2e2E]], i32 0, i32 0)
- // CHECK: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 1))
+ // CHECK-COMMON: call void @_ZN17MultipleExtension1BC1Ev({{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 1))
- // CHECK: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]])
- // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]]
- // CHECK: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 2)
- // CHECK: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[E]]
+ // CHECK-COMMON: call void @_ZN17MultipleExtension1DC1Ev({{.*}} @[[TEMPD:_ZGRN17MultipleExtension2e2E.*]])
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1DD1Ev {{.*}} @[[TEMPD]]
+ // CHECK-COMMON: store {{.*}} @[[TEMPD]], {{.*}} getelementptr inbounds ({{.*}} @[[E]], i32 0, i32 2)
+ // CHECK-COMMON: call i32 @__cxa_atexit({{.*}} @_ZN17MultipleExtension1ED1Ev {{.*}} @[[E]]
void g();
- // CHECK: define void @[[NS:_ZN17MultipleExtension]]1fEv(
+ // CHECK-COMMON: define void @[[NS:_ZN17MultipleExtension]]1fEv(
void f() {
E &&e1 = { A(), B(), D().c };
- // CHECK: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0
- // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]])
- // CHECK: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]]
- // CHECK: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 1
- // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]])
- // CHECK: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2
- // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]])
- // CHECK: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i32 0, i32 1
- // CHECK: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]]
- // CHECK: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]]
+ // CHECK-COMMON: %[[TEMPE1_A:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1:.*]], i32 0, i32 0
+ // CHECK-COMMON: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA1:.*]])
+ // CHECK-COMMON: store {{.*}} %[[TEMPA1]], {{.*}} %[[TEMPE1_A]]
+ // CHECK-COMMON: %[[TEMPE1_B:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 1
+ // CHECK-COMMON: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE1_B]])
+ // CHECK-COMMON: %[[TEMPE1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPE1]], i32 0, i32 2
+ // CHECK-COMMON: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD1:.*]])
+ // CHECK-COMMON: %[[TEMPD1_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD1]], i32 0, i32 1
+ // CHECK-COMMON: store {{.*}} %[[TEMPD1_C]], {{.*}} %[[TEMPE1_C]]
+ // CHECK-COMMON: store {{.*}} %[[TEMPE1]], {{.*}} %[[E1:.*]]
g();
- // CHECK: call void @[[NS]]1gEv()
+ // CHECK-COMMON: call void @[[NS]]1gEv()
E e2 = { A(), B(), D().c };
- // CHECK: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0
- // CHECK: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]])
- // CHECK: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]]
- // CHECK: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 1
- // CHECK: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]])
- // CHECK: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2
- // CHECK: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]])
- // CHECK: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i32 0, i32 1
- // CHECK: store {{.*}} %[[TEMPD2_C]], {{.*}}* %[[TEMPE2_C]]
+ // CHECK-COMMON: %[[TEMPE2_A:.*]] = getelementptr inbounds {{.*}} %[[E2:.*]], i32 0, i32 0
+ // CHECK-COMMON: call void @[[NS]]1AC1Ev({{.*}} %[[TEMPA2:.*]])
+ // CHECK-COMMON: store {{.*}} %[[TEMPA2]], {{.*}} %[[TEMPE2_A]]
+ // CHECK-COMMON: %[[TEMPE2_B:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 1
+ // CHECK-COMMON: call void @[[NS]]1BC1Ev({{.*}} %[[TEMPE2_B]])
+ // CHECK-COMMON: %[[TEMPE2_C:.*]] = getelementptr inbounds {{.*}} %[[E2]], i32 0, i32 2
+ // CHECK-COMMON: call void @[[NS]]1DC1Ev({{.*}} %[[TEMPD2:.*]])
+ // CHECK-COMMON: %[[TEMPD2_C:.*]] = getelementptr inbounds {{.*}} %[[TEMPD2]], i32 0, i32 1
+ // CHECK-COMMON: store {{.*}} %[[TEMPD2_C]], {{.*}}* %[[TEMPE2_C]]
g();
- // CHECK: call void @[[NS]]1gEv()
-
- // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[E2]])
- // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD2]])
- // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA2]])
- // CHECK: call void @[[NS]]1ED1Ev({{.*}} %[[TEMPE1]])
- // CHECK: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD1]])
- // CHECK: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA1]])
+ // CHECK-COMMON: call void @[[NS]]1gEv()
+
+ // CHECK-COMMON: call void @[[NS]]1ED1Ev({{.*}} %[[E2]])
+ // CHECK-COMMON: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD2]])
+ // CHECK-COMMON: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA2]])
+ // CHECK-COMMON: call void @[[NS]]1ED1Ev({{.*}} %[[TEMPE1]])
+ // CHECK-COMMON: call void @[[NS]]1DD1Ev({{.*}} %[[TEMPD1]])
+ // CHECK-COMMON: call void @[[NS]]1AD1Ev({{.*}} %[[TEMPA1]])
}
}
@@ -785,36 +787,36 @@
void f() {
using T = A[3];
- // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 1
- // CHECK-NOT: @_ZN11ArrayAccess1AD
- // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 2
- // CHECK-NOT: @_ZN11ArrayAccess1AD
- // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 3
- // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 1
+ // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 2
+ // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 3
+ // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD
A &&a = T{1, 2, 3}[1];
- // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 4
- // CHECK-NOT: @_ZN11ArrayAccess1AD
- // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 5
- // CHECK-NOT: @_ZN11ArrayAccess1AD
- // CHECK: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 6
- // CHECK-NOT: @_ZN11ArrayAccess1AD
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 4
+ // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 5
+ // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1AC1Ei({{.*}}, i32 6
+ // CHECK-COMMON-NOT: @_ZN11ArrayAccess1AD
A &&b = 2[T{4, 5, 6}];
- // CHECK: call void @_ZN11ArrayAccess1gEv(
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1gEv(
g();
- // CHECK: call void @_ZN11ArrayAccess1AD
- // CHECK: call void @_ZN11ArrayAccess1AD
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1AD
+ // CHECK-COMMON: call void @_ZN11ArrayAccess1AD
}
}
namespace PR14130 {
struct S { S(int); };
struct U { S &&s; };
U v { { 0 } };
- // CHECK: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 0)
- // CHECK: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE
+ // CHECK-COMMON: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 0)
+ // CHECK-COMMON: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE
}
namespace Ctor {
@@ -824,8 +826,8 @@
A &&a;
B() : a{} { f(); }
} b;
- // CHECK: define {{.*}}void @_ZN4Ctor1BC1Ev(
- // CHECK: call void @_ZN4Ctor1AC1Ev(
- // CHECK: call void @_ZN4Ctor1fEv(
- // CHECK: call void @_ZN4Ctor1AD1Ev(
+ // CHECK-COMMON: define {{.*}}void @_ZN4Ctor1BC1Ev(
+ // CHECK-COMMON: call void @_ZN4Ctor1AC1Ev(
+ // CHECK-COMMON: call void @_ZN4Ctor1fEv(
+ // CHECK-COMMON: call void @_ZN4Ctor1AD1Ev(
}
Index: test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
+++ test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp
@@ -1,126 +1,129 @@
-// RUN: %clang_cc1 -emit-llvm -O1 -o - -fexceptions -triple=i386-pc-win32 %s | FileCheck %s
+// %clang_cc1 -emit-llvm -O1 -o - -fexceptions -triple=i386-pc-win32 %s | FileCheck %s -check-prefixes=CHECK-COMMON,CHECK-NONNULL
+// RUN: %clang_cc1 -emit-llvm -O1 -o - -fexceptions -fno-delete-null-pointer-checks -triple=i386-pc-win32 %s | FileCheck %s -check-prefixes=CHECK-COMMON,CHECK-NO-NULL
struct S { char a; };
struct V { virtual void f(); };
struct A : virtual V {};
struct B : S, virtual V {};
struct T {};
T* test0() { return dynamic_cast<T*>((B*)0); }
-// CHECK-LABEL: define dso_local noalias %struct.T* @"?test0@@YAPAUT@@XZ"()
-// CHECK: ret %struct.T* null
+// CHECK-COMMON-LABEL: define dso_local noalias %struct.T* @"?test0@@YAPAUT@@XZ"()
+// CHECK-COMMON: ret %struct.T* null
T* test1(V* x) { return &dynamic_cast<T&>(*x); }
-// CHECK-LABEL: define dso_local %struct.T* @"?test1@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
-// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
-// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
-// CHECK-NEXT: ret %struct.T* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test1@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
+// CHECK-COMMON: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-COMMON-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-COMMON-NEXT: ret %struct.T* [[RET]]
T* test2(A* x) { return &dynamic_cast<T&>(*x); }
-// CHECK-LABEL: define dso_local %struct.T* @"?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
-// CHECK: [[CAST:%.*]] = bitcast %struct.A* %x to i8*
-// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
-// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
-// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
-// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
-// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[VBOFFS]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
-// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
-// CHECK-NEXT: ret %struct.T* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
+// CHECK-COMMON: [[CAST:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
+// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[VBOFFS]]
+// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-COMMON-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-COMMON-NEXT: ret %struct.T* [[RET]]
T* test3(B* x) { return &dynamic_cast<T&>(*x); }
-// CHECK-LABEL: define dso_local %struct.T* @"?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
-// CHECK: [[VOIDP:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
-// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 4
-// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR:%.*]] to i32**
-// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
-// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
-// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
-// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
-// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[DELTA]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
-// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
-// CHECK-NEXT: ret %struct.T* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
+// CHECK-COMMON: [[VOIDP:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-COMMON-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 4
+// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR:%.*]] to i32**
+// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-COMMON-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[DELTA]]
+// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 1)
+// CHECK-COMMON-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-COMMON-NEXT: ret %struct.T* [[RET]]
T* test4(V* x) { return dynamic_cast<T*>(x); }
-// CHECK-LABEL: define dso_local %struct.T* @"?test4@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
-// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
-// CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
-// CHECK-NEXT: ret %struct.T* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test4@@YAPAUT@@PAUV@@@Z"(%struct.V* %x)
+// CHECK-COMMON: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[CAST]], i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUV@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-COMMON-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-COMMON-NEXT: ret %struct.T* [[RET]]
T* test5(A* x) { return dynamic_cast<T*>(x); }
-// CHECK-LABEL: define dso_local %struct.T* @"?test5@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
-// CHECK: [[CHECK:%.*]] = icmp eq %struct.A* %x, null
-// CHECK-NEXT: br i1 [[CHECK]]
-// CHECK: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
-// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
-// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
-// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
-// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
-// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
-// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
-// CHECK-NEXT: br label
-// CHECK: [[RET:%.*]] = phi %struct.T*
-// CHECK-NEXT: ret %struct.T* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test5@@YAPAUT@@PAUA@@@Z"(%struct.A* %x)
+// CHECK-COMMON: [[CHECK:%.*]] = icmp eq %struct.A* %x, null
+// CHECK-COMMON-NEXT: br i1 [[CHECK]]
+// CHECK-COMMON: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
+// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
+// CHECK-COMMON-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUA@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-COMMON-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-COMMON-NEXT: br label
+// CHECK-COMMON: [[RET:%.*]] = phi %struct.T*
+// CHECK-COMMON-NEXT: ret %struct.T* [[RET]]
T* test6(B* x) { return dynamic_cast<T*>(x); }
-// CHECK-LABEL: define dso_local %struct.T* @"?test6@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
-// CHECK: [[CHECK:%.*]] = icmp eq %struct.B* %x, null
-// CHECK-NEXT: br i1 [[CHECK]]
-// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
-// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4
-// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32**
-// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
-// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
-// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
-// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
-// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
-// CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
-// CHECK-NEXT: br label
-// CHECK: [[RET:%.*]] = phi %struct.T*
-// CHECK-NEXT: ret %struct.T* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local %struct.T* @"?test6@@YAPAUT@@PAUB@@@Z"(%struct.B* %x)
+// CHECK-COMMON: [[CHECK:%.*]] = icmp eq %struct.B* %x, null
+// CHECK-COMMON-NEXT: br i1 [[CHECK]]
+// CHECK-COMMON: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-COMMON-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4
+// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32**
+// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-COMMON-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
+// CHECK-NONNULL: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* nonnull [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-NO-NULL: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUB@@@8" to i8*), i8* {{.*}}bitcast (%rtti.TypeDescriptor7* @"??_R0?AUT@@@8" to i8*), i32 0)
+// CHECK-COMMON-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T*
+// CHECK-COMMON-NEXT: br label
+// CHECK-COMMON: [[RET:%.*]] = phi %struct.T*
+// CHECK-COMMON-NEXT: ret %struct.T* [[RET]]
void* test7(V* x) { return dynamic_cast<void*>(x); }
-// CHECK-LABEL: define dso_local i8* @"?test7@@YAPAXPAUV@@@Z"(%struct.V* %x)
-// CHECK: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
-// CHECK-NEXT: [[RET:%.*]] = tail call i8* @__RTCastToVoid(i8* [[CAST]])
-// CHECK-NEXT: ret i8* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local i8* @"?test7@@YAPAXPAUV@@@Z"(%struct.V* %x)
+// CHECK-COMMON: [[CAST:%.*]] = bitcast %struct.V* %x to i8*
+// CHECK-COMMON-NEXT: [[RET:%.*]] = tail call i8* @__RTCastToVoid(i8* [[CAST]])
+// CHECK-COMMON-NEXT: ret i8* [[RET]]
void* test8(A* x) { return dynamic_cast<void*>(x); }
-// CHECK-LABEL: define dso_local i8* @"?test8@@YAPAXPAUA@@@Z"(%struct.A* %x)
-// CHECK: [[CHECK:%.*]] = icmp eq %struct.A* %x, null
-// CHECK-NEXT: br i1 [[CHECK]]
-// CHECK: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
-// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
-// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
-// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
-// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
-// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
-// CHECK-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
-// CHECK-NEXT: br label
-// CHECK: [[RET:%.*]] = phi i8*
-// CHECK-NEXT: ret i8* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local i8* @"?test8@@YAPAXPAUA@@@Z"(%struct.A* %x)
+// CHECK-COMMON: [[CHECK:%.*]] = icmp eq %struct.A* %x, null
+// CHECK-COMMON-NEXT: br i1 [[CHECK]]
+// CHECK-COMMON: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8*
+// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0
+// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]]
+// CHECK-COMMON-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-COMMON-NEXT: br label
+// CHECK-COMMON: [[RET:%.*]] = phi i8*
+// CHECK-COMMON-NEXT: ret i8* [[RET]]
void* test9(B* x) { return dynamic_cast<void*>(x); }
-// CHECK-LABEL: define dso_local i8* @"?test9@@YAPAXPAUB@@@Z"(%struct.B* %x)
-// CHECK: [[CHECK:%.*]] = icmp eq %struct.B* %x, null
-// CHECK-NEXT: br i1 [[CHECK]]
-// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
-// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4
-// CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32**
-// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
-// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
-// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
-// CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
-// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
-// CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]])
-// CHECK-NEXT: br label
-// CHECK: [[RET:%.*]] = phi i8*
-// CHECK-NEXT: ret i8* [[RET]]
+// CHECK-COMMON-LABEL: define dso_local i8* @"?test9@@YAPAXPAUB@@@Z"(%struct.B* %x)
+// CHECK-COMMON: [[CHECK:%.*]] = icmp eq %struct.B* %x, null
+// CHECK-COMMON-NEXT: br i1 [[CHECK]]
+// CHECK-COMMON: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0
+// CHECK-COMMON-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4
+// CHECK-COMMON-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32**
+// CHECK-COMMON-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4
+// CHECK-COMMON-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1
+// CHECK-COMMON-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4
+// CHECK-COMMON-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4
+// CHECK-COMMON-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]]
+// CHECK-NONNULL: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* nonnull [[ADJ]])
+// CHECK-NO-NULL: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]])
+// CHECK-COMMON-NEXT: br label
+// CHECK-COMMON: [[RET:%.*]] = phi i8*
+// CHECK-COMMON-NEXT: ret i8* [[RET]]
namespace PR25606 {
struct Cleanup {
@@ -134,10 +137,10 @@
Cleanup c;
return dynamic_cast<S3 *>(&s);
}
-// CHECK-LABEL: define dso_local %"struct.PR25606::S3"* @"?f@PR25606@@YAPAUS3@1@AAUS2@1@@Z"(
-// CHECK: [[CALL:%.*]] = invoke i8* @__RTDynamicCast
+// CHECK-COMMON-LABEL: define dso_local %"struct.PR25606::S3"* @"?f@PR25606@@YAPAUS3@1@AAUS2@1@@Z"(
+// CHECK-COMMON: [[CALL:%.*]] = invoke i8* @__RTDynamicCast
-// CHECK: [[BC:%.*]] = bitcast i8* [[CALL]] to %"struct.PR25606::S3"*
-// CHECK: call x86_thiscallcc void @"??1Cleanup@PR25606@@QAE@XZ"(
-// CHECK: ret %"struct.PR25606::S3"* [[BC]]
+// CHECK-COMMON: [[BC:%.*]] = bitcast i8* [[CALL]] to %"struct.PR25606::S3"*
+// CHECK-COMMON: call x86_thiscallcc void @"??1Cleanup@PR25606@@QAE@XZ"(
+// CHECK-NONNULL: ret %"struct.PR25606::S3"* [[BC]]
}
Index: test/CodeGenCXX/constructors.cpp
===================================================================
--- test/CodeGenCXX/constructors.cpp
+++ test/CodeGenCXX/constructors.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output --check-prefixes=CHECK-COMMON,CHECK-NONNULL
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -fno-delete-null-pointer-checks -o - | FileCheck %s --implicit-check-not=should_not_appear_in_output --check-prefixes=CHECK-COMMON,CHECK-NO-NULL
struct Member { int x; Member(); Member(int); Member(const Member &); };
struct VBase { int x; VBase(); VBase(int); VBase(const VBase &); };
@@ -21,19 +22,21 @@
A::A(struct Undeclared &ref) : mem(0) {}
// Check that delegation works.
-// CHECK-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
-// CHECK: call void @_ZN6MemberC1Ei(
+// CHECK-NONNULL-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// CHECK-NO-NULL-LABEL: define void @_ZN1AC2ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-COMMON: call void @_ZN6MemberC1Ei(
-// CHECK-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
-// CHECK: call void @_ZN1AC2ER10Undeclared(
+// CHECK-NONNULL-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// CHECK-NO-NULL-LABEL: define void @_ZN1AC1ER10Undeclared(%struct.A* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-COMMON: call void @_ZN1AC2ER10Undeclared(
A::A(ValueClass v) : mem(v.y - v.x) {}
-// CHECK-LABEL: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
-// CHECK: call void @_ZN6MemberC1Ei(
+// CHECK-COMMON-LABEL: define void @_ZN1AC2E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
+// CHECK-COMMON: call void @_ZN6MemberC1Ei(
-// CHECK-LABEL: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
-// CHECK: call void @_ZN1AC2E10ValueClass(
+// CHECK-COMMON-LABEL: define void @_ZN1AC1E10ValueClass(%struct.A* %this, i64 %v.coerce) unnamed_addr
+// CHECK-COMMON: call void @_ZN1AC2E10ValueClass(
/* Test that things work for inheritance. */
struct B : A {
@@ -43,12 +46,14 @@
B::B(struct Undeclared &ref) : A(ref), mem(1) {}
-// CHECK-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
-// CHECK: call void @_ZN1AC2ER10Undeclared(
-// CHECK: call void @_ZN6MemberC1Ei(
+// CHECK-NONNULL-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// CHECK-NO-NULL-LABEL: define void @_ZN1BC2ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-COMMON: call void @_ZN1AC2ER10Undeclared(
+// CHECK-COMMON: call void @_ZN6MemberC1Ei(
-// CHECK-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
-// CHECK: call void @_ZN1BC2ER10Undeclared(
+// CHECK-NONNULL-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* nonnull %ref) unnamed_addr
+// CHECK-NO-NULL-LABEL: define void @_ZN1BC1ER10Undeclared(%struct.B* %this, %struct.Undeclared* %ref) unnamed_addr
+// CHECK-COMMON: call void @_ZN1BC2ER10Undeclared(
/* Test that the delegation optimization is disabled for classes with
@@ -62,13 +67,13 @@
};
C::C(int x) : A(ValueClass(x, x+1)), mem(x * x) {}
-// CHECK-LABEL: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr
-// CHECK: call void @_ZN6MemberC1Ei(
+// CHECK-COMMON-LABEL: define void @_ZN1CC2Ei(%struct.C* %this, i8** %vtt, i32 %x) unnamed_addr
+// CHECK-COMMON: call void @_ZN6MemberC1Ei(
-// CHECK-LABEL: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr
-// CHECK: call void @_ZN10ValueClassC1Eii(
-// CHECK: call void @_ZN1AC2E10ValueClass(
-// CHECK: call void @_ZN6MemberC1Ei(
+// CHECK-COMMON-LABEL: define void @_ZN1CC1Ei(%struct.C* %this, i32 %x) unnamed_addr
+// CHECK-COMMON: call void @_ZN10ValueClassC1Eii(
+// CHECK-COMMON: call void @_ZN1AC2E10ValueClass(
+// CHECK-COMMON: call void @_ZN6MemberC1Ei(
/* Test that the delegation optimization is disabled for varargs
@@ -80,15 +85,15 @@
D::D(int x, ...) : A(ValueClass(x, x+1)), mem(x*x) {}
-// CHECK-LABEL: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
-// CHECK: call void @_ZN10ValueClassC1Eii(
-// CHECK: call void @_ZN1AC2E10ValueClass(
-// CHECK: call void @_ZN6MemberC1Ei(
+// CHECK-COMMON-LABEL: define void @_ZN1DC2Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
+// CHECK-COMMON: call void @_ZN10ValueClassC1Eii(
+// CHECK-COMMON: call void @_ZN1AC2E10ValueClass(
+// CHECK-COMMON: call void @_ZN6MemberC1Ei(
-// CHECK-LABEL: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
-// CHECK: call void @_ZN10ValueClassC1Eii(
-// CHECK: call void @_ZN1AC2E10ValueClass(
-// CHECK: call void @_ZN6MemberC1Ei(
+// CHECK-COMMON-LABEL: define void @_ZN1DC1Eiz(%struct.D* %this, i32 %x, ...) unnamed_addr
+// CHECK-COMMON: call void @_ZN10ValueClassC1Eii(
+// CHECK-COMMON: call void @_ZN1AC2E10ValueClass(
+// CHECK-COMMON: call void @_ZN6MemberC1Ei(
// PR6622: this shouldn't crash
namespace test0 {
@@ -105,9 +110,9 @@
struct A { A(); void *ptr; };
struct B { B(); int x; A a[0]; };
B::B() {}
- // CHECK-LABEL: define void @_ZN5test11BC2Ev(
- // CHECK: [[THIS:%.*]] = load [[B:%.*]]*, [[B:%.*]]**
- // CHECK-NEXT: ret void
+ // CHECK-COMMON-LABEL: define void @_ZN5test11BC2Ev(
+ // CHECK-COMMON: [[THIS:%.*]] = load [[B:%.*]]*, [[B:%.*]]**
+ // CHECK-COMMON-NEXT: ret void
}
// Ensure that we
@@ -134,32 +139,32 @@
virtual ~A() = 0;
};
- // CHECK-LABEL: define void @_ZN8abstract1AD2Ev(
- // CHECK: call {{.*}}@_ZN8abstract1XD2Ev(
- // CHECK: ret
+ // CHECK-COMMON-LABEL: define void @_ZN8abstract1AD2Ev(
+ // CHECK-COMMON: call {{.*}}@_ZN8abstract1XD2Ev(
+ // CHECK-COMMON: ret
- // CHECK-LABEL: define void @_ZN8abstract1AD1Ev(
- // CHECK: call {{.*}}@llvm.trap(
- // CHECK: unreachable
+ // CHECK-COMMON-LABEL: define void @_ZN8abstract1AD1Ev(
+ // CHECK-COMMON: call {{.*}}@llvm.trap(
+ // CHECK-COMMON: unreachable
- // CHECK-LABEL: define void @_ZN8abstract1AD0Ev(
- // CHECK: call {{.*}}@llvm.trap(
- // CHECK: unreachable
+ // CHECK-COMMON-LABEL: define void @_ZN8abstract1AD0Ev(
+ // CHECK-COMMON: call {{.*}}@llvm.trap(
+ // CHECK-COMMON: unreachable
A::~A() {}
struct B : virtual should_not_appear_in_output<int>, X {
virtual void f() = 0;
~B();
};
- // CHECK-LABEL: define void @_ZN8abstract1BD2Ev(
- // CHECK: call {{.*}}@_ZN8abstract1XD2Ev(
- // CHECK: ret
+ // CHECK-COMMON-LABEL: define void @_ZN8abstract1BD2Ev(
+ // CHECK-COMMON: call {{.*}}@_ZN8abstract1XD2Ev(
+ // CHECK-COMMON: ret
- // CHECK-LABEL: define void @_ZN8abstract1BD1Ev(
- // CHECK: call {{.*}}@llvm.trap(
- // CHECK: unreachable
+ // CHECK-COMMON-LABEL: define void @_ZN8abstract1BD1Ev(
+ // CHECK-COMMON: call {{.*}}@llvm.trap(
+ // CHECK-COMMON: unreachable
- // CHECK-NOT: @_ZN8abstract1BD0Ev(
+ // CHECK-COMMON-NOT: @_ZN8abstract1BD0Ev(
B::~B() {}
}
Index: test/CodeGenCXX/address-space-ref.cpp
===================================================================
--- test/CodeGenCXX/address-space-ref.cpp
+++ test/CodeGenCXX/address-space-ref.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s -check-prefixes=PREFIX-COMMON,PREFIX-NONNULL
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -fno-delete-null-pointer-checks -emit-llvm -o - | FileCheck %s -check-prefixes=PREFIX-COMMON,PREFIX-NO-NULL
// For a reference to a complete type, output the dereferenceable attribute (in
// any address space).
@@ -9,7 +10,7 @@
return x;
}
-// CHECK: define dereferenceable(4) i32 addrspace(1)* @_Z3fooRU3AS1iS0_(i32 addrspace(1)* dereferenceable(4) %x, i32 addrspace(1)* dereferenceable(4) %y)
+// PREFIX-COMMON: define dereferenceable(4) i32 addrspace(1)* @_Z3fooRU3AS1iS0_(i32 addrspace(1)* dereferenceable(4) %x, i32 addrspace(1)* dereferenceable(4) %y)
// For a reference to an incomplete type in an alternate address space, output
// neither dereferenceable nor nonnull.
@@ -21,14 +22,15 @@
return x;
}
-// CHECK: define %class.bc addrspace(1)* @_Z3barRU3AS12bcS1_(%class.bc addrspace(1)* %x, %class.bc addrspace(1)* %y)
+// PREFIX-COMMON: define %class.bc addrspace(1)* @_Z3barRU3AS12bcS1_(%class.bc addrspace(1)* %x, %class.bc addrspace(1)* %y)
// For a reference to an incomplete type in addrspace(0), output nonnull.
bc & bar2(bc &x, bc & y) {
return x;
}
-// CHECK: define nonnull %class.bc* @_Z4bar2R2bcS0_(%class.bc* nonnull %x, %class.bc* nonnull %y)
+// PREFIX-NON-NULL: define nonnull %class.bc* @_Z4bar2R2bcS0_(%class.bc* nonnull %x, %class.bc* nonnull %y)
+// PREFIX-NO-NULL: define %class.bc* @_Z4bar2R2bcS0_(%class.bc* %x, %class.bc* %y)
Index: test/CodeGen/vla.c
===================================================================
--- test/CodeGen/vla.c
+++ test/CodeGen/vla.c
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s -check-prefixes=PREFIX-VLA,PREFIX-NONNULL
+// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -fno-delete-null-pointer-checks -o - | FileCheck %s -check-prefixes=PREFIX-VLA,PREFIX-NO-NULL
int b(char* x);
@@ -37,39 +38,39 @@
}
// rdar://8403108
-// CHECK-LABEL: define void @f_8403108
+// PREFIX-VLA-LABEL: define void @f_8403108
void f_8403108(unsigned x) {
- // CHECK: call i8* @llvm.stacksave()
+ // PREFIX-VLA: call i8* @llvm.stacksave()
char s1[x];
while (1) {
- // CHECK: call i8* @llvm.stacksave()
+ // PREFIX-VLA: call i8* @llvm.stacksave()
char s2[x];
if (1)
break;
- // CHECK: call void @llvm.stackrestore(i8*
+ // PREFIX-VLA: call void @llvm.stackrestore(i8*
}
- // CHECK: call void @llvm.stackrestore(i8*
+ // PREFIX-VLA: call void @llvm.stackrestore(i8*
}
// pr7827
void function(short width, int data[][width]) {} // expected-note {{passing argument to parameter 'data' here}}
void test() {
int bork[4][13];
- // CHECK: call void @function(i16 signext 1, i32* null)
+ // PREFIX-VLA: call void @function(i16 signext 1, i32* null)
function(1, 0);
- // CHECK: call void @function(i16 signext 1, i32* inttoptr
+ // PREFIX-VLA: call void @function(i16 signext 1, i32* inttoptr
function(1, 0xbadbeef); // expected-warning {{incompatible integer to pointer conversion passing}}
- // CHECK: call void @function(i16 signext 1, i32* {{.*}})
+ // PREFIX-VLA: call void @function(i16 signext 1, i32* {{.*}})
function(1, bork);
}
void function1(short width, int data[][width][width]) {}
void test1() {
int bork[4][13][15];
- // CHECK: call void @function1(i16 signext 1, i32* {{.*}})
+ // PREFIX-VLA: call void @function1(i16 signext 1, i32* {{.*}})
function1(1, bork);
- // CHECK: call void @function(i16 signext 1, i32* {{.*}})
+ // PREFIX-VLA: call void @function(i16 signext 1, i32* {{.*}})
function(1, bork[2]);
}
@@ -79,128 +80,129 @@
{
GLOB = 0;
char b[1][n+3]; /* Variable length array. */
- // CHECK: [[tmp_1:%.*]] = load i32, i32* @GLOB, align 4
- // CHECK-NEXT: add nsw i32 [[tmp_1]], 1
+ // PREFIX-VLA: [[tmp_1:%.*]] = load i32, i32* @GLOB, align 4
+ // PREFIX-VLA-NEXT: add nsw i32 [[tmp_1]], 1
__typeof__(b[GLOB++]) c;
return GLOB;
}
// http://llvm.org/PR8567
-// CHECK-LABEL: define double @test_PR8567
+// PREFIX-VLA-LABEL: define double @test_PR8567
double test_PR8567(int n, double (*p)[n][5]) {
- // CHECK: [[NV:%.*]] = alloca i32, align 4
- // CHECK-NEXT: [[PV:%.*]] = alloca [5 x double]*, align 4
- // CHECK-NEXT: store
- // CHECK-NEXT: store
- // CHECK-NEXT: [[N:%.*]] = load i32, i32* [[NV]], align 4
- // CHECK-NEXT: [[P:%.*]] = load [5 x double]*, [5 x double]** [[PV]], align 4
- // CHECK-NEXT: [[T0:%.*]] = mul nsw i32 1, [[N]]
- // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[P]], i32 [[T0]]
- // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[T1]], i32 2
- // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[T2]], i32 0, i32 3
- // CHECK-NEXT: [[T4:%.*]] = load double, double* [[T3]]
- // CHECK-NEXT: ret double [[T4]]
+ // PREFIX-VLA: [[NV:%.*]] = alloca i32, align 4
+ // PREFIX-VLA-NEXT: [[PV:%.*]] = alloca [5 x double]*, align 4
+ // PREFIX-VLA-NEXT: store
+ // PREFIX-VLA-NEXT: store
+ // PREFIX-VLA-NEXT: [[N:%.*]] = load i32, i32* [[NV]], align 4
+ // PREFIX-VLA-NEXT: [[P:%.*]] = load [5 x double]*, [5 x double]** [[PV]], align 4
+ // PREFIX-VLA-NEXT: [[T0:%.*]] = mul nsw i32 1, [[N]]
+ // PREFIX-VLA-NEXT: [[T1:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[P]], i32 [[T0]]
+ // PREFIX-VLA-NEXT: [[T2:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[T1]], i32 2
+ // PREFIX-VLA-NEXT: [[T3:%.*]] = getelementptr inbounds [5 x double], [5 x double]* [[T2]], i32 0, i32 3
+ // PREFIX-VLA-NEXT: [[T4:%.*]] = load double, double* [[T3]]
+ // PREFIX-VLA-NEXT: ret double [[T4]]
return p[1][2][3];
}
int test4(unsigned n, char (*p)[n][n+1][6]) {
- // CHECK-LABEL: define i32 @test4(
- // CHECK: [[N:%.*]] = alloca i32, align 4
- // CHECK-NEXT: [[P:%.*]] = alloca [6 x i8]*, align 4
- // CHECK-NEXT: [[P2:%.*]] = alloca [6 x i8]*, align 4
- // CHECK-NEXT: store i32
- // CHECK-NEXT: store [6 x i8]*
+ // PREFIX-VLA-LABEL: define i32 @test4(
+ // PREFIX-VLA: [[N:%.*]] = alloca i32, align 4
+ // PREFIX-VLA-NEXT: [[P:%.*]] = alloca [6 x i8]*, align 4
+ // PREFIX-VLA-NEXT: [[P2:%.*]] = alloca [6 x i8]*, align 4
+ // PREFIX-VLA-NEXT: store i32
+ // PREFIX-VLA-NEXT: store [6 x i8]*
// VLA captures.
- // CHECK-NEXT: [[DIM0:%.*]] = load i32, i32* [[N]], align 4
- // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4
- // CHECK-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1
-
- // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]*, [6 x i8]** [[P]], align 4
- // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[N]], align 4
- // CHECK-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2
- // CHECK-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
- // CHECK-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]]
- // CHECK-NEXT: [[T5:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* [[T0]], i32 [[T4]]
- // CHECK-NEXT: [[T6:%.*]] = load i32, i32* [[N]], align 4
- // CHECK-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4
- // CHECK-NEXT: [[T8:%.*]] = sub i32 0, [[T7]]
- // CHECK-NEXT: [[T9:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
- // CHECK-NEXT: [[T10:%.*]] = mul nsw i32 [[T8]], [[T9]]
- // CHECK-NEXT: [[T11:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* [[T5]], i32 [[T10]]
- // CHECK-NEXT: store [6 x i8]* [[T11]], [6 x i8]** [[P2]], align 4
+ // PREFIX-VLA-NEXT: [[DIM0:%.*]] = load i32, i32* [[N]], align 4
+ // PREFIX-VLA-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4
+ // PREFIX-VLA-NEXT: [[DIM1:%.*]] = add i32 [[T0]], 1
+
+ // PREFIX-VLA-NEXT: [[T0:%.*]] = load [6 x i8]*, [6 x i8]** [[P]], align 4
+ // PREFIX-VLA-NEXT: [[T1:%.*]] = load i32, i32* [[N]], align 4
+ // PREFIX-VLA-NEXT: [[T2:%.*]] = udiv i32 [[T1]], 2
+ // PREFIX-VLA-NEXT: [[T3:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
+ // PREFIX-VLA-NEXT: [[T4:%.*]] = mul nsw i32 [[T2]], [[T3]]
+ // PREFIX-VLA-NEXT: [[T5:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* [[T0]], i32 [[T4]]
+ // PREFIX-VLA-NEXT: [[T6:%.*]] = load i32, i32* [[N]], align 4
+ // PREFIX-VLA-NEXT: [[T7:%.*]] = udiv i32 [[T6]], 4
+ // PREFIX-VLA-NEXT: [[T8:%.*]] = sub i32 0, [[T7]]
+ // PREFIX-VLA-NEXT: [[T9:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
+ // PREFIX-VLA-NEXT: [[T10:%.*]] = mul nsw i32 [[T8]], [[T9]]
+ // PREFIX-VLA-NEXT: [[T11:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* [[T5]], i32 [[T10]]
+ // PREFIX-VLA-NEXT: store [6 x i8]* [[T11]], [6 x i8]** [[P2]], align 4
__typeof(p) p2 = (p + n/2) - n/4;
- // CHECK-NEXT: [[T0:%.*]] = load [6 x i8]*, [6 x i8]** [[P2]], align 4
- // CHECK-NEXT: [[T1:%.*]] = load [6 x i8]*, [6 x i8]** [[P]], align 4
- // CHECK-NEXT: [[T2:%.*]] = ptrtoint [6 x i8]* [[T0]] to i32
- // CHECK-NEXT: [[T3:%.*]] = ptrtoint [6 x i8]* [[T1]] to i32
- // CHECK-NEXT: [[T4:%.*]] = sub i32 [[T2]], [[T3]]
- // CHECK-NEXT: [[T5:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
- // CHECK-NEXT: [[T6:%.*]] = mul nuw i32 6, [[T5]]
- // CHECK-NEXT: [[T7:%.*]] = sdiv exact i32 [[T4]], [[T6]]
- // CHECK-NEXT: ret i32 [[T7]]
+ // PREFIX-VLA-NEXT: [[T0:%.*]] = load [6 x i8]*, [6 x i8]** [[P2]], align 4
+ // PREFIX-VLA-NEXT: [[T1:%.*]] = load [6 x i8]*, [6 x i8]** [[P]], align 4
+ // PREFIX-VLA-NEXT: [[T2:%.*]] = ptrtoint [6 x i8]* [[T0]] to i32
+ // PREFIX-VLA-NEXT: [[T3:%.*]] = ptrtoint [6 x i8]* [[T1]] to i32
+ // PREFIX-VLA-NEXT: [[T4:%.*]] = sub i32 [[T2]], [[T3]]
+ // PREFIX-VLA-NEXT: [[T5:%.*]] = mul nuw i32 [[DIM0]], [[DIM1]]
+ // PREFIX-VLA-NEXT: [[T6:%.*]] = mul nuw i32 6, [[T5]]
+ // PREFIX-VLA-NEXT: [[T7:%.*]] = sdiv exact i32 [[T4]], [[T6]]
+ // PREFIX-VLA-NEXT: ret i32 [[T7]]
return p2 - p;
}
// rdar://11485774
void test5(void)
{
- // CHECK-LABEL: define void @test5(
+ // PREFIX-VLA-LABEL: define void @test5(
int a[5], i = 0;
- // CHECK: [[A:%.*]] = alloca [5 x i32], align 4
- // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
- // CHECK-NEXT: [[CL:%.*]] = alloca i32*, align 4
- // CHECK-NEXT: store i32 0, i32* [[I]], align 4
+ // PREFIX-VLA: [[A:%.*]] = alloca [5 x i32], align 4
+ // PREFIX-VLA-NEXT: [[I:%.*]] = alloca i32, align 4
+ // PREFIX-VLA-NEXT: [[CL:%.*]] = alloca i32*, align 4
+ // PREFIX-VLA-NEXT: store i32 0, i32* [[I]], align 4
(typeof(++i, (int (*)[i])a)){&a} += 0;
- // CHECK-NEXT: [[Z:%.*]] = load i32, i32* [[I]], align 4
- // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[Z]], 1
- // CHECK-NEXT: store i32 [[INC]], i32* [[I]], align 4
- // CHECK-NEXT: [[O:%.*]] = load i32, i32* [[I]], align 4
- // CHECK-NEXT: [[AR:%.*]] = getelementptr inbounds [5 x i32], [5 x i32]* [[A]], i32 0, i32 0
- // CHECK-NEXT: [[T:%.*]] = bitcast [5 x i32]* [[A]] to i32*
- // CHECK-NEXT: store i32* [[T]], i32** [[CL]]
- // CHECK-NEXT: [[TH:%.*]] = load i32*, i32** [[CL]]
- // CHECK-NEXT: [[VLAIX:%.*]] = mul nsw i32 0, [[O]]
- // CHECK-NEXT: [[ADDPTR:%.*]] = getelementptr inbounds i32, i32* [[TH]], i32 [[VLAIX]]
- // CHECK-NEXT: store i32* [[ADDPTR]], i32** [[CL]]
+ // PREFIX-VLA-NEXT: [[Z:%.*]] = load i32, i32* [[I]], align 4
+ // PREFIX-VLA-NEXT: [[INC:%.*]] = add nsw i32 [[Z]], 1
+ // PREFIX-VLA-NEXT: store i32 [[INC]], i32* [[I]], align 4
+ // PREFIX-VLA-NEXT: [[O:%.*]] = load i32, i32* [[I]], align 4
+ // PREFIX-VLA-NEXT: [[AR:%.*]] = getelementptr inbounds [5 x i32], [5 x i32]* [[A]], i32 0, i32 0
+ // PREFIX-VLA-NEXT: [[T:%.*]] = bitcast [5 x i32]* [[A]] to i32*
+ // PREFIX-VLA-NEXT: store i32* [[T]], i32** [[CL]]
+ // PREFIX-VLA-NEXT: [[TH:%.*]] = load i32*, i32** [[CL]]
+ // PREFIX-VLA-NEXT: [[VLAIX:%.*]] = mul nsw i32 0, [[O]]
+ // PREFIX-VLA-NEXT: [[ADDPTR:%.*]] = getelementptr inbounds i32, i32* [[TH]], i32 [[VLAIX]]
+ // PREFIX-VLA-NEXT: store i32* [[ADDPTR]], i32** [[CL]]
}
void test6(void)
{
- // CHECK-LABEL: define void @test6(
+ // PREFIX-VLA-LABEL: define void @test6(
int n = 20, **a, i=0;
- // CHECK: [[N:%.*]] = alloca i32, align 4
- // CHECK-NEXT: [[A:%.*]] = alloca i32**, align 4
- // CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
+ // PREFIX-VLA: [[N:%.*]] = alloca i32, align 4
+ // PREFIX-VLA-NEXT: [[A:%.*]] = alloca i32**, align 4
+ // PREFIX-VLA-NEXT: [[I:%.*]] = alloca i32, align 4
(int (**)[i]){&a}[0][1][5] = 0;
- // CHECK-NEXT: [[CL:%.*]] = alloca i32**, align 4
- // CHECK-NEXT: store i32 20, i32* [[N]], align 4
- // CHECK-NEXT: store i32 0, i32* [[I]], align 4
- // CHECK-NEXT: [[Z:%.*]] = load i32, i32* [[I]], align 4
- // CHECK-NEXT: [[O:%.*]] = bitcast i32*** [[A]] to i32**
- // CHECK-NEXT: store i32** [[O]], i32*** [[CL]]
- // CHECK-NEXT: [[T:%.*]] = load i32**, i32*** [[CL]]
- // CHECK-NEXT: [[IX:%.*]] = getelementptr inbounds i32*, i32** [[T]], i32 0
- // CHECK-NEXT: [[TH:%.*]] = load i32*, i32** [[IX]], align 4
- // CHECK-NEXT: [[F:%.*]] = mul nsw i32 1, [[Z]]
- // CHECK-NEXT: [[IX1:%.*]] = getelementptr inbounds i32, i32* [[TH]], i32 [[F]]
- // CHECK-NEXT: [[IX2:%.*]] = getelementptr inbounds i32, i32* [[IX1]], i32 5
- // CHECK-NEXT: store i32 0, i32* [[IX2]], align 4
+ // PREFIX-VLA-NEXT: [[CL:%.*]] = alloca i32**, align 4
+ // PREFIX-VLA-NEXT: store i32 20, i32* [[N]], align 4
+ // PREFIX-VLA-NEXT: store i32 0, i32* [[I]], align 4
+ // PREFIX-VLA-NEXT: [[Z:%.*]] = load i32, i32* [[I]], align 4
+ // PREFIX-VLA-NEXT: [[O:%.*]] = bitcast i32*** [[A]] to i32**
+ // PREFIX-VLA-NEXT: store i32** [[O]], i32*** [[CL]]
+ // PREFIX-VLA-NEXT: [[T:%.*]] = load i32**, i32*** [[CL]]
+ // PREFIX-VLA-NEXT: [[IX:%.*]] = getelementptr inbounds i32*, i32** [[T]], i32 0
+ // PREFIX-VLA-NEXT: [[TH:%.*]] = load i32*, i32** [[IX]], align 4
+ // PREFIX-VLA-NEXT: [[F:%.*]] = mul nsw i32 1, [[Z]]
+ // PREFIX-VLA-NEXT: [[IX1:%.*]] = getelementptr inbounds i32, i32* [[TH]], i32 [[F]]
+ // PREFIX-VLA-NEXT: [[IX2:%.*]] = getelementptr inbounds i32, i32* [[IX1]], i32 5
+ // PREFIX-VLA-NEXT: store i32 0, i32* [[IX2]], align 4
}
// Follow gcc's behavior for VLAs in parameter lists. PR9559.
void test7(int a[b(0)]) {
- // CHECK-LABEL: define void @test7(
- // CHECK: call i32 @b(i8* null)
+ // PREFIX-VLA-LABEL: define void @test7(
+ // PREFIX-VLA: call i32 @b(i8* null)
}
// Make sure we emit dereferenceable or nonnull when the static keyword is
// provided.
void test8(int a[static 3]) { }
-// CHECK: define void @test8(i32* dereferenceable(12) %a)
+// PREFIX-VLA: define void @test8(i32* dereferenceable(12) %a)
void test9(int n, int a[static n]) { }
-// CHECK: define void @test9(i32 %n, i32* nonnull %a)
+// PREFIX-NONNULL: define void @test9(i32 %n, i32* nonnull %a)
+// PREFIX-NO-NULL: define void @test9(i32 %n, i32* %a)
Index: test/CodeGen/nonnull.c
===================================================================
--- test/CodeGen/nonnull.c
+++ test/CodeGen/nonnull.c
@@ -1,32 +1,39 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck -check-prefix=PREFIX-NONNULL %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -fno-delete-null-pointer-checks < %s | FileCheck -check-prefix=PREFIX-NO-NULL %s
-// CHECK: define void @foo(i32* nonnull %x)
+// PREFIX-NONNULL: define void @foo(i32* nonnull %x)
+// PREFIX-NO-NULL: define void @foo(i32* %x)
void foo(int * __attribute__((nonnull)) x) {
*x = 0;
}
-// CHECK: define void @bar(i32* nonnull %x)
+// PREFIX-NONNULL: define void @bar(i32* nonnull %x)
+// PREFIX-NO-NULL: define void @bar(i32* %x)
void bar(int * x) __attribute__((nonnull(1))) {
*x = 0;
}
-// CHECK: define void @bar2(i32* %x, i32* nonnull %y)
+// PREFIX-NONNULL: define void @bar2(i32* %x, i32* nonnull %y)
+// PREFIX-NO-NULL: define void @bar2(i32* %x, i32* %y)
void bar2(int * x, int * y) __attribute__((nonnull(2))) {
*x = 0;
}
static int a;
-// CHECK: define nonnull i32* @bar3()
+// PREFIX-NONNULL: define nonnull i32* @bar3()
+// PREFIX-NO-NULL: define i32* @bar3()
int * bar3() __attribute__((returns_nonnull)) {
return &a;
}
-// CHECK: define i32 @bar4(i32 %n, i32* nonnull %p)
+// PREFIX-NONNULL: define i32 @bar4(i32 %n, i32* nonnull %p)
+// PREFIX-NO-NULL: define i32 @bar4(i32 %n, i32* %p)
int bar4(int n, int *p) __attribute__((nonnull)) {
return n + *p;
}
-// CHECK: define i32 @bar5(i32 %n, i32* nonnull %p)
+// PREFIX-NONNULL: define i32 @bar5(i32 %n, i32* nonnull %p)
+// PREFIX-NO-NULL: define i32 @bar5(i32 %n, i32* %p)
int bar5(int n, int *p) __attribute__((nonnull(1, 2))) {
return n + *p;
}
@@ -37,15 +44,18 @@
double d;
} TransparentUnion __attribute__((transparent_union));
-// CHECK: define i32 @bar6(i64 %
+// PREFIX-NONNULL: define i32 @bar6(i64 %
+// PREFIX-NO-NULL: define i32 @bar6(i64 %
int bar6(TransparentUnion tu) __attribute__((nonnull(1))) {
return *tu.p;
}
-// CHECK: define void @bar7(i32* nonnull %a, i32* nonnull %b)
+// PREFIX-NONNULL: define void @bar7(i32* nonnull %a, i32* nonnull %b)
+// PREFIX-NO-NULL: define void @bar7(i32* %a, i32* %b)
void bar7(int *a, int *b) __attribute__((nonnull(1)))
__attribute__((nonnull(2))) {}
-// CHECK: define void @bar8(i32* nonnull %a, i32* nonnull %b)
+// PREFIX-NONNULL: define void @bar8(i32* nonnull %a, i32* nonnull %b)
+// PREFIX-NO-NULL: define void @bar8(i32* %a, i32* %b)
void bar8(int *a, int *b) __attribute__((nonnull))
__attribute__((nonnull(1))) {}
Index: test/CodeGen/delete-null-pointer-checks.c
===================================================================
--- /dev/null
+++ test/CodeGen/delete-null-pointer-checks.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=NULL-POINTER-INVALID %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -fno-delete-null-pointer-checks | FileCheck -check-prefix=NULL-POINTER-VALID %s
+
+int test1(int a) {
+ return a;
+}
+
+// NULL-POINTER-INVALID-NOT: attributes #0 = {{.*}} "null-pointer-is-valid"="true"
+// NULL-POINTER-VALID: attributes #0 = {{.*}} "null-pointer-is-valid"="true"
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -746,6 +746,8 @@
Opts.NoUseJumpTables = Args.hasArg(OPT_fno_jump_tables);
+ Opts.NullPointerIsValid = Args.hasArg(OPT_fno_delete_null_pointer_checks);
+
Opts.ProfileSampleAccurate = Args.hasArg(OPT_fprofile_sample_accurate);
Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ);
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -3344,6 +3344,10 @@
options::OPT_fno_merge_all_constants, false))
CmdArgs.push_back("-fmerge-all-constants");
+ if (Args.hasFlag(options::OPT_fno_delete_null_pointer_checks,
+ options::OPT_fdelete_null_pointer_checks, false))
+ CmdArgs.push_back("-fno-delete-null-pointer-checks");
+
// LLVM Code Generator Options.
if (Args.hasArg(options::OPT_frewrite_map_file) ||
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1734,6 +1734,8 @@
FuncAttrs.addAttribute("less-precise-fpmad",
llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
+ if (CodeGenOpts.NullPointerIsValid)
+ FuncAttrs.addAttribute("null-pointer-is-valid", "true");
if (!CodeGenOpts.FPDenormalMode.empty())
FuncAttrs.addAttribute("denormal-fp-math", CodeGenOpts.FPDenormalMode);
@@ -1867,7 +1869,8 @@
}
if (TargetDecl->hasAttr<RestrictAttr>())
RetAttrs.addAttribute(llvm::Attribute::NoAlias);
- if (TargetDecl->hasAttr<ReturnsNonNullAttr>())
+ if (TargetDecl->hasAttr<ReturnsNonNullAttr>() &&
+ !CodeGenOpts.NullPointerIsValid)
RetAttrs.addAttribute(llvm::Attribute::NonNull);
if (TargetDecl->hasAttr<AnyX86NoCallerSavedRegistersAttr>())
FuncAttrs.addAttribute("no_caller_saved_registers");
@@ -1974,7 +1977,8 @@
if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
RetAttrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy)
.getQuantity());
- else if (getContext().getTargetAddressSpace(PTy) == 0)
+ else if (getContext().getTargetAddressSpace(PTy) == 0 &&
+ !CodeGenOpts.NullPointerIsValid)
RetAttrs.addAttribute(llvm::Attribute::NonNull);
}
@@ -2083,7 +2087,8 @@
if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
Attrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy)
.getQuantity());
- else if (getContext().getTargetAddressSpace(PTy) == 0)
+ else if (getContext().getTargetAddressSpace(PTy) == 0 &&
+ !CodeGenOpts.NullPointerIsValid)
Attrs.addAttribute(llvm::Attribute::NonNull);
}
@@ -2343,7 +2348,8 @@
if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
if (getNonNullAttr(CurCodeDecl, PVD, PVD->getType(),
- PVD->getFunctionScopeIndex()))
+ PVD->getFunctionScopeIndex()) &&
+ !CGM.getCodeGenOpts().NullPointerIsValid)
AI->addAttr(llvm::Attribute::NonNull);
QualType OTy = PVD->getOriginalType();
@@ -2362,7 +2368,8 @@
Attrs.addDereferenceableAttr(
getContext().getTypeSizeInChars(ETy).getQuantity()*ArrSize);
AI->addAttrs(Attrs);
- } else if (getContext().getTargetAddressSpace(ETy) == 0) {
+ } else if (getContext().getTargetAddressSpace(ETy) == 0 &&
+ !CGM.getCodeGenOpts().NullPointerIsValid) {
AI->addAttr(llvm::Attribute::NonNull);
}
}
@@ -2372,7 +2379,8 @@
// we can't use the dereferenceable attribute, but in addrspace(0)
// we know that it must be nonnull.
if (ArrTy->getSizeModifier() == VariableArrayType::Static &&
- !getContext().getTargetAddressSpace(ArrTy->getElementType()))
+ !getContext().getTargetAddressSpace(ArrTy->getElementType()) &&
+ !CGM.getCodeGenOpts().NullPointerIsValid)
AI->addAttr(llvm::Attribute::NonNull);
}
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ include/clang/Frontend/CodeGenOptions.def
@@ -130,6 +130,7 @@
CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled.
CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf.
CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero
+CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined.
CODEGENOPT(Reassociate , 1, 0) ///< Allow reassociation of FP math ops
CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated.
CODEGENOPT(NoTrappingMath , 1, 0) ///< Set when -fno-trapping-math is enabled.
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1076,6 +1076,12 @@
Flags<[CC1Option]>;
def fno_rewrite_imports : Flag<["-"], "fno-rewrite-imports">, Group<f_Group>;
+def fdelete_null_pointer_checks : Flag<["-"],
+ "fdelete-null-pointer-checks">, Group<f_Group>;
+def fno_delete_null_pointer_checks : Flag<["-"],
+ "fno-delete-null-pointer-checks">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Assume that null pointer dereferences are not undefined">;
+
def frewrite_map_file : Separate<["-"], "frewrite-map-file">,
Group<f_Group>,
Flags<[ DriverOption, CC1Option ]>;
@@ -2843,8 +2849,6 @@
defm eliminate_unused_debug_types : BooleanFFlag<"eliminate-unused-debug-types">, Group<clang_ignored_f_Group>;
defm branch_count_reg : BooleanFFlag<"branch-count-reg">, Group<clang_ignored_gcc_optimization_f_Group>;
defm default_inline : BooleanFFlag<"default-inline">, Group<clang_ignored_gcc_optimization_f_Group>;
-defm delete_null_pointer_checks : BooleanFFlag<"delete-null-pointer-checks">,
- Group<clang_ignored_gcc_optimization_f_Group>;
defm fat_lto_objects : BooleanFFlag<"fat-lto-objects">, Group<clang_ignored_gcc_optimization_f_Group>;
defm float_store : BooleanFFlag<"float-store">, Group<clang_ignored_gcc_optimization_f_Group>;
defm friend_injection : BooleanFFlag<"friend-injection">, Group<clang_ignored_f_Group>;
Index: docs/ClangCommandLineReference.rst
===================================================================
--- docs/ClangCommandLineReference.rst
+++ docs/ClangCommandLineReference.rst
@@ -1543,6 +1543,10 @@
Disable implicit builtin knowledge of a specific function
+.. option:: -fdelete-null-pointer-checks, -fno-delete-null-pointer-checks
+
+Assume that null pointers cannot be dereferenced safely and any code/data cannot reside at address zero.
+
.. option:: -fno-elide-type
Do not elide types when printing diagnostics
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits