]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR middle-end/50189 (Wrong code error in -O2 [-fstrict-enums] compile...
authorRichard Guenther <rguenther@suse.de>
Tue, 3 Jan 2012 15:28:19 +0000 (15:28 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 3 Jan 2012 15:28:19 +0000 (15:28 +0000)
2012-01-03  Richard Guenther  <rguenther@suse.de>

Backport from mainline
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: r182850

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

index d8f3174d587a5bb8527e1e738eee67eac8a6b7a4..148276d819f6d0d5c18186559e6111804cde83f2 100644 (file)
@@ -1,3 +1,12 @@
+2012-01-03  Richard Guenther  <rguenther@suse.de>
+
+       Backport from mainline
+       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.
+
 2012-01-03  Richard Guenther  <rguenther@suse.de>
 
        Backport from mainline
index 1fedf3408125441f98bfeaa9c062339fcdf97f1a..52d9121408cad2f45d8692b75a6f64e56374a3f0 100644 (file)
@@ -1,3 +1,11 @@
+2012-01-03  Richard Guenther  <rguenther@suse.de>
+
+       Backport from mainline
+       2011-10-12  Paul Koning  <pkoning@gcc.gnu.org>
+
+       PR tree-optimization/50189
+       * g++.dg/torture/pr50189.C: New testcase.
+
 2012-01-03  Richard Guenther  <rguenther@suse.de>
 
        Backport from mainline
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..519e1a4
--- /dev/null
@@ -0,0 +1,120 @@
+// { dg-do run }
+
+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 62011fd0b96e0e9f549f860b6b3a68603472886d..3ed7b56e8a60004370547ec2e9e0c525dfcdce47 100644 (file)
@@ -1445,7 +1445,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
@@ -1619,8 +1619,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;
            }
@@ -1654,8 +1654,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;
            }