Teach sema and codegen about the difference between address of labels,
which is a common idiom to improve PIC'ness of code using the addr of
label extension.  This implementation is a gross hack, but the only other
alternative would be to teach evalutate about this horrid combination.
While GCC allows things like "&&foo - &&bar + 1", people don't use this
in practice.  This implements PR5131.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83957 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 6da11c1..8516d41 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1256,15 +1256,24 @@
   }
   case ImplicitValueInitExprClass:
     return true;
-  case ParenExprClass: {
+  case ParenExprClass:
     return cast<ParenExpr>(this)->getSubExpr()->isConstantInitializer(Ctx);
-  }
   case UnaryOperatorClass: {
     const UnaryOperator* Exp = cast<UnaryOperator>(this);
     if (Exp->getOpcode() == UnaryOperator::Extension)
       return Exp->getSubExpr()->isConstantInitializer(Ctx);
     break;
   }
+  case BinaryOperatorClass: {
+    // Special case &&foo - &&bar.  It would be nice to generalize this somehow
+    // but this handles the common case.
+    const BinaryOperator *Exp = cast<BinaryOperator>(this);
+    if (Exp->getOpcode() == BinaryOperator::Sub &&
+        isa<AddrLabelExpr>(Exp->getLHS()->IgnoreParenNoopCasts(Ctx)) &&
+        isa<AddrLabelExpr>(Exp->getRHS()->IgnoreParenNoopCasts(Ctx)))
+      return true;
+    break;
+  }
   case ImplicitCastExprClass:
   case CStyleCastExprClass:
     // Handle casts with a destination that's a struct or union; this