r326052 - Add a C++11 and C2x spelling for the type safety attribute (argument_with_type_tag, pointer_with_type_tag, and type_tag_for_datatype) in the clang vendor namespace.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 25 06:01:05 PST 2018


Author: aaronballman
Date: Sun Feb 25 06:01:04 2018
New Revision: 326052

URL: http://llvm.org/viewvc/llvm-project?rev=326052&view=rev
Log:
Add a C++11 and C2x spelling for the type safety attribute (argument_with_type_tag, pointer_with_type_tag, and type_tag_for_datatype) in the clang vendor namespace.

The TypeTagForDatatype attribute had custom parsing rules that previously prevented it from being supported with square bracket notation. The ArgumentWithTypeTag attribute previously had unnecessary custom parsing that could be handled declaratively.

Added:
    cfe/trunk/test/Sema/attr-type-safety.c
Modified:
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Sema/warn-type-safety.c

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=326052&r1=326051&r2=326052&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Sun Feb 25 06:01:04 2018
@@ -2458,18 +2458,18 @@ def TestTypestate : InheritableAttr {
 // Type safety attributes for `void *' pointers and type tags.
 
 def ArgumentWithTypeTag : InheritableAttr {
-  let Spellings = [GNU<"argument_with_type_tag">,
-                   GNU<"pointer_with_type_tag">];
+  let Spellings = [Clang<"argument_with_type_tag", 1>,
+                   Clang<"pointer_with_type_tag", 1>];
+  let Subjects = SubjectList<[HasFunctionProto], ErrorDiag>;
   let Args = [IdentifierArgument<"ArgumentKind">,
               UnsignedArgument<"ArgumentIdx">,
               UnsignedArgument<"TypeTagIdx">,
-              BoolArgument<"IsPointer">];
-  let HasCustomParsing = 1;
+              BoolArgument<"IsPointer", /*opt*/0, /*fake*/1>];
   let Documentation = [ArgumentWithTypeTagDocs, PointerWithTypeTagDocs];
 }
 
 def TypeTagForDatatype : InheritableAttr {
-  let Spellings = [GNU<"type_tag_for_datatype">];
+  let Spellings = [Clang<"type_tag_for_datatype", 1>];
   let Args = [IdentifierArgument<"ArgumentKind">,
               TypeArgument<"MatchingCType">,
               BoolArgument<"LayoutCompatible">,

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=326052&r1=326051&r2=326052&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sun Feb 25 06:01:04 2018
@@ -420,6 +420,10 @@ unsigned Parser::ParseClangAttributeArgs
     ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
                                     ScopeName, ScopeLoc, Syntax);
     break;
+  case AttributeList::AT_TypeTagForDatatype:
+    ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                                     ScopeName, ScopeLoc, Syntax);
+    break;
   }
   return Attrs.getList() ? Attrs.getList()->getNumArgs() : 0;
 }

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=326052&r1=326051&r2=326052&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Sun Feb 25 06:01:04 2018
@@ -4554,17 +4554,6 @@ static void handleArgumentWithTypeTagAtt
     return;
   }
   
-  if (!checkAttributeNumArgs(S, AL, 3))
-    return;
-
-  IdentifierInfo *ArgumentKind = AL.getArgAsIdent(0)->Ident;
-
-  if (!isFunctionOrMethod(D) || !hasFunctionProto(D)) {
-    S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)
-      << AL.getName() << ExpectedFunctionOrMethod;
-    return;
-  }
-
   uint64_t ArgumentIdx;
   if (!checkFunctionOrMethodParameterIndex(S, D, AL, 2, AL.getArgAsExpr(1),
                                            ArgumentIdx))
@@ -4575,7 +4564,7 @@ static void handleArgumentWithTypeTagAtt
                                            TypeTagIdx))
     return;
 
-  bool IsPointer = (AL.getName()->getName() == "pointer_with_type_tag");
+  bool IsPointer = AL.getName()->getName() == "pointer_with_type_tag";
   if (IsPointer) {
     // Ensure that buffer has a pointer type.
     QualType BufferTy = getFunctionOrMethodParamType(D, ArgumentIdx);
@@ -4585,10 +4574,9 @@ static void handleArgumentWithTypeTagAtt
     }
   }
 
-  D->addAttr(::new (S.Context)
-             ArgumentWithTypeTagAttr(AL.getRange(), S.Context, ArgumentKind,
-                                     ArgumentIdx, TypeTagIdx, IsPointer,
-                                     AL.getAttributeSpellingListIndex()));
+  D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(
+      AL.getRange(), S.Context, AL.getArgAsIdent(0)->Ident, ArgumentIdx,
+      TypeTagIdx, IsPointer, AL.getAttributeSpellingListIndex()));
 }
 
 static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,

