From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24011 invoked by alias); 9 Apr 2015 18:28:26 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 23983 invoked by uid 89); 9 Apr 2015 18:28:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.4 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 09 Apr 2015 18:28:24 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t39ISMTX029416 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Thu, 9 Apr 2015 14:28:22 -0400 Received: from redhat.com (ovpn-204-30.brq.redhat.com [10.40.204.30]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t39ISIVb017055 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Thu, 9 Apr 2015 14:28:21 -0400 Date: Thu, 09 Apr 2015 18:28:00 -0000 From: Marek Polacek To: GCC Patches Subject: [PATCH] Fix ctor reference folding (PR middle-end/65554) Message-ID: <20150409182817.GD9798@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-SW-Source: 2015-04/txt/msg00407.txt.bz2 This test was failing at -O due to non-trivial conversion at assignment. The reason is that gimple_fold_builtin_memory_op created invalid GIMPLE, because fold_ctor_reference called via fold_const_aggregate_ref was discarding a cast, so it returned a different type than it got. Fixed by dropping useless type conversions only. It also fixes a stale comment that I noticed. Bootstrapped/regtested on x86_64-linux. Preapproved by Jakub on IRC, applying to trunk. 2015-04-09 Marek Polacek Jakub Jelinek PR middle-end/65554 * gimple-fold.c (gimple_fold_builtin_memory_op): Update comment. (fold_ctor_reference): Use STRIP_USELESS_TYPE_CONVERSION instead of STRIP_NOPS. * g++.dg/opt/pr65554.C: New test. diff --git gcc/gimple-fold.c gcc/gimple-fold.c index f89220c..9458f96 100644 --- gcc/gimple-fold.c +++ gcc/gimple-fold.c @@ -769,7 +769,7 @@ var_decl_component_p (tree var) } /* Fold function call to builtin mem{{,p}cpy,move}. Return - NULL_TREE if no simplification can be made. + false if no simplification can be made. If ENDP is 0, return DEST (like memcpy). If ENDP is 1, return DEST+LEN (like mempcpy). If ENDP is 2, return DEST+LEN-1 (like stpcpy). @@ -5472,7 +5472,7 @@ fold_ctor_reference (tree type, tree ctor, unsigned HOST_WIDE_INT offset, ret = canonicalize_constructor_val (unshare_expr (ctor), from_decl); ret = fold_unary (VIEW_CONVERT_EXPR, type, ret); if (ret) - STRIP_NOPS (ret); + STRIP_USELESS_TYPE_CONVERSION (ret); return ret; } /* For constants and byte-aligned/sized reads try to go through diff --git gcc/testsuite/g++.dg/opt/pr65554.C gcc/testsuite/g++.dg/opt/pr65554.C index e69de29..70e43a4 100644 --- gcc/testsuite/g++.dg/opt/pr65554.C +++ gcc/testsuite/g++.dg/opt/pr65554.C @@ -0,0 +1,124 @@ +// PR middle-end/65554 +// { dg-do compile { target c++11 } } +// { dg-options "-O" } + +namespace std +{ + struct B { enum { __value }; }; + template struct C + { + static _Iterator _S_base (_Iterator p1) { return p1; } + }; + template using _RequireInputIter = int; + template _Iterator __niter_base (_Iterator p1) + { + return std::C <_Iterator>::_S_base (p1); + } + template _Iterator __miter_base (_Iterator p1) + { + return std::C <_Iterator>::_S_base (p1); + } + struct D + { + template static _Tp *__copy_m (_Tp * p1, _Tp * p2, _Tp *) + { + int _Num = p2 - p1; + __builtin_memmove (0, p1, sizeof (_Tp) * _Num); + } + }; + template void __copy_move_a (_II p1, _II p2, _OI p3) + { + D::__copy_m (p1, p2, p3); + } + template void __copy_move_a2 (_II p1, _II p2, _OI p3) + { + __copy_move_a <0> (std::__niter_base (p1), std::__niter_base (p2), std::__niter_base (p3)); + } + template void copy (_II p1, _II p2, _OI p3) + { + __copy_move_a2 (std::__miter_base (p1), std::__miter_base (p2), p3); + } +} +template struct F { typedef _Tp *pointer; }; +namespace std +{ + template using __allocator_base = F <_Tp>; + template struct allocator:__allocator_base <_Tp> {}; + template struct initializer_list + { + typedef _E *const_iterator; + _E *_M_array; + unsigned long _M_len; + const_iterator begin () { return _M_array; } + const_iterator end () { return begin () + 1; } + }; + template struct allocator_traits + { + template static typename _Tp::pointer _S_pointer_helper (_Tp *); + typedef decltype (_S_pointer_helper ((_Alloc *) 0)) __pointer; + typedef __pointer pointer; + }; +} +template struct __alloc_traits: +std::allocator_traits > {}; +namespace std +{ + struct G + { + template static _ForwardIterator __uninit_copy (_InputIterator p1, _InputIterator p2, _ForwardIterator p3) + { + copy (p1, p2, p3); + } + }; + template void + uninitialized_copy (_InputIterator p1, _InputIterator p2, _ForwardIterator p3) + { + G::__uninit_copy (p1, p2, p3); + } + template void __uninitialized_copy_a (_InputIterator p1, _InputIterator p2, _ForwardIterator p3, allocator <_Tp> &) + { + uninitialized_copy (p1, p2, p3); + } + struct H + { + typedef std::allocator _Tp_alloc_type; + typedef __alloc_traits <_Tp_alloc_type>::pointer pointer; + _Tp_alloc_type & _M_get_Tp_allocator (); + }; + template > struct J: H + { + void operator= (initializer_list <_Tp> p1) + { + this->assign (p1.begin (), p1.end ()); + } + template > void assign (_InputIterator p1, _InputIterator p2) + { + _M_assign_dispatch (p1, p2, 0); + } + pointer _M_allocate_and_copy___result; + template void _M_allocate_and_copy (int, _ForwardIterator p2, _ForwardIterator p3) + { + __uninitialized_copy_a (p2, p3, _M_allocate_and_copy___result, _M_get_Tp_allocator ()); + } + template void _M_assign_dispatch (_InputIterator p1, _InputIterator p2, int) + { + _M_assign_aux (p1, p2, 0); + } + template void _M_assign_aux (_ForwardIterator, _ForwardIterator, int); + }; + template + template void J <_Tp, _Alloc>::_M_assign_aux (_ForwardIterator p1, _ForwardIterator p2, int) + { + _M_allocate_and_copy (0, p1, p2); + } + class I + { + void tabCompletion (std::J &) const; + }; + void + I::tabCompletion (J &) const + { + J extra; + extra = { "foo" }; + } +} Marek