This triggers the static_assert while it shouldn't, because DR 1227 says "The substitution proceeds in lexical order and stops when a condition that causes deduction to fail is encountered." Compiles with clang++/EDG. template<bool, typename = void> struct enable_if { }; template<typename T> struct enable_if<true, T> { using type = T; }; template<class T> struct hard_error { static_assert(sizeof(T) == 0); static inline constexpr bool value = true; }; template<class T> struct always_false { static inline constexpr bool value = false; }; template<class T> int foo (int, typename enable_if<always_false<T>::value, int>::type = 0, typename enable_if<hard_error<T>::value, int>::type = 0 ) { return 0; } template<class T> char const *foo (long) { return ""; } int main () { char const *sz = foo<int>(0); }
Patch: https://gcc.gnu.org/pipermail/gcc-patches/2021-April/569184.html
The master branch has been updated by Patrick Palka <ppalka@gcc.gnu.org>: https://gcc.gnu.org/g:b0d73a66ae3962fa83309527d85613d72a6aa43d commit r12-1398-gb0d73a66ae3962fa83309527d85613d72a6aa43d Author: Patrick Palka <ppalka@redhat.com> Date: Fri Jun 11 16:00:52 2021 -0400 c++: Substitute into function parms in lexical order [PR96560] This makes tsubst_arg_types substitute into a function's parameter types in left-to-right instead of right-to-left order, in accordance with DR 1227. DR 1227 PR c++/96560 gcc/cp/ChangeLog: * pt.c (tsubst_arg_types): Rearrange so that we substitute into TYPE_ARG_TYPES in forward order while short circuiting appropriately. Adjust formatting. gcc/testsuite/ChangeLog: * g++.dg/template/sfinae-dr1227.C: New test.
Fixed.