diff options
Diffstat (limited to 'test/CodeGenCXX')
143 files changed, 2545 insertions, 493 deletions
diff --git a/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp b/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp new file mode 100644 index 000000000000..02f9fc6e911d --- /dev/null +++ b/test/CodeGenCXX/2003-11-02-WeakLinkage.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// The template should compile to linkonce linkage, not weak linkage. + +// CHECK-NOT: weak +template<class T> +void thefunc(); + +template<class T> +inline void thefunc() {} + +void test() { + thefunc<int>(); +} diff --git a/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp b/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp new file mode 100644 index 000000000000..9cecf4861163 --- /dev/null +++ b/test/CodeGenCXX/2003-11-18-PtrMemConstantInitializer.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct Gfx { + void opMoveSetShowText(); +}; + +struct Operator { + void (Gfx::*func)(); +}; + +Operator opTab[] = { + {&Gfx::opMoveSetShowText}, +}; diff --git a/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp b/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp new file mode 100644 index 000000000000..3e5339732767 --- /dev/null +++ b/test/CodeGenCXX/2003-11-27-MultipleInheritanceThunk.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +struct CallSite { + int X; + + CallSite(const CallSite &CS); +}; + +struct AliasAnalysis { + int TD; + + virtual int getModRefInfo(CallSite CS); +}; + + +struct Pass { + int X; + virtual int foo(); +}; + +struct AliasAnalysisCounter : public Pass, public AliasAnalysis { + int getModRefInfo(CallSite CS) { + return 0; + } +}; + +AliasAnalysisCounter AAC; diff --git a/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp b/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp new file mode 100644 index 000000000000..45325bc65c61 --- /dev/null +++ b/test/CodeGenCXX/2003-11-29-DuplicatedCleanupTest.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +void doesntThrow() throw(); +struct F { + ~F() { doesntThrow(); } +}; + +void atest() { + F A; +lab: + F B; + goto lab; +} + +void test(int val) { +label: { + F A; + F B; + if (val == 0) goto label; + if (val == 1) goto label; +} +} + +void test3(int val) { +label: { + F A; + F B; + if (val == 0) { doesntThrow(); goto label; } + if (val == 1) { doesntThrow(); goto label; } +} +} + +void test4(int val) { +label: { + F A; + F B; + if (val == 0) { F C; goto label; } + if (val == 1) { F D; goto label; } +} +} diff --git a/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp b/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp new file mode 100644 index 000000000000..38de271b6132 --- /dev/null +++ b/test/CodeGenCXX/2003-12-08-ArrayOfPtrToMemberFunc.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct Evil { + void fun (); +}; +int foo(); +typedef void (Evil::*memfunptr) (); +static memfunptr jumpTable[] = { &Evil::fun }; + +void Evil::fun() { + (this->*jumpTable[foo()]) (); +} diff --git a/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp b/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp new file mode 100644 index 000000000000..0c9333fb6d7a --- /dev/null +++ b/test/CodeGenCXX/2004-01-11-DynamicInitializedConstant.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// CHECK-NOT: constant +extern int X; +const int Y = X; +const int* foo() { return &Y; } diff --git a/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp b/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp new file mode 100644 index 000000000000..a6e2e30dd59b --- /dev/null +++ b/test/CodeGenCXX/2004-03-08-ReinterpretCastCopy.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct A { + virtual void Method() = 0; +}; + +struct B : public A { + virtual void Method() { } +}; + +typedef void (A::*fn_type_a)(void); +typedef void (B::*fn_type_b)(void); + +int main(int argc, char **argv) +{ + fn_type_a f = reinterpret_cast<fn_type_a>(&B::Method); + fn_type_b g = reinterpret_cast<fn_type_b>(f); + B b; + (b.*g)(); + return 0; +} diff --git a/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp b/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp new file mode 100644 index 000000000000..5d8c8b004b79 --- /dev/null +++ b/test/CodeGenCXX/2004-03-09-UnmangledBuiltinMethods.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +// CHECK: _ZN11AccessFlags6strlenEv +struct AccessFlags { + void strlen(); +}; + +void AccessFlags::strlen() { } diff --git a/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp b/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp new file mode 100644 index 000000000000..01350c00b9bd --- /dev/null +++ b/test/CodeGenCXX/2004-03-15-CleanupsAndGotos.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +// Testcase from Bug 291 + +struct X { + ~X(); +}; + +void foo() { + X v; + +TryAgain: + goto TryAgain; +} diff --git a/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp b/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp new file mode 100644 index 000000000000..97254c18a51a --- /dev/null +++ b/test/CodeGenCXX/2004-06-08-LateTemplateInstantiation.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +template<typename Ty> +struct normal_iterator { + int FIELD; +}; + +void foo(normal_iterator<int>); +normal_iterator<int> baz(); + +void bar() { + foo(baz()); +} + +void *bar2() { + return (void*)foo; +} diff --git a/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp b/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp new file mode 100644 index 000000000000..618894fd7248 --- /dev/null +++ b/test/CodeGenCXX/2004-09-27-DidntEmitTemplate.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// This is a testcase for LLVM PR445, which was a problem where the +// instantiation of callDefaultCtor was not being emitted correctly. + +// CHECK-NOT: declare{{.*}}callDefaultCtor +struct Pass {}; + +template<typename PassName> +Pass *callDefaultCtor() { return new Pass(); } + +void foo(Pass *(*C)()); + +struct basic_string { + bool empty() const { return true; } +}; + + +bool foo2(basic_string &X) { + return X.empty(); +} +void baz() { foo(callDefaultCtor<Pass>); } diff --git a/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp b/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp new file mode 100644 index 000000000000..ebcce7796e71 --- /dev/null +++ b/test/CodeGenCXX/2004-11-27-ExceptionCleanupAssertion.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null + +// This is PR421 + +struct Strongbad { + Strongbad(const char *str ); + ~Strongbad(); + operator const char *() const; +}; + +void TheCheat () { + Strongbad foo(0); + Strongbad dirs[] = { Strongbad(0) + 1}; +} diff --git a/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp b/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp new file mode 100644 index 000000000000..3bfecd54b780 --- /dev/null +++ b/test/CodeGenCXX/2004-11-27-FriendDefaultArgCrash.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +// PR447 + +namespace nm { + struct str { + friend int foo(int arg = 0); + }; +} diff --git a/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp b/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp new file mode 100644 index 000000000000..875c412c6b48 --- /dev/null +++ b/test/CodeGenCXX/2005-01-03-StaticInitializers.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +struct S { + int A[2]; +}; + +// CHECK-NOT: llvm.global_ctor +int XX = (int)(long)&(((struct S*)0)->A[1]); diff --git a/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp b/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp new file mode 100644 index 000000000000..dee581736050 --- /dev/null +++ b/test/CodeGenCXX/2005-02-11-AnonymousUnion.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - + +// Test anonymous union with members of the same size. +int test1(float F) { + union { + float G; + int i; + }; + G = F; + return i; +} + +// test anonymous union with members of differing size. +int test2(short F) { + volatile union { + short G; + int i; + }; + G = F; + return i; +} + +// Make sure that normal unions work. duh :) +volatile union U_t { + short S; + int i; +} U; + +int test3(short s) { + U.S = s; + return U.i; +} diff --git a/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp b/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp new file mode 100644 index 000000000000..b1db67aebfd3 --- /dev/null +++ b/test/CodeGenCXX/2005-02-13-BadDynamicInit.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// This testcase corresponds to PR509 +struct Data { + unsigned *data; + unsigned array[1]; +}; + +// CHECK-NOT: llvm.global_ctors +Data shared_null = { shared_null.array }; diff --git a/test/CodeGenCXX/2005-02-14-BitFieldOffset.cpp b/test/CodeGenCXX/2005-02-14-BitFieldOffset.cpp new file mode 100644 index 000000000000..c37f5dce32b2 --- /dev/null +++ b/test/CodeGenCXX/2005-02-14-BitFieldOffset.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// CHECK-NOT: i32 6 +struct QVectorTypedData { + int size; + unsigned int sharable : 1; + unsigned short array[1]; +}; + +void foo(QVectorTypedData *X) { + X->array[0] = 123; +} diff --git a/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp b/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp new file mode 100644 index 000000000000..937a300b5dfb --- /dev/null +++ b/test/CodeGenCXX/2005-02-19-BitfieldStructCrash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct QChar {unsigned short X; QChar(unsigned short); } ; + +struct Command { + Command(QChar c) : c(c) {} + unsigned int type : 4; + QChar c; + }; + +Command X(QChar('c')); + +void Foo(QChar ); +void bar() { Foo(X.c); } diff --git a/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp b/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp new file mode 100644 index 000000000000..986001ada0da --- /dev/null +++ b/test/CodeGenCXX/2005-02-19-UnnamedVirtualThunkArgument.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +struct Foo { + Foo(); + virtual ~Foo(); +}; + +struct Bar { + Bar(); + virtual ~Bar(); + virtual bool test(bool) const; +}; + +struct Baz : public Foo, public Bar { + Baz(); + virtual ~Baz(); + virtual bool test(bool) const; +}; + +bool Baz::test(bool) const { + return true; +} diff --git a/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp b/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp new file mode 100644 index 000000000000..36f911e227fe --- /dev/null +++ b/test/CodeGenCXX/2005-02-20-BrokenReferenceTest.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +void test(unsigned char *b, int rb) { + typedef unsigned char imgfoo[10][rb]; + imgfoo &br = *(imgfoo *)b; + + br[0][0] = 1; + + rb = br[0][0]; +} diff --git a/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp b/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp new file mode 100644 index 000000000000..b809751cd0f2 --- /dev/null +++ b/test/CodeGenCXX/2006-03-01-GimplifyCrash.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +struct PrefMapElem { + virtual ~PrefMapElem(); + unsigned int fPrefId; +}; + +int foo() { + PrefMapElem* fMap; + if (fMap[0].fPrefId == 1) + return 1; + + return 0; +} diff --git a/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp b/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp new file mode 100644 index 000000000000..01476b7ff0c2 --- /dev/null +++ b/test/CodeGenCXX/2006-03-06-C++RecurseCrash.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +namespace std { + class exception { }; + + class type_info { + public: + virtual ~type_info(); + }; + +} + +namespace __cxxabiv1 { + class __si_class_type_info : public std::type_info { + ~__si_class_type_info(); + }; +} + +class recursive_init: public std::exception { +public: + virtual ~recursive_init() throw (); +}; + +recursive_init::~recursive_init() throw() { } diff --git a/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp b/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp new file mode 100644 index 000000000000..bd270dd60238 --- /dev/null +++ b/test/CodeGenCXX/2006-09-12-OpaqueStructCrash.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s + +struct A { + virtual ~A(); +}; + +template <typename Ty> +struct B : public A { + ~B () { delete [] val; } +private: + Ty* val; +}; + +template <typename Ty> +struct C : public A { + C (); + ~C (); +}; + +template <typename Ty> +struct D : public A { + D () {} + private: + B<C<Ty> > blocks; +}; + +template class D<double>; diff --git a/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp b/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp new file mode 100644 index 000000000000..8f61f7b10a81 --- /dev/null +++ b/test/CodeGenCXX/2006-10-30-ClassBitfield.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR954 + +struct _Refcount_Base { + unsigned long _M_ref_count; + int _M_ref_count_lock; + _Refcount_Base() : _M_ref_count(0) {} +}; + +struct _Rope_RopeRep : public _Refcount_Base +{ +public: + int _M_tag:8; +}; + +int foo(_Rope_RopeRep* r) { return r->_M_tag; } diff --git a/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp b/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp new file mode 100644 index 000000000000..34594f43a0b9 --- /dev/null +++ b/test/CodeGenCXX/2006-11-20-GlobalSymbols.cpp @@ -0,0 +1,11 @@ +// PR1013 +// Check to make sure debug symbols use the correct name for globals and +// functions. Will not assemble if it fails to. +// RUN: %clang_cc1 -emit-llvm -g -o - %s | FileCheck %s + +// CHECK: f\01oo" +int foo __asm__("f\001oo"); + +int bar() { + return foo; +} diff --git a/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp b/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp new file mode 100644 index 000000000000..2088e63fd5f8 --- /dev/null +++ b/test/CodeGenCXX/2006-11-30-ConstantExprCrash.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - +// PR1027 + +struct sys_var { + unsigned name_length; + + bool no_support_one_shot; + sys_var() {} +}; + + +struct sys_var_thd : public sys_var { +}; + +extern sys_var_thd sys_auto_is_null; + +sys_var *getsys_variables() { + return &sys_auto_is_null; +} + +sys_var *sys_variables = &sys_auto_is_null; diff --git a/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp b/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp new file mode 100644 index 000000000000..0cd83fa7ed4c --- /dev/null +++ b/test/CodeGenCXX/2007-01-02-UnboundedArray.cpp @@ -0,0 +1,14 @@ +// Make sure unbounded arrays compile with debug information. +// +// RUN: %clang_cc1 -emit-llvm -g %s -o - + +// PR1068 + +struct Object { + char buffer[]; +}; + +int main(int argc, char** argv) { + new Object; + return 0; +} diff --git a/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp b/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp new file mode 100644 index 000000000000..f3aa51e725b1 --- /dev/null +++ b/test/CodeGenCXX/2007-01-06-PtrMethodInit.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR1084 + +extern "C" +{ + typedef unsigned char PRUint8; + typedef unsigned int PRUint32; +} +typedef PRUint32 nsresult; +struct nsID +{ +}; +typedef nsID nsIID; +class nsISupports +{ +}; +extern "C++" +{ + template < class T > struct nsCOMTypeInfo + { + static const nsIID & GetIID () + { + } + }; +} + +class nsIDOMEvent:public nsISupports +{ +}; +class nsIDOMEventListener:public nsISupports +{ +public:static const nsIID & GetIID () + { + } + virtual nsresult + __attribute__ ((regparm (0), cdecl)) HandleEvent (nsIDOMEvent * event) = + 0; +}; +class nsIDOMMouseListener:public nsIDOMEventListener +{ +public:static const nsIID & GetIID () + { + static const nsIID iid = { + }; + } + virtual nsresult + __attribute__ ((regparm (0), + cdecl)) MouseDown (nsIDOMEvent * aMouseEvent) = 0; +}; +typedef +typeof (&nsIDOMEventListener::HandleEvent) + GenericHandler; + struct EventDispatchData + { + PRUint32 message; + GenericHandler method; + PRUint8 bits; + }; + struct EventTypeData + { + const EventDispatchData *events; + int numEvents; + const nsIID *iid; + }; + static const EventDispatchData sMouseEvents[] = { + { + (300 + 2), + reinterpret_cast < GenericHandler > (&nsIDOMMouseListener::MouseDown), + 0x01} + }; +static const EventTypeData sEventTypes[] = { + { + sMouseEvents, (sizeof (sMouseEvents) / sizeof (sMouseEvents[0])), + &nsCOMTypeInfo < nsIDOMMouseListener >::GetIID ()} +}; diff --git a/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp b/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp new file mode 100644 index 000000000000..6c39b55fd33e --- /dev/null +++ b/test/CodeGenCXX/2007-04-05-PackedBitFields-1.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +#ifdef PACKED +#define P __attribute__((packed)) +#else +#define P +#endif + +struct P M_Packed { + unsigned int l_Packed; + unsigned short k_Packed : 6, + i_Packed : 15, + j_Packed : 11; + +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (x.i_Packed != 0); +} diff --git a/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp b/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp new file mode 100644 index 000000000000..d7b0eaeae1a2 --- /dev/null +++ b/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap-2.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +#ifdef PACKED +#define P __attribute__((packed)) +#else +#define P +#endif + +struct P M_Packed { + unsigned long sorted : 1; + unsigned long from_array : 1; + unsigned long mixed_encoding : 1; + unsigned long encoding : 8; + unsigned long count : 21; + +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (x.count != 0); +} diff --git a/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp b/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp new file mode 100644 index 000000000000..691176739259 --- /dev/null +++ b/test/CodeGenCXX/2007-04-05-PackedBitFieldsOverlap.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +#ifdef PACKED +#define P __attribute__((packed)) +#else +#define P +#endif + +struct P M_Packed { + unsigned int l_Packed; + unsigned short k_Packed : 6, + i_Packed : 15; + char c; + +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (x.i_Packed != 0); +} diff --git a/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp b/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp new file mode 100644 index 000000000000..b31f95fa3b8a --- /dev/null +++ b/test/CodeGenCXX/2007-04-05-PackedBitFieldsSmall.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + + +#ifdef PACKED +// This is an example where size of Packed struct is smaller then +// the size of bit field type. +#define P __attribute__((packed)) +#else +#define P +#endif + +struct P M_Packed { + unsigned long long X:50; + unsigned Y:2; +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (0 != x.Y); +} + +int testM_Packed2 (void) { + struct M_Packed x; + return (0 != x.X); +} diff --git a/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp b/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp new file mode 100644 index 000000000000..c848e7cb7dd9 --- /dev/null +++ b/test/CodeGenCXX/2007-04-05-StructPackedFieldUnpacked.cpp @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - + +#ifdef PACKED +#define P __attribute__((packed)) +#else +#define P +#endif + +struct UnPacked { + int X; + int Y; +}; + +struct P M_Packed { + unsigned char A; + struct UnPacked B; +}; + +struct M_Packed sM_Packed; + +int testM_Packed (void) { + struct M_Packed x; + return (x.B.Y != 0); +} diff --git a/test/CodeGenCXX/2007-04-10-PackedUnion.cpp b/test/CodeGenCXX/2007-04-10-PackedUnion.cpp new file mode 100644 index 000000000000..863fc82692e9 --- /dev/null +++ b/test/CodeGenCXX/2007-04-10-PackedUnion.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +extern "C" { + +#pragma pack(push, 2) + typedef struct ABC* abc; + + struct ABCS { + float red; + float green; + float blue; + float alpha; + }; + + typedef void (*XYZ)(); +#pragma pack(pop) +} + + +union ABCU { + ABCS color; + XYZ bg; +}; + +struct AData { + ABCU data; +}; + +class L { + public: + L() {} + L(const L& other); + + private: + AData fdata; +}; + + +L::L(const L& other) +{ + fdata = other.fdata; +} diff --git a/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp b/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp new file mode 100644 index 000000000000..4475fda95c08 --- /dev/null +++ b/test/CodeGenCXX/2007-04-14-FNoBuiltin.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -fno-builtin -o - | FileCheck %s +// Check that -fno-builtin is honored. + +extern "C" int printf(const char*, ...); +void foo(const char *msg) { + // CHECK: call{{.*}}printf + printf("%s\n",msg); +} diff --git a/test/CodeGenCXX/2007-05-03-VectorInit.cpp b/test/CodeGenCXX/2007-05-03-VectorInit.cpp new file mode 100644 index 000000000000..5bc196f30fe2 --- /dev/null +++ b/test/CodeGenCXX/2007-05-03-VectorInit.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -emit-llvm %s -O0 -o - +// PR1378 + +typedef float v4sf __attribute__((vector_size(16))); + +typedef v4sf float4; + +static float4 splat4(float a) +{ + float4 tmp = {a,a,a,a}; + return tmp; +} + +float4 foo(float a) +{ + return splat4(a); +} diff --git a/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp b/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp new file mode 100644 index 000000000000..d7c96f562acc --- /dev/null +++ b/test/CodeGenCXX/2007-07-29-RestrictPtrArg.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +void foo(int * __restrict myptr1, int * myptr2) { + // CHECK: noalias + myptr1[0] = 0; + myptr2[0] = 0; +} diff --git a/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp b/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp new file mode 100644 index 000000000000..aa9f48bb0abc --- /dev/null +++ b/test/CodeGenCXX/2007-07-29-RestrictRefArg.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +void foo(int & __restrict myptr1, int & myptr2) { + // CHECK: noalias + myptr1 = 0; + myptr2 = 0; +} diff --git a/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp b/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp new file mode 100644 index 000000000000..ec8a516c696b --- /dev/null +++ b/test/CodeGenCXX/2007-09-10-RecursiveTypeResolution.cpp @@ -0,0 +1,87 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// PR1634 + +namespace Manta +{ + class CallbackHandle + { + protected:virtual ~ CallbackHandle (void) + { + } + }; +template < typename Data1 > class CallbackBase_1Data:public CallbackHandle + { + }; +} + +namespace __gnu_cxx +{ + template < typename _Iterator, typename _Container > + class __normal_iterator + { + _Iterator _M_current; + }; +} + +namespace std +{ + template < typename _Tp > struct allocator + { + typedef _Tp *pointer; + }; + template < typename _InputIterator, + typename _Tp > inline void find (_InputIterator __last, + const _Tp & __val) + { + }; +} + +namespace Manta +{ + template < typename _Tp, typename _Alloc> struct _Vector_base + { + struct _Vector_impl + { + _Tp *_M_start; + }; + public: + _Vector_impl _M_impl; + }; + template < typename _Tp, typename _Alloc = std::allocator < _Tp > > + class vector:protected _Vector_base < _Tp,_Alloc > + { + public: + typedef __gnu_cxx::__normal_iterator < typename _Alloc::pointer, + vector < _Tp, _Alloc > > iterator; + iterator end () + { + } + }; + class MantaInterface + { + }; + class RTRT + { + virtual CallbackHandle *registerTerminationCallback (CallbackBase_1Data < + MantaInterface * >*); + virtual void unregisterCallback (CallbackHandle *); + typedef vector < CallbackBase_1Data < int >*>PRCallbackMapType; + PRCallbackMapType parallelPreRenderCallbacks; + }; +} +using namespace Manta; +CallbackHandle * +RTRT::registerTerminationCallback (CallbackBase_1Data < MantaInterface * >*cb) +{ + return cb; +} + +void +RTRT::unregisterCallback (CallbackHandle * callback) +{ + { + typedef CallbackBase_1Data < int > callback_t; + callback_t *cb = static_cast < callback_t * >(callback); + find (parallelPreRenderCallbacks.end (), cb); + } +} diff --git a/test/CodeGenCXX/2007-10-01-StructResize.cpp b/test/CodeGenCXX/2007-10-01-StructResize.cpp new file mode 100644 index 000000000000..8e5750d3c4ef --- /dev/null +++ b/test/CodeGenCXX/2007-10-01-StructResize.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +#pragma pack(4) + +struct Bork { + unsigned int f1 : 3; + unsigned int f2 : 30; +}; + +int Foo(Bork *hdr) { + hdr->f1 = 7; + hdr->f2 = 927; +} diff --git a/test/CodeGenCXX/2008-01-12-VecInit.cpp b/test/CodeGenCXX/2008-01-12-VecInit.cpp new file mode 100644 index 000000000000..92bfd51d1ba8 --- /dev/null +++ b/test/CodeGenCXX/2008-01-12-VecInit.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// rdar://5685492 + +typedef int __attribute__((vector_size(16))) v; +v vt = {1, 2, 3, 4}; diff --git a/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp b/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp new file mode 100644 index 000000000000..f842f958e9e6 --- /dev/null +++ b/test/CodeGenCXX/2008-05-07-CrazyOffsetOf.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// rdar://5914926 + +struct bork { + struct bork *next_local; + char * query; +}; +int offset = (char *) &(((struct bork *) 0x10)->query) - (char *) 0x10; diff --git a/test/CodeGenCXX/2009-03-17-dbg.cpp b/test/CodeGenCXX/2009-03-17-dbg.cpp new file mode 100644 index 000000000000..e2e6c5a2dd29 --- /dev/null +++ b/test/CodeGenCXX/2009-03-17-dbg.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -g + +template <typename T1,typename T2> +inline void f(const T1&,const T2&) { } + +template <typename T1,typename T2,void F(const T1&,const T2&)> +struct A { + template <typename T> void g(T& i) { } +}; + +int main() { + int i; + A<int,int,f> a; + a.g(i); +} diff --git a/test/CodeGenCXX/2009-04-23-bool2.cpp b/test/CodeGenCXX/2009-04-23-bool2.cpp new file mode 100644 index 000000000000..cf81cc42eae4 --- /dev/null +++ b/test/CodeGenCXX/2009-04-23-bool2.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +// g++.old-deja/g++.jason/bool2.C from gcc testsuite. +// Crashed before 67975 went in. +struct F { + bool b1 : 1; + bool b2 : 7; +}; + +int main() +{ + F f = { true, true }; + + if (int (f.b1) != 1) + return 1; +} diff --git a/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp new file mode 100644 index 000000000000..8361680546f3 --- /dev/null +++ b/test/CodeGenCXX/2009-05-04-PureConstNounwind.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fexceptions -emit-llvm %s -o - | FileCheck %s +int c(void) __attribute__((const)); +int p(void) __attribute__((pure)); +int t(void); + +// CHECK: define i32 @_Z1fv() { +int f(void) { + // CHECK: call i32 @_Z1cv() nounwind readnone + // CHECK: call i32 @_Z1pv() nounwind readonly + return c() + p() + t(); +} + +// CHECK: declare i32 @_Z1cv() nounwind readnone +// CHECK: declare i32 @_Z1pv() nounwind readonly +// CHECK-NOT: declare i32 @_Z1tv() nounwind diff --git a/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp b/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp new file mode 100644 index 000000000000..500520b567f5 --- /dev/null +++ b/test/CodeGenCXX/2009-06-16-DebugInfoCrash.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -g +// This crashes if we try to emit debug info for TEMPLATE_DECL members. +template <class T> class K2PtrVectorBase {}; +template <class T> class K2Vector {}; +template <class U > class K2Vector<U*> : public K2PtrVectorBase<U*> {}; +class ScriptInfoManager { + void PostRegister() ; + template <class SI> short ReplaceExistingElement(K2Vector<SI*>& v); +}; +void ScriptInfoManager::PostRegister() {} diff --git a/test/CodeGenCXX/2009-07-16-Using.cpp b/test/CodeGenCXX/2009-07-16-Using.cpp new file mode 100644 index 000000000000..a692d4dbc32e --- /dev/null +++ b/test/CodeGenCXX/2009-07-16-Using.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null + +namespace A { + typedef int B; +} +struct B { +}; +using ::A::B; diff --git a/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp b/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp new file mode 100644 index 000000000000..4404d4a8d518 --- /dev/null +++ b/test/CodeGenCXX/2009-08-05-ZeroInitWidth.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - +// rdar://7114564 +struct A { + unsigned long long : (sizeof(unsigned long long) * 8) - 16; +}; +struct B { + A a; +}; +struct B b = { + {} +}; diff --git a/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp b/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp new file mode 100644 index 000000000000..21b88c93ad7f --- /dev/null +++ b/test/CodeGenCXX/2009-08-11-VectorRetTy.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -emit-llvm -o /dev/null +// <rdar://problem/7096460> +typedef void (*Func) (); +typedef long long m64 __attribute__((__vector_size__(8), __may_alias__)); +static inline m64 __attribute__((__always_inline__, __nodebug__)) _mm_set1_pi16() {} +template <class MM> +static void Bork() { + const m64 mmx_0x00ff = _mm_set1_pi16(); +} +struct A {}; +Func arr[] = { + Bork<A> +}; diff --git a/test/CodeGenCXX/2009-09-09-packed-layout.cpp b/test/CodeGenCXX/2009-09-09-packed-layout.cpp new file mode 100644 index 000000000000..9de2f61420c4 --- /dev/null +++ b/test/CodeGenCXX/2009-09-09-packed-layout.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -emit-llvm -triple i386-apple-darwin11 %s -o /dev/null +class X { + public: + virtual ~X(); + short y; +}; +#pragma pack(push, 1) +class Z : public X { + public: enum { foo = ('x') }; + virtual int y() const; +}; +#pragma pack(pop) +class Y : public X { +public: enum { foo = ('y'), bar = 0 }; +}; +X x; +Y y; +Z z; diff --git a/test/CodeGenCXX/2009-10-27-crash.cpp b/test/CodeGenCXX/2009-10-27-crash.cpp new file mode 100644 index 000000000000..482bb752995f --- /dev/null +++ b/test/CodeGenCXX/2009-10-27-crash.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -emit-llvm %s -o /dev/null +// Radar 7328944 + +typedef struct +{ + unsigned short a : 1; + unsigned short b : 2; + unsigned short c : 1; + unsigned short d : 1; + unsigned short e : 1; + unsigned short f : 1; + unsigned short g : 2; + unsigned short : 7; + union + { + struct + { + unsigned char h : 1; + unsigned char i : 1; + unsigned char j : 1; + unsigned char : 5; + }; + struct + { + unsigned char k : 3; + unsigned char : 5; + }; + }; + unsigned char : 8; +} tt; + +typedef struct +{ + unsigned char s; + tt t; + unsigned int u; +} ttt; + +ttt X = { + 4, + { 0 }, + 55, +}; diff --git a/test/CodeGenCXX/2009-12-23-MissingSext.cpp b/test/CodeGenCXX/2009-12-23-MissingSext.cpp new file mode 100644 index 000000000000..e6ff7b3952c5 --- /dev/null +++ b/test/CodeGenCXX/2009-12-23-MissingSext.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// The store of p.y into the temporary was not +// getting extended to 32 bits, so uninitialized +// bits of the temporary were used. 7366161. +struct foo { + char x:8; + signed int y:24; +}; +int bar(struct foo p, int x) { +// CHECK: bar +// CHECK: and {{.*}} 16777215 +// CHECK: and {{.*}} 16777215 + x = (p.y > x ? x : p.y); + return x; +// CHECK: ret +} diff --git a/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp b/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp new file mode 100644 index 000000000000..7c05535b3587 --- /dev/null +++ b/test/CodeGenCXX/2010-05-10-Var-DbgInfo.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -emit-llvm -O0 -g %s -o /dev/null +// PR 7104 + +struct A { + int Ai; +}; + +struct B : public A {}; +struct C : public B {}; + +const char * f(int C::*){ return ""; } +int f(int B::*) { return 1; } + +struct D : public C {}; + +const char * g(int B::*){ return ""; } +int g(int D::*) { return 1; } + +void test() +{ + int i = f(&A::Ai); + + const char * str = g(&A::Ai); +} + +// conversion of B::* to C::* is better than conversion of A::* to C::* +typedef void (A::*pmfa)(); +typedef void (B::*pmfb)(); +typedef void (C::*pmfc)(); + +struct X { + operator pmfa(); + operator pmfb(); +}; + + +void g(pmfc); + +void test2(X x) +{ + g(x); +} diff --git a/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp b/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp new file mode 100644 index 000000000000..fe0740b7cb5c --- /dev/null +++ b/test/CodeGenCXX/2010-05-11-alwaysinlineinstantiation.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s + +// CHECK-NOT: ZN12basic_stringIcEC1Ev +// CHECK: ZN12basic_stringIcED1Ev +// CHECK: ZN12basic_stringIcED1Ev +template<class charT> +class basic_string +{ +public: + basic_string(); + ~basic_string(); +}; + +template <class charT> +__attribute__ ((__visibility__("hidden"), __always_inline__)) inline +basic_string<charT>::basic_string() +{ +} + +template <class charT> +inline +basic_string<charT>::~basic_string() +{ +} + +typedef basic_string<char> string; + +extern template class basic_string<char>; + +int main() +{ + string s; +} diff --git a/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp b/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp new file mode 100644 index 000000000000..048811f6e641 --- /dev/null +++ b/test/CodeGenCXX/2010-05-12-PtrToMember-Dbg.cpp @@ -0,0 +1,17 @@ +//RUN: %clang_cc1 -emit-llvm -g -o - %s | FileCheck %s +//CHECK: DW_TAG_auto_variable +class Foo +{ + public: + int x; + int y; + Foo (int i, int j) { x = i; y = j; } +}; + + +Foo foo(10, 11); + +int main() { + int Foo::* pmi = &Foo::y; + return foo.*pmi; +} diff --git a/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp b/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp new file mode 100644 index 000000000000..2542378e909a --- /dev/null +++ b/test/CodeGenCXX/2010-06-21-LocalVarDbg.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -g -emit-llvm %s -o - | FileCheck %s +// Do not use function name to create named metadata used to hold +// local variable info. For example. llvm.dbg.lv.~A is an invalid name. + +// CHECK-NOT: llvm.dbg.lv.~A +class A { +public: + ~A() { int i = 0; i++; } +}; + +int foo(int i) { + A a; + return 0; +} diff --git a/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp b/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp new file mode 100644 index 000000000000..f82e527844fd --- /dev/null +++ b/test/CodeGenCXX/2010-06-22-BitfieldInit.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o - +struct TEST2 +{ + int subid:32; + int :0; +}; + +typedef struct _TEST3 +{ + TEST2 foo; + TEST2 foo2; +} TEST3; + +TEST3 test = + { + {0}, + {0} + }; + +int main() { return 0; } diff --git a/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp b/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp new file mode 100644 index 000000000000..c2f37f740549 --- /dev/null +++ b/test/CodeGenCXX/2010-06-22-ZeroBitfield.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o - +struct s8_0 { unsigned : 0; }; +struct s8_1 { double x; }; +struct s8 { s8_0 a; s8_1 b; }; +s8 f8() { return s8(); } diff --git a/test/CodeGenCXX/2010-07-23-DeclLoc.cpp b/test/CodeGenCXX/2010-07-23-DeclLoc.cpp new file mode 100644 index 000000000000..74054481cdb4 --- /dev/null +++ b/test/CodeGenCXX/2010-07-23-DeclLoc.cpp @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s +// Require the template function declaration refer to the correct filename. +// First, locate the function decl in metadata, and pluck out the file handle: +// CHECK: {{extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*extract_dwarf_data_from_header.*[^ ]+", metadata !}}[[filehandle:[0-9]+]], +// Second: Require that filehandle refer to the correct filename: +// CHECK: {{^!}}[[filehandle]] = metadata {{![{].*}} metadata !"decl_should_be_here.hpp", +typedef long unsigned int __darwin_size_t; +typedef __darwin_size_t size_t; +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; +namespace std { + template<typename _Tp> class auto_ptr { + _Tp* _M_ptr; + public: + typedef _Tp element_type; + auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { } + element_type& operator*() const throw() { } + }; +} +class Pointer32 { +public: + typedef uint32_t ptr_t; + typedef uint32_t size_t; +}; +class Pointer64 { +public: + typedef uint64_t ptr_t; + typedef uint64_t size_t; +}; +class BigEndian {}; +class LittleEndian {}; +template <typename _SIZE, typename _ENDIANNESS> class SizeAndEndianness { +public: + typedef _SIZE SIZE; +}; +typedef SizeAndEndianness<Pointer32, LittleEndian> ISA32Little; +typedef SizeAndEndianness<Pointer32, BigEndian> ISA32Big; +typedef SizeAndEndianness<Pointer64, LittleEndian> ISA64Little; +typedef SizeAndEndianness<Pointer64, BigEndian> ISA64Big; +template <typename SIZE> class TRange { +protected: + typename SIZE::ptr_t _location; + typename SIZE::size_t _length; + TRange(typename SIZE::ptr_t location, typename SIZE::size_t length) : _location(location), _length(length) { } +}; +template <typename SIZE, typename T> class TRangeValue : public TRange<SIZE> { + T _value; +public: + TRangeValue(typename SIZE::ptr_t location, typename SIZE::size_t length, T value) : TRange<SIZE>(location, length), _value(value) {}; +}; +template <typename SIZE> class TAddressRelocator {}; +class CSCppSymbolOwner{}; +class CSCppSymbolOwnerData{}; +template <typename SIZE> class TRawSymbolOwnerData +{ + TRangeValue< SIZE, uint8_t* > _TEXT_text_section; + const char* _dsym_path; + uint32_t _dylib_current_version; + uint32_t _dylib_compatibility_version; +public: + TRawSymbolOwnerData() : + _TEXT_text_section(0, 0, __null), _dsym_path(__null), _dylib_current_version(0), _dylib_compatibility_version(0) {} +}; +template <typename SIZE_AND_ENDIANNESS> class TExtendedMachOHeader {}; +# 16 "decl_should_be_here.hpp" +template <typename SIZE_AND_ENDIANNESS> void extract_dwarf_data_from_header(TExtendedMachOHeader<SIZE_AND_ENDIANNESS>& header, + TRawSymbolOwnerData<typename SIZE_AND_ENDIANNESS::SIZE>& symbol_owner_data, + TAddressRelocator<typename SIZE_AND_ENDIANNESS::SIZE>* address_relocator) {} +struct CSCppSymbolOwnerHashFunctor { + size_t operator()(const CSCppSymbolOwner& symbol_owner) const { +# 97 "wrong_place_for_decl.cpp" + } +}; +template <typename SIZE_AND_ENDIANNESS> CSCppSymbolOwnerData* create_symbol_owner_data_arch_specific(CSCppSymbolOwner* symbol_owner, const char* dsym_path) { + typedef typename SIZE_AND_ENDIANNESS::SIZE SIZE; + std::auto_ptr< TRawSymbolOwnerData<SIZE> > data(new TRawSymbolOwnerData<SIZE>()); + std::auto_ptr< TExtendedMachOHeader<SIZE_AND_ENDIANNESS> > header; + extract_dwarf_data_from_header(*header, *data, (TAddressRelocator<typename SIZE_AND_ENDIANNESS::SIZE>*)__null); +} +CSCppSymbolOwnerData* create_symbol_owner_data2(CSCppSymbolOwner* symbol_owner, const char* dsym_path) { + create_symbol_owner_data_arch_specific< ISA32Little >(symbol_owner, dsym_path); + create_symbol_owner_data_arch_specific< ISA32Big >(symbol_owner, dsym_path); + create_symbol_owner_data_arch_specific< ISA64Little >(symbol_owner, dsym_path); + create_symbol_owner_data_arch_specific< ISA64Big >(symbol_owner, dsym_path); +} diff --git a/test/CodeGenCXX/PR5050-constructor-conversion.cpp b/test/CodeGenCXX/PR5050-constructor-conversion.cpp index 9b993f2506c6..c50dafbbab20 100644 --- a/test/CodeGenCXX/PR5050-constructor-conversion.cpp +++ b/test/CodeGenCXX/PR5050-constructor-conversion.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s struct A { A(const A&, int i1 = 1); }; diff --git a/test/CodeGenCXX/abstract-class-ctors-dtors.cpp b/test/CodeGenCXX/abstract-class-ctors-dtors.cpp index e1c1a75e4790..012c2231551d 100644 --- a/test/CodeGenCXX/abstract-class-ctors-dtors.cpp +++ b/test/CodeGenCXX/abstract-class-ctors-dtors.cpp @@ -9,7 +9,7 @@ struct A { // CHECK-NOT: define void @_ZN1AC1Ev // CHECK: define void @_ZN1AC2Ev -// CHECK-NOT: define void @_ZN1AD1Ev +// CHECK: define void @_ZN1AD1Ev // CHECK: define void @_ZN1AD2Ev A::A() { } diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp index 324ff4aee2b7..a12ae53f395f 100644 --- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp +++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp @@ -67,6 +67,55 @@ namespace test2 { // CHECK: } } +namespace PR10512 { + struct A { + A(); + A(int); + A(long); + + struct { + struct {int x;}; + struct {int y;}; + }; + }; + + // CHECK: define void @_ZN7PR105121AC2Ev + // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]] + // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: ret void + A::A() {} + + // CHECK: define void @_ZN7PR105121AC2Ei + // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]] + // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i32 + // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] + // CHECK-NEXT: store i32 [[X:%[a-zA-z0-9.]+]], i32* [[XADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i32* [[XADDR]] + // CHECK-NEXT: store i32 [[TMP]] + // CHECK-NEXT: ret void + A::A(int x) : x(x) { } + + // CHECK: define void @_ZN7PR105121AC2El + // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]] + // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i64 + // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] + // CHECK-NEXT: store i64 [[X:%[a-zA-z0-9.]+]], i64* [[XADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 1}} + // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} + // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i64* [[XADDR]] + // CHECK-NEXT: [[CONV:%[a-zA-z0-9.]+]] = trunc i64 [[TMP]] to i32 + // CHECK-NEXT: store i32 [[CONV]] + // CHECK-NEXT: ret void + A::A(long y) : y(y) { } +} + namespace test3 { struct A { union { diff --git a/test/CodeGenCXX/apple-kext-linkage.C b/test/CodeGenCXX/apple-kext-linkage.C index 9df11511762c..59d228e2300c 100644 --- a/test/CodeGenCXX/apple-kext-linkage.C +++ b/test/CodeGenCXX/apple-kext-linkage.C @@ -13,13 +13,21 @@ void foo() { Derived d1; // ok } +// CHECK: define internal i32 @_Z1fj( inline unsigned f(unsigned n) { return n == 0 ? 0 : n + f(n-1); } unsigned g(unsigned n) { return f(n); } +// rdar://problem/10133200: give explicit instantiations external linkage in kernel mode +// CHECK: define void @_Z3barIiEvv() +template <typename T> void bar() {} +template void bar<int>(); +// CHECK: define internal i32 @_Z5identIiET_S0_( template <typename X> X ident(X x) { return x; } + int foo(int n) { return ident(n); } -// CHECK-NOT: define linkonce_odr -// CHECK 5 : define internal +// CHECK: define internal void @_ZN7DerivedD1Ev( +// CHECK: define internal void @_ZN7DerivedD0Ev( +// CHECK: define internal void @_ZN7DeriveddlEPv( diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp index dcb27ce0dab3..a767f425553b 100644 --- a/test/CodeGenCXX/arm.cpp +++ b/test/CodeGenCXX/arm.cpp @@ -308,9 +308,10 @@ namespace test7 { // CHECK: ret void static int x = foo(); - // CHECK: call i8* @llvm.eh.exception() + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test74testEvE1x) - // CHECK: call void @llvm.eh.resume( + // CHECK: resume { i8*, i32 } } } @@ -347,9 +348,10 @@ namespace test8 { // CHECK: ret void static A x; - // CHECK: call i8* @llvm.eh.exception() + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: call void @__cxa_guard_abort(i32* @_ZGVZN5test84testEvE1x) - // CHECK: call void @llvm.eh.resume( + // CHECK: resume { i8*, i32 } } } diff --git a/test/CodeGenCXX/array-construction.cpp b/test/CodeGenCXX/array-construction.cpp index 5efe18322d85..7b565a490c11 100644 --- a/test/CodeGenCXX/array-construction.cpp +++ b/test/CodeGenCXX/array-construction.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/array-operator-delete-call.cpp b/test/CodeGenCXX/array-operator-delete-call.cpp index 41b0118fe8a9..1b23c4d137aa 100644 --- a/test/CodeGenCXX/array-operator-delete-call.cpp +++ b/test/CodeGenCXX/array-operator-delete-call.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp index 0e310bdbbc13..cc56525e1d54 100644 --- a/test/CodeGenCXX/blocks.cpp +++ b/test/CodeGenCXX/blocks.cpp @@ -104,3 +104,27 @@ namespace test3 { consume(^{ (void) b; }); } } + +// rdar://problem/9971485 +namespace test4 { + struct A { + A(); + ~A(); + }; + + void foo(A a); + + void test() { + extern void consume(void(^)()); + consume(^{ return foo(A()); }); + } + // CHECK: define void @_ZN5test44testEv() + // CHECK: define internal void @__test_block_invoke + // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 + // CHECK-NEXT: bitcast i8* + // CHECK-NEXT: call void @_ZN5test41AC1Ev([[A]]* [[TMP]]) + // CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]]) + // CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]]) + // CHECK-NEXT: ret void +} + diff --git a/test/CodeGenCXX/builtins.cpp b/test/CodeGenCXX/builtins.cpp index 0629c31015c7..4542563717a1 100644 --- a/test/CodeGenCXX/builtins.cpp +++ b/test/CodeGenCXX/builtins.cpp @@ -7,3 +7,15 @@ int main() { // CHECK: call signext i8 @memmove() return memmove(); } + +// <rdar://problem/10063539> + +template<int (*Compare)(const char *s1, const char *s2)> +int equal(const char *s1, const char *s2) { + return Compare(s1, s2) == 0; +} + +// CHECK: define weak_odr i32 @_Z5equalIXadL_Z16__builtin_strcmpPKcS1_EEEiS1_S1_ +// CHECK: call i32 @strcmp +template int equal<&__builtin_strcmp>(const char*, const char*); + diff --git a/test/CodeGenCXX/cast-conversion.cpp b/test/CodeGenCXX/cast-conversion.cpp index b7a9740ddf1c..d023b9abfee0 100644 --- a/test/CodeGenCXX/cast-conversion.cpp +++ b/test/CodeGenCXX/cast-conversion.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s struct A { diff --git a/test/CodeGenCXX/class-layout.cpp b/test/CodeGenCXX/class-layout.cpp index 9569f476dd87..dac0a0ae5467 100644 --- a/test/CodeGenCXX/class-layout.cpp +++ b/test/CodeGenCXX/class-layout.cpp @@ -45,3 +45,35 @@ namespace Test5 { char c; } *b; } + +// PR10912: don't crash +namespace Test6 { + template <typename T> class A { + // If T is complete, IR-gen will want to translate it recursively + // when translating T*. + T *foo; + }; + + class B; + + // This causes IR-gen to have an incomplete translation of A<B> + // sitting around. + A<B> *a; + + class C {}; + class B : public C { + // This forces Sema to instantiate A<B>, which triggers a callback + // to IR-gen. Because of the previous, incomplete translation, + // IR-gen actually cares, and it immediately tries to complete + // A<B>'s IR type. That, in turn, causes the translation of B*. + // B isn't complete yet, but it has a definition, and if we try to + // compute a record layout for that definition then we'll really + // regret it later. + A<B> a; + }; + + // The derived class E and empty base class C are required to + // provoke the original assertion. + class E : public B {}; + E *e; +} diff --git a/test/CodeGenCXX/conditional-expr-lvalue.cpp b/test/CodeGenCXX/conditional-expr-lvalue.cpp index a0843c40f071..96aa8b07a664 100644 --- a/test/CodeGenCXX/conditional-expr-lvalue.cpp +++ b/test/CodeGenCXX/conditional-expr-lvalue.cpp @@ -5,3 +5,16 @@ void f(bool flag) { (flag ? a : b) = 3; } + +// PR10756 +namespace test0 { + struct A { + A(const A &); + A &operator=(const A &); + A sub() const; + void foo() const; + }; + void foo(bool cond, const A &a) { + (cond ? a : a.sub()).foo(); + } +} diff --git a/test/CodeGenCXX/constructor-conversion.cpp b/test/CodeGenCXX/constructor-conversion.cpp index 58d0d39c8107..f50346328500 100644 --- a/test/CodeGenCXX/constructor-conversion.cpp +++ b/test/CodeGenCXX/constructor-conversion.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/constructor-convert.cpp b/test/CodeGenCXX/constructor-convert.cpp index 9122dae128ec..7feeaa900af6 100644 --- a/test/CodeGenCXX/constructor-convert.cpp +++ b/test/CodeGenCXX/constructor-convert.cpp @@ -2,6 +2,7 @@ // PR5775 class Twine { +public: Twine(const char *Str) { } }; diff --git a/test/CodeGenCXX/constructor-default-arg.cpp b/test/CodeGenCXX/constructor-default-arg.cpp index dc0ab50ba5c6..32086c1ad37c 100644 --- a/test/CodeGenCXX/constructor-default-arg.cpp +++ b/test/CodeGenCXX/constructor-default-arg.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/constructor-for-array-members.cpp b/test/CodeGenCXX/constructor-for-array-members.cpp index ef5900e59c11..7a365cd26da4 100644 --- a/test/CodeGenCXX/constructor-for-array-members.cpp +++ b/test/CodeGenCXX/constructor-for-array-members.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp index a195afe0692f..6af5188a41f6 100644 --- a/test/CodeGenCXX/constructor-init.cpp +++ b/test/CodeGenCXX/constructor-init.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 %s -emit-llvm -o %t +// RUN: FileCheck %s < %t +// RUN: FileCheck -check-prefix=CHECK-PR10720 %s < %t extern "C" int printf(...); @@ -149,3 +151,73 @@ template<typename T> X<T>::X(const X &other) : start(0), end(0) { } X<int> get_X(X<int> x) { return x; } + +namespace PR10720 { + struct X { + X(const X&); + X(X&&); + X& operator=(const X&); + X& operator=(X&&); + ~X(); + }; + + struct pair2 { + X second[4]; + + // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSERKS0_ + // CHECK-PR10720: load + // CHECK-PR10720: icmp ne + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSERKS0_ + // CHECK-PR10720: ret + pair2 &operator=(const pair2&) = default; + + // CHECK-PR10720: define linkonce_odr {{.*}} @_ZN7PR107205pair2aSEOS0_ + // CHECK-PR10720: load + // CHECK-PR10720: icmp ne + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call {{.*}} @_ZN7PR107201XaSEOS0_ + // CHECK-PR10720: ret + pair2 &operator=(pair2&&) = default; + + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: load + // CHECK-PR10720: icmp ult + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_ + // CHECK-PR10720-NEXT: br label + // CHECK-PR10720: ret void + pair2(pair2&&) = default; + + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: load + // CHECK-PR10720: icmp ult + // CHECK-PR10720-NEXT: br i1 + // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_ + // CHECK-PR10720-NEXT: br label + // CHECK-PR10720: ret void + pair2(const pair2&) = default; + }; + + struct pair { + int second[4]; + // CHECK-PR10720: define linkonce_odr void @_ZN7PR107204pairC2ERKS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: call void @llvm.memcpy + // CHECK-PR10720-NEXT: ret void + pair(const pair&) = default; + }; + + void foo(const pair &x, const pair2 &x2) { + pair y(x); + pair2 y2(x2); + pair2 y2m(static_cast<pair2&&>(y2)); + + y2 = x2; + y2m = static_cast<pair2&&>(y2); + } + +} + diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp index 7472d7e5bc63..fe4687c1b303 100644 --- a/test/CodeGenCXX/constructor-template.cpp +++ b/test/CodeGenCXX/constructor-template.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s // PR4826 diff --git a/test/CodeGenCXX/conversion-function.cpp b/test/CodeGenCXX/conversion-function.cpp index e2f8f7e17b93..76d9e027d997 100644 --- a/test/CodeGenCXX/conversion-function.cpp +++ b/test/CodeGenCXX/conversion-function.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s // XFAIL: * extern "C" int printf(...); diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp index c1c9f63079f9..425f79de5067 100644 --- a/test/CodeGenCXX/convert-to-fptr.cpp +++ b/test/CodeGenCXX/convert-to-fptr.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/copy-assign-synthesis-1.cpp b/test/CodeGenCXX/copy-assign-synthesis-1.cpp index 17abeb90d4b3..46d048364118 100644 --- a/test/CodeGenCXX/copy-assign-synthesis-1.cpp +++ b/test/CodeGenCXX/copy-assign-synthesis-1.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp b/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp new file mode 100644 index 000000000000..eb13503fdc3f --- /dev/null +++ b/test/CodeGenCXX/copy-assign-volatile-synthesis.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// rdar://9894548 + +typedef unsigned long word_t; +typedef unsigned long u64_t; +typedef unsigned int u32_t; + +class ioapic_redir_t { +public: + union { + struct { + word_t vector : 8; + + word_t delivery_mode : 3; + word_t dest_mode : 1; + + word_t delivery_status : 1; + word_t polarity : 1; + word_t irr : 1; + word_t trigger_mode : 1; + + word_t mask : 1; + word_t _pad0 : 15; + + word_t dest : 8; + }; + volatile u32_t raw[2]; + volatile u64_t raw64; + }; +}; + +struct ioapic_shadow_struct +{ + ioapic_redir_t redirs[24]; +} ioapic_shadow[16]; + +void init_ioapic(unsigned long ioapic_id) +{ + ioapic_redir_t entry; + ioapic_shadow[ioapic_id].redirs[3] = entry; +} + +// CHECK: call void @llvm.memcpy diff --git a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp index 09eb4fe7a7f6..f4d5ccc0e331 100644 --- a/test/CodeGenCXX/cxx0x-defaulted-templates.cpp +++ b/test/CodeGenCXX/cxx0x-defaulted-templates.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s template <typename T> struct X { diff --git a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp index 0bac492796f8..f5684d93abd9 100644 --- a/test/CodeGenCXX/cxx0x-delegating-ctors.cpp +++ b/test/CodeGenCXX/cxx0x-delegating-ctors.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -fexceptions -fcxx-exceptions -std=c++0x -o - %s | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -fexceptions -fcxx-exceptions -std=c++11 -o - %s | FileCheck %s struct non_trivial { non_trivial(); diff --git a/test/CodeGenCXX/cxx0x-initializer-scalars.cpp b/test/CodeGenCXX/cxx0x-initializer-scalars.cpp new file mode 100644 index 000000000000..10c696604867 --- /dev/null +++ b/test/CodeGenCXX/cxx0x-initializer-scalars.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o - %s | FileCheck %s + +void f() +{ + // CHECK: store i32 0 + int i{}; +} diff --git a/test/CodeGenCXX/debug-info-char16.cpp b/test/CodeGenCXX/debug-info-char16.cpp new file mode 100644 index 000000000000..da8ca051da84 --- /dev/null +++ b/test/CodeGenCXX/debug-info-char16.cpp @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -S -std=c++11 -masm-verbose -g %s -o -| FileCheck %s + +//CHECK: .ascii "char16_t" +//CHECK-NEXT: .byte 0 +//CHECK-NEXT: .byte 16 + +// 16 is DW_ATE_UTF (0x10) encoding attribute. +char16_t char_a = u'h'; + diff --git a/test/CodeGenCXX/debug-info-cxx0x.cpp b/test/CodeGenCXX/debug-info-cxx0x.cpp index 5753b05d728e..37ccdb01c5c0 100644 --- a/test/CodeGenCXX/debug-info-cxx0x.cpp +++ b/test/CodeGenCXX/debug-info-cxx0x.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm-only -std=c++0x -g %s +// RUN: %clang_cc1 -emit-llvm-only -std=c++11 -g %s namespace PR9414 { int f() { diff --git a/test/CodeGenCXX/debug-info-nullptr.cpp b/test/CodeGenCXX/debug-info-nullptr.cpp new file mode 100644 index 000000000000..588dc5f3c399 --- /dev/null +++ b/test/CodeGenCXX/debug-info-nullptr.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -S -std=c++11 -masm-verbose -g %s -o -| FileCheck %s + +//CHECK: DW_TAG_unspecified_type +//CHECK-NEXT: "nullptr_t" + +void foo() { + decltype(nullptr) t = 0; + } diff --git a/test/CodeGenCXX/debug-info-wchar.cpp b/test/CodeGenCXX/debug-info-wchar.cpp new file mode 100644 index 000000000000..6f5384966b99 --- /dev/null +++ b/test/CodeGenCXX/debug-info-wchar.cpp @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm -g %s -o -| FileCheck %s +void foo() { +// CHECK: metadata !"wchar_t", + const wchar_t w = L'x'; +} diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp index 71c8603a9faa..33b52789caf2 100644 --- a/test/CodeGenCXX/debug-info.cpp +++ b/test/CodeGenCXX/debug-info.cpp @@ -55,3 +55,15 @@ void foo() { const wchar_t c = L'x'; wchar_t d = c; } + +namespace b5249287 { +template <typename T> class A { + struct B; +}; + +class Cls { + template <typename T> friend class A<T>::B; +}; + +Cls obj; +} diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp index 08ce0de3b5c3..5a88f9f92437 100644 --- a/test/CodeGenCXX/delete.cpp +++ b/test/CodeGenCXX/delete.cpp @@ -30,7 +30,7 @@ void t4(T *t) { // PR5102 template <typename T> class A { - operator T *() const; + public: operator T *() const; }; void f() { @@ -122,3 +122,14 @@ namespace test4 { ::delete xp; } } + +namespace test5 { + struct Incomplete; + // CHECK: define void @_ZN5test523array_delete_incompleteEPNS_10IncompleteES1_ + void array_delete_incomplete(Incomplete *p1, Incomplete *p2) { + // CHECK: call void @_ZdlPv + delete p1; + // CHECK: call void @_ZdaPv + delete [] p2; + } +} diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp index c47c83180906..8c51809e0427 100644 --- a/test/CodeGenCXX/derived-to-base-conv.cpp +++ b/test/CodeGenCXX/derived-to-base-conv.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp index 33819858149b..d9962e615ec5 100644 --- a/test/CodeGenCXX/destructors.cpp +++ b/test/CodeGenCXX/destructors.cpp @@ -237,7 +237,6 @@ namespace test5 { // CHECK: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align // CHECK-NEXT: [[EXN:%.*]] = alloca i8* // CHECK-NEXT: [[SEL:%.*]] = alloca i32 - // CHECK-NEXT: [[EHCLEANUP:%.*]] = alloca i32 // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]]* [[ELEMS]], i32 0, i32 0 // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5 // CHECK-NEXT: br label @@ -323,7 +322,32 @@ namespace test7 { // CHECK: invoke void @_ZN5test71DD1Ev( // CHECK: call void @_ZN5test71AD2Ev( B::~B() {} +} + +// PR10467 +namespace test8 { + struct A { A(); ~A(); }; + void die() __attribute__((noreturn)); + void test() { + A x; + while (1) { + A y; + goto l; + } + l: die(); + } + + // CHECK: define void @_ZN5test84testEv() + // CHECK: [[X:%.*]] = alloca [[A:%.*]], align 1 + // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]], align 1 + // CHECK: call void @_ZN5test81AC1Ev([[A]]* [[X]]) + // CHECK-NEXT: br label + // CHECK: invoke void @_ZN5test81AC1Ev([[A]]* [[Y]]) + // CHECK: invoke void @_ZN5test81AD1Ev([[A]]* [[Y]]) + // CHECK-NOT: switch + // CHECK: invoke void @_ZN5test83dieEv() + // CHECK: unreachable } // Checks from test3: @@ -332,9 +356,10 @@ namespace test7 { // CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev( // CHECK: call void @_ZdlPv({{.*}}) nounwind // CHECK: ret void - // CHECK: call i8* @llvm.eh.exception( + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: call void @_ZdlPv({{.*}}) nounwind - // CHECK: call void @llvm.eh.resume( + // CHECK: resume { i8*, i32 } // Checked at top of file: // @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev @@ -362,9 +387,10 @@ namespace test7 { // CHECK: invoke void @_ZN5test312_GLOBAL__N_11CD1Ev( // CHECK: call void @_ZdlPv({{.*}}) nounwind // CHECK: ret void - // CHECK: call i8* @llvm.eh.exception() + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: call void @_ZdlPv({{.*}}) nounwind - // CHECK: call void @llvm.eh.resume( + // CHECK: resume { i8*, i32 } // CHECK: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev( // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 diff --git a/test/CodeGenCXX/dynamic-cast-always-null.cpp b/test/CodeGenCXX/dynamic-cast-always-null.cpp index e4e86942181d..2c3ea13d1957 100644 --- a/test/CodeGenCXX/dynamic-cast-always-null.cpp +++ b/test/CodeGenCXX/dynamic-cast-always-null.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++0x -o - | FileCheck %s +// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions -std=c++11 -o - | FileCheck %s struct A { virtual ~A(); }; struct B final : A { }; struct C { virtual ~C(); int c; }; diff --git a/test/CodeGenCXX/dynamic-cast.cpp b/test/CodeGenCXX/dynamic-cast.cpp index e84bb9b4ff50..813e36e941b7 100644 --- a/test/CodeGenCXX/dynamic-cast.cpp +++ b/test/CodeGenCXX/dynamic-cast.cpp @@ -11,7 +11,8 @@ const B& f(A *a) { // CHECK: invoke void @__cxa_bad_cast() noreturn dynamic_cast<const B&>(*a); } catch (...) { - // CHECK: call i8* @llvm.eh.exception + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: catch i8* null } return fail; } diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index 58cb44515ddf..584af40da62d 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t.ll +// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s struct test1_D { @@ -32,7 +32,6 @@ void test2() { // CHECK: define void @_Z5test2v() // CHECK: [[EXNVAR:%.*]] = alloca i8* // CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32 -// CHECK-NEXT: [[CLEANUPDESTVAR:%.*]] = alloca i32 // CHECK-NEXT: [[EXNOBJ:%.*]] = call i8* @__cxa_allocate_exception(i64 16) // CHECK-NEXT: [[EXN:%.*]] = bitcast i8* [[EXNOBJ]] to [[DSTAR:%[^*]*\*]] // CHECK-NEXT: invoke void @_ZN7test2_DC1ERKS_([[DSTAR]] [[EXN]], [[DSTAR]] @d2) @@ -107,7 +106,6 @@ namespace test7 { // CHECK: [[CAUGHTEXNVAR:%.*]] = alloca i8* // CHECK-NEXT: [[SELECTORVAR:%.*]] = alloca i32 // CHECK-NEXT: [[INTCATCHVAR:%.*]] = alloca i32 -// CHECK-NEXT: [[EHCLEANUPDESTVAR:%.*]] = alloca i32 try { try { // CHECK-NEXT: [[EXNALLOC:%.*]] = call i8* @__cxa_allocate_exception @@ -117,25 +115,34 @@ namespace test7 { throw 1; } -// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception() +// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*) +// CHECK-NEXT: catch i8* null +// CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] -// CHECK-NEXT: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null) +// CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 // CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] -// CHECK-NEXT: call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) -// CHECK-NEXT: icmp eq +// CHECK-NEXT: br label +// CHECK: [[SELECTOR:%.*]] = load i32* [[SELECTORVAR]] +// CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) +// CHECK-NEXT: icmp eq i32 [[SELECTOR]], [[T0]] // CHECK-NEXT: br i1 -// CHECK: load i8** [[CAUGHTEXNVAR]] -// CHECK-NEXT: call i8* @__cxa_begin_catch -// CHECK: invoke void @__cxa_rethrow +// CHECK: [[T0:%.*]] = load i8** [[CAUGHTEXNVAR]] +// CHECK-NEXT: [[T1:%.*]] = call i8* @__cxa_begin_catch(i8* [[T0]]) +// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i32* +// CHECK-NEXT: [[T3:%.*]] = load i32* [[T2]] +// CHECK-NEXT: store i32 [[T3]], i32* {{%.*}}, align 4 +// CHECK-NEXT: invoke void @__cxa_rethrow catch (int) { throw; } } -// CHECK: [[CAUGHTEXN:%.*]] = call i8* @llvm.eh.exception() +// CHECK: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) +// CHECK-NEXT: catch i8* null +// CHECK-NEXT: [[CAUGHTEXN:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 // CHECK-NEXT: store i8* [[CAUGHTEXN]], i8** [[CAUGHTEXNVAR]] -// CHECK-NEXT: [[SELECTOR:%.*]] = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* [[CAUGHTEXN]], i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* null) +// CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 // CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] -// CHECK-NEXT: store i32 1, i32* [[EHCLEANUPDESTVAR]] // CHECK-NEXT: call void @__cxa_end_catch() // CHECK-NEXT: br label // CHECK: load i8** [[CAUGHTEXNVAR]] @@ -186,15 +193,14 @@ namespace test9 { // CHECK: invoke void @_ZN5test96opaqueEv() opaque(); } catch (int x) { + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: catch i8* bitcast (i8** @_ZTIi to i8*) + // CHECK: call i8* @__cxa_begin_catch // CHECK: invoke void @_ZN5test96opaqueEv() // CHECK: invoke void @__cxa_rethrow() opaque(); } - - // landing pad from first call to invoke - // CHECK: call i8* @llvm.eh.exception - // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* {{.*}}, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*)) } // __cxa_end_catch can throw for some kinds of caught exceptions. @@ -296,10 +302,7 @@ namespace test12 { // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Z]]) // CHECK: invoke void @_ZN6test121AD1Ev([[A]]* [[Y]]) - - // It'd be great if something eliminated this switch. - // CHECK: load i32* [[CLEANUPDEST]] - // CHECK-NEXT: switch i32 + // CHECK-NOT: switch goto success; } @@ -409,7 +412,6 @@ namespace test16 { // CHECK-NEXT: [[TEMP:%.*]] = alloca [[A:%.*]], // CHECK-NEXT: [[EXNSLOT:%.*]] = alloca i8* // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 - // CHECK-NEXT: [[EHDEST:%.*]] = alloca i32 // CHECK-NEXT: [[TEMP_ACTIVE:%.*]] = alloca i1 cond() ? throw B(A()) : foo(); diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp index b32b90bf7412..0fbb09c2624a 100644 --- a/test/CodeGenCXX/exceptions.cpp +++ b/test/CodeGenCXX/exceptions.cpp @@ -276,7 +276,6 @@ namespace test5 { // CHECK-NEXT: [[SELECTORSLOT:%.*]] = alloca i32 // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1 // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1 - // CHECK-NEXT: alloca i32 // CHECK-NEXT: invoke void @_ZN5test53fooEv() // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]] // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]]) @@ -325,7 +324,6 @@ namespace test7 { // CHECK-NEXT: alloca [[A:%.*]], // CHECK-NEXT: alloca i8* // CHECK-NEXT: alloca i32 - // CHECK-NEXT: alloca i32 // CHECK-NEXT: [[OUTER_A:%.*]] = alloca i1 // CHECK-NEXT: alloca i8* // CHECK-NEXT: [[INNER_NEW:%.*]] = alloca i1 @@ -392,3 +390,38 @@ namespace test7 { return new B(A(), new B(A(), 0)); } } + +// Just don't crash. +namespace test8 { + struct A { + // Having both of these is required to trigger the assert we're + // trying to avoid. + A(const A&); + A&operator=(const A&); + + ~A(); + }; + + A makeA(); + void test() { + throw makeA(); + } + // CHECK: define void @_ZN5test84testEv +} + +// Make sure we generate the correct code for the delete[] call which +// happens if A::A() throws. (We were previously calling delete[] on +// a pointer to the first array element, not the pointer returned by new[].) +// PR10870 +namespace test9 { + struct A { + A(); + ~A(); + }; + A* test() { + return new A[10]; + } + // CHECK: define {{%.*}}* @_ZN5test94testEv + // CHECK: [[TEST9_NEW:%.*]] = call noalias i8* @_Znam + // CHECK: call void @_ZdaPv(i8* [[TEST9_NEW]]) +} diff --git a/test/CodeGenCXX/for-range-temporaries.cpp b/test/CodeGenCXX/for-range-temporaries.cpp index be594ce5223d..c705702f4f51 100644 --- a/test/CodeGenCXX/for-range-temporaries.cpp +++ b/test/CodeGenCXX/for-range-temporaries.cpp @@ -1,5 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++0x -emit-llvm -o - -UDESUGAR %s | opt -instnamer -S | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++0x -emit-llvm -o - -DDESUGAR %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -UDESUGAR %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -DDESUGAR %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - -DDESUGAR -DTEMPLATE %s | opt -instnamer -S | FileCheck %s struct A { A(); @@ -65,6 +66,9 @@ struct I { void body(const I &); +#ifdef TEMPLATE +template<typename D> +#endif void for_temps() { A a; #ifdef DESUGAR @@ -83,7 +87,11 @@ void for_temps() { #endif } -// CHECK: define void @_Z9for_tempsv() +#ifdef TEMPLATE +template void for_temps<D>(); +#endif + +// CHECK: define {{.*}}for_temps // CHECK: call void @_ZN1AC1Ev( // CHECK: call void @_ZN1BC1Ev( // CHECK: call void @_ZN1CC1ERK1B( diff --git a/test/CodeGenCXX/for-range.cpp b/test/CodeGenCXX/for-range.cpp index ab1a2317ba93..0f35dda737fe 100644 --- a/test/CodeGenCXX/for-range.cpp +++ b/test/CodeGenCXX/for-range.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++0x -emit-llvm -o - %s | opt -instnamer -S | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c++11 -emit-llvm -o - %s | opt -instnamer -S | FileCheck %s struct A { A(); diff --git a/test/CodeGenCXX/fp16-mangle.cpp b/test/CodeGenCXX/fp16-mangle.cpp new file mode 100644 index 000000000000..4a056d6c6bbb --- /dev/null +++ b/test/CodeGenCXX/fp16-mangle.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s + +// CHECK: @_ZN1SIDhDhE1iE = global i32 3 +template <typename T, typename U> struct S { static int i; }; +template <> int S<__fp16, __fp16>::i = 3; + +// CHECK: define void @_Z1fPDh(i16* %x) +void f (__fp16 *x) { } + +// CHECK: define void @_Z1gPDhS_(i16* %x, i16* %y) +void g (__fp16 *x, __fp16 *y) { } + diff --git a/test/CodeGenCXX/fp16-overload.cpp b/test/CodeGenCXX/fp16-overload.cpp new file mode 100644 index 000000000000..75622109c175 --- /dev/null +++ b/test/CodeGenCXX/fp16-overload.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple arm-none-linux-gnueabi %s | FileCheck %s + +extern int foo(float x); +extern int foo(double x); + +__fp16 a; + +// CHECK: call i32 @_Z3foof +// CHECK-NOT: call i32 @_Z3food +int bar (void) { return foo(a); } diff --git a/test/CodeGenCXX/global-array-destruction.cpp b/test/CodeGenCXX/global-array-destruction.cpp index bbe574daa588..5b5dfac0f228 100644 --- a/test/CodeGenCXX/global-array-destruction.cpp +++ b/test/CodeGenCXX/global-array-destruction.cpp @@ -1,5 +1,5 @@ // REQUIRES: x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/goto.cpp b/test/CodeGenCXX/goto.cpp index 9a12a9125398..f32847d122bc 100644 --- a/test/CodeGenCXX/goto.cpp +++ b/test/CodeGenCXX/goto.cpp @@ -13,7 +13,6 @@ namespace test0 { // CHECK-NEXT: [[Z:%.*]] = alloca [[A]] // CHECK-NEXT: [[EXN:%.*]] = alloca i8* // CHECK-NEXT: [[SEL:%.*]] = alloca i32 - // CHECK-NEXT: alloca i32 // CHECK-NEXT: [[V:%.*]] = alloca [[V:%.*]]*, // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]] // CHECK-NEXT: [[CLEANUPACTIVE:%.*]] = alloca i1 diff --git a/test/CodeGenCXX/init-incomplete-type.cpp b/test/CodeGenCXX/incomplete-types.cpp index 1755dfb7beb1..1d4f430e5cb5 100644 --- a/test/CodeGenCXX/init-incomplete-type.cpp +++ b/test/CodeGenCXX/incomplete-types.cpp @@ -28,4 +28,16 @@ namespace incomplete_type_refs { return &g[1]; } -}
\ No newline at end of file +} + +namespace PR10395 { + struct T; + extern T x[]; + T* f() { return x; } +} + +namespace PR10384 { + struct X; + extern X x[1]; + X* f() { return x; } +} diff --git a/test/CodeGenCXX/m64-ptr.cpp b/test/CodeGenCXX/m64-ptr.cpp new file mode 100644 index 000000000000..29916bf32a65 --- /dev/null +++ b/test/CodeGenCXX/m64-ptr.cpp @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-darwin -o - | FileCheck %s + +// Make sure pointers are passed as pointers, not converted to int. +// The first load should be of type i8** in either 32 or 64 bit mode. +// This formerly happened on x86-64, 7375899. + +class StringRef { +public: + const char *Data; + long Len; +}; +void foo(StringRef X); +void bar(StringRef &A) { +// CHECK: @_Z3barR9StringRef +// CHECK: load i8** + foo(A); +// CHECK: ret void +} diff --git a/test/CodeGenCXX/mangle-alias-template.cpp b/test/CodeGenCXX/mangle-alias-template.cpp index 2020a0a584e1..1143ea114a1a 100644 --- a/test/CodeGenCXX/mangle-alias-template.cpp +++ b/test/CodeGenCXX/mangle-alias-template.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s template<typename T> struct alloc {}; template<typename T> using Alloc = alloc<T>; diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp index 75294e059c55..c5f72d83c750 100644 --- a/test/CodeGenCXX/mangle-exprs.cpp +++ b/test/CodeGenCXX/mangle-exprs.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 | FileCheck %s template < bool condition, typename T = void > struct enable_if { typedef T type; }; diff --git a/test/CodeGenCXX/mangle-ref-qualifiers.cpp b/test/CodeGenCXX/mangle-ref-qualifiers.cpp index b3f37d7db31a..568cf9f24700 100644 --- a/test/CodeGenCXX/mangle-ref-qualifiers.cpp +++ b/test/CodeGenCXX/mangle-ref-qualifiers.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s struct X { int f() &; int g() &&; diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp index 30b579ceb823..04e3e84304e8 100644 --- a/test/CodeGenCXX/mangle-subst-std.cpp +++ b/test/CodeGenCXX/mangle-subst-std.cpp @@ -3,14 +3,14 @@ // Check mangling of Vtables, VTTs, and construction vtables that // involve standard substitutions. -// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant // CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant +// CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant // CHECK: @_ZTCSd0_Si = linkonce_odr unnamed_addr constant // CHECK: @_ZTCSd16_So = linkonce_odr unnamed_addr constant -// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant // CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant -// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant +// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant // CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant +// CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant namespace std { struct A { A(); }; diff --git a/test/CodeGenCXX/mangle-unnameable-conversions.cpp b/test/CodeGenCXX/mangle-unnameable-conversions.cpp index 2132eff5e511..2ecded05d979 100644 --- a/test/CodeGenCXX/mangle-unnameable-conversions.cpp +++ b/test/CodeGenCXX/mangle-unnameable-conversions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s template<typename T> using id = T; struct S { diff --git a/test/CodeGenCXX/mangle-variadic-templates.cpp b/test/CodeGenCXX/mangle-variadic-templates.cpp index a987b49a1281..b5bdae234445 100644 --- a/test/CodeGenCXX/mangle-variadic-templates.cpp +++ b/test/CodeGenCXX/mangle-variadic-templates.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -emit-llvm -triple=x86_64-apple-darwin9 -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -triple=x86_64-apple-darwin9 -o - %s | FileCheck %s template<unsigned I, typename ...Types> struct X { }; diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index 453b7b713ac6..47c42a7347fa 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++0x | FileCheck %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -fblocks -std=c++11 | FileCheck %s struct X { }; struct Y { }; @@ -533,17 +533,6 @@ namespace test15 { template void f<7>(S<7 + e>); } -// rdar://problem/8125400. Don't crash. -namespace test16 { - static union {}; - static union { union {}; }; - static union { struct {}; }; - static union { union { union {}; }; }; - static union { union { struct {}; }; }; - static union { struct { union {}; }; }; - static union { struct { struct {}; }; }; -} - // rdar://problem/8302148 namespace test17 { template <int N> struct A {}; diff --git a/test/CodeGenCXX/member-alignment.cpp b/test/CodeGenCXX/member-alignment.cpp new file mode 100644 index 000000000000..8e120f712507 --- /dev/null +++ b/test/CodeGenCXX/member-alignment.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// XFAIL: arm,powerpc + +// rdar://7268289 + +class t { +public: + virtual void foo(void); + void bar(void); +}; + +void +t::bar(void) { +// CHECK: _ZN1t3barEv{{.*}} align 2 +} + +void +t::foo(void) { +// CHECK: _ZN1t3fooEv{{.*}} align 2 +} diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index 4c42bd8283ae..5ce5fbf760db 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -33,7 +33,7 @@ void f() { pa = 0; // Is this okay? What are LLVM's volatile semantics for structs? - // CHECK: volatile store { i64, i64 } zeroinitializer, { i64, i64 }* @vpa + // CHECK: store volatile { i64, i64 } zeroinitializer, { i64, i64 }* @vpa vpa = 0; // CHECK: [[TMP:%.*]] = load { i64, i64 }* @pa, align 8 diff --git a/test/CodeGenCXX/member-init-anon-union.cpp b/test/CodeGenCXX/member-init-anon-union.cpp new file mode 100644 index 000000000000..1ff7537387c2 --- /dev/null +++ b/test/CodeGenCXX/member-init-anon-union.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s + +// PR10531. + +static union { + int a = 42; + char *b; +}; + +int f() { return a; } + +// CHECK: define internal void @__cxx_global_var_init +// CHECK-NOT: } +// CHECK: call {{.*}}@"[[CONSTRUCT_GLOBAL:.*]]C1Ev" + + +int g() { + union { + int a; + int b = 81; + }; + // CHECK: define {{.*}}_Z1gv + // CHECK-NOT: } + // CHECK: call {{.*}}@"[[CONSTRUCT_LOCAL:.*]]C1Ev" + return b; +} + + +// CHECK: define {{.*}}@"[[CONSTRUCT_LOCAL]]C2Ev" +// CHECK-NOT: } +// CHECK: store i32 81 + +// CHECK: define {{.*}}@"[[CONSTRUCT_GLOBAL]]C2Ev" +// CHECK-NOT: } +// CHECK: store i32 42 diff --git a/test/CodeGenCXX/member-init-ctor.cpp b/test/CodeGenCXX/member-init-ctor.cpp index d70947bcab00..21723942571f 100644 --- a/test/CodeGenCXX/member-init-ctor.cpp +++ b/test/CodeGenCXX/member-init-ctor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -std=c++0x -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s bool b(); struct S { diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp index 0efb35538038..57bf27ab7aff 100644 --- a/test/CodeGenCXX/nrvo.cpp +++ b/test/CodeGenCXX/nrvo.cpp @@ -68,8 +68,10 @@ X test2(bool B) { // -> %cleanup, %lpad1 // %lpad: landing pad for ctor of 'y', dtor of 'y' - // CHECK-EH: call i8* @llvm.eh.exception() - // CHECK-EH: call i32 (i8*, i8*, ...)* @llvm.eh.selector + // CHECK-EH: [[CAUGHTVAL:%.*]] = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-EH-NEXT: cleanup + // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 0 + // CHECK-EH-NEXT: extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 // CHECK-EH-NEXT: br label // -> %eh.cleanup @@ -95,12 +97,11 @@ X test2(bool B) { // %invoke.cont17: rethrow block for %eh.cleanup. // This really should be elsewhere in the function. - // CHECK-EH: call void @llvm.eh.resume( - // CHECK-EH-NEXT: unreachable + // CHECK-EH: resume { i8*, i32 } // %terminate.lpad: terminate landing pad. - // CHECK-EH: call i8* @llvm.eh.exception() - // CHECK-EH-NEXT: call i32 (i8*, i8*, ...)* @llvm.eh.selector + // CHECK-EH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-EH-NEXT: catch i8* null // CHECK-EH-NEXT: call void @_ZSt9terminatev() // CHECK-EH-NEXT: unreachable diff --git a/test/CodeGenCXX/nullptr.cpp b/test/CodeGenCXX/nullptr.cpp index 1ea23ec0a95b..e93f7061bdda 100644 --- a/test/CodeGenCXX/nullptr.cpp +++ b/test/CodeGenCXX/nullptr.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -I%S -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -I%S -emit-llvm -o - %s | FileCheck %s #include <typeinfo> diff --git a/test/CodeGenCXX/partial-destruction.cpp b/test/CodeGenCXX/partial-destruction.cpp index 82deca06cf80..f232a159eda5 100644 --- a/test/CodeGenCXX/partial-destruction.cpp +++ b/test/CodeGenCXX/partial-destruction.cpp @@ -16,7 +16,6 @@ namespace test0 { // CHECK-NEXT: [[ENDVAR:%.*]] = alloca [[A]]* // CHECK-NEXT: [[EXN:%.*]] = alloca i8* // CHECK-NEXT: [[SEL:%.*]] = alloca i32 - // CHECK-NEXT: [[CLEANUP:%.*]] = alloca i32 // Initialize. // CHECK-NEXT: [[E_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i64 0, i64 0 @@ -51,7 +50,8 @@ namespace test0 { // CHECK: ret void // Partial destroy for initialization. - // CHECK: llvm.eh.selector({{.*}}, i32 0) + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: [[PARTIAL_END:%.*]] = load [[A]]** [[ENDVAR]] // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_BEGIN]], [[PARTIAL_END]] // CHECK-NEXT: br i1 [[T0]], @@ -62,7 +62,8 @@ namespace test0 { // CHECK-NEXT: br i1 [[T0]], // Primary EH destructor. - // CHECK: llvm.eh.selector({{.*}}, i32 0) + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: [[E0:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i32 0, i32 0 // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]]* [[E0]], i64 10 // CHECK-NEXT: br label @@ -71,7 +72,8 @@ namespace test0 { // FIXME: There's some really bad block ordering here which causes // the partial destroy for the primary normal destructor to fall // within the primary EH destructor. - // CHECK: llvm.eh.selector({{.*}}, i32 0) + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]] // CHECK-NEXT: br i1 [[T0]] // CHECK: [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ] @@ -100,7 +102,6 @@ namespace test1 { // CHECK: [[V:%.*]] = alloca [[B:%.*]], align 4 // CHECK-NEXT: alloca i8* // CHECK-NEXT: alloca i32 - // CHECK-NEXT: alloca i32 // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 0 // CHECK-NEXT: call void @_ZN5test11AC1Ei([[A:%.*]]* [[X]], i32 5) // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 1 @@ -113,8 +114,10 @@ namespace test1 { // CHECK-NEXT: ret void // FIXME: again, the block ordering is pretty bad here - // CHECK: eh.selector({{.*}}, i32 0) - // CHECK: eh.selector({{.*}}, i32 0) + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[Y]]) // CHECK: invoke void @_ZN5test11AD1Ev([[A]]* [[X]]) } @@ -129,7 +132,6 @@ namespace test2 { // CHECK: [[V:%.*]] = alloca [4 x [7 x [[A:%.*]]]], align 1 // CHECK-NEXT: alloca i8* // CHECK-NEXT: alloca i32 - // CHECK-NEXT: alloca i32 // Main initialization loop. // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x [7 x [[A]]]]* [[V]], i32 0, i32 0, i32 0 @@ -142,7 +144,8 @@ namespace test2 { // CHECK-NEXT: br i1 [[DONE]], // Partial destruction landing pad. - // CHECK: llvm.eh.exception() + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: cleanup // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[CUR]] // CHECK-NEXT: br i1 [[EMPTY]], // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[DEL:%.*]], {{%.*}} ] diff --git a/test/CodeGenCXX/pr9965.cpp b/test/CodeGenCXX/pr9965.cpp index 596dee9caaa3..145fd4e424f4 100644 --- a/test/CodeGenCXX/pr9965.cpp +++ b/test/CodeGenCXX/pr9965.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s template<typename T> struct X { diff --git a/test/CodeGenCXX/ptr-to-member-function.cpp b/test/CodeGenCXX/ptr-to-member-function.cpp index d012fb9c59b5..3989c0362889 100644 --- a/test/CodeGenCXX/ptr-to-member-function.cpp +++ b/test/CodeGenCXX/ptr-to-member-function.cpp @@ -1,7 +1,7 @@ // REQUIRES: x86-registered-target,x86-64-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -S %s -o %t-64.s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++0x -S %s -o %t-32.s +// RUN: %clang_cc1 -triple i386-apple-darwin -std=c++11 -S %s -o %t-32.s // RUN: FileCheck -check-prefix LP32 --input-file=%t-32.s %s // 13.3.3.2 Ranking implicit conversion sequences diff --git a/test/CodeGenCXX/reference-cast.cpp b/test/CodeGenCXX/reference-cast.cpp index 585d1dbd4084..1d08b2b2e4b7 100644 --- a/test/CodeGenCXX/reference-cast.cpp +++ b/test/CodeGenCXX/reference-cast.cpp @@ -168,3 +168,27 @@ const _Complex float &f1() { // CHECK: store float return get_complex_double(); } + +// CHECK: define i32 @_Z7pr10592RKi(i32* +unsigned pr10592(const int &v) { + // CHECK: [[VADDR:%[a-zA-Z0-9.]+]] = alloca i32* + // CHECK-NEXT: [[REFTMP:%[a-zA-Z0-9.]+]] = alloca i32 + // CHECK-NEXT: store i32* [[V:%[a-zA-Z0-9.]+]], i32** [[VADDR]] + // CHECK-NEXT: [[VADDR_1:%[a-zA-Z0-9.]+]] = load i32** [[VADDR]] + // CHECK-NEXT: [[VVAL:%[a-zA-Z0-9.]+]] = load i32* [[VADDR_1]] + // CHECK-NEXT: store i32 [[VVAL]], i32* [[REFTMP]] + // CHECK-NEXT: [[VVAL_I:%[a-zA-Z0-9.]+]] = load i32* [[REFTMP]] + // CHECK-NEXT: ret i32 [[VVAL_I]] + return static_cast<const unsigned &>(v); +} + +namespace PR10650 { + struct Helper { + unsigned long long id(); + }; + unsigned long long test(Helper *obj) { + return static_cast<const unsigned long long&>(obj->id()); + } + // CHECK: define i64 @_ZN7PR106504testEPNS_6HelperE + // CHECK: store i64 +} diff --git a/test/CodeGenCXX/reinterpret-cast.cpp b/test/CodeGenCXX/reinterpret-cast.cpp index ff5679248c25..dafa67529f77 100644 --- a/test/CodeGenCXX/reinterpret-cast.cpp +++ b/test/CodeGenCXX/reinterpret-cast.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -o - %s -std=c++0x +// RUN: %clang_cc1 -emit-llvm -o - %s -std=c++11 void *f1(unsigned long l) { return reinterpret_cast<void *>(l); } diff --git a/test/CodeGenCXX/rvalue-references.cpp b/test/CodeGenCXX/rvalue-references.cpp index e15172355ebd..1c25543beabc 100644 --- a/test/CodeGenCXX/rvalue-references.cpp +++ b/test/CodeGenCXX/rvalue-references.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s struct Spacer { int x; }; @@ -83,3 +83,29 @@ C test_move_return() { // CHECK: call void @_ZN1CD1Ev //CHECK: ret void } + +// PR10800: don't crash +namespace test1 { + int &&move(int&); + + struct A { A(int); }; + struct B { + A a; + B(int i); + }; + + // CHECK: define void @_ZN5test11BC2Ei( + // CHECK: [[T0:%.*]] = call i32* @_ZN5test14moveERi( + // CHECK-NEXT: [[T1:%.*]] = load i32* [[T0]] + // CHECK-NEXT: call void @_ZN5test11AC1Ei({{.*}}, i32 [[T1]]) + // CHECK-NEXT: ret void + B::B(int i) : a(move(i)) {} +} + +// PR11009 +struct MoveConvertible { + operator int&& () const; +}; +void moveConstruct() { + (void)(int)MoveConvertible(); +} diff --git a/test/CodeGenCXX/scoped-enums.cpp b/test/CodeGenCXX/scoped-enums.cpp index d40ab3651116..fca05098923c 100644 --- a/test/CodeGenCXX/scoped-enums.cpp +++ b/test/CodeGenCXX/scoped-enums.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -emit-llvm -o - %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s // PR9923 enum class Color { red, blue, green }; diff --git a/test/CodeGenCXX/sizeof-unwind-exception.cpp b/test/CodeGenCXX/sizeof-unwind-exception.cpp new file mode 100644 index 000000000000..5db4df7c75ac --- /dev/null +++ b/test/CodeGenCXX/sizeof-unwind-exception.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=X86-64 +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=X86-32 +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=ARM-DARWIN +// RUN: %clang_cc1 -triple arm-unknown-gnueabi -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=ARM-EABI +// RUN: %clang_cc1 -triple mipsel-unknown-unknown -emit-llvm -fcxx-exceptions -fexceptions %s -O2 -o - | FileCheck %s --check-prefix=MIPS + +void foo(); +void test() { + try { + foo(); + } catch (int *&i) { + *i = 5; + } +} + +// PR10789: different platforms have different sizes for struct UnwindException. + +// X86-64: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) nounwind +// X86-64-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i64 32 +// X86-32: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) nounwind +// X86-32-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i64 32 +// ARM-DARWIN: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) nounwind +// ARM-DARWIN-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i64 32 +// ARM-EABI: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) nounwind +// ARM-EABI-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i32 88 +// MIPS: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) nounwind +// MIPS-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i32 24 + diff --git a/test/CodeGenCXX/static-assert.cpp b/test/CodeGenCXX/static-assert.cpp index dbb8f34d8414..53dc9a73805f 100644 --- a/test/CodeGenCXX/static-assert.cpp +++ b/test/CodeGenCXX/static-assert.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -emit-llvm -o - -std=c++0x -verify +// RUN: %clang_cc1 %s -emit-llvm -o - -std=c++11 -verify static_assert(true, ""); diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp index d488e636696e..9e2673cc967d 100644 --- a/test/CodeGenCXX/static-init.cpp +++ b/test/CodeGenCXX/static-init.cpp @@ -12,13 +12,11 @@ struct A { }; void f() { + // CHECK: load atomic i8* bitcast (i64* @_ZGVZ1fvE1a to i8*) acquire, align 1 // CHECK: call i32 @__cxa_guard_acquire // CHECK: call void @_ZN1AC1Ev // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*)) // CHECK: call void @__cxa_guard_release - - // rdar://problem/9496726 - // CHECK: call void @llvm.memory.barrier(i1 true, i1 true, i1 false, i1 false, i1 false) static A a; } diff --git a/test/CodeGenCXX/template-instantiation.cpp b/test/CodeGenCXX/template-instantiation.cpp index cc30af0aba4b..09b3a4fcc544 100644 --- a/test/CodeGenCXX/template-instantiation.cpp +++ b/test/CodeGenCXX/template-instantiation.cpp @@ -17,6 +17,19 @@ // CHECK: define linkonce_odr void @_ZN5test21CIiE6foobarIdEEvT_( // CHECK: define available_externally void @_ZN5test21CIiE6zedbarEd( +// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi1EEE() +// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi2EEE() +// CHECK: define linkonce_odr void @_ZN7PR106662g1ENS_1SILi3EEE() +// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi1EEE() +// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi2EEE() +// CHECK: define linkonce_odr void @_ZN7PR106662g2ENS_1SILi3EEE() +// CHECK: declare void @_ZN7PR106662h1ENS_1SILi1EEE() +// CHECK: declare void @_ZN7PR106662h1ENS_1SILi2EEE() +// CHECK: declare void @_ZN7PR106662h1ENS_1SILi3EEE() +// CHECK: declare void @_ZN7PR106662h2ENS_1SILi1EEE() +// CHECK: declare void @_ZN7PR106662h2ENS_1SILi2EEE() +// CHECK: declare void @_ZN7PR106662h2ENS_1SILi3EEE() + namespace test0 { struct basic_streambuf { virtual ~basic_streambuf(); @@ -152,3 +165,26 @@ namespace PR10001 { int x = S<int>::f(); } + +// Ensure that definitions are emitted for all friend functions defined within +// class templates. Order of declaration is extremely important here. Different +// instantiations of the class happen at different points during the deferred +// method body parsing and afterward. Those different points of instantiation +// change the exact form the class template appears to have. +namespace PR10666 { + template <int N> struct S { + void f1() { S<1> s; } + friend void g1(S s) {} + friend void h1(S s); + void f2() { S<2> s; } + friend void g2(S s) {} + friend void h2(S s); + void f3() { S<3> s; } + }; + void test(S<1> s1, S<2> s2, S<3> s3) { + g1(s1); g1(s2); g1(s3); + g2(s1); g2(s2); g2(s3); + h1(s1); h1(s2); h1(s3); + h2(s1); h2(s2); h2(s3); + } +} diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index 8aeca653da55..98e5ae3e6ee7 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/test/CodeGenCXX/temporaries.cpp @@ -395,7 +395,7 @@ namespace Elision { // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[I]]) } - // CHECK: define void @_ZN7Elision5test2Ev([[A]]* sret + // CHECK: define void @_ZN7Elision5test2Ev([[A]]* noalias sret A test2() { // CHECK: call void @_ZN7Elision3fooEv() // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) @@ -403,7 +403,7 @@ namespace Elision { return (foo(), A()); } - // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* sret + // CHECK: define void @_ZN7Elision5test3EiNS_1AE([[A]]* noalias sret A test3(int v, A x) { if (v < 5) // CHECK: call void @_ZN7Elision1AC1Ev([[A]]* [[RET:%.*]]) @@ -444,7 +444,7 @@ namespace Elision { } // rdar://problem/8433352 - // CHECK: define void @_ZN7Elision5test5Ev([[A]]* sret + // CHECK: define void @_ZN7Elision5test5Ev([[A]]* noalias sret struct B { A a; B(); }; A test5() { // CHECK: [[AT0:%.*]] = alloca [[A]], align 8 diff --git a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp index aa79a4f6dd3d..769d120be323 100644 --- a/test/CodeGenCXX/threadsafe-statics-exceptions.cpp +++ b/test/CodeGenCXX/threadsafe-statics-exceptions.cpp @@ -21,9 +21,8 @@ void f() { throw Y(); // Finally, the landing pad. - // CHECK: call i8* @llvm.eh.exception() - // CHECK: call i32 (i8*, i8*, ...)* @llvm.eh.selector + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK: cleanup // CHECK: call void @__cxa_guard_abort(i64* @_ZGVZ1fvE1x) - // CHECK: call void @llvm.eh.resume( - // CHECK: unreachable + // CHECK: resume { i8*, i32 } } diff --git a/test/CodeGenCXX/thunk-linkonce-odr.cpp b/test/CodeGenCXX/thunk-linkonce-odr.cpp new file mode 100644 index 000000000000..4f4d61d5a9a8 --- /dev/null +++ b/test/CodeGenCXX/thunk-linkonce-odr.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s +// <rdar://problem/7929157> & <rdar://problem/8104369> + +struct A { + virtual int f() { return 1; } +}; + +struct B { + virtual int f() { return 2; } +}; + +struct C : A, B { + virtual int f() { return 3; } +}; + +struct D : C { + virtual int f() { return 4; } +}; + +static int f(D* d) { + B* b = d; + return b->f(); +}; + +int g() { + D d; + return f(&d); +} + +// Thunks should be marked as "linkonce ODR" not "weak". +// +// CHECK: define linkonce_odr i32 @_ZThn{{[48]}}_N1D1fEv +// CHECK: define linkonce_odr i32 @_ZThn{{[48]}}_N1C1fEv diff --git a/test/CodeGenCXX/typeid.cpp b/test/CodeGenCXX/typeid.cpp index 1af96705ba41..7ebf41c09f6c 100644 --- a/test/CodeGenCXX/typeid.cpp +++ b/test/CodeGenCXX/typeid.cpp @@ -13,7 +13,8 @@ const char *f() { // CHECK: invoke void @__cxa_bad_typeid() noreturn return typeid(*static_cast<A *>(0)).name(); } catch (...) { - // CHECK: call i8* @llvm.eh.exception + // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) + // CHECK-NEXT: catch i8* null } return 0; diff --git a/test/CodeGenCXX/union-dtor.cpp b/test/CodeGenCXX/union-dtor.cpp new file mode 100644 index 000000000000..a0b822aa54dd --- /dev/null +++ b/test/CodeGenCXX/union-dtor.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -std=c++11 %s -S -o - -emit-llvm | FileCheck %s + +// PR10304: destructors should not call destructors for variant members. + +template<bool b = false> +struct Foo { + Foo() { static_assert(b, "Foo::Foo used"); } + ~Foo() { static_assert(b, "Foo::~Foo used"); } +}; + +struct Bar { + Bar(); + ~Bar(); +}; + +union FooBar { + FooBar() {} + ~FooBar() {} + Foo<> foo; + Bar bar; +}; + +struct Variant { + Variant() {} + ~Variant() {} + union { + Foo<> foo; + Bar bar; + }; +}; + +FooBar foobar; +Variant variant; + +// The ctor and dtor of Foo<> and Bar should not be mentioned in the resulting +// code. +// +// CHECK-NOT: 3FooILb1EEC1 +// CHECK-NOT: 3BarC1 +// +// CHECK-NOT: 3FooILb1EED1 +// CHECK-NOT: 3BarD1 diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp index 04a18b3fa801..fb981d1ff717 100644 --- a/test/CodeGenCXX/value-init.cpp +++ b/test/CodeGenCXX/value-init.cpp @@ -238,6 +238,25 @@ namespace test6 { // CHECK: ret void } +namespace PR11124 { + // Make sure C::C doesn't overwrite parts of A while it is zero-initializing B + struct A { int a; A(); A(int); }; + struct B : virtual A { int b; }; + struct C : B { C(); }; + C::C() : A(3), B() {} + // CHECK: define void @_ZN7PR111241CC1Ev + // CHECK: call void @llvm.memset.p0i8.i64(i8* {{.*}}, i8 0, i64 12, i32 8, i1 false) + // CHECK-NEXT: call void @_ZN7PR111241BC2Ev + // Make sure C::C doesn't overwrite parts of A while it is zero-initializing B + + struct B2 : virtual A { int B::*b; }; + struct C2 : B2 { C2(); }; + C2::C2() : A(3), B2() {} + // CHECK: define void @_ZN7PR111242C2C1Ev + // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* {{.*}}, i64 16, i32 8, i1 false) + // CHECK-NEXT: call void @_ZN7PR111242B2C2Ev +} + // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr // CHECK: call void @llvm.memset.p0i8.i64 // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev diff --git a/test/CodeGenCXX/vararg-conversion-ctor.cpp b/test/CodeGenCXX/vararg-conversion-ctor.cpp index 7e42859ac93e..a49b1dba9961 100644 --- a/test/CodeGenCXX/vararg-conversion-ctor.cpp +++ b/test/CodeGenCXX/vararg-conversion-ctor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++0x -emit-llvm %s -o %t-64.ll +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm %s -o %t-64.ll // RUN: FileCheck -check-prefix LPLL64 --input-file=%t-64.ll %s extern "C" int printf(...); diff --git a/test/CodeGenCXX/varargs.cpp b/test/CodeGenCXX/varargs.cpp new file mode 100644 index 000000000000..af34336a0ae2 --- /dev/null +++ b/test/CodeGenCXX/varargs.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s + +// rdar://7309675 +// PR4678 +namespace test0 { + // test1 should be compmiled to be a varargs function in the IR even + // though there is no way to do a va_begin. Otherwise, the optimizer + // will warn about 'dropped arguments' at the call site. + + // CHECK: define i32 @_ZN5test05test1Ez(...) + int test1(...) { + return -1; + } + + // CHECK: call i32 (...)* @_ZN5test05test1Ez(i32 0) + void test() { + test1(0); + } +} + +namespace test1 { + struct A { + int x; + int y; + }; + + void foo(...); + + void test() { + A x; + foo(x); + } + // CHECK: define void @_ZN5test14testEv() + // CHECK: [[X:%.*]] = alloca [[A:%.*]], align 4 + // CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 4 + // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[TMP]] to i8* + // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[X]] to i8* + // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T0]], i8* [[T1]], i64 8, i32 4, i1 false) + // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[TMP]] to i64* + // CHECK-NEXT: [[T1:%.*]] = load i64* [[T0]], align 1 + // CHECK-NEXT: call void (...)* @_ZN5test13fooEz(i64 [[T1]]) + // CHECK-NEXT: ret void +} diff --git a/test/CodeGenCXX/variadic-templates.cpp b/test/CodeGenCXX/variadic-templates.cpp index 90c837067559..c56bec33a0f8 100644 --- a/test/CodeGenCXX/variadic-templates.cpp +++ b/test/CodeGenCXX/variadic-templates.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s template<typename ...Types> int get_num_types(Types...) { diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp index fdccd4604545..0f36a6a75324 100644 --- a/test/CodeGenCXX/visibility.cpp +++ b/test/CodeGenCXX/visibility.cpp @@ -26,8 +26,8 @@ // CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 // CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global // CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 -// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant // CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant +// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant // CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant namespace Test1 { diff --git a/test/CodeGenCXX/volatile-1.cpp b/test/CodeGenCXX/volatile-1.cpp index 1a69648d42a7..71ff1ed7d689 100644 --- a/test/CodeGenCXX/volatile-1.cpp +++ b/test/CodeGenCXX/volatile-1.cpp @@ -26,8 +26,8 @@ void test() { i; (float)(ci); - // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) // CHECK-NEXT: sitofp [[INT]] // These are not uses in C++: @@ -37,202 +37,202 @@ void test() { (void)a; (void)(ci=ci); - // CHECK-NEXT: [[R:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) (void)(i=j); - // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* @j - // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* @i + // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* @j + // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i ci+=ci; - // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) // Not sure why they're ordered this way. // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] - // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // Note that C++ requires an extra volatile load over C from the LHS of the '+'. + // Note that C++ requires an extra load volatile over C from the LHS of the '+'. (ci += ci) + ci; - // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] - // CHECK-NEXT: volatile store [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: volatile store [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[R1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I1:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[R2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I2:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) // These additions can be elided. // CHECK-NEXT: add [[INT]] [[R1]], [[R2]] // CHECK-NEXT: add [[INT]] [[I1]], [[I2]] asm("nop"); // CHECK-NEXT: call void asm - // Extra volatile load in C++. + // Extra load volatile in C++. (i += j) + k; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: add nsw [[INT]] - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: add nsw [[INT]] asm("nop"); // CHECK-NEXT: call void asm - // Extra volatile load in C++. + // Extra load volatile in C++. (i += j) + 1; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: add nsw [[INT]] - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: add nsw [[INT]] asm("nop"); // CHECK-NEXT: call void asm ci+ci; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: add [[INT]] // CHECK-NEXT: add [[INT]] __real i; +ci; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile asm("nop"); // CHECK-NEXT: call void asm (void)(i=i); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile (float)(i=i); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: sitofp (void)i; i=i; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile - // Extra volatile load in C++. + // Extra load volatile in C++. i=i=i; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile (void)__builtin_choose_expr(0, i=i, j=j); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile k ? (i=i) : (j=j); - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile // CHECK-NEXT: icmp // CHECK-NEXT: br i1 - // CHECK: volatile load - // CHECK-NEXT: volatile store + // CHECK: load volatile + // CHECK-NEXT: store volatile // CHECK-NEXT: br label - // CHECK: volatile load - // CHECK-NEXT: volatile store + // CHECK: load volatile + // CHECK-NEXT: store volatile // CHECK-NEXT: br label // CHECK: phi (void)(i,(i=i)); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile i=i,k; - // CHECK-NEXT: volatile load [[INT]]* @i - // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i + // CHECK-NEXT: load volatile [[INT]]* @i + // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i (i=j,k=j); - // CHECK-NEXT: volatile load [[INT]]* @j - // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i - // CHECK-NEXT: volatile load [[INT]]* @j - // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @k + // CHECK-NEXT: load volatile [[INT]]* @j + // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i + // CHECK-NEXT: load volatile [[INT]]* @j + // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @k (i=j,k); - // CHECK-NEXT: volatile load [[INT]]* @j - // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i + // CHECK-NEXT: load volatile [[INT]]* @j + // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i (i,j); // Extra load in C++. i=c=k; - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile // CHECK-NEXT: trunc - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: sext - // CHECK-NEXT: volatile store + // CHECK-NEXT: store volatile i+=k; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: add nsw [[INT]] - // CHECK-NEXT: volatile store + // CHECK-NEXT: store volatile ci; asm("nop"); // CHECK-NEXT: call void asm (int)ci; - // CHECK-NEXT: volatile load {{.*}} @ci, i32 0, i32 0 - // CHECK-NEXT: volatile load {{.*}} @ci, i32 0, i32 1 + // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0 + // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1 (bool)ci; - // CHECK-NEXT: volatile load {{.*}} @ci, i32 0, i32 0 - // CHECK-NEXT: volatile load {{.*}} @ci, i32 0, i32 1 + // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 0 + // CHECK-NEXT: load volatile {{.*}} @ci, i32 0, i32 1 // CHECK-NEXT: icmp ne // CHECK-NEXT: icmp ne // CHECK-NEXT: or i1 ci=ci; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile asm("nop"); // CHECK-NEXT: call void asm // Extra load in C++. ci=ci=ci; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile __imag ci = __imag ci = __imag ci; - // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[T:%.*]] = volatile load [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: volatile store [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) __real (i = j); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile __imag i; @@ -258,95 +258,95 @@ void test() { // Not a use. gcc got this wrong in 4.2 and omitted the side effects // entirely, but it is fixed in 4.4.0. __imag (i = j); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile // C++ does an extra load here. Note that we have to do full loads. (float)(ci=ci); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: sitofp // Not a use, bug? gcc treats this as not a use, that's probably a // bug due to tree folding ignoring volatile. (int)(ci=ci); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile // A use. (float)(i=i); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: sitofp // A use. gcc treats this as not a use, that's probably a bug due to tree // folding ignoring volatile. (int)(i=i); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile // A use. -(i=j); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: sub // A use. gcc treats this a not a use, that's probably a bug due to tree // folding ignoring volatile. +(i=k); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile // A use. gcc treats this a not a use, that's probably a bug due to tree // folding ignoring volatile. __real (ci=ci); - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile store + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: store volatile // A use. i + 0; - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile // CHECK-NEXT: add // A use. (i=j) + i; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: add // A use. gcc treats this as not a use, that's probably a bug due to tree // folding ignoring volatile. (i=j) + 0; - // CHECK-NEXT: volatile load - // CHECK-NEXT: volatile store - // CHECK-NEXT: volatile load + // CHECK-NEXT: load volatile + // CHECK-NEXT: store volatile + // CHECK-NEXT: load volatile // CHECK-NEXT: add (i,j)=k; - // CHECK-NEXT: volatile load [[INT]]* @k - // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @j + // CHECK-NEXT: load volatile [[INT]]* @k + // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j (j=k,i)=i; - // CHECK-NEXT: volatile load [[INT]]* @i - // CHECK-NEXT: volatile load [[INT]]* @k - // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @j - // CHECK-NEXT: volatile store {{.*}}, [[INT]]* @i + // CHECK-NEXT: load volatile [[INT]]* @i + // CHECK-NEXT: load volatile [[INT]]* @k + // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j + // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i // CHECK-NEXT: ret void } diff --git a/test/CodeGenCXX/vtable-layout-abi-examples.cpp b/test/CodeGenCXX/vtable-layout-abi-examples.cpp index c01c5ef72cc5..8f084a9c5b7b 100644 --- a/test/CodeGenCXX/vtable-layout-abi-examples.cpp +++ b/test/CodeGenCXX/vtable-layout-abi-examples.cpp @@ -1,4 +1,15 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts 2>&1 | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm-only -fdump-vtable-layouts > %t 2>&1 +// RUN: FileCheck --check-prefix=CHECK-1 %s < %t +// RUN: FileCheck --check-prefix=CHECK-2 %s < %t +// RUN: FileCheck --check-prefix=CHECK-3 %s < %t +// RUN: FileCheck --check-prefix=CHECK-4 %s < %t +// RUN: FileCheck --check-prefix=CHECK-5 %s < %t +// RUN: FileCheck --check-prefix=CHECK-6 %s < %t +// RUN: FileCheck --check-prefix=CHECK-7 %s < %t +// RUN: FileCheck --check-prefix=CHECK-8 %s < %t +// RUN: FileCheck --check-prefix=CHECK-9 %s < %t +// RUN: FileCheck --check-prefix=CHECK-10 %s < %t +// RUN: FileCheck --check-prefix=CHECK-11 %s < %t /// Examples from the Itanium C++ ABI specification. /// http://www.codesourcery.com/public/cxx-abi/ @@ -7,13 +18,13 @@ namespace Test1 { // This is from http://www.codesourcery.com/public/cxx-abi/cxx-vtable-ex.html -// CHECK: Vtable for 'Test1::A' (5 entries). -// CHECK-NEXT: 0 | offset_to_top (0) -// CHECK-NEXT: 1 | Test1::A RTTI -// CHECK-NEXT: -- (Test1::A, 0) vtable address -- -// CHECK-NEXT: 2 | void Test1::A::f() -// CHECK-NEXT: 3 | void Test1::A::g() -// CHECK-NEXT: 4 | void Test1::A::h() +// CHECK-1: Vtable for 'Test1::A' (5 entries). +// CHECK-1-NEXT: 0 | offset_to_top (0) +// CHECK-1-NEXT: 1 | Test1::A RTTI +// CHECK-1-NEXT: -- (Test1::A, 0) vtable address -- +// CHECK-1-NEXT: 2 | void Test1::A::f() +// CHECK-1-NEXT: 3 | void Test1::A::g() +// CHECK-1-NEXT: 4 | void Test1::A::h() struct A { virtual void f (); virtual void g (); @@ -22,24 +33,24 @@ struct A { }; void A::f() {} -// CHECK: Vtable for 'Test1::B' (13 entries). -// CHECK-NEXT: 0 | vbase_offset (16) -// CHECK-NEXT: 1 | offset_to_top (0) -// CHECK-NEXT: 2 | Test1::B RTTI -// CHECK-NEXT: -- (Test1::B, 0) vtable address -- -// CHECK-NEXT: 3 | void Test1::B::f() -// CHECK-NEXT: 4 | void Test1::B::h() -// CHECK-NEXT: 5 | vcall_offset (-16) -// CHECK-NEXT: 6 | vcall_offset (0) -// CHECK-NEXT: 7 | vcall_offset (-16) -// CHECK-NEXT: 8 | offset_to_top (-16) -// CHECK-NEXT: 9 | Test1::B RTTI -// CHECK-NEXT: -- (Test1::A, 16) vtable address -- -// CHECK-NEXT: 10 | void Test1::B::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] -// CHECK-NEXT: 11 | void Test1::A::g() -// CHECK-NEXT: 12 | void Test1::B::h() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] +// CHECK-2: Vtable for 'Test1::B' (13 entries). +// CHECK-2-NEXT: 0 | vbase_offset (16) +// CHECK-2-NEXT: 1 | offset_to_top (0) +// CHECK-2-NEXT: 2 | Test1::B RTTI +// CHECK-2-NEXT: -- (Test1::B, 0) vtable address -- +// CHECK-2-NEXT: 3 | void Test1::B::f() +// CHECK-2-NEXT: 4 | void Test1::B::h() +// CHECK-2-NEXT: 5 | vcall_offset (-16) +// CHECK-2-NEXT: 6 | vcall_offset (0) +// CHECK-2-NEXT: 7 | vcall_offset (-16) +// CHECK-2-NEXT: 8 | offset_to_top (-16) +// CHECK-2-NEXT: 9 | Test1::B RTTI +// CHECK-2-NEXT: -- (Test1::A, 16) vtable address -- +// CHECK-2-NEXT: 10 | void Test1::B::f() +// CHECK-2-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-2-NEXT: 11 | void Test1::A::g() +// CHECK-2-NEXT: 12 | void Test1::B::h() +// CHECK-2-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] struct B: public virtual A { void f (); void h (); @@ -47,24 +58,24 @@ struct B: public virtual A { }; void B::f() {} -// CHECK: Vtable for 'Test1::C' (13 entries). -// CHECK-NEXT: 0 | vbase_offset (16) -// CHECK-NEXT: 1 | offset_to_top (0) -// CHECK-NEXT: 2 | Test1::C RTTI -// CHECK-NEXT: -- (Test1::C, 0) vtable address -- -// CHECK-NEXT: 3 | void Test1::C::g() -// CHECK-NEXT: 4 | void Test1::C::h() -// CHECK-NEXT: 5 | vcall_offset (-16) -// CHECK-NEXT: 6 | vcall_offset (-16) -// CHECK-NEXT: 7 | vcall_offset (0) -// CHECK-NEXT: 8 | offset_to_top (-16) -// CHECK-NEXT: 9 | Test1::C RTTI -// CHECK-NEXT: -- (Test1::A, 16) vtable address -- -// CHECK-NEXT: 10 | void Test1::A::f() -// CHECK-NEXT: 11 | void Test1::C::g() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] -// CHECK-NEXT: 12 | void Test1::C::h() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] +// CHECK-3: Vtable for 'Test1::C' (13 entries). +// CHECK-3-NEXT: 0 | vbase_offset (16) +// CHECK-3-NEXT: 1 | offset_to_top (0) +// CHECK-3-NEXT: 2 | Test1::C RTTI +// CHECK-3-NEXT: -- (Test1::C, 0) vtable address -- +// CHECK-3-NEXT: 3 | void Test1::C::g() +// CHECK-3-NEXT: 4 | void Test1::C::h() +// CHECK-3-NEXT: 5 | vcall_offset (-16) +// CHECK-3-NEXT: 6 | vcall_offset (-16) +// CHECK-3-NEXT: 7 | vcall_offset (0) +// CHECK-3-NEXT: 8 | offset_to_top (-16) +// CHECK-3-NEXT: 9 | Test1::C RTTI +// CHECK-3-NEXT: -- (Test1::A, 16) vtable address -- +// CHECK-3-NEXT: 10 | void Test1::A::f() +// CHECK-3-NEXT: 11 | void Test1::C::g() +// CHECK-3-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] +// CHECK-3-NEXT: 12 | void Test1::C::h() +// CHECK-3-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] struct C: public virtual A { void g (); void h (); @@ -72,33 +83,33 @@ struct C: public virtual A { }; void C::g() {} -// CHECK: Vtable for 'Test1::D' (18 entries). -// CHECK-NEXT: 0 | vbase_offset (32) -// CHECK-NEXT: 1 | offset_to_top (0) -// CHECK-NEXT: 2 | Test1::D RTTI -// CHECK-NEXT: -- (Test1::B, 0) vtable address -- -// CHECK-NEXT: -- (Test1::D, 0) vtable address -- -// CHECK-NEXT: 3 | void Test1::B::f() -// CHECK-NEXT: 4 | void Test1::D::h() -// CHECK-NEXT: 5 | vbase_offset (16) -// CHECK-NEXT: 6 | offset_to_top (-16) -// CHECK-NEXT: 7 | Test1::D RTTI -// CHECK-NEXT: -- (Test1::C, 16) vtable address -- -// CHECK-NEXT: 8 | void Test1::C::g() -// CHECK-NEXT: 9 | void Test1::D::h() -// CHECK-NEXT: [this adjustment: -16 non-virtual] -// CHECK-NEXT: 10 | vcall_offset (-32) -// CHECK-NEXT: 11 | vcall_offset (-16) -// CHECK-NEXT: 12 | vcall_offset (-32) -// CHECK-NEXT: 13 | offset_to_top (-32) -// CHECK-NEXT: 14 | Test1::D RTTI -// CHECK-NEXT: -- (Test1::A, 32) vtable address -- -// CHECK-NEXT: 15 | void Test1::B::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] -// CHECK-NEXT: 16 | void Test1::C::g() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] -// CHECK-NEXT: 17 | void Test1::D::h() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] +// CHECK-4: Vtable for 'Test1::D' (18 entries). +// CHECK-4-NEXT: 0 | vbase_offset (32) +// CHECK-4-NEXT: 1 | offset_to_top (0) +// CHECK-4-NEXT: 2 | Test1::D RTTI +// CHECK-4-NEXT: -- (Test1::B, 0) vtable address -- +// CHECK-4-NEXT: -- (Test1::D, 0) vtable address -- +// CHECK-4-NEXT: 3 | void Test1::B::f() +// CHECK-4-NEXT: 4 | void Test1::D::h() +// CHECK-4-NEXT: 5 | vbase_offset (16) +// CHECK-4-NEXT: 6 | offset_to_top (-16) +// CHECK-4-NEXT: 7 | Test1::D RTTI +// CHECK-4-NEXT: -- (Test1::C, 16) vtable address -- +// CHECK-4-NEXT: 8 | void Test1::C::g() +// CHECK-4-NEXT: 9 | void Test1::D::h() +// CHECK-4-NEXT: [this adjustment: -16 non-virtual] +// CHECK-4-NEXT: 10 | vcall_offset (-32) +// CHECK-4-NEXT: 11 | vcall_offset (-16) +// CHECK-4-NEXT: 12 | vcall_offset (-32) +// CHECK-4-NEXT: 13 | offset_to_top (-32) +// CHECK-4-NEXT: 14 | Test1::D RTTI +// CHECK-4-NEXT: -- (Test1::A, 32) vtable address -- +// CHECK-4-NEXT: 15 | void Test1::B::f() +// CHECK-4-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-4-NEXT: 16 | void Test1::C::g() +// CHECK-4-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] +// CHECK-4-NEXT: 17 | void Test1::D::h() +// CHECK-4-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] struct D: public B, public C { void h (); int id; @@ -110,43 +121,43 @@ struct X { virtual void x(); }; -// CHECK: Vtable for 'Test1::E' (24 entries). -// CHECK-NEXT: 0 | vbase_offset (56) -// CHECK-NEXT: 1 | offset_to_top (0) -// CHECK-NEXT: 2 | Test1::E RTTI -// CHECK-NEXT: -- (Test1::E, 0) vtable address -- -// CHECK-NEXT: -- (Test1::X, 0) vtable address -- -// CHECK-NEXT: 3 | void Test1::X::x() -// CHECK-NEXT: 4 | void Test1::E::f() -// CHECK-NEXT: 5 | void Test1::E::h() -// CHECK-NEXT: 6 | vbase_offset (40) -// CHECK-NEXT: 7 | offset_to_top (-16) -// CHECK-NEXT: 8 | Test1::E RTTI -// CHECK-NEXT: -- (Test1::B, 16) vtable address -- -// CHECK-NEXT: -- (Test1::D, 16) vtable address -- -// CHECK-NEXT: 9 | void Test1::E::f() -// CHECK-NEXT: [this adjustment: -16 non-virtual] -// CHECK-NEXT: 10 | void Test1::E::h() -// CHECK-NEXT: [this adjustment: -16 non-virtual] -// CHECK-NEXT: 11 | vbase_offset (24) -// CHECK-NEXT: 12 | offset_to_top (-32) -// CHECK-NEXT: 13 | Test1::E RTTI -// CHECK-NEXT: -- (Test1::C, 32) vtable address -- -// CHECK-NEXT: 14 | void Test1::C::g() -// CHECK-NEXT: 15 | void Test1::E::h() -// CHECK-NEXT: [this adjustment: -32 non-virtual] -// CHECK-NEXT: 16 | vcall_offset (-56) -// CHECK-NEXT: 17 | vcall_offset (-24) -// CHECK-NEXT: 18 | vcall_offset (-56) -// CHECK-NEXT: 19 | offset_to_top (-56) -// CHECK-NEXT: 20 | Test1::E RTTI -// CHECK-NEXT: -- (Test1::A, 56) vtable address -- -// CHECK-NEXT: 21 | void Test1::E::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] -// CHECK-NEXT: 22 | void Test1::C::g() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] -// CHECK-NEXT: 23 | void Test1::E::h() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] +// CHECK-5: Vtable for 'Test1::E' (24 entries). +// CHECK-5-NEXT: 0 | vbase_offset (56) +// CHECK-5-NEXT: 1 | offset_to_top (0) +// CHECK-5-NEXT: 2 | Test1::E RTTI +// CHECK-5-NEXT: -- (Test1::E, 0) vtable address -- +// CHECK-5-NEXT: -- (Test1::X, 0) vtable address -- +// CHECK-5-NEXT: 3 | void Test1::X::x() +// CHECK-5-NEXT: 4 | void Test1::E::f() +// CHECK-5-NEXT: 5 | void Test1::E::h() +// CHECK-5-NEXT: 6 | vbase_offset (40) +// CHECK-5-NEXT: 7 | offset_to_top (-16) +// CHECK-5-NEXT: 8 | Test1::E RTTI +// CHECK-5-NEXT: -- (Test1::B, 16) vtable address -- +// CHECK-5-NEXT: -- (Test1::D, 16) vtable address -- +// CHECK-5-NEXT: 9 | void Test1::E::f() +// CHECK-5-NEXT: [this adjustment: -16 non-virtual] +// CHECK-5-NEXT: 10 | void Test1::E::h() +// CHECK-5-NEXT: [this adjustment: -16 non-virtual] +// CHECK-5-NEXT: 11 | vbase_offset (24) +// CHECK-5-NEXT: 12 | offset_to_top (-32) +// CHECK-5-NEXT: 13 | Test1::E RTTI +// CHECK-5-NEXT: -- (Test1::C, 32) vtable address -- +// CHECK-5-NEXT: 14 | void Test1::C::g() +// CHECK-5-NEXT: 15 | void Test1::E::h() +// CHECK-5-NEXT: [this adjustment: -32 non-virtual] +// CHECK-5-NEXT: 16 | vcall_offset (-56) +// CHECK-5-NEXT: 17 | vcall_offset (-24) +// CHECK-5-NEXT: 18 | vcall_offset (-56) +// CHECK-5-NEXT: 19 | offset_to_top (-56) +// CHECK-5-NEXT: 20 | Test1::E RTTI +// CHECK-5-NEXT: -- (Test1::A, 56) vtable address -- +// CHECK-5-NEXT: 21 | void Test1::E::f() +// CHECK-5-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-5-NEXT: 22 | void Test1::C::g() +// CHECK-5-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] +// CHECK-5-NEXT: 23 | void Test1::E::h() +// CHECK-5-NEXT: [this adjustment: 0 non-virtual, -40 vcall offset offset] struct E : X, D { int ie; void f(); @@ -164,22 +175,22 @@ struct A { virtual void f(); }; struct B : virtual public A { int i; }; struct C : virtual public A { int j; }; -// CHECK: Vtable for 'Test2::D' (11 entries). -// CHECK-NEXT: 0 | vbase_offset (0) -// CHECK-NEXT: 1 | vcall_offset (0) -// CHECK-NEXT: 2 | offset_to_top (0) -// CHECK-NEXT: 3 | Test2::D RTTI -// CHECK-NEXT: -- (Test2::A, 0) vtable address -- -// CHECK-NEXT: -- (Test2::B, 0) vtable address -- -// CHECK-NEXT: -- (Test2::D, 0) vtable address -- -// CHECK-NEXT: 4 | void Test2::A::f() -// CHECK-NEXT: 5 | void Test2::D::d() -// CHECK-NEXT: 6 | vbase_offset (-16) -// CHECK-NEXT: 7 | vcall_offset (-16) -// CHECK-NEXT: 8 | offset_to_top (-16) -// CHECK-NEXT: 9 | Test2::D RTTI -// CHECK-NEXT: -- (Test2::C, 16) vtable address -- -// CHECK-NEXT: 10 | [unused] void Test2::A::f() +// CHECK-6: Vtable for 'Test2::D' (11 entries). +// CHECK-6-NEXT: 0 | vbase_offset (0) +// CHECK-6-NEXT: 1 | vcall_offset (0) +// CHECK-6-NEXT: 2 | offset_to_top (0) +// CHECK-6-NEXT: 3 | Test2::D RTTI +// CHECK-6-NEXT: -- (Test2::A, 0) vtable address -- +// CHECK-6-NEXT: -- (Test2::B, 0) vtable address -- +// CHECK-6-NEXT: -- (Test2::D, 0) vtable address -- +// CHECK-6-NEXT: 4 | void Test2::A::f() +// CHECK-6-NEXT: 5 | void Test2::D::d() +// CHECK-6-NEXT: 6 | vbase_offset (-16) +// CHECK-6-NEXT: 7 | vcall_offset (-16) +// CHECK-6-NEXT: 8 | offset_to_top (-16) +// CHECK-6-NEXT: 9 | Test2::D RTTI +// CHECK-6-NEXT: -- (Test2::C, 16) vtable address -- +// CHECK-6-NEXT: 10 | [unused] void Test2::A::f() struct D : public B, public C { virtual void d(); }; @@ -201,40 +212,40 @@ struct V2 : virtual V1 { virtual void f(); }; -// CHECK: Vtable for 'Test3::C' (14 entries). -// CHECK-NEXT: 0 | vbase_offset (32) -// CHECK-NEXT: 1 | vbase_offset (16) -// CHECK-NEXT: 2 | offset_to_top (0) -// CHECK-NEXT: 3 | Test3::C RTTI -// CHECK-NEXT: -- (Test3::C, 0) vtable address -- -// CHECK-NEXT: 4 | void Test3::C::f() -// CHECK-NEXT: 5 | vcall_offset (-16) -// CHECK-NEXT: 6 | offset_to_top (-16) -// CHECK-NEXT: 7 | Test3::C RTTI -// CHECK-NEXT: -- (Test3::V1, 16) vtable address -- -// CHECK-NEXT: 8 | void Test3::C::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] -// CHECK-NEXT: 9 | vcall_offset (-32) -// CHECK-NEXT: 10 | vbase_offset (-16) -// CHECK-NEXT: 11 | offset_to_top (-32) -// CHECK-NEXT: 12 | Test3::C RTTI -// CHECK-NEXT: -- (Test3::V2, 32) vtable address -- -// CHECK-NEXT: 13 | void Test3::C::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] +// CHECK-7: Vtable for 'Test3::C' (14 entries). +// CHECK-7-NEXT: 0 | vbase_offset (32) +// CHECK-7-NEXT: 1 | vbase_offset (16) +// CHECK-7-NEXT: 2 | offset_to_top (0) +// CHECK-7-NEXT: 3 | Test3::C RTTI +// CHECK-7-NEXT: -- (Test3::C, 0) vtable address -- +// CHECK-7-NEXT: 4 | void Test3::C::f() +// CHECK-7-NEXT: 5 | vcall_offset (-16) +// CHECK-7-NEXT: 6 | offset_to_top (-16) +// CHECK-7-NEXT: 7 | Test3::C RTTI +// CHECK-7-NEXT: -- (Test3::V1, 16) vtable address -- +// CHECK-7-NEXT: 8 | void Test3::C::f() +// CHECK-7-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-7-NEXT: 9 | vcall_offset (-32) +// CHECK-7-NEXT: 10 | vbase_offset (-16) +// CHECK-7-NEXT: 11 | offset_to_top (-32) +// CHECK-7-NEXT: 12 | Test3::C RTTI +// CHECK-7-NEXT: -- (Test3::V2, 32) vtable address -- +// CHECK-7-NEXT: 13 | void Test3::C::f() +// CHECK-7-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] -// CHECK: Construction vtable for ('Test3::V2', 32) in 'Test3::C' (9 entries). -// CHECK-NEXT: 0 | vcall_offset (0) -// CHECK-NEXT: 1 | vbase_offset (-16) -// CHECK-NEXT: 2 | offset_to_top (0) -// CHECK-NEXT: 3 | Test3::V2 RTTI -// CHECK-NEXT: -- (Test3::V2, 32) vtable address -- -// CHECK-NEXT: 4 | void Test3::V2::f() -// CHECK-NEXT: 5 | vcall_offset (16) -// CHECK-NEXT: 6 | offset_to_top (16) -// CHECK-NEXT: 7 | Test3::V2 RTTI -// CHECK-NEXT: -- (Test3::V1, 16) vtable address -- -// CHECK-NEXT: 8 | void Test3::V2::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-8: Construction vtable for ('Test3::V2', 32) in 'Test3::C' (9 entries). +// CHECK-8-NEXT: 0 | vcall_offset (0) +// CHECK-8-NEXT: 1 | vbase_offset (-16) +// CHECK-8-NEXT: 2 | offset_to_top (0) +// CHECK-8-NEXT: 3 | Test3::V2 RTTI +// CHECK-8-NEXT: -- (Test3::V2, 32) vtable address -- +// CHECK-8-NEXT: 4 | void Test3::V2::f() +// CHECK-8-NEXT: 5 | vcall_offset (16) +// CHECK-8-NEXT: 6 | offset_to_top (16) +// CHECK-8-NEXT: 7 | Test3::V2 RTTI +// CHECK-8-NEXT: -- (Test3::V1, 16) vtable address -- +// CHECK-8-NEXT: 8 | void Test3::V2::f() +// CHECK-8-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] struct C : virtual V1, virtual V2 { int c; virtual void f(); @@ -245,63 +256,63 @@ struct B { int b; }; -// CHECK: Vtable for 'Test3::D' (15 entries). -// CHECK-NEXT: 0 | vbase_offset (40) -// CHECK-NEXT: 1 | vbase_offset (24) -// CHECK-NEXT: 2 | offset_to_top (0) -// CHECK-NEXT: 3 | Test3::D RTTI -// CHECK-NEXT: -- (Test3::C, 0) vtable address -- -// CHECK-NEXT: -- (Test3::D, 0) vtable address -- -// CHECK-NEXT: 4 | void Test3::C::f() -// CHECK-NEXT: 5 | void Test3::D::g() -// CHECK-NEXT: 6 | vcall_offset (-24) -// CHECK-NEXT: 7 | offset_to_top (-24) -// CHECK-NEXT: 8 | Test3::D RTTI -// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- -// CHECK-NEXT: 9 | void Test3::C::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] -// CHECK-NEXT: 10 | vcall_offset (-40) -// CHECK-NEXT: 11 | vbase_offset (-16) -// CHECK-NEXT: 12 | offset_to_top (-40) -// CHECK-NEXT: 13 | Test3::D RTTI -// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- -// CHECK-NEXT: 14 | void Test3::C::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] +// CHECK-9: Vtable for 'Test3::D' (15 entries). +// CHECK-9-NEXT: 0 | vbase_offset (40) +// CHECK-9-NEXT: 1 | vbase_offset (24) +// CHECK-9-NEXT: 2 | offset_to_top (0) +// CHECK-9-NEXT: 3 | Test3::D RTTI +// CHECK-9-NEXT: -- (Test3::C, 0) vtable address -- +// CHECK-9-NEXT: -- (Test3::D, 0) vtable address -- +// CHECK-9-NEXT: 4 | void Test3::C::f() +// CHECK-9-NEXT: 5 | void Test3::D::g() +// CHECK-9-NEXT: 6 | vcall_offset (-24) +// CHECK-9-NEXT: 7 | offset_to_top (-24) +// CHECK-9-NEXT: 8 | Test3::D RTTI +// CHECK-9-NEXT: -- (Test3::V1, 24) vtable address -- +// CHECK-9-NEXT: 9 | void Test3::C::f() +// CHECK-9-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-9-NEXT: 10 | vcall_offset (-40) +// CHECK-9-NEXT: 11 | vbase_offset (-16) +// CHECK-9-NEXT: 12 | offset_to_top (-40) +// CHECK-9-NEXT: 13 | Test3::D RTTI +// CHECK-9-NEXT: -- (Test3::V2, 40) vtable address -- +// CHECK-9-NEXT: 14 | void Test3::C::f() +// CHECK-9-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] -// CHECK: Construction vtable for ('Test3::C', 0) in 'Test3::D' (14 entries). -// CHECK-NEXT: 0 | vbase_offset (40) -// CHECK-NEXT: 1 | vbase_offset (24) -// CHECK-NEXT: 2 | offset_to_top (0) -// CHECK-NEXT: 3 | Test3::C RTTI -// CHECK-NEXT: -- (Test3::C, 0) vtable address -- -// CHECK-NEXT: 4 | void Test3::C::f() -// CHECK-NEXT: 5 | vcall_offset (-24) -// CHECK-NEXT: 6 | offset_to_top (-24) -// CHECK-NEXT: 7 | Test3::C RTTI -// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- -// CHECK-NEXT: 8 | void Test3::C::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] -// CHECK-NEXT: 9 | vcall_offset (-40) -// CHECK-NEXT: 10 | vbase_offset (-16) -// CHECK-NEXT: 11 | offset_to_top (-40) -// CHECK-NEXT: 12 | Test3::C RTTI -// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- -// CHECK-NEXT: 13 | void Test3::C::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] +// CHECK-10: Construction vtable for ('Test3::C', 0) in 'Test3::D' (14 entries). +// CHECK-10-NEXT: 0 | vbase_offset (40) +// CHECK-10-NEXT: 1 | vbase_offset (24) +// CHECK-10-NEXT: 2 | offset_to_top (0) +// CHECK-10-NEXT: 3 | Test3::C RTTI +// CHECK-10-NEXT: -- (Test3::C, 0) vtable address -- +// CHECK-10-NEXT: 4 | void Test3::C::f() +// CHECK-10-NEXT: 5 | vcall_offset (-24) +// CHECK-10-NEXT: 6 | offset_to_top (-24) +// CHECK-10-NEXT: 7 | Test3::C RTTI +// CHECK-10-NEXT: -- (Test3::V1, 24) vtable address -- +// CHECK-10-NEXT: 8 | void Test3::C::f() +// CHECK-10-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-10-NEXT: 9 | vcall_offset (-40) +// CHECK-10-NEXT: 10 | vbase_offset (-16) +// CHECK-10-NEXT: 11 | offset_to_top (-40) +// CHECK-10-NEXT: 12 | Test3::C RTTI +// CHECK-10-NEXT: -- (Test3::V2, 40) vtable address -- +// CHECK-10-NEXT: 13 | void Test3::C::f() +// CHECK-10-NEXT: [this adjustment: 0 non-virtual, -32 vcall offset offset] -// CHECK: Construction vtable for ('Test3::V2', 40) in 'Test3::D' (9 entries). -// CHECK-NEXT: 0 | vcall_offset (0) -// CHECK-NEXT: 1 | vbase_offset (-16) -// CHECK-NEXT: 2 | offset_to_top (0) -// CHECK-NEXT: 3 | Test3::V2 RTTI -// CHECK-NEXT: -- (Test3::V2, 40) vtable address -- -// CHECK-NEXT: 4 | void Test3::V2::f() -// CHECK-NEXT: 5 | vcall_offset (16) -// CHECK-NEXT: 6 | offset_to_top (16) -// CHECK-NEXT: 7 | Test3::V2 RTTI -// CHECK-NEXT: -- (Test3::V1, 24) vtable address -- -// CHECK-NEXT: 8 | void Test3::V2::f() -// CHECK-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] +// CHECK-11: Construction vtable for ('Test3::V2', 40) in 'Test3::D' (9 entries). +// CHECK-11-NEXT: 0 | vcall_offset (0) +// CHECK-11-NEXT: 1 | vbase_offset (-16) +// CHECK-11-NEXT: 2 | offset_to_top (0) +// CHECK-11-NEXT: 3 | Test3::V2 RTTI +// CHECK-11-NEXT: -- (Test3::V2, 40) vtable address -- +// CHECK-11-NEXT: 4 | void Test3::V2::f() +// CHECK-11-NEXT: 5 | vcall_offset (16) +// CHECK-11-NEXT: 6 | offset_to_top (16) +// CHECK-11-NEXT: 7 | Test3::V2 RTTI +// CHECK-11-NEXT: -- (Test3::V1, 24) vtable address -- +// CHECK-11-NEXT: 8 | void Test3::V2::f() +// CHECK-11-NEXT: [this adjustment: 0 non-virtual, -24 vcall offset offset] struct D : B, C { int d; virtual void g(); diff --git a/test/CodeGenCXX/weak-external.cpp b/test/CodeGenCXX/weak-external.cpp new file mode 100644 index 000000000000..dad54f6861b0 --- /dev/null +++ b/test/CodeGenCXX/weak-external.cpp @@ -0,0 +1,66 @@ +// RUN: %clang -fexceptions %s -S -emit-llvm -o - | FileCheck %s +// PR4262 + +// CHECK-NOT: _ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag + +// The "basic_string" extern template instantiation declaration is supposed to +// suppress the implicit instantiation of non-inline member functions. Make sure +// that we suppress the implicit instantiation of non-inline member functions +// defined out-of-line. That we aren't instantiating the basic_string +// constructor when we shouldn't be. Such an instantiation forces the implicit +// instantiation of _S_construct<const char*>. Since _S_construct is a member +// template, it's instantiation is *not* suppressed (despite being in +// basic_string<char>), so we would emit it as a weak definition. + +#define _LIBCPP_EXCEPTION_ABI __attribute__ ((__visibility__("default"))) +#define _LIBCPP_INLINE_VISIBILITY __attribute__ ((__visibility__("hidden"), __always_inline__)) +#define _LIBCPP_VISIBLE __attribute__ ((__visibility__("default"))) +#if (__has_feature(cxx_noexcept)) +# define _NOEXCEPT noexcept +# define _NOEXCEPT_(x) noexcept(x) +#else +# define _NOEXCEPT throw() +# define _NOEXCEPT_(x) +#endif + +namespace std // purposefully not using versioning namespace +{ + +template<class charT> struct char_traits; +template<class T> class allocator; +template <class _CharT, + class _Traits = char_traits<_CharT>, + class _Allocator = allocator<_CharT> > + class _LIBCPP_VISIBLE basic_string; +typedef basic_string<char, char_traits<char>, allocator<char> > string; + +class _LIBCPP_EXCEPTION_ABI exception +{ +public: + _LIBCPP_INLINE_VISIBILITY exception() _NOEXCEPT {} + virtual ~exception() _NOEXCEPT; + virtual const char* what() const _NOEXCEPT; +}; + +class _LIBCPP_EXCEPTION_ABI runtime_error + : public exception +{ +private: + void* __imp_; +public: + explicit runtime_error(const string&); + explicit runtime_error(const char*); + + runtime_error(const runtime_error&) _NOEXCEPT; + runtime_error& operator=(const runtime_error&) _NOEXCEPT; + + virtual ~runtime_error() _NOEXCEPT; + + virtual const char* what() const _NOEXCEPT; +}; + +} + +void dummysymbol() { + throw(std::runtime_error("string")); +} diff --git a/test/CodeGenCXX/x86-64-abi-sret-vs-2word-struct-param.cpp b/test/CodeGenCXX/x86-64-abi-sret-vs-2word-struct-param.cpp new file mode 100644 index 000000000000..1aa80f2d6e6f --- /dev/null +++ b/test/CodeGenCXX/x86-64-abi-sret-vs-2word-struct-param.cpp @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck %s +// XTARGET: x86 +// PR4242 +// (PR 4242 bug is on 64-bit only, test passes on x86-32 as well) + +struct S { + void* data[3]; +}; + +struct T { + void* data[2]; +}; + +// CHECK: %struct.T* byval +extern "C" S fail(int, int, int, int, T t, void* p) { + S s; + s.data[0] = t.data[0]; + s.data[1] = t.data[1]; + s.data[2] = p; + return s; +} + +// CHECK: %struct.T* byval +extern "C" S* succeed(S* sret, int, int, int, int, T t, void* p) { + sret->data[0] = t.data[0]; + sret->data[1] = t.data[1]; + sret->data[2] = p; + return sret; +} diff --git a/test/CodeGenCXX/x86_32-arguments.cpp b/test/CodeGenCXX/x86_32-arguments.cpp index 4d4339381dbe..1cbeb71b2285 100644 --- a/test/CodeGenCXX/x86_32-arguments.cpp +++ b/test/CodeGenCXX/x86_32-arguments.cpp @@ -6,7 +6,7 @@ struct S { short s; }; -// CHECK: define void @_Z1fv(%struct.S* sret % +// CHECK: define void @_Z1fv(%struct.S* noalias sret % S f() { return S(); } // CHECK: define void @_Z1f1S(%struct.S*) void f(S) { } @@ -18,7 +18,7 @@ public: double c; }; -// CHECK: define void @_Z1gv(%class.C* sret % +// CHECK: define void @_Z1gv(%class.C* noalias sret % C g() { return C(); } // CHECK: define void @_Z1f1C(%class.C*) @@ -103,13 +103,13 @@ struct s7_1 { double x; }; struct s7 : s7_0, s7_1 { }; s7 f7() { return s7(); } -// CHECK: define void @_Z2f8v(%struct.s8* sret %agg.result) +// CHECK: define void @_Z2f8v(%struct.s8* noalias sret %agg.result) struct s8_0 { }; struct s8_1 { double x; }; struct s8 { s8_0 a; s8_1 b; }; s8 f8() { return s8(); } -// CHECK: define void @_Z2f9v(%struct.s9* sret %agg.result) +// CHECK: define void @_Z2f9v(%struct.s9* noalias sret %agg.result) struct s9_0 { unsigned : 0; }; struct s9_1 { double x; }; struct s9 { s9_0 a; s9_1 b; }; |