if (binop->get_arg0 () == arg1)
return get_or_create_cast (type, binop->get_arg1 ());
break;
+ case POINTER_DIFF_EXPR:
+ /* (X POINTER_PLUS Y) POINTER_DIFF_EXPR X -> Y. */
+ if (const binop_svalue *binop = arg0->dyn_cast_binop_svalue ())
+ if (binop->get_op () == POINTER_PLUS_EXPR)
+ if (binop->get_arg0 () == arg1)
+ return get_or_create_cast (type, binop->get_arg1 ());
+ break;
case MULT_EXPR:
/* (VAL * 0). */
if (cst1
--- /dev/null
+#include "analyzer-decls.h"
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+
+ptrdiff_t
+ptrdiff_hidden_from_optimizer (const char *, const char *)
+ __attribute__((noinline));
+
+ptrdiff_t
+ptrdiff_hidden_from_optimizer (const char *p, const char *q)
+{
+ return p - q;
+}
+
+void
+test_concrete (void)
+{
+ const char *abc = "abc";
+ __analyzer_eval (ptrdiff_hidden_from_optimizer (abc + 3, abc) == 3); // { dg-warning "TRUE" }
+}
+
+void
+test_symbolic (size_t sz)
+{
+ const char *abc = "abc";
+ __analyzer_eval (ptrdiff_hidden_from_optimizer (abc + sz, abc) == sz); // { dg-warning "TRUE" }
+}