guitard0g updated this revision to Diff 362643.
guitard0g added a comment.
Herald added a subscriber: jdoerfert.
Change Escape/NoEscape to use InheritableAttr and update an attribute test to
fix test failure.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D107026/new/
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
clang/test/Misc/pragma-attribute-supported-attributes-list.test
Index: clang/test/Misc/pragma-attribute-supported-attributes-list.test
===================================================================
--- clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -61,6 +61,7 @@
// CHECK-NEXT: EnforceTCB (SubjectMatchRule_function)
// CHECK-NEXT: EnforceTCBLeaf (SubjectMatchRule_function)
// CHECK-NEXT: EnumExtensibility (SubjectMatchRule_enum)
+// CHECK-NEXT: Escape (SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: ExcludeFromExplicitInstantiation (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
// CHECK-NEXT: ExternalSourceSymbol ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_implementation, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable))
// CHECK-NEXT: FlagEnum (SubjectMatchRule_enum)
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
@@ -1943,12 +1943,18 @@
let Documentation = [Undocumented];
}
-def NoEscape : Attr {
+def NoEscape : InheritableAttr {
let Spellings = [Clang<"noescape">];
let Subjects = SubjectList<[ParmVar]>;
let Documentation = [NoEscapeDocs];
}
+def Escape : InheritableAttr {
+ 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