Fix regression in r216520: don't apply nonnull to non-pointer function

parameters in the IR.

llvm-svn: 216574
This commit is contained in:
Richard Smith 2014-08-27 18:56:18 +00:00
parent c26a79d4f2
commit 00cc1c09c3
2 changed files with 31 additions and 2 deletions
clang
lib/CodeGen
test/CodeGen

View File

@ -1557,8 +1557,17 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
llvm::Value *V = AI;
if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg)) {
if ((NNAtt && NNAtt->isNonNull(PVD->getFunctionScopeIndex())) ||
PVD->hasAttr<NonNullAttr>())
// FIXME: __attribute__((nonnull)) can also be applied to:
// - references to pointers, where the pointee is known to be
// nonnull (apparently a Clang extension)
// - transparent unions containing pointers
// In the former case, LLVM IR cannot represent the constraint. In
// the latter case, we have no guarantee that the transparent union
// is in fact passed as a pointer.
if (((NNAtt && NNAtt->isNonNull(PVD->getFunctionScopeIndex())) ||
PVD->hasAttr<NonNullAttr>()) &&
(PVD->getType()->isAnyPointerType() ||
PVD->getType()->isBlockPointerType()))
AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
AI->getArgNo() + 1,
llvm::Attribute::NonNull));

View File

@ -21,3 +21,23 @@ int * bar3() __attribute__((returns_nonnull)) {
return &a;
}
// CHECK: define i32 @bar4(i32 %n, i32* nonnull %p)
int bar4(int n, int *p) __attribute__((nonnull)) {
return n + *p;
}
// CHECK: define i32 @bar5(i32 %n, i32* nonnull %p)
int bar5(int n, int *p) __attribute__((nonnull(1, 2))) {
return n + *p;
}
typedef union {
unsigned long long n;
int *p;
double d;
} TransparentUnion __attribute__((transparent_union));
// CHECK: define i32 @bar6(i64 %
int bar6(TransparentUnion tu) __attribute__((nonnull(1))) {
return *tu.p;
}