diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-01-31 06:41:30 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-01-31 06:41:30 +0000 |
commit | de21b245c664ffa810b933319dd51e56b192761a (patch) | |
tree | 046b2a57f31cb520df612163d2ce80d1fc9e4b6e /clang/lib/AST/ExprConstant.cpp | |
parent | f1179025ae43be2b23d6c936f10063aab622ea2a (diff) | |
download | bcm5719-llvm-de21b245c664ffa810b933319dd51e56b192761a.tar.gz bcm5719-llvm-de21b245c664ffa810b933319dd51e56b192761a.zip |
constexpr: the result of a relational operator between pointers to void is
unspecified unless the pointers are equal; therefore, such a comparison is not
a constant expression unless the pointers are equal.
llvm-svn: 149366
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index c038e3feae7..5a385e6eb47 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -4331,6 +4331,18 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { const CharUnits &LHSOffset = LHSValue.getLValueOffset(); const CharUnits &RHSOffset = RHSValue.getLValueOffset(); + + // C++11 [expr.rel]p3: + // Pointers to void (after pointer conversions) can be compared, with a + // result defined as follows: If both pointers represent the same + // address or are both the null pointer value, the result is true if the + // operator is <= or >= and false otherwise; otherwise the result is + // unspecified. + // We interpret this as applying to pointers to *cv* void. + if (LHSTy->isVoidPointerType() && LHSOffset != RHSOffset && + E->getOpcode() != BO_EQ && E->getOpcode() != BO_NE) + CCEDiag(E, diag::note_constexpr_void_comparison); + switch (E->getOpcode()) { default: llvm_unreachable("missing comparison operator"); case BO_LT: return Success(LHSOffset < RHSOffset, E); |