r204657 - Capability attributes can now be declared on a typedef declaration as well as a structure declaration. This allows for C code to use Boolean expressions on a capability as part of another attribute. Eg) __attribute__((requires_capability(!SomeCapability)))

Aaron Ballman aaron at aaronballman.com
Mon Mar 24 12:29:20 PDT 2014


Author: aaronballman
Date: Mon Mar 24 14:29:19 2014
New Revision: 204657

URL: http://llvm.org/viewvc/llvm-project?rev=204657&view=rev
Log:
Capability attributes can now be declared on a typedef declaration as well as a structure declaration. This allows for C code to use Boolean expressions on a capability as part of another attribute. Eg) __attribute__((requires_capability(!SomeCapability)))

Modified:
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/AttributeList.h
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/Sema/attr-capabilities.c
    cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=204657&r1=204656&r2=204657&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Mon Mar 24 14:29:19 2014
@@ -1302,7 +1302,8 @@ def Capability : InheritableAttr {
   let Spellings = [GNU<"capability">, CXX11<"clang", "capability">,
                    GNU<"shared_capability">,
                    CXX11<"clang", "shared_capability">];
-  let Subjects = SubjectList<[Struct], ErrorDiag, "ExpectedStruct">;
+  let Subjects = SubjectList<[Struct, TypedefName], ErrorDiag,
+                             "ExpectedStructOrTypedef">;
   let Args = [StringArgument<"Name">];
   let Accessors = [Accessor<"isShared",
                     [GNU<"shared_capability">,

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=204657&r1=204656&r2=204657&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Mar 24 14:29:19 2014
@@ -2102,7 +2102,7 @@ def warn_attribute_wrong_decl_type : War
   "struct or union|struct, union or class|types|"
   "Objective-C instance methods|init methods of interface or class extension declarations|"
   "variables, functions and classes|Objective-C protocols|"
-  "functions and global variables}1">,
+  "functions and global variables|structs or typedefs}1">,
   InGroup<IgnoredAttributes>;
 def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
 def warn_type_attribute_wrong_type : Warning<
@@ -2180,10 +2180,6 @@ def warn_thread_attribute_argument_not_l
   "%0 attribute requires arguments whose type is annotated "
   "with 'capability' attribute; type here is %1">,
   InGroup<ThreadSafetyAttributes>, DefaultIgnore;
-def warn_thread_attribute_argument_not_class : Warning<
-  "%0 attribute requires arguments that are class type or point to"
-  " class type; type here is %1">,
-  InGroup<ThreadSafetyAttributes>, DefaultIgnore;  
 def warn_thread_attribute_decl_not_lockable : Warning<
   "%0 attribute can only be applied in a context annotated "
   "with 'capability(\"mutex\")' attribute">,

Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=204657&r1=204656&r2=204657&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Mon Mar 24 14:29:19 2014
@@ -838,7 +838,8 @@ enum AttributeDeclKind {
   ExpectedObjCInterfaceDeclInitMethod,
   ExpectedFunctionVariableOrClass,
   ExpectedObjectiveCProtocol,
-  ExpectedFunctionGlobalVarMethodOrProperty
+  ExpectedFunctionGlobalVarMethodOrProperty,
+  ExpectedStructOrTypedef
 };
 
 }  // end namespace clang

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=204657&r1=204656&r2=204657&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Mar 24 14:29:19 2014
@@ -363,63 +363,78 @@ static const RecordType *getRecordType(Q
   return 0;
 }
 
-
-static bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier,
-                                             CXXBasePath &Path, void *Unused) {
-  const RecordType *RT = Specifier->getType()->getAs<RecordType>();
-  return RT->getDecl()->hasAttr<CapabilityAttr>();
-}
-
-
-/// \brief Thread Safety Analysis: Checks that the passed in RecordType
-/// resolves to a lockable object.
-static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr,
-                                   QualType Ty) {
+static bool checkRecordTypeForCapability(Sema &S, const AttributeList &Attr,
+                                         QualType Ty) {
   const RecordType *RT = getRecordType(Ty);
 
-  // Warn if could not get record type for this argument.
-  if (!RT) {
-    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
-      << Attr.getName() << Ty;
-    return;
-  }
+  if (!RT)
+    return false;
 
-  // Don't check for lockable if the class hasn't been defined yet.
+  // Don't check for the capability if the class hasn't been defined yet.
   if (RT->isIncompleteType())
-    return;
+    return true;
 
-  // Allow smart pointers to be used as lockable objects.
+  // Allow smart pointers to be used as capability objects.
   // FIXME -- Check the type that the smart pointer points to.
   if (threadSafetyCheckIsSmartPointer(S, RT))
-    return;
+    return true;
 
-  // Check if the type is lockable.
+  // Check if the record itself has a capability.
   RecordDecl *RD = RT->getDecl();
   if (RD->hasAttr<CapabilityAttr>())
-    return;
+    return true;
 
-  // Else check if any base classes are lockable.
+  // Else check if any base classes have a capability.
   if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
     CXXBasePaths BPaths(false, false);
-    if (CRD->lookupInBases(checkBaseClassIsLockableCallback, 0, BPaths))
-      return;
+    if (CRD->lookupInBases([](const CXXBaseSpecifier *BS, CXXBasePath &P,
+      void *) {
+      return BS->getType()->getAs<RecordType>()
+        ->getDecl()->hasAttr<CapabilityAttr>();
+    }, 0, BPaths))
+      return true;
   }
+  return false;
+}
+
+static bool checkTypedefTypeForCapability(Sema &S, const AttributeList &Attr,
+                                          QualType Ty) {
+  const auto *TD = Ty->getAs<TypedefType>();
+  if (!TD)
+    return false;
+
+  TypedefNameDecl *TN = TD->getDecl();
+  if (!TN)
+    return false;
+
+  return TN->hasAttr<CapabilityAttr>();
+}
+
+/// \brief Checks that the passed in type is qualified as a capability. This
+/// type can either be a struct, or a typedef to a built-in type (such as int).
+static void checkForCapability(Sema &S, const AttributeList &Attr,
+                               QualType Ty) {
+  if (checkTypedefTypeForCapability(S, Attr, Ty))
+    return;
+
+  if (checkRecordTypeForCapability(S, Attr, Ty))
+    return;
 
   S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
     << Attr.getName() << Ty;
 }
 
-/// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
-/// from Sidx, resolve to a lockable object.
+/// \brief Checks that all attribute arguments, starting from Sidx, resolve to
+/// a capability object.
 /// \param Sidx The attribute argument index to start checking with.
 /// \param ParamIdxOk Whether an argument can be indexing into a function
 /// parameter list.
-static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
-                                         const AttributeList &Attr,
-                                         SmallVectorImpl<Expr*> &Args,
-                                         int Sidx = 0,
-                                         bool ParamIdxOk = false) {
-  for(unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
+static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
+                                           const AttributeList &Attr,
+                                           SmallVectorImpl<Expr *> &Args,
+                                           int Sidx = 0,
+                                           bool ParamIdxOk = false) {
+  for (unsigned Idx = Sidx; Idx < Attr.getNumArgs(); ++Idx) {
     Expr *ArgExp = Attr.getArgAsExpr(Idx);
 
     if (ArgExp->isTypeDependent()) {
@@ -455,7 +470,7 @@ static void checkAttrArgsAreLockableObjs
           if (DRE->getDecl()->isCXXInstanceMember())
             ArgTy = DRE->getDecl()->getType();
 
-    // First see if we can just cast to record type, or point to record type.
+    // First see if we can just cast to record type, or pointer to record type.
     const RecordType *RT = getRecordType(ArgTy);
 
     // Now check if we index into a record type function param.
@@ -476,7 +491,7 @@ static void checkAttrArgsAreLockableObjs
       }
     }
 
-    checkForLockableRecord(S, D, Attr, ArgTy);
+    checkForCapability(S, Attr, ArgTy);
 
     Args.push_back(ArgExp);
   }
@@ -505,7 +520,7 @@ static bool checkGuardedByAttrCommon(Sem
                                      Expr* &Arg) {
   SmallVector<Expr*, 1> Args;
   // check that all arguments are lockable objects
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
   if (Size != 1)
     return false;
@@ -556,7 +571,7 @@ static bool checkAcquireOrderAttrCommon(
   }
 
   // Check that all arguments are lockable objects.
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   if (Args.empty())
     return false;
 
@@ -594,7 +609,7 @@ static bool checkLockFunAttrCommon(Sema
                                    SmallVectorImpl<Expr *> &Args) {
   // zero or more arguments ok
   // check that all arguments are lockable objects
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
 
   return true;
 }
@@ -640,7 +655,7 @@ static bool checkTryLockFunAttrCommon(Se
   }
 
   // check that all arguments are lockable objects
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 1);
 
   return true;
 }
@@ -675,7 +690,7 @@ static void handleLockReturnedAttr(Sema
                                    const AttributeList &Attr) {
   // check that the argument is lockable object
   SmallVector<Expr*, 1> Args;
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
   if (Size == 0)
     return;
@@ -692,7 +707,7 @@ static void handleLocksExcludedAttr(Sema
 
   // check that all arguments are lockable objects
   SmallVector<Expr*, 1> Args;
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
   if (Size == 0)
     return;
@@ -3898,7 +3913,7 @@ static void handleReleaseCapabilityAttr(
                                         const AttributeList &Attr) {
   // Check that all arguments are lockable objects.
   SmallVector<Expr *, 1> Args;
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, true);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args, 0, true);
 
   D->addAttr(::new (S.Context) ReleaseCapabilityAttr(
       Attr.getRange(), S.Context, Args.data(), Args.size(),
@@ -3912,7 +3927,7 @@ static void handleRequiresCapabilityAttr
 
   // check that all arguments are lockable objects
   SmallVector<Expr*, 1> Args;
-  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  checkAttrArgsAreCapabilityObjs(S, D, Attr, Args);
   if (Args.empty())
     return;
 

Modified: cfe/trunk/test/Sema/attr-capabilities.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-capabilities.c?rev=204657&r1=204656&r2=204657&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-capabilities.c (original)
+++ cfe/trunk/test/Sema/attr-capabilities.c Mon Mar 24 14:29:19 2014
@@ -1,14 +1,14 @@
 // RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s
 
-struct __attribute__((capability("role"))) ThreadRole {};
+typedef int __attribute__((capability("role"))) ThreadRole;
 struct __attribute__((shared_capability("mutex"))) Mutex {};
 struct NotACapability {};
 
 // Test an invalid capability name
 struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}}
 
-int Test1 __attribute__((capability("test1")));  // expected-error {{'capability' attribute only applies to structs}}
-int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs}}
+int Test1 __attribute__((capability("test1")));  // expected-error {{'capability' attribute only applies to structs or typedefs}}
+int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs or typedefs}}
 int Test3 __attribute__((acquire_capability("test3")));  // expected-warning {{'acquire_capability' attribute only applies to functions}}
 int Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}}
 int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}}
@@ -20,14 +20,14 @@ struct __attribute__((capability)) Test5
 struct __attribute__((shared_capability("test1", 12))) Test6 {}; // expected-error {{'shared_capability' attribute takes one argument}}
 
 struct NotACapability BadCapability;
-struct ThreadRole GUI, Worker;
+ThreadRole GUI, Worker;
 void Func1(void) __attribute__((requires_capability(GUI))) {}
 void Func2(void) __attribute__((requires_shared_capability(Worker))) {}
 
 void Func3(void) __attribute__((requires_capability)) {}  // expected-error {{'requires_capability' attribute takes at least 1 argument}}
 void Func4(void) __attribute__((requires_shared_capability)) {}  // expected-error {{'requires_shared_capability' attribute takes at least 1 argument}}
 
-void Func5(void) __attribute__((requires_capability(1))) {}  // expected-warning {{'requires_capability' attribute requires arguments that are class type or point to class type}}
+void Func5(void) __attribute__((requires_capability(1))) {}  // expected-warning {{'requires_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 void Func6(void) __attribute__((requires_shared_capability(BadCapability))) {}  // expected-warning {{'requires_shared_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'struct NotACapability'}}
 
 void Func7(void) __attribute__((assert_capability(GUI))) {}

Modified: cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp?rev=204657&r1=204656&r2=204657&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp Mon Mar 24 14:29:19 2014
@@ -353,11 +353,11 @@ int gb_var_arg_8 GUARDED_BY(muPointer);
 
 // illegal attribute arguments
 int gb_var_arg_bad_1 GUARDED_BY(1); // \
-  // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}}
+  // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int gb_var_arg_bad_2 GUARDED_BY("mu"); // \
   // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
 int gb_var_arg_bad_3 GUARDED_BY(muDoublePointer); // \
