Bug 86932 - [8 Regression] Empty non-type template parameter pack not considered for SFINAE.
Summary: [8 Regression] Empty non-type template parameter pack not considered for SFINAE.
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 8.2.0
: P2 normal
Target Milestone: 8.4
Assignee: Jason Merrill
URL:
Keywords: accepts-invalid
Depends on: 90227
Blocks:
  Show dependency treegraph
 
Reported: 2018-08-13 09:15 UTC by zennehoy
Modified: 2019-11-20 06:20 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work: 7.3.0
Known to fail: 8.2.0, 9.0
Last reconfirmed: 2018-08-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description zennehoy 2018-08-13 09:15:44 UTC
The following code incorrectly compiles under GCC 8.1/8.2, but fails (as expected) with GCC 7.3 and other compilers:

    #include <type_traits>
    
    template<class U, typename std::enable_if_t<std::is_const_v<U>>...>
    void f() {}
    
    int main()
    {
        f<int>();
    }

The originating stackoverflow discussion about this issue can be found here:
https://stackoverflow.com/q/51787713/694509

A working example can be found on godbolt:
https://godbolt.org/g/Rb46qQ
Comment 1 zennehoy 2018-08-13 09:59:37 UTC
Sorry, I included the problematic void non-type template parameter pack.

The type of std::enable_if_t should be specified as something other than void, e.g., int:

    #include <type_traits>
    
    template<class U, typename std::enable_if_t<std::is_const_v<U>, int>...>
    void f() {}
    
    int main()
    {
        f<int>();
    }
Comment 2 Jonathan Wakely 2018-08-13 10:18:50 UTC
You've got a stray 'typename' there.

Reduced:

template<bool, typename T> struct enable_if { using type = T; };
template<typename T> struct enable_if<false, T> { };

template<typename> struct is_foo { static constexpr bool value = false; };

template<class U, typename enable_if<is_foo<U>::value, int>::type...>
void f() {}

int main()
{
  f<int>();
}

Started to be accepted with r247842

            PR c++/79549 - C++17 ICE with non-type auto template parameter pack
    
            * pt.c (convert_template_argument): Just return an argument pack.
            (coerce_template_parameter_pack, template_parm_to_arg)
            (extract_fnparm_pack, make_argument_pack, tsubst_template_args)
            (tsubst_decl, tsubst, type_unification_real, unify_pack_expansion):
            Don't set the type of a NONTYPE_ARGUMENT_PACK.
            * parser.c (make_char_string_pack, make_string_pack): Likewise.
Comment 3 Jakub Jelinek 2019-02-22 15:21:24 UTC
GCC 8.3 has been released.
Comment 4 Jason Merrill 2019-03-27 14:27:32 UTC
Author: jason
Date: Wed Mar 27 14:27:00 2019
New Revision: 269965

URL: https://gcc.gnu.org/viewcvs?rev=269965&root=gcc&view=rev
Log:
	PR c++/86932 - missed SFINAE with empty pack.

The issue here was that when processing the explicit template args in
fn_type_unification we added an empty argument pack for the parameter pack,
so we never tried to do any deduction for it, and therefore never looked at
its type.  We need that empty pack behavior for partial ordering, but we
don't want it here, so let's make it conditional on tf_partial.

	* pt.c (coerce_template_parms): Don't add an empty pack if
	tf_partial.
	(fn_type_unification): Pass tf_partial to coerce_template_parms.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/sfinae65.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
Comment 5 Jason Merrill 2019-03-27 14:28:47 UTC
Fixed on trunk so far.
Comment 6 Jason Merrill 2019-04-05 02:51:24 UTC
Author: jason
Date: Fri Apr  5 02:50:52 2019
New Revision: 270160

URL: https://gcc.gnu.org/viewcvs?rev=270160&root=gcc&view=rev
Log:
	PR c++/89966 - error with non-type auto tparm.

My patch for PR 86932 broke this testcase by passing tf_partial to
coerce_template_template_parms, which prevented do_auto_deduction from
actually replacing the auto.

	* pt.c (do_auto_deduction): Clear tf_partial.

Added:
    trunk/gcc/testsuite/g++.dg/cpp1z/nontype-auto15.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
Comment 7 Eric Gallager 2019-11-20 06:20:45 UTC
(In reply to Jason Merrill from comment #5)
> Fixed on trunk so far.

So... just waiting on a backport to the branch for 8, then?