re PR middle-end/50189 (Wrong code error in -O2 [-fstrict-enums] compile, target...
authorPaul Koning <pkoning@gcc.gnu.org>
Wed, 12 Oct 2011 15:16:14 +0000 (11:16 -0400)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 12 Oct 2011 15:16:14 +0000 (15:16 +0000)
2011-10-12  Paul Koning  <pkoning@gcc.gnu.org>

PR tree-optimization/50189
* tree-vrp.c (extract_range_from_assert): Use the type of
the variable, not the limit.

* g++.dg/torture/pr50189.C: New testcase.

From-SVN: r179857

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr50189.C [new file with mode: 0644]
gcc/tree-vrp.c

index 6bc0bd6809bec612ebf71b78a3101f515b8dccc4..194fdb5a7ada575a1fceebaae3be6a7a40df3d3e 100644 (file)
@@ -1,3 +1,9 @@
+2011-10-12  Paul Koning  <pkoning@gcc.gnu.org>
+
+       PR tree-optimization/50189
+       * tree-vrp.c (extract_range_from_assert): Use the type of
+       the variable, not the limit.
+
 2011-10-12  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/50700
index 827aa2dced8565171aa9088b605c8882de7f5ccb..5af301f78237d740f7f03f397b878911041ace9d 100644 (file)
@@ -1,3 +1,8 @@
+2011-10-12  Paul Koning  <pkoning@gcc.gnu.org>
+
+       PR tree-optimization/50189
+       * g++.dg/torture/pr50189.C: New testcase.
+
 2011-10-12  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/50700
diff --git a/gcc/testsuite/g++.dg/torture/pr50189.C b/gcc/testsuite/g++.dg/torture/pr50189.C
new file mode 100644 (file)
index 0000000..06f1d36
--- /dev/null
@@ -0,0 +1,121 @@
+// { dg-do run }
+// { dg-options "-fstrict-enums" }
+
+extern "C" void abort (void);
+class CCUTILS_KeyedScalarLevelPosition
+{
+public:
+
+    typedef enum
+    {
+        UNINITED = 0,
+        AT_BEGIN = 1,
+        AT_END = 2,
+        AT_KEY = 3
+
+    } position_t;
+
+    bool is_init() const
+    { return(m_timestamp != UNINITED); }
+
+    bool is_at_begin() const
+    { return(m_timestamp == AT_BEGIN); }
+
+    position_t get_state() const
+    {
+        return((m_timestamp >= AT_KEY)
+             ? AT_KEY
+             : ((position_t)m_timestamp));
+    }
+
+    void set_at_begin()
+    { m_timestamp = AT_BEGIN; }
+
+    unsigned int get_index() const
+    { return(m_index); }
+
+    void set_pos(unsigned int a_index, unsigned int a_timestmap)
+    {
+        m_index = a_index;
+        m_timestamp = a_timestmap;
+    }
+
+    bool check_pos(unsigned int a_num_entries, unsigned int a_timestamp) const
+    {
+        if (get_state() != AT_KEY)
+            return(false);
+
+        if (m_timestamp != a_timestamp)
+            return(false);
+
+        return(m_index < a_num_entries);
+    }
+
+    void set_not_init()
+    { m_timestamp = 0; }
+
+private:
+
+    unsigned int m_timestamp;
+    unsigned int m_index;
+
+};
+
+class CCUTILS_KeyedScalarPosition
+{
+public:
+
+    CCUTILS_KeyedScalarLevelPosition m_L1;
+    CCUTILS_KeyedScalarLevelPosition m_L2;
+};
+
+class baz
+{
+public:
+    int *n[20];
+    unsigned int m_cur_array_len;
+    unsigned int m_timestamp;
+
+    unsigned int _get_timestamp() const
+    { return(m_timestamp); }
+
+    bool _check_L1_pos(const CCUTILS_KeyedScalarPosition &a_position) const
+    {
+        return(a_position.m_L1.check_pos(
+                   m_cur_array_len, _get_timestamp()));
+    }
+
+    void *next (CCUTILS_KeyedScalarPosition &);
+};
+
+void * baz::next (CCUTILS_KeyedScalarPosition &a_position)
+{
+    if (a_position.m_L1.is_at_begin() || (!a_position.m_L1.is_init()))
+    {
+        a_position.m_L1.set_pos(0, _get_timestamp());
+        a_position.m_L2.set_at_begin();
+    }
+    else if (!_check_L1_pos(a_position))
+        return(0);
+
+    return n[a_position.m_L1.get_index ()];
+}
+
+int main (int, char **)
+{
+    baz obj;
+    CCUTILS_KeyedScalarPosition a_pos;
+    void *ret;
+    int n[5];
+    
+    obj.n[0] = n;
+    obj.m_cur_array_len = 1;
+    obj.m_timestamp = 42;
+    
+    a_pos.m_L1.set_pos (0, 42);
+    
+    ret = obj.next (a_pos);
+    if (ret == 0)
+      abort ();
+    return 0;
+}
index 56fc5a20b2b4a65f0773e566e4f2d9918587a7d7..604e7f0ad02aaaec8531edf6a98fcb9df0b4dea9 100644 (file)
@@ -1519,7 +1519,7 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
 
   limit = avoid_overflow_infinity (limit);
 
-  type = TREE_TYPE (limit);
+  type = TREE_TYPE (var);
   gcc_assert (limit != var);
 
   /* For pointer arithmetic, we only keep track of pointer equality
@@ -1693,8 +1693,8 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
          /* For LT_EXPR, we create the range [MIN, MAX - 1].  */
          if (cond_code == LT_EXPR)
            {
-             tree one = build_int_cst (type, 1);
-             max = fold_build2 (MINUS_EXPR, type, max, one);
+             tree one = build_int_cst (TREE_TYPE (max), 1);
+             max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max, one);
              if (EXPR_P (max))
                TREE_NO_WARNING (max) = 1;
            }
@@ -1728,8 +1728,8 @@ extract_range_from_assert (value_range_t *vr_p, tree expr)
          /* For GT_EXPR, we create the range [MIN + 1, MAX].  */
          if (cond_code == GT_EXPR)
            {
-             tree one = build_int_cst (type, 1);
-             min = fold_build2 (PLUS_EXPR, type, min, one);
+             tree one = build_int_cst (TREE_TYPE (min), 1);
+             min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min, one);
              if (EXPR_P (min))
                TREE_NO_WARNING (min) = 1;
            }