// bool operator==(T, T);
// bool operator!=(T, T);
void addRelationalPointerOrEnumeralOverloads() {
- // C++ [over.built]p1:
- // If there is a user-written candidate with the same name and parameter
- // types as a built-in candidate operator function, the built-in operator
- // function is hidden and is not included in the set of candidate
- // functions.
+ // C++ [over.match.oper]p3:
+ // [...]the built-in candidates include all of the candidate operator
+ // functions defined in 13.6 that, compared to the given operator, [...]
+ // do not have the same parameter-type-list as any non-template non-member
+ // candidate.
//
- // The text is actually in a note, but if we don't implement it then we end
- // up with ambiguities when the user provides an overloaded operator for
- // an enumeration type. Note that only enumeration types have this problem,
- // so we track which enumeration types we've seen operators for. Also, the
- // only other overloaded operator with enumeration argumenst, operator=,
+ // Note that in practice, this only affects enumeration types because there
+ // aren't any built-in candidates of record type, and a user-defined operator
+ // must have an operand of record or enumeration type. Also, the only other
+ // overloaded operator with enumeration arguments, operator=,
// cannot be overloaded for enumeration types, so this is the only place
// where we must suppress candidates like this.
llvm::DenseSet<std::pair<CanQualType, CanQualType> >
if (!C->Viable || !C->Function || C->Function->getNumParams() != 2)
continue;
+ if (C->Function->isFunctionTemplateSpecialization())
+ continue;
+
QualType FirstParamType =
C->Function->getParamDecl(0)->getType().getUnqualifiedType();
QualType SecondParamType =
+++ /dev/null
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-enum E1 { one };
-enum E2 { two };
-
-bool operator >= (E1, E1) {
- return false;
-}
-
-bool operator >= (E1, const E2) {
- return false;
-}
-
-bool test(E1 a, E1 b, E2 c) {
- return a >= b || a >= c;
-}
--- /dev/null
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// This is specifically testing the bullet:
+// "do not have the same parameter-type-list as any non-template
+// non-member candidate."
+// The rest is sort of hard to test separately.
+
+enum E1 { one };
+enum E2 { two };
+
+struct A;
+
+A operator >= (E1, E1);
+A operator >= (E1, const E2);
+
+E1 a;
+E2 b;
+
+extern A test1;
+extern decltype(a >= a) test1;
+extern decltype(a >= b) test1;
+
+template <typename T> A operator <= (E1, T);
+extern bool test2;
+extern decltype(a <= a) test2;
+
+extern A test3;
+extern decltype(a <= b) test3;
\ No newline at end of file