AST: Don't assume two zero sized objects live at different addresses

Zero sized objects may overlap with each other or any other object.

This fixes PR21786.

llvm-svn: 223852
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 2891338..acf78ef 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -1422,6 +1422,12 @@
   return Decl && Decl->isWeak();
 }
 
+static bool isZeroSized(const LValue &Value) {
+  const ValueDecl *Decl = GetLValueBaseDecl(Value);
+  return Decl && isa<VarDecl>(Decl) &&
+         Decl->getASTContext().getTypeSize(Decl->getType()) == 0;
+}
+
 static bool EvalPointerValueAsBool(const APValue &Value, bool &Result) {
   // A null base expression indicates a null pointer.  These are always
   // evaluatable, and they are false unless the offset is zero.
@@ -6979,6 +6985,10 @@
             (RHSValue.Base && RHSValue.Offset.isZero() &&
              isOnePastTheEndOfCompleteObject(Info.Ctx, LHSValue)))
           return Error(E);
+        // We can't tell whether an object is at the same address as another
+        // zero sized object.
+        if (isZeroSized(LHSValue) || isZeroSized(RHSValue))
+          return Error(E);
         // Pointers with different bases cannot represent the same object.
         // (Note that clang defaults to -fmerge-all-constants, which can
         // lead to inconsistent results for comparisons involving the address