[cfe-commits] r113713 - in /cfe/trunk: lib/Sema/SemaOverload.cpp test/CXX/over/over.built/p1.cpp

Douglas Gregor dgregor at apple.com
Sat Sep 11 21:28:07 PDT 2010


Author: dgregor
Date: Sat Sep 11 23:28:07 2010
New Revision: 113713

URL: http://llvm.org/viewvc/llvm-project?rev=113713&view=rev
Log:
Implement the "note" in C++ [over.built]p1, which is actually meant to
be a semantic requirement that a built-in overloaded operator is not
added to the overload set of there is already a user-defined
overloaded operator with the same parameter types. Fixes PR8087.

Added:
    cfe/trunk/test/CXX/over/over.built/p1.cpp   (with props)
Modified:
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=113713&r1=113712&r2=113713&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sat Sep 11 23:28:07 2010
@@ -25,6 +25,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/PartialDiagnostic.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include <algorithm>
@@ -4527,6 +4528,44 @@
                                           Op == OO_PipePipe),
                                          VisibleTypeConversionsQuals);
 
+  // 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.
+  //
+  // 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.
+  llvm::DenseSet<std::pair<CanQualType, CanQualType> > 
+    UserDefinedBinaryOperators;
+  
+  if (CandidateTypes.enumeration_begin() != CandidateTypes.enumeration_end()) {
+    for (OverloadCandidateSet::iterator C = CandidateSet.begin(),
+                                     CEnd = CandidateSet.end();
+         C != CEnd; ++C) {
+      if (!C->Viable || !C->Function || C->Function->getNumParams() != 2)
+        continue;
+      
+      // Check if the first parameter is of enumeration type.
+      QualType FirstParamType
+        = C->Function->getParamDecl(0)->getType().getUnqualifiedType();
+      if (!FirstParamType->isEnumeralType())
+        continue;
+      
+      // Check if the second parameter is of enumeration type.
+      QualType SecondParamType
+        = C->Function->getParamDecl(1)->getType().getUnqualifiedType();
+      if (!SecondParamType->isEnumeralType())
+        continue;
+
+      // Add this operator to the set of known user-defined operators.
+      UserDefinedBinaryOperators.insert(
+                  std::make_pair(Context.getCanonicalType(FirstParamType),
+                                 Context.getCanonicalType(SecondParamType)));
+    }
+  }
+  
   bool isComparison = false;
   switch (Op) {
   case OO_None:
@@ -4779,7 +4818,10 @@
            = CandidateTypes.enumeration_begin();
          Enum != CandidateTypes.enumeration_end(); ++Enum) {
       QualType ParamTypes[2] = { *Enum, *Enum };
-      AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet);
+      CanQualType CanonType = Context.getCanonicalType(*Enum);
+      if (!UserDefinedBinaryOperators.count(
+                                          std::make_pair(CanonType, CanonType)))
+        AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet);
     }
 
     // Fall through.

Added: cfe/trunk/test/CXX/over/over.built/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.built/p1.cpp?rev=113713&view=auto
==============================================================================
--- cfe/trunk/test/CXX/over/over.built/p1.cpp (added)
+++ cfe/trunk/test/CXX/over/over.built/p1.cpp Sat Sep 11 23:28:07 2010
@@ -0,0 +1,16 @@
+// 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;
+}

Propchange: cfe/trunk/test/CXX/over/over.built/p1.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CXX/over/over.built/p1.cpp
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/CXX/over/over.built/p1.cpp
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list