Bug 116876 (cwg1705) - GCC accepts invalid call to overloaded function template when neither is at least as specialized as the other
Summary: GCC accepts invalid call to overloaded function template when neither is at l...
Status: UNCONFIRMED
Alias: cwg1705
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 15.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2024-09-28 15:28 UTC by Jason Liam
Modified: 2024-10-16 17:13 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jason Liam 2024-09-28 15:28:18 UTC
The following invalid program is accepted by gcc and msvc but rejected by clang. 

```
#include <utility>
#include <iostream>
template< class T > void f( T& t ){} ;
template< class T > void f( const T&& ) {};
int main()
{
    int i = 0;
    f<int&>(i); //clang:nope, gcc:ok, msvc:ok
} 
```
Demo: https://godbolt.org/z/4K7ErvWjh

Related thread: https://stackoverflow.com/questions/79034394/function-template-overloading-when-called-with-reference-type-rejected-by-clang
Comment 1 Andrew Pinski 2024-09-28 18:06:39 UTC
EDG also accepts it. So maybe this is a clang issue.
Comment 3 Andrew Pinski 2024-09-28 18:12:13 UTC
EDG, GCC and MSVC all use the reference function rather const rvalue reference function.

if we change the const rvalue reference to just an rvalue reference, then clang accepts it:
> template< class T > void f( T&& ) { puts("rvalue-reference"); };


So are you sure this is not a clang issue?
Comment 4 Jason Liam 2024-09-29 04:10:01 UTC
> So are you sure this is not a clang issue?

Yes, because [temp.deduct.partial#9.1] make the second overload not to be atleast as specialized as the first and then [temp.deduct.partial#9.2] make the first template not to be atleast as specialized as the second. So neither overloads are at least as specialized than the other and hence also **neither of them more specialized**.

This was explained in the thread link I posted in the original bug: https://stackoverflow.com/a/79034540/12002570

Now coming to the example you gave where we have changed the second overload to `f(T&&)`, this starts working because then the [temp.deduct.partial#9.2] will no longer apply and we will get on of the overloads more specialized than the other.
Comment 5 Patrick Palka 2024-10-15 18:17:43 UTC
That [temp.deduct.partial] wording was changed with wg21.link/cwg1705.  It seems GCC is behaving correctly wrt to the old wording and just hasn't implemented the new wording?