https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69694
Patrick Palka <ppalka at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2016-02-11 CC| |ppalka at gcc dot gnu.org Known to work| |4.9.1 Ever confirmed|0 |1 --- Comment #1 from Patrick Palka <ppalka at gcc dot gnu.org> --- Reduced test case: template<typename... Ts> using void_t = void; extern void *declval_void; template<typename, typename> struct Fun { }; template<typename Desc> struct Fun<Desc, void_t<decltype (declval_void = Desc::name)>> { void fun(); }; struct Tag { static constexpr void* name = 0; }; template<typename> void a() { Fun<Tag, void>{}.fun(); } g++ 4.9 compiles this successfully, g++ 5.1 doesn't, neither does trunk. The problem is that type_dependent_expression_p considers the MODOP_EXPR within the decltype to be dependent even after substitution because its TREE_TYPE is NULL. Since the decltype is considered dependent even after substitution, it never gets resolved to a concrete type. This stops void_t<decltype (...)> from getting resolved to "void". And ultimately it makes partial-specialization selection not work properly. So build_x_modify_expr probably should not build a MODOP_EXPR with NULL TREE_TYPE if the operands are not dependent.