guitard0g created this revision. guitard0g added reviewers: aaron.ballman, NoQ, vsavchenko. guitard0g requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
The 'escape' attribute indicates that the annotated pointer parameter may escape the scope of the function. This attribute is meant to be used for compiler diagnostics/static analysis checks. The attribute will first be used by the Swift compiler in a new implicit bridging diagnostic, but may have other non-Swift use-cases for diagnostics. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D107026 Files: clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/lib/Sema/SemaDeclAttr.cpp clang/test/AST/ast-dump-attr.cpp clang/test/AST/ast-dump-attr.m
Index: clang/test/AST/ast-dump-attr.m =================================================================== --- clang/test/AST/ast-dump-attr.m +++ clang/test/AST/ast-dump-attr.m @@ -65,4 +65,8 @@ // CHECK-NEXT: | `-NoEscapeAttr // CHECK-NEXT: |-ParmVarDecl{{.*}} Test14 'int' // CHECK-NEXT: `-NSConsumesSelfAttr +-(void)Test15: (int *) [[clang::escape]] Test16; +// CHECK: ObjCMethodDecl{{.*}} Test15: 'void' +// CHECK-NEXT: -ParmVarDecl{{.*}} Test16 'int *' +// CHECK-NEXT: `-EscapeAttr @end Index: clang/test/AST/ast-dump-attr.cpp =================================================================== --- clang/test/AST/ast-dump-attr.cpp +++ clang/test/AST/ast-dump-attr.cpp @@ -200,6 +200,15 @@ // CHECK-NEXT: NoEscapeAttr } +namespace TestEscape { + void escapeFunc(int *p0, __attribute__((escape)) int *p1) {} + // CHECK: NamespaceDecl{{.*}} TestEscape + // CHECK-NEXT: `-FunctionDecl{{.*}} escapeFunc 'void (int *, int *)' + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: EscapeAttr +} + namespace TestSuppress { [[gsl::suppress("at-namespace")]]; // CHECK: NamespaceDecl{{.*}} TestSuppress Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -1553,11 +1553,11 @@ D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL)); } -static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { +static void handleXEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (D->isInvalidDecl()) return; - // noescape only applies to pointer types. + // escape/noescape only applies to pointer types. QualType T = cast<ParmVarDecl>(D)->getType(); if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) { S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only) @@ -1565,7 +1565,16 @@ return; } - D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL)); + switch (AL.getKind()) { + default: + llvm_unreachable("invalid escape attribute"); + case ParsedAttr::AT_NoEscape: + handleSimpleAttribute<NoEscapeAttr>(S, D, AL); + return; + case ParsedAttr::AT_Escape: + handleSimpleAttribute<EscapeAttr>(S, D, AL); + return; + } } static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) { @@ -8007,8 +8016,9 @@ case ParsedAttr::AT_ReturnsNonNull: handleReturnsNonNullAttr(S, D, AL); break; + case ParsedAttr::AT_Escape: case ParsedAttr::AT_NoEscape: - handleNoEscapeAttr(S, D, AL); + handleXEscapeAttr(S, D, AL); break; case ParsedAttr::AT_AssumeAligned: handleAssumeAlignedAttr(S, D, AL); Index: clang/include/clang/Basic/AttrDocs.td =================================================================== --- clang/include/clang/Basic/AttrDocs.td +++ clang/include/clang/Basic/AttrDocs.td @@ -253,6 +253,27 @@ }]; } +def EscapeDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +``escape`` placed on a function parameter of a pointer type is used to indicate +that the pointer can escape the function. This means that a reference to the object +the pointer points to that is derived from the parameter value may survive +after the function returns. + +For example: + +.. code-block:: c + + int *gp; + + void escapingFunc(__attribute__((escape)) int *p) { + gp = p; + } + + }]; +} + def CarriesDependencyDocs : Documentation { let Category = DocCatFunction; let Content = [{ Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -1949,6 +1949,12 @@ let Documentation = [NoEscapeDocs]; } +def Escape : Attr { + let Spellings = [Clang<"escape">]; + let Subjects = SubjectList<[ParmVar]>; + let Documentation = [EscapeDocs]; +} + def AssumeAligned : InheritableAttr { let Spellings = [GCC<"assume_aligned">]; let Subjects = SubjectList<[ObjCMethod, Function]>;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits