From dbf62e3eee51c0532da044a903ee48fe02b6f63e Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 20 Jan 2014 05:50:47 +0000 Subject: Wire up basic parser/sema support for attribute 'returns_nonnull'. This attribute is supported by GCC. More generally it should probably be a type attribute, but this behavior matches 'nonnull'. This patch does not include warning logic for checking if a null value is returned from a function annotated with this attribute. That will come in subsequent patches. llvm-svn: 199626 --- clang/lib/Sema/SemaDeclAttr.cpp | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'clang/lib/Sema/SemaDeclAttr.cpp') diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index eaad404666e..ed8610cec39 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1157,12 +1157,14 @@ static void possibleTransparentUnionPointerType(QualType &T) { } static bool attrNonNullArgCheck(Sema &S, QualType T, const AttributeList &Attr, - SourceRange R) { + SourceRange R, bool isReturnValue = false) { T = T.getNonReferenceType(); possibleTransparentUnionPointerType(T); if (!T->isAnyPointerType() && !T->isBlockPointerType()) { - S.Diag(Attr.getLoc(), diag::warn_attribute_pointers_only) + S.Diag(Attr.getLoc(), + isReturnValue ? diag::warn_attribute_return_pointers_only + : diag::warn_attribute_pointers_only) << Attr.getName() << R; return false; } @@ -1231,6 +1233,23 @@ static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) { Attr.getAttributeSpellingListIndex())); } +static void handleReturnsNonNullAttr(Sema &S, Decl *D, + const AttributeList &Attr) { + QualType ResultType; + if (const FunctionType *Ty = D->getFunctionType()) + ResultType = Ty->getResultType(); + else if (const ObjCMethodDecl *MD = dyn_cast(D)) + ResultType = MD->getResultType(); + + if (!attrNonNullArgCheck(S, ResultType, Attr, Attr.getRange(), + /* isReturnValue */ true)) + return; + + D->addAttr(::new (S.Context) + ReturnsNonNullAttr(Attr.getRange(), S.Context, + Attr.getAttributeSpellingListIndex())); +} + static const char *ownershipKindToDiagName(OwnershipAttr::OwnershipKind K) { switch (K) { case OwnershipAttr::Holds: return "'ownership_holds'"; @@ -3978,6 +3997,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, else handleNonNullAttr(S, D, Attr); break; + case AttributeList::AT_ReturnsNonNull: + handleReturnsNonNullAttr(S, D, Attr); + break; case AttributeList::AT_Overloadable: handleSimpleAttribute(S, D, Attr); break; case AttributeList::AT_Ownership: handleOwnershipAttr (S, D, Attr); break; -- cgit v1.2.3