https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90598
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> --- The problem is that by the time finish_decltype_type is called, the destructor call is already folded into a TARGET_EXPR <D.2335, {}> = {CLOBBER}; The following untested patch fixes it for me: 2019-05-23 Jakub Jelinek <ja...@redhat.com> PR c++/90598 * call.c (build_trivial_dtor_call): Wrap MODIFY_EXPR for -flifetime-dse into void_type_node NOP_EXPR. * g++.dg/cpp0x/pr90598.C: New test. --- gcc/cp/call.c.jj 2019-05-23 12:57:16.658493722 +0200 +++ gcc/cp/call.c 2019-05-23 18:37:09.570874611 +0200 @@ -7995,8 +7995,8 @@ build_trivial_dtor_call (tree instance) /* A trivial destructor should still clobber the object. */ tree clobber = build_clobber (TREE_TYPE (instance)); - return build2 (MODIFY_EXPR, void_type_node, - instance, clobber); + return build1 (NOP_EXPR, void_type_node, + build2 (MODIFY_EXPR, void_type_node, instance, clobber)); } /* Subroutine of the various build_*_call functions. Overload resolution --- gcc/testsuite/g++.dg/cpp0x/pr90598.C.jj 2019-05-23 18:39:37.034464509 +0200 +++ gcc/testsuite/g++.dg/cpp0x/pr90598.C 2019-05-23 18:39:05.471980348 +0200 @@ -0,0 +1,8 @@ +// PR c++/90598 +// { dg-do compile { target c++11 } } + +struct A {}; +using B = decltype(A ().~A ()); +template <typename T> struct C; +template <> struct C<void> {}; +C<B> t;