]> granicus.if.org Git - clang/commitdiff
Fix regression in r216520: don't apply nonnull to non-pointer function
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 27 Aug 2014 18:56:18 +0000 (18:56 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 27 Aug 2014 18:56:18 +0000 (18:56 +0000)
parameters in the IR.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216574 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCall.cpp
test/CodeGen/nonnull.c

index 45a625908987785e1953acb7b3cac06fd5f5ed8e..c95680ccda6c535707814c0f137f8163cab96697 100644 (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));
index 4d6cc4568d8b19e382be2b581947cdde4f0186c0..e234105d9ad68acb996cad66ffe489a104ded08f 100644 (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;
+}