From 30c93dba5bb24637aa49b9222394d8aca7c88263 Mon Sep 17 00:00:00 2001 From: Akira Hatanaka Date: Wed, 20 Sep 2017 06:55:43 +0000 Subject: [PATCH] Revert "Add support for attribute 'noescape'." This reverts commit r313722. It looks like compiler-rt/lib/tsan/rtl/tsan_libdispatch_mac.cc cannot be compiled because some of the functions declared in the file do not match the ones in the SDK headers (which are annotated with 'noescape'). llvm-svn: 313725 --- clang/include/clang/AST/ASTContext.h | 27 +------ clang/include/clang/AST/Type.h | 14 ---- clang/include/clang/Basic/Attr.td | 6 -- clang/include/clang/Basic/AttrDocs.td | 41 ---------- clang/include/clang/Basic/DiagnosticGroups.td | 1 - clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 -- clang/lib/AST/ASTContext.cpp | 64 ++++----------- clang/lib/AST/ItaniumMangle.cpp | 3 - clang/lib/AST/TypePrinter.cpp | 2 - clang/lib/CodeGen/CGCall.cpp | 9 +-- clang/lib/Sema/SemaDeclAttr.cpp | 19 ----- clang/lib/Sema/SemaDeclCXX.cpp | 17 +--- clang/lib/Sema/SemaDeclObjC.cpp | 8 -- clang/lib/Sema/SemaOverload.cpp | 25 +----- clang/lib/Sema/SemaType.cpp | 5 -- clang/test/CodeGenCXX/noescape.cpp | 67 ---------------- clang/test/CodeGenObjC/noescape.m | 71 ----------------- clang/test/Misc/ast-dump-attr.cpp | 8 -- ...pragma-attribute-supported-attributes-list.test | 3 +- clang/test/Sema/noescape.c | 25 ------ clang/test/SemaObjCXX/noescape.mm | 90 ---------------------- 21 files changed, 24 insertions(+), 486 deletions(-) delete mode 100644 clang/test/CodeGenCXX/noescape.cpp delete mode 100644 clang/test/CodeGenObjC/noescape.m delete mode 100644 clang/test/Sema/noescape.c delete mode 100644 clang/test/SemaObjCXX/noescape.mm diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 831d461..3718098 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2413,30 +2413,9 @@ public: QualType mergeObjCGCQualifiers(QualType, QualType); - /// This function merges the ExtParameterInfo lists of two functions. It - /// returns true if the lists are compatible. The merged list is returned in - /// NewParamInfos. - /// - /// \param FirstFnType The type of the first function. - /// - /// \param SecondFnType The type of the second function. - /// - /// \param CanUseFirst This flag is set to true if the first function's - /// ExtParameterInfo list can be used as the composite list of - /// ExtParameterInfo. - /// - /// \param CanUseSecond This flag is set to true if the second function's - /// ExtParameterInfo list can be used as the composite list of - /// ExtParameterInfo. - /// - /// \param NewParamInfos The composite list of ExtParameterInfo. The list is - /// empty if none of the flags are set. - /// - bool mergeExtParameterInfo( - const FunctionProtoType *FirstFnType, - const FunctionProtoType *SecondFnType, - bool &CanUseFirst, bool &CanUseSecond, - SmallVectorImpl &NewParamInfos); + bool doFunctionTypesMatchOnExtParameterInfos( + const FunctionProtoType *FromFunctionType, + const FunctionProtoType *ToFunctionType); void ResetObjCLayout(const ObjCContainerDecl *CD); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 98ab767..eaf5995 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -3149,7 +3149,6 @@ public: ABIMask = 0x0F, IsConsumed = 0x10, HasPassObjSize = 0x20, - IsNoEscape = 0x40, }; unsigned char Data; @@ -3190,19 +3189,6 @@ public: return Copy; } - bool isNoEscape() const { - return Data & IsNoEscape; - } - - ExtParameterInfo withIsNoEscape(bool NoEscape) const { - ExtParameterInfo Copy = *this; - if (NoEscape) - Copy.Data |= IsNoEscape; - else - Copy.Data &= ~IsNoEscape; - return Copy; - } - unsigned char getOpaqueValue() const { return Data; } static ExtParameterInfo getFromOpaqueValue(unsigned char data) { ExtParameterInfo result; diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index c356770..894e0a0 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -1396,12 +1396,6 @@ def ObjCKindOf : TypeAttr { let Documentation = [Undocumented]; } -def NoEscape : Attr { - let Spellings = [GNU<"noescape">, CXX11<"clang", "noescape">]; - let Subjects = SubjectList<[ParmVar]>; - let Documentation = [NoEscapeDocs]; -} - def AssumeAligned : InheritableAttr { let Spellings = [GCC<"assume_aligned">]; let Subjects = SubjectList<[ObjCMethod, Function]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 0500c28..6a7bbbc 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -130,47 +130,6 @@ members, and static locals. }]; } -def NoEscapeDocs : Documentation { - let Category = DocCatVariable; - let Content = [{ -``noescape`` placed on a function parameter of a pointer type is used to inform -the compiler that the pointer cannot escape: that is, no reference to the object -the pointer points to that is derived from the parameter value will survive -after the function returns. Users are responsible for making sure parameters -annotated with ``noescape`` do not actuallly escape. - -For example: - -.. code-block:: c - int *gp; - - void nonescapingFunc(__attribute__((noescape)) int *p) { - *p += 100; // OK. - } - - void escapingFunc(__attribute__((noescape)) int *p) { - gp = p; // Not OK. - } - -Additionally, when the parameter is a `block pointer -`, the same restriction -applies to copies of the block. For example: - - typedef void (^BlockTy)(); - BlockTy g0, g1; - - void nonescapingFunc(__attribute__((noescape)) BlockTy block) { - block(); // OK. - } - - void escapingFunc(__attribute__((noescape)) BlockTy block) { - g0 = block; // Not OK. - g1 = Block_copy(block); // Not OK either. - } - - }]; -} - def CarriesDependencyDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index bb7c837..33cae6c 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -90,7 +90,6 @@ def GNUStringLiteralOperatorTemplate : DiagGroup<"gnu-string-literal-operator-template">; def UndefinedVarTemplate : DiagGroup<"undefined-var-template">; def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">; -def MissingNoEscape : DiagGroup<"missing-noescape">; def DeleteIncomplete : DiagGroup<"delete-incomplete">; def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index c0532ba..3974fe0 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1661,11 +1661,6 @@ def err_conflicting_overriding_cc_attributes : Error< "virtual function %0 has different calling convention attributes " "%diff{($) than the function it overrides (which has calling convention $)|" "than the function it overrides}1,2">; -def warn_overriding_method_missing_noescape : Warning< - "parameter of overriding method should be annotated with " - "__attribute__((noescape))">, InGroup; -def note_overridden_marked_noescape : Note< - "parameter of overridden method is annotated with __attribute__((noescape))">; def err_covariant_return_inaccessible_base : Error< "invalid covariant return for virtual function: %1 is a " diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 82e7452..4d26748 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -7968,17 +7968,9 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, if (lproto->getTypeQuals() != rproto->getTypeQuals()) return QualType(); - SmallVector newParamInfos; - bool canUseLeft, canUseRight; - if (!mergeExtParameterInfo(lproto, rproto, canUseLeft, canUseRight, - newParamInfos)) + if (!doFunctionTypesMatchOnExtParameterInfos(rproto, lproto)) return QualType(); - if (!canUseLeft) - allLTypes = false; - if (!canUseRight) - allRTypes = false; - // Check parameter type compatibility SmallVector types; for (unsigned i = 0, n = lproto->getNumParams(); i < n; i++) { @@ -8009,8 +8001,6 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, FunctionProtoType::ExtProtoInfo EPI = lproto->getExtProtoInfo(); EPI.ExtInfo = einfo; - EPI.ExtParameterInfos = - newParamInfos.empty() ? nullptr : newParamInfos.data(); return getFunctionType(retType, types, EPI); } @@ -8370,50 +8360,26 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, llvm_unreachable("Invalid Type::Class!"); } -bool ASTContext::mergeExtParameterInfo( - const FunctionProtoType *FirstFnType, const FunctionProtoType *SecondFnType, - bool &CanUseFirst, bool &CanUseSecond, - SmallVectorImpl &NewParamInfos) { - assert(NewParamInfos.empty() && "param info list not empty"); - CanUseFirst = CanUseSecond = true; - bool FirstHasInfo = FirstFnType->hasExtParameterInfos(); - bool SecondHasInfo = SecondFnType->hasExtParameterInfos(); - +bool ASTContext::doFunctionTypesMatchOnExtParameterInfos( + const FunctionProtoType *firstFnType, + const FunctionProtoType *secondFnType) { // Fast path: if the first type doesn't have ext parameter infos, - // we match if and only if the second type also doesn't have them. - if (!FirstHasInfo && !SecondHasInfo) - return true; + // we match if and only if they second type also doesn't have them. + if (!firstFnType->hasExtParameterInfos()) + return !secondFnType->hasExtParameterInfos(); - bool NeedParamInfo = false; - size_t E = FirstHasInfo ? FirstFnType->getExtParameterInfos().size() - : SecondFnType->getExtParameterInfos().size(); + // Otherwise, we can only match if the second type has them. + if (!secondFnType->hasExtParameterInfos()) + return false; - for (size_t I = 0; I < E; ++I) { - FunctionProtoType::ExtParameterInfo FirstParam, SecondParam; - if (FirstHasInfo) - FirstParam = FirstFnType->getExtParameterInfo(I); - if (SecondHasInfo) - SecondParam = SecondFnType->getExtParameterInfo(I); + auto firstEPI = firstFnType->getExtParameterInfos(); + auto secondEPI = secondFnType->getExtParameterInfos(); + assert(firstEPI.size() == secondEPI.size()); - // Cannot merge unless everything except the noescape flag matches. - if (FirstParam.withIsNoEscape(false) != SecondParam.withIsNoEscape(false)) + for (size_t i = 0, n = firstEPI.size(); i != n; ++i) { + if (firstEPI[i] != secondEPI[i]) return false; - - bool FirstNoEscape = FirstParam.isNoEscape(); - bool SecondNoEscape = SecondParam.isNoEscape(); - bool IsNoEscape = FirstNoEscape && SecondNoEscape; - NewParamInfos.push_back(FirstParam.withIsNoEscape(IsNoEscape)); - if (NewParamInfos.back().getOpaqueValue()) - NeedParamInfo = true; - if (FirstNoEscape != IsNoEscape) - CanUseFirst = false; - if (SecondNoEscape != IsNoEscape) - CanUseSecond = false; } - - if (!NeedParamInfo) - NewParamInfos.clear(); - return true; } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index a9c5ab2..dbda7a5 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2643,9 +2643,6 @@ CXXNameMangler::mangleExtParameterInfo(FunctionProtoType::ExtParameterInfo PI) { if (PI.isConsumed()) mangleVendorQualifier("ns_consumed"); - - if (PI.isNoEscape()) - mangleVendorQualifier("noescape"); } // ::= diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index 1f5b483..15c63bf 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -665,8 +665,6 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T, auto EPI = T->getExtParameterInfo(i); if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) "; - if (EPI.isNoEscape()) - OS << "__attribute__((noescape)) "; auto ABI = EPI.getABI(); if (ABI != ParameterABI::Ordinary) OS << "__attribute__((" << getParameterABISpelling(ABI) << ")) "; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index a432c3c..c6988b5 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -455,15 +455,11 @@ const CGFunctionInfo & CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, QualType receiverType) { SmallVector argTys; - SmallVector extParamInfos(2); argTys.push_back(Context.getCanonicalParamType(receiverType)); argTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType())); // FIXME: Kill copy? for (const auto *I : MD->parameters()) { argTys.push_back(Context.getCanonicalParamType(I->getType())); - auto extParamInfo = FunctionProtoType::ExtParameterInfo().withIsNoEscape( - I->hasAttr()); - extParamInfos.push_back(extParamInfo); } FunctionType::ExtInfo einfo; @@ -479,7 +475,7 @@ CodeGenTypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, return arrangeLLVMFunctionInfo( GetReturnType(MD->getReturnType()), /*instanceMethod=*/false, - /*chainCall=*/false, argTys, einfo, extParamInfos, required); + /*chainCall=*/false, argTys, einfo, {}, required); } const CGFunctionInfo & @@ -2097,9 +2093,6 @@ void CodeGenModule::ConstructAttributeList( break; } - if (FI.getExtParameterInfo(ArgNo).isNoEscape()) - Attrs.addAttribute(llvm::Attribute::NoCapture); - if (Attrs.hasAttributes()) { unsigned FirstIRArg, NumIRArgs; std::tie(FirstIRArg, NumIRArgs) = IRFunctionArgs.getIRArgs(ArgNo); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index cffb860..b8432eb 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1531,22 +1531,6 @@ static void handleReturnsNonNullAttr(Sema &S, Decl *D, Attr.getAttributeSpellingListIndex())); } -static void handleNoEscapeAttr(Sema &S, Decl *D, const AttributeList &Attr) { - if (D->isInvalidDecl()) - return; - - // noescape only applies to pointer types. - QualType T = cast(D)->getType(); - if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) { - S.Diag(Attr.getLoc(), diag::warn_attribute_pointers_only) - << Attr.getName() << Attr.getRange() << 0; - return; - } - - D->addAttr(::new (S.Context) NoEscapeAttr( - Attr.getRange(), S.Context, Attr.getAttributeSpellingListIndex())); -} - static void handleAssumeAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) { Expr *E = Attr.getArgAsExpr(0), @@ -6183,9 +6167,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_ReturnsNonNull: handleReturnsNonNullAttr(S, D, Attr); break; - case AttributeList::AT_NoEscape: - handleNoEscapeAttr(S, D, Attr); - break; case AttributeList::AT_AssumeAligned: handleAssumeAlignedAttr(S, D, Attr); break; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 312e0e2..529084a 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -14081,21 +14081,8 @@ void Sema::DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock) { bool Sema::CheckOverridingFunctionAttributes(const CXXMethodDecl *New, const CXXMethodDecl *Old) { - const auto *NewFT = New->getType()->getAs(); - const auto *OldFT = Old->getType()->getAs(); - - if (OldFT->hasExtParameterInfos()) { - for (unsigned I = 0, E = OldFT->getNumParams(); I != E; ++I) - // A parameter of the overriding method should be annotated with noescape - // if the corresponding parameter of the overridden method is annotated. - if (OldFT->getExtParameterInfo(I).isNoEscape() && - !NewFT->getExtParameterInfo(I).isNoEscape()) { - Diag(New->getParamDecl(I)->getLocation(), - diag::warn_overriding_method_missing_noescape); - Diag(Old->getParamDecl(I)->getLocation(), - diag::note_overridden_marked_noescape); - } - } + const FunctionType *NewFT = New->getType()->getAs(); + const FunctionType *OldFT = Old->getType()->getAs(); CallingConv NewCC = NewFT->getCallConv(), OldCC = OldFT->getCallConv(); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 6b33f7c..5f9f608 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -188,14 +188,6 @@ void Sema::CheckObjCMethodOverride(ObjCMethodDecl *NewMethod, Diag(newDecl->getLocation(), diag::warn_nsconsumed_attribute_mismatch); Diag(oldDecl->getLocation(), diag::note_previous_decl) << "parameter"; } - - // A parameter of the overriding method should be annotated with noescape - // if the corresponding parameter of the overridden method is annotated. - if (oldDecl->hasAttr() && !newDecl->hasAttr()) { - Diag(newDecl->getLocation(), - diag::warn_overriding_method_missing_noescape); - Diag(oldDecl->getLocation(), diag::note_overridden_marked_noescape); - } } } diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 8f28ec2..36f24fd 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1481,23 +1481,6 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, .getTypePtr()); Changed = true; } - - // Convert FromFPT's ExtParameterInfo if necessary. The conversion is valid - // only if the ExtParameterInfo lists of the two function prototypes can be - // merged and the merged list is identical to ToFPT's ExtParameterInfo list. - SmallVector NewParamInfos; - bool CanUseToFPT, CanUseFromFPT; - if (Context.mergeExtParameterInfo(ToFPT, FromFPT, CanUseToFPT, - CanUseFromFPT, NewParamInfos) && - CanUseToFPT && !CanUseFromFPT) { - FunctionProtoType::ExtProtoInfo ExtInfo = FromFPT->getExtProtoInfo(); - ExtInfo.ExtParameterInfos = - NewParamInfos.empty() ? nullptr : NewParamInfos.data(); - QualType QT = Context.getFunctionType(FromFPT->getReturnType(), - FromFPT->getParamTypes(), ExtInfo); - FromFn = QT->getAs(); - Changed = true; - } } if (!Changed) @@ -2680,12 +2663,8 @@ bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType, // Argument types are too different. Abort. return false; } - - SmallVector NewParamInfos; - bool CanUseToFPT, CanUseFromFPT; - if (!Context.mergeExtParameterInfo(ToFunctionType, FromFunctionType, - CanUseToFPT, CanUseFromFPT, - NewParamInfos)) + if (!Context.doFunctionTypesMatchOnExtParameterInfos(FromFunctionType, + ToFunctionType)) return false; ConvertedType = ToType; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index f35eef2..c4d7bb1 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -4479,11 +4479,6 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, HasAnyInterestingExtParameterInfos = true; } - if (Param->hasAttr()) { - ExtParameterInfos[i] = ExtParameterInfos[i].withIsNoEscape(true); - HasAnyInterestingExtParameterInfos = true; - } - ParamTys.push_back(ParamTy); } diff --git a/clang/test/CodeGenCXX/noescape.cpp b/clang/test/CodeGenCXX/noescape.cpp deleted file mode 100644 index e8abd41..0000000 --- a/clang/test/CodeGenCXX/noescape.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// RUN: %clang_cc1 -std=c++11 -emit-llvm -o - %s | FileCheck %s - -struct S { - int a[4]; - S(int *, int * __attribute__((noescape))); - S &operator=(int * __attribute__((noescape))); - void m0(int *, int * __attribute__((noescape))); - virtual void vm1(int *, int * __attribute__((noescape))); -}; - -// CHECK: define void @_ZN1SC2EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture) -// CHECK: define void @_ZN1SC1EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture) {{.*}} { -// CHECK: call void @_ZN1SC2EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) - -S::S(int *, int * __attribute__((noescape))) {} - -// CHECK: define {{.*}} %struct.S* @_ZN1SaSEPi(%struct.S* {{.*}}, {{.*}} nocapture) -S &S::operator=(int * __attribute__((noescape))) { return *this; } - -// CHECK: define void @_ZN1S2m0EPiS0_(%struct.S* {{.*}}, {{.*}} nocapture) -void S::m0(int *, int * __attribute__((noescape))) {} - -// CHECK: define void @_ZN1S3vm1EPiS0_(%struct.S* {{.*}}, {{.*}} nocapture) -void S::vm1(int *, int * __attribute__((noescape))) {} - -// CHECK-LABEL: define void @_Z5test0P1SPiS1_( -// CHECK: call void @_ZN1SC1EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) -// CHECK: call {{.*}} %struct.S* @_ZN1SaSEPi(%struct.S* {{.*}}, {{.*}} nocapture {{.*}}) -// CHECK: call void @_ZN1S2m0EPiS0_(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) -// CHECK: call void {{.*}}(%struct.S* {{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) -void test0(S *s, int *p0, int *p1) { - S t(p0, p1); - t = p1; - s->m0(p0, p1); - s->vm1(p0, p1); -} - -namespace std { - typedef decltype(sizeof(0)) size_t; -} - -// CHECK: define {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}}) -void *operator new(std::size_t, void * __attribute__((noescape)) p) { - return p; -} - -// CHECK-LABEL: define i8* @_Z5test1Pv( -// CHECK : %call = call {{.*}} @_ZnwmPv({{.*}}, {{.*}} nocapture {{.*}}) -void *test1(void *p0) { - return ::operator new(16, p0); -} - -// CHECK-LABEL: define void @_Z5test2PiS_( -// CHECK: call void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) -// CHECK: define internal void @"_ZZ5test2PiS_ENK3$_0clES_S_"({{.*}}, {{.*}}, {{.*}} nocapture) -void test2(int *p0, int *p1) { - auto t = [](int *, int * __attribute__((noescape))){}; - t(p0, p1); -} - -// CHECK-LABEL: define void @_Z5test3PFvU8noescapePiES_( -// CHECK: call void {{.*}}(i32* nocapture {{.*}}) -typedef void (*NoEscapeFunc)(__attribute__((noescape)) int *); - -void test3(NoEscapeFunc f, int *p) { - f(p); -} diff --git a/clang/test/CodeGenObjC/noescape.m b/clang/test/CodeGenObjC/noescape.m deleted file mode 100644 index 8ea2aa9..0000000 --- a/clang/test/CodeGenObjC/noescape.m +++ /dev/null @@ -1,71 +0,0 @@ -// RUN: %clang_cc1 -fblocks -emit-llvm -o - %s | FileCheck %s - -typedef void (^BlockTy)(void); - -union U { - int *i; - long long *ll; -} __attribute__((transparent_union)); - -void noescapeFunc0(id, __attribute__((noescape)) BlockTy); -void noescapeFunc1(__attribute__((noescape)) int *); -void noescapeFunc2(__attribute__((noescape)) id); -void noescapeFunc3(__attribute__((noescape)) union U); - -// CHECK-LABEL: define void @test0( -// CHECK: call void @noescapeFunc0({{.*}}, {{.*}} nocapture {{.*}}) -// CHECK: declare void @noescapeFunc0(i8*, {{.*}} nocapture) -void test0(BlockTy b) { - noescapeFunc0(0, b); -} - -// CHECK-LABEL: define void @test1( -// CHECK: call void @noescapeFunc1({{.*}} nocapture {{.*}}) -// CHECK: declare void @noescapeFunc1({{.*}} nocapture) -void test1(int *i) { - noescapeFunc1(i); -} - -// CHECK-LABEL: define void @test2( -// CHECK: call void @noescapeFunc2({{.*}} nocapture {{.*}}) -// CHECK: declare void @noescapeFunc2({{.*}} nocapture) -void test2(id i) { - noescapeFunc2(i); -} - -// CHECK-LABEL: define void @test3( -// CHECK: call void @noescapeFunc3({{.*}} nocapture {{.*}}) -// CHECK: declare void @noescapeFunc3({{.*}} nocapture) -void test3(union U u) { - noescapeFunc3(u); -} - -// CHECK: define internal void @"\01-[C0 m0:]"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}}) - -// CHECK-LABEL: define void @test4( -// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32*)*)(i8* {{.*}}, i8* {{.*}}, i32* nocapture {{.*}}) - -@interface C0 --(void) m0:(int*)__attribute__((noescape)) p0; -@end - -@implementation C0 --(void) m0:(int*)__attribute__((noescape)) p0 { -} -@end - -void test4(C0 *c0, int *p) { - [c0 m0:p]; -} - -// CHECK-LABEL: define void @test5( -// CHECK: call void {{.*}}(i8* bitcast ({ i8**, i32, i32, i8*, {{.*}} }* @{{.*}} to i8*), i32* nocapture {{.*}}) -// CHECK: call void {{.*}}(i8* {{.*}}, i32* nocapture {{.*}}) -// CHECK: define internal void @{{.*}}(i8* {{.*}}, i32* nocapture {{.*}}) - -typedef void (^BlockTy2)(__attribute__((noescape)) int *); - -void test5(BlockTy2 b, int *p) { - ^(int *__attribute__((noescape)) p0){}(p); - b(p); -} diff --git a/clang/test/Misc/ast-dump-attr.cpp b/clang/test/Misc/ast-dump-attr.cpp index bf94295..07f9160 100644 --- a/clang/test/Misc/ast-dump-attr.cpp +++ b/clang/test/Misc/ast-dump-attr.cpp @@ -180,14 +180,6 @@ __attribute__((external_source_symbol(generated_declaration, defined_in="module" // CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr5 // CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration -namespace TestNoEscape { - void noescapeFunc(int *p0, __attribute__((noescape)) int *p1) {} - // CHECK: `-FunctionDecl{{.*}} noescapeFunc 'void (int *, __attribute__((noescape)) int *)' - // CHECK-NEXT: ParmVarDecl - // CHECK-NEXT: ParmVarDecl - // CHECK-NEXT: NoEscapeAttr -} - namespace TestSuppress { [[gsl::suppress("at-namespace")]]; // CHECK: NamespaceDecl{{.*}} TestSuppress diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 7529a24..16c1f67 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -2,7 +2,7 @@ // The number of supported attributes should never go down! -// CHECK: #pragma clang attribute supports 65 attributes: +// CHECK: #pragma clang attribute supports 64 attributes: // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function) // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function) @@ -35,7 +35,6 @@ // CHECK-NEXT: MipsShortCall (SubjectMatchRule_function) // CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter) // CHECK-NEXT: NoDuplicate (SubjectMatchRule_function) -// CHECK-NEXT: NoEscape (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: NoMicroMips (SubjectMatchRule_function) // CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global) // CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global) diff --git a/clang/test/Sema/noescape.c b/clang/test/Sema/noescape.c deleted file mode 100644 index 39f3f6f..0000000 --- a/clang/test/Sema/noescape.c +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify %s - -void escapefunc(int *); -void noescapefunc(__attribute__((noescape)) int *); -void (*escapefuncptr)(int *); -void (*noescapefuncptr)(__attribute__((noescape)) int *); - -void func_ne(__attribute__((noescape)) int *, int *); -void func_en(int *, __attribute__((noescape)) int *); - -void (*funcptr_ee)(int *, int *); -void (*funcptr_nn)(__attribute__((noescape)) int *, __attribute__((noescape)) int *); - -void test0(int c) { - escapefuncptr = &escapefunc; - escapefuncptr = &noescapefunc; - noescapefuncptr = &escapefunc; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}} - noescapefuncptr = &noescapefunc; - - escapefuncptr = c ? &escapefunc : &noescapefunc; - noescapefuncptr = c ? &escapefunc : &noescapefunc; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *)' from 'void (*)(int *)'}} - - funcptr_ee = c ? &func_ne : &func_en; - funcptr_nn = c ? &func_ne : &func_en; // expected-warning {{incompatible function pointer types assigning to 'void (*)(__attribute__((noescape)) int *, __attribute__((noescape)) int *)' from 'void (*)(int *, int *)'}} -} diff --git a/clang/test/SemaObjCXX/noescape.mm b/clang/test/SemaObjCXX/noescape.mm deleted file mode 100644 index 6c5d989..0000000 --- a/clang/test/SemaObjCXX/noescape.mm +++ /dev/null @@ -1,90 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++11 %s -// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -std=c++1z %s - -typedef void (^BlockTy)(); - -struct S { - int i; - void m(); -}; - -void noescapeFunc0(id, __attribute__((noescape)) BlockTy); -void noescapeFunc1(id, [[clang::noescape]] BlockTy); -void noescapeFunc2(__attribute__((noescape)) int *); // expected-note {{previous declaration is here}} -void noescapeFunc3(__attribute__((noescape)) id); -void noescapeFunc4(__attribute__((noescape)) int &); -void noescapeFunc2(int *); // expected-error {{conflicting types for 'noescapeFunc2'}} - -void invalidFunc0(int __attribute__((noescape))); // expected-warning {{'noescape' attribute only applies to pointer arguments}} -void invalidFunc1(int __attribute__((noescape(0)))); // expected-error {{'noescape' attribute takes no arguments}} -void invalidFunc2(int0 *__attribute__((noescape))); // expected-error {{use of undeclared identifier 'int0'; did you mean 'int'?}} -void invalidFunc3(__attribute__((noescape)) int (S::*Ty)); // expected-warning {{'noescape' attribute only applies to pointer arguments}} -void invalidFunc4(__attribute__((noescape)) void (S::*Ty)()); // expected-warning {{'noescape' attribute only applies to pointer arguments}} -int __attribute__((noescape)) g; // expected-warning {{'noescape' attribute only applies to parameters}} - -struct S1 { - virtual void m0(int *__attribute__((noescape))); // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}} -}; - -struct S2 : S1 { - void m0(int *__attribute__((noescape))) override; -}; - -struct S3 : S1 { - void m0(int *) override; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}} -}; - -__attribute__((objc_root_class)) -@interface C0 --(void) m0:(int*)__attribute__((noescape)) p; // expected-note {{parameter of overridden method is annotated with __attribute__((noescape))}} -@end - -@implementation C0 --(void) m0:(int*)__attribute__((noescape)) p {} -@end - -@interface C1 : C0 --(void) m0:(int*)__attribute__((noescape)) p; -@end - -@implementation C1 : C0 --(void) m0:(int*)__attribute__((noescape)) p {} -@end - -@interface C2 : C0 --(void) m0:(int*) p; // expected-warning {{parameter of overriding method should be annotated with __attribute__((noescape))}} -@end - -@implementation C2 : C0 --(void) m0:(int*) p {} -@end - -void func0(int *); -void (*fnptr0)(int *); -void (*fnptr1)(__attribute__((noescape)) int *); -template struct S4 {}; -template struct S5 {}; - -#if __cplusplus < 201406 - // expected-note@-4 {{template parameter is declared here}} - // expected-note@-4 {{template parameter is declared here}} -#endif - -void test0() { - fnptr0 = &func0; - fnptr0 = &noescapeFunc2; - fnptr1 = &func0; // expected-error {{assigning to 'void (*)(__attribute__((noescape)) int *)' from incompatible type 'void (*)(int *)'}} - fnptr1 = &noescapeFunc2; - S4<&func0> e0; - S4<&noescapeFunc2> e1; - S5<&func0> ne0; - -#if __cplusplus < 201406 - // expected-error@-4 {{non-type template argument of type 'void (*)(__attribute__((noescape)) int *)' cannot be converted to a value of type 'void (*)(int *)'}} - // expected-error@-4 {{non-type template argument of type 'void (*)(int *)' cannot be converted to a value of type 'void (*)(__attribute__((noescape)) int *)'}} -#else - // expected-error@-6 {{value of type 'void (*)(int *)' is not implicitly convertible to 'void (*)(__attribute__((noescape)) int *)'}} -#endif - - S5<&noescapeFunc2> ne1; -} -- 2.7.4