Handle nonnull attribute with optional argument number on
functions with arguments of transparent unions type.
// rdar://9584012


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133941 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 9302277..f5e80d5 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -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?