-  // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'Mutex **'}}
+  // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int gb_var_arg_bad_4 GUARDED_BY(umu); // \
   // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'UnlockableMu'}}
 
@@ -424,11 +424,11 @@ int * pgb_var_arg_8 PT_GUARDED_BY(muPoin
 
 // illegal attribute arguments
 int * pgb_var_arg_bad_1 PT_GUARDED_BY(1); // \
-  // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \
   // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
 int * pgb_var_arg_bad_3 PT_GUARDED_BY(muDoublePointer); // \
-  // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \
   // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -485,11 +485,11 @@ Mutex aa_var_arg_8 ACQUIRED_AFTER(muPoin
 
 // illegal attribute arguments
 Mutex aa_var_arg_bad_1 ACQUIRED_AFTER(1); // \
-  // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \
   // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
 Mutex aa_var_arg_bad_3 ACQUIRED_AFTER(muDoublePointer); // \
-  // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \
   // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute}}
 UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \
@@ -548,11 +548,11 @@ Mutex ab_var_arg_8 ACQUIRED_BEFORE(muPoi
 
 // illegal attribute arguments
 Mutex ab_var_arg_bad_1 ACQUIRED_BEFORE(1); // \
-  // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \
   // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
 Mutex ab_var_arg_bad_3 ACQUIRED_BEFORE(muDoublePointer); // \
-  // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \
   // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute}}
 UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \
@@ -617,7 +617,7 @@ int elf_function_9(Mutex x, Mutex y) EXC
 int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \
   // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
 int elf_function_bad_3() EXCLUSIVE_LOCK_FUNCTION(muDoublePointer); // \
-  // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \
   // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -689,7 +689,7 @@ int slf_function_9(Mutex x, Mutex y) SHA
 int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \
   // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
 int slf_function_bad_3() SHARED_LOCK_FUNCTION(muDoublePointer); // \
-  // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \
   // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -771,7 +771,7 @@ int etf_function_bad_3() EXCLUSIVE_TRYLO
 int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \
   // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
 int etf_function_bad_5() EXCLUSIVE_TRYLOCK_FUNCTION(1, muDoublePointer); // \
-  // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \
   // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -845,7 +845,7 @@ int stf_function_bad_3() SHARED_TRYLOCK_
 int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \
   // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
 int stf_function_bad_5() SHARED_TRYLOCK_FUNCTION(1, muDoublePointer); // \
-  // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \
   // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -908,7 +908,7 @@ int uf_function_9(Mutex x, Mutex y) UNLO
 int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \
   // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
 int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \
-  // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \
   // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -980,11 +980,11 @@ int lr_function_8() LOCK_RETURNED(muPoin
 
 // illegal attribute arguments
 int lr_function_bad_1() LOCK_RETURNED(1); // \
-  // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int lr_function_bad_2() LOCK_RETURNED("mu"); // \
   // expected-warning {{ignoring 'lock_returned' attribute because its argument is invalid}}
 int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \
-  // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int lr_function_bad_4() LOCK_RETURNED(umu); // \
   // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -1047,11 +1047,11 @@ int le_function_8() LOCKS_EXCLUDED(muPoi
 
 // illegal attribute arguments
 int le_function_bad_1() LOCKS_EXCLUDED(1); // \
-  // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \
   // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
 int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \
-  // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int le_function_bad_4() LOCKS_EXCLUDED(umu); // \
   // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -1114,11 +1114,11 @@ int elr_function_8() EXCLUSIVE_LOCKS_REQ
 
 // illegal attribute arguments
 int elr_function_bad_1() EXCLUSIVE_LOCKS_REQUIRED(1); // \
-  // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \
   // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
 int elr_function_bad_3() EXCLUSIVE_LOCKS_REQUIRED(muDoublePointer); // \
-  // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \
   // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}
 
@@ -1182,11 +1182,11 @@ int slr_function_8() SHARED_LOCKS_REQUIR
 
 // illegal attribute arguments
 int slr_function_bad_1() SHARED_LOCKS_REQUIRED(1); // \
-  // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
 int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \
   // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
 int slr_function_bad_3() SHARED_LOCKS_REQUIRED(muDoublePointer); // \
-  // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'Mutex **'}}
 int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \
   // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}}
 





More information about the cfe-commits mailing list