From 0894e597485f694a19b21db3e36ac1cd1b3f3723 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Tue, 18 Feb 2014 17:36:50 +0000 Subject: [PATCH] DeLesley Hutchins (who wrote the original thread-safety attribute functionality) and I have agreed to start migrating from lock-specific terminology to "capability"-specific terminology. This opens the door for future threading-related analysis passes so that a common nomenclature can be used. The following attributes have been (silently) deprecated, with their replacements listed: lockable => capability exclusive_locks_required => requires_capability shared_locks_required => requires_shared_capability locks_excluded => requires_capability There are no functional changes intended. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@201585 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Attr.td | 54 +++++++----- include/clang/Basic/DiagnosticSemaKinds.td | 4 +- lib/Analysis/ThreadSafety.cpp | 27 ++---- lib/Sema/SemaDeclAttr.cpp | 95 ++++++++++----------- lib/Sema/SemaDeclCXX.cpp | 9 +- test/Sema/attr-capabilities.c | 25 ++++++ test/SemaCXX/warn-thread-safety-parsing.cpp | 32 +++---- 7 files changed, 130 insertions(+), 116 deletions(-) create mode 100644 test/Sema/attr-capabilities.c diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 0b3afb97c9..2d984949b0 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -1279,6 +1279,7 @@ def Lockable : InheritableAttr { let Spellings = [GNU<"lockable">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let ASTNode = 0; // Replaced by Capability } def ScopedLockable : InheritableAttr { @@ -1287,6 +1288,37 @@ def ScopedLockable : InheritableAttr { let Documentation = [Undocumented]; } +def Capability : InheritableAttr { + let Spellings = [GNU<"capability">, CXX11<"clang", "capability">, + GNU<"shared_capability">, + CXX11<"clang", "shared_capability">]; + let Subjects = SubjectList<[Struct], ErrorDiag, "ExpectedStruct">; + let Args = [StringArgument<"Name">]; + let Accessors = [Accessor<"isShared", + [GNU<"shared_capability">, + CXX11<"clang","shared_capability">]>]; + let Documentation = [Undocumented]; +} + +def RequiresCapability : InheritableAttr { + let Spellings = [GNU<"requires_capability">, + CXX11<"clang", "requires_capability">, + GNU<"exclusive_locks_required">, + GNU<"requires_shared_capability">, + CXX11<"clang", "requires_shared_capability">, + GNU<"shared_locks_required">]; + let Args = [VariadicExprArgument<"Args">]; + let LateParsed = 1; + let TemplateDependent = 1; + let ParseArgumentsAsUnevaluated = 1; + let DuplicatesAllowedWhileMerging = 1; + let Subjects = SubjectList<[Function, FunctionTemplate]>; + let Accessors = [Accessor<"isShared", [GNU<"requires_shared_capability">, + GNU<"shared_locks_required">, + CXX11<"clang","requires_shared_capability">]>]; + let Documentation = [Undocumented]; +} + def NoThreadSafetyAnalysis : InheritableAttr { let Spellings = [GNU<"no_thread_safety_analysis">]; let Subjects = SubjectList<[Function, FunctionTemplate]>; @@ -1443,28 +1475,6 @@ def LocksExcluded : InheritableAttr { let Documentation = [Undocumented]; } -def ExclusiveLocksRequired : InheritableAttr { - let Spellings = [GNU<"exclusive_locks_required">]; - let Args = [VariadicExprArgument<"Args">]; - let LateParsed = 1; - let TemplateDependent = 1; - let ParseArgumentsAsUnevaluated = 1; - let DuplicatesAllowedWhileMerging = 1; - let Subjects = SubjectList<[Function, FunctionTemplate]>; - let Documentation = [Undocumented]; -} - -def SharedLocksRequired : InheritableAttr { - let Spellings = [GNU<"shared_locks_required">]; - let Args = [VariadicExprArgument<"Args">]; - let LateParsed = 1; - let TemplateDependent = 1; - let ParseArgumentsAsUnevaluated = 1; - let DuplicatesAllowedWhileMerging = 1; - let Subjects = SubjectList<[Function, FunctionTemplate]>; - let Documentation = [Undocumented]; -} - // C/C++ consumed attributes. def Consumable : InheritableAttr { diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 910263c4f2..af3445b16f 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2139,7 +2139,7 @@ def warn_thread_attribute_ignored : Warning< InGroup, DefaultIgnore; def warn_thread_attribute_argument_not_lockable : Warning< "%0 attribute requires arguments whose type is annotated " - "with 'lockable' attribute; type here is %1">, + "with 'capability' attribute; type here is %1">, InGroup, DefaultIgnore; def warn_thread_attribute_argument_not_class : Warning< "%0 attribute requires arguments that are class type or point to" @@ -2147,7 +2147,7 @@ def warn_thread_attribute_argument_not_class : Warning< InGroup, DefaultIgnore; def warn_thread_attribute_decl_not_lockable : Warning< "%0 attribute can only be applied in a context annotated " - "with 'lockable' attribute">, + "with 'capability(\"mutex\")' attribute">, InGroup, DefaultIgnore; def warn_thread_attribute_decl_not_pointer : Warning< "%0 only applies to pointer types; type here is %1">, diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp index c271f38035..33799c4f88 100644 --- a/lib/Analysis/ThreadSafety.cpp +++ b/lib/Analysis/ThreadSafety.cpp @@ -2015,21 +2015,13 @@ void BuildLockset::handleCall(Expr *Exp, const NamedDecl *D, VarDecl *VD) { break; } - case attr::ExclusiveLocksRequired: { - ExclusiveLocksRequiredAttr *A = cast(At); + case attr::RequiresCapability: { + RequiresCapabilityAttr *A = cast(At); - for (ExclusiveLocksRequiredAttr::args_iterator - I = A->args_begin(), E = A->args_end(); I != E; ++I) - warnIfMutexNotHeld(D, Exp, AK_Written, *I, POK_FunctionCall); - break; - } - - case attr::SharedLocksRequired: { - SharedLocksRequiredAttr *A = cast(At); - - for (SharedLocksRequiredAttr::args_iterator I = A->args_begin(), + for (RequiresCapabilityAttr::args_iterator I = A->args_begin(), E = A->args_end(); I != E; ++I) - warnIfMutexNotHeld(D, Exp, AK_Read, *I, POK_FunctionCall); + warnIfMutexNotHeld(D, Exp, A->isShared() ? AK_Read : AK_Written, *I, + POK_FunctionCall); break; } @@ -2390,12 +2382,9 @@ void ThreadSafetyAnalyzer::runAnalysis(AnalysisDeclContext &AC) { for (unsigned i = 0; i < ArgAttrs.size(); ++i) { Attr *Attr = ArgAttrs[i]; Loc = Attr->getLocation(); - if (ExclusiveLocksRequiredAttr *A - = dyn_cast(Attr)) { - getMutexIDs(ExclusiveLocksToAdd, A, (Expr*) 0, D); - } else if (SharedLocksRequiredAttr *A - = dyn_cast(Attr)) { - getMutexIDs(SharedLocksToAdd, A, (Expr*) 0, D); + if (RequiresCapabilityAttr *A = dyn_cast(Attr)) { + getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A, + 0, D); } else if (UnlockFunctionAttr *A = dyn_cast(Attr)) { // UNLOCK_FUNCTION() is used to hide the underlying lock implementation. // We must ignore such methods. diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index ccfb7bc0ab..ef19a0b992 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -367,7 +367,7 @@ static const RecordType *getRecordType(QualType QT) { static bool checkBaseClassIsLockableCallback(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, void *Unused) { const RecordType *RT = Specifier->getType()->getAs(); - return RT->getDecl()->hasAttr(); + return RT->getDecl()->hasAttr(); } @@ -395,7 +395,7 @@ static void checkForLockableRecord(Sema &S, Decl *D, const AttributeList &Attr, // Check if the type is lockable. RecordDecl *RD = RT->getDecl(); - if (RD->hasAttr()) + if (RD->hasAttr()) return; // Else check if any base classes are lockable. @@ -548,7 +548,7 @@ static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, QualType QT = cast(D)->getType(); if (!QT->isDependentType()) { const RecordType *RT = getRecordType(QT); - if (!RT || !RT->getDecl()->hasAttr()) { + if (!RT || !RT->getDecl()->hasAttr()) { S.Diag(Attr.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << Attr.getName(); return false; @@ -698,46 +698,6 @@ static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D, Attr.getAttributeSpellingListIndex())); } -static bool checkLocksRequiredCommon(Sema &S, Decl *D, - const AttributeList &Attr, - SmallVectorImpl &Args) { - if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) - return false; - - // check that all arguments are lockable objects - checkAttrArgsAreLockableObjs(S, D, Attr, Args); - if (Args.empty()) - return false; - - return true; -} - -static void handleExclusiveLocksRequiredAttr(Sema &S, Decl *D, - const AttributeList &Attr) { - SmallVector Args; - if (!checkLocksRequiredCommon(S, D, Attr, Args)) - return; - - Expr **StartArg = &Args[0]; - D->addAttr(::new (S.Context) - ExclusiveLocksRequiredAttr(Attr.getRange(), S.Context, - StartArg, Args.size(), - Attr.getAttributeSpellingListIndex())); -} - -static void handleSharedLocksRequiredAttr(Sema &S, Decl *D, - const AttributeList &Attr) { - SmallVector Args; - if (!checkLocksRequiredCommon(S, D, Attr, Args)) - return; - - Expr **StartArg = &Args[0]; - D->addAttr(::new (S.Context) - SharedLocksRequiredAttr(Attr.getRange(), S.Context, - StartArg, Args.size(), - Attr.getAttributeSpellingListIndex())); -} - static void handleUnlockFunAttr(Sema &S, Decl *D, const AttributeList &Attr) { // zero or more arguments ok @@ -3929,6 +3889,40 @@ Sema::mergeMSInheritanceAttr(Decl *D, SourceRange Range, bool BestCase, MSInheritanceAttr(Range, Context, BestCase, AttrSpellingListIndex); } +static void handleCapabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) { + // The capability attributes take a single string parameter for the name of + // the capability they represent. The lockable attribute does not take any + // parameters. However, semantically, both attributes represent the same + // concept, and so they use the same semantic attribute. Eventually, the + // lockable attribute will be removed. + StringRef N; + SourceLocation LiteralLoc; + if (Attr.getKind() == AttributeList::AT_Capability && + !S.checkStringLiteralArgumentAttr(Attr, 0, N, &LiteralLoc)) + return; + + D->addAttr(::new (S.Context) CapabilityAttr(Attr.getRange(), S.Context, N, + Attr.getAttributeSpellingListIndex())); +} + +static void handleRequiresCapabilityAttr(Sema &S, Decl *D, + const AttributeList &Attr) { + if (!checkAttributeAtLeastNumArgs(S, Attr, 1)) + return; + + // check that all arguments are lockable objects + SmallVector Args; + checkAttrArgsAreLockableObjs(S, D, Attr, Args); + if (Args.empty()) + return; + + RequiresCapabilityAttr *RCA = ::new (S.Context) + RequiresCapabilityAttr(Attr.getRange(), S.Context, Args.data(), + Args.size(), Attr.getAttributeSpellingListIndex()); + + D->addAttr(RCA); +} + /// Handles semantic checking for features that are common to all attributes, /// such as checking whether a parameter was properly specified, or the correct /// number of arguments were passed, etc. @@ -4243,8 +4237,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_NoSanitizeMemory: handleSimpleAttribute(S, D, Attr); break; - case AttributeList::AT_Lockable: - handleSimpleAttribute(S, D, Attr); break; case AttributeList::AT_GuardedBy: handleGuardedByAttr(S, D, Attr); break; @@ -4254,9 +4246,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_ExclusiveLockFunction: handleExclusiveLockFunctionAttr(S, D, Attr); break; - case AttributeList::AT_ExclusiveLocksRequired: - handleExclusiveLocksRequiredAttr(S, D, Attr); - break; case AttributeList::AT_ExclusiveTrylockFunction: handleExclusiveTrylockFunctionAttr(S, D, Attr); break; @@ -4269,9 +4258,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_SharedLockFunction: handleSharedLockFunctionAttr(S, D, Attr); break; - case AttributeList::AT_SharedLocksRequired: - handleSharedLocksRequiredAttr(S, D, Attr); - break; case AttributeList::AT_SharedTrylockFunction: handleSharedTrylockFunctionAttr(S, D, Attr); break; @@ -4285,6 +4271,13 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, handleAcquiredAfterAttr(S, D, Attr); break; + // Capability analysis attributes. + case AttributeList::AT_Capability: + case AttributeList::AT_Lockable: + handleCapabilityAttr(S, D, Attr); break; + case AttributeList::AT_RequiresCapability: + handleRequiresCapabilityAttr(S, D, Attr); break; + // Consumed analysis attributes. case AttributeList::AT_Consumable: handleConsumableAttr(S, D, Attr); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 5912bb82ea..e4967f899e 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -12749,12 +12749,9 @@ bool Sema::checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method) { Arg = LR->getArg(); else if (LocksExcludedAttr *LE = dyn_cast(*A)) Args = ArrayRef(LE->args_begin(), LE->args_size()); - else if (ExclusiveLocksRequiredAttr *ELR - = dyn_cast(*A)) - Args = ArrayRef(ELR->args_begin(), ELR->args_size()); - else if (SharedLocksRequiredAttr *SLR - = dyn_cast(*A)) - Args = ArrayRef(SLR->args_begin(), SLR->args_size()); + else if (RequiresCapabilityAttr *RC + = dyn_cast(*A)) + Args = ArrayRef(RC->args_begin(), RC->args_size()); if (Arg && !Finder.TraverseStmt(Arg)) return true; diff --git a/test/Sema/attr-capabilities.c b/test/Sema/attr-capabilities.c new file mode 100644 index 0000000000..fa3a3fab25 --- /dev/null +++ b/test/Sema/attr-capabilities.c @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s + +struct __attribute__((capability("thread role"))) ThreadRole {}; +struct __attribute__((shared_capability("mutex"))) Mutex {}; +struct NotACapability {}; + +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}} + +struct __attribute__((capability(12))) Test3 {}; // expected-error {{'capability' attribute requires a string}} +struct __attribute__((shared_capability(Test2))) Test4 {}; // expected-error {{'shared_capability' attribute requires a string}} + +struct __attribute__((capability)) Test5 {}; // expected-error {{'capability' attribute takes one argument}} +struct __attribute__((shared_capability("test1", 12))) Test6 {}; // expected-error {{'shared_capability' attribute takes one argument}} + +struct NotACapability BadCapability; +struct 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 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'}} diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp index f672d690b0..a27818692c 100644 --- a/test/SemaCXX/warn-thread-safety-parsing.cpp +++ b/test/SemaCXX/warn-thread-safety-parsing.cpp @@ -359,7 +359,7 @@ int gb_var_arg_bad_2 GUARDED_BY("mu"); // \ 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 **'}} int gb_var_arg_bad_4 GUARDED_BY(umu); // \ - // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'UnlockableMu'}} + // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'UnlockableMu'}} //3. // Thread Safety analysis tests @@ -430,7 +430,7 @@ int * pgb_var_arg_bad_2 PT_GUARDED_BY("mu"); // \ 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}} int * pgb_var_arg_bad_4 PT_GUARDED_BY(umu); // \ - // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'pt_guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute}} //-----------------------------------------// @@ -491,9 +491,9 @@ Mutex aa_var_arg_bad_2 ACQUIRED_AFTER("mu"); // \ 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}} Mutex aa_var_arg_bad_4 ACQUIRED_AFTER(umu); // \ - // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'acquired_after' attribute requires arguments whose type is annotated with 'capability' attribute}} UnlockableMu aa_var_arg_bad_5 ACQUIRED_AFTER(mu_aa); // \ - // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'lockable' attribute}} + // expected-warning {{'acquired_after' attribute can only be applied in a context annotated with 'capability("mutex")' attribute}} //-----------------------------------------// // Acquired Before (ab) @@ -554,9 +554,9 @@ Mutex ab_var_arg_bad_2 ACQUIRED_BEFORE("mu"); // \ 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}} Mutex ab_var_arg_bad_4 ACQUIRED_BEFORE(umu); // \ - // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'acquired_before' attribute requires arguments whose type is annotated with 'capability' attribute}} UnlockableMu ab_var_arg_bad_5 ACQUIRED_BEFORE(mu_ab); // \ - // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'lockable' attribute}} + // expected-warning {{'acquired_before' attribute can only be applied in a context annotated with 'capability("mutex")' attribute}} //-----------------------------------------// @@ -619,7 +619,7 @@ int elf_function_bad_2() EXCLUSIVE_LOCK_FUNCTION("mu"); // \ 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}} int elf_function_bad_4() EXCLUSIVE_LOCK_FUNCTION(umu); // \ - // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'exclusive_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}} int elf_function_bad_1() EXCLUSIVE_LOCK_FUNCTION(1); // \ // expected-error {{'exclusive_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}} @@ -691,7 +691,7 @@ int slf_function_bad_2() SHARED_LOCK_FUNCTION("mu"); // \ 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}} int slf_function_bad_4() SHARED_LOCK_FUNCTION(umu); // \ - // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'shared_lock_function' attribute requires arguments whose type is annotated with 'capability' attribute}} int slf_function_bad_1() SHARED_LOCK_FUNCTION(1); // \ // expected-error {{'shared_lock_function' attribute parameter 1 is out of bounds: no parameters to index into}} @@ -773,7 +773,7 @@ int etf_function_bad_4() EXCLUSIVE_TRYLOCK_FUNCTION(1, "mu"); // \ 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}} int etf_function_bad_6() EXCLUSIVE_TRYLOCK_FUNCTION(1, umu); // \ - // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'exclusive_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}} //-----------------------------------------// @@ -847,7 +847,7 @@ int stf_function_bad_4() SHARED_TRYLOCK_FUNCTION(1, "mu"); // \ 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}} int stf_function_bad_6() SHARED_TRYLOCK_FUNCTION(1, umu); // \ - // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'shared_trylock_function' attribute requires arguments whose type is annotated with 'capability' attribute}} //-----------------------------------------// @@ -910,7 +910,7 @@ int uf_function_bad_2() UNLOCK_FUNCTION("mu"); // \ int uf_function_bad_3() UNLOCK_FUNCTION(muDoublePointer); // \ // expected-warning {{'unlock_function' attribute requires arguments that are class type or point to class type}} int uf_function_bad_4() UNLOCK_FUNCTION(umu); // \ - // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'unlock_function' attribute requires arguments whose type is annotated with 'capability' attribute}} int uf_function_bad_1() UNLOCK_FUNCTION(1); // \ // expected-error {{'unlock_function' attribute parameter 1 is out of bounds: no parameters to index into}} @@ -986,7 +986,7 @@ int lr_function_bad_2() LOCK_RETURNED("mu"); // \ int lr_function_bad_3() LOCK_RETURNED(muDoublePointer); // \ // expected-warning {{'lock_returned' attribute requires arguments that are class type or point to class type}} int lr_function_bad_4() LOCK_RETURNED(umu); // \ - // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'lock_returned' attribute requires arguments whose type is annotated with 'capability' attribute}} @@ -1053,7 +1053,7 @@ int le_function_bad_2() LOCKS_EXCLUDED("mu"); // \ int le_function_bad_3() LOCKS_EXCLUDED(muDoublePointer); // \ // expected-warning {{'locks_excluded' attribute requires arguments that are class type or point to class type}} int le_function_bad_4() LOCKS_EXCLUDED(umu); // \ - // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute}} @@ -1120,7 +1120,7 @@ int elr_function_bad_2() EXCLUSIVE_LOCKS_REQUIRED("mu"); // \ 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}} int elr_function_bad_4() EXCLUSIVE_LOCKS_REQUIRED(umu); // \ - // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'exclusive_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}} @@ -1188,7 +1188,7 @@ int slr_function_bad_2() SHARED_LOCKS_REQUIRED("mu"); // \ 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}} int slr_function_bad_4() SHARED_LOCKS_REQUIRED(umu); // \ - // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'lockable' attribute}} + // expected-warning {{'shared_locks_required' attribute requires arguments whose type is annotated with 'capability' attribute}} //-----------------------------------------// @@ -1430,7 +1430,7 @@ class Foo { int a GUARDED_BY(mu1_); int b GUARDED_BY(mu2_); int c GUARDED_BY(mu3_); // \ - // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'lockable' attribute; type here is 'InheritanceTest::Derived3'}} + // expected-warning {{'guarded_by' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'InheritanceTest::Derived3'}} void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1_, mu2_) { a = 0; -- 2.40.0