Added: cfe/trunk/test/Sema/attr-type-safety.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-type-safety.c?rev=326052&view=auto
==============================================================================
--- cfe/trunk/test/Sema/attr-type-safety.c (added)
+++ cfe/trunk/test/Sema/attr-type-safety.c Sun Feb 25 06:01:04 2018
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -fdouble-square-bracket-attributes -verify %s
+
+struct A {};
+
+typedef struct A *MPI_Datatype;
+
+extern struct A datatype_wrong1 [[clang::type_tag_for_datatype]]; // expected-error {{'type_tag_for_datatype' attribute requires parameter 1 to be an identifier}}
+
+extern struct A datatype_wrong2 [[clang::type_tag_for_datatype(mpi,1,2)]]; // expected-error {{expected a type}}
+
+extern struct A datatype_wrong3 [[clang::type_tag_for_datatype(mpi,not_a_type)]]; // expected-error {{unknown type name 'not_a_type'}}
+
+extern struct A datatype_wrong4 [[clang::type_tag_for_datatype(mpi,int,int)]]; // expected-error {{expected identifier}}
+
+extern struct A datatype_wrong5 [[clang::type_tag_for_datatype(mpi,int,not_a_flag)]]; // expected-error {{invalid comparison flag 'not_a_flag'}}
+
+extern struct A datatype_wrong6 [[clang::type_tag_for_datatype(mpi,int,layout_compatible,not_a_flag)]]; // expected-error {{invalid comparison flag 'not_a_flag'}}
+
+extern struct A A_tag [[clang::type_tag_for_datatype(a,int)]];
+extern struct A B_tag [[clang::type_tag_for_datatype(b,int)]];
+
+static const int C_tag [[clang::type_tag_for_datatype(c,int)]] = 10;
+static const int D_tag [[clang::type_tag_for_datatype(d,int)]] = 20;
+
+[[clang::pointer_with_type_tag]] // expected-error {{'pointer_with_type_tag' attribute requires exactly 3 arguments}}
+int wrong1(void *buf, MPI_Datatype datatype);
+
+[[clang::pointer_with_type_tag(mpi,0,7)]]  // expected-error {{attribute parameter 2 is out of bounds}}
+int wrong2(void *buf, MPI_Datatype datatype);
+
+[[clang::pointer_with_type_tag(mpi,3,7)]] // expected-error {{attribute parameter 2 is out of bounds}}
+int wrong3(void *buf, MPI_Datatype datatype);
+
+[[clang::pointer_with_type_tag(mpi,1,0)]] // expected-error {{attribute parameter 3 is out of bounds}}
+int wrong4(void *buf, MPI_Datatype datatype);
+
+[[clang::pointer_with_type_tag(mpi,1,3)]] // expected-error {{attribute parameter 3 is out of bounds}}
+int wrong5(void *buf, MPI_Datatype datatype);
+
+[[clang::pointer_with_type_tag(mpi,0x8000000000000001ULL,1)]] // expected-error {{attribute parameter 2 is out of bounds}}
+int wrong6(void *buf, MPI_Datatype datatype);
+
+[[clang::pointer_with_type_tag(a,1,2)]] void A_func(void *ptr, void *tag);
+[[clang::pointer_with_type_tag(c,1,2)]] void C_func(void *ptr, int tag);
+

Modified: cfe/trunk/test/Sema/warn-type-safety.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-type-safety.c?rev=326052&r1=326051&r2=326052&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-type-safety.c (original)
+++ cfe/trunk/test/Sema/warn-type-safety.c Sun Feb 25 06:01:04 2018
@@ -7,7 +7,7 @@ struct A {};
 typedef struct A *MPI_Datatype;
 
 int wrong1(void *buf, MPI_Datatype datatype)
-    __attribute__(( pointer_with_type_tag )); // expected-error {{'pointer_with_type_tag' attribute requires parameter 1 to be an identifier}}
+    __attribute__(( pointer_with_type_tag )); // expected-error {{'pointer_with_type_tag' attribute requires exactly 3 arguments}}
 
 int wrong2(void *buf, MPI_Datatype datatype)
     __attribute__(( pointer_with_type_tag(mpi,0,7) )); // expected-error {{attribute parameter 2 is out of bounds}}
@@ -32,7 +32,7 @@ int wrong7(void *buf, MPI_Datatype datat
 int wrong8(void *buf, MPI_Datatype datatype)
     __attribute__(( pointer_with_type_tag(mpi,1,x) )); // expected-error {{attribute requires parameter 3 to be an integer constant}}
 
-int wrong9 __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{attribute only applies to functions and methods}}
+int wrong9 __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{'pointer_with_type_tag' attribute only applies to non-K&R-style functions}}
 
 int wrong10(double buf, MPI_Datatype type)
     __attribute__(( pointer_with_type_tag(mpi,1,2) )); // expected-error {{'pointer_with_type_tag' attribute only applies to pointer arguments}}




More information about the cfe-commits mailing list