<html><head><meta http-equiv="Content-Type" content="text/html; charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div><div><div></div><div><br class=""></div><div><br class=""></div><div><div>The static function canPassInRegisters computes whether the record can be passed in registers depending on which of the three ABIs (clang-abi-compat=4.0, 64-bit microsoft, and Itanium C++ ABI) we are using. The function returns the correct answer except when ARC is enabled and the record has a __weak field, which is why CXXRecordDecl::canPassInRegisters() has to be called too to check the presence of __weak fields when computing the value for flag RecordDecl::CanPassInRegisters.  I discovered there is a bug which causes a struct containing another struct with __weak fields to be passed directly, but I think that can be fixed in a separate patch.</div><div><br class=""></div><div>Sema::CheckCompletedCXXClass also computes the value for flag RecordDecl::ParamDestroyedInCallee (note that this flag is meaningless when Microsoft ABI is used). This is how it works when a struct has __weak or __strong fields:</div><div><br class=""></div><div>1. In CXXRecordDecl::addedMember, pretend that __weak or __strong fields do not make special functions non-trivial for the purpose of calls.</div><div>2. If canPassInRegisters returns true, use the C ABI to pass the record, which destructs records in the callee and passes records with __weak fields indirectly (records having __strong fields but no __weak fields are not forced to be passed indirectly). If it returns false, use the C++ ABI, which destructs the record in the caller and passes it indirectly.</div><div>3. Since we cannot count on canPassInRegisters to tell whether a record can be passed directly in the presence of a __weak field, CXXRecordDecl::addedMember calls setCanPassInRegisters(false) so that we know the record cannot be passed directly.</div><div><br class=""></div><div>hasTrivialABIOverride (which computes "canPassInRegisters() && hasNonTrivialDestructor()") used to determine whether a struct is destructed in the callee, but the function can no longer be used since structs with __weak fields are always passed indirectly.</div><div><br class=""></div></div></div></div><div><blockquote type="cite" class=""><div class=""><div dir="ltr" style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class="">Please can you fix these names?</div><div class=""> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); padding-left: 1ex;"> /// Look up the special member function that would be called by a special<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/<wbr class="">ASTReaderDecl.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ASTReaderDecl.<wbr class="">cpp?rev=328731&r1=328730&r2=<wbr class="">328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Serialization/<wbr class="">ASTReaderDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/<wbr class="">ASTReaderDecl.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -743,6 +743,7 @@ ASTDeclReader::<wbr class="">VisitRecordDeclImpl(Recor<br class="">   RD-><wbr class="">setNonTrivialToPrimitiveCopy(<wbr class="">Record.readInt());<br class="">   RD-><wbr class="">setNonTrivialToPrimitiveDestro<wbr class="">y(Record.readInt());<br class="">   RD->setCanPassInRegisters(<wbr class="">Record.readInt());<br class="">+  RD->setParamDestroyedInCallee(<wbr class="">Record.readInt());<br class="">   return Redecl;<br class=""> }<br class=""><br class="">@@ -4109,6 +4110,7 @@ void ASTDeclReader::UpdateDecl(Decl *D,<br class="">           OldDD && (OldDD->Definition != RD ||<br class="">                     !Reader.<wbr class="">PendingFakeDefinitionData.<wbr class="">count(OldDD));<br class="">       RD->setCanPassInRegisters(<wbr class="">Record.readInt());<br class="">+      RD->setParamDestroyedInCallee(<wbr class="">Record.readInt());<br class="">       ReadCXXRecordDefinition(RD, /*Update*/true);<br class=""><br class="">       // Visible update is handled separately.<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ASTWriter.cpp?<wbr class="">rev=328731&r1=328730&r2=<wbr class="">328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/<wbr class="">ASTWriter.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -5194,6 +5194,7 @@ void ASTWriter::<wbr class="">WriteDeclUpdatesBlocks(R<br class="">         auto *RD = cast<CXXRecordDecl>(D);<br class="">         UpdatedDeclContexts.insert(RD-<wbr class="">>getPrimaryContext());<br class="">         Record.push_back(RD-><wbr class="">canPassInRegisters());<br class="">+        Record.push_back(RD-><wbr class="">isParamDestroyedInCallee());<br class="">         Record.AddCXXDefinitionData(<wbr class="">RD);<br class="">         Record.AddOffset(<wbr class="">WriteDeclContextLexicalBlock(<br class="">             *Context, const_cast<CXXRecordDecl *>(RD)));<br class=""><br class="">Modified: cfe/trunk/lib/Serialization/<wbr class="">ASTWriterDecl.cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/lib/<wbr class="">Serialization/ASTWriterDecl.<wbr class="">cpp?rev=328731&r1=328730&r2=<wbr class="">328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/lib/Serialization/<wbr class="">ASTWriterDecl.cpp (original)<br class="">+++ cfe/trunk/lib/Serialization/<wbr class="">ASTWriterDecl.cpp Wed Mar 28 14:13:14 2018<br class="">@@ -470,6 +470,7 @@ void ASTDeclWriter::<wbr class="">VisitRecordDecl(Reco<br class="">   Record.push_back(D-><wbr class="">isNonTrivialToPrimitiveCopy())<wbr class="">;<br class="">   Record.push_back(D-><wbr class="">isNonTrivialToPrimitiveDestroy<wbr class="">());<br class="">   Record.push_back(D-><wbr class="">canPassInRegisters());<br class="">+  Record.push_back(D-><wbr class="">isParamDestroyedInCallee());<br class=""><br class="">   if (D->getDeclContext() == D->getLexicalDeclContext() &&<br class="">       !D->hasAttrs() &&<br class="">@@ -1912,6 +1913,8 @@ void ASTWriter::WriteDeclAbbrevs() {<br class="">   // isNonTrivialToPrimitiveDestroy<br class="">   Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::Fixed, 1));<br class="">   Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::Fixed, 1)); // canPassInRegisters<br class="">+  // isParamDestroyedInCallee<br class="">+  Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::Fixed, 1));<br class=""><br class="">   // DC<br class="">   Abv->Add(BitCodeAbbrevOp(<wbr class="">BitCodeAbbrevOp::VBR, 6));   // LexicalOffset<br class=""><br class="">Modified: cfe/trunk/test/CodeGenCXX/<wbr class="">microsoft-abi-sret-and-byval.<wbr class="">cpp<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenCXX/microsoft-abi-sret-<wbr class="">and-byval.cpp?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/test/CodeGenCXX/<wbr class="">microsoft-abi-sret-and-byval.<wbr class="">cpp (original)<br class="">+++ cfe/trunk/test/CodeGenCXX/<wbr class="">microsoft-abi-sret-and-byval.<wbr class="">cpp Wed Mar 28 14:13:14 2018<br class="">@@ -172,12 +172,9 @@ void small_arg_with_dtor(<wbr class="">SmallWithDtor s<br class=""> void call_small_arg_with_dtor() {<br class="">   small_arg_with_dtor(<wbr class="">SmallWithDtor());<br class=""> }<br class="">-// The temporary is copied, so it's destroyed in the caller as well as the<br class="">-// callee.<br class=""> // WIN64-LABEL: define dso_local void @"?call_small_arg_with_dtor@@<wbr class="">YAXXZ"()<br class=""> // WIN64:   call %struct.SmallWithDtor* @"??0SmallWithDtor@@QEAA@XZ"<br class=""> // WIN64:   call void @"?small_arg_with_dtor@@<wbr class="">YAXUSmallWithDtor@@@Z"(i32 %{{.*}})<br class="">-// WIN64:   call void @"??1SmallWithDtor@@QEAA@XZ"<br class=""> // WIN64:   ret void<br class=""><br class=""> // Test that references aren't destroyed in the callee.<br class=""><br class="">Modified: cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-special-member-functions.mm/" rel="noreferrer" target="_blank" class="">a<wbr class="">rc-special-member-functions.mm</a><br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/arc-special-member-functions.mm?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenObjCXX/arc-special-<wbr class="">member-functions.mm?rev=<wbr class="">328731&r1=328730&r2=328731&<wbr class="">view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-special-member-functions.mm/" rel="noreferrer" target="_blank" class="">a<wbr class="">rc-special-member-functions.mm</a><span class="Apple-converted-space"> </span>(original)<br class="">+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://arc-special-member-functions.mm/" rel="noreferrer" target="_blank" class="">a<wbr class="">rc-special-member-functions.mm</a><span class="Apple-converted-space"> </span>Wed Mar 28 14:13:14 2018<br class="">@@ -31,6 +31,8 @@ void test_ObjCMember_copy_<wbr class="">construct_dest<br class=""> void test_ObjCMember_copy_assign(<wbr class="">ObjCMember m1, ObjCMember m2) {<br class="">   // CHECK: {{call.*_ZN10ObjCMemberaSERKS_<wbr class="">}}<br class="">   m1 = m2;<br class="">+  // CHECK-NEXT: call void @_ZN10ObjCMemberD1Ev(<br class="">+  // CHECK-NEXT: call void @_ZN10ObjCMemberD1Ev(<br class="">   // CHECK-NEXT: ret void<br class=""> }<br class=""><br class="">@@ -58,6 +60,8 @@ void test_ObjCArrayMember_copy_<wbr class="">construct<br class=""> void test_ObjCArrayMember_copy_<wbr class="">assign(ObjCArrayMember m1, ObjCArrayMember m2) {<br class="">   // CHECK: {{call.*@_<wbr class="">ZN15ObjCArrayMemberaSERKS_}}<br class="">   m1 = m2;<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCArrayMemberD1Ev(<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCArrayMemberD1Ev(<br class="">   // CHECK-NEXT: ret void<br class=""> }<br class=""><br class="">@@ -79,7 +83,8 @@ void test_ObjCBlockMember_default_<wbr class="">constr<br class=""> void test_ObjCBlockMember_copy_<wbr class="">construct_destruct(<wbr class="">ObjCBlockMember m1) {<br class="">   // CHECK: call void @_ZN15ObjCBlockMemberC1ERKS_<br class="">   ObjCBlockMember m2 = m1;<br class="">-  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(<br class="">   // CHECK-NEXT: ret void<br class=""> }<br class=""><br class="">@@ -87,6 +92,8 @@ void test_ObjCBlockMember_copy_<wbr class="">construct<br class=""> void test_ObjCBlockMember_copy_<wbr class="">assign(ObjCBlockMember m1, ObjCBlockMember m2) {<br class="">   // CHECK: {{call.*_<wbr class="">ZN15ObjCBlockMemberaSERKS_}}<br class="">   m1 = m2;<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(<br class="">+  // CHECK-NEXT: call void @_ZN15ObjCBlockMemberD1Ev(<br class="">   // CHECK-NEXT: ret void<br class=""> }<br class=""><br class=""><br class="">Copied: cfe/trunk/test/CodeGenObjCXX/<a href="http://objc-struct-cxx-abi.mm/" rel="noreferrer" target="_blank" class="">o<wbr class="">bjc-struct-cxx-abi.mm</a><span class="Apple-converted-space"> </span>(from r328730, cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a>)<br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm?p2=cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm&p1=cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm&r1=328730&r2=328731&rev=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenObjCXX/objc-struct-cxx-<wbr class="">abi.mm?p2=cfe/trunk/test/<wbr class="">CodeGenObjCXX/objc-struct-cxx-<wbr class="">abi.mm&p1=cfe/trunk/test/<wbr class="">CodeGenObjCXX/trivial_abi.mm&<wbr class="">r1=328730&r2=328731&rev=<wbr class="">328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><span class="Apple-converted-space"> </span>(original)<br class="">+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://objc-struct-cxx-abi.mm/" rel="noreferrer" target="_blank" class="">o<wbr class="">bjc-struct-cxx-abi.mm</a><span class="Apple-converted-space"> </span>Wed Mar 28 14:13:14 2018<br class="">@@ -1,27 +1,60 @@<br class=""> // RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s<br class=""> // RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s<br class="">+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - -DTRIVIALABI %s | FileCheck %s<br class="">+// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - -DTRIVIALABI %s | FileCheck %s<br class="">+<br class="">+// Check that structs consisting solely of __strong or __weak pointer fields are<br class="">+// destructed in the callee function and structs consisting solely of __strong<br class="">+// pointer fields are passed directly.<br class=""><br class=""> // CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { i8*, i8* }<br class=""> // CHECK: %[[STRUCT_STRONG:.*]] = type { i8* }<br class=""> // CHECK: %[[STRUCT_S:.*]] = type { i8* }<br class="">+// CHECK: %[[STRUCT_CONTAINSNONTRIVIAL:.<wbr class="">*]] = type { %{{.*}}, i8* }<br class=""><br class="">+#ifdef TRIVIALABI<br class=""> struct __attribute__((trivial_abi)) StrongWeak {<br class="">+#else<br class="">+struct StrongWeak {<br class="">+#endif<br class="">   id fstrong;<br class="">   __weak id fweak;<br class=""> };<br class=""><br class="">+#ifdef TRIVIALABI<br class=""> struct __attribute__((trivial_abi)) Strong {<br class="">+#else<br class="">+struct Strong {<br class="">+#endif<br class="">   id fstrong;<br class=""> };<br class=""><br class=""> template<class T><br class="">+#ifdef TRIVIALABI<br class=""> struct __attribute__((trivial_abi)) S {<br class="">+#else<br class="">+struct S {<br class="">+#endif<br class="">   T a;<br class=""> };<br class=""><br class="">+struct NonTrivial {<br class="">+  NonTrivial();<br class="">+  NonTrivial(const NonTrivial &);<br class="">+  ~NonTrivial();<br class="">+  int *a;<br class="">+};<br class="">+<br class="">+// This struct is not passed directly nor destructed in the callee because f0<br class="">+// has type NonTrivial.<br class="">+struct ContainsNonTrivial {<br class="">+  NonTrivial f0;<br class="">+  id f1;<br class="">+};<br class="">+<br class=""> // CHECK: define void @_<wbr class="">Z19testParamStrongWeak10Strong<wbr class="">Weak(%[[STRUCT_STRONGWEAK]]* %{{.*}})<br class="">-// CHECK-NOT: call<br class="">-// CHECK: ret void<br class="">+// CHECK: call %struct.StrongWeak* @_ZN10StrongWeakD1Ev(<br class="">+// CHECK-NEXT: ret void<br class=""><br class=""> void testParamStrongWeak(StrongWeak a) {<br class=""> }<br class="">@@ -33,7 +66,7 @@ void testParamStrongWeak(StrongWeak a) {<br class=""> // CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class=""> // CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[<wbr class="">STRUCT_STRONGWEAK]]* %[[AGG_TMP]], %[[STRUCT_STRONGWEAK]]* dereferenceable(16) %[[V0]])<br class=""> // CHECK: call void @_<wbr class="">Z19testParamStrongWeak10Strong<wbr class="">Weak(%[[STRUCT_STRONGWEAK]]* %[[AGG_TMP]])<br class="">-// CHECK: %[[CALL1:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakD1Ev(%[[<wbr class="">STRUCT_STRONGWEAK]]* %[[AGG_TMP]])<br class="">+// CHECK-NOT: call<br class=""> // CHECK: ret void<br class=""><br class=""> void testCallStrongWeak(StrongWeak *a) {<br class="">@@ -96,8 +129,23 @@ Strong testReturnStrong(Strong *a) {<br class=""> }<br class=""><br class=""> // CHECK: define void @_<wbr class="">Z21testParamWeakTemplate1SIU6_<wbr class="">_weakP11objc_objectE(%[[<wbr class="">STRUCT_S]]* %{{.*}})<br class="">+// CHECK: call %struct.S* @_ZN1SIU6__weakP11objc_<wbr class="">objectED1Ev(<br class="">+// CHECK-NEXT: ret void<br class="">+<br class="">+void testParamWeakTemplate(S<__weak id> a) {<br class="">+}<br class="">+<br class="">+// CHECK: define void @_<wbr class="">Z27testParamContainsNonTrivial<wbr class="">18ContainsNonTrivial(%[[<wbr class="">STRUCT_CONTAINSNONTRIVIAL]]* %{{.*}})<br class=""> // CHECK-NOT: call<br class=""> // CHECK: ret void<br class=""><br class="">-void testParamWeakTemplate(S<__weak id> a) {<br class="">+void testParamContainsNonTrivial(<wbr class="">ContainsNonTrivial a) {<br class="">+}<br class="">+<br class="">+// CHECK: define void @_<wbr class="">Z26testCallContainsNonTrivialP<wbr class="">18ContainsNonTrivial(<br class="">+// CHECK: call void @_<wbr class="">Z27testParamContainsNonTrivial<wbr class="">18ContainsNonTrivial(%[[<wbr class="">STRUCT_CONTAINSNONTRIVIAL]]* %{{.*}})<br class="">+// CHECK: call %struct.ContainsNonTrivial* @_ZN18ContainsNonTrivialD1Ev(%<wbr class="">[[STRUCT_CONTAINSNONTRIVIAL]]* %{{.*}})<br class="">+<br class="">+void testCallContainsNonTrivial(<wbr class="">ContainsNonTrivial *a) {<br class="">+  testParamContainsNonTrivial(*<wbr class="">a);<br class=""> }<br class=""><br class="">Modified: cfe/trunk/test/CodeGenObjCXX/<a href="http://property-dot-copy-elision.mm/" rel="noreferrer" target="_blank" class="">p<wbr class="">roperty-dot-copy-elision.mm</a><br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/property-dot-copy-elision.mm?rev=328731&r1=328730&r2=328731&view=diff" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenObjCXX/property-dot-<wbr class="">copy-elision.mm?rev=328731&r1=<wbr class="">328730&r2=328731&view=diff</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/test/CodeGenObjCXX/<a href="http://property-dot-copy-elision.mm/" rel="noreferrer" target="_blank" class="">p<wbr class="">roperty-dot-copy-elision.mm</a><span class="Apple-converted-space"> </span>(original)<br class="">+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://property-dot-copy-elision.mm/" rel="noreferrer" target="_blank" class="">p<wbr class="">roperty-dot-copy-elision.mm</a><span class="Apple-converted-space"> </span>Wed Mar 28 14:13:14 2018<br class="">@@ -1,11 +1,13 @@<br class=""> // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++1z -fobjc-arc -o - %s | FileCheck %s<br class=""><br class=""> struct S0 {<br class="">+  ~S0();<br class="">   id f;<br class=""> };<br class=""><br class=""> struct S1 {<br class="">   S1();<br class="">+  ~S1();<br class="">   S1(S0);<br class="">   id f;<br class=""> };<br class=""><br class="">Removed: cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><br class="">URL:<span class="Apple-converted-space"> </span><a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/trivial_abi.mm?rev=328730&view=auto" rel="noreferrer" target="_blank" class="">http://llvm.org/viewvc/llvm-<wbr class="">project/cfe/trunk/test/<wbr class="">CodeGenObjCXX/trivial_abi.mm?<wbr class="">rev=328730&view=auto</a><br class="">==============================<wbr class="">==============================<wbr class="">==================<br class="">--- cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><span class="Apple-converted-space"> </span>(original)<br class="">+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://trivial_abi.mm/" rel="noreferrer" target="_blank" class="">t<wbr class="">rivial_abi.mm</a><span class="Apple-converted-space"> </span>(removed)<br class="">@@ -1,103 +0,0 @@<br class="">-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -emit-llvm -o - %s | FileCheck %s<br class="">-// RUN: %clang_cc1 -triple arm64-apple-ios11 -std=c++11 -fobjc-arc  -fobjc-weak -fobjc-runtime-has-weak -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s<br class="">-<br class="">-// CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { i8*, i8* }<br class="">-// CHECK: %[[STRUCT_STRONG:.*]] = type { i8* }<br class="">-// CHECK: %[[STRUCT_S:.*]] = type { i8* }<br class="">-<br class="">-struct __attribute__((trivial_abi)) StrongWeak {<br class="">-  id fstrong;<br class="">-  __weak id fweak;<br class="">-};<br class="">-<br class="">-struct __attribute__((trivial_abi)) Strong {<br class="">-  id fstrong;<br class="">-};<br class="">-<br class="">-template<class T><br class="">-struct __attribute__((trivial_abi)) S {<br class="">-  T a;<br class="">-};<br class="">-<br class="">-// CHECK: define void @_<wbr class="">Z19testParamStrongWeak10Strong<wbr class="">Weak(%[[STRUCT_STRONGWEAK]]* %{{.*}})<br class="">-// CHECK-NOT: call<br class="">-// CHECK: ret void<br class="">-<br class="">-void testParamStrongWeak(StrongWeak a) {<br class="">-}<br class="">-<br class="">-// CHECK: define void @_<wbr class="">Z18testCallStrongWeakP10Strong<wbr class="">Weak(%[[STRUCT_STRONGWEAK]]* %[[A:.*]])<br class="">-// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONGWEAK]]*, align 8<br class="">-// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONGWEAK]], align 8<br class="">-// CHECK: store %[[STRUCT_STRONGWEAK]]* %[[A]], %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[<wbr class="">STRUCT_STRONGWEAK]]* %[[AGG_TMP]], %[[STRUCT_STRONGWEAK]]* dereferenceable(16) %[[V0]])<br class="">-// CHECK: call void @_<wbr class="">Z19testParamStrongWeak10Strong<wbr class="">Weak(%[[STRUCT_STRONGWEAK]]* %[[AGG_TMP]])<br class="">-// CHECK: %[[CALL1:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakD1Ev(%[[<wbr class="">STRUCT_STRONGWEAK]]* %[[AGG_TMP]])<br class="">-// CHECK: ret void<br class="">-<br class="">-void testCallStrongWeak(StrongWeak *a) {<br class="">-  testParamStrongWeak(*a);<br class="">-}<br class="">-<br class="">-// CHECK: define void @_<wbr class="">Z20testReturnStrongWeakP10Stro<wbr class="">ngWeak(%[[STRUCT_STRONGWEAK:.*<wbr class="">]]* noalias sret %[[AGG_RESULT:.*]], %[[STRUCT_STRONGWEAK]]* %[[A:.*]])<br class="">-// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONGWEAK]]*, align 8<br class="">-// CHECK: store %[[STRUCT_STRONGWEAK]]* %[[A]], %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONGWEAK]]*, %[[STRUCT_STRONGWEAK]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONGWEAK]]* @_ZN10StrongWeakC1ERKS_(%[[<wbr class="">STRUCT_STRONGWEAK]]* %[[AGG_RESULT]], %[[STRUCT_STRONGWEAK]]* dereferenceable(16) %[[V0]])<br class="">-// CHECK: ret void<br class="">-<br class="">-StrongWeak testReturnStrongWeak(<wbr class="">StrongWeak *a) {<br class="">-  return *a;<br class="">-}<br class="">-<br class="">-// CHECK: define void @_Z15testParamStrong6Strong(<wbr class="">i64 %[[A_COERCE:.*]])<br class="">-// CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONG]], align 8<br class="">-// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[A]], i32 0, i32 0<br class="">-// CHECK: %[[COERCE_VAL_IP:.*]] = inttoptr i64 %[[A_COERCE]] to i8*<br class="">-// CHECK: store i8* %[[COERCE_VAL_IP]], i8** %[[COERCE_DIVE]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(%[[STRUCT_<wbr class="">STRONG]]* %[[A]])<br class="">-// CHECK: ret void<br class="">-<br class="">-// CHECK: define linkonce_odr %[[STRUCT_STRONG]]* @_ZN6StrongD1Ev(<br class="">-<br class="">-void testParamStrong(Strong a) {<br class="">-}<br class="">-<br class="">-// CHECK: define void @_Z14testCallStrongP6Strong(%[<wbr class="">[STRUCT_STRONG]]* %[[A:.*]])<br class="">-// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8<br class="">-// CHECK: %[[AGG_TMP:.*]] = alloca %[[STRUCT_STRONG]], align 8<br class="">-// CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONG]]*, %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongC1ERKS_(%[[STRUCT_<wbr class="">STRONG]]* %[[AGG_TMP]], %[[STRUCT_STRONG]]* dereferenceable(8) %[[V0]])<br class="">-// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[AGG_TMP]], i32 0, i32 0<br class="">-// CHECK: %[[V1:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8<br class="">-// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V1]] to i64<br class="">-// CHECK: call void @_Z15testParamStrong6Strong(<wbr class="">i64 %[[COERCE_VAL_PI]])<br class="">-// CHECK: ret void<br class="">-<br class="">-void testCallStrong(Strong *a) {<br class="">-  testParamStrong(*a);<br class="">-}<br class="">-<br class="">-// CHECK: define i64 @_Z16testReturnStrongP6Strong(<wbr class="">%[[STRUCT_STRONG]]* %[[A:.*]])<br class="">-// CHECK: %[[RETVAL:.*]] = alloca %[[STRUCT_STRONG]], align 8<br class="">-// CHECK: %[[A_ADDR:.*]] = alloca %[[STRUCT_STRONG]]*, align 8<br class="">-// CHECK: store %[[STRUCT_STRONG]]* %[[A]], %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[V0:.*]] = load %[[STRUCT_STRONG]]*, %[[STRUCT_STRONG]]** %[[A_ADDR]], align 8<br class="">-// CHECK: %[[CALL:.*]] = call %[[STRUCT_STRONG]]* @_ZN6StrongC1ERKS_(%[[STRUCT_<wbr class="">STRONG]]* %[[RETVAL]], %[[STRUCT_STRONG]]* dereferenceable(8) %[[V0]])<br class="">-// CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[RETVAL]], i32 0, i32 0<br class="">-// CHECK: %[[V1:.*]] = load i8*, i8** %[[COERCE_DIVE]], align 8<br class="">-// CHECK: %[[COERCE_VAL_PI:.*]] = ptrtoint i8* %[[V1]] to i64<br class="">-// CHECK: ret i64 %[[COERCE_VAL_PI]]<br class="">-<br class="">-Strong testReturnStrong(Strong *a) {<br class="">-  return *a;<br class="">-}<br class="">-<br class="">-// CHECK: define void @_<wbr class="">Z21testParamWeakTemplate1SIU6_<wbr class="">_weakP11objc_objectE(%[[<wbr class="">STRUCT_S]]* %{{.*}})<br class="">-// CHECK-NOT: call<br class="">-// CHECK: ret void<br class="">-<br class="">-void testParamWeakTemplate(S<__weak id> a) {<br class="">-}<br class=""><br class=""><br class="">______________________________<wbr class="">_________________<br class="">cfe-commits mailing list<br class=""><a href="mailto:cfe-commits@lists.llvm.org" class="">cfe-commits@lists.llvm.org</a><br class=""><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank" class="">http://lists.llvm.org/cgi-bin/<wbr class="">mailman/listinfo/cfe-commits</a></blockquote></div></div></div></div></blockquote></div><br class=""></div></div></div></body></html>