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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits