Bug 84802 - [8 Regression] ICE in gimplify_decl_expr since r251433
Summary: [8 Regression] ICE in gimplify_decl_expr since r251433
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.0
: P1 normal
Target Milestone: 8.0
Assignee: Jason Merrill
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-03-10 08:48 UTC by Jakub Jelinek
Modified: 2018-03-12 14:36 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2018-03-10 00:00:00


Attachments
pr84802.C (2.10 KB, text/plain)
2018-03-10 08:55 UTC, Jakub Jelinek
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2018-03-10 08:48:54 UTC
The following testcase ICEs with -std=c++17 starting with r251433:
rh1553747.ii: In lambda function:
rh1553747.ii:176:55: internal compiler error: Segmentation fault
   auto en() { return ek<dc>([](const auto &eh) { auto eo = [eh] {}; return eo; }); }
                                                       ^~
0x117d273 crash_signal
	../../gcc/toplev.c:341
0xe0a924 gimplify_decl_expr
	../../gcc/gimplify.c:1644
0xe34287 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	../../gcc/gimplify.c:11526
0xe1c327 gimplify_stmt(tree_node**, gimple**)
	../../gcc/gimplify.c:6546
0xe0adb2 gimplify_statement_list
	../../gcc/gimplify.c:1734
Apparently it ICEs on a DEC_EXPR for VOIDmode variable that has not been laid out and has DECL_VALUE_EXPR.

namespace a {
typedef decltype(nullptr) b;
template <typename c, c d> struct n { static constexpr c e = d; };
typedef n<bool, true> f;
typedef n<bool, false> g;
template <bool d> using h = n<bool, d>;
template <bool d> using i = n<bool, d>;
template <typename> struct aa;
template <typename...> struct j;
template <typename k, typename l> struct j<k, l> : aa<l>::m {};
struct o : h<!bool()> {};
template <typename c, typename p = c> p ab(int);
template <typename c> auto ac() -> decltype(ab<c>(0));
template <typename c, typename... ad>
struct ae : h<__is_constructible(c, ad...)> {};
template <typename c, typename p> struct q : h<__is_assignable(c, p)> {};
template <typename, typename> struct r : g {};
template <typename s> struct t {
  template <typename> static f z(int);
  typedef decltype(z<s>(0)) m;
};
template <typename, typename> struct af : t<int>::m {};
template <bool, typename = void> struct ag;
template <typename c> struct ag<true, c> { typedef c m; };
template <typename ah> struct aa { typedef ah m; };
template <typename c> using aj = c;
template <bool ai> using ak = typename ag<ai>::m;
template <bool, typename al, typename> using am = al;
template <typename c, typename... ad> constexpr bool an = ae<c, ad...>::e;
template <typename c, typename p> constexpr bool ao = r<c, p>::e;
template <typename w, typename s> constexpr bool ap = af<w, s>::e;
template <typename> void aq();
template <typename c> c ar(c);
struct as { template <typename p> using at = p *; };
int au;
template <typename av> struct aw {
  template <typename c, typename... ad> static o ax(c *, ad... ay) { c(ay...); return o(); }
  template <typename c, typename... ad> static auto az(av, c ba, ad... ay) { ax(ba, ay...); }
};
}
template <typename av> struct u : a::aw<av> { typedef av bb; };
class bc;
class bd {};
namespace a {
template <typename> class be;
template <typename bf> struct bg {
  static bf *bh(int) { return nullptr; }
};
template <typename, typename> class bi;
template <typename bj, typename bf, typename... bk>
struct bi<bj(bk...), bf> : bg<bf> {
  static bj bl(const int &bm, bk...) { (*bg<bf>::bh(bm))(aq<bk>...); return bj (); }
};
template <typename w, typename s> using bn = j<r<w, s>, af<w, s>>;
template <typename bj, typename... bk> struct be<bj(bk...)> {
  struct bo : bn<int, b> {};
  template <typename ai, typename> using bq = typename ag<ai::e>::m;
  template <typename bf, typename = bq<o, void>, typename = bq<bo, void>>
  be(bf);
  using bp = bj (*)(const int &, bk...);
  bp bs;
};
template <typename bj, typename... bk>
template <typename bf, typename, typename>
be<bj(bk...)>::be(bf) {
  bs = bi<bj(bk...), bf>::bl;
}
}
struct br { br(bd *); };
class bu : public bd {};
namespace a {
template <typename c> struct bt {
  template <typename p> using bw = as::at<p>;
  bw<c> v;
};
template <typename c> class bv {
protected:
  typedef u<c> by;
  typedef u<by> bx;
  struct : by {
    bt<c> ca;
  } bz;
};
template <typename c, typename = c> struct cc : bv<c> {
  typedef typename bv<c>::bx bx;
  typedef typename bx::bb bb;
  template <typename... ad> bb cb(ad &&...);
};
template <typename c, typename av>
template <typename... ad>
typename cc<c, av>::bb cc<c, av>::cb(ad &&... ay) {
  bx::az(this->bz, this->bz.ca.v, ay...); return cc<c, av>::bb ();
}
}
template <class cd> struct ce {
  static_assert(a::q<cd &, a::b>::e);
  operator cd();
};
namespace base {
template <typename> class cf;
template <typename cg, typename... ch> struct cf<cg(ch...)> {
  template <typename ci, typename = a::ak<a::ap<decltype(a::ac<ci>()), cg>>>
  cf(ci cj) : cf(cj, {}) {}
  template <typename ci> cf(ci cj, a::f) : ck(cj) {}
  a::be<cg()> ck;
};
template <typename cl> using cm = a::be<cl>;
template <typename cl> using cn = cf<cl>;
}
namespace co {
struct de {
  de();
  template <typename cp, typename = decltype(a::ac<cp>())> de(cp &&);
  a::cc<base::cn<void()>> cq;
};
template <typename cp, typename> de::de(cp &&cr) { cq.cb(cr); }
template <typename...> struct ct : a::i<sizeof(int)> {};
template <typename> constexpr bool cs = ct<>::e;
template <typename...> struct x;
template <typename ea> struct x<ea> : a::i<cs<ea>> {};
template <typename ea> constexpr bool cu = x<ea>::e;
template <typename, typename> class cv;
struct cw;
namespace cx {
struct cy { void cz(de) const; };
}
template <typename> class consumer : public cx::cy {};
template <typename, typename da, typename db, typename y, typename dd>
consumer<da> dg(db, y, dd);
namespace cx {
template <typename, typename da> consumer<da> &eb();
template <typename dc, typename da> struct df {
  template <typename dj> using dh = consumer<dj>;
  template <typename di, typename = a::ak<a::ap<decltype(a::ac<di>()), de> && !a::ao<a::aj<di>, df>>>
  df(di cj) : dm(cj) {}
  base::cm<de(dh<cv<dc, da>>)> dm;
};
}
template <typename dc, typename da = cw, typename = cx::df<dc, da>> class dk;
namespace cx {
template <typename, typename, typename di> struct dl {
  template <typename ec, typename = a::ak<a::an<di, ec>>>
  dl(ec &&);
  template <typename db, typename y, typename dd, typename = a::ak<cu<dd>>>
  de dn(db &&, y &&, dd &&) &&;
  template <typename dj> void ed(const dj &, de &) &&;
  di ef;
};
template <typename dc, typename da, typename di>
template <typename ec, typename>
dl<dc, da, di>::dl(ec &&generator) : ef(generator) {}
template <typename dc, typename da, typename di>
template <typename db, typename y, typename dd, typename>
de dl<dc, da, di>::dn(db &&, y &&, dd &&) && {
  auto eo = de();
  consumer eg = dg<dc, da>(a::aq<db>, a::aq<y>, a::aq<dd>);
  a::ar(*this).ed(eg, eo); return de();
}
template <typename dc, typename da, typename di>
template <typename dj>
void dl<dc, da, di>::ed(const dj &eh, de &) && { eh.cz(ef(eh)); }
template <typename dc, typename da>
using ei = dl<dc, da, df<dc, da>>;
}
template <typename dc, typename da, typename di>
struct dk : public cx::dl<bc, cw, di> {
  using parent_type = cx::ei<bc, cw>;
  template <typename ej, typename = a::ak<!a::ao<ej, cx::df<dc, da>>>>
  dk(cx::dl<dc, da, ej> cj) : parent_type(cj.ef) {}
};
template <typename dc, typename da = cw, typename di, typename = a::ak<a::ap<decltype(a::ac<di>()(cx::eb<dc, da>())), de>>>
auto ek(di) -> dk<dc, da, a::aj<di>> { throw 1; }
template <typename dc, typename da, typename di, typename ea>
auto operator|(dk<dc, da, di> e, ea el) { return el(e); }
template <typename dc> struct em {
  auto en() { return ek<dc>([](const auto &eh) { auto eo = [eh] {}; return eo; }); }
};
namespace cx {
struct ep {
  template <typename dc, typename da, typename di, typename MetaGenerator>
  auto operator()(dk<dk<dc, di>, da, MetaGenerator> initial) {
    return ek<dc>([initial](auto) { a::ar(initial).dn([] {}, [] {}, [] {}); });
  }
};
}
auto eq() -> cx::ep;
}
class er : public bu {};
namespace base {
template <typename cd> struct es {
  template <typename... ch>
  es(int, ch... args) : et(new cd(args...)) {}
  br et;
};
template <typename cd, typename... ch> cd eu(ch... args) { es<cd>(a::au, args...); throw 1; } }
template <typename ex>
using ev = a::am<a::ao<ex, bu>, er, ex>;
template <typename ex>
class ew : public ev<ex> {};
namespace Ui {
class ey : public ew<int> {};
struct ez : public ew<int> { ez(bu *, co::dk<bc>, int); };
}
class fa {
  struct fb { Ui::ey *fc; };
  void fd();
  fb fe;
  co::em<co::dk<bc>> ff;
};
void fa::fd() {
  ce<int *> st;
  base::eu<Ui::ez>(fe.fc, ff.en() | co::eq(), *st);
}
Comment 1 Jakub Jelinek 2018-03-10 08:55:47 UTC
Created attachment 43612 [details]
pr84802.C

Updated testcase so that clang++ accepts it (just changed sizeof(int) to 1).
Comment 2 Jason Merrill 2018-03-12 12:59:10 UTC
Author: jason
Date: Mon Mar 12 12:58:38 2018
New Revision: 258447

URL: https://gcc.gnu.org/viewcvs?rev=258447&root=gcc&view=rev
Log:
	PR c++/84802 - ICE capturing uninstantiated class.

	* lambda.c (build_capture_proxy): Call complete_type.

Added:
    trunk/gcc/testsuite/g++.dg/cpp1y/lambda-generic-ice9.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/lambda.c
Comment 3 Jakub Jelinek 2018-03-12 14:36:24 UTC
Fixed, thanks.