[cfe-commits] r155129 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclAttr.cpp test/SemaCXX/warn-thread-safety-parsing.cpp

DeLesley Hutchins delesley at google.com
Thu Apr 19 09:10:44 PDT 2012


Author: delesley
Date: Thu Apr 19 11:10:44 2012
New Revision: 155129

URL: http://llvm.org/viewvc/llvm-project?rev=155129&view=rev
Log:
Thread safety analysis: split warnings into two groups: attribute warnings
which are checked in the parser, and analysis warnings that require the
full analysis.  This allows attribute syntax to be checked independently
of the full thread safety analysis.  Also introduces a new warning for the
case where a string is used as a lock expression; this allows the analysis
to gracefully handle expressions that would otherwise cause a parse error.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=155129&r1=155128&r2=155129&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Thu Apr 19 11:10:44 2012
@@ -354,7 +354,10 @@
  ]>;
 
 // Thread Safety warnings 
-def ThreadSafety : DiagGroup<"thread-safety">;
+def ThreadSafetyAttributes : DiagGroup<"thread-safety-attributes">;
+def ThreadSafetyAnalysis : DiagGroup<"thread-safety-analysis">;
+def ThreadSafety : DiagGroup<"thread-safety", 
+                             [ThreadSafetyAttributes, ThreadSafetyAnalysis]>;
 
 // Note that putting warnings in -Wall will not disable them by default. If a
 // warning should be active _only_ when -Wall is passed in, mark it as

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=155129&r1=155128&r2=155129&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Apr 19 11:10:44 2012
@@ -1656,72 +1656,79 @@
   "attribute ignored">;
   
 // Thread Safety Attributes
-// Errors when parsing the attributes
+def warn_thread_attribute_ignored : Warning<
+  "ignoring %0 attribute because its argument is invalid">,
+  InGroup<ThreadSafetyAttributes>, DefaultIgnore;
+def warn_thread_attribute_argument_not_lockable : Warning<
+  "%0 attribute requires arguments whose type is annotated "
+  "with 'lockable' 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 'lockable' attribute">,
+  InGroup<ThreadSafetyAttributes>, DefaultIgnore;
+def warn_thread_attribute_decl_not_pointer : Warning<
+  "'%0' only applies to pointer types; type here is %1">,
+  InGroup<ThreadSafetyAttributes>, DefaultIgnore;
 def err_attribute_argument_out_of_range : Error<
   "%0 attribute parameter %1 is out of bounds: "
   "%plural{0:no parameters to index into|"
   "1:can only be 1, since there is one parameter|"
   ":must be between 1 and %2}2">;
-def warn_attribute_argument_not_lockable : Warning<
-  "%0 attribute requires arguments whose type is annotated "
-  "with 'lockable' attribute; type here is '%1'">,
-  InGroup<ThreadSafety>, DefaultIgnore;
-def warn_attribute_decl_not_lockable : Warning<
-  "%0 attribute can only be applied in a context annotated "
-  "with 'lockable' attribute">,
-  InGroup<ThreadSafety>, DefaultIgnore;
-def warn_attribute_argument_not_class : Warning<
-  "%0 attribute requires arguments that are class type or point to"
-  " class type; type here is '%1'">,
-  InGroup<ThreadSafety>, DefaultIgnore;   
+
+// Thread Safety Analysis   
 def warn_unlock_but_no_lock : Warning<
   "unlocking '%0' that was not locked">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_double_lock : Warning<
   "locking '%0' that is already locked">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_no_unlock : Warning<
   "mutex '%0' is still locked at the end of function">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 // FIXME: improve the error message about locks not in scope
 def warn_lock_some_predecessors : Warning<
   "mutex '%0' is not locked on every path through here">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_expecting_lock_held_on_loop : Warning<
   "expecting mutex '%0' to be locked at start of each loop">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def note_locked_here : Note<"mutex acquired here">;
 def warn_lock_exclusive_and_shared : Warning<
   "mutex '%0' is locked exclusively and shared in the same scope">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def note_lock_exclusive_and_shared : Note<
   "the other lock of mutex '%0' is here">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_variable_requires_lock : Warning<
   "%select{reading|writing}2 variable '%0' requires locking "
   "%select{'%1'|'%1' exclusively}2">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_var_deref_requires_lock : Warning<
   "%select{reading|writing}2 the value pointed to by '%0' requires locking "
   "%select{'%1'|'%1' exclusively}2">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_variable_requires_any_lock : Warning<
   "%select{reading|writing}1 variable '%0' requires locking "
   "%select{any mutex|any mutex exclusively}1">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_var_deref_requires_any_lock : Warning<
   "%select{reading|writing}1 the value pointed to by '%0' requires locking "
   "%select{any mutex|any mutex exclusively}1">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_fun_requires_lock : Warning<
   "calling function '%0' requires %select{shared|exclusive}2 lock on '%1'">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_fun_excludes_mutex : Warning<
   "cannot call function '%0' while mutex '%1' is locked">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 def warn_cannot_resolve_lock : Warning<
   "cannot resolve lock expression">,
