Hi rsmith, nlewycky, aaron.ballman,

We now have an LLVM-level nonnull attribute that can be applied to function 
parameters, and we emit it for reference types (as of r209723), but we don't 
yet emit it when a __attribute__((nonnull)) is provided. This patch adds 
support for turning     __attribute__((nonnull))  on the source level into 
nonnull at the IR level.

http://reviews.llvm.org/D4472

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

Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1381,6 +1381,10 @@
       ++AI;  // Skip the sret parameter.
   }
 
+  // Get the function-level nonnull attribute if it exists.
+  const NonNullAttr *NNAtt =
+    CurCodeDecl ? CurCodeDecl->getAttr<NonNullAttr>() : nullptr;
+
   // Track if we received the parameter as a pointer (indirect, byval, or
   // inalloca).  If already have a pointer, EmitParmDecl doesn't need to copy 
it
   // into a local alloca for us.
@@ -1468,6 +1472,13 @@
         assert(AI != Fn->arg_end() && "Argument mismatch!");
         llvm::Value *V = AI;
 
+        if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg))
+          if ((NNAtt && NNAtt->isNonNull(PVD->getFunctionScopeIndex())) ||
+              PVD->hasAttr<NonNullAttr>())
+            AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+                                                AI->getArgNo() + 1,
+                                                llvm::Attribute::NonNull));
+
         if (Arg->getType().isRestrictQualified())
           AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
                                               AI->getArgNo() + 1,
Index: test/CodeGen/nonnull.c
===================================================================
--- /dev/null
+++ test/CodeGen/nonnull.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck %s
+
+// CHECK: define void @foo(i32* nonnull %x)
+void foo(int * __attribute__((nonnull)) x) {
+  *x = 0;
+}
+
+// CHECK: define void @bar(i32* nonnull %x)
+void bar(int * x) __attribute__((nonnull(1)))  {
+  *x = 0;
+}
+
+// CHECK: define void @bar2(i32* %x, i32* nonnull %y)
+void bar2(int * x, int * y) __attribute__((nonnull(2)))  {
+  *x = 0;
+}
+
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1381,6 +1381,10 @@
       ++AI;  // Skip the sret parameter.
   }
 
+  // Get the function-level nonnull attribute if it exists.
+  const NonNullAttr *NNAtt =
+    CurCodeDecl ? CurCodeDecl->getAttr<NonNullAttr>() : nullptr;
+
   // Track if we received the parameter as a pointer (indirect, byval, or
   // inalloca).  If already have a pointer, EmitParmDecl doesn't need to copy it
   // into a local alloca for us.
@@ -1468,6 +1472,13 @@
         assert(AI != Fn->arg_end() && "Argument mismatch!");
         llvm::Value *V = AI;
 
+        if (const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(Arg))
+          if ((NNAtt && NNAtt->isNonNull(PVD->getFunctionScopeIndex())) ||
+              PVD->hasAttr<NonNullAttr>())
+            AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
+                                                AI->getArgNo() + 1,
+                                                llvm::Attribute::NonNull));
+
         if (Arg->getType().isRestrictQualified())
           AI->addAttr(llvm::AttributeSet::get(getLLVMContext(),
                                               AI->getArgNo() + 1,
Index: test/CodeGen/nonnull.c
===================================================================
--- /dev/null
+++ test/CodeGen/nonnull.c
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm < %s | FileCheck %s
+
+// CHECK: define void @foo(i32* nonnull %x)
+void foo(int * __attribute__((nonnull)) x) {
+  *x = 0;
+}
+
+// CHECK: define void @bar(i32* nonnull %x)
+void bar(int * x) __attribute__((nonnull(1)))  {
+  *x = 0;
+}
+
+// CHECK: define void @bar2(i32* %x, i32* nonnull %y)
+void bar2(int * x, int * y) __attribute__((nonnull(2)))  {
+  *x = 0;
+}
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to