aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-09-18 21:52:24 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-09-18 21:52:24 +0000
commit97c6739a1e74a3131261081054ff4a75e4e3b64c (patch)
tree0f8b668bae1dbc6da740a16063efb564cc71b604 /lib/Sema/SemaOverload.cpp
parent9cd5b24315aea4bc58bac03cfb4874e076b013b8 (diff)
Fix a small bug in the way we handle builtin candidates for
relational operators of enumeration type. From the gcc testsuite. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164171 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp22
1 files changed, 12 insertions, 10 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 14f8db6db5..1dec1ff7d2 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -6790,17 +6790,16 @@ public:
// 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> >
@@ -6815,6 +6814,9 @@ public:
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 =