Hi Eli,<div><br></div><div>This "breaks" pointer arithmetic for some cases with undefined behavior (but which are probably common anyway):</div><div><br></div><div>  int a;</div><div>  bool b = &a - 1 < &a;<br>
<br>I suspect (without evidence) that this happens frequently in real code. Perhaps we should refuse to fold a pointer comparison for a non-null base if either (unsigned) offset is greater than the size of the base object?</div>
<div><br><div class="gmail_quote">On Sun, Apr 15, 2012 at 9:30 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com">eli.friedman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: efriedma<br>
Date: Sun Apr 15 23:30:08 2012<br>
New Revision: 154794<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=154794&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=154794&view=rev</a><br>
Log:<br>
Make constant evaluation for pointer comparisons work correctly for some uncommon cases.  <rdar://problem/10962435>.<br>
<br>
<br>
Added:<br>
    cfe/trunk/test/Sema/const-eval-64.c<br>
Modified:<br>
    cfe/trunk/lib/AST/ExprConstant.cpp<br>
    cfe/trunk/test/Sema/const-eval.c<br>
<br>
Modified: cfe/trunk/lib/AST/ExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=154794&r1=154793&r2=154794&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=154794&r1=154793&r2=154794&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Apr 15 23:30:08 2012<br>
@@ -5088,14 +5088,26 @@<br>
         }<br>
       }<br>
<br>
+      // The comparison here must be unsigned, and performed with the same<br>
+      // width as the pointer.<br>
+      // FIXME: Knowing the base is the same for the LHS and RHS isn't enough<br>
+      // for relational operators.<br>
+      unsigned PtrSize = Info.Ctx.getTypeSize(LHSTy);<br>
+      uint64_t CompareLHS = LHSOffset.getQuantity();<br>
+      uint64_t CompareRHS = RHSOffset.getQuantity();<br>
+      assert(PtrSize <= 64 && "Unexpected pointer width");<br>
+      uint64_t Mask = ~0ULL >> (64 - PtrSize);<br>
+      CompareLHS &= Mask;<br>
+      CompareRHS &= Mask;<br>
+<br>
       switch (E->getOpcode()) {<br>
       default: llvm_unreachable("missing comparison operator");<br>
-      case BO_LT: return Success(LHSOffset < RHSOffset, E);<br>
-      case BO_GT: return Success(LHSOffset > RHSOffset, E);<br>
-      case BO_LE: return Success(LHSOffset <= RHSOffset, E);<br>
-      case BO_GE: return Success(LHSOffset >= RHSOffset, E);<br>
-      case BO_EQ: return Success(LHSOffset == RHSOffset, E);<br>
-      case BO_NE: return Success(LHSOffset != RHSOffset, E);<br>
+      case BO_LT: return Success(CompareLHS < CompareRHS, E);<br>
+      case BO_GT: return Success(CompareLHS > CompareRHS, E);<br>
+      case BO_LE: return Success(CompareLHS <= CompareRHS, E);<br>
+      case BO_GE: return Success(CompareLHS >= CompareRHS, E);<br>
+      case BO_EQ: return Success(CompareLHS == CompareRHS, E);<br>
+      case BO_NE: return Success(CompareLHS != CompareRHS, E);<br>
       }<br>
     }<br>
   }<br>
<br>
Added: cfe/trunk/test/Sema/const-eval-64.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-eval-64.c?rev=154794&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-eval-64.c?rev=154794&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Sema/const-eval-64.c (added)<br>
+++ cfe/trunk/test/Sema/const-eval-64.c Sun Apr 15 23:30:08 2012<br>
@@ -0,0 +1,7 @@<br>
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-linux %s<br>
+<br>
+#define EVAL_EXPR(testno, expr) int test##testno = sizeof(struct{char qq[expr];});<br>
+<br>
+// <rdar://problem/10962435><br>
+EVAL_EXPR(1, ((char*)-1LL) + 1 == 0 ? 1 : -1)<br>
+EVAL_EXPR(2, ((char*)-1LL) + 1 < (char*) -1 ? 1 : -1)<br>
<br>
Modified: cfe/trunk/test/Sema/const-eval.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-eval.c?rev=154794&r1=154793&r2=154794&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/const-eval.c?rev=154794&r1=154793&r2=154794&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Sema/const-eval.c (original)<br>
+++ cfe/trunk/test/Sema/const-eval.c Sun Apr 15 23:30:08 2012<br>
@@ -121,3 +121,7 @@<br>
 // <rdar://problem/11205586><br>
 // (Make sure we continue to reject this.)<br>
 EVAL_EXPR(44, "x"[0]); // expected-error {{variable length array}}<br>
+<br>
+// <rdar://problem/10962435><br>
+EVAL_EXPR(45, ((char*)-1) + 1 == 0 ? 1 : -1)<br>
+EVAL_EXPR(46, ((char*)-1) + 1 < (char*) -1 ? 1 : -1)<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>