Fix <rdar://problem/6497608> clang does not catch ivar type mismatches in @implementation.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65948 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 59b6e93..19a2a63 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Sema.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/Parse/DeclSpec.h"
@@ -688,20 +689,29 @@
     ObjCIvarDecl* ClsIvar = *IVI;
     assert (ImplIvar && "missing implementation ivar");
     assert (ClsIvar && "missing class ivar");
+    
+    // First, make sure the types match.
     if (Context.getCanonicalType(ImplIvar->getType()) !=
         Context.getCanonicalType(ClsIvar->getType())) {
       Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_type)
         << ImplIvar->getIdentifier()
         << ImplIvar->getType() << ClsIvar->getType();
       Diag(ClsIvar->getLocation(), diag::note_previous_definition);
-    }
-    // TODO: Two mismatched (unequal width) Ivar bitfields should be diagnosed 
-    // as error.
-    else if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
+    } else if (ImplIvar->isBitField() && ClsIvar->isBitField()) {
+      Expr *ImplBitWidth = ImplIvar->getBitWidth();
+      Expr *ClsBitWidth = ClsIvar->getBitWidth();
+      if (ImplBitWidth->getIntegerConstantExprValue(Context).getZExtValue() !=
+          ClsBitWidth->getIntegerConstantExprValue(Context).getZExtValue()) {
+        Diag(ImplBitWidth->getLocStart(), diag::err_conflicting_ivar_bitwidth)
+          << ImplIvar->getIdentifier();
+        Diag(ClsBitWidth->getLocStart(), diag::note_previous_definition);
+      }
+    } 
+    // Make sure the names are identical.
+    if (ImplIvar->getIdentifier() != ClsIvar->getIdentifier()) {
       Diag(ImplIvar->getLocation(), diag::err_conflicting_ivar_name)
         << ImplIvar->getIdentifier() << ClsIvar->getIdentifier();
       Diag(ClsIvar->getLocation(), diag::note_previous_definition);
-      return;
     }
     --numIvars;
   }