From 3567c426c4f3a79a41ab976afb16c5c5848f7dcd Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 27 Sep 2010 22:42:37 +0000 Subject: [PATCH] Patch to support transparent_union arguments passed to nonnull attributed functions. Implements radar 6857843. llvm-svn: 114917 --- clang/lib/AST/Expr.cpp | 7 +++++++ clang/lib/Sema/SemaDeclAttr.cpp | 13 +++++++++++++ clang/test/SemaObjC/nonnull.m | 19 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 9536b9bf2454..708512ce4619 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1862,6 +1862,13 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx, if (getType()->isNullPtrType()) return true; + if (const RecordType *UT = getType()->getAsUnionType()) + if (UT && UT->getDecl()->hasAttr()) + if (const CompoundLiteralExpr *CLE = dyn_cast(this)){ + const Expr *InitExpr = CLE->getInitializer(); + if (const InitListExpr *ILE = dyn_cast(InitExpr)) + return ILE->getInit(0)->isNullPointerConstant(Ctx, NPC); + } // This expression must be an integer type. if (!getType()->isIntegerType() || (Ctx.getLangOptions().CPlusPlus && getType()->isEnumeralType())) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 09feb50bd301..682a430ee406 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -371,6 +371,19 @@ static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) { QualType T = getFunctionOrMethodArgType(d, I); if (T->isAnyPointerType() || T->isBlockPointerType()) NonNullArgs.push_back(I); + else if (const RecordType *UT = T->getAsUnionType()) { + if (UT && UT->getDecl()->hasAttr()) { + RecordDecl *UD = UT->getDecl(); + for (RecordDecl::field_iterator it = UD->field_begin(), + itend = UD->field_end(); it != itend; ++it) { + T = it->getType(); + if (T->isAnyPointerType() || T->isBlockPointerType()) { + NonNullArgs.push_back(I); + break; + } + } + } + } } // No pointer arguments? The attribute in this case is diff --git a/clang/test/SemaObjC/nonnull.m b/clang/test/SemaObjC/nonnull.m index cbafc37e8ec0..6c45d97b0660 100644 --- a/clang/test/SemaObjC/nonnull.m +++ b/clang/test/SemaObjC/nonnull.m @@ -48,3 +48,22 @@ foo (int i1, int i2, int i3, void (^cp1)(), void (^cp2)(), void (^cp3)()) } void func5(int) NONNULL_ATTR; // no warning + +// rdar://6857843 +struct dispatch_object_s { + int x; +}; + +typedef union { + long first; + struct dispatch_object_s *_do; +} dispatch_object_t __attribute__((transparent_union)); + +__attribute__((nonnull)) +void _dispatch_queue_push_list(dispatch_object_t _head); // no warning + +void func6(dispatch_object_t _head) { + _dispatch_queue_push_list(0); // expected-warning {{null passed to a callee which requires a non-null argument}} + _dispatch_queue_push_list(_head._do); // no warning +} +