зеркало из https://github.com/microsoft/clang-1.git
Patch to support transparent_union arguments
passed to nonnull attributed functions. Implements radar 6857843. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114917 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
3e9438b525
Коммит
ff3a078d2a
|
@ -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<TransparentUnionAttr>())
|
||||
if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){
|
||||
const Expr *InitExpr = CLE->getInitializer();
|
||||
if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr))
|
||||
return ILE->getInit(0)->isNullPointerConstant(Ctx, NPC);
|
||||
}
|
||||
// This expression must be an integer type.
|
||||
if (!getType()->isIntegerType() ||
|
||||
(Ctx.getLangOptions().CPlusPlus && getType()->isEnumeralType()))
|
||||
|
|
|
@ -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<TransparentUnionAttr>()) {
|
||||
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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче