Hello Akira, This commit added broken tests to one of our builders: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/8964
Failing Tests (8): Clang :: CodeGenObjCXX/objc-struct-cxx-abi.mm Clang :: SemaObjCXX/attr-trivial-abi.mm . . . Please have a look? The builder was red and did not send notifications. Thanks Galina On Mon, Apr 9, 2018 at 1:39 PM, Akira Hatanaka via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: ahatanak > Date: Mon Apr 9 13:39:47 2018 > New Revision: 329617 > > URL: http://llvm.org/viewvc/llvm-project?rev=329617&view=rev > Log: > [ObjC++] Never pass structs that transitively contain __weak fields in > registers. > > This patch fixes a bug in r328731 that caused structs transitively > containing __weak fields to be passed in registers. The patch replaces > the flag RecordDecl::CanPassInRegisters with a 2-bit enum that indicates > whether the struct or structs containing the struct are forced to be > passed indirectly. > > rdar://problem/39194693 > > Modified: > cfe/trunk/include/clang/AST/Decl.h > cfe/trunk/include/clang/AST/Type.h > cfe/trunk/lib/AST/Decl.cpp > cfe/trunk/lib/AST/DeclCXX.cpp > cfe/trunk/lib/AST/Type.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > cfe/trunk/lib/Serialization/ASTWriter.cpp > cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm > > Modified: cfe/trunk/include/clang/AST/Decl.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/AST/Decl.h?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/include/clang/AST/Decl.h (original) > +++ cfe/trunk/include/clang/AST/Decl.h Mon Apr 9 13:39:47 2018 > @@ -3541,6 +3541,31 @@ public: > /// union Y { int A, B; }; // Has body with members A and B > (FieldDecls). > /// This decl will be marked invalid if *any* members are invalid. > class RecordDecl : public TagDecl { > +public: > + /// Enum that represents the different ways arguments are passed to and > + /// returned from function calls. This takes into account the > target-specific > + /// and version-specific rules along with the rules determined by the > + /// language. > + enum ArgPassingKind { > + /// The argument of this type can be passed directly in registers. > + APK_CanPassInRegs, > + > + /// The argument of this type cannot be passed directly in registers. > + /// Records containing this type as a subobject are not forced to be > passed > + /// indirectly. This value is used only in C++. This value is > required by > + /// C++ because, in uncommon situations, it is possible for a class > to have > + /// only trivial copy/move constructors even when one of its > subobjects has > + /// a non-trivial copy/move constructor (if e.g. the corresponding > copy/move > + /// constructor in the derived class is deleted). > + APK_CannotPassInRegs, > + > + /// The argument of this type cannot be passed directly in registers. > + /// Records containing this type as a subobject are forced to be > passed > + /// indirectly. > + APK_CanNeverPassInRegs > + }; > + > +private: > friend class DeclContext; > > // FIXME: This can be packed into the bitfields in Decl. > @@ -3571,17 +3596,14 @@ class RecordDecl : public TagDecl { > bool NonTrivialToPrimitiveCopy : 1; > bool NonTrivialToPrimitiveDestroy : 1; > > - /// True if this class can be passed in a non-address-preserving fashion > - /// (such as in registers). > - /// This does not imply anything about how the ABI in use will actually > - /// pass an object of this class. > - bool CanPassInRegisters : 1; > - > /// Indicates whether this struct is destroyed in the callee. This flag > is > /// meaningless when Microsoft ABI is used since parameters are always > /// destroyed in the callee. > bool ParamDestroyedInCallee : 1; > > + /// Represents the way this type is passed to a function. > + ArgPassingKind ArgPassingRestrictions : 2; > + > protected: > RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, > SourceLocation StartLoc, SourceLocation IdLoc, > @@ -3669,12 +3691,15 @@ public: > /// it must have at least one trivial, non-deleted copy or move > constructor. > /// FIXME: This should be set as part of completeDefinition. > bool canPassInRegisters() const { > - return CanPassInRegisters; > + return ArgPassingRestrictions == APK_CanPassInRegs; > + } > + > + ArgPassingKind getArgPassingRestrictions() const { > + return ArgPassingRestrictions; > } > > - /// Set that we can pass this RecordDecl in registers. > - void setCanPassInRegisters(bool CanPass) { > - CanPassInRegisters = CanPass; > + void setArgPassingRestrictions(ArgPassingKind Kind) { > + ArgPassingRestrictions = Kind; > } > > bool isParamDestroyedInCallee() const { > > Modified: cfe/trunk/include/clang/AST/Type.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/AST/Type.h?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/include/clang/AST/Type.h (original) > +++ cfe/trunk/include/clang/AST/Type.h Mon Apr 9 13:39:47 2018 > @@ -1149,8 +1149,6 @@ public: > /// source object is placed in an uninitialized state. > PrimitiveCopyKind isNonTrivialToPrimitiveDestructiveMove() const; > > - bool canPassInRegisters() const; > - > enum DestructionKind { > DK_none, > DK_cxx_destructor, > > Modified: cfe/trunk/lib/AST/Decl.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ > Decl.cpp?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/AST/Decl.cpp (original) > +++ cfe/trunk/lib/AST/Decl.cpp Mon Apr 9 13:39:47 2018 > @@ -3956,7 +3956,7 @@ RecordDecl::RecordDecl(Kind DK, TagKind > LoadedFieldsFromExternalStorage(false), > NonTrivialToPrimitiveDefaultInitialize(false), > NonTrivialToPrimitiveCopy(false), NonTrivialToPrimitiveDestroy( > false), > - CanPassInRegisters(true), ParamDestroyedInCallee(false) { > + ParamDestroyedInCallee(false), > ArgPassingRestrictions(APK_CanPassInRegs) > { > assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); > } > > > Modified: cfe/trunk/lib/AST/DeclCXX.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ > DeclCXX.cpp?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/AST/DeclCXX.cpp (original) > +++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Apr 9 13:39:47 2018 > @@ -421,6 +421,10 @@ CXXRecordDecl::setBases(CXXBaseSpecifier > if (BaseClassDecl->hasVolatileMember()) > setHasVolatileMember(true); > > + if (BaseClassDecl->getArgPassingRestrictions() == > + RecordDecl::APK_CanNeverPassInRegs) > + setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); > + > // Keep track of the presence of mutable fields. > if (BaseClassDecl->hasMutableFields()) { > data().HasMutableFields = true; > @@ -950,7 +954,7 @@ void CXXRecordDecl::addedMember(Decl *D) > > // Structs with __weak fields should never be passed directly. > if (LT == Qualifiers::OCL_Weak) > - setCanPassInRegisters(false); > + setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); > > Data.HasIrrelevantDestructor = false; > } else if (!Context.getLangOpts().ObjCAutoRefCount) { > @@ -1117,6 +1121,9 @@ void CXXRecordDecl::addedMember(Decl *D) > setHasObjectMember(true); > if (FieldRec->hasVolatileMember()) > setHasVolatileMember(true); > + if (FieldRec->getArgPassingRestrictions() == > + RecordDecl::APK_CanNeverPassInRegs) > + setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); > > // C++0x [class]p7: > // A standard-layout class is a class that: > > Modified: cfe/trunk/lib/AST/Type.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ > Type.cpp?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/AST/Type.cpp (original) > +++ cfe/trunk/lib/AST/Type.cpp Mon Apr 9 13:39:47 2018 > @@ -2239,17 +2239,6 @@ QualType::isNonTrivialToPrimitiveDestruc > return isNonTrivialToPrimitiveCopy(); > } > > -bool QualType::canPassInRegisters() const { > - if (const auto *RT = > - getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>()) > - return RT->getDecl()->canPassInRegisters(); > - > - if (getQualifiers().getObjCLifetime() == Qualifiers::OCL_Weak) > - return false; > - > - return true; > -} > - > bool Type::isLiteralType(const ASTContext &Ctx) const { > if (isDependentType()) > return false; > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ > SemaDecl.cpp?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Apr 9 13:39:47 2018 > @@ -15465,8 +15465,13 @@ void Sema::ActOnFields(Scope *S, SourceL > Record->setNonTrivialToPrimitiveDestroy(true); > Record->setParamDestroyedInCallee(true); > } > - if (!FT.canPassInRegisters()) > - Record->setCanPassInRegisters(false); > + > + if (const auto *RT = FT->getAs<RecordType>()) { > + if (RT->getDecl()->getArgPassingRestrictions() == > + RecordDecl::APK_CanNeverPassInRegs) > + Record->setArgPassingRestrictions(RecordDecl::APK_ > CanNeverPassInRegs); > + } else if (FT.getQualifiers().getObjCLifetime() == > Qualifiers::OCL_Weak) > + Record->setArgPassingRestrictions(RecordDecl::APK_ > CanNeverPassInRegs); > } > > if (Record && FD->getType().isVolatileQualified()) > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ > SemaDeclCXX.cpp?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Apr 9 13:39:47 2018 > @@ -5847,20 +5847,20 @@ static bool paramCanBeDestroyedInCallee( > return HasNonDeletedCopyOrMove; > } > > -static bool computeCanPassInRegister(bool DestroyedInCallee, > - const CXXRecordDecl *RD, > - TargetInfo::CallingConvKind CCK, > - Sema &S) { > +static RecordDecl::ArgPassingKind > +computeArgPassingRestrictions(bool DestroyedInCallee, const > CXXRecordDecl *RD, > + TargetInfo::CallingConvKind CCK, Sema &S) { > if (RD->isDependentType() || RD->isInvalidDecl()) > - return true; > + return RecordDecl::APK_CanPassInRegs; > > - // The param cannot be passed in registers if CanPassInRegisters is > already > - // set to false. > - if (!RD->canPassInRegisters()) > - return false; > + // The param cannot be passed in registers if ArgPassingRestrictions is > set to > + // APK_CanNeverPassInRegs. > + if (RD->getArgPassingRestrictions() == RecordDecl::APK_ > CanNeverPassInRegs) > + return RecordDecl::APK_CanNeverPassInRegs; > > if (CCK != TargetInfo::CCK_MicrosoftX86_64) > - return DestroyedInCallee; > + return DestroyedInCallee ? RecordDecl::APK_CanPassInRegs > + : RecordDecl::APK_CannotPassInRegs; > > bool CopyCtorIsTrivial = false, CopyCtorIsTrivialForCall = false; > bool DtorIsTrivialForCall = false; > @@ -5900,7 +5900,7 @@ static bool computeCanPassInRegister(boo > > // If the copy ctor and dtor are both trivial-for-calls, pass direct. > if (CopyCtorIsTrivialForCall && DtorIsTrivialForCall) > - return true; > + return RecordDecl::APK_CanPassInRegs; > > // If a class has a destructor, we'd really like to pass it indirectly > // because it allows us to elide copies. Unfortunately, MSVC makes that > @@ -5914,8 +5914,8 @@ static bool computeCanPassInRegister(boo > // passed in registers, which is non-conforming. > if (CopyCtorIsTrivial && > S.getASTContext().getTypeSize(RD->getTypeForDecl()) <= 64) > - return true; > - return false; > + return RecordDecl::APK_CanPassInRegs; > + return RecordDecl::APK_CannotPassInRegs; > } > > /// \brief Perform semantic checks on a class definition that has been > @@ -6090,8 +6090,8 @@ void Sema::CheckCompletedCXXClass(CXXRec > if (Record->hasNonTrivialDestructor()) > Record->setParamDestroyedInCallee(DestroyedInCallee); > > - Record->setCanPassInRegisters( > - computeCanPassInRegister(DestroyedInCallee, Record, CCK, *this)); > + Record->setArgPassingRestrictions( > + computeArgPassingRestrictions(DestroyedInCallee, Record, CCK, > *this)); > } > > /// Look up the special member function that would be called by a special > > Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ > Serialization/ASTReaderDecl.cpp?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Mon Apr 9 13:39:47 2018 > @@ -742,8 +742,8 @@ ASTDeclReader::VisitRecordDeclImpl(Recor > RD->setNonTrivialToPrimitiveDefaultInitialize(Record.readInt()); > RD->setNonTrivialToPrimitiveCopy(Record.readInt()); > RD->setNonTrivialToPrimitiveDestroy(Record.readInt()); > - RD->setCanPassInRegisters(Record.readInt()); > RD->setParamDestroyedInCallee(Record.readInt()); > + RD->setArgPassingRestrictions((RecordDecl::ArgPassingKind) > Record.readInt()); > return Redecl; > } > > @@ -4114,8 +4114,9 @@ void ASTDeclReader::UpdateDecl(Decl *D, > bool HadRealDefinition = > OldDD && (OldDD->Definition != RD || > !Reader.PendingFakeDefinitionData.count(OldDD)); > - RD->setCanPassInRegisters(Record.readInt()); > RD->setParamDestroyedInCallee(Record.readInt()); > + RD->setArgPassingRestrictions( > + (RecordDecl::ArgPassingKind)Record.readInt()); > ReadCXXRecordDefinition(RD, /*Update*/true); > > // Visible update is handled separately. > > Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ > Serialization/ASTWriter.cpp?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Apr 9 13:39:47 2018 > @@ -5193,8 +5193,8 @@ void ASTWriter::WriteDeclUpdatesBlocks(R > case UPD_CXX_INSTANTIATED_CLASS_DEFINITION: { > auto *RD = cast<CXXRecordDecl>(D); > UpdatedDeclContexts.insert(RD->getPrimaryContext()); > - Record.push_back(RD->canPassInRegisters()); > Record.push_back(RD->isParamDestroyedInCallee()); > + Record.push_back(RD->getArgPassingRestrictions()); > Record.AddCXXDefinitionData(RD); > Record.AddOffset(WriteDeclContextLexicalBlock( > *Context, const_cast<CXXRecordDecl *>(RD))); > > Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ > Serialization/ASTWriterDecl.cpp?rev=329617&r1=329616&r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) > +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Mon Apr 9 13:39:47 2018 > @@ -469,8 +469,8 @@ void ASTDeclWriter::VisitRecordDecl(Reco > Record.push_back(D->isNonTrivialToPrimitiveDefaultInitialize()); > Record.push_back(D->isNonTrivialToPrimitiveCopy()); > Record.push_back(D->isNonTrivialToPrimitiveDestroy()); > - Record.push_back(D->canPassInRegisters()); > Record.push_back(D->isParamDestroyedInCallee()); > + Record.push_back(D->getArgPassingRestrictions()); > > if (D->getDeclContext() == D->getLexicalDeclContext() && > !D->hasAttrs() && > @@ -1913,9 +1913,10 @@ void ASTWriter::WriteDeclAbbrevs() { > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); > // isNonTrivialToPrimitiveDestroy > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); > - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // > canPassInRegisters > // isParamDestroyedInCallee > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); > + // getArgPassingRestrictions > + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 2)); > > // DC > Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalOffset > > Modified: cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > CodeGenObjCXX/objc-struct-cxx-abi.mm?rev=329617&r1=329616& > r2=329617&view=diff > ============================================================ > ================== > --- cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm (original) > +++ cfe/trunk/test/CodeGenObjCXX/objc-struct-cxx-abi.mm Mon Apr 9 > 13:39:47 2018 > @@ -8,6 +8,8 @@ > // pointer fields are passed directly. > > // CHECK: %[[STRUCT_STRONGWEAK:.*]] = type { i8*, i8* } > +// CHECK: %[[STRUCT_CONTAINSSTRONGWEAK:.*]] = type { > %[[STRUCT_STRONGWEAK]] } > +// CHECK: %[[STRUCT_DERIVEDSTRONGWEAK:.*]] = type { > %[[STRUCT_STRONGWEAK]] } > // CHECK: %[[STRUCT_STRONG:.*]] = type { i8* } > // CHECK: %[[STRUCT_S:.*]] = type { i8* } > // CHECK: %[[STRUCT_CONTAINSNONTRIVIAL:.*]] = type { %{{.*}}, i8* } > @@ -22,6 +24,21 @@ struct StrongWeak { > }; > > #ifdef TRIVIALABI > +struct __attribute__((trivial_abi)) ContainsStrongWeak { > +#else > +struct ContainsStrongWeak { > +#endif > + StrongWeak sw; > +}; > + > +#ifdef TRIVIALABI > +struct __attribute__((trivial_abi)) DerivedStrongWeak : StrongWeak { > +#else > +struct DerivedStrongWeak : StrongWeak { > +#endif > +}; > + > +#ifdef TRIVIALABI > struct __attribute__((trivial_abi)) Strong { > #else > struct Strong { > @@ -84,6 +101,18 @@ StrongWeak testReturnStrongWeak(StrongWe > return *a; > } > > +// CHECK: define void @_Z27testParamContainsStrongWeak > 18ContainsStrongWeak(%[[STRUCT_CONTAINSSTRONGWEAK]]* %[[A:.*]]) > +// CHECK: call %[[STRUCT_CONTAINSSTRONGWEAK]]* > @_ZN18ContainsStrongWeakD1Ev(%[[STRUCT_CONTAINSSTRONGWEAK]]* %[[A]]) > + > +void testParamContainsStrongWeak(ContainsStrongWeak a) { > +} > + > +// CHECK: define void @_Z26testParamDerivedStrongWeak1 > 7DerivedStrongWeak(%[[STRUCT_DERIVEDSTRONGWEAK]]* %[[A:.*]]) > +// CHECK: call %[[STRUCT_DERIVEDSTRONGWEAK]]* > @_ZN17DerivedStrongWeakD1Ev(%[[STRUCT_DERIVEDSTRONGWEAK]]* %[[A]]) > + > +void testParamDerivedStrongWeak(DerivedStrongWeak a) { > +} > + > // CHECK: define void @_Z15testParamStrong6Strong(i64 %[[A_COERCE:.*]]) > // CHECK: %[[A:.*]] = alloca %[[STRUCT_STRONG]], align 8 > // CHECK: %[[COERCE_DIVE:.*]] = getelementptr inbounds > %[[STRUCT_STRONG]], %[[STRUCT_STRONG]]* %[[A]], i32 0, i32 0 > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits