]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree-ssa-structalias.c (handle_ptr_arith): Make sure to only handle positive offsets...
authorRichard Biener <rguenth@gcc.gnu.org>
Tue, 19 Jun 2007 12:57:58 +0000 (12:57 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 19 Jun 2007 12:57:58 +0000 (12:57 +0000)
2007-06-19  Richard Guenther  <rguenther@suse.de>

* tree-ssa-structalias.c (handle_ptr_arith): Make sure to
only handle positive offsets that fit in a HOST_WIDE_INT.

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

From-SVN: r125849

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

index 3b9f881348d21434cc788240c9dbb8c7bf00596c..409885a20153b62381c15bd0456969fb740d4fc4 100644 (file)
@@ -1,4 +1,9 @@
-2007-06-18  Uros Bizjak  <ubizjak@gmail.com>
+2007-06-19  Richard Guenther  <rguenther@suse.de>
+
+       * tree-ssa-structalias.c (handle_ptr_arith): Make sure to
+       only handle positive offsets that fit in a HOST_WIDE_INT.
+
+2007-06-19  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/i386.c (ix86_emit_swsqrtsf): Limit the result of
        rsqrt insn to FLT_MAX to avoid NaN for zero input argument.
index 467635d0fb737325f57d535657f5fb30504c4dc6..dd2a1a40e2b12b92fe82bf9f243c3791b59fba20 100644 (file)
@@ -1,3 +1,7 @@
+2007-06-19  Richard Guenther  <rguenther@suse.de>
+
+       * g++.dg/torture/pr30252.C: New testcase.
+
 2007-06-19  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/32353
diff --git a/gcc/testsuite/g++.dg/torture/pr30252.C b/gcc/testsuite/g++.dg/torture/pr30252.C
new file mode 100644 (file)
index 0000000..aabf88f
--- /dev/null
@@ -0,0 +1,226 @@
+/* { dg-do run } */
+/* { dg-options "-fstrict-aliasing" } */
+
+extern "C" void abort (void);
+namespace sigc {
+  template <class T_type>
+  struct type_trait
+  {
+    typedef T_type& pass;
+    typedef const T_type& take;
+    typedef T_type* pointer;
+  };
+  template <class T_base, class T_derived>
+  struct is_base_and_derived
+  {
+    struct big {
+      char memory[64];
+    };
+    static big is_base_class_(...);
+    static char is_base_class_(typename type_trait<T_base>::pointer);
+    static const bool value =
+    sizeof(is_base_class_(reinterpret_cast<typename type_trait<T_derived>::pointer>(0))) ==
+    sizeof(char);
+  };
+  struct nil;
+  struct functor_base {};
+  template <class T_functor, bool I_derives_functor_base=is_base_and_derived<functor_base,T_functor>::value>
+  struct functor_trait
+  {
+  };
+  template <class T_functor>
+  struct functor_trait<T_functor,true>
+  {
+    typedef typename T_functor::result_type result_type;
+    typedef T_functor functor_type;
+  };
+  template <class T_arg1, class T_return>
+  class pointer_functor1 : public functor_base
+  {
+    typedef T_return (*function_type)(T_arg1);
+    function_type func_ptr_;
+  public:
+    typedef T_return result_type;
+    explicit pointer_functor1(function_type _A_func): func_ptr_(_A_func) {}
+    T_return operator()(typename type_trait<T_arg1>::take _A_a1) const
+    { return func_ptr_(_A_a1); }
+  };
+  template <class T_arg1, class T_return>
+  inline pointer_functor1<T_arg1, T_return>
+  ptr_fun1(T_return (*_A_func)(T_arg1))
+  { return pointer_functor1<T_arg1, T_return>(_A_func); }
+  struct adaptor_base : public functor_base {};
+  template <class T_functor,
+    class T_arg1=void,
+    bool I_derives_adaptor_base=is_base_and_derived<adaptor_base,T_functor>::value>
+  struct deduce_result_type
+  { typedef typename functor_trait<T_functor>::result_type type; };
+  template <class T_functor>
+  struct adaptor_functor : public adaptor_base
+  {
+    template <class T_arg1=void>
+    struct deduce_result_type
+    { typedef typename sigc::deduce_result_type<T_functor, T_arg1>::type type; };
+    typedef typename functor_trait<T_functor>::result_type result_type;
+    result_type
+    operator()() const;
+    template <class T_arg1>
+    typename deduce_result_type<T_arg1>::type
+    operator()(T_arg1 _A_arg1) const
+    { return functor_(_A_arg1); }
+    explicit adaptor_functor(const T_functor& _A_functor)
+      : functor_(_A_functor)
+    {}
+    mutable T_functor functor_;
+  };
+  template <class T_functor>
+  typename adaptor_functor<T_functor>::result_type
+  adaptor_functor<T_functor>::operator()() const
+  { return functor_(); }
+  template <class T_functor, bool I_isadaptor = is_base_and_derived<adaptor_base, T_functor>::value> struct adaptor_trait;
+  template <class T_functor>
+  struct adaptor_trait<T_functor, true>
+  {
+    typedef T_functor adaptor_type;
+  };
+  template <class T_functor>
+  struct adaptor_trait<T_functor, false>
+  {
+    typedef typename functor_trait<T_functor>::functor_type functor_type;
+    typedef adaptor_functor<functor_type> adaptor_type;
+  };
+  template <class T_functor>
+  struct adapts : public adaptor_base
+  {
+    typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type;
+    explicit adapts(const T_functor& _A_functor)
+      : functor_(_A_functor)
+    {}
+    mutable adaptor_type functor_;
+  };
+  template <class T_type>
+  struct reference_wrapper
+  {
+  };
+  template <class T_type>
+  struct unwrap_reference
+  {
+    typedef T_type type;
+  };
+  template <class T_type>
+  class bound_argument
+  {
+  public:
+    bound_argument(const T_type& _A_argument)
+      : visited_(_A_argument)
+    {}
+    inline T_type& invoke()
+    { return visited_; }
+    T_type visited_;
+  };
+  template <class T_wrapped>
+  class bound_argument< reference_wrapper<T_wrapped> >
+  {
+  };
+  template <int I_location, class T_functor, class T_type1=nil>
+  struct bind_functor;
+  template <class T_functor, class T_type1>
+  struct bind_functor<-1, T_functor, T_type1> : public adapts<T_functor>
+  {
+    typedef typename adapts<T_functor>::adaptor_type adaptor_type;
+    typedef typename adaptor_type::result_type result_type;
+    result_type
+    operator()()
+    {
+      return this->functor_.template operator()<typename type_trait<typename unwrap_reference<T_type1>::type>::pass> (bound1_.invoke());
+    }
+    bind_functor(typename type_trait<T_functor>::take _A_func, typename type_trait<T_type1>::take _A_bound1)
+      : adapts<T_functor>(_A_func), bound1_(_A_bound1)
+    {}
+    bound_argument<T_type1> bound1_;
+  };
+  template <class T_type1, class T_functor>
+  inline bind_functor<-1, T_functor,
+                     T_type1>
+  bind(const T_functor& _A_func, T_type1 _A_b1)
+  { return bind_functor<-1, T_functor,
+      T_type1>
+      (_A_func, _A_b1);
+  }
+  namespace internal {
+    struct slot_rep;
+    typedef void* (*hook)(slot_rep *);
+    struct slot_rep
+    {
+      hook call_;
+    };
+  }
+  class slot_base : public functor_base
+  {
+  public:
+    typedef internal::slot_rep rep_type;
+    explicit slot_base(rep_type* rep)
+      : rep_(rep)
+    {
+    }
+    mutable rep_type *rep_;
+  };
+  namespace internal {
+    template <class T_functor>
+    struct typed_slot_rep : public slot_rep
+    {
+      typedef typename adaptor_trait<T_functor>::adaptor_type adaptor_type;
+      adaptor_type functor_;
+      inline typed_slot_rep(const T_functor& functor)
+       : functor_(functor)
+      {
+      }
+    };
+    template<class T_functor>
+    struct slot_call0
+    {
+      static void *call_it(slot_rep* rep)
+      {
+       typedef typed_slot_rep<T_functor> typed_slot;
+       typed_slot *typed_rep = static_cast<typed_slot*>(rep);
+       return (typed_rep->functor_)();
+      }
+      static hook address()
+      {
+       return &call_it;
+      }
+    };
+  }
+
+  class slot0 : public slot_base
+  {
+  public:
+    typedef void * (*call_type)(rep_type*);
+    inline void *operator()() const
+    {
+      return slot_base::rep_->call_ (slot_base::rep_);
+    }
+    template <class T_functor>
+    slot0(const T_functor& _A_func)
+      : slot_base(new internal::typed_slot_rep<T_functor>(_A_func))
+    {
+      slot_base::rep_->call_ = internal::slot_call0<T_functor>::address();
+    }
+  };
+}
+struct A
+{
+  static void *foo (void *p) { return p; }
+  typedef sigc::slot0 C;
+  C bar();
+};
+A::C A::bar ()
+{
+  return sigc::bind (sigc::ptr_fun1 (&A::foo), (void*)0);
+}
+int main (void)
+{
+  A a;
+  if (a.bar ()() != 0)
+    abort ();
+}
index 2b69728300231486f269a71d39ef01aa0655c9a7..663dff0b1cbeba9014c4e0b26fa01f15f250cf05 100644 (file)
@@ -3291,7 +3291,7 @@ handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr)
   unsigned int i = 0;
   unsigned int j = 0;
   VEC (ce_s, heap) *temp = NULL;
-  unsigned int rhsoffset = 0;
+  unsigned HOST_WIDE_INT rhsoffset = 0;
 
   if (TREE_CODE (expr) != POINTER_PLUS_EXPR)
     return false;
@@ -3302,8 +3302,15 @@ handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr)
 
   get_constraint_for (op0, &temp);
 
-  if (TREE_CODE (op1) == INTEGER_CST)
-    rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT;
+  /* We can only handle positive offsets that do not overflow
+     if we multiply it by BITS_PER_UNIT.  */
+  if (host_integerp (op1, 1))
+    {
+      rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT;
+
+      if (rhsoffset / BITS_PER_UNIT != TREE_INT_CST_LOW (op1))
+       return false;
+    }
 
   for (i = 0; VEC_iterate (ce_s, lhsc, i, c); i++)
     for (j = 0; VEC_iterate (ce_s, temp, j, c2); j++)