-  InGroup<ThreadSafety>, DefaultIgnore;
+  InGroup<ThreadSafetyAnalysis>, DefaultIgnore;
 
 
 def warn_impcast_vector_scalar : Warning<

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=155129&r1=155128&r2=155129&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Apr 19 11:10:44 2012
@@ -243,12 +243,13 @@
 /// Note that this function may produce an error message.
 /// \return true if the Decl is a pointer type; false otherwise
 ///
-static bool checkIsPointer(Sema &S, const Decl *D, const AttributeList &Attr) {
+static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
+                                       const AttributeList &Attr) {
   if (const ValueDecl *vd = dyn_cast<ValueDecl>(D)) {
     QualType QT = vd->getType();
     if (QT->isAnyPointerType())
       return true;
-    S.Diag(Attr.getLoc(), diag::warn_pointer_attribute_wrong_type)
+    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_pointer)
       << Attr.getName()->getName() << QT;
   } else {
     S.Diag(Attr.getLoc(), diag::err_attribute_can_be_applied_only_to_value_decl)
@@ -271,14 +272,14 @@
 }
 
 /// \brief Thread Safety Analysis: Checks that the passed in RecordType
-/// resolves to a lockable object. May flag an error.
+/// resolves to a lockable object.
 static void checkForLockableRecord(Sema &S, Decl *D, 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_attribute_argument_not_class)
+    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_class)
       << Attr.getName() << Ty.getAsString();
     return;
   }
@@ -287,18 +288,18 @@
     return;
   // Warn if the type is not lockable.
   if (!RT->getDecl()->getAttr<LockableAttr>()) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_argument_not_lockable)
+    S.Diag(Attr.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
       << Attr.getName() << Ty.getAsString();
     return;
   }
 }
 
 /// \brief Thread Safety Analysis: Checks that all attribute arguments, starting
-/// from Sidx, resolve to a lockable object. May flag an error.
+/// from Sidx, resolve to a lockable 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 bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
+static void checkAttrArgsAreLockableObjs(Sema &S, Decl *D,
                                          const AttributeList &Attr,
                                          SmallVectorImpl<Expr*> &Args,
                                          int Sidx = 0,
@@ -307,11 +308,19 @@
     Expr *ArgExp = Attr.getArg(Idx);
 
     if (ArgExp->isTypeDependent()) {
-      // FIXME -- need to processs this again on template instantiation
+      // FIXME -- need to check this again on template instantiation
       Args.push_back(ArgExp);
       continue;
     }
 
+    if (isa<StringLiteral>(ArgExp)) {
+      // We allow constant strings to be used as a placeholder for expressions
+      // that are not valid C++ syntax, but warn that they are ignored.
+      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_ignored) <<
+        Attr.getName();
+      continue;
+    }
+
     QualType ArgTy = ArgExp->getType();
 
     // First see if we can just cast to record type, or point to record type.
