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 | 82f28583b8e81ae9b61635a0652f6a45623df16d (patch) | |
tree | 0c115e17cc6345a73e0627e2afde2cf40e3b9315 /lib/AST/ExprConstant.cpp | |
parent | ff8f9ec8336c62b5e3504e2a394f4b25c0cb1963 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149366 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index c038e3feae..5a385e6eb4 100644 --- a/lib/AST/ExprConstant.cpp +++ b/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); |