def TLSVar : SubsetSubject<Var,
[{S->getTLSKind() != 0}]>;
+def SharedVar : SubsetSubject<Var,
+ [{S->hasGlobalStorage() && !S->getTLSKind()}]>;
+
// A single argument to an attribute
class Argument<string name, bit optional> {
string Name = name;
def GuardedVar : InheritableAttr {
let Spellings = [GNU<"guarded_var">];
- let Subjects = SubjectList<[Field, Var]>;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
}
def PtGuardedVar : InheritableAttr {
let Spellings = [GNU<"pt_guarded_var">];
- let Subjects = SubjectList<[Field, Var]>;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
}
def Lockable : InheritableAttr {
let Args = [ExprArgument<"Arg">];
let LateParsed = 1;
let TemplateDependent = 1;
- let Subjects = SubjectList<[Field, Var]>;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
}
def PtGuardedBy : InheritableAttr {
let Args = [ExprArgument<"Arg">];
let LateParsed = 1;
let TemplateDependent = 1;
- let Subjects = SubjectList<[Field, Var]>;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
}
def AcquiredAfter : InheritableAttr {
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
- let Subjects = SubjectList<[Field, Var]>;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
}
def AcquiredBefore : InheritableAttr {
let Args = [VariadicExprArgument<"Args">];
let LateParsed = 1;
let TemplateDependent = 1;
- let Subjects = SubjectList<[Field, Var]>;
+ let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
+ "ExpectedFieldOrGlobalVar">;
}
def ExclusiveLockFunction : InheritableAttr {
Attr.getAttributeSpellingListIndex()));
}
-///
-/// \brief Check if passed in Decl is a field or potentially shared global var
-/// \return true if the Decl is a field or potentially shared global variable
-///
-static bool mayBeSharedVariable(const Decl *D) {
- if (const VarDecl *vd = dyn_cast<VarDecl>(D))
- return vd->hasGlobalStorage() && !vd->getTLSKind();
-
- return true;
-}
-
/// \brief Check if the passed-in expression is of type int or bool.
static bool isIntOrBool(Expr *Exp) {
QualType QT = Exp->getType();
// least add some helper functions to check most argument patterns (#
// and types of args).
-static bool checkGuardedVarAttrCommon(Sema &S, Decl *D,
- const AttributeList &Attr) {
- // 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)
- << Attr.getName() << ExpectedFieldOrGlobalVar;
- return false;
- }
-
- return true;
-}
-
-static void handleGuardedVarAttr(Sema &S, Decl *D, const AttributeList &Attr) {
- if (!checkGuardedVarAttrCommon(S, D, Attr))
- return;
-
- D->addAttr(::new (S.Context)
- GuardedVarAttr(Attr.getRange(), S.Context,
- Attr.getAttributeSpellingListIndex()));
-}
-
static void handlePtGuardedVarAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
- if (!checkGuardedVarAttrCommon(S, D, Attr))
- return;
-
if (!threadSafetyCheckIsPointer(S, D, Attr))
return;
static bool checkGuardedByAttrCommon(Sema &S, Decl *D,
const AttributeList &Attr,
Expr* &Arg) {
- // 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)
- << Attr.getName() << ExpectedFieldOrGlobalVar;
- return false;
- }
-
SmallVector<Expr*, 1> Args;
// check that all arguments are lockable objects
checkAttrArgsAreLockableObjs(S, D, Attr, Args);
if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
return false;
- // D must be either a member field or global (potentially shared) variable.
- ValueDecl *VD = dyn_cast<ValueDecl>(D);
- if (!VD || !mayBeSharedVariable(D)) {
- S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
- << Attr.getName() << ExpectedFieldOrGlobalVar;
- return false;
- }
-
// Check that this attribute only applies to lockable types.
- QualType QT = VD->getType();
+ QualType QT = cast<ValueDecl>(D)->getType();
if (!QT->isDependentType()) {
const RecordType *RT = getRecordType(QT);
if (!RT || !RT->getDecl()->getAttr<LockableAttr>()) {
handleAssertSharedLockAttr(S, D, Attr);
break;
case AttributeList::AT_GuardedVar:
- handleGuardedVarAttr(S, D, Attr);
- break;
+ handleSimpleAttribute<GuardedVarAttr>(S, D, Attr); break;
case AttributeList::AT_PtGuardedVar:
handlePtGuardedVarAttr(S, D, Attr);
break;