Add new checker-specific attribute 'objc_ownership_returns'. This isn't hooked

up to the checker yet, but essentially it allows a user to specify that an
Objective-C method or C function returns an owned an Objective-C object.

llvm-svn: 70001
This commit is contained in:
Ted Kremenek 2009-04-24 23:09:54 +00:00
parent defc644e06
commit 44e662cd4f
7 changed files with 57 additions and 1 deletions

View File

@ -51,6 +51,7 @@ public:
NonNull,
ObjCException,
ObjCNSObject,
ObjCOwnershipReturns, // Clang/Checker-specific.
Overloadable, // Clang-specific
Packed,
Pure,
@ -587,6 +588,21 @@ public:
static bool classof(const Attr *A) { return A->getKind() == Regparm; }
static bool classof(const RegparmAttr *A) { return true; }
};
#define DEF_SIMPLE_ATTR(ATTR)\
class ATTR##Attr : public Attr {\
public:\
ATTR##Attr() : Attr(ATTR) {}\
static bool classof(const Attr *A) { return A->getKind() == ATTR; }\
static bool classof(const ATTR##Attr *A) { return true; }\
};
// Checker-specific attributes.
DEF_SIMPLE_ATTR(ObjCOwnershipReturns)
#undef DEF_SIMPLE_ATTR
} // end namespace clang
#endif

View File

@ -75,8 +75,9 @@ public:
AT_nothrow,
AT_nsobject,
AT_objc_exception,
AT_objc_ownership_returns, // Clang-specific.
AT_objc_gc,
AT_overloadable, // Clang-specific
AT_overloadable, // Clang-specific.
AT_packed,
AT_pure,
AT_regparm,

View File

@ -3045,6 +3045,7 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(ObjCException);
SIMPLE_ATTR(ObjCNSObject);
SIMPLE_ATTR(ObjCOwnershipReturns);
SIMPLE_ATTR(Overloadable);
UNSIGNED_ATTR(Packed);
SIMPLE_ATTR(Pure);

View File

@ -2181,6 +2181,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
case Attr::ObjCException:
case Attr::ObjCNSObject:
case Attr::ObjCOwnershipReturns:
case Attr::Overloadable:
break;

View File

@ -133,6 +133,10 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
case 18:
if (!memcmp(Str, "warn_unused_result", 18)) return AT_warn_unused_result;
break;
case 22:
if (!memcmp(Str, "objc_ownership_returns", 22))
return AT_objc_ownership_returns;
break;
}
return UnknownAttribute;
}

View File

@ -1517,6 +1517,22 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
}
//===----------------------------------------------------------------------===//
// Checker-specific attribute handlers.
//===----------------------------------------------------------------------===//
static void HandleObjCOwnershipReturnsAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
if (!isa<ObjCMethodDecl>(d) && !isa<FunctionDecl>(d)) {
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
"objc_ownership_returns" << 3 /* function or method */;
return;
}
d->addAttr(::new (S.Context) ObjCOwnershipReturnsAttr());
}
//===----------------------------------------------------------------------===//
// Top Level Sema Entry Points
//===----------------------------------------------------------------------===//
@ -1553,6 +1569,11 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
// Checker-specific.
case AttributeList::AT_objc_ownership_returns:
HandleObjCOwnershipReturnsAttr(D, Attr, S); break;
case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break;
case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;

View File

@ -405,3 +405,15 @@ void rdar6704930(unsigned char *s, unsigned int length) {
}
}
//===----------------------------------------------------------------------===//
// Tests of ownership attributes.
//===----------------------------------------------------------------------===//
@interface TestOwnershipAttr : NSObject
- (NSString*) returnsAnOwnedString __attribute__((objc_ownership_returns));
@end
void test_attr_1(TestOwnershipAttr *X) {
NSString *str = [X returnsAnOwnedString];
}