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