diff options
-rw-r--r-- | include/clang/Basic/DiagnosticGroups.td | 5 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 61 | ||||
-rw-r--r-- | lib/Sema/SemaDeclAttr.cpp | 94 | ||||
-rw-r--r-- | test/SemaCXX/warn-thread-safety-parsing.cpp | 24 |
4 files changed, 96 insertions, 88 deletions
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index c83985345b..3f6c5c0c0d 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -354,7 +354,10 @@ def Most : DiagGroup<"most", [ ]>; // 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 diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index d972774628..986479921d 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1656,72 +1656,79 @@ def warn_availability_version_ordering : Warning< "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< diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 5c6ddd2cb9..3770b3c373 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -243,12 +243,13 @@ static bool isIntOrBool(Expr *Exp) { /// 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 @@ static const RecordType *getRecordType(QualType QT) { } /// \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 @@ static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, 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 @@ static bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 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 @@ static bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D, 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 @@ static bool checkAttrArgsAreLockableObjs(Sema &S, Decl *D, Args.push_back(ArgExp); } - return true; } //===----------------------------------------------------------------------===// @@ -364,7 +372,7 @@ static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr, return; } - if (pointer && !checkIsPointer(S, D, Attr)) + if (pointer && !threadSafetyCheckIsPointer(S, D, Attr)) return; if (pointer) @@ -380,8 +388,6 @@ static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 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 @@ static void handleGuardedByAttr(Sema &S, Decl *D, const AttributeList &Attr, 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 handleNoThreadSafetyAttr(Sema &S, Decl *D, } 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 @@ static void handleAcquireOrderAttr(Sema &S, Decl *D, const AttributeList &Attr, 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 @@ static void handleLockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, // 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 @@ static void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 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 @@ static void handleTrylockFunAttr(Sema &S, Decl *D, const AttributeList &Attr, 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 @@ static void handleLocksRequiredAttr(Sema &S, Decl *D, const AttributeList &Attr, // 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 @@ static void handleUnlockFunAttr(Sema &S, Decl *D, // 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 @@ static void handleLocksExcludedAttr(Sema &S, Decl *D, // 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)); diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp index c2fa1d77a0..a9e58dd872 100644 --- a/test/SemaCXX/warn-thread-safety-parsing.cpp +++ b/test/SemaCXX/warn-thread-safety-parsing.cpp @@ -343,7 +343,7 @@ int gb_var_arg_8 __attribute__((guarded_by(muPointer))); 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_8 __attribute__((pt_guarded_by(muPointer))); 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_8 __attribute__((acquired_after(muPointer))); 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_8 __attribute__((acquired_before(muPointer))); 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 @@ int elf_function_9(Mu x, Mu y) __attribute__((exclusive_lock_function(1,2))); // 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 @@ int slf_function_9(Mu x, Mu y) __attribute__((shared_lock_function(1,2))); // 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 @@ int etf_function_bad_3() __attribute__((exclusive_trylock_function(muDoublePoint // 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 @@ int stf_function_bad_3() __attribute__((shared_trylock_function(muDoublePointer) // 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 @@ int uf_function_9(Mu x, Mu y) __attribute__((unlock_function(1,2))); // 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_8() __attribute__((locks_excluded(muPointer))); 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_8() __attribute__((exclusive_locks_required(muPointer))); 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_8() __attribute__((shared_locks_required(muPointer))); 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))); // \ |