[cfe-commits] r133941 - in /cfe/trunk: lib/Sema/SemaDeclAttr.cpp test/Sema/nonnull.c

Fariborz Jahanian fjahanian at apple.com
Mon Jun 27 14:12:03 PDT 2011


Author: fjahanian
Date: Mon Jun 27 16:12:03 2011
New Revision: 133941

URL: http://llvm.org/viewvc/llvm-project?rev=133941&view=rev
Log:
Handle nonnull attribute with optional argument number on
functions with arguments of transparent unions type.
// rdar://9584012

Added:
    cfe/trunk/test/Sema/nonnull.c
Modified:
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=133941&r1=133940&r2=133941&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Jun 27 16:12:03 2011
@@ -361,6 +361,21 @@
                                                       QT));
 }
 
+static void PossibleTransparentUnionPointerType(QualType &T) {
+  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) {
+        QualType QT = it->getType();
+        if (QT->isAnyPointerType() || QT->isBlockPointerType()) {
+          T = QT;
+          return;
+        }
+      }
+    }
+}
+
 static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   // GCC ignores the nonnull attribute on K&R style function prototypes, so we
   // ignore it as well
@@ -413,6 +428,8 @@
 
     // Is the function argument a pointer type?
     QualType T = getFunctionOrMethodArgType(d, x).getNonReferenceType();
+    PossibleTransparentUnionPointerType(T);
+    
     if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
       // FIXME: Should also highlight argument in decl.
       S.Diag(Attr.getLoc(), diag::warn_nonnull_pointers_only)
@@ -428,21 +445,9 @@
   if (NonNullArgs.empty()) {
     for (unsigned I = 0, E = getFunctionOrMethodNumArgs(d); I != E; ++I) {
       QualType T = getFunctionOrMethodArgType(d, I).getNonReferenceType();
+      PossibleTransparentUnionPointerType(T);
       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?

Added: cfe/trunk/test/Sema/nonnull.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/nonnull.c?rev=133941&view=auto
==============================================================================
--- cfe/trunk/test/Sema/nonnull.c (added)
+++ cfe/trunk/test/Sema/nonnull.c Mon Jun 27 16:12:03 2011
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+// rdar://9584012
+
+typedef struct {
+	char *str;
+} Class;
+
+typedef union {
+	Class *object;
+} Instance __attribute__((transparent_union));
+
+__attribute__((nonnull(1))) void Class_init(Instance this, char *str) {
+	this.object->str = str;
+}
+
+int main(void) {
+	Class *obj;
+	Class_init(0, "Hello World"); // expected-warning {{null passed to a callee which requires a non-null argument}}
+	Class_init(obj, "Hello World");
+}
+





More information about the cfe-commits mailing list