If we're going to try to do normal semantic checking of static_cast in a template, we need to use build_non_dependent_expr like we do for function calls.
Tested x86_64-pc-linux-gnu, applying to trunk.
commit 4d7e6ada4e9f1c83d59b0e83d7e554ddae5cb3a8 Author: Jason Merrill <ja...@redhat.com> Date: Fri Jan 12 13:49:44 2018 -0500 PR c++/83186 - ICE with static_cast of list-initialized temporary. * typeck.c (build_static_cast): Use build_non_dependent_expr. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 669a2b45bfd..f0dc03de111 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -7204,6 +7204,8 @@ build_static_cast (tree type, tree oexpr, tsubst_flags_t complain) TREE_SIDE_EFFECTS (expr) = 1; return convert_from_reference (expr); } + else if (processing_template_decl) + expr = build_non_dependent_expr (expr); /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-cast1.C b/gcc/testsuite/g++.dg/cpp0x/initlist-cast1.C new file mode 100644 index 00000000000..5446d85f3aa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-cast1.C @@ -0,0 +1,12 @@ +// PR c++/83186 +// { dg-do compile { target c++11 } } + +struct a { + operator unsigned(); +}; +template <class> void b() { static_cast<unsigned>(a{}); } + +int main() +{ + b<int>(); +}