@@ -329,7 +338,7 @@
         if(!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
           S.Diag(Attr.getLoc(), diag::err_attribute_argument_out_of_range)
             << Attr.getName() << Idx + 1 << NumParams;
-          return false;
+          continue;
         }
         ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
       }
@@ -339,7 +348,6 @@
 
     Args.push_back(ArgExp);
   }
-  return true;
 }
 
 //===----------------------------------------------------------------------===//
@@ -364,7 +372,7 @@
     return;
   }
 
-  if (pointer && !checkIsPointer(S, D, Attr))
+  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
     return;
 
   if (pointer)
@@ -380,8 +388,6 @@
   if (!checkAttributeNumArgs(S, Attr, 1))
     return;
 
-  Expr *Arg = Attr.getArg(0);
-
   // D must be either a member field or global (potentially shared) variable.
   if (!mayBeSharedVariable(D)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
@@ -389,12 +395,16 @@
     return;
   }
 
-  if (pointer && !checkIsPointer(S, D, Attr))
+  if (pointer && !threadSafetyCheckIsPointer(S, D, Attr))
     return;
 
-  if (!Arg->isTypeDependent()) {
-    checkForLockableRecord(S, D, Attr, Arg->getType());
-  }
+  SmallVector<Expr*, 1> Args;
+  // check that all arguments are lockable objects
+  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
+  unsigned Size = Args.size();
+  if (Size != 1)
+    return;
+  Expr *Arg = Args[0];
 
   if (pointer)
     D->addAttr(::new (S.Context) PtGuardedByAttr(Attr.getRange(),
@@ -442,7 +452,7 @@
 }
 
 static void handleNoAddressSafetyAttr(Sema &S, Decl *D,
-                                     const AttributeList &Attr) {
+                                      const AttributeList &Attr) {
   assert(!Attr.isInvalid());
 
   if (!checkAttributeNumArgs(S, Attr, 0))
@@ -473,25 +483,24 @@
     return;
   }
 
-  // Check that this attribute only applies to lockable types
+  // Check that this attribute only applies to lockable types.
   QualType QT = VD->getType();
   if (!QT->isDependentType()) {
     const RecordType *RT = getRecordType(QT);
     if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
-      S.Diag(Attr.getLoc(), diag::warn_attribute_decl_not_lockable)
+      S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable)
               << Attr.getName();
       return;
     }
   }
 
   SmallVector<Expr*, 1> Args;
-  // check that all arguments are lockable objects
-  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
-    return;
-
+  // Check that all arguments are lockable objects.
+  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
-  assert(Size == Attr.getNumArgs());
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
+  if (Size == 0)
+    return;
+  Expr **StartArg = &Args[0];
 
   if (before)
     D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
@@ -516,11 +525,8 @@
 
   // check that all arguments are lockable objects
   SmallVector<Expr*, 1> Args;
-  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
-    return;
-
+  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
   unsigned Size = Args.size();
-  assert(Size == Attr.getNumArgs());
   Expr **StartArg = Size == 0 ? 0 : &Args[0];
 
   if (exclusive)
@@ -540,7 +546,6 @@
   if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
     return;
 
-
   if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D)) {
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << ExpectedFunctionOrMethod;
@@ -555,9 +560,7 @@
 
   SmallVector<Expr*, 2> Args;
   // check that all arguments are lockable objects
-  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1))
-    return;
-
+  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 1);
   unsigned Size = Args.size();
   Expr **StartArg = Size == 0 ? 0 : &Args[0];
 
@@ -588,12 +591,11 @@
 
   // check that all arguments are lockable objects
   SmallVector<Expr*, 1> Args;
-  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
-    return;
-
+  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
-  assert(Size == Attr.getNumArgs());
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
+  if (Size == 0)
+    return;
+  Expr **StartArg = &Args[0];
 
   if (exclusive)
     D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
