aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-01-31 06:41:30 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-01-31 06:41:30 +0000
commit82f28583b8e81ae9b61635a0652f6a45623df16d (patch)
tree0c115e17cc6345a73e0627e2afde2cf40e3b9315 /lib/AST/ExprConstant.cpp
parentff8f9ec8336c62b5e3504e2a394f4b25c0cb1963 (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.cpp12
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);