Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

clang incorrectly diagnoses template operator* as invalid #13945

Open Quuxplusone opened 12 years ago

Quuxplusone commented 12 years ago
Bugzilla Link PR13869
Status NEW
Importance P enhancement
Reported by Eli Friedman (efriedma@quicinc.com)
Reported on 2012-09-18 15:53:22 -0700
Last modified on 2018-01-23 09:38:15 -0800
Version trunk
Hardware PC All
CC dgregor@apple.com, llvm-bugs@lists.llvm.org, rafael@espindo.la, richard-llvm@metafoo.co.uk, ville.voutilainen@gmail.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
Testcase (from g++.old-deja/g++.pt/overload8.C):

struct baz;
void operator*(baz&, double);
template <class T> inline T operator*(double s, const T &p);
void m(baz& a) { a * .5; }

gcc accepts this; clang gives an error "overloaded 'operator*' must have at
least one parameter of class or enumeration type".  Doug says clang should
accept this.
Quuxplusone commented 9 years ago
Same thing:

template <typename T, typename U>
void operator<<(T t, U u)
{
}

template <typename T>
void
operator<<(T t, int i)
{
}

struct S
{
};

int main()
{
    char buf[8];
    S s;
    buf << s;
    return 0;
}

gcc accepts, clang rejects, all the way up to the current trunk.

[over.oper]/6 says
"An operator function shall either be a non-static member function or be a non-
member function that has
at least one parameter whose type is a class, a reference to a class, an
enumeration, or a reference to an
enumeration."

I would certainly expect the violation of that "shall" to be a SFINAE
case, not a hard error.
Quuxplusone commented 9 years ago

This is not covered by SFINAE. Per [temp.deduct]p8,

"Only invalid types and expressions in the immediate context of the function type and its template parameter types can result in a deduction failure."

The issue occurs when we create the declaration of the function template specialization, which happens after we've already determined the function type (which is valid and doesn't result in any kind of failure).

While I agree with Doug that clang should accept this, I don't think this code is valid per the standard as written; taking this to CWG.