NoQ created this revision. NoQ added reviewers: aaron.ballman, dcoughlin, george.karpenkov. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Continuing the trend started in D54912 <https://reviews.llvm.org/D54912>, i'd like to stuff one more XNU/Mach/Darwin-specific attribute into there. This one's fairly simple and is designed in order to be respected by the Static Analyzer's Mach Interface Generator calling convention checker that's getting added in D57558 <https://reviews.llvm.org/D57558>. @aaron.ballman, are you actually interested in reviewing these attributes? 'Cause George added you on his reviews but i totally understand that these are fairly exotic. Repository: rC Clang https://reviews.llvm.org/D58365 Files: clang/include/clang/Basic/Attr.td clang/include/clang/Basic/AttrDocs.td clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaDeclAttr.cpp clang/test/Misc/pragma-attribute-supported-attributes-list.test clang/test/Sema/attr-mig.c clang/test/Sema/attr-mig.cpp
Index: clang/test/Sema/attr-mig.cpp =================================================================== --- /dev/null +++ clang/test/Sema/attr-mig.cpp @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef int kern_return_t; +typedef kern_return_t IOReturn; +#define KERN_SUCCESS 0 +#define kIOReturnSuccess KERN_SUCCESS + +class MyServer { +public: + virtual __attribute__((mig_server_routine)) IOReturn externalMethod(); + virtual __attribute__((mig_server_routine)) void anotherMethod(); // expected-warning{{'mig_server_routine' attribute only applies to functions that return a kernel return code}} + virtual __attribute__((mig_server_routine)) int yetAnotherMethod(); // expected-warning{{'mig_server_routine' attribute only applies to functions that return a kernel return code}} +}; + +IOReturn MyServer::externalMethod() { + return kIOReturnSuccess; +} Index: clang/test/Sema/attr-mig.c =================================================================== --- /dev/null +++ clang/test/Sema/attr-mig.c @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +typedef int kern_return_t; +#define KERN_SUCCESS 0 + +__attribute__((mig_server_routine)) kern_return_t var = KERN_SUCCESS; // expected-warning-re{{'mig_server_routine' attribute only applies to functions{{$}}}} + +__attribute__((mig_server_routine)) void foo_void(); // expected-warning{{'mig_server_routine' attribute only applies to functions that return a kernel return code}} +__attribute__((mig_server_routine)) int foo_int(); // expected-warning{{'mig_server_routine' attribute only applies to functions that return a kernel return code}} + +__attribute__((mig_server_routine)) kern_return_t bar_extern(); // no-warning +__attribute__((mig_server_routine)) kern_return_t bar_forward(); // no-warning + +__attribute__((mig_server_routine)) kern_return_t bar_definition() { // no-warning + return KERN_SUCCESS; +} + +kern_return_t bar_forward() { // no-warning + return KERN_SUCCESS; +} 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 @@ -60,6 +60,7 @@ // CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record) // CHECK-NEXT: Lockable (SubjectMatchRule_record) +// CHECK-NEXT: MIGServerRoutine (SubjectMatchRule_function) // CHECK-NEXT: MSStruct (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) // CHECK-NEXT: MinSize (SubjectMatchRule_function, SubjectMatchRule_objc_method) Index: clang/lib/Sema/SemaDeclAttr.cpp =================================================================== --- clang/lib/Sema/SemaDeclAttr.cpp +++ clang/lib/Sema/SemaDeclAttr.cpp @@ -6396,6 +6396,25 @@ handleSimpleAttribute<ObjCExternallyRetainedAttr>(S, D, AL); } +static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // Check that the return type is a `typedef int kern_return_t` or a typedef + // around it, because otherwise calling convention checks make no sense. + QualType T = cast<FunctionDecl>(D)->getReturnType(); + bool IsKernReturnT = false; + while (const auto *TT = T->getAs<TypedefType>()) { + IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t"); + T = TT->desugar(); + } + if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) { + S.Diag(D->getBeginLoc(), + diag::warn_mig_server_routine_does_not_return_kern_return_t) + << AL.getName()->getName(); + return; + } + + handleSimpleAttribute<MIGServerRoutineAttr>(S, D, AL); +} + //===----------------------------------------------------------------------===// // Top Level Sema Entry Points //===----------------------------------------------------------------------===// @@ -7119,6 +7138,11 @@ case ParsedAttr::AT_ObjCExternallyRetained: handleObjCExternallyRetainedAttr(S, D, AL); break; + + // Mach Interface Generator annotations. + case ParsedAttr::AT_MIGServerRoutine: + handleMIGServerRoutineAttr(S, D, AL); + break; } } Index: clang/include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticSemaKinds.td +++ clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8696,6 +8696,11 @@ def ext_opencl_ext_vector_type_rgba_selector: ExtWarn< "vector component name '%0' is an OpenCL version 2.2 feature">, InGroup<OpenCLUnsupportedRGBA>; + +// MIG routine annotations. +def warn_mig_server_routine_does_not_return_kern_return_t : Warning< + "'%0' attribute only applies to functions that return a kernel return code">, + InGroup<IgnoredAttributes>; } // end of sema category let CategoryName = "OpenMP Issue" in { Index: clang/include/clang/Basic/AttrDocs.td =================================================================== --- clang/include/clang/Basic/AttrDocs.td +++ clang/include/clang/Basic/AttrDocs.td @@ -4028,3 +4028,23 @@ When compiled without ``-fobjc-arc``, this attribute is ignored. }]; } + +def MIGCallingConventionDocs : Documentation { + let Category = DocCatType; + let Content = [{ + The Mach Interface Generator release-on-success calling convention dictates +functions that follow it to only release arguments passed to them when they +return "success" (a ``kern_return_t`` error code that indicates that +no errors have occured). Otherwise the release is performed by the MIG client +that called the function. The annotation ``__attribute__((mig_server_routine))`` +is applied in order to specify which functions are affected by the calling +convention. This allows the Static Analyzer to find bugs caused by violations of +that convention. The attribute would normally appear on the forward declaration +of the actual server routine in the MIG server header, but it may also be +added to arbitrary functions that need to follow the same convention - for +example, a user can add them to auxiliary functions called by the server routine +that have their return value of type ``kern_return_t`` unconditionally returned +from the routine. The attribute can be applied to C++ methods, and in this case +it will be automatically applied to overrides if the method is virtual. +}]; +} Index: clang/include/clang/Basic/Attr.td =================================================================== --- clang/include/clang/Basic/Attr.td +++ clang/include/clang/Basic/Attr.td @@ -1307,6 +1307,12 @@ let Documentation = [Undocumented]; } +def MIGServerRoutine : InheritableAttr { + let Spellings = [Clang<"mig_server_routine">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [MIGCallingConventionDocs]; +} + def MSABI : DeclOrTypeAttr { let Spellings = [GCC<"ms_abi">]; // let Subjects = [Function, ObjCMethod];
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits