diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /gcc/testsuite/g++.dg/tree-ssa | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'gcc/testsuite/g++.dg/tree-ssa')
135 files changed, 5400 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/tree-ssa/20040317-1.C b/gcc/testsuite/g++.dg/tree-ssa/20040317-1.C new file mode 100644 index 000000000..e2f3dcdce --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/20040317-1.C @@ -0,0 +1,38 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +/* Test provided by Brian Ryner in PR 14511. The alias analyzer was + not handling structures containing arrays properly. In this case, + the static cast was introducing two assignments of the form + + this_6->_vptr.IFoo = &_ZTV4IFoo[2]; + this_4->_vptr.IFoo = &_ZTV3Bar[2]; + + which were not considered to alias each other because the alias + analyzer was not computing a proper pointer to array elements. + Another related bug was the type based alias analyzer not computing + alias relations to _ZTV4IFoo and _ZTV3Bar. Since those variables + are read-only, it was disregarding alias information for them. + So, the memory tags for the two 'this' variables were not being + marked as aliased with these variables. Resulting in the two + assignments not aliasing each other. + + This was causing the optimizers to generate a call to the virtual + method Foo() instead of the overloaded version. */ + +struct IFoo +{ + virtual void Foo() = 0; +}; + +struct Bar : IFoo +{ + void Foo() { } +}; + +int main(int argc, char **argv) +{ + Bar* b = new Bar(); + static_cast<IFoo*>(b)->Foo(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/block1.C b/gcc/testsuite/g++.dg/tree-ssa/block1.C new file mode 100644 index 000000000..5573251cb --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/block1.C @@ -0,0 +1,11 @@ +// PR 13764: We were inserting an extra body block in all functions, but +// it's only really necessary for [cd]tors. +// { dg-options "-fdump-tree-gimple" } + +void bar (void) +{ + int a; +} + +// { dg-final { scan-tree-dump-times "\{" 1 "gimple" } } +// { dg-final { cleanup-tree-dump "gimple" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/builtin1.C b/gcc/testsuite/g++.dg/tree-ssa/builtin1.C new file mode 100644 index 000000000..76813cb8d --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/builtin1.C @@ -0,0 +1,10 @@ +// { dg-do link } + +extern void link_error(); + +int main() +{ + if (! __builtin_constant_p (&"Hello"[0])) + link_error(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/copyprop-1.C b/gcc/testsuite/g++.dg/tree-ssa/copyprop-1.C new file mode 100644 index 000000000..03f6b1207 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/copyprop-1.C @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-dce2" } */ + +/* Verify that we can eliminate the useless conversions to/from + const qualified pointer types + this_2 = o_1; + D.20003_4 = this_2->data_m; + this_5 = D.20003_4; + D.20005_6 = this_5->value; + copyprop should propagate o_1 and D.20003_4 to the loads of data_m + and value. dce removes all traces of this. */ + +struct Data { + int get() const { return value; } + int value; +}; + +struct Object { + int operator[](int i) const { return data_m->get(); } + Data *data_m; +}; + +int foo(Object&o) +{ + return o[0]; +} + +/* Remaining should be two loads. */ + +/* { dg-final { scan-tree-dump-times " = \[^\n\]*;" 2 "dce2" } } */ +/* { dg-final { cleanup-tree-dump "dce2" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/copyprop.C b/gcc/testsuite/g++.dg/tree-ssa/copyprop.C new file mode 100644 index 000000000..5ba193618 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/copyprop.C @@ -0,0 +1,739 @@ +// PR 39548 verify ssa ICE +// +// { dg-do compile { target { lp64 } } } +// { dg-options "-Wno-error -fno-exceptions -fno-tree-vrp -O2 -fprofile-generate -finline-limit=500" } +// + +#include <map> +#include <vector> +#include <iostream> +#include <cstdlib> +using namespace std; +template<typename _FIter, typename _Tp> _FIter lower_bound(_FIter, _FIter, _Tp&); +template<class _Key> struct hash { }; +template<class _Val> struct _Hashtable_node { + _Hashtable_node* _M_next; + _Val _M_val; +}; +static const unsigned long __stl_prime_list[] = { 2, 3, 5 }; +inline unsigned long prime(unsigned long __n) { + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + 29; + const unsigned long* pos = lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; +} +template<class _Val, class _Key, class _HashFcn, class _ExtractKey, class _EqualKey, class _Alloc> struct hashtable { + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; + typedef size_t size_type; + typedef value_type& reference; + typedef _Hashtable_node<_Val> _Node; + typedef typename _Alloc::template rebind<value_type>::other allocator_type; + allocator_type get_allocator() const { } + typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; + typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; + typedef vector<_Node*, _Nodeptr_Alloc> _Vector_type; + _Node_Alloc _M_node_allocator; + void _M_put_node(_Node* __p) { + _M_node_allocator.deallocate(__p, 1); + } + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + _Vector_type _M_buckets; + size_type _M_num_elements; + hashtable(size_type __n, const _HashFcn& __hf, const _EqualKey& __eql, const allocator_type& __a = allocator_type()) : _M_num_elements(0) { + _M_initialize_buckets(__n); + } + ~hashtable() { clear(); } + reference find_or_insert(const value_type& __obj); + size_type count(const key_type& __key) const { + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; + for (const _Node* __cur = _M_buckets[__n]; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) ++__result; + } + size_type erase(const key_type& __key); + void clear(); + size_type _M_next_size(size_type __n) const { return prime(__n); } + void _M_initialize_buckets(size_type __n) { + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + } + size_type _M_bkt_num_key(const key_type& __key) const { + return _M_bkt_num_key(__key, _M_buckets.size()); + } + size_type _M_bkt_num_key(const key_type& __key, size_t __n) const { + return _M_hash(__key) % __n; + } + void _M_delete_node(_Node* __n) { + this->get_allocator().destroy(&__n->_M_val); + _M_put_node(__n); + } +}; +template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: erase(const key_type& __key) { + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + if (__first) _Node* __cur = __first; +} +template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: clear() { + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) { _M_delete_node(__cur); } + } +} +template<class _Key, class _Tp, class _HashFn = hash<_Key>, class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> > struct hash_map { + typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn, _Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc> _Ht; + _Ht _M_ht; + typedef typename _Ht::key_type key_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + typedef typename _Ht::size_type size_type; + typedef typename _Ht::allocator_type allocator_type; + hash_map() : _M_ht(100, hasher(), key_equal(), allocator_type()) { } + _Tp& operator[](const key_type& __key) { + return _M_ht.find_or_insert(value_type(__key, _Tp())).second; + } + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + size_type erase(const key_type& __key) { + return _M_ht.erase(__key); + } +}; +extern size_t strlen (__const char *__s); +template <class C> struct scoped_ptr { + explicit scoped_ptr(C* p = __null) : ptr_(p) { delete ptr_; } + void reset(C* p = __null) { + if (p != ptr_) { delete ptr_; } + } + C& operator*() const {} + C* operator->() const {} + bool operator==(C* p) const { return ptr_ == p; } + bool operator!=(C* p) const { return ptr_ != p; } + C* ptr_; +}; +namespace std { +class strstreambuf : public basic_streambuf<char, char_traits<char> > { +}; +class strstream : public basic_iostream<char> { + public: int pcount() const; + char* str(); + strstreambuf _M_buf; +}; +}; +const int INFO = 0, WARNING = 1, ERROR = 2, FATAL = 3, NUM_SEVERITIES = 4; +struct foo_1 { + foo_1(string* str) : str_(str) { } + operator bool() const { + return (__builtin_expect(str_ != __null, 0)); + } + string* str_; +}; +template<class t1, class t2> string* Makefoo_1(const t1& v1, const t2& v2, const char* names) { + strstream ss; + ss << names << " (" << v1 << " vs. " << v2 << ")"; + return new string(ss.str(), ss.pcount()); +} +template <class t1, class t2> inline string* Check_GTImpl(const t1& v1, const t2& v2, const char* names) { + if (v1 > v2) return __null; + else return Makefoo_1(v1, v2, names); +} +struct blah_54 { + blah_54(const char* file, int line, int severity); + ~blah_54(); + ostream& stream() { }; +}; +class blah_0 : public blah_54 { + public: blah_0(const char* file, int line); + blah_0(const char* file, int line, const foo_1& result); +}; +template <class Value, class Key, class HashFcn, class ExtractKey, class EqualKey, class Alloc> class dense_hashtable; +template <class V, class K, class HF, class ExK, class EqK, class A> struct dense_hashtable_iterator { + typedef V* pointer; + dense_hashtable_iterator(const dense_hashtable<V,K,HF,ExK,EqK,A> *h, pointer it, pointer it_end, bool advance) : ht(h), pos(it), end(it_end) { + if (advance) advance_past_empty_and_deleted(); + } + pointer operator->() const { } + void advance_past_empty_and_deleted() { + while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this)) ) ++pos; + } + const dense_hashtable<V,K,HF,ExK,EqK,A> *ht; + pointer pos, end; +}; +template <class V, class K, class HF, class ExK, class EqK, class A> struct dense_hashtable_const_iterator { + typedef dense_hashtable_iterator<V,K,HF,ExK,EqK,A> iterator; + typedef dense_hashtable_const_iterator<V,K,HF,ExK,EqK,A> const_iterator; + typedef const V& reference; + typedef const V* pointer; + dense_hashtable_const_iterator(const dense_hashtable<V,K,HF,ExK,EqK,A> *h, pointer it, pointer it_end, bool advance) : ht(h), pos(it), end(it_end) { + if (advance) advance_past_empty_and_deleted(); + } + dense_hashtable_const_iterator(const iterator &it) : pos(it.pos), end(it.end) {} + reference operator*() const { return *pos; } + pointer operator->() const {} + void advance_past_empty_and_deleted() { + while ( pos != end && (ht->test_empty(*this) || ht->test_deleted(*this))) ++pos; + } + const_iterator& operator++() { } + bool operator!=(const const_iterator& it) const { } + const dense_hashtable<V,K,HF,ExK,EqK,A> *ht; + pointer pos, end; +}; +template <class Value, class Key, class HashFcn, class ExtractKey, class EqualKey, class Alloc> class dense_hashtable { + public: typedef Key key_type; + typedef Value value_type; + typedef HashFcn hasher; + typedef EqualKey key_equal; + typedef size_t size_type; + typedef dense_hashtable_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> iterator; + typedef dense_hashtable_const_iterator<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> const_iterator; + static const float HT_OCCUPANCY_FLT; + static const float HT_EMPTY_FLT; + static const size_t HT_MIN_BUCKETS = 32; + iterator end() { + return iterator(this, table + num_buckets, table + num_buckets, true); + } + const_iterator end() const { + return const_iterator(this, table + num_buckets, table+num_buckets,true); + } + void set_value(value_type* dst, const value_type& src) { + new(dst) value_type(src); + } + void destroy_buckets(size_type first, size_type last) { + for (; first != last; ++first) table[first].~value_type(); + } + private: void squash_deleted() { + if ( num_deleted ) { + dense_hashtable tmp(*this); + swap(tmp); + } + } + public: void set_deleted_key(const value_type &val) { squash_deleted(); } + bool test_deleted(size_type bucknum) const { + return (use_deleted && num_deleted > 0 && equals(get_key(delval), get_key(table[bucknum]))); + } + bool test_deleted(const const_iterator &it) const { + return (use_deleted && num_deleted > 0 && equals(get_key(delval), get_key(*it))); + } + bool set_deleted(const_iterator &it) { + set_value(const_cast<value_type*>(&(*it)), delval); + } + bool test_empty(size_type bucknum) const { + return equals(get_key(emptyval), get_key(table[bucknum])); + } + bool test_empty(const const_iterator &it) const { + return equals(get_key(emptyval), get_key(*it)); + } + void fill_range_with_empty(value_type* table_start, value_type* table_end) { + uninitialized_fill(table_start, table_end, emptyval); + } + void set_empty(size_type buckstart, size_type buckend) { + destroy_buckets(buckstart, buckend); + fill_range_with_empty(table + buckstart, table + buckend); + } + size_type size() const { + return num_elements - num_deleted; + } + size_type bucket_count() const { } + static const size_type ILLEGAL_BUCKET = size_type(-1); + size_type min_size(size_type num_elts, size_type min_buckets_wanted) { + size_type sz = HT_MIN_BUCKETS; + while ( sz < min_buckets_wanted || num_elts >= sz * enlarge_resize_percent ) sz *= 2; + } + void maybe_shrink() { + if (shrink_threshold > 0 && (num_elements-num_deleted) < shrink_threshold && bucket_count() > HT_MIN_BUCKETS ) { + size_type sz = bucket_count() / 2; + sz /= 2; + dense_hashtable tmp(*this, sz); + swap(tmp); + } + } + void resize_delta(size_type delta, size_type min_buckets_wanted = 0) { + if ( consider_shrink ) maybe_shrink(); + const size_type needed_size = min_size(num_elements + delta, min_buckets_wanted); + if ( needed_size > bucket_count() ) { + const size_type resize_to = min_size(num_elements - num_deleted + delta, min_buckets_wanted); + dense_hashtable tmp(*this, resize_to); + swap(tmp); + } + } + void copy_from(const dense_hashtable &ht, size_type min_buckets_wanted = 0) { + clear(); + const size_type resize_to = min_size(ht.size(), min_buckets_wanted); + num_elements++; + } + explicit dense_hashtable(size_type n = 0, const HashFcn& hf = HashFcn(), const EqualKey& eql = EqualKey(),const ExtractKey& ext = ExtractKey()) : num_deleted(0), use_deleted(false), use_empty(false), delval(), emptyval(), enlarge_resize_percent(HT_OCCUPANCY_FLT), shrink_resize_percent(HT_EMPTY_FLT), table(__null), num_buckets(min_size(0, n)), num_elements(0) { + reset_thresholds(); + } + dense_hashtable(const dense_hashtable& ht, size_type min_buckets_wanted = 0) : num_deleted(0), use_deleted(ht.use_deleted), use_empty(ht.use_empty), delval(ht.delval), emptyval(ht.emptyval), enlarge_resize_percent(ht.enlarge_resize_percent), shrink_resize_percent(ht.shrink_resize_percent), table(__null), num_buckets(0), num_elements(0) { + reset_thresholds(); + copy_from(ht, min_buckets_wanted); + set_value(&emptyval, ht.emptyval); + enlarge_resize_percent = ht.enlarge_resize_percent; + copy_from(ht); + } + ~dense_hashtable() { + if (table) { + destroy_buckets(0, num_buckets); + free(table); + } + } + void swap(dense_hashtable& ht) { + std::swap(equals, ht.equals); + { + value_type tmp; + set_value(&delval, ht.delval); + set_value(&ht.delval, tmp); + set_value(&ht.emptyval, tmp); + } + std::swap(table, ht.table); + std::swap(num_buckets, ht.num_buckets); + reset_thresholds(); + ht.reset_thresholds(); + } + void clear() { + if (table) destroy_buckets(0, num_buckets); + num_buckets = min_size(0,0); + set_empty(0, num_buckets); + } + pair<size_type, size_type> find_position(const key_type &key) const { + const size_type bucket_count_minus_one = bucket_count() - 1; + size_type bucknum = hash(key) & bucket_count_minus_one; + size_type insert_pos = ILLEGAL_BUCKET; + while ( 1 ) { + if ( test_empty(bucknum) ) { + if ( insert_pos == ILLEGAL_BUCKET ) return pair<size_type,size_type>(ILLEGAL_BUCKET, insert_pos); + } + else if ( test_deleted(bucknum) ) { + if ( insert_pos == ILLEGAL_BUCKET ) insert_pos = bucknum; + } + else if ( equals(key, get_key(table[bucknum])) ) { + return pair<size_type,size_type>(bucknum, ILLEGAL_BUCKET); + } + } + } + iterator find(const key_type& key) { + if ( size() == 0 ) return end(); + pair<size_type, size_type> pos = find_position(key); + if ( pos.first == ILLEGAL_BUCKET ) return end(); + return iterator(this, table + pos.first, table + num_buckets, false); + } + const_iterator find(const key_type& key) const { + if ( size() == 0 ) return end(); + pair<size_type, size_type> pos = find_position(key); + if ( pos.first == ILLEGAL_BUCKET ) return end(); + return const_iterator(this, table + pos.first, table+num_buckets, false); + } + size_type count(const key_type &key) const { + pair<size_type, size_type> pos = find_position(key); } + pair<iterator, bool> insert_noresize(const value_type& obj) { + const pair<size_type,size_type> pos = find_position(get_key(obj)); + if ( pos.first != ILLEGAL_BUCKET) { + return pair<iterator,bool>(iterator(this, table + pos.first, table + num_buckets, false), false); + } + else { + if ( test_deleted(pos.second) ) { ++num_elements; } + return pair<iterator,bool>(iterator(this, table + pos.second, table + num_buckets, false), true); + } + } + pair<iterator, bool> insert(const value_type& obj) { + resize_delta(1); + return insert_noresize(obj); + } + size_type erase(const key_type& key) { + const_iterator pos = find(key); + if ( pos != end() ) { + set_deleted(pos); + } + } + hasher hash; + key_equal equals; + ExtractKey get_key; + size_type num_deleted; + bool use_deleted; + bool use_empty; + value_type delval; + value_type emptyval; + float enlarge_resize_percent; + float shrink_resize_percent; + size_type shrink_threshold; + size_type enlarge_threshold; + value_type *table; + size_type num_buckets; + size_type num_elements; + bool consider_shrink; + void reset_thresholds() { + enlarge_threshold = static_cast<size_type>(num_buckets * shrink_resize_percent); + } +}; +template<> struct hash<long> { + size_t operator()(long x) const { + } +}; +template<> struct hash<unsigned long> { + size_t operator()(unsigned long x) const { + } +}; +template <class Key, class T, class HashFcn = hash<Key>, class EqualKey = equal_to<Key>, class Alloc = allocator<T> > class dense_hash_map { + struct SelectKey { + const Key& operator()(const pair<const Key, T>& p) const { + return p.first; + } + }; + typedef dense_hashtable<pair<const Key, T>, Key, HashFcn, SelectKey, EqualKey, Alloc> ht; + ht rep; + public: typedef typename ht::key_type key_type; + typedef T data_type; + typedef typename ht::value_type value_type; + typedef typename ht::size_type size_type; + typedef typename ht::iterator iterator; + typedef typename ht::const_iterator const_iterator; + iterator end() { + return rep.end(); + } + iterator find(const key_type& key) { return rep.find(key); } + data_type& operator[](const key_type& key) { + iterator it = find(key); + return insert(value_type(key, data_type())).first->second; + } + pair<iterator, bool> insert(const value_type& obj) { + return rep.insert(obj); + } + void set_deleted_key(const key_type& key) { + rep.set_deleted_key(value_type(key, data_type())); + } + size_type erase(const key_type& key) { return rep.erase(key); } +}; +template <class Value, class HashFcn = hash<Value>, class EqualKey = equal_to<Value>, class Alloc = allocator<Value> > class dense_hash_set { + struct Identity { + const Value& operator()(const Value& v) const { return v; } + }; + typedef dense_hashtable<Value, Value, HashFcn, Identity, EqualKey, Alloc> ht; + ht rep; + public: typedef typename ht::key_type key_type; + typedef typename ht::value_type value_type; + typedef typename ht::size_type size_type; + typedef typename ht::const_iterator iterator; + size_type count(const key_type& key) const { + return rep.count(key); + } + pair<iterator, bool> insert(const value_type& obj) { + pair<typename ht::iterator, bool> p = rep.insert(obj); + } + size_type erase(const key_type& key) { + return rep.erase(key); + } +}; +class linked_ptr_internal { + public: bool depart() { if (next_ == this) return true; } + mutable linked_ptr_internal const* next_; +}; +template <typename T> class linked_ptr { + public: explicit linked_ptr(T* ptr = __null) { + } + ~linked_ptr() { depart(); } + T& operator*() const { } + T* value_; + linked_ptr_internal link_; + void depart() { + if (link_.depart()) delete value_; + } +}; +class blah_3 { + const char* ptr_; + int length_; + public: blah_3(const char* str) : ptr_(str), length_((str == __null) ? 0 : static_cast<int>(strlen(str))) { } +}; +class blah_5; +class Bitmap { + public: Bitmap(unsigned int size) : array_size_(RequiredArraySize(size)) { } + static unsigned int RequiredArraySize(unsigned int num_bits) { return (num_bits + 31) >> 5; } + unsigned int array_size_; +}; +enum blah_31 { CREATIVE_FORMAT_TEXT_NARROW, kNumblah_31s }; +enum blah_33 { BLACKLISTED }; +template <typename EnumT> class blah_55; +typedef blah_55<blah_31> blah_31Set; +enum blah_36 { APPROVAL_STATUS_APPROVED, APPROVAL_STATUS_UNKNOWN }; +enum blah_37 { hahah_INVALID, hahah_KEYWORD }; +template<typename EnumT> class blah_55 { + public: blah_55(int enum_size); + bool Insert(EnumT x); + const int enum_size_; + Bitmap elements_; +}; +template<typename EnumT> blah_55<EnumT>::blah_55(int enum_size) :enum_size_(enum_size), elements_(enum_size) { + while (foo_1 _result = Check_GTImpl(1, 0, "enum_size" " " ">" " " "0")) blah_0(".h", 1902, _result).stream(); +}; +enum blah_38 { + ttttttt_9, }; +class blah_46 { + public: blah_46() : hahaha_id_(0), type_(hahah_INVALID), approval_status_(APPROVAL_STATUS_APPROVED) { + } + blah_46(long cid) : hahaha_id_(cid), type_(hahah_INVALID), approval_status_(APPROVAL_STATUS_APPROVED) { + } + long id() const { + return (static_cast<long>(hahaha_id_) << 16) >> 16; + } + static const blah_46 kBlacklistedID; + bool operator == (const blah_46& x) const { return id() == x.id(); } + bool operator < (const blah_46& x) const { return id() < x.id(); } + long hahaha_id_ : 48; + blah_37 type_ : 8; + blah_36 approval_status_ : 4; +}; +template <> struct hash<blah_46> { + size_t operator()(const blah_46 &x) const { + return size_t(x.id()); + } +}; +class blah_57 { + public: blah_57(); + void AddReason(blah_33 reason, const blah_3& debug_str, const blah_46& hahaha_id, bool ); + void set_collects_multiple_reasons(bool t) { } + private: struct foo_3 { + string reject_desc; + }; + foo_3 first_reason_; +}; +template <class T> struct foo_5 : public unary_function<T*, long> { + long operator()(const T* p) const { + long id = reinterpret_cast<long>(p); + if (id < 2) return -id; + } +}; +template <class T> class DensePtrSet : public dense_hashtable<T*, long, hash<long>, foo_5<T>, equal_to<long>, allocator<T*> > { + public: DensePtrSet() { + this->set_deleted_key(reinterpret_cast<T*>(1)); + } + const T* Find(long key) const { + typename DensePtrSet<T>::const_iterator it = this->find(key); + return it != this->end() ? *it : __null; + } +}; +struct foo_7 { + foo_7(bool spell_correction, bool query_broadening, bool previous_query, bool near_aaaaa, bool same_length, float mult, float exp_score) : shengmo_0(spell_correction), shengmo_1(query_broadening), shengmo_2(previous_query), shengmo_3(near_aaaaa), shengmo_4(same_length), multiplier(mult), expansion_score(exp_score) { + } + int CompareSameKeywordMatch(const foo_7& compare) const; + bool shengmo_0, shengmo_1, shengmo_2, shengmo_3, shengmo_4; + float multiplier, expansion_score; +}; +enum blah_41 { + ACP_ECPM_EARLY = 2 }; +struct foo_8 { unsigned int packed_ctr1; }; +struct foo_9 { foo_9() {}}; +class blah_16; +class blah_17; +class foo_12 { public: foo_12() {} + unsigned long hahaha_id() const {} + unsigned int qbb_score() const {} + private: static const vector<blah_46> hmmmmh_4; + long hahaha_id_ : 40; +}; +class foo_13 { + public: typedef dense_hash_map<long, int> BestMap; + foo_13() { best_rrrrrrr_.set_deleted_key(-1); } + void erase(long ad_group_id) { + best_rrrrrrr_.erase(ad_group_id); + } + typedef BestMap::iterator iterator; + typedef BestMap::const_iterator const_iterator; + const_iterator begin() const { } + iterator end() { return best_rrrrrrr_.end(); } + iterator find(long ad_group_id) { return best_rrrrrrr_.find(ad_group_id); } + const foo_12& GetMatch(const_iterator it) const {} + void hmmmmh_27(long ad_group_id, const foo_12& addme); + private: BestMap best_rrrrrrr_; + vector<foo_12> rrrrrrr_buffer_; +}; +struct foo_10 : public dense_hash_set<blah_46> {}; +class foo_9Set : public DensePtrSet<foo_9> {}; +typedef map<blah_46, foo_7*> foo_6Data; +typedef hash_map<long, linked_ptr<blah_57> > RejectedAdGroupMap; +enum blah_43 {}; +class foo_14 { + public: foo_14(const unsigned int, const blah_16*, const int*); + bool GathersMultipleRejectionReasons() const; + void hmmmmh_30(blah_46 hahaha_id, blah_38 type); + const foo_7* Insertfoo_6(const blah_46 hahaha_id, bool shengmo_0, bool shengmo_1, bool shengmo_2, bool shengmo_3, bool shengmo_4_rewrite, float multiplier, float context_score); + void hmmmmh_7(blah_46 hahaha_id, blah_38 type); + foo_9* Insertfoo_9(); + bool hmmmmh_8(long ad_group_id, const foo_12 &entry); + void hmmmmh_9(long ad_group_id); + foo_13::iterator hmmmmh_0(long ad_group_id); + bool hmmmmh_8(long ad_group_id, foo_13::iterator best, const foo_12& entry); + void hmmmmh_5(const blah_46 hahaha_id); + void hmmmmh_29(const blah_46 hahaha_id); + bool hmmmmh_12(const blah_46 hahaha_id) const; + bool hmmmmh_13(const blah_46 hahaha_id) const; + const foo_9* Getfoo_9(const blah_46 hahaha_id) const; + bool Gathersfoo_9() const {} + const foo_10* rrrrrrr_type_data() const {} + const foo_10* negative_rrrrrrr_type_data() const {} + const foo_10* positive_rrrrrrr_type_data() const {} + const foo_9Set* kw_info_set() const { } + const foo_6Data* rewrite_data() const {} + const vector<blah_17>& query_rectangles() const {} + void hmmmmh_14(); + void AddQueryRectangle(const blah_17& query_rectangle); + void hmmmmh_15(long ad_group_id, const blah_46 hahaha_id, blah_33 reject_class, const char* reject_desc = __null); + void hmmmmh_16(const vector<long>& rejected_sssr_ids); + void Copy(const foo_14& cmi); + void hmmmmh_10(); + private: const blah_16* ad_request_; + const int* cr_query_; + blah_43 gather_flags_; + vector<blah_17> query_rectangles_; + foo_10 rrrrrrr_type_data_; + foo_9Set kw_info_set_; + foo_6Data rewrite_data_; + scoped_ptr<RejectedAdGroupMap> rejected_sssr_map_; + foo_13 ad_group_rrrrrrr_data_; + vector<blah_46> geo_hahaha_; + bool geo_hahaha_is_sorted_; + foo_10 negative_rrrrrrr_type_data_, positive_rrrrrrr_type_data_; + scoped_ptr<foo_10> extra_hahaha_set_; + int dimension_id_; + blah_31Set creative_formats_; + scoped_ptr<dense_hash_set<unsigned long> > near_aaaaa_rrrrrrr_fps_; + blah_41 comparison_policy_; + blah_46 next_virtual_hahaha_id_; + vector<void*>* sub_queries_; + bool allow_only_whitelisted_customers_, automatic_hahaha_rrrrrrr_; + scoped_ptr<blah_5> kw_arena_, expanded_rrrrrrr_arena_; +}; +class blah_19 { + void hmmmmh_3(); + enum blah_45 {}; +}; +void blah_19::hmmmmh_3() {} +class blah_16 { + public: int near_aaaaa_rrrrrrr_fps_size() const {} + unsigned long near_aaaaa_rrrrrrr_fps(int i) const {} +}; +class blah_21 { + protected: blah_21(char* first_block, const size_t block_size, bool align_to_page); + void* GetMemoryFallback(const size_t size, const int align); + void* GetMemory(const size_t size, const int align) { + if ( size > 0 && size < remaining_ && align == 1 ) { + last_alloc_ = freestart_; + } + return GetMemoryFallback(size, align); + } + char* freestart_; + char* last_alloc_; + size_t remaining_; +}; +class blah_5 : blah_21 { + public: char* Alloc(const size_t size) { + return reinterpret_cast<char*>(GetMemory(size, 1)); + } +}; +class blah_25 { + public: virtual ~blah_25(); +}; +class blah_17 : blah_25 { }; +void Fillfoo_8(const foo_12& x2, struct foo_8* out) { + out->packed_ctr1 = x2.qbb_score(); +} +const vector<blah_46> foo_12::hmmmmh_4; +foo_14::foo_14(const unsigned int gather_flags, const blah_16* ad_request, const int* cr_query): ad_request_(ad_request), cr_query_(cr_query), gather_flags_(static_cast<blah_43>(gather_flags)), geo_hahaha_is_sorted_(false), dimension_id_(0), creative_formats_(kNumblah_31s), comparison_policy_(ACP_ECPM_EARLY), sub_queries_(new vector<void*>()), allow_only_whitelisted_customers_(false), automatic_hahaha_rrrrrrr_(false) { + hmmmmh_10(); +} +void foo_14::hmmmmh_5(const blah_46 hahaha_id) { + negative_rrrrrrr_type_data_.insert(hahaha_id); +} +void foo_14::hmmmmh_7(blah_46 hahaha_id, blah_38 type) { } +foo_13::iterator foo_14::hmmmmh_0( long ad_group_id) { + return ad_group_rrrrrrr_data_.find(ad_group_id); +} +bool foo_14::hmmmmh_8(long ad_group_id, foo_13::iterator best, const foo_12& entry) { + rejected_sssr_map_->erase(ad_group_id); + ad_group_rrrrrrr_data_.hmmmmh_27(ad_group_id, entry); +} +bool foo_14::hmmmmh_8(long ad_group_id, const foo_12& entry) { + foo_13::iterator best = hmmmmh_0(ad_group_id); +} +void foo_14::hmmmmh_9(long ad_group_id) { + ad_group_rrrrrrr_data_.erase(ad_group_id); +} +void foo_14::hmmmmh_10() { + if (near_aaaaa_rrrrrrr_fps_ != __null) { + blah_54(".cc", 226, WARNING).stream() << ""; + for (int j = 0; + j < ad_request_->near_aaaaa_rrrrrrr_fps_size(); j++) { + near_aaaaa_rrrrrrr_fps_->insert(ad_request_->near_aaaaa_rrrrrrr_fps(j)); + } + } +} +const foo_7* foo_14::Insertfoo_6(const blah_46 hahaha_id, bool shengmo_0, bool shengmo_1, bool shengmo_2, bool shengmo_3, bool shengmo_4_rewrite, float multiplier, float context_score) { + if (rrrrrrr_type_data_.count(hahaha_id) > 0) return __null; + foo_7* new_info = new(expanded_rrrrrrr_arena_->Alloc(sizeof(foo_7))) foo_7(shengmo_0,shengmo_1, shengmo_2, shengmo_3, shengmo_4_rewrite, multiplier, context_score); + pair<foo_6Data::iterator, bool> status = rewrite_data_.insert( make_pair(hahaha_id, new_info)); + foo_7* inserted = status.first->second; + if (!status.second) { + if (inserted->CompareSameKeywordMatch(*new_info) < 0) *inserted = *new_info; + } +} +foo_9* foo_14::Insertfoo_9() { + foo_9* info = new(kw_arena_->Alloc(sizeof(foo_9))) foo_9; + if (Gathersfoo_9()) kw_info_set_.insert(info); + creative_formats_.Insert(CREATIVE_FORMAT_TEXT_NARROW); +} +bool foo_14::hmmmmh_12(const blah_46 hahaha_id) const { + if (rrrrrrr_type_data_.count(hahaha_id)) return true; +} +bool foo_14::hmmmmh_13(const blah_46 hahaha_id) const { + if (positive_rrrrrrr_type_data_.count(hahaha_id)) return true; +} +const foo_9* foo_14::Getfoo_9(const blah_46 hahaha_id) const { + if (Gathersfoo_9()) return kw_info_set_.Find(hahaha_id.id()); + static int occurrences_383 = 0, occurrences_mod_n_383 = 0; + if (++occurrences_mod_n_383 > 1000) occurrences_mod_n_383 -= 1000; +} +void foo_14::hmmmmh_15(long ad_group_id, const blah_46 hahaha_id, blah_33 reject_class, const char* reject_desc) { + if (rejected_sssr_map_ == __null) { + blah_54("a.cc", 413, ERROR).stream() << "re NULL"; + rejected_sssr_map_.reset(new RejectedAdGroupMap); + } + if (rejected_sssr_map_->count(ad_group_id) == 0) { + blah_57* ad_rejection = new blah_57(); + ad_rejection->set_collects_multiple_reasons( GathersMultipleRejectionReasons()); + (*rejected_sssr_map_)[ad_group_id] = linked_ptr<blah_57>(ad_rejection); + } + blah_57& ad_rejection = *(*rejected_sssr_map_)[ad_group_id]; + ad_rejection.AddReason(reject_class, reject_desc, hahaha_id, false); +} +void foo_14::hmmmmh_16(const vector<long>& rejected_sssr_ids) { + for (vector<long>::const_iterator it = rejected_sssr_ids.begin(); + it != rejected_sssr_ids.end(); ++it) { + ad_group_rrrrrrr_data_.erase(*it); + for (foo_13::const_iterator it = ad_group_rrrrrrr_data_.begin(); + it != ad_group_rrrrrrr_data_.end(); ++it) { + hmmmmh_15(it->first, ad_group_rrrrrrr_data_.GetMatch(it).hahaha_id(), BLACKLISTED); + } + } + hmmmmh_30(blah_46::kBlacklistedID, ttttttt_9); +} +void foo_14::Copy(const foo_14& cmi) { + rrrrrrr_type_data_ = *cmi.rrrrrrr_type_data(); + negative_rrrrrrr_type_data_ = *cmi.negative_rrrrrrr_type_data(); + positive_rrrrrrr_type_data_ = *cmi.positive_rrrrrrr_type_data(); + if (cmi.Gathersfoo_9()) { + kw_info_set_ = *cmi.kw_info_set(); + rewrite_data_ = *cmi.rewrite_data(); + } + hmmmmh_14(); + for (int i = 0; i < cmi.query_rectangles().size(); + ++i) AddQueryRectangle(cmi.query_rectangles()[i]); +} +void foo_13::hmmmmh_27(long ad_group_id, const foo_12& addme) { + int& best_index = best_rrrrrrr_[ad_group_id]; + rrrrrrr_buffer_.push_back(addme); +} +void foo_14::hmmmmh_29(const blah_46 hahaha_id) { + if (extra_hahaha_set_ != __null) extra_hahaha_set_->erase(hahaha_id); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C b/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C new file mode 100644 index 000000000..5513d3650 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C @@ -0,0 +1,52 @@ +// PR tree-optimization/39557 +// invalid post-dom info leads to infinite loop +// { dg-do run } +// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fno-rtti" } + +struct C +{ + virtual const char *bar () const; +}; + +struct D +{ + D () : d1 (0) { } + C *d2[4]; + int d1; + inline const C & baz (int i) const { return *d2[i]; } +}; + +struct E +{ + unsigned char e1[2]; + D e2; + bool foo () const { return (e1[1] & 1) != 0; } + virtual const char *bar () const __attribute__ ((noinline)); +}; + +const char * +C::bar () const +{ + return 0; +} + +C c; + +const char * +E::bar () const +{ + const char *e = __null; + if (foo () && (e = c.C::bar ())) + return e; + for (int i = 0, n = e2.d1; i < n; i++) + if ((e = e2.baz (i).C::bar ())) + return e; + return e; +} + +int +main () +{ + E e; + e.bar (); +} // { dg-message "note: file" "" } diff --git a/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C b/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C new file mode 100644 index 000000000..8dfaa52b6 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ehcleanup-1.C @@ -0,0 +1,24 @@ +// { dg-options "-O2 -fdump-tree-ehcleanup1-details" } +extern void can_throw (); +class a +{ +public: + ~a () + { + if (0) + can_throw (); + } +}; +void +t (void) +{ + class a a; + can_throw (); +} +// We ought to remove implicit cleanup, since destructor is empty. +// { dg-final { scan-tree-dump-times "Empty EH handler" 1 "ehcleanup1" } } +// +// And as a result also contained control flow. +// { dg-final { scan-tree-dump-times "Removing unreachable" 2 "ehcleanup1" } } +// +// { dg-final { cleanup-tree-dump "ehcleanup1" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/empty-1.C b/gcc/testsuite/g++.dg/tree-ssa/empty-1.C new file mode 100644 index 000000000..6a6e452be --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/empty-1.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +struct S {}; +S bar (const S &a) +{ + S s; + s = a; + return s; +} + +/* Test whether memcpy call has been optimized out. */ +/* { dg-final { scan-tree-dump-times "memcpy" 0 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/empty-2.C b/gcc/testsuite/g++.dg/tree-ssa/empty-2.C new file mode 100644 index 000000000..01b77b4fb --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/empty-2.C @@ -0,0 +1,15 @@ +// PR c++/45307 +// { dg-options "-fdump-tree-gimple -fdump-tree-optimized -O" } + +struct fallible_t { }; +const fallible_t fallible = fallible_t(); + +void t(void) +{ +} + +// { dg-final { scan-tree-dump-not "fallible" "gimple" } } +// Whole constructor should be optimized away. +// { dg-final { scan-tree-dump-not "int" "optimized" } } +// { dg-final { cleanup-tree-dump "gimple" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/fold-compare.C b/gcc/testsuite/g++.dg/tree-ssa/fold-compare.C new file mode 100644 index 000000000..2b4c41103 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/fold-compare.C @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +struct ExtentsBase { + ExtentsBase() : startx_(), endx_() { } + ExtentsBase(const ExtentsBase &b) { + *this = b; + } + + const ExtentsBase & operator=(const ExtentsBase &b) { + if (this != &b) { + startx_ = b.startx_; + } + return *this; + } + + int startx_; + int endx_; +}; + +int f(const ExtentsBase &e1) { + ExtentsBase my_extents = e1; + return my_extents.startx_; +} + +/* { dg-final { scan-tree-dump-not "&my_extents" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ + diff --git a/gcc/testsuite/g++.dg/tree-ssa/fwprop-align.C b/gcc/testsuite/g++.dg/tree-ssa/fwprop-align.C new file mode 100644 index 000000000..69f260216 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/fwprop-align.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop2" } */ + +struct A +{ + void foo () + { + } +}; + +int main() +{ + void (A::* const p)() = & A::foo; + A a; + (a.*p)(); +} + +/* We should eliminate the check if p points to a virtual function. */ +/* { dg-final { scan-tree-dump-times "& 1" 0 "forwprop2" } } */ +/* { dg-final { cleanup-tree-dump "forwprop2" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/inline-1.C b/gcc/testsuite/g++.dg/tree-ssa/inline-1.C new file mode 100644 index 000000000..95b7d0609 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/inline-1.C @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-einline" } */ +/* { dg-add-options bind_pic_locally } */ + +namespace std { + extern "C" void puts(const char *s); +} + +template <class T, class E> void +foreach (T b, T e, void (*ptr)(E)) +{ + for (; b != e; b++) + ptr(*b); +} + +void +inline_me (char *x) +{ + std::puts(x); +} + +static void +inline_me_too (char *x) +{ + std::puts(x); +} + +int main(int argc, char **argv) +{ + foreach (argv, argv + argc, inline_me); + foreach (argv, argv + argc, inline_me_too); +} + +/* { dg-final { scan-tree-dump-times "Inlining void inline_me\\(" 1 "einline"} } */ +/* { dg-final { scan-tree-dump-times "Inlining void inline_me_too\\(" 1 "einline"} } */ +/* { dg-final { cleanup-tree-dump "einline" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/inline-2.C b/gcc/testsuite/g++.dg/tree-ssa/inline-2.C new file mode 100644 index 000000000..656cba031 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/inline-2.C @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-einline" } */ +/* { dg-add-options bind_pic_locally } */ + +namespace std { + extern "C" void puts(const char *s); +} + +template <class T, class E> void +foreach (T b, T e, E ptr) +{ + for (; b != e; b++) + ptr(*b); +} + +void +inline_me (char *x) +{ + std::puts(x); +} + +static void +inline_me_too (char *x) +{ + std::puts(x); +} + +int main(int argc, char **argv) +{ + foreach (argv, argv + argc, inline_me); + foreach (argv, argv + argc, inline_me_too); +} + +/* { dg-final { scan-tree-dump-times "Inlining void inline_me\\(" 1 "einline"} } */ +/* { dg-final { scan-tree-dump-times "Inlining void inline_me_too\\(" 1 "einline"} } */ +/* { dg-final { cleanup-tree-dump "einline" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/inline-3.C b/gcc/testsuite/g++.dg/tree-ssa/inline-3.C new file mode 100644 index 000000000..f01f26caf --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/inline-3.C @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-einline" } */ +/* { dg-add-options bind_pic_locally } */ + +#include <algorithm> + +void foo(const char *s); + +void +inline_me (char *x) +{ + foo(x); +} + +static void +inline_me_too (char *x) +{ + foo(x); +} + +int main(int argc, char **argv) +{ + std::for_each (argv, argv + argc, inline_me); + std::for_each (argv, argv + argc, inline_me_too); +} + +/* { dg-final { scan-tree-dump-times "Inlining void inline_me\\(" 1 "einline"} } */ +/* { dg-final { scan-tree-dump-times "Inlining void inline_me_too\\(" 1 "einline"} } */ +/* { dg-final { cleanup-tree-dump "einline" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/ivopts-1.C b/gcc/testsuite/g++.dg/tree-ssa/ivopts-1.C new file mode 100644 index 000000000..0eaa0fb25 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ivopts-1.C @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-ivopts" } */ + +struct Foo { + Foo() : s(1) {} + int s; +}; +void foo(Foo&); +void bar(void) +{ + Foo x[4]; + foo(x[0]); +} + +/* { dg-final { scan-tree-dump-not "-&x" "ivopts" } } */ +/* { dg-final { scan-tree-dump-not "offset: (4294967292|0x0f+fc)" "ivopts" } } */ +/* { dg-final { scan-tree-dump-not "&x\\\[5\\\]" "ivopts" } } */ +/* { dg-final { cleanup-tree-dump "ivopts" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/ivopts-2.C b/gcc/testsuite/g++.dg/tree-ssa/ivopts-2.C new file mode 100644 index 000000000..908299d98 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ivopts-2.C @@ -0,0 +1,11 @@ +/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */ +/* { dg-options "-O2 -fdump-tree-ivopts-details" } */ + +void test (int *b, int *e, int stride) + { + for (int *p = b; p != e; p += stride) + *p = 1; + } + +/* { dg-final { scan-tree-dump-times "PHI <p" 1 "ivopts"} } */ +/* { dg-final { cleanup-tree-dump "ivopts" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/new1.C b/gcc/testsuite/g++.dg/tree-ssa/new1.C new file mode 100644 index 000000000..a859f0ac3 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/new1.C @@ -0,0 +1,42 @@ +// PR c++/36633 + +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall -fdump-tree-forwprop1" } */ +// No particular reason for choosing forwprop1 dump to look at. + +struct B { ~B() {} }; +struct D : public B {}; +//struct D {}; + +struct my_deleter +{ + void operator()(D * d) + { + // delete [] d; + } +}; + +struct smart_ptr +{ + smart_ptr(D * ptr) : p(ptr) { } + ~smart_ptr() { d(p); } + D * p; + my_deleter d; +}; + +int +test01() +{ + smart_ptr p(new D[7]); + + return 0; +} + +int main() +{ + test01(); + return 0; +} + +/* { dg-final { scan-tree-dump-not "= .* \\+ -" "forwprop1" } } */ +/* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/nothrow-1.C b/gcc/testsuite/g++.dg/tree-ssa/nothrow-1.C new file mode 100644 index 000000000..33462946a --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/nothrow-1.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-cfg" } */ +/* { dg-add-options bind_pic_locally } */ + +double a; +void t() +{ + a=1; +} +void t1(void); +void abort(void); + +void q() +{ + try { + t(); + } + catch (...) {abort();} +} +/* We shouldnotice nothrow attribute. */ +/* { dg-final { scan-tree-dump-times "exception" 0 "cfg"} } */ +/* { dg-final { cleanup-tree-dump "cfg" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/obj-type-ref.C b/gcc/testsuite/g++.dg/tree-ssa/obj-type-ref.C new file mode 100644 index 000000000..9854d32e8 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/obj-type-ref.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ + +/* This used to fail with type-checking enabled because we didn't + expect OBJ_TYPE_REF expressions. */ + +class QObject {}; +class Pile : public QObject { +public: + virtual void setVisible(void); +}; +class Spider { + void dealRow(); + Pile *redeals[5]; + int m_redeal; +}; +void Spider::dealRow() +{ + redeals[m_redeal++]->setVisible(); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pointer-reference-alias.C b/gcc/testsuite/g++.dg/tree-ssa/pointer-reference-alias.C new file mode 100644 index 000000000..777656d59 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pointer-reference-alias.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +int f(int *a) +{ + int &b = *a; + b = 0; + return *a; +} + +/* There should be only one dereferencing of a. */ +/* { dg-final { scan-tree-dump-times "\\*a" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr13146.C b/gcc/testsuite/g++.dg/tree-ssa/pr13146.C new file mode 100644 index 000000000..22baf03d3 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr13146.C @@ -0,0 +1,77 @@ +/* { dg-do link } */ +/* { dg-options "-O -fstrict-aliasing" } */ + +class first +{ +public: + double d; + int f1; +}; + +class middle : public first +{ +}; + +class second : public middle +{ +public: + int f2; + short a; +}; + +class third +{ +public: + char a; + char b; +}; + +class multi: public third, public second +{ +public: + short s; + /* The following field used to be of type char but that causes + class multi to effectively get alias-set zero which we end + up not optimizing because of the fix for PR44164. */ + int f3; +}; + +extern void link_error (); + +void +foo (first *s1, second *s2) +{ + s1->f1 = 0; + s2->f2 = 0; + s1->f1++; + s2->f2++; + s1->f1++; + s2->f2++; + if (s1->f1 != 2) + link_error (); +} + +void +bar (first *s1, multi *s3) +{ + s1->f1 = 0; + s3->f3 = 0; + s1->f1++; + s3->f3++; + s1->f1++; + s3->f3++; + if (s1->f1 != 2) + link_error (); +} + + +int +main() +{ + first a; + second b; + multi c; + foo (&a, &b); + bar (&a, &c); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr14703.C b/gcc/testsuite/g++.dg/tree-ssa/pr14703.C new file mode 100644 index 000000000..58705277e --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr14703.C @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized -fno-ipa-reference" } */ +#include <iostream> + +namespace { +template <unsigned long long L> class fib { + public: + static const unsigned long long value = fib<L - 1>::value + fib<L - 2>::value; +}; + +template <> class fib<0> { + public: + static const unsigned long long value = 1; +}; + +template <> class fib<1> { + public: + static const unsigned long long value = 1; +}; + +template<unsigned long long L> inline unsigned long long fibconst() +{ + return fibconst<L - 1>() + fibconst<L - 2>(); +} + +template <> inline unsigned long long fibconst<0>() +{ + return 1ull; +} + +template <> inline unsigned long long fibconst<1>() +{ + return 1ull; +} + +template <> inline unsigned long long fibconst<2>() +{ + return 2ull; +} + +} + +int main() +{ + ::std::cerr << "fib<90>::value == " << fib<90>::value << "\n"; + ::std::cerr << "fibcst<90>() == " << fibconst<90>() << "\n"; +} +// { dg-final { scan-tree-dump-not "fibconst" "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr14814.C b/gcc/testsuite/g++.dg/tree-ssa/pr14814.C new file mode 100644 index 000000000..59e3c9bc9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr14814.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-forwprop2" } */ + +class YY { public: + YY(const YY &v) { e[0] = v.e[0]; e[1] = v.e[1]; e[2] = v.e[2]; } + double &y() { return e[1]; } + double e[3]; }; + +class XX { public: + YY direction() const { return v; } + YY v; }; + +int foo(XX& r) { + if (r.direction().y() < 0.000001) return 0; + return 1; } + +/* { dg-final { scan-tree-dump-times "&this" 0 "forwprop2" } } */ +/* { dg-final { scan-tree-dump-times "&r" 0 "forwprop2" } } */ +/* { dg-final { cleanup-tree-dump "forwprop2" } } */ + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr15791-1.C b/gcc/testsuite/g++.dg/tree-ssa/pr15791-1.C new file mode 100644 index 000000000..68f14adad --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr15791-1.C @@ -0,0 +1,25 @@ +/* { dg-do link } */ + +void link_error (); + +int main () +{ + struct { int b[2]; } x; + int b[2]; + if (&b[1] != &b[1]) + link_error (); + if (&b[0] != b) + link_error (); + if (b == &b[2]) + link_error (); + if (b != b) + link_error (); + if (&x.b[1] == &x.b[0]) + link_error (); + if (x.b != &x.b[0]) + link_error (); + if (&x.b[1] == x.b) + link_error (); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr15791-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr15791-2.C new file mode 100644 index 000000000..fb8cbbe4c --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr15791-2.C @@ -0,0 +1,13 @@ +/* { dg-do link } */ +/* { dg-options "" } */ + +void link_error (); +struct a {}; +int main () +{ + struct a b[2]; + if (&b[0] == &b[1]) + link_error (); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr15791-3.C b/gcc/testsuite/g++.dg/tree-ssa/pr15791-3.C new file mode 100644 index 000000000..2fd03e2e0 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr15791-3.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-gimple" } */ + +int f(int i, unsigned j) +{ + int b[2]; + if (&b[i] == &b[j]) + return 1; + return 0; +} + +/* { dg-final { scan-tree-dump-times "i == j" 0 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr15791-4.C b/gcc/testsuite/g++.dg/tree-ssa/pr15791-4.C new file mode 100644 index 000000000..82be2e33a --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr15791-4.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-gimple" } */ + +int f(int i, int j) +{ + int b[2][2]; + if (&b[1][i] == &b[0][j]) + return 1; + return 0; +} + +/* { dg-final { scan-tree-dump-times "i == j" 0 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr15791-5.C b/gcc/testsuite/g++.dg/tree-ssa/pr15791-5.C new file mode 100644 index 000000000..06ce523a7 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr15791-5.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-fdump-tree-gimple" } */ + +int foo(int i, int j) +{ + char g[16]; + if (&g[i] == &g[j]) + return 1; + return 0; +} + +/* { dg-final { scan-tree-dump-times "i == j" 1 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr16688.C b/gcc/testsuite/g++.dg/tree-ssa/pr16688.C new file mode 100644 index 000000000..ce88bc2b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr16688.C @@ -0,0 +1,273 @@ +/* PR 16688. Test provided by Wolfgang Bangerth. The alias analyzer + was aborting when trying to group aliases. */ + +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +template<typename _Tp> +struct iterator_traits; + +template<typename _Tp> +struct iterator_traits<_Tp*> { + typedef _Tp& reference; +}; + +template<typename _Iterator> struct NI { + _Iterator current; + + typedef typename iterator_traits<_Iterator>::reference reference; + + NI() { } + + NI(const _Iterator& __i) : current(__i) { } + + reference operator*() const { return *current; } + + NI& operator++() { return *this; } + + const _Iterator& base() const { return current; } +}; + +template<typename _IteratorL, typename _IteratorR> +inline int +operator-(const NI<_IteratorL>& __lhs, + const NI<_IteratorR>& __rhs) +{ return __lhs.base() - __rhs.base(); } + + +template<typename _II, typename _OI> +inline _OI +__copy_aux(_II __first, _II __last, _OI __result) +{ + struct __copy { + static _OI + copy(_II __first, _II __last, _OI __result) + { + for (; __first != __last; ++__result, ++__first) + *__result = *__first; + return __result; + } + }; + + return __copy::copy(__first, __last, __result); +} + +struct __copy_normal +{ + template<typename _II, typename _OI> + static _OI + copy_n(_II __first, _II __last, _OI __result) + { + return __copy_aux(__first, __last, __result); + } +}; +template<typename _InputIterator, typename _OutputIterator> +inline _OutputIterator +copy(_InputIterator __first, _InputIterator __last, + _OutputIterator __result) +{ + return __copy_normal::copy_n(__first, __last, __result); +} + +template <typename T, typename U, typename V> +void uninitialized_fill_n(T,U,V); + + +template<typename _Tp> +struct _Vector_base { + struct _Vector_impl { + _Tp* start; + _Tp* finish; + _Tp* end_of_storage; + _Vector_impl() : start(0), finish(0), end_of_storage(0) + { } + } impl; + + _Vector_base(unsigned __n) { + impl.start = allocate(__n); + impl.finish = impl.start; + impl.end_of_storage = impl.start + __n; + } + + ~_Vector_base() { + deallocate(impl.start, + impl.end_of_storage - impl.start); + } + + _Tp* allocate(unsigned __n); + + void deallocate(_Tp* __p, unsigned __n); + + NI<_Tp*> begin() { return NI<_Tp*> (impl.start); } +}; + + +template<typename _Tp> +struct vector : _Vector_base<_Tp> +{ + vector(int __n) + : _Vector_base<_Tp>(__n) + { + uninitialized_fill_n(this->impl.start, __n, _Tp()); + } +}; + + + +struct Tensor +{ + Tensor (); + Tensor (const Tensor &); + + double values[2]; +}; + + +inline +Tensor::Tensor (const Tensor &p) +{ + for (unsigned int i=0; i<2; ++i) + values[i] = p.values[i]; +} + + +struct TriaAccessor +{ + typedef void * AccessorData; + + void copy_from (const TriaAccessor &); + void operator = (const TriaAccessor *); + + TriaAccessor & operator = (const TriaAccessor &); + + bool operator == (const TriaAccessor &) const; + + bool operator != (const TriaAccessor &) const; + void operator ++ (); + + int state () const; + bool used () const; + + int present_level; + int present_index; + int** levels; +}; + +inline int TriaAccessor::state () const { + if ((present_level>=0) && (present_index>=0)) + return 0; + else + if ((present_level==-1) && (present_index==-1)) + return 1; + else + return 2; +} + + +inline +void TriaAccessor::operator ++ () { + ++this->present_index; + + while (this->present_index >= + static_cast<int>(*this->levels[this->present_level])) + { + ++this->present_level; + this->present_index = 0; + + if (this->present_level >= static_cast<int>(1)) + { + + this->present_level = this->present_index = -1; + return; + } + } +} + +struct MGDoFObjectAccessor : TriaAccessor {}; + + + +struct TriaRawIterator +{ + TriaRawIterator (); + + TriaRawIterator (const TriaRawIterator &); + TriaRawIterator (const MGDoFObjectAccessor &a); + const MGDoFObjectAccessor & operator * () const; + + MGDoFObjectAccessor & operator * (); + const MGDoFObjectAccessor * operator -> () const; + + MGDoFObjectAccessor * operator -> (); + + TriaRawIterator & operator = (const TriaRawIterator &); + + bool operator == (const TriaRawIterator &) const; + bool operator != (const TriaRawIterator &) const; + bool operator < (const TriaRawIterator &) const; + MGDoFObjectAccessor accessor; + + TriaRawIterator & operator ++ (); +}; + +struct TriaIterator : TriaRawIterator +{ + TriaIterator (); + + TriaIterator (const TriaIterator &i); + + TriaIterator & + operator = (const TriaIterator &); + + TriaIterator & + operator = (const TriaRawIterator &); +}; + + +inline +TriaRawIterator::TriaRawIterator (const TriaRawIterator &i) : + accessor (i.accessor) {} + +inline +TriaIterator::TriaIterator (const TriaIterator &i) : + TriaRawIterator (static_cast<TriaRawIterator >(i)) {} + +inline +TriaRawIterator & TriaRawIterator::operator ++ () { + while (++accessor, (this->accessor.state() == 0)) + if (this->accessor.used() == true) + return *this; + return *this; +} + +struct Comp { + Comp (const Tensor &dir) : dir(dir) {} + + bool operator () (const TriaIterator &c1, const TriaIterator &c2) const; + const Tensor dir; +}; + + +template<typename Iter> +void x1(Iter first, Iter last, int i, Comp comp) +{ + x1(Iter(), last, i, comp); +} + +template<typename Iter> +inline void x2(Iter first, Iter last, Comp comp) +{ + if (first.base() != last.base()) + x1(first, last, (last - first), comp); +} + +void downstream_dg (const Tensor& direction) +{ + vector<TriaIterator> ordered_cells(13); + const Comp comparator(direction); + + TriaIterator begin, end; + + copy (begin, end, ordered_cells.begin()); + x2 (ordered_cells.begin(), ordered_cells.begin(), comparator); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr17153.C b/gcc/testsuite/g++.dg/tree-ssa/pr17153.C new file mode 100644 index 000000000..658225e6e --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr17153.C @@ -0,0 +1,17 @@ +/* The alias analyzer was marking RETVAL non-addressable, but RETVAL + is a special variable that's available across different functions. */ +void foo(const char*); + +struct A {}; + +struct B : A +{ + B(){} + B bar() + { + foo(__PRETTY_FUNCTION__); + return B(); + } +}; + +B b=B().bar(); diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr17400.C b/gcc/testsuite/g++.dg/tree-ssa/pr17400.C new file mode 100644 index 000000000..a6619a84f --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr17400.C @@ -0,0 +1,53 @@ +// Test PR 17400. Test case provided by Serge Belyshev. + +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + + +void inc (int &); +bool dec_test (int &); + +struct A +{ + int c; + + friend void AddRef (A * p) + { + inc (p->c); + } + + friend void Release (A * p) + { + if(dec_test (p->c)) + delete p; + } +}; + +struct B +{ + B (A *p) : obj(p) + { + AddRef (obj); + } + + ~B() + { + Release (obj); + } + + void swap (B &rhs) + { + A * tmp = obj; + obj = rhs.obj; + rhs.obj = tmp; + } + + A *obj; +}; + +void bar (A *p1, A* p2) +{ + B px (p1); + B px2 (p2); + px.swap (px2); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr17517.C b/gcc/testsuite/g++.dg/tree-ssa/pr17517.C new file mode 100644 index 000000000..bcd5e91db --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr17517.C @@ -0,0 +1,32 @@ +// Test PR 17517. Test case provided by Serge Belyshev. + + /* { dg-do compile } */ + /* { dg-options "-O2" } */ + + +extern void foo (); + +struct Ptr { + int * ptr; + Ptr () { ptr = 0; } + ~Ptr() { delete ptr; } + Ptr &operator= (int * p) { ptr = p; return *this; } +}; + +int *new_checker () { foo (); return 0; } + +void pipe (int c) +{ + Ptr checker; + + foo (); + for (;;) + { + switch (c) + { + case '-': + checker = new_checker (); + break; + } + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr18178.C b/gcc/testsuite/g++.dg/tree-ssa/pr18178.C new file mode 100644 index 000000000..9223e8323 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr18178.C @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +// Define this to see it work. +// #define WORK_WORK_WORK + +#define THIRD + +#ifdef THIRD +#define FIRST i < 0 || +#define ORIG int +#define CAST +#else + +#define FIRST +#ifdef WORK_WORK_WORK +#define ORIG unsigned int +#define CAST +#else +#define ORIG int +#define CAST (unsigned) +#endif // WORK_WORK_WORK + +#endif // THIRD + +struct array +{ + const ORIG len; + int *data; +}; + +extern void call (ORIG); + +void doit (array *a) +{ + for (ORIG i = 0; i < a->len; ++i) + { + if (FIRST CAST (i) >= CAST (a->len)) + throw 5; + call (a->data[i]); + } +} + +/* VRP should remove all but 1 if() in the loop. */ + +/* { dg-final { scan-tree-dump-times "if " 1 "vrp1"} } */ +/* { dg-final { cleanup-tree-dump "vrp1" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19637.C b/gcc/testsuite/g++.dg/tree-ssa/pr19637.C new file mode 100644 index 000000000..2d1dcceba --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr19637.C @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom1" } */ + +#include <new> + +struct Foo { + Foo() { i[0] = 1; } + int i[2]; +}; + +int foo_char(void) +{ + int i[2]; + new (reinterpret_cast<char *>(i)) Foo(); + return reinterpret_cast<Foo *>(i)->i[0]; +} + +int foo_void(void) +{ + int i[2]; + new (reinterpret_cast<void *>(i)) Foo(); + return reinterpret_cast<Foo *>(i)->i[0]; +} + +int foo_void_offset(void) +{ + int i[2]; + new (reinterpret_cast<void *>(&i[0])) Foo(); + return reinterpret_cast<Foo *>(&i[0])->i[0]; +} + +/* { dg-final { scan-tree-dump-times "return 1;" 3 "dom1" } } */ +/* { dg-final { cleanup-tree-dump "dom1" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19786.C b/gcc/testsuite/g++.dg/tree-ssa/pr19786.C new file mode 100644 index 000000000..faaecdfd9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr19786.C @@ -0,0 +1,48 @@ +// { dg-do run } +/* { dg-options "-O2" } */ + +// We used to get alias grouping wrong on this one, hoisting accesses +// to the vector's end out of the loop. + +#include <vector> +#include <cassert> + +struct A +{ + double unused; // If I remove it => it works. + std::vector<int> v; + + A() : v(1) {} +}; + +inline // If not inline => it works. +A g() +{ + A r; + r.v.resize(2); + r.v[0] = 1; + + while (!r.v.empty() && r.v.back() == 0) + r.v.pop_back(); + + return r; +} + +A f(const A &a) +{ + if (a.v.empty()) return a; + if (a.v.empty()) return a; + + // A z = g(); return z; // If I return like this => it works. + return g(); +} + +int main() +{ + A a; + A b; + A r = f(a); + assert(r.v.size() != 0); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C new file mode 100644 index 000000000..bba79a9d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +int a[4]; +int *x, *y, *z; + +void foo(void) +{ + x = &a[3] - 1; + y = &a[1] + 1; + z = 1 + &a[1]; +} + +void bar(int i) +{ + x = &a[i] - 1; + y = &a[i] + 1; + z = 1 + &a[i]; +} + +/* { dg-final { scan-tree-dump-times "&a\\\[2\\\]" 3 "optimized" } } */ + +/* We want &a[D.bla + 1] and &a[D.foo - 1] in the final code, but + tuples mean that the offset is calculated in a separate instruction. + Simply test for the existence of +1 and -1 once, which also ensures + the above. If the addition/subtraction would be applied to the + pointer we would instead see +-4 (or 8, depending on sizeof(int)). */ +/* { dg-final { scan-tree-dump-times "\\\+ -1;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19952.C b/gcc/testsuite/g++.dg/tree-ssa/pr19952.C new file mode 100644 index 000000000..54589a294 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr19952.C @@ -0,0 +1,24 @@ +/* PR 19952 */ +/* { dg-do compile } */ +/* { dg-options "-ftree-vectorize -O2" } */ + +int i; + +struct A +{ + ~A() { ++i; } +}; + +struct B +{ + A a; +}; + +void foo() +{ + for (int i=0; i<2; ++i) + { + B *p; + if (p) p->~B(); + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr20280.C b/gcc/testsuite/g++.dg/tree-ssa/pr20280.C new file mode 100644 index 000000000..ec4dad706 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr20280.C @@ -0,0 +1,63 @@ +// PR c++/20280 + +// { dg-do compile } + +// Gimplification of the COND_EXPR used to fail because it had an +// addressable type, and create_tmp_var rejected that. + +struct A +{ + ~A(); +}; + +struct B : A {}; + +A& foo(); + +void bar(bool b) +{ + (B&) (b ? foo() : foo()); +} + +// Make sure bit-fields and addressable types don't cause crashes. +// These were not in the original bug report. + +// Added by Alexandre Oliva <aoliva@redhat.com> + +// Copyright 2005 Free Software Foundation + +struct X +{ + long i : 32, j, k : 32; +}; + +void g(long&); +void h(const long&); + +void f(X &x, bool b) +{ + (b ? x.i : x.j) = 1; + (b ? x.j : x.k) = 2; + (b ? x.i : x.k) = 3; + + (void)(b ? x.i : x.j); + (void)(b ? x.i : x.k); + (void)(b ? x.j : x.k); + + g (b ? x.i : x.j); // { dg-error "cannot bind bitfield" } + g (b ? x.i : x.k); // { dg-error "cannot bind bitfield" } + g (b ? x.j : x.k); // { dg-error "cannot bind bitfield" } + + // It's not entirely clear whether these should be accepted. The + // conditional expressions are lvalues for sure, and 8.5.3/5 exempts + // lvalues for bit-fields, but it's not clear that conditional + // expressions that are lvalues and that have at least one possible + // result that is a bit-field lvalue meets this condition. + h (b ? x.i : x.j); + h (b ? x.i : x.k); + h (b ? x.j : x.k); + + (long &)(b ? x.i : x.j); // { dg-error "address of bit-field" } + (long &)(b ? x.i : x.k); // { dg-error "address of bit-field" } + (long &)(b ? x.j : x.k); // { dg-error "address of bit-field" } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr20458.C b/gcc/testsuite/g++.dg/tree-ssa/pr20458.C new file mode 100644 index 000000000..d4e7d1a1a --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr20458.C @@ -0,0 +1,37 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +/* The tail call optimization would inapproriately tail call the + destructors due to not recognizing a call clobbered variable */ +namespace std +{ + class locale + { + public: + locale(); + ~locale(); + }; +} + +struct B +{ + std::locale _M_buf_locale; + virtual ~B() {} +}; + +struct C : public B +{ + char *s; +}; + +void foo () +{ + C c; +} + +int main() +{ + foo (); + return 0; +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr20489.C b/gcc/testsuite/g++.dg/tree-ssa/pr20489.C new file mode 100644 index 000000000..0a1a569d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr20489.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct A +{ + ~A(); +}; + +/* If we don't create SFT's for the "empty" structure A, bad things + will happen, and we will fail verification. */ +struct B +{ + int i; + A a; + + void foo() {} +}; + +void bar() +{ + B().foo(); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr20920.C b/gcc/testsuite/g++.dg/tree-ssa/pr20920.C new file mode 100644 index 000000000..02edd2827 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr20920.C @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* This was causing a failure in the out of SSA pass because VRP was + trying to insert assertions for SSA names that flow through + abnormal edges. */ +void f(int) __attribute__((__noreturn__)); +int d(const char *); +char * j (); + +char * +foo (int x) +{ + char *path = __null; + try + { + path = j (); + if (path != __null) + if (d (path) != 0) + f (127); + f (127); + } + catch (...) { } + + return path; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr20963.C b/gcc/testsuite/g++.dg/tree-ssa/pr20963.C new file mode 100644 index 000000000..d8f91e1be --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr20963.C @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* This was causing PRE to insert the value of the ADDR variable, to + remove the invariant cast but in doing so, it was creating a + non-invariant expression out of the invariant one, causing a later + failure in PRE. */ +struct sMCB { + unsigned char type; +}; + +extern void foo (void); +unsigned char mem_readb(char *pt) __attribute__((nothrow)); + +void DOS_FreeProcessMemory(unsigned short pspseg) { + while (1) { + if (pspseg) + foo (); + char *addr = (char*)(&((sMCB*)0)->type); + if (mem_readb(addr)==0x5a) break; + } +}; + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr21082.C b/gcc/testsuite/g++.dg/tree-ssa/pr21082.C new file mode 100644 index 000000000..d6c2fa1d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr21082.C @@ -0,0 +1,14 @@ +/* { dg-do link } */ +/* { dg-options "-fstrict-overflow" } */ + +void link_error(); + +int a[4]; +__INTPTR_TYPE__ b, c; + +int main() +{ + if (&a[b] - &a[c] != b - c) + link_error(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr21407.C b/gcc/testsuite/g++.dg/tree-ssa/pr21407.C new file mode 100644 index 000000000..561dc707a --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr21407.C @@ -0,0 +1,8 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +extern "C" void abort(void); +struct T1 {int a, b; virtual void f(){}}; +struct T : T1 { struct T1 w; int b; }; +void foo (struct T1 *p) { struct T *q = dynamic_cast<T*>(p); if (q->b != 2) abort (); } +/* We shouldn't kill the store to c.b, because foo uses it. */ +int main () { struct T c; c.b = 2; foo (&c); return 0; } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr21463.C b/gcc/testsuite/g++.dg/tree-ssa/pr21463.C new file mode 100644 index 000000000..6d6ee93ba --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr21463.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt1" } */ + +template<class T> static inline const T &ref_max(const T &a, const T &b) +{ return a<b ? b : a; } +template<class T> static inline const T &ref_min(const T &a, const T &b) +{ return a<b ? a : b; } + +template<class T> struct foo_t { + T a0, a1; + T bar_ref(const T b, const T c) { + return ref_max(ref_min(a0, c), ref_min(ref_max(a1, c), b)); + } +}; + +template struct foo_t<int>; + +/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "phiopt1" } } */ +/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "phiopt1" } } */ +/* { dg-final { cleanup-tree-dump "phiopt1" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr21584-1.C b/gcc/testsuite/g++.dg/tree-ssa/pr21584-1.C new file mode 100644 index 000000000..2c96d1027 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr21584-1.C @@ -0,0 +1,38 @@ +extern "C" { + +extern char *strcpy (char *__restrict __dest, __const char *__restrict __src) + throw () __attribute__ ((__nonnull__ (1, 2))); + +extern char *foo (char *__restrict __s) throw (); +} + +class cset { +public: + cset(); + int operator()(unsigned char) const; +private: + char v[(127 * 2 + 1)+1]; +}; + +inline int cset::operator()(unsigned char c) const +{ + return v[c]; +} + +extern cset csspace; + +void baz() +{ + char *vec; + char buf[512]; + + char *p = buf; + while (csspace(*p)) + p++; + + if (*p != '#' && (p = foo(buf)) != 0) { + vec = new char[10+ 1]; + strcpy(vec, p); + } +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr21584-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr21584-2.C new file mode 100644 index 000000000..6246e8d4c --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr21584-2.C @@ -0,0 +1,22 @@ +extern char *strcpy (char *__restrict __dest, __const char *__restrict __src); + +extern char *foo (void); +extern void *malloc(__SIZE_TYPE__) __attribute__((malloc)); + +char v[100]; + +void baz() +{ + char *vec; + char buf[512]; + + char *p = buf; + while (v[(*p)]) + p++; + + if (*p != '#' && (p = foo()) != 0) { + strcpy ((char*)malloc(10), p); + } +} + + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22005.C b/gcc/testsuite/g++.dg/tree-ssa/pr22005.C new file mode 100644 index 000000000..cdaac2b88 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22005.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +struct cl_string +{ + union{ int i; }; + cl_string (); +}; +struct cl_print_univpoly_flags { cl_string univpoly_varname; }; +struct cl_print_flags: cl_print_univpoly_flags {int i;}; +cl_print_flags default_print_flags; diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22037.C b/gcc/testsuite/g++.dg/tree-ssa/pr22037.C new file mode 100644 index 000000000..11fc1b038 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22037.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +extern double sqrt (double) throw (); + +void foo(double& d, int n) +{ + double e=0; + for(int i=0; i<n; i++); + for(int i=0; i<n; i++) e=1; + d = sqrt(e); + + for(int i=0; i<n; i++); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22071.C b/gcc/testsuite/g++.dg/tree-ssa/pr22071.C new file mode 100644 index 000000000..719aed374 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22071.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* This code ends up taking the address of part of the structure that is padding, + and because there is no real field there, the structure alias analyzer would + abort. */ +struct empty_class {}; +struct class1 : empty_class +{ + class1() {} + empty_class value_; +}; +struct lambda : class1 { }; +lambda _1; diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22279.C b/gcc/testsuite/g++.dg/tree-ssa/pr22279.C new file mode 100644 index 000000000..0e17f08ec --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22279.C @@ -0,0 +1,43 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct string +{ + long long _M_p; + long long i; + string(); + int begin(); + int end(); + string(int, int); +}; +struct symbol +{ + int type; + string name; + long long raw_name; + long long demangled_name; + long long version_name; + int version_status; + int status; + void init(); +}; +void symbol::init() { name = string(); } +struct pair +{ + symbol first; + symbol second; + pair(const symbol& __a, const symbol& __b) : first(__a), second(__b) { } +}; +struct vector +{ + void push_back(const pair& __x); +}; +/* This ends up with two RHS deref copies, and we need to get the offsets right on them. */ +void f(vector incompatible) +{ + symbol base; + incompatible.push_back(pair(base, base)); +} + + + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22404.C b/gcc/testsuite/g++.dg/tree-ssa/pr22404.C new file mode 100644 index 000000000..2c6b8cd27 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22404.C @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* We were not getting the offset of a in B and a in C::B correct, + causing an abort. */ +struct A { A(); }; + +struct B : A +{ + A a; +}; + +struct C : B { }; + +C c; diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22444.C b/gcc/testsuite/g++.dg/tree-ssa/pr22444.C new file mode 100644 index 000000000..7df4b9cce --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22444.C @@ -0,0 +1,141 @@ +// PR tree-optimization/22444 +// When creating SFT's, we shouldn't add the original variable +// to the addressable vars list, because this may cause false aliasing +// with the subvars leading to the subvars not being renamed when they should +// { dg-do compile } +// { dg-options "-O2" } +__extension__ typedef __PTRDIFF_TYPE__ ptrdiff_t; +__extension__ typedef __SIZE_TYPE__ size_t; +namespace std +{ + template<class _T1, class _T2> struct pair + { + _T1 first; + _T2 second; + pair(const _T1& __a, const _T2& __b) : first(__a), second(__b) { } + }; +} +namespace __gnu_internal +{ + typedef char __one; + template<typename _Tp> __one __test_type(int _Tp::*); +} +namespace std +{ + template<typename _Tp> struct ___is_pod + { + enum { __value = (sizeof(__gnu_internal::__test_type<_Tp>(0))!= sizeof(__gnu_internal::__one)) }; + }; + template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t, typename _Pointer = _Tp*, typename _Reference = _Tp&> struct iterator + { }; + template<typename _Iterator> struct iterator_traits + { + typedef typename _Iterator::difference_type difference_type; + }; + template<typename _Iterator> class reverse_iterator : public iterator<typename iterator_traits<_Iterator>::iterator_category, typename iterator_traits<_Iterator>::value_type, typename iterator_traits<_Iterator>::difference_type, typename iterator_traits<_Iterator>::pointer, typename iterator_traits<_Iterator>::reference> + { + typedef _Iterator iterator_type; + typedef typename iterator_traits<_Iterator>::difference_type difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + reverse_iterator operator+(difference_type __n) const {} + reverse_iterator& operator+=(difference_type __n) { } + reference operator[](difference_type __n) const { } + }; +} +namespace __gnu_cxx +{ + template<bool _Thread> class __pool; + template<template <bool> class _PoolTp, bool _Thread> struct __common_pool_policy; + template<typename _Tp> class __mt_alloc_base + { + typedef ptrdiff_t difference_type; + typedef _Tp* pointer; + }; + template<typename _Tp, typename _Poolp = __common_pool_policy<__pool, true> > class __mt_alloc : public __mt_alloc_base<_Tp> + { + typedef size_t size_type; + }; +} +namespace std +{ + template<typename _Tp> struct allocator:public __gnu_cxx::__mt_alloc<_Tp> + { + template<typename _Tp1> struct rebind + { + typedef allocator<_Tp1> other; + }; + }; + template <class _Arg, class _Result> struct unary_function { }; + template <class _Arg1, class _Arg2, class _Result> struct binary_function + { + typedef _Arg2 second_argument_type; + }; + template <class _Tp> struct less : public binary_function<_Tp, _Tp, bool> + { + bool operator()(const _Tp& __x, const _Tp& __y) const { } + }; + template <class _Tp> struct _Identity : public unary_function<_Tp,_Tp> { }; + struct _Rb_tree_node_base + { + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + _Base_ptr _M_right; + static _Base_ptr _S_minimum(_Base_ptr __x) { } + static _Base_ptr _S_maximum(_Base_ptr __x) { } + }; + template<typename _Val> struct _Rb_tree_node { }; + template<typename _Tp> struct _Rb_tree_iterator + { + typedef _Tp* pointer; + typedef _Rb_tree_iterator<_Tp> _Self; + typedef _Rb_tree_node_base::_Base_ptr _Base_ptr; + pointer operator->() const { } + _Self operator++(int) { } + _Base_ptr _M_node; + }; + template<typename _Tp> struct _Rb_tree_const_iterator + { + typedef const _Tp* pointer; + typedef _Rb_tree_iterator<_Tp> iterator; + typedef _Rb_tree_node_base::_Const_Base_ptr _Base_ptr; + _Rb_tree_const_iterator(const iterator& __it) : _M_node(__it._M_node) { } + _Base_ptr _M_node; + }; + template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc = allocator<_Val> > struct _Rb_tree + { + typedef typename _Alloc::template rebind<std::_Rb_tree_node<_Val> >::other _Node_allocator; + typedef _Rb_tree_node_base* _Base_ptr; + typedef const _Rb_tree_node_base* _Const_Base_ptr; + typedef std::_Rb_tree_node<_Val> _Rb_tree_node; + typedef _Key key_type; + typedef _Val value_type; + typedef value_type* pointer; + typedef _Rb_tree_node* _Link_type; + template<typename _Key_compare, bool _Is_pod_comparator = std::___is_pod<_Key_compare>::__value> struct _Rb_tree_impl + : _Node_allocator + { + _Rb_tree_node_base _M_header; + }; + _Rb_tree_impl<_Compare> _M_impl; + typedef _Rb_tree_iterator<value_type> iterator; + typedef _Rb_tree_const_iterator<value_type> const_iterator; + typedef std::reverse_iterator<iterator> reverse_iterator; + pair<iterator,bool> insert_unique(const value_type& __x); + }; + template<class _Key, class _Compare, class _Alloc> class set + { + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef typename _Alloc::template rebind<_Key>::other _Key_alloc_type; + typedef _Rb_tree<_Key, value_type, _Identity<value_type>, key_compare, _Key_alloc_type> _Rep_type; + _Rep_type _M_t; + typedef typename _Rep_type::const_iterator iterator; + std::pair<iterator,bool> insert(const value_type& __x) + { + std::pair<typename _Rep_type::iterator, bool> __p = _M_t.insert_unique(__x); + return std::pair<iterator, bool>(__p.first, __p.second); + } + }; +} +template class std::set<int, std::less<int>, std::allocator<char> >; diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22488.C b/gcc/testsuite/g++.dg/tree-ssa/pr22488.C new file mode 100644 index 000000000..9063b067a --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22488.C @@ -0,0 +1,33 @@ +// PR tree-optimization/22488 +// This testcase is really a C++ FE bug in represnting virtual inheritance +// It gives the appearance to the middle end that the fields exist twice +// which resulted in a very confused structure analyzer +// { dg-do compile } +// { dg-options "-O" } +struct X +{ + int i0, i1; + char c; +}; + +struct A +{ + int i; + char c0, c1; + + virtual ~A(); +}; + +struct B : virtual A {}; + +struct C : B +{ + X x; + + void bar(X y) { x = y; } +}; + +void foo() +{ + C().bar(X()); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22550.C b/gcc/testsuite/g++.dg/tree-ssa/pr22550.C new file mode 100644 index 000000000..5f5577620 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22550.C @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +class X { +public: + int mfunc1 () { + return 1; + } + int mfunc2 () { + return 2; + } + X (int a, int b) { } +}; + +typedef int (X::*memfunc_p_t) (); + +memfunc_p_t mf_arr[2] = { &X::mfunc1, &X::mfunc2 }; + +int +main () +{ + // Get pntr to the array of pointers to member-funcs + memfunc_p_t (*mf_arr_p)[2] = &mf_arr; + // Compare indirect against direct access to an array element + if ((*mf_arr_p)[0] != mf_arr[0]) + return 1; + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr22615.C b/gcc/testsuite/g++.dg/tree-ssa/pr22615.C new file mode 100644 index 000000000..a8936c4cb --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr22615.C @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* Ensure that we don't crash when people decide to return the address of padding. */ + +struct A +{ + char c; + int i; +}; + +A a; + +struct B +{ + char c, d; +}; + +union C +{ + A *p; + B *q; + + C() : p(&a) {} + char& foo() { return q->d; } +}; +void bar() { C().foo() = 0; } + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr23046.C b/gcc/testsuite/g++.dg/tree-ssa/pr23046.C new file mode 100644 index 000000000..eb8f39558 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr23046.C @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +enum eumtype { ENUM1, ENUM2 }; +void g(const eumtype kind ); +void f(long i); +void g(const eumtype kind) +{ + if ((kind != ENUM1) && (kind != ENUM2)) + f(kind); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr23164.C b/gcc/testsuite/g++.dg/tree-ssa/pr23164.C new file mode 100644 index 000000000..2318a309c --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr23164.C @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +bool f(); +struct S { + S(); + ~S(); +}; +void g() { + for (;;) { + S s1, s2, s3, s4, s5, s6; + if (f()) + continue; + if (f()) + return; + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr23624.C b/gcc/testsuite/g++.dg/tree-ssa/pr23624.C new file mode 100644 index 000000000..769d690ce --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr23624.C @@ -0,0 +1,8 @@ +/* { dg-do compile } */ + +template <int> +void f() +{ + int *t, i; + t[i ? 0 : i]; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr23948.C b/gcc/testsuite/g++.dg/tree-ssa/pr23948.C new file mode 100644 index 000000000..c34161409 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr23948.C @@ -0,0 +1,19 @@ +/* { dg-options "-O1 -ffast-math -fdump-tree-recip" } */ +/* { dg-do compile } */ + +struct MIOFILE { + ~MIOFILE(); +}; +double potentially_runnable_resource_share(); +void f1(double); +int make_scheduler_request(double a, double b) +{ + MIOFILE mf; + double prrs = potentially_runnable_resource_share(); + f1(a/prrs); + f1(1/prrs); + f1(b/prrs); +} + +/* { dg-final { scan-tree-dump-times " / " 1 "recip" } } */ +/* { dg-final { cleanup-tree-dump "recip" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24172.C b/gcc/testsuite/g++.dg/tree-ssa/pr24172.C new file mode 100644 index 000000000..245186a3c --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24172.C @@ -0,0 +1,11 @@ +// { dg-options "-O2" } +void IOException( char); +inline int* dummy( const char* const mode ) +{ + IOException(*mode+*mode); +} + +void prepare_inpaint( ) +{ + dummy ("rb"); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24231-1.C b/gcc/testsuite/g++.dg/tree-ssa/pr24231-1.C new file mode 100644 index 000000000..d3c053efd --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24231-1.C @@ -0,0 +1,42 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* FRE testcase for PR 24231, problem with PRE coalescing abnormal phis. */ +struct f +{ + int i; +}; +struct h{h();}; +int g(void); +int g1(void) throw(); +int h2222(f*); +void ghh(int); + +int main(void) +{ + int i; + f t; + try + { + i = g1(); + try + { + i = g(); + }catch(...) + {} + int j = i; + try + { t.i = i; + i = g(); + }catch(...) + {} + i = 2; + int h = t.i; + ghh (h); + + g(); + }catch(...) + {} + return i; +} + + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24231-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr24231-2.C new file mode 100644 index 000000000..188b1a26b --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24231-2.C @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* FRE testcase for PR 24231, problem with PRE coalescing abnormal phis. */ +struct f +{ + int i; +}; +struct h{h();}; +int g(void); +int g1(void) throw(); +int h2222(f*); +void ghh(int); + +int main(void) +{ + int i; + f t; + try + { + i = g1(); + try + { + i = g(); + }catch(...) + {} + int j = i; + try + { + i = g(); + }catch(...) + {} + t.i = j; + i = 2; + int h = t.i; + ghh (h); + + g(); + }catch(...) + {} + return i; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24231-3.C b/gcc/testsuite/g++.dg/tree-ssa/pr24231-3.C new file mode 100644 index 000000000..a9ea58b11 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24231-3.C @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* PRE testcase for PR 24231, problem with PRE coalescing abnormal phis. */ +struct MemoryManager { + virtual void deallocate() = 0; +}; +struct XalanVector { + ~XalanVector() { + m_memoryManager->deallocate(); + } + void swap(XalanVector& theOther) { + MemoryManager* const theTempManager = m_memoryManager; + m_memoryManager = theOther.m_memoryManager; + theOther.m_memoryManager = theTempManager; + theOther.m_size = 0; + } + void push_back() { + XalanVector theTemp(*this); + theTemp.push_back(); + swap(theTemp); + } + MemoryManager* m_memoryManager; + int m_size; +}; +void f(void) { + XalanVector tempVector; + tempVector.push_back(); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24238.C b/gcc/testsuite/g++.dg/tree-ssa/pr24238.C new file mode 100644 index 000000000..3fdd5784e --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24238.C @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +typedef struct SDL_Rect { + unsigned short w, h; +}SDL_Rect; +SDL_Rect *location(); +SDL_Rect inner_location() +{ + SDL_Rect r = *location(); + r.w -= 1; + return r; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24351-1.C b/gcc/testsuite/g++.dg/tree-ssa/pr24351-1.C new file mode 100644 index 000000000..40959effa --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24351-1.C @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +struct adaptor_base { +}; +struct bound_argument { + bound_argument(); +}; +template <class T_functor> struct adaptor_functor : public adaptor_base { + explicit adaptor_functor(const T_functor& _A_functor) : functor_(_A_functor) +{ + } + T_functor functor_; + bound_argument bound_; +}; +template <class T_functor> struct adapts : public adaptor_base { + explicit adapts(const T_functor& _A_functor) : functor_(_A_functor) { + } + adaptor_functor<T_functor> functor_; +}; +int main() { + adapts<adapts<int> > a (adapts<int>(1)); +} + + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24351-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr24351-2.C new file mode 100644 index 000000000..cfc0e4a4c --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24351-2.C @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +struct adaptor_base {}; +struct bound_argument { + bound_argument(); +}; +struct adaptor_functorint : public adaptor_base {}; +struct adaptsint : public adaptor_base { + adaptsint(const int& _A_functor); + adaptor_functorint functor_; +}; +struct adaptor_functor_adaptsint { + adaptor_functor_adaptsint(const adaptsint& _A_functor) : functor_(_A_functor) + {} + adaptsint functor_; + bound_argument bound_; +}; +struct adapts_adaptsint { + adapts_adaptsint(const adaptsint& _A_functor) : functor_(_A_functor) + {} + adaptor_functor_adaptsint functor_; +}; +int main() { + adapts_adaptsint a (adaptsint(1)); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24351-3.C b/gcc/testsuite/g++.dg/tree-ssa/pr24351-3.C new file mode 100644 index 000000000..09a3f9462 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24351-3.C @@ -0,0 +1,101 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +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_type> struct type_trait<T_type&> { + typedef T_type& pass; + }; + template<> struct type_trait<void> { + typedef void pass; + }; + 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 { + typedef typename T_functor::result_type result_type; + typedef T_functor functor_type; + }; + struct adaptor_base : public functor_base { + }; + template <class T_functor, class T_arg1=void,class T_arg2=void,class T_arg3=void,class T_arg4=void,class T_arg5=void,class T_arg6=void,class T_arg7=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,class T_arg2=void,class T_arg3=void,class T_arg4=void,class T_arg5=void,class T_arg6=void,class T_arg7=void> struct deduce_result_type { + typedef typename sigc::deduce_result_type<T_functor, T_arg1,T_arg2,T_arg3,T_arg4,T_arg5,T_arg6,T_arg7>::type type; + }; + typedef typename functor_trait<T_functor>::result_type result_type; + template <class T_arg1,class T_arg2> typename deduce_result_type<T_arg1,T_arg2>::type operator()(T_arg1 _A_arg1,T_arg2 _A_arg2) const { + return functor_(_A_arg1,_A_arg2); + } + explicit adaptor_functor(const T_functor& _A_functor) : functor_(_A_functor) { + } + mutable T_functor 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 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() { + } + T_type visited_; + }; + template <int I_location, class T_functor, class T_type1=nil,class T_type2=nil,class T_type3=nil,class T_type4=nil,class T_type5=nil,class T_type6=nil,class T_type7=nil> struct bind_functor; + template <class T_functor, class T_bound> struct bind_functor<0, T_functor, T_bound, nil,nil,nil,nil,nil,nil> : public adapts<T_functor> { + typedef typename adapts<T_functor>::adaptor_type adaptor_type; + template <class T_arg1=void,class T_arg2=void,class T_arg3=void,class T_arg4=void,class T_arg5=void,class T_arg6=void,class T_arg7=void> struct deduce_result_type { + typedef typename adaptor_type::template deduce_result_type<typename type_trait<typename unwrap_reference<T_bound>::type>::pass, typename type_trait<T_arg1>::pass, typename type_trait<T_arg2>::pass, typename type_trait<T_arg3>::pass, typename type_trait<T_arg4>::pass, typename type_trait<T_arg5>::pass, typename type_trait<T_arg6>::pass>::type type; + }; + typedef typename adaptor_type::result_type result_type; + result_type operator()() { + return this->functor_.template operator()<typename type_trait<typename unwrap_reference<T_bound>::type>::pass> (bound_.invoke()); + } + template <class T_arg1> typename deduce_result_type<T_arg1>::type operator()(T_arg1 _A_arg1) { + return this->functor_.template operator()<typename type_trait<typename unwrap_reference<T_bound>::type>::pass, typename type_trait<T_arg1>::pass> (bound_.invoke(), _A_arg1); + } + bind_functor(typename type_trait<T_functor>::take _A_func, typename type_trait<T_bound>::take _A_bound) : adapts<T_functor>(_A_func), bound_(_A_bound) { + } + bound_argument<T_bound> bound_; + }; + template <int I_location, class T_bound1, class T_functor> inline bind_functor<I_location, T_functor, T_bound1> bind(const T_functor& _A_func, T_bound1 _A_b1) { + return bind_functor<I_location, T_functor, T_bound1>(_A_func, _A_b1); + }; +} +struct foo { + typedef int result_type; + int operator()(int i, int j); +}; +int main() { + sigc::bind<0>(sigc::bind<0>(foo(),7),8)(); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr24439.C b/gcc/testsuite/g++.dg/tree-ssa/pr24439.C new file mode 100644 index 000000000..74576b5f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr24439.C @@ -0,0 +1,10 @@ +/* { dg-do compile } */ + +/* We used to ICE in invert_truthvalue on the void type + 2nd argument of the COND_EXPR. */ + +void foo(void) +{ + int value=1; + !(value?true:throw); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr25771.C b/gcc/testsuite/g++.dg/tree-ssa/pr25771.C new file mode 100644 index 000000000..6823494ea --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr25771.C @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +int ggggg(); +struct string { + static int _S_empty_rep_storage[]; + void _M_destroy(); + char* _M_rep; + ~string() + { + if (_M_rep != (char*)&_S_empty_rep_storage ) + if (ggggg() <= 0) + _M_destroy(); + } +}; +extern void SDL_FreeSurface(int surface); +struct scoped_resource { + ~scoped_resource() { + SDL_FreeSurface(1); + } +}; +struct surface { + scoped_resource surface_; +}; +struct button { + string help_text_; + string label_; + surface image_; +}; +struct scrollbar { + string help_text_; + button uparrow_; +}; +scrollbar a; + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr26140.C b/gcc/testsuite/g++.dg/tree-ssa/pr26140.C new file mode 100644 index 000000000..3e3743fbd --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr26140.C @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +struct Pitch +{ + int notename_; +}; +struct Audio_note +{ + Audio_note (Pitch p); +}; +void create_audio_elements () +{ + Pitch *pit; + new Audio_note (*pit); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr26406.C b/gcc/testsuite/g++.dg/tree-ssa/pr26406.C new file mode 100644 index 000000000..c2d160508 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr26406.C @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int *f(int *b) +{ + int * a = new int[104]; + *a = 1; + if (a == 0) + return b; + return a; +} + +/* { dg-final { scan-tree-dump-not "if" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr26443.C b/gcc/testsuite/g++.dg/tree-ssa/pr26443.C new file mode 100644 index 000000000..1db87ab87 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr26443.C @@ -0,0 +1,20 @@ +// { dg-do compile } + +struct A +{ + double x[4]; +}; + +struct B +{ + A y[2]; +}; + +A foo(B *p) +{ + for ( int i=0; i<4; ++i ) + p->y[1].x[i]=0; + + A a; + return a; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr26757.C b/gcc/testsuite/g++.dg/tree-ssa/pr26757.C new file mode 100644 index 000000000..4d124e3c4 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr26757.C @@ -0,0 +1,44 @@ +// PR c++/26757 +// { dg-do run } +// { dg-options "-O" } + +extern "C" void abort (); + +typedef struct A +{ + int c; + int d; +} A; + +A *b; + +void +foo () +{ + b->c++; + extern A *b; + b->d++; + +} + +void +bar () +{ + if (b->d) + b->c++; +} + + +int +main () +{ + A a = { 0, 0 }; + b = &a; + foo (); + bar (); + if (b->c != 2) + abort (); + if (b->d != 1) + abort (); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27090.C b/gcc/testsuite/g++.dg/tree-ssa/pr27090.C new file mode 100644 index 000000000..0fb46f35d --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27090.C @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +template <class T> +struct Bar +{ + int get() { return static_cast<T*>(this)->get2(); } +}; +struct Foo : public Bar<Foo> +{ + int get2() { return x; } + int x; +}; + +int foo(Foo& f) +{ + return f.get(); +} + +/* { dg-final { scan-tree-dump "f_..D.->x;" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27283.C b/gcc/testsuite/g++.dg/tree-ssa/pr27283.C new file mode 100644 index 000000000..224ea6a9b --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27283.C @@ -0,0 +1,57 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +namespace Gambit +{ + template < class T > class Array + { + protected:int mindex, maxdex; + T *data; + int InsertAt (const T & t, int n) + { + T *new_data = new T[++this->maxdex - this->mindex + 1] - this->mindex; + int i; + for (i = this->mindex; i <= n - 1; i++) + new_data[i] = this->data[i]; + } + public: Array (unsigned int len = 0):mindex (1), maxdex (len), + data ((len) ? new T[len] - + 1 : 0) + { + } + virtual ~ Array () + { + if (maxdex >= mindex) + delete[](data + mindex); + } + const T & operator[] (int index) const + { + } + int Append (const T & t) + { + return InsertAt (t, this->maxdex + 1); + } + }; +} +class gIndexOdometer +{ +private:Gambit::Array < int >MinIndices; + Gambit::Array < int >CurIndices; + gIndexOdometer (const Gambit::Array < int >, const Gambit::Array < int >); + void SetIndex (const int &, const int &); + int NoIndices () const; + gIndexOdometer AfterExcisionOf (int &) const; +}; +gIndexOdometer +gIndexOdometer::AfterExcisionOf (int &to_be_zapped) const +{ + Gambit::Array < int >NewMins, NewMaxs; + int i; + for (i = 1; i <= NoIndices (); i++) + { + NewMins.Append (MinIndices[i]); + } + gIndexOdometer NewOdo (NewMins, NewMaxs); + NewOdo.SetIndex (i, CurIndices[i]); +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27291.C b/gcc/testsuite/g++.dg/tree-ssa/pr27291.C new file mode 100644 index 000000000..b8b5e136a --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27291.C @@ -0,0 +1,363 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +namespace std +{ + template < class _T1, class _T2 > struct pair + { + }; +} +extern "C" +{ + extern "C" + { + typedef int int32_t __attribute__ ((__mode__ (__SI__))); + struct _pthread_fastlock + { + } + pthread_mutexattr_t; + } +} +namespace std +{ + struct __numeric_limits_base + { + }; + template < typename _Tp > + struct numeric_limits:public __numeric_limits_base + { + static const bool is_integer = true; + }; +}; +typedef unsigned int uint32_t; +namespace std +{ + template < typename _Alloc > class allocator; + template < class _CharT > struct char_traits; + template < typename _CharT, typename _Traits = + char_traits < _CharT >, typename _Alloc = + allocator < _CharT > >class basic_string; + typedef basic_string < char >string; +} +namespace __gnu_cxx +{ + template < typename _Tp > class new_allocator + { + }; +} +namespace std +{ + template < typename _Tp > class allocator:public __gnu_cxx::new_allocator < + _Tp > + { + }; + template < typename _CharT, typename _Traits, + typename _Alloc > class basic_string + { + public:inline basic_string (); + basic_string (const _CharT * __s, const _Alloc & __a = _Alloc ()); + }; +} +namespace boost +{ + template < class T > class integer_traits:public std::numeric_limits < T > + { + }; + namespace detail + { + template < class T, T min_val, T max_val > class integer_traits_base + { + }; + } + template <> class integer_traits < int >:public std::numeric_limits < int >, + public detail::integer_traits_base < int, (-2147483647 - 1), 2147483647 > + { + }; + namespace random + { + template < class IntType, IntType m > class const_mod + { + public:static IntType add (IntType x, IntType c) + { + } + static IntType mult (IntType a, IntType x) + { + return mult_schrage (a, x); + } + static IntType mult_add (IntType a, IntType x, IntType c) + { + return add (mult (a, x), c); + } + static IntType mult_schrage (IntType a, IntType value) + { + for (;;) + { + if (value > 0) + break; + value += m; + } + } + }; + template < class IntType, IntType a, IntType c, IntType m, + IntType val > class linear_congruential + { + public:typedef IntType result_type; + static const IntType modulus = m; + explicit linear_congruential (IntType x0 = 1):_modulus (modulus), + _x (_modulus ? (x0 % _modulus) : + x0) + { + } + IntType operator () () + { + _x = const_mod < IntType, m >::mult_add (a, _x, c); + } + private:IntType _modulus; + IntType _x; + }; + } + typedef random::linear_congruential < int32_t, 16807, 0, 2147483647, + 1043618065 > minstd_rand0; + namespace random + { + namespace detail + { + template < class T > struct ptr_helper + { + typedef T value_type; + typedef T & reference_type; + typedef const T & rvalue_type; + static reference_type ref (T & r) + { + } + }; + template < class T > struct ptr_helper <T & > + { + typedef T value_type; + typedef T & rvalue_type; + }; + } + } + template < class UniformRandomNumberGenerator, class RealType = + double >class uniform_01 + { + public:typedef UniformRandomNumberGenerator base_type; + typedef RealType result_type; + explicit uniform_01 (base_type rng):_rng (rng), + _factor (result_type (1) / + (result_type ((_rng.max) () - (_rng.min) ()) + + result_type (std::numeric_limits < + base_result >::is_integer ? 1 : 0))) + { + } + result_type operator () () + { + return result_type (_rng () - (_rng.min) ()) * _factor; + } + private:typedef typename base_type::result_type base_result; + base_type _rng; + result_type _factor; + }; + namespace random + { + namespace detail + { + template < class UniformRandomNumberGenerator > + class pass_through_engine + { + private:typedef ptr_helper < UniformRandomNumberGenerator > + helper_type; + public:typedef typename helper_type::value_type base_type; + typedef typename base_type::result_type result_type; + explicit pass_through_engine (UniformRandomNumberGenerator + rng):_rng (static_cast < + typename helper_type:: + rvalue_type > (rng)) + { + } + result_type min () const + { + } + result_type max () const + { + } + base_type & base () + { + } + result_type operator () () + { + return base ()(); + } + private:UniformRandomNumberGenerator _rng; + }; + } + template < class RealType, int w, unsigned int p, + unsigned int q > class lagged_fibonacci_01 + { + public:typedef RealType result_type; + static const unsigned int long_lag = p; + lagged_fibonacci_01 () + { + seed (); + } + public:void seed (uint32_t value = 331u) + { + minstd_rand0 intgen (value); + seed (intgen); + } + template < class Generator > void seed (Generator & gen) + { + typedef detail::pass_through_engine < Generator & >ref_gen; + uniform_01 < ref_gen, RealType > gen01 = + uniform_01 < ref_gen, RealType > (ref_gen (gen)); + for (unsigned int j = 0; j < long_lag; ++j) + x[j] = gen01 (); + } + RealType x[long_lag]; + }; + } + typedef random::lagged_fibonacci_01 < double, 48, 607, + 273 > lagged_fibonacci607; + namespace random + { + namespace detail + { + template < bool have_int, bool want_int > struct engine_helper; + template <> struct engine_helper <true, true > + { + template < class Engine, class DistInputType > struct impl + { + typedef pass_through_engine < Engine > type; + }; + }; + } + } + template < class Engine, class Distribution > class variate_generator + { + private:typedef random::detail::pass_through_engine < Engine > + decorated_engine; + public:typedef typename decorated_engine::base_type engine_value_type; + typedef Distribution distribution_type; + variate_generator (Engine e, Distribution d):_eng (decorated_engine (e)), + _dist (d) + { + } + private:enum + { + have_int = + std::numeric_limits < + typename decorated_engine::result_type >::is_integer, want_int = + std::numeric_limits < typename Distribution::input_type >::is_integer + }; + typedef typename random::detail::engine_helper < have_int, + want_int >::template impl < decorated_engine, + typename Distribution::input_type >::type internal_engine_type; + internal_engine_type _eng; + distribution_type _dist; + }; + template < class RealType = double >class uniform_real + { + public:typedef RealType input_type; + }; +} +namespace alps +{ + class BufferedRandomNumberGeneratorBase + { + }; + template < class RNG > + class BufferedRandomNumberGenerator:public + BufferedRandomNumberGeneratorBase + { + public: BufferedRandomNumberGenerator ():rng_ (), gen_ (rng_, + boost:: + uniform_real <> ()) + { + } + protected: RNG rng_; + boost::variate_generator < RNG &, boost::uniform_real <> >gen_; + }; +} +namespace boost +{ + namespace detail + { + class sp_counted_base + { + }; + class shared_count + { + private:sp_counted_base * pi_; + public:shared_count ():pi_ (0) + { + } + template < class Y > explicit shared_count (Y * p):pi_ (0) + { + } + }; + } + template < class T > class shared_ptr + { + public:typedef T element_type; + template < class Y > explicit shared_ptr (Y * p):px (p), pn (p) + { + } + T *px; + detail::shared_count pn; + }; +} +namespace std +{ + template < typename _Key, typename _Tp, typename _Compare = + std::allocator < std::pair < const _Key, _Tp > > > class map + { + public:typedef _Key key_type; + typedef _Tp mapped_type; + mapped_type & operator[] (const key_type & __k) + { + } + }; +} +namespace alps +{ + namespace detail + { + template < class BASE > class abstract_creator + { + public:typedef BASE base_type; + virtual base_type *create () const = 0; + }; + template < class BASE, + class T > class creator:public abstract_creator < BASE > + { + public:typedef BASE base_type; + base_type *create () const + { + return new T (); + } + }; + } + template < class KEY, class BASE > class factory + { + public:typedef BASE base_type; + typedef KEY key_type; + typedef boost::shared_ptr < detail::abstract_creator < base_type > + >pointer_type; + template < class T > bool register_type (key_type k) + { + creators_[k] = pointer_type (new detail::creator < BASE, T > ()); + } + private:typedef std::map < key_type, pointer_type > map_type; + map_type creators_; + }; + class RNGFactory:public factory < std::string, + BufferedRandomNumberGeneratorBase > + { + public:RNGFactory (); + }; +} +alps::RNGFactory::RNGFactory () +{ + register_type < BufferedRandomNumberGenerator < boost::lagged_fibonacci607 > + >("lagged_fibonacci607"); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27548.C b/gcc/testsuite/g++.dg/tree-ssa/pr27548.C new file mode 100644 index 000000000..d23b959a5 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27548.C @@ -0,0 +1,60 @@ +// PR tree-optimization/27548 +// { dg-do compile } +// { dg-options "-O1" } + +namespace Gambit +{ + template < class T > class Array + { + protected:int mindex, maxdex; + T *data; + int InsertAt (const T & t, int n) + { + T *new_data = new T[++this->maxdex - this->mindex + 1] - this->mindex; + int i; + for (i = this->mindex; i <= n - 1; i++) + new_data[i] = this->data[i]; + new_data[i++] = t; + } + public: Array (unsigned int len = 0):mindex (1), maxdex (len), + data ((len) ? new T[len] - + 1 : 0) + { + } + virtual ~ Array () + { + if (maxdex >= mindex) + delete[](data + mindex); + } + const T & operator[] (int index) const + { + } + int Append (const T & t) + { + return InsertAt (t, this->maxdex + 1); + } + }; +} + +class gIndexOdometer +{ +private:Gambit::Array < int >MinIndices; + Gambit::Array < int >CurIndices; + gIndexOdometer (const Gambit::Array < int >, const Gambit::Array < int >); + void SetIndex (const int &, const int &); + int NoIndices () const; + gIndexOdometer AfterExcisionOf (int &) const; +}; +gIndexOdometer +gIndexOdometer::AfterExcisionOf (int &to_be_zapped) const +{ + Gambit::Array < int >NewMins, NewMaxs; + int i; + for (i = 1; i <= NoIndices (); i++) + { + NewMins.Append (MinIndices[i]); + } + gIndexOdometer NewOdo (NewMins, NewMaxs); + for (i = 1; i < to_be_zapped; i++) + NewOdo.SetIndex (i, CurIndices[i]); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27549.C b/gcc/testsuite/g++.dg/tree-ssa/pr27549.C new file mode 100644 index 000000000..cd5944d24 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27549.C @@ -0,0 +1,79 @@ +// PR tree-optimization/27549 +// { dg-do compile } +// { dg-options "-O2" } + +typedef __SIZE_TYPE__ size_t; + +struct E +{ + virtual ~E () {} + virtual size_t e () const = 0; + virtual void f (char *x) const = 0; +}; + +struct F : public E +{ + F () {} + virtual ~F () {} + virtual size_t e () const { return 0; } + virtual void f (char *x) const { *x = '\0'; } +}; + +struct S +{ + S () { a = new char[32]; b = 32; c = 0; a[0] = 0; } + void s (const char *x, size_t y) { v (c + y + 1); __builtin_memcpy(a + c, x, y); c += y; a[c] = '\0'; } + void s (const E *x) { size_t l = x->e(); v (c + l + 1); x->f (a + c); c += l; } + const char *t () { return a; } + void v (size_t n) + { + if (b >= n) return; + + size_t b2 = b; + char *a2 = a; + + for (;;) + { + b *= 2; + if (b >= n) + break; + } + + a = new char[b]; + + if (b2) + { + __builtin_memcpy(a, a2, c); + a2[0] = 0; + for (size_t i = 1; i < b2; i++) + a2[i] = a2[i - 1]; + delete[] a2; + } + } + + ~S () + { + if (b) + { + a[0] = 0; + for (size_t i = 1; i < b; i++) + a[i] = a[i - 1]; + } + delete[] a; + } + char * a; + size_t b, c; +}; + +const char *p; +size_t q; +const F u; + +const char * +foo () +{ + S s; + s.s (p, q); + s.s (&u); + return s.t (); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27830.C b/gcc/testsuite/g++.dg/tree-ssa/pr27830.C new file mode 100644 index 000000000..01c7fc187 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27830.C @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +struct gc{}; +struct transform:public gc +{ + double x, y, z, t; + transform (void){} +}; +inline transform f (void) +{ + return transform (); +}; +void transformed (void) +{ + new transform (f()); +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27894.C b/gcc/testsuite/g++.dg/tree-ssa/pr27894.C new file mode 100644 index 000000000..ac97a35f1 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27894.C @@ -0,0 +1,82 @@ +// PR c++/27894 +// { dg-do compile } +// { dg-options "-O" } + +class A; +struct B +{ + B (unsigned long); + int b2 () const; + A *b1 () const; +}; + +enum { P = 0 }; +enum O { Q = 75, }; +class C; +struct D { A *d; }; +struct E +{ + B e1 (int) const; + A *e2 (const B &) const; + D e3[4096]; +}; + +inline A * +E::e2 (const B & x) const +{ + const D *w = &e3[x.b2 ()]; + return (A *) w->d; +} + +extern E *e; + +inline A * +B::b1 () const +{ + extern E *e; + return e->e2 (*this); +} + +template <class T> struct F : public B +{ + F (const B &); + T *b1 () const; +}; + +template < class T > inline T * F <T>::b1 () const +{ + return (T *) B::b1 (); +}; + +typedef F <C> N; + +class G {}; +class H : public G {}; +class I : public H {}; +class J {}; +class K {}; +struct L +{ + void l (J *, C *, int, const char *, O); +}; +class M : public K, public I +{ + void m (J &, int, const char *); + void m (J &, int, int, const char *, float); +}; + +void +M::m (J &x, int y, const char *z) +{ + L *w = new L; + N v = e->e1 (y); + w->l (&x, v.b1 (), P, z, Q); +} + +void +M::m (J &x, int y, int s, const char *z, float t) +{ + L *w = new L; + N v = e->e1 (y); + w->l (&x, v.b1 (), s, z, (O) (int) ((t) ? (50 + 20 / (float) t) : 0)); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr28003.C b/gcc/testsuite/g++.dg/tree-ssa/pr28003.C new file mode 100644 index 000000000..ff260bcf4 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr28003.C @@ -0,0 +1,31 @@ +// PR tree-optimization/28003 +// Alias grouping needs to be computed after call clobbering, because it +// changes around the tags and variables in a way that makes our +// call clobbering computation incorrect. +// { dg-do run } +// { dg-options "-O2" } +extern "C" void abort(void); +struct A +{ + int i, j[9]; + A() : i(1) { j[0]=j[1]=j[2]=j[3]=j[4]=j[5]=j[6]=j[7]=j[8]=0; } +}; + +struct B +{ + A a; +}; + +B b[] = +{ + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, + {}, {}, {}, {}, {} +}; + +int main() +{ + if (1 - b[sizeof(b)/sizeof(B) - 1].a.i != 0) + abort(); + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr28238.C b/gcc/testsuite/g++.dg/tree-ssa/pr28238.C new file mode 100644 index 000000000..97e388fbd --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr28238.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +struct iterator{}; +struct ByteIterator : iterator +{ + ByteIterator (){} + int a[1024]; +}; +inline ByteIterator f () +{ + return ByteIterator (); +} +class ConfLexerCore +{ + ConfLexerCore (); + ByteIterator m_matchStart; +}; +ConfLexerCore::ConfLexerCore () +: m_matchStart (f ()) +{ } + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr29902.C b/gcc/testsuite/g++.dg/tree-ssa/pr29902.C new file mode 100644 index 000000000..838a41169 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr29902.C @@ -0,0 +1,19 @@ +/* { dg-do compile { target i?86-*-* } } */ +/* { dg-options "-O1 -fprefetch-loop-arrays -march=athlon" } */ +/* { dg-require-effective-target ilp32 } */ + +int length1(); +int g(int); +void f(int capacity_, char *old_storage) +{ + try { + length1(); + int old_capacity = capacity_; + capacity_ *= 2; + g(capacity_); + for (int i = 1; i < old_capacity; i++) + old_storage[i] = old_storage[i - 1]; + } catch (...) { + for (int i = 1; i < capacity_; i++){old_storage[i] = 0;} + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr30738.C b/gcc/testsuite/g++.dg/tree-ssa/pr30738.C new file mode 100644 index 000000000..b9d735e81 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr30738.C @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-phiopt1" } */ + +template <class T> +static inline const T& +min_ref (const T &x, const T &y) +{ + return x < y ? x : y; +} + +int test_min_ref (int x, int y) +{ + return min_ref (x, y); +} + +/* { dg-final { scan-tree-dump "MIN_EXPR" "phiopt1" } } */ +/* { dg-final { cleanup-tree-dump "phiopt1" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C new file mode 100644 index 000000000..d2edb1953 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr31146-2.C @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop1" } */ + +#include <new> + +template <class T> +struct Vec +{ + Vec() + { + for (int i=0; i<3; ++i) + new (&a[i]) T(0); + } + T a[3]; +}; + +double foo (void) +{ + Vec<double> v; + return v.a[2]; +} + +/* { dg-final { scan-tree-dump "Replaced .* != 0B. with .1" "forwprop1" } } */ +/* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31146.C b/gcc/testsuite/g++.dg/tree-ssa/pr31146.C new file mode 100644 index 000000000..478a488e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr31146.C @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop" } */ + +/* We should be able to optimize this to i[j] = 1 during + early optimizations. */ + +int i[5]; +void foo (int j) +{ + void *p = &i[j]; + int *q = (int *)p; + *q = 1; +} + +/* { dg-final { scan-tree-dump "MEM\\\[.*&i\\\]\\\[j.*\\\] =.* 1;" "forwprop1" } } */ +/* { dg-final { cleanup-tree-dump "forwprop?" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr31307.C b/gcc/testsuite/g++.dg/tree-ssa/pr31307.C new file mode 100644 index 000000000..bdfe5bd5a --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr31307.C @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +union MY_M128 +{ + double i; +}; + +struct RegFile +{ + MY_M128 dst[4]; +}; + +__inline__ __attribute__((always_inline)) static void +MEM_OPT_LOAD(MY_M128* reg, double* mem) +{ + reg[0].i = *mem; +} + +void _ia32_movntdq (double *, double); + +__inline__ __attribute__((always_inline)) static void +MEM_OPT_STORE(MY_M128* reg, double* mem) +{ + _ia32_movntdq ((double*)mem, (double)reg[0].i); +} + +double _mm_adds_epu8 (double __A, double __B); + +int test(unsigned char *d) +{ + RegFile r; + MEM_OPT_LOAD((r.dst) , ((double*) d)); + r.dst[0].i = _mm_adds_epu8(r.dst[0].i, r.dst[0].i); + MEM_OPT_STORE((r.dst), (double*) d); + return 0; +} + +/* { dg-final { scan-tree-dump-not "r.dst" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr33593.C b/gcc/testsuite/g++.dg/tree-ssa/pr33593.C new file mode 100644 index 000000000..f5497407f --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr33593.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fnon-call-exceptions -fdump-tree-optimized" } */ + +#include <stdio.h> + +void foo (int) { printf ("Bar\n"); } + +int +main (void) +{ + int a = 1 / 0; // { dg-warning "division by zero" } + printf ("Foo\n"); + foo (a); +} + +// The expression 1 / 0 should not be propagated into the call to foo() if it +// may trap. +// { dg-final { scan-tree-dump-times "foo \\(1 \\/ 0\\)" 0 "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr33604.C b/gcc/testsuite/g++.dg/tree-ssa/pr33604.C new file mode 100644 index 000000000..7e820d3ef --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr33604.C @@ -0,0 +1,48 @@ +/* { dg-do run } */ +/* { dg-options "-O -fdump-tree-optimized-vops" } */ + +struct Value +{ + double value; + Value(double value_) : value (value_) {} + operator double() const { return value; } + Value& operator=(double other) { value = other; } +}; + +struct Ref +{ + const Value& m; + Ref(const Value& m_) : m(m_) {} + operator double() const { return m; } +}; + +struct Diff +{ + const Ref lhs, rhs; + Diff(const Value& lhs_, const Value& rhs_) : lhs(lhs_), rhs(rhs_) {} + operator double() const { return lhs - rhs; } +}; + +extern "C" void abort (void); +int main(int argc, char *argv[]) +{ + Value I(1), m(4); + for(int a = 0; a < 1000; a++) + m = Diff (I, m); + + if (!(m / 4 == I)) + abort (); + return 0; +} + +/* Check that we propagate + D.2182_13 = (struct Ref *) &D.2137.lhs; + to + D.2182_13->lhs.m ={v} &I; + yielding + D.2137.lhs.m ={v} &I; + so that SRA can promote all locals to registers and we end up + referencing a single virtual operand at abort () after optimization. */ + +/* { dg-final { scan-tree-dump-times ".MEM_\[0-9\]*\\\(D\\\)" 1 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr33615-2.C b/gcc/testsuite/g++.dg/tree-ssa/pr33615-2.C new file mode 100644 index 000000000..542731a60 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr33615-2.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fnon-call-exceptions -fdump-tree-pre-details -w" } */ + +extern volatile int y; + +double +foo (double a, int x) +{ + while (x--) + { + y++; + a += 1.0 / 0.0; + } + return a; +} + +// The expression 1.0 / 0.0 should not be treated as a loop invariant +// if it may throw an exception. +// { dg-final { scan-tree-dump-times "Replaced 1\\\.0e\\\+0 / 0\\\.0" 0 "pre" } } +// { dg-final { cleanup-tree-dump "pre" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr33615.C b/gcc/testsuite/g++.dg/tree-ssa/pr33615.C new file mode 100644 index 000000000..4b0754282 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr33615.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fnon-call-exceptions -fdump-tree-lim-details -w" } */ + +extern volatile int y; + +double +foo (double a, int x) +{ + while (x--) + { + y++; + a += 1.0 / 0.0; + } + return a; +} + +// The expression 1.0 / 0.0 should not be treated as a loop invariant +// if it may throw an exception. +// { dg-final { scan-tree-dump-times "invariant up to" 0 "lim1" } } +// { dg-final { cleanup-tree-dump "lim\[1-2\]" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr34063.C b/gcc/testsuite/g++.dg/tree-ssa/pr34063.C new file mode 100644 index 000000000..994920bb9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr34063.C @@ -0,0 +1,25 @@ +// { PR tree-optimization/34063 } +// { dg-do compile } +// { dg-options "-O2" } + +struct S +{ + double e[9]; + + double const & + operator() (int r, int c) const + { + return e[r * 3 + c]; + } +}; + +void +foo() +{ + S r; + double *p; + for (int j = 0; j < 3; j++) + for (int k = 0; k < 3; k++) + for (int l = k + 1; l < 3; l++) + *p++ = r (k, 0) * r (l, j) + r (k, j) * r (l, 0); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr34355.C b/gcc/testsuite/g++.dg/tree-ssa/pr34355.C new file mode 100644 index 000000000..978ed75df --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr34355.C @@ -0,0 +1,27 @@ +// { dg-do compile } +// { dg-require-effective-target pthread } +// { dg-options "-O3 -ftree-parallelize-loops=4" } + +typedef double EXPRESS[5]; + +extern int Terms; + +void Parse_Rel_Factor (EXPRESS Express, int *Terms) +{ + EXPRESS Local_Express = {5.0, 4.0, 3.0, 2.0, 1.0}; + int Local_Terms = 5; + + int i; + + for (i = (*Terms); i < Local_Terms; i++) + Express[i] = 0.0; + + Express[i] += Local_Express[i]; +} + +double Parse_Float () +{ + EXPRESS Express = {1.0, 2.0, 3.0, 4.0, 5.0}; + + Parse_Rel_Factor (Express, &Terms); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr35144.C b/gcc/testsuite/g++.dg/tree-ssa/pr35144.C new file mode 100644 index 000000000..f0bb7bb63 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr35144.C @@ -0,0 +1,30 @@ +// PR c++/35144 +// { dg-do compile } +// { dg-options "-O2" } + +struct A +{ + int baz (); +}; + +typedef int (A::*P) (); + +struct B +{ + B (); + int foo (P x, int y = 0); +}; + +struct C +{ + typedef int (B::*Q) (P, int); + void bar (Q x) { c = x; } + Q c; +}; + +extern C c; + +B::B () +{ + c.bar ((C::Q) &B::foo); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr36766.C b/gcc/testsuite/g++.dg/tree-ssa/pr36766.C new file mode 100644 index 000000000..37e0d517e --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr36766.C @@ -0,0 +1,31 @@ +// PR tree-optimization/36766 +// { dg-do compile } +// { dg-options "-O -fnon-call-exceptions" } + +struct A +{ + ~A () + { + int *a = this->b; + } + int *b; +}; + +struct B : A +{ + B () + { + int *a = this->b; + } + ~B () + { + int *a = this->b; + } +}; + +void +foo () +{ + B *c = new B; + delete c; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr37084.C b/gcc/testsuite/g++.dg/tree-ssa/pr37084.C new file mode 100644 index 000000000..8fceb0cbb --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr37084.C @@ -0,0 +1,16 @@ +// PR tree-optimization/37084 +// { dg-do compile } +// { dg-options "-O" } + +struct A +{ + A (); +}; + +inline A +foo () +{ + return A (); +} + +const A a (foo ()); diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr37284.C b/gcc/testsuite/g++.dg/tree-ssa/pr37284.C new file mode 100644 index 000000000..26ddc1a05 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr37284.C @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-fstrict-aliasing" } */ + +void* operator new(__SIZE_TYPE__, void* __p) throw() +{ + return __p; +} + +class PatternDriverTop; + +typedef const PatternDriverTop* _Tp; + +void construct(_Tp* __p, const _Tp& __val) +{ + ::new((void *)__p) _Tp(__val); +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr37337.C b/gcc/testsuite/g++.dg/tree-ssa/pr37337.C new file mode 100644 index 000000000..5b8521df8 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr37337.C @@ -0,0 +1,37 @@ +// PR middle-end/37337 +// { dg-do compile } +// { dg-options "-O2" } + +extern "C" +{ + typedef struct _IO_FILE FILE; + extern int __fprintf_chk (FILE *, int, const char *, ...); + extern inline __attribute__ ((always_inline, gnu_inline, artificial)) + int fprintf (FILE *s, const char *f, ...) + { + return __fprintf_chk (s, 1, f, __builtin_va_arg_pack ()); + } +} + +extern int a; +struct A +{ + virtual ~A (void) + { + } +}; + +struct B : public A +{ + B (); + FILE *b; +}; + +void f (int *); +B::B () +{ + f (&a); + for (int i = 0; i < 6; i++) + fprintf (b, "%02x", 0xff); + fprintf (b, "\n--\n"); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr37356.C b/gcc/testsuite/g++.dg/tree-ssa/pr37356.C new file mode 100644 index 000000000..45b99a037 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr37356.C @@ -0,0 +1,34 @@ +// PR middle-end/37356 */ +// { dg-do compile } +// { dg-options "-O" } + +bool foo (); +int bar (); + +bool +baz (int v) +{ + return v == bar (); +} + +struct A +{ + A () { baz (1) || foo (); } +}; + +struct B +{ + static A get () { return A (); } + B (const int &x) { } + B () : b (get ()) { } + A b; +}; + +B c; + +void +test () +{ + int d; + c = d; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr37393.C b/gcc/testsuite/g++.dg/tree-ssa/pr37393.C new file mode 100644 index 000000000..2f9281c96 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr37393.C @@ -0,0 +1,27 @@ +// PR middle-end/37393 +// { dg-do compile } +// { dg-options "-O2" } + +struct A +{ + ~A (); + bool foo () const; +}; + +extern "C" +{ + extern void bar (const char *, ...) __attribute__ ((noreturn)); + extern inline __attribute__ ((always_inline, gnu_inline, artificial)) void + baz (const char *fmt, ...) + { + bar (fmt, __builtin_va_arg_pack ()); + } +}; + +void +test () +{ + A a; + if (a.foo ()) + baz ("foo"); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr38104.C b/gcc/testsuite/g++.dg/tree-ssa/pr38104.C new file mode 100644 index 000000000..6523a5e17 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr38104.C @@ -0,0 +1,19 @@ +// PR tree-optimization/38104 +// { dg-do compile } +// { dg-options "-O3" } + +struct S { int foo; }; + +void f0 (); + +void +f1 (struct S s) +{ + f0 (); +} + +void +f2 () +{ + f1 (*(struct S *) (0)); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr38572.C b/gcc/testsuite/g++.dg/tree-ssa/pr38572.C new file mode 100644 index 000000000..89d228f02 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr38572.C @@ -0,0 +1,32 @@ +// PR tree-optimization/38572 +// { dg-do compile } +// { dg-options "-O2" } + +// Crash caused by the out-of-bounds enum values (all the remaining cruft +// is needed only to trigger the appropriate code path in tree-vrp.c). +enum JSOp +{ + JSOP_GETELEM = 5, + JSOP_LIMIT +}; +extern void g (); +void f (char *pc, char *endpc, int format, char ***fp, enum JSOp op) +{ + while (pc <= endpc) + { + if ((fp && *fp && pc == **fp) || pc == endpc) + { + if (format == 1) + op = (JSOp) 256; + else if (format == 2) + op = (JSOp) 257; + else + op = JSOP_GETELEM; + } + if (op >= JSOP_LIMIT) + { + if (format) + g (); + } + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr38632.C b/gcc/testsuite/g++.dg/tree-ssa/pr38632.C new file mode 100644 index 000000000..04fca2280 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr38632.C @@ -0,0 +1,22 @@ +// { dg-do compile } +// { dg-require-effective-target pthread } +// { dg-options "-O -ftree-parallelize-loops=2" } + +void foo(); + +void bar(int n, char *p) +{ + try + { + foo(); + ++n; + foo(); + for (int i = 0; i < n-1; ++i) + p[i] = 0; + } + catch (...) + { + for (int i = 0; i < n; ++i) + p[i] = 0; + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41186.C b/gcc/testsuite/g++.dg/tree-ssa/pr41186.C new file mode 100644 index 000000000..91f21a8c6 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr41186.C @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre-details" } */ + +struct Foo { + Foo() {}; + int i; + short f; +}; +struct Bar : public Foo { + Bar() {}; + short b; +}; + +extern "C" void abort(void); + +int main() +{ + Bar b1, b2; + b2.i = 0; + b1.f = 0; + b1.b = 1; + b2.f = 1; + b2.b = 2; + static_cast<Foo&>(b1) = static_cast<Foo&>(b2); + if (b1.i != 0 || b1.b != 1) + abort (); + if (b1.f != 1) + abort (); + return 0; +} + +/* { dg-final { scan-tree-dump "Replaced b1.b with 1" "fre" } } */ +/* { dg-final { scan-tree-dump "Replaced b1.i with 0" "fre" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump "Replaced b1.f with 1" "fre" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "fre" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41275.C b/gcc/testsuite/g++.dg/tree-ssa/pr41275.C new file mode 100644 index 000000000..d9b3dce8f --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr41275.C @@ -0,0 +1,16 @@ +// PR middle-end/41275 +// { dg-do compile } +// { dg-options "-O2" } +// this used to ICE +struct ErrmsgWindow +{ + virtual ~ErrmsgWindow() + { + extern int _switch_mode_errorstr; + _switch_mode_errorstr = 42; + } +}; +void ShowErrorMessage(void) +{ + ErrmsgWindow w; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41428.C b/gcc/testsuite/g++.dg/tree-ssa/pr41428.C new file mode 100644 index 000000000..32716cad1 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr41428.C @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-ccp1-details" } */ + +extern "C" void abort (void); +inline void *operator new (__SIZE_TYPE__, void *__p) throw () { return __p; } + +int foo(void) +{ + float f = 0; + int *i = new (&f) int (1); + return *(int *)&f; +} + +/* { dg-final { scan-tree-dump "Folded into: if \\\(1 != 0\\\)" "ccp1" } } */ +/* { dg-final { cleanup-tree-dump "ccp1" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41905.C b/gcc/testsuite/g++.dg/tree-ssa/pr41905.C new file mode 100644 index 000000000..4424ce8d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr41905.C @@ -0,0 +1,4 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +int foo() __attribute__((noreturn)); +int bar() { return foo(); } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41906.C b/gcc/testsuite/g++.dg/tree-ssa/pr41906.C new file mode 100644 index 000000000..321d33aea --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr41906.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fpermissive -w" } */ +/* We aren't interested in the warning, but in the ICE. */ +void foo(); +extern void abort (void); + +void bar() +{ + try { foo(); } + catch (...) {} + catch (int) {abort ();} +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr41961.C b/gcc/testsuite/g++.dg/tree-ssa/pr41961.C new file mode 100644 index 000000000..229e7d4b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr41961.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// { dg-require-effective-target pthread } +// { dg-options "-O3 -ftree-parallelize-loops=2" } + +struct A +{ + char c[17]; + void foo(); +}; + +void A::foo() +{ + for (int i = 0; i < 17; ++i) + c[i] = 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr42337.C b/gcc/testsuite/g++.dg/tree-ssa/pr42337.C new file mode 100644 index 000000000..8abd4b2d1 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr42337.C @@ -0,0 +1,173 @@ +// PR tree-optimize/42337 +// { dg-do compile } +// { dg-options "-O2" } + +template<class _T1, class _T2> struct pair { + _T2 second; +}; +template<typename _Tp> +inline const _Tp& max(const _Tp& __a, const _Tp& __b) { } + +template<typename _ForwardIterator, typename _Tp, typename _Compare> _ForwardIterator +lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __val, _Compare __comp) { } +template<class _CharT> struct char_traits {}; + +template<typename _Iterator, typename _Container> class __normal_iterator { + public: typedef _Iterator iterator_type; + __normal_iterator& operator++() { + } +}; +template<typename _IteratorL, typename _IteratorR, typename _Container> +inline bool operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, const __normal_iterator<_IteratorR, _Container>& __rhs) { } +template<typename _Tp> class new_allocator { + public: + typedef _Tp* pointer; + typedef const _Tp* const_pointer; +}; + +template<typename _Tp> +class allocator: public new_allocator<_Tp> { + public: + template<typename _Tp1> struct rebind { + typedef allocator<_Tp1> other; + }; +}; + +template<typename _Arg, typename _Result> struct unary_function { }; +template<typename _Arg1, typename _Arg2, typename _Result> struct binary_function { }; +template<typename _Tp> struct less : public binary_function<_Tp, _Tp, bool> { }; +template<typename _Pair> struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { }; +template<typename _Tp> struct _Rb_tree_iterator { + typedef _Tp* pointer; + pointer operator->() const { + } +}; +template<typename _Key, typename _Val, typename _KeyOfValue, typename _Compare, typename _Alloc = allocator<_Val> > +class _Rb_tree { + typedef _Val value_type; + public: typedef _Rb_tree_iterator<value_type> iterator; +}; +template <typename _Key, typename _Tp, typename _Compare = less<_Key>, typename _Alloc = allocator<pair<const _Key, _Tp> > > +class map { + public: typedef _Key key_type; + typedef pair<const _Key, _Tp> value_type; + typedef _Compare key_compare; + private: typedef typename _Alloc::template rebind<value_type>::other _Pair_alloc_type; + typedef _Rb_tree<key_type, value_type, _Select1st<value_type>, key_compare, _Pair_alloc_type> _Rep_type; + public: typedef typename _Pair_alloc_type::pointer pointer; + typedef typename _Rep_type::iterator iterator; + iterator find(const key_type& __x) { } +}; + +template<typename _Tp, typename _Alloc> struct _Vector_base { + typedef typename _Alloc::template rebind<_Tp>::other _Tp_alloc_type; +}; +template<typename _Tp, typename _Alloc = allocator<_Tp> > +class vector : protected _Vector_base<_Tp, _Alloc> { + typedef _Vector_base<_Tp, _Alloc> _Base; + typedef typename _Base::_Tp_alloc_type _Tp_alloc_type; + public: + typedef typename _Tp_alloc_type::pointer pointer; + typedef typename _Tp_alloc_type::const_pointer const_pointer; + typedef __normal_iterator<pointer, vector> iterator; + typedef __normal_iterator<const_pointer, vector> const_iterator; + iterator begin() { } + const_iterator begin() const { } + const_iterator end() const { } + unsigned long size() const { } +}; + +class SSC { + public: + SSC () {} + SSC (const int& cs); +}; +extern int flag; + +struct TP { + const int cl_; + const vector<int> &its_; + int max_s_; + }; + +double foo(TP *p); +map<int, int> cs_; + +template <typename T> class vector32 { + public: + typedef T& reference; + typedef T* iterator; + typedef const T* const_iterator; + iterator begin() { return data_; } + iterator end() { return data_ + size_; } + long unsigned int size() const { return size_; } + T* data_; + unsigned size_; +}; + +struct SF : public pair<unsigned long long, double> { }; + +template<typename KEY, typename VALUE> class SFVT { + private: typedef vector32<SF> Container; + typedef typename Container::const_iterator CI; + mutable Container v_; + mutable bool sorted_; + struct Cmp : public binary_function<SF, SF, bool> { + }; + __attribute__((always_inline)) VALUE IS(const SFVT &sfv) const { + if (sfv.v_.size() < v_.size()) { + return sfv.IS(*this); + } + else { + VALUE sum = 0.0; + CI beg = sfv.v_.begin(); + CI end = sfv.v_.end(); + for (CI i = v_.begin(); + i != v_.end(); + ++i) { beg = lower_bound(beg, end, *i, Cmp()); if (beg == end) { return sum; } } + } + } + public: explicit SFVT(const int capacity = 0) : sorted_(true) { } + long unsigned int size() const { } + __attribute__((always_inline)) VALUE DP(const SFVT &sfv) const { + return IS(sfv); + } +}; +class SFV : public SFVT<unsigned long long, double> { }; + +class Edge; +extern int flag2; + +double foo(TP *p) { + int nbests_requested = max(p->max_s_, flag); + map<int, int>::iterator it = cs_.find(p->cl_); + int* c = &it->second; + for (vector<int>::const_iterator iter = p->its_.begin(); + iter != p->its_.end(); + ++iter) { + } + vector<int*> fb; + vector<double> w; + int *hg = 0; + if (flag2 == 10) { + hg = &flag2; + } + int nr = 0; + for (vector<int*>::iterator iter = fb.begin(); + (iter != fb.end() && nr < nbests_requested); + ++iter) { + } + if (hg) { + SFV s_weights; + for (int i = 0; + i < w.size(); + ++i) { + } + SFV uw; + for (int i = 0, j = 0; + i < uw.size() && j < s_weights.size(); + ) { + } + const double tc = uw.DP(s_weights); + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr43411.C b/gcc/testsuite/g++.dg/tree-ssa/pr43411.C new file mode 100644 index 000000000..476e16ad2 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr43411.C @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +class P { public: virtual int val() { return 123; } }; +class Psub : public P { }; + +extern int sink1, sink2; + +void test() { + Psub p; + P &pRef = p; + sink1 = p.val(); + sink2 = pRef.val(); +} + + +inline int v(P &p) { return p.val(); } + +void testInlineP() { + P p; + sink1 = v(p); +} + +void testInlinePsub() { + Psub p; + sink1 = v(p); +} + +// { dg-final { scan-tree-dump-not "OBJ_TYPE_REF" "optimized" { xfail *-*-* } } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr44706.C b/gcc/testsuite/g++.dg/tree-ssa/pr44706.C new file mode 100644 index 000000000..39904d8b9 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr44706.C @@ -0,0 +1,46 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fdump-tree-fnsplit" } */ +class MemoryManager; +class XMLExcepts { +public : + enum Codes { + AttrList_BadIndex + }; +}; +class XMLException { +public: + XMLException(const char* const srcFile, const unsigned int srcLine, +MemoryManager* const memoryManager = 0); +}; +class ArrayIndexOutOfBoundsException : public XMLException { +public: + ArrayIndexOutOfBoundsException(const char* const srcFile , const unsigned +int srcLine , const XMLExcepts::Codes toThrow , MemoryManager* memoryManager = +0) : XMLException(srcFile, srcLine, memoryManager) { + } +}; +class XMLAttDef { + bool fExternalAttribute; +}; +class XMLAttDefList { +public: + MemoryManager* getMemoryManager() const; +}; +class DTDAttDef : public XMLAttDef { +}; +class DTDAttDefList : public XMLAttDefList { + virtual const XMLAttDef &getAttDef(unsigned int index) const ; + DTDAttDef** fArray; + unsigned int fCount; +}; +const XMLAttDef &DTDAttDefList::getAttDef(unsigned int index) const { + if(index >= fCount) + throw ArrayIndexOutOfBoundsException("foo.cpp", 0, +XMLExcepts::AttrList_BadIndex, getMemoryManager()); + return *(fArray[index]); +} + +/* Mistake in branch prediction caused us to split away real body of the function keeping + only throw () invokation. This is bad idea. */ +/* { dg-final { scan-tree-dump-not "Splitting function" "fnsplit"} } */ +/* { dg-final { cleanup-tree-dump "fnsplit" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr44914.C b/gcc/testsuite/g++.dg/tree-ssa/pr44914.C new file mode 100644 index 000000000..57ca7e83f --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr44914.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fipa-sra -fnon-call-exceptions" } */ + +struct A +{ + ~A () { } +}; + +struct B +{ + A a; + int i; + void f (int) { } + B () + { + f (i); + } +}; + +B b; diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr45453.C b/gcc/testsuite/g++.dg/tree-ssa/pr45453.C new file mode 100644 index 000000000..78c6460f7 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr45453.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +struct S +{ + S(); + virtual inline void foo () + { + foo(); + } +}; + +void +B () +{ + S().foo (); +} +/* We should inline foo and devirtualize call to foo in the inlined version. */ +// { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 1 "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr45605.C b/gcc/testsuite/g++.dg/tree-ssa/pr45605.C new file mode 100644 index 000000000..861b122e5 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr45605.C @@ -0,0 +1,37 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-ssa" } */ +extern "C" void abort(); +bool destructor_called = false; + +struct B { + virtual void Run(){}; +}; + +struct D : public B { + virtual void Run() + { + struct O { + ~O() { destructor_called = true; }; + } o; + + struct Raiser { + Raiser() throw( int ) {throw 1;}; + } raiser; + }; +}; + +int main() { + try { + D d; + static_cast<B&>(d).Run(); + } catch (...) {} + + if (!destructor_called) + abort (); +} + + + +/* We should devirtualize call to D::Run */ +/* { dg-final { scan-tree-dump-times "D::Run \\(" 1 "ssa" { xfail *-*-* } } } */ +/* { dg-final { cleanup-tree-dump "ssa" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr46228.C b/gcc/testsuite/g++.dg/tree-ssa/pr46228.C new file mode 100644 index 000000000..a720dbe3b --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr46228.C @@ -0,0 +1,23 @@ +// { dg-options "-fdump-tree-optimized -Os" } +#include <set> +#include <stdio.h> + +int main() +{ + static const int array[] = { 1,2,3,4,5,6,7,8,9,10,6 }; + std::set<int> the_set; + int count = 0; + for (unsigned i = 0; i < sizeof(array)/sizeof(*array); i++) + { + std::pair<std::set<int>::iterator, bool> result = + the_set.insert(array[i]); + if (result.second) + count++; + } + printf("%d unique items in array.\n", count); + return 0; +} + +// This function is small enough to be inlined even at -Os. +// { dg-final { scan-tree-dump-not "_ZNSt8_Rb_treeIiiSt9_IdentityIiESt4lessIiESaIiEED2Ev" "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr46734.C b/gcc/testsuite/g++.dg/tree-ssa/pr46734.C new file mode 100644 index 000000000..e95c62089 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr46734.C @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fipa-sra" } */ + +struct A +{ + int *p; + A() {p = (int *) -1;} + ~A() {if (p && p != (int *) -1) *p = 0;} +}; + +struct B +{ + A a; + char data[23]; + B() : a() {data[0] = 0;} +}; + +extern A ga; +extern int *gi; +extern void *gz; +extern B *gb; + +static int * __attribute__ ((noinline)) foo (B *b, void *z) +{ + __builtin_memcpy (gz, z, 28); + ga = b->a; + return b->a.p; +} + +int *bar (B *b, void *z) +{ + gb = b; + return foo (b, z); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr46987.C b/gcc/testsuite/g++.dg/tree-ssa/pr46987.C new file mode 100644 index 000000000..7163915a2 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr46987.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +struct A { + virtual A *getThis(); +}; + +struct B { + virtual B *getThis(); +}; + +struct AB : public A, public B { + virtual AB *getThis() { return 0; } +}; + +void foo () +{ + AB ab; + B *b = &ab; + b->getThis(); +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr47707.C b/gcc/testsuite/g++.dg/tree-ssa/pr47707.C new file mode 100644 index 000000000..98852de17 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr47707.C @@ -0,0 +1,29 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -fno-tree-vrp" } */ +#include <assert.h> + +struct CH +{ + unsigned char ch : 3; +} ch; + +__attribute__((noinline)) void MakeCheckOp (unsigned int *v1, unsigned int *v2) +{ + assert (*v1 == *v2); + +} + +int main (void) +{ + + int len; + + for (len = 4; len >= 1; len--) + { + unsigned v1, v2; + ch.ch = len; + v1 = ch.ch; + v2 = len; + MakeCheckOp (&v1, &v2); + } +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr49516.C b/gcc/testsuite/g++.dg/tree-ssa/pr49516.C new file mode 100644 index 000000000..2c6fd0496 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr49516.C @@ -0,0 +1,86 @@ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +extern "C" void abort (void); + +typedef int int32; +typedef unsigned int uint32; +typedef unsigned long long uint64; +typedef short int16; + +class Tp { + public: + Tp(int, const int segment, const int index) __attribute__((noinline)); + + inline bool operator==(const Tp& other) const; + inline bool operator!=(const Tp& other) const; + int GetType() const { return type_; } + int GetSegment() const { return segment_; } + int GetIndex() const { return index_; } + private: + inline static bool IsValidSegment(const int segment); + static const int kSegmentBits = 28; + static const int kTypeBits = 4; + static const int kMaxSegment = (1 << kSegmentBits) - 1; + + union { + + struct { + int32 index_; + uint32 segment_ : kSegmentBits; + uint32 type_ : kTypeBits; + }; + struct { + int32 dummy_; + uint32 type_and_segment_; + }; + uint64 value_; + }; +}; + +Tp::Tp(int t, const int segment, const int index) + : index_(index), segment_(segment), type_(t) {} + +inline bool Tp::operator==(const Tp& other) const { + return value_ == other.value_; +} +inline bool Tp::operator!=(const Tp& other) const { + return value_ != other.value_; +} + +class Range { + public: + inline Range(const Tp& position, const int count) __attribute__((always_inline)); + inline Tp GetBeginTokenPosition() const; + inline Tp GetEndTokenPosition() const; + private: + Tp position_; + int count_; + int16 begin_index_; + int16 end_index_; +}; + +inline Range::Range(const Tp& position, + const int count) + : position_(position), count_(count), begin_index_(0), end_index_(0) + { } + +inline Tp Range::GetBeginTokenPosition() const { + return position_; +} +inline Tp Range::GetEndTokenPosition() const { + return Tp(position_.GetType(), position_.GetSegment(), + position_.GetIndex() + count_); +} + +int main () +{ + Range range(Tp(0, 0, 3), 0); + if (!(range.GetBeginTokenPosition() == Tp(0, 0, 3))) + abort (); + + if (!(range.GetEndTokenPosition() == Tp(0, 0, 3))) + abort(); + + return 0; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr49911.C b/gcc/testsuite/g++.dg/tree-ssa/pr49911.C new file mode 100644 index 000000000..520a7750d --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr49911.C @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fstrict-enums -fno-rtti -fno-exceptions -fno-strict-aliasing -fdump-tree-vrp2" } */ + + +extern void JS_Assert(); +typedef enum { +eax, ecx, edx, ebx, esp, ebp, +esi, edi } +RegisterID; +union StateRemat { + RegisterID reg_; + int offset_; +}; +static StateRemat FromRegister(RegisterID reg) { + StateRemat sr; + sr.reg_ = reg; + return sr; +} +static StateRemat FromAddress3(int address) { + StateRemat sr; + sr.offset_ = address; + //sr.offset_ = 0; + if (address < 46 && address >= 0) { + JS_Assert(); + } + return sr; +} +struct FrameState { + StateRemat dataRematInfo2(bool y, int z) { + if (y) return FromRegister(RegisterID(1)); + return FromAddress3(z); + } +}; +FrameState frame; +StateRemat x; +void jsop_setelem(bool y, int z) { + x = frame.dataRematInfo2(y, z); +} + +/* { dg-final { scan-tree-dump-times "Folding predicate.*45" 0 "vrp2"} } */ +/* { dg-final { cleanup-tree-dump "vrp2" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr50622.C b/gcc/testsuite/g++.dg/tree-ssa/pr50622.C new file mode 100644 index 000000000..d7f4fa74b --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr50622.C @@ -0,0 +1,30 @@ +// { dg-do compile } +// { dg-options "-O2" } + +typedef __complex__ double Value; +struct LorentzVector +{ + LorentzVector & operator+=(const LorentzVector & a) { + theX += a.theX; + theY += a.theY; + theZ += a.theZ; + theT += a.theT; + return *this; + } + + Value theX; + Value theY; + Value theZ; + Value theT; +}; + +inline LorentzVector +operator+(LorentzVector a, const LorentzVector & b) { + return a += b; +} + +Value ex, et; +LorentzVector sum() { + LorentzVector v1; v1.theX =ex; v1.theY =ex+et; v1.theZ =ex-et; v1.theT =et; + return v1+v1; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr54515.C b/gcc/testsuite/g++.dg/tree-ssa/pr54515.C new file mode 100644 index 000000000..11ed46893 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr54515.C @@ -0,0 +1,19 @@ +// { dg-do compile } +// { dg-options "-O2" } + +template < typename T > T h2le (T) +{ + T a; + unsigned short &b = a; + short c = 0; + unsigned char (&d)[2] = reinterpret_cast < unsigned char (&)[2] > (c); + unsigned char (&e)[2] = reinterpret_cast < unsigned char (&)[2] > (b); + e[0] = d[0]; + return a; +} + +void +bar () +{ + h2le ((unsigned short) 0); +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr8781.C b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C new file mode 100644 index 000000000..a9d279af7 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr8781.C @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre-details" } */ + +int f(); + +template<typename predicate> +class noop_t { + const predicate &pred; +public: + explicit noop_t(const predicate &p) : pred(p) {} + + int operator()() const { return pred(); } +}; + +template<typename predicate> +inline noop_t<predicate> noop(const predicate pred) { + return noop_t<predicate>(pred); +} + +int x() +{ + return (noop(noop(noop(noop(noop(noop(noop(noop(noop(f)))))))))()); +} + +/* We should optimize this to a direct call. */ + +/* { dg-final { scan-tree-dump "Replacing call target with f" "fre" } } */ +/* { dg-final { cleanup-tree-dump "fre" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C b/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C new file mode 100644 index 000000000..c32ebba00 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +// { dg-options "-O2 -fdump-tree-optimized" } + + +struct f +{ + char m; + char m1; +}; + +static inline char f:: *g(int a) +{ + return a?0:&f::m; +} + +int h(void) +{ + char f:: *a = g(0); + return a == 0; +} + +/* We should have no cast to offset_type. */ +/* { dg-final { scan-tree-dump-times "offset_type" 0 "optimized"} } */ +// And we should optimized this code to just return 0 +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ + diff --git a/gcc/testsuite/g++.dg/tree-ssa/restrict1.C b/gcc/testsuite/g++.dg/tree-ssa/restrict1.C new file mode 100644 index 000000000..dc120b1e8 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/restrict1.C @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-lim-details" } */ + +struct Foo +{ + Foo(); + Foo(const Foo&); + int n; + int * __restrict__ p; +}; +void bar(Foo f, int * __restrict__ q) +{ + for (int i = 0; i < f.n; ++i) + { + *q += f.p[i]; + } +} + +/* { dg-final { scan-tree-dump "Executing store motion" "lim1" } } */ +/* { dg-final { cleanup-tree-dump "lim1" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/sra-1.C b/gcc/testsuite/g++.dg/tree-ssa/sra-1.C new file mode 100644 index 000000000..e3e3918eb --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/sra-1.C @@ -0,0 +1,29 @@ +/* https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=223576 */ + +/* SRA failed to canonicalize bit-field types, introducing type + mismatches. */ + +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct A +{ + int a:16; + /* These dummy bit-fields are here to prevent GCC 4.2+ from merging + the bit-field compares into a single word compare, which disables + SRA. */ + int a2:16; + int a3:16; + int a4:16; + int b:8; + bool operator==(A const x) const + { + return (this->a == x.a && this->b == x.b); + } +}; + +bool +foo (A const x, A const y) +{ + return x == y; +} diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-cast-1.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-cast-1.C new file mode 100644 index 000000000..4e953220f --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-cast-1.C @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +int &f(int *a) +{ + return *a; +} + +/* There should be no cast as pointer and references are + considered the same type. */ +/* { dg-final { scan-tree-dump-times "\\(int &\\)" 0 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-1.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-1.C new file mode 100644 index 000000000..b2d5f4b05 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-1.C @@ -0,0 +1,61 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +void link_error(); + + +struct State { + int p0, p1, p2; + inline State(){p0=0;p1=0;p2=0;} + inline State(const State &s) { + p0 = s.p0; + p1 = s.p1; + p2 = s.p2; + } + + inline void operator =(const State &s) { + p0 = s.p0; + p1 = s.p1; + p2 = s.p2; + } + + inline void step(void) { + p0 = p1+p2; + p1 = p0*p1+p2; + p2 = p0-p2; + } +}; + + +inline void iterate_ok(State &inS1, State &inS2, unsigned int n) +{ + State s1 = inS1; + for (unsigned int i = 0; i < n; i++) { + s1.step(); + } + inS1 = s1; +} + +void temp() +{ + State s1; + s1.p0 = 0; + s1.p1 = 0; + s1.p2 = 0; + State s2; + s2.p0 = 0; + s2.p1 = 0; + s2.p2 = 0; + iterate_ok (s1, s2, 1); + if (s1.p0) + link_error(); + if (s1.p0) + link_error(); + if (s1.p0) + link_error(); +} + +/* We should have removed the casts from pointers to references and caused SRA to happen. */ + +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-2.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-2.C new file mode 100644 index 000000000..d73787018 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-2.C @@ -0,0 +1,52 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +void link_error(); + +struct OOf { + int value; + OOf() {value = 0;} +}; +inline OOf operator+(OOf op1, OOf op2) +{ + OOf f; + f.value = op1.value + op2.value; + return f; +} +inline OOf operator*(OOf op1, OOf op2) +{ + OOf f; + f.value = op1.value * op2.value; + return f; +} +inline OOf operator-(OOf op1, OOf op2) +{ + OOf f; + f.value = op1.value - op2.value; + return f; +} +inline OOf test_func( + OOf a, + OOf b, + OOf c +) +{ + OOf d, e; + OOf result; + d = a * b + b * c; + e = a * c - b * d; + result = d * e; + return result; +} + +void test() +{ + OOf a, b, c; + OOf d = test_func (a,b,c); + if (d.value) + link_error(); +} + +/* We should have removed the casts from pointers to references and caused SRA to happen. */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-3.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-3.C new file mode 100644 index 000000000..2a2d89c63 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-sra-3.C @@ -0,0 +1,83 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* Test check use_block_copy bit propagation in sra element hierarchy. */ + +typedef unsigned char UINT8 ; +typedef unsigned int UINT ; +class C4 +{ +public: + int xy[2]; +}; + +class C3 +{ +public: + inline void + Reset() + { + C4 const mvMax = {0x7fff, 0x7fff}; + + m42(0,mvMax); + m42(1,mvMax); + m43(0); + }; + + inline void m42 (UINT i, C4 mv) + { + mMv[i] = mv; + }; + + + + inline void m43(UINT j) + { + m44 (j); + d41 = j + 1; + }; + +private: + + C4 mMv[2]; + UINT8 d41; + inline void m44 (UINT j) const {}; +}; + +class C2 +{ +private: + bool valid; +}; + +class C1 +{ +public: + void m1(C3 *c); + +private: + const C2 * d1[2]; + void m2(C3 *m); +}; + +void C1::m1 (C3 *r) +{ + C3 x; + m2(&x); +} +void C1::m2(C3 *x) +{ + C3 m3; + int i; + m3.Reset (); + for(i=0; i<2; i++) + { + const C2 * r = d1[i]; + if (r!=__null) + { + C4 const c400 = {0,0}; + m3.m42 (i, c400); + + } + } +} + diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-store-ccp-1.C b/gcc/testsuite/g++.dg/tree-ssa/ssa-store-ccp-1.C new file mode 100644 index 000000000..06e9b1e35 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-store-ccp-1.C @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +class bar +{ +public: + static const int conststaticvariable; +}; + + +int f(void) +{ + return bar::conststaticvariable; +} + +/* There should be a reference to conststaticvariable since it may + be overriden at link time. */ +/* { dg-final { scan-tree-dump-times "conststaticvariable" 1 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C new file mode 100644 index 000000000..808b5ab27 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options { -O -fdump-tree-optimized } } */ + +int a[4][8]; + +int foo(long i) +{ + return *(&a[0][0] + i*8); // a[i][0] +} + +struct Foo { double x, y; }; + +Foo b[4]; + +double bar(long i) +{ + return *(&b[0].x + i*2); // b[i].x +} + +/* { dg-final { scan-tree-dump "a\\\[.*i.*\\\]\\\[0\\\]" "optimized" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump "b\\\[.*i.*\\\].x" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/tmmti.C b/gcc/testsuite/g++.dg/tree-ssa/tmmti.C new file mode 100644 index 000000000..111127b0d --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/tmmti.C @@ -0,0 +1,7 @@ +/* { dg-do compile } */ + +void bar(unsigned int i) +{ + int a[4]; + char *p = (char*)&a[1] + 4*i; +} |