r204350 - Replacing the exclusive_lock_function, shared_lock_function and unlock_function attributes with the acquire_capability and release_capability attributes. The old spellings will continue to work, but the underlying semantic attributes have been replaced.
Aaron Ballman
aaron at aaronballman.com
Thu Mar 20 09:02:49 PDT 2014
Author: aaronballman
Date: Thu Mar 20 11:02:49 2014
New Revision: 204350
URL: http://llvm.org/viewvc/llvm-project?rev=204350&view=rev
Log:
Replacing the exclusive_lock_function, shared_lock_function and unlock_function attributes with the acquire_capability and release_capability attributes. The old spellings will continue to work, but the underlying semantic attributes have been replaced.
Downgraded the capability diagnostics from error to warning to match the desired behavior, and updated the existing test cases.
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/lib/Analysis/ThreadSafety.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/Sema/attr-capabilities.c
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=204350&r1=204349&r2=204350&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Thu Mar 20 11:02:49 2014
@@ -1335,9 +1335,10 @@ def AcquireCapability : InheritableAttr
let Spellings = [GNU<"acquire_capability">,
CXX11<"clang", "acquire_capability">,
GNU<"acquire_shared_capability">,
- CXX11<"clang", "acquire_shared_capability">];
- let Subjects = SubjectList<[Function, FunctionTemplate],
- ErrorDiag>;
+ CXX11<"clang", "acquire_shared_capability">,
+ GNU<"exclusive_lock_function">,
+ GNU<"shared_lock_function">];
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
@@ -1345,7 +1346,8 @@ def AcquireCapability : InheritableAttr
let Args = [VariadicExprArgument<"Args">];
let Accessors = [Accessor<"isShared",
[GNU<"acquire_shared_capability">,
- CXX11<"clang", "acquire_shared_capability">]>];
+ CXX11<"clang", "acquire_shared_capability">,
+ GNU<"shared_lock_function">]>];
let Documentation = [AcquireCapabilityDocs];
}
@@ -1373,9 +1375,9 @@ def ReleaseCapability : InheritableAttr
GNU<"release_shared_capability">,
CXX11<"clang", "release_shared_capability">,
GNU<"release_generic_capability">,
- CXX11<"clang", "release_generic_capability">];
- let Subjects = SubjectList<[Function, FunctionTemplate],
- ErrorDiag>;
+ CXX11<"clang", "release_generic_capability">,
+ GNU<"unlock_function">];
+ let Subjects = SubjectList<[Function, FunctionTemplate]>;
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
@@ -1463,28 +1465,6 @@ def AcquiredBefore : InheritableAttr {
let Documentation = [Undocumented];
}
-def ExclusiveLockFunction : InheritableAttr {
- let Spellings = [GNU<"exclusive_lock_function">];
- 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 SharedLockFunction : InheritableAttr {
- let Spellings = [GNU<"shared_lock_function">];
- 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 AssertExclusiveLock : InheritableAttr {
let Spellings = [GNU<"assert_exclusive_lock">];
let Args = [VariadicExprArgument<"Args">];
@@ -1528,17 +1508,6 @@ def SharedTrylockFunction : InheritableA
let LateParsed = 1;
let TemplateDependent = 1;
let ParseArgumentsAsUnevaluated = 1;
- let DuplicatesAllowedWhileMerging = 1;
- let Subjects = SubjectList<[Function, FunctionTemplate]>;
- let Documentation = [Undocumented];
-}
-
-def UnlockFunction : InheritableAttr {
- let Spellings = [GNU<"unlock_function">];
- let Args = [VariadicExprArgument<"Args">];
- let LateParsed = 1;
- let TemplateDependent = 1;
- let ParseArgumentsAsUnevaluated = 1;
let DuplicatesAllowedWhileMerging = 1;
let Subjects = SubjectList<[Function, FunctionTemplate]>;
let Documentation = [Undocumented];
Modified: cfe/trunk/lib/Analysis/ThreadSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafety.cpp?rev=204350&r1=204349&r2=204350&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ThreadSafety.cpp (original)
+++ cfe/trunk/lib/Analysis/ThreadSafety.cpp Thu Mar 20 11:02:49 2014
@@ -1933,19 +1933,13 @@ void BuildLockset::handleCall(Expr *Exp,
for(unsigned i = 0; i < ArgAttrs.size(); ++i) {
Attr *At = const_cast<Attr*>(ArgAttrs[i]);
switch (At->getKind()) {
- // When we encounter an exclusive lock function, we need to add the lock
- // to our lockset with kind exclusive.
- case attr::ExclusiveLockFunction: {
- ExclusiveLockFunctionAttr *A = cast<ExclusiveLockFunctionAttr>(At);
- Analyzer->getMutexIDs(ExclusiveLocksToAdd, A, Exp, D, VD);
- break;
- }
-
- // When we encounter a shared lock function, we need to add the lock
- // to our lockset with kind shared.
- case attr::SharedLockFunction: {
- SharedLockFunctionAttr *A = cast<SharedLockFunctionAttr>(At);
- Analyzer->getMutexIDs(SharedLocksToAdd, A, Exp, D, VD);
+ // When we encounter a lock function, we need to add the lock to our
+ // lockset.
+ case attr::AcquireCapability: {
+ auto *A = cast<AcquireCapabilityAttr>(At);
+ Analyzer->getMutexIDs(A->isShared() ? SharedLocksToAdd
+ : ExclusiveLocksToAdd,
+ A, Exp, D, VD);
break;
}
@@ -1977,8 +1971,8 @@ void BuildLockset::handleCall(Expr *Exp,
// When we encounter an unlock function, we need to remove unlocked
// mutexes from the lockset, and flag a warning if they are not there.
- case attr::UnlockFunction: {
- UnlockFunctionAttr *A = cast<UnlockFunctionAttr>(At);
+ case attr::ReleaseCapability: {
+ auto *A = cast<ReleaseCapabilityAttr>(At);
Analyzer->getMutexIDs(LocksToRemove, A, Exp, D, VD);
break;
}
@@ -2351,7 +2345,7 @@ void ThreadSafetyAnalyzer::runAnalysis(A
if (RequiresCapabilityAttr *A = dyn_cast<RequiresCapabilityAttr>(Attr)) {
getMutexIDs(A->isShared() ? SharedLocksToAdd : ExclusiveLocksToAdd, A,
0, D);
- } else if (UnlockFunctionAttr *A = dyn_cast<UnlockFunctionAttr>(Attr)) {
+ } else if (auto *A = dyn_cast<ReleaseCapabilityAttr>(Attr)) {
// UNLOCK_FUNCTION() is used to hide the underlying lock implementation.
// We must ignore such methods.
if (A->args_size() == 0)
@@ -2359,16 +2353,12 @@ void ThreadSafetyAnalyzer::runAnalysis(A
// FIXME -- deal with exclusive vs. shared unlock functions?
getMutexIDs(ExclusiveLocksToAdd, A, (Expr*) 0, D);
getMutexIDs(LocksReleased, A, (Expr*) 0, D);
- } else if (ExclusiveLockFunctionAttr *A
- = dyn_cast<ExclusiveLockFunctionAttr>(Attr)) {
- if (A->args_size() == 0)
- return;
- getMutexIDs(ExclusiveLocksAcquired, A, (Expr*) 0, D);
- } else if (SharedLockFunctionAttr *A
- = dyn_cast<SharedLockFunctionAttr>(Attr)) {
+ } else if (auto *A = dyn_cast<AcquireCapabilityAttr>(Attr)) {
if (A->args_size() == 0)
return;
- getMutexIDs(SharedLocksAcquired, A, (Expr*) 0, D);
+ getMutexIDs(A->isShared() ? SharedLocksAcquired
+ : ExclusiveLocksAcquired,
+ A, nullptr, D);
} else if (isa<ExclusiveTrylockFunctionAttr>(Attr)) {
// Don't try to check trylock functions for now
return;
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=204350&r1=204349&r2=204350&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Mar 20 11:02:49 2014
@@ -599,33 +599,6 @@ static bool checkLockFunAttrCommon(Sema
return true;
}
-static void handleSharedLockFunctionAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
- SmallVector<Expr*, 1> Args;
- if (!checkLockFunAttrCommon(S, D, Attr, Args))
- return;
-
- unsigned Size = Args.size();
- Expr **StartArg = Size == 0 ? 0 : &Args[0];
- D->addAttr(::new (S.Context)
- SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
- Attr.getAttributeSpellingListIndex()));
-}
-
-static void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
- SmallVector<Expr*, 1> Args;
- if (!checkLockFunAttrCommon(S, D, Attr, Args))
- return;
-
- unsigned Size = Args.size();
- Expr **StartArg = Size == 0 ? 0 : &Args[0];
- D->addAttr(::new (S.Context)
- ExclusiveLockFunctionAttr(Attr.getRange(), S.Context,
- StartArg, Size,
- Attr.getAttributeSpellingListIndex()));
-}
-
static void handleAssertSharedLockAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
SmallVector<Expr*, 1> Args;
@@ -698,20 +671,6 @@ static void handleExclusiveTrylockFuncti
Attr.getAttributeSpellingListIndex()));
}
-static void handleUnlockFunAttr(Sema &S, Decl *D,
- const AttributeList &Attr) {
- // zero or more arguments ok
- // check that all arguments are lockable objects
- SmallVector<Expr*, 1> Args;
- checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, /*ParamIdxOk=*/true);
- unsigned Size = Args.size();
- Expr **StartArg = Size == 0 ? 0 : &Args[0];
-
- D->addAttr(::new (S.Context)
- UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
- Attr.getAttributeSpellingListIndex()));
-}
-
static void handleLockReturnedAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
// check that the argument is lockable object
@@ -3912,12 +3871,7 @@ static void handleAssertCapabilityAttr(S
static void handleAcquireCapabilityAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
SmallVector<Expr*, 1> Args;
- if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
- return;
-
- // Check that all arguments are lockable objects.
- checkAttrArgsAreLockableObjs(S, D, Attr, Args);
- if (Args.empty())
+ if (!checkLockFunAttrCommon(S, D, Attr, Args))
return;
D->addAttr(::new (S.Context) AcquireCapabilityAttr(Attr.getRange(),
@@ -3942,19 +3896,13 @@ static void handleTryAcquireCapabilityAt
static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
- SmallVector<Expr*, 1> Args;
- if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
- return;
-
// Check that all arguments are lockable objects.
- checkAttrArgsAreLockableObjs(S, D, Attr, Args);
- if (Args.empty())
- return;
+ SmallVector<Expr *, 1> Args;
+ checkAttrArgsAreLockableObjs(S, D, Attr, Args, 0, true);
- D->addAttr(::new (S.Context) ReleaseCapabilityAttr(Attr.getRange(),
- S.Context,
- Args.data(), Args.size(),
- Attr.getAttributeSpellingListIndex()));
+ D->addAttr(::new (S.Context) ReleaseCapabilityAttr(
+ Attr.getRange(), S.Context, Args.data(), Args.size(),
+ Attr.getAttributeSpellingListIndex()));
}
static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
@@ -4417,9 +4365,6 @@ static void ProcessDeclAttribute(Sema &S
case AttributeList::AT_PtGuardedBy:
handlePtGuardedByAttr(S, D, Attr);
break;
- case AttributeList::AT_ExclusiveLockFunction:
- handleExclusiveLockFunctionAttr(S, D, Attr);
- break;
case AttributeList::AT_ExclusiveTrylockFunction:
handleExclusiveTrylockFunctionAttr(S, D, Attr);
break;
@@ -4429,15 +4374,9 @@ static void ProcessDeclAttribute(Sema &S
case AttributeList::AT_LocksExcluded:
handleLocksExcludedAttr(S, D, Attr);
break;
- case AttributeList::AT_SharedLockFunction:
- handleSharedLockFunctionAttr(S, D, Attr);
- break;
case AttributeList::AT_SharedTrylockFunction:
handleSharedTrylockFunctionAttr(S, D, Attr);
break;
- case AttributeList::AT_UnlockFunction:
- handleUnlockFunAttr(S, D, Attr);
- break;
case AttributeList::AT_AcquiredBefore:
handleAcquiredBeforeAttr(S, D, Attr);
break;
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=204350&r1=204349&r2=204350&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Mar 20 11:02:49 2014
@@ -12597,19 +12597,13 @@ bool Sema::checkThisInStaticMemberFuncti
Args = ArrayRef<Expr *>(AA->args_begin(), AA->args_size());
else if (const auto *AB = dyn_cast<AcquiredBeforeAttr>(A))
Args = ArrayRef<Expr *>(AB->args_begin(), AB->args_size());
- else if (const auto *ELF = dyn_cast<ExclusiveLockFunctionAttr>(A))
- Args = ArrayRef<Expr *>(ELF->args_begin(), ELF->args_size());
- else if (const auto *SLF = dyn_cast<SharedLockFunctionAttr>(A))
- Args = ArrayRef<Expr *>(SLF->args_begin(), SLF->args_size());
else if (const auto *ETLF = dyn_cast<ExclusiveTrylockFunctionAttr>(A)) {
Arg = ETLF->getSuccessValue();
Args = ArrayRef<Expr *>(ETLF->args_begin(), ETLF->args_size());
} else if (const auto *STLF = dyn_cast<SharedTrylockFunctionAttr>(A)) {
Arg = STLF->getSuccessValue();
Args = ArrayRef<Expr *>(STLF->args_begin(), STLF->args_size());
- } else if (const auto *UF = dyn_cast<UnlockFunctionAttr>(A))
- Args = ArrayRef<Expr *>(UF->args_begin(), UF->args_size());
- else if (const auto *LR = dyn_cast<LockReturnedAttr>(A))
+ } else if (const auto *LR = dyn_cast<LockReturnedAttr>(A))
Arg = LR->getArg();
else if (const auto *LE = dyn_cast<LocksExcludedAttr>(A))
Args = ArrayRef<Expr *>(LE->args_begin(), LE->args_size());
Modified: cfe/trunk/test/Sema/attr-capabilities.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-capabilities.c?rev=204350&r1=204349&r2=204350&view=diff
==============================================================================
--- cfe/trunk/test/Sema/attr-capabilities.c (original)
+++ cfe/trunk/test/Sema/attr-capabilities.c Thu Mar 20 11:02:49 2014
@@ -9,9 +9,9 @@ struct __attribute__((capability("wrong"
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 Test3 __attribute__((acquire_capability("test3"))); // expected-error {{'acquire_capability' attribute only applies to functions}}
+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-error {{'release_capability' attribute only applies to functions}}
+int Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}}
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}}
@@ -39,17 +39,10 @@ void Func10(void) __attribute__((assert_
void Func11(void) __attribute__((acquire_capability(GUI))) {}
void Func12(void) __attribute__((acquire_shared_capability(GUI))) {}
-void Func13(void) __attribute__((acquire_capability())) {} // expected-error {{'acquire_capability' attribute takes at least 1 argument}}
-void Func14(void) __attribute__((acquire_shared_capability())) {} // expected-error {{'acquire_shared_capability' attribute takes at least 1 argument}}
-
void Func15(void) __attribute__((release_capability(GUI))) {}
void Func16(void) __attribute__((release_shared_capability(GUI))) {}
void Func17(void) __attribute__((release_generic_capability(GUI))) {}
-void Func18(void) __attribute__((release_capability())) {} // expected-error {{'release_capability' attribute takes at least 1 argument}}
-void Func19(void) __attribute__((release_shared_capability())) {} // expected-error {{'release_shared_capability' attribute takes at least 1 argument}}
-void Func20(void) __attribute__((release_generic_capability())) {} // expected-error {{'release_generic_capability' attribute takes at least 1 argument}}
-
void Func21(void) __attribute__((try_acquire_capability(1))) {}
void Func22(void) __attribute__((try_acquire_shared_capability(1))) {}
More information about the cfe-commits
mailing list