[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-02-13 Thread jamborm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #14 from Martin Jambor  ---
Author: jamborm
Date: Tue Feb 13 12:25:36 2018
New Revision: 257623

URL: https://gcc.gnu.org/viewcvs?rev=257623=gcc=rev
Log:
[PR 83990] Fix location handling in ipa_modify_call_arguments

2018-02-13  Martin Jambor  

PR c++/83990
* ipa-param-manipulation.c (ipa_modify_call_arguments): Use location
of call statements, also set location of a load to a temporary.


Modified:
trunk/gcc/ChangeLog
trunk/gcc/ipa-param-manipulation.c

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-26 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #13 from Jakub Jelinek  ---
Comment on attachment 43254
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43254
Lost location fix

As use use it multiple time, perhaps do location_t loc = gimple_location
(stmt);
early and use loc afterwards?
Otherwise LGTM.

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-26 Thread jamborm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #12 from Martin Jambor  ---
Created attachment 43254
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43254=edit
Lost location fix

I'm testing this patch which does what Jakub suggested in comment #4.  With the
patch, -fno-ipa-sra has no effect on either the original testcase or the
reduced one from comment 10.

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-25 Thread jamborm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #11 from Martin Jambor  ---
I was indeed looking at the testcase from comment #4, sorry.  I will look at
the new ones (and check with the original one).

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-25 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #10 from Jakub Jelinek  ---
namespace b {
typedef long unsigned c;
}
void *operator new(b::c, void *) noexcept;
namespace b {
template < typename d > d *e(d &) noexcept;
template < typename d, d f > struct g { static constexpr d h = f; };
typedef g< bool, false > i;
template < bool, typename, typename > struct aa;
template < typename... > struct j;
template < typename k, typename l > struct j< k, l > : aa< 1, k, l > {};
template < typename... > struct ab;
template < typename k, typename l > struct ab< k, l > : aa< k::h, l, k >::ac
{};
template < typename ad > struct m : g< bool, !ad::h > {};
struct ae : i {};
template < typename d > struct n : j< ae, d >::ac {};
struct t {
  template < typename > static g< bool, true > ag(int);
};
template < typename d > struct ah : t { typedef decltype(ag< d >(0)) ac; };
struct aj : ah< int >::ac {};
struct u {
  template < typename, typename > static g< bool, true > ag(int);
};
template < typename d, typename o > struct w : u {
  typedef decltype(ag< d, o >(0)) ac;
};
template < typename o > struct p : ab< aj, w< int, o > > {};
template < typename d, typename > struct q : aa< n< d >::h, int, p< int > > {};
template < typename o > struct r : q< int, o >::ac {};
template < typename... > struct ak;
template < typename d, typename o > struct ak< d, o > : r< o > {};
template < typename, typename... al > struct am : ak< int, al... >::ac {};
template < typename d > struct ao : g< bool, noexcept(d()) > {};
template < typename, typename... al >
struct ap : ab< am< int, al... >, ao< al... > > {};
template < typename d > struct aq : ap< d, d > {};
template < typename d > struct ar : aq< d > {};
template < bool, typename at, typename > struct aa { typedef at ac; };
template < typename at, typename au > struct aa< false, at, au > {
  typedef au ac;
};
template < typename av > struct aw { using ac = av; };
template < typename av, template < typename > class > using ay = aw< av >;
template < typename av, template < typename > class ax >
using az = typename ay< av, ax >::ac;
template < typename d > d ba(d ) { return static_cast< d && >(bb); }
template < typename d > d bc(d);
struct bd : ab< m< ar< int > >, int > {};
template < typename > struct be;
template < typename d > struct be< d * > { typedef d bg; };
template < typename bi > class bj {
  bi bk;

public:
  typedef typename be< bi >::bg &
  bj(bi) : bk() {}
  bg operator*() { return bg(*bk); }
  void operator++() { ++bk; }
};
template < typename bi, typename bo = typename aa< bd::h, bi, bj< bi > >::ac >
bo __make_move_if_noexcept_iterator(bi bp) {
  return bp;
}
template < typename d > class allocator {
  long bq;
  typedef d bf;
  template < typename > struct br { typedef allocator bs; };
};
struct bt {
  template < typename d > struct bu {
using ac = typename d::template br< int >::bs;
  };
  template < typename d > using bv = typename d::bw;
};
template < typename bx, typename > using by = typename bt::bu< bx >::ac;
template < typename bx > struct bz : bt {
  using bw = az< typename bx::bf *, bv >;
  template < typename d > using ca = by< bx, d >;
};
}
template < typename bx > struct cb : b::bz< bx > {
  template < typename > struct br {
typedef typename b::bz< bx >::template ca< int > bs;
  };
};
namespace b {
template < typename > class Trans_NS_d_cc {
public:
  typedef long bq;
  struct cg : cb< allocator< char > >::br< int >::bs {
cg(cb< br< int >::bs >::bw, allocator);
cb< br< int >::bs >::bw ch;
  } ci;
  void ck(bq);
  cb< cb< allocator< char > >::br< int >::bs >::bw cj() { return ci.ch; }
  cb< cb< allocator< char > >::br< int >::bs >::bw cl();
  bool cm() { return cj(); }
  cb< allocator< char > >::br< int >::bs cn();
  Trans_NS_d_cc(Trans_NS_d_cc &) noexcept : ci(cl(), bc(cn())) {
if (co.cm())
  ck(length());
  }
  bq length();
};
template < typename cp, typename... al > void cq(cp *cr, al &&... cs) {
  new (cr) cp(ba(cs)...);
}
struct ct {
  template < typename cu, typename cv > static cv cw(cu cx, cv) {
cv cy;
try {
  for (;; ++cx)
cq(e(*cy), *cx);
} catch (...) {
}
return cy;
  }
};
template < typename cu, typename cv > void cz(cu cx, cv db) { ct::cw(cx, db); }
template < typename cu, typename cv, typename d >
void dc(cu cx, cu , cv db, d) {
  cz(cx, db);
}
template < typename > struct dd {
  typedef allocator< Trans_NS_d_cc< char > > de;
  typedef cb< de >::bw bw;
  struct {
bw df;
bw dg;
  } di;
};
template < typename > class dj : dd< allocator< char > > {
public:
  void dl();
  template < typename cv > void dm(c, cv cx, cv da) {
bw db;
try {
  dc(cx, da, db, 0);
} catch (...) {
}
  }
};
c dl_dn;
template < typename d > void dj< d >::dl() {
  dm(dl_dn, __make_move_if_noexcept_iterator(di.df),
 __make_move_if_noexcept_iterator(di.dg));
}
}
void a() {
  b::dj< int > s;
  s.dl();
}

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-25 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #9 from Jakub Jelinek  ---
Another reduced testcase.  This one shows the warning with both -O3
-Wnull-dereference -std=c++17 {,-fno-ipa-sra}, but with the former without
location, with the latter with a location.

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-25 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #8 from Jakub Jelinek  ---
(In reply to Martin Jambor from comment #7)
> (In reply to Jakub Jelinek from comment #4)
> >
> > ...
> > 
> > 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.
> 
> Interesting, I see base being an ADDR_EXPR on trunk.  But anyway...

Are you looking at the #c0 testcase or the reduced one?  The reduced one only
shows the -Wnull-dereference warning, with correct location.
Only the original one has the UNKNOWN_LOCATION on the statement on which the
warning is emitted.

> That might indeed make more sense, I will look into it.
> 
> But please note that I get exactly the same warning when I add
> -fno-ipa-sra on the command line (and I have verified in gdb that
> ipa_modify_call_arguments is not invoked at all with the option just
> to double check) so ipa_modify_call_arguments cannot be the whole
> story.

-fno-ipa-sra makes the warning go away altogether for me on the trunk on the
original testcase:
./cc1plus -quiet -std=c++17 -O3 -Wnull-dereference pr83990.ii; echo ===; \
./cc1plus -quiet -std=c++17 -O3 -Wnull-dereference pr83990.ii -fno-ipa-sra; \
echo ===
In function ‘void std::vector<_Tp, _Alloc>::reserve(std::vector<_Tp,
_Alloc>::size_type) [with _Tp = std::__cxx11::basic_string; _Alloc =
std::allocator]’:
cc1plus: warning: potential null pointer dereference [-Wnull-dereference]
===
===

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-25 Thread jamborm at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #7 from Martin Jambor  ---
(In reply to Jakub Jelinek from comment #4)
>
> ...
> 
> 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.

Interesting, I see base being an ADDR_EXPR on trunk.  But anyway...

> 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 (, 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)

That might indeed make more sense, I will look into it.

But please note that I get exactly the same warning when I add
-fno-ipa-sra on the command line (and I have verified in gdb that
ipa_modify_call_arguments is not invoked at all with the option just
to double check) so ipa_modify_call_arguments cannot be the whole
story.

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|7.3 |7.4

--- Comment #6 from Richard Biener  ---
GCC 7.3 is being released, adjusting target milestone.

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-24 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

Jeffrey A. Law  changed:

   What|Removed |Added

 Status|UNCONFIRMED |NEW
   Last reconfirmed||2018-01-24
 CC||law at redhat dot com
 Ever confirmed|0   |1

--- Comment #5 from Jeffrey A. Law  ---
In the reduced testcase we have:

;;   basic block 3, loop depth 1, count 10737436510031 (estimated locally),
maybe hot
;;prev block 2, next block 4, flags: (NEW, REACHABLE, VISITED)
;;pred:   2 [always]  count:1073741826 (estimated locally)
(FALLTHRU,EXECUTABLE)
;;5 [always]  count:10737436510031 (estimated locally)
(FALLTHRU,DFS_BACK,EXECUTABLE)
  # da_6 = PHI <0B(2), _7(5)>
  _5 = operator new (8, db_4(D));
  MEM[(struct  &)_5] ={v} {CLOBBER};
  _8 = [(struct e *)_5].cm;
  a::d::e::cq (_5);
  _9 = a::d::e::co (_5);
  a::d::e::cl::cl (_8, _9, D.3228);
  cp_10 = da_6->cm.r;
  if (cp_10 != 0B)
goto ; [53.47%]
  else
goto ; [46.53%]

THe warning seems warranted to me.  The location as has been pointed out in
other comments is totally bogus.


Similarly for the full testcase:

;;   basic block 4, loop depth 1
;;pred:   3
;;7
  # __first$_M_current_2 = PHI <0B(3), _47(7)>
  # __cur_38 = PHI <_50(3), __cur_48(7)>
  MEM[(struct  &)__cur_38] ={v} {CLOBBER};
  _41 = &__cur_38->D.22571._M_local_buf;
  MEM[(struct  &)__cur_38] ={v} {CLOBBER};
  MEM[(struct _Alloc_hider *)__cur_38]._M_p = _41;
  _42 = MEM[(const struct basic_string *)__first$_M_current_2];
  _43 = [(const struct basic_string
*)__first$_M_current_2].D.22571._M_local_buf;
  if (_42 == _43)
goto ; [30.00%]
  else
goto ; [70.00%]
;;succ:   5
;;6

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-24 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

Jakub Jelinek  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  ---
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 ) { 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 &
  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 &) 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 < 

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-24 Thread TonyELewis at hotmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

--- Comment #3 from Tony E Lewis  ---
Just to be clear...

I don't think it's _necessarily_ a problem that the warning is being triggered
in this particular context (because I'm not in a position to judge that). The
core problem I wish to highlight is that, despite being triggered within a
system header, the warning isn't being silenced as I would expect. And my
suspicion is that this is caused by the source location info having been lost
so the location cannot be recognised as within a system header (as has been
hypothesised for bug 83591).

(I also wish to highlight that the lack of source location info makes the
warning very much harder to respond to.)

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-24 Thread jakub at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek  ---
I think this started with r246301.
This warning s an optimization warning and as the wording says, can have false
positives, the optimizer during path isolation simply finds a basic block
containing a pointer dereference where the pointer is known to be NULL on some
predecessor edge to the BB.
  basic_string(basic_string&& __str) noexcept
  : _M_dataplus(_M_local_data(), std::move(__str._M_get_allocator()))
  {
if (__str._M_is_local())
  {
traits_type::copy(_M_local_buf, __str._M_local_buf,
  _S_local_capacity + 1);
  }
and
  template
static _ForwardIterator
__uninit_copy(_InputIterator __first, _InputIterator __last,
  _ForwardIterator __result)
{
  _ForwardIterator __cur = __result;
  __try
{
  for (; __first != __last; ++__first, (void)++__cur)
std::_Construct(std::__addressof(*__cur), *__first);
  return __cur;
}
are the relevant snippets, the __first != __last guard is what guards the basic
block and the optimizers see some possibility that __first could be NULL in
some case.

[Bug c++/83990] [7/8 Regression] Spurious "potential null pointer dereference" warning regression from 7.1 onwards

2018-01-24 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83990

Richard Biener  changed:

   What|Removed |Added

   Keywords||diagnostic
  Known to work||6.4.0
   Target Milestone|--- |7.3
Summary|Spurious "potential null|[7/8 Regression] Spurious
   |pointer dereference"|"potential null pointer
   |warning regression from 7.1 |dereference" warning
   |onwards |regression from 7.1 onwards