@@ -619,11 +621,8 @@
 
   // check that all arguments are lockable objects
   SmallVector<Expr*, 1> Args;
-  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true))
-    return;
-
+  checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
   unsigned Size = Args.size();
-  assert(Size == Attr.getNumArgs());
   Expr **StartArg = Size == 0 ? 0 : &Args[0];
 
   D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
@@ -668,12 +667,11 @@
 
   // check that all arguments are lockable objects
   SmallVector<Expr*, 1> Args;
-  if (!checkAttrArgsAreLockableObjs(S, D, Attr, Args))
-    return;
-
+  checkAttrArgsAreLockableObjs(S, D, Attr, Args);
   unsigned Size = Args.size();
-  assert(Size == Attr.getNumArgs());
-  Expr **StartArg = Size == 0 ? 0 : &Args[0];
+  if (Size == 0)
+    return;
+  Expr **StartArg = &Args[0];
 
   D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
                                                  StartArg, Size));

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=155129&r1=155128&r2=155129&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-thread-safety-parsing.cpp Thu Apr 19 11:10:44 2012
@@ -343,7 +343,7 @@
 int gb_var_arg_bad_1 __attribute__((guarded_by(1))); // \
   // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'int'}}
 int gb_var_arg_bad_2 __attribute__((guarded_by("mu"))); // \
-  // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'const char [3]'}}
+  // expected-warning {{ignoring 'guarded_by' attribute because its argument is invalid}}
 int gb_var_arg_bad_3 __attribute__((guarded_by(muDoublePointer))); // \
   // expected-warning {{'guarded_by' attribute requires arguments that are class type or point to class type; type here is 'class Mu **'}}
 int gb_var_arg_bad_4 __attribute__((guarded_by(umu))); // \
@@ -414,7 +414,7 @@
 int * pgb_var_arg_bad_1 __attribute__((pt_guarded_by(1))); // \
   // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
 int * pgb_var_arg_bad_2 __attribute__((pt_guarded_by("mu"))); // \
-  // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'pt_guarded_by' attribute because its argument is invalid}}
 int * pgb_var_arg_bad_3 __attribute__((pt_guarded_by(muDoublePointer))); // \
   // expected-warning {{'pt_guarded_by' attribute requires arguments that are class type or point to class type}}
 int * pgb_var_arg_bad_4 __attribute__((pt_guarded_by(umu))); // \
@@ -475,7 +475,7 @@
 Mu aa_var_arg_bad_1 __attribute__((acquired_after(1))); // \
   // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
 Mu aa_var_arg_bad_2 __attribute__((acquired_after("mu"))); // \
-  // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'acquired_after' attribute because its argument is invalid}}
 Mu aa_var_arg_bad_3 __attribute__((acquired_after(muDoublePointer))); // \
   // expected-warning {{'acquired_after' attribute requires arguments that are class type or point to class type}}
 Mu aa_var_arg_bad_4 __attribute__((acquired_after(umu))); // \
@@ -538,7 +538,7 @@
 Mu ab_var_arg_bad_1 __attribute__((acquired_before(1))); // \
   // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
 Mu ab_var_arg_bad_2 __attribute__((acquired_before("mu"))); // \
-  // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'acquired_before' attribute because its argument is invalid}}
 Mu ab_var_arg_bad_3 __attribute__((acquired_before(muDoublePointer))); // \
   // expected-warning {{'acquired_before' attribute requires arguments that are class type or point to class type}}
 Mu ab_var_arg_bad_4 __attribute__((acquired_before(umu))); // \
@@ -603,7 +603,7 @@
 
 // illegal attribute arguments
 int elf_function_bad_2() __attribute__((exclusive_lock_function("mu"))); // \
-  // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'exclusive_lock_function' attribute because its argument is invalid}}
 int elf_function_bad_3() __attribute__((exclusive_lock_function(muDoublePointer))); // \
   // expected-warning {{'exclusive_lock_function' attribute requires arguments that are class type or point to class type}}
 int elf_function_bad_4() __attribute__((exclusive_lock_function(umu))); // \
@@ -675,7 +675,7 @@
 
 // illegal attribute arguments
 int slf_function_bad_2() __attribute__((shared_lock_function("mu"))); // \
-  // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'shared_lock_function' attribute because its argument is invalid}}
 int slf_function_bad_3() __attribute__((shared_lock_function(muDoublePointer))); // \
   // expected-warning {{'shared_lock_function' attribute requires arguments that are class type or point to class type}}
 int slf_function_bad_4() __attribute__((shared_lock_function(umu))); // \
@@ -757,7 +757,7 @@
   // expected-error {{'exclusive_trylock_function' attribute first argument must be of int or bool type}}
 
 int etf_function_bad_4() __attribute__((exclusive_trylock_function(1, "mu"))); // \
-  // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'exclusive_trylock_function' attribute because its argument is invalid}}
 int etf_function_bad_5() __attribute__((exclusive_trylock_function(1, muDoublePointer))); // \
   // expected-warning {{'exclusive_trylock_function' attribute requires arguments that are class type or point to class type}}
 int etf_function_bad_6() __attribute__((exclusive_trylock_function(1, umu))); // \
@@ -831,7 +831,7 @@
   // expected-error {{'shared_trylock_function' attribute first argument must be of int or bool type}}
 
 int stf_function_bad_4() __attribute__((shared_trylock_function(1, "mu"))); // \
-  // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'shared_trylock_function' attribute because its argument is invalid}}
 int stf_function_bad_5() __attribute__((shared_trylock_function(1, muDoublePointer))); // \
   // expected-warning {{'shared_trylock_function' attribute requires arguments that are class type or point to class type}}
 int stf_function_bad_6() __attribute__((shared_trylock_function(1, umu))); // \
@@ -894,7 +894,7 @@
 
 // illegal attribute arguments
 int uf_function_bad_2() __attribute__((unlock_function("mu"))); // \
-  // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'unlock_function' attribute because its argument is invalid}}
 int uf_function_bad_3() __attribute__((unlock_function(muDoublePointer))); // \
   // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}}
 int uf_function_bad_4() __attribute__((unlock_function(umu))); // \
@@ -1037,7 +1037,7 @@
 int le_function_bad_1() __attribute__((locks_excluded(1))); // \
   // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
 int le_function_bad_2() __attribute__((locks_excluded("mu"))); // \
-  // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'locks_excluded' attribute because its argument is invalid}}
 int le_function_bad_3() __attribute__((locks_excluded(muDoublePointer))); // \
   // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}}
 int le_function_bad_4() __attribute__((locks_excluded(umu))); // \
@@ -1104,7 +1104,7 @@
 int elr_function_bad_1() __attribute__((exclusive_locks_required(1))); // \
   // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
 int elr_function_bad_2() __attribute__((exclusive_locks_required("mu"))); // \
-  // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'exclusive_locks_required' attribute because its argument is invalid}}
 int elr_function_bad_3() __attribute__((exclusive_locks_required(muDoublePointer))); // \
   // expected-warning {{'exclusive_locks_required' attribute requires arguments that are class type or point to class type}}
 int elr_function_bad_4() __attribute__((exclusive_locks_required(umu))); // \
@@ -1172,7 +1172,7 @@
 int slr_function_bad_1() __attribute__((shared_locks_required(1))); // \
   // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
 int slr_function_bad_2() __attribute__((shared_locks_required("mu"))); // \
-  // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
+  // expected-warning {{ignoring 'shared_locks_required' attribute because its argument is invalid}}
 int slr_function_bad_3() __attribute__((shared_locks_required(muDoublePointer))); // \
   // expected-warning {{'shared_locks_required' attribute requires arguments that are class type or point to class type}}
 int slr_function_bad_4() __attribute__((shared_locks_required(umu))); // \





More information about the cfe-commits mailing list