[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards
jakub at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Wed Jan 24 17:56:00 GMT 2018
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?
More information about the Gcc-bugs
mailing list