https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jamborm at gcc dot gnu.org, | |marxin at gcc dot gnu.org, | |redi at gcc dot gnu.org --- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> --- creduced testcase: namespace a { typedef long unsigned c; } void *operator new(a::c, void *) noexcept; template < typename f, f g > struct aa { static constexpr f h = g; }; typedef aa< bool, false > i; template < bool, typename, typename > struct ab; template < typename... > struct j; template < typename k, typename ac > struct j< k, ac > : ab< 1, k, ac > {}; template < typename... > struct ad; template < typename k, typename ac > struct ad< k, ac > : ab< k::h, ac, k >::ae {}; template < typename l > struct af : aa< bool, !l::h > {}; struct m : i {}; template < typename f > struct n : j< m, f >::ae {}; struct ah { template < typename > static aa< bool, true > ai(int); }; template < typename f > struct aj : ah { typedef decltype(ai< f >(0)) ae; }; struct u : aj< int >::ae {}; struct v { template < typename, typename > static aa< bool, true > ai(int); }; template < typename f, typename o > struct x : v { typedef decltype(ai< f, o >(0)) ae; }; template < typename o > struct p : ad< u, x< int, o > > {}; template < typename f, typename > struct q : ab< n< f >::h, int, p< int > > {}; template < typename o > struct al : q< int, o >::ae {}; template < typename... > struct am; template < typename f, typename o > struct am< f, o > : al< o > {}; template < typename, typename... an > struct ao : am< int, an... >::ae {}; struct aq : aa< bool, noexcept(int()) > {}; template < typename, typename... an > struct ar : ad< ao< int, an... >, aq > {}; template < typename f > struct as : ar< f, f > {}; template < typename f > struct at : as< f > {}; template < bool, typename av, typename > struct ab { typedef av ae; }; template < typename av, typename aw > struct ab< false, av, aw > { typedef aw ae; }; template < typename ax > struct ay { using ae = ax; }; template < typename ax, template < typename > class > using ba = ay< ax >; template < typename ax, template < typename > class az > using bb = typename ba< ax, az >::ae; template < typename f > f bc(f &bd) { return static_cast< f && >(bd); } struct bf : ad< af< at< int > >, int > {}; template < typename > struct bg; template < typename f > struct bg< f * > { typedef f bi; }; template < typename bk > class bl { bk bm; public: typedef typename bg< bk >::bi &&bi; bl(bk) : bm() {} bi operator*() { return bi(*bm); } void operator++() { ++bm; } }; template < typename bk, typename bp = typename ab< bf::h, bk, bl< bk > >::ae > bp bq(bk br) { return br; } namespace bs { struct bt { static char bv(char *, char *, long); }; } namespace a { struct bt : bs::bt {}; template < typename f > class allocator { public: typedef f bh; template < typename > struct bw { typedef allocator bx; }; }; struct by { template < typename f > struct bz { using ae = typename f::template bw< int >::bx; }; template < typename f > using ca = typename f::b; }; template < typename cc, typename > using cd = typename by::bz< cc >::ae; template < typename cc > struct ce : by { using cb = bb< typename cc::bh *, ca >; template < typename f > using cf = cd< cc, f >; }; } namespace bs { template < typename cc > struct cg : a::ce< cc > { template < typename > struct bw { typedef typename a::ce< cc >::template cf< int > bx; }; }; } namespace a { namespace d { class e { public: typedef bt cj; struct cl { cl(bs::cg< bs::cg< allocator< char > >::bw< char >::bx >::cb, allocator< char >); bs::cg< bs::cg< allocator< char > >::bw< char >::bx >::cb r; } cm; char cn[]; bs::cg< bs::cg< allocator< char > >::bw< char >::bx >::cb co(); bool t() { bs::cg< bs::cg< allocator< char > >::bw< char >::bx >::cb cp = cm.r; return cp; } bs::cg< allocator< char > >::bw< char >::bx cq(); e(e &&cr) noexcept : cm(co(), cq()) { if (cr.t()) cj::bv(cn, cn, 1); } }; } template < typename cs, typename... an > void ct(cs *cu, an &&... cv) { new (cu) cs(bc(cv)...); } struct cw { template < typename cx, typename cy > static cy cz(cx da, cy) { cy db; try { for (;; ++da) ct(db, *da); } catch (...) { } return db; } }; template < typename cx, typename cy > void dc(cx da, cx, cy de) { cw::cz(da, de); } template < typename cx, typename cy, typename f > void __uninitialized_copy_a(cx da, cx dd, cy de, f) { dc(da, dd, de); } template < typename > struct df { typedef allocator< d::e > dg; typedef bs::cg< dg >::cb cb; struct { cb di; cb dj; } dl; }; template < typename > class dm : df< allocator< d::e > > { public: void reserve(); template < typename cy > void _M_allocate_and_copy(long, cy da, cy dd) { cb de; try { __uninitialized_copy_a(da, dd, de, 0); } catch (...) { } } }; template < typename f > void dm< f >::reserve() { _M_allocate_and_copy(0, bq(dl.di), bq(dl.dj)); } } void b() { a::dm< int > s; s.reserve(); } The statement on which on the original testcase it warns indeed has no location, that was created during IPA optimizations: ipa_modify_call_arguments does: loc = DECL_P (base) ? DECL_SOURCE_LOCATION (base) : EXPR_LOCATION (base); This itself is weird in this case, base is a SSA_NAME this_4(D), so has no location and loc is UNKNOWN_LOCATION. Then we: /* If expr is not a valid gimple call argument emit a load into a temporary. */ if (is_gimple_reg_type (TREE_TYPE (expr))) { gimple *tem = gimple_build_assign (NULL_TREE, expr); if (gimple_in_ssa_p (cfun)) { gimple_set_vuse (tem, gimple_vuse (stmt)); expr = make_ssa_name (TREE_TYPE (expr), tem); } else expr = create_tmp_reg (TREE_TYPE (expr)); gimple_assign_set_lhs (tem, expr); gsi_insert_before (&gsi, tem, GSI_SAME_STMT); and don't gimple_set_location for it at all. Wonder if loc shouldn't be set to e.g. gimple_location (stmt) which would be the last line of these 3: bool _M_is_local() const { return _M_data() == _M_local_data(); } Martin?