[cfe-commits] r80112 - in /cfe/trunk: lib/Sema/SemaOverload.cpp test/SemaCXX/overload-binop-implicitconvert.cpp

Douglas Gregor dgregor at apple.com
Wed Aug 26 10:08:25 PDT 2009


Author: dgregor
Date: Wed Aug 26 12:08:25 2009
New Revision: 80112

URL: http://llvm.org/viewvc/llvm-project?rev=80112&view=rev
Log:
Fix for overloaded binary operators whose operands need implicit
conversions, from Sylvere Teissier!

Added:
    cfe/trunk/test/SemaCXX/overload-binop-implicitconvert.cpp
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=80112&r1=80111&r2=80112&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Aug 26 12:08:25 2009
@@ -4332,6 +4332,7 @@
                             FunctionSet &Functions,
                             Expr *LHS, Expr *RHS) {
   Expr *Args[2] = { LHS, RHS };
+  LHS=RHS=0; //Please use only Args instead of LHS/RHS couple
 
   BinaryOperator::Opcode Opc = static_cast<BinaryOperator::Opcode>(OpcIn);
   OverloadedOperatorKind Op = BinaryOperator::getOverloadedOperator(Opc);
@@ -4339,10 +4340,10 @@
 
   // If either side is type-dependent, create an appropriate dependent
   // expression.
-  if (LHS->isTypeDependent() || RHS->isTypeDependent()) {
+  if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
     // .* cannot be overloaded.
     if (Opc == BinaryOperator::PtrMemD)
-      return Owned(new (Context) BinaryOperator(LHS, RHS, Opc,
+      return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
                                                 Context.DependentTy, OpLoc));
 
     OverloadedFunctionDecl *Overloads 
@@ -4364,14 +4365,14 @@
   // If this is the .* operator, which is not overloadable, just
   // create a built-in binary operator.
   if (Opc == BinaryOperator::PtrMemD)
-    return CreateBuiltinBinOp(OpLoc, Opc, LHS, RHS);
+    return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
   // If this is one of the assignment operators, we only perform
   // overload resolution if the left-hand side is a class or
   // enumeration type (C++ [expr.ass]p3).
   if (Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign &&
-      !LHS->getType()->isOverloadableType())
-    return CreateBuiltinBinOp(OpLoc, Opc, LHS, RHS);
+      !Args[0]->getType()->isOverloadableType())
+    return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 
   // Build an empty overload set.
   OverloadCandidateSet CandidateSet;
@@ -4398,15 +4399,15 @@
 
         // Convert the arguments.
         if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
-          if (PerformObjectArgumentInitialization(LHS, Method) ||
-              PerformCopyInitialization(RHS, FnDecl->getParamDecl(0)->getType(),
+          if (PerformObjectArgumentInitialization(Args[0], Method) ||
+              PerformCopyInitialization(Args[1], FnDecl->getParamDecl(0)->getType(),
                                         "passing"))
             return ExprError();
         } else {
           // Convert the arguments.
-          if (PerformCopyInitialization(LHS, FnDecl->getParamDecl(0)->getType(),
+          if (PerformCopyInitialization(Args[0], FnDecl->getParamDecl(0)->getType(),
                                         "passing") ||
-              PerformCopyInitialization(RHS, FnDecl->getParamDecl(1)->getType(),
+              PerformCopyInitialization(Args[1], FnDecl->getParamDecl(1)->getType(),
                                         "passing"))
             return ExprError();
         }
@@ -4428,9 +4429,9 @@
         // We matched a built-in operator. Convert the arguments, then
         // break out so that we will build the appropriate built-in
         // operator node.
-        if (PerformImplicitConversion(LHS, Best->BuiltinTypes.ParamTypes[0],
+        if (PerformImplicitConversion(Args[0], Best->BuiltinTypes.ParamTypes[0],
                                       Best->Conversions[0], "passing") ||
-            PerformImplicitConversion(RHS, Best->BuiltinTypes.ParamTypes[1],
+            PerformImplicitConversion(Args[1], Best->BuiltinTypes.ParamTypes[1],
                                       Best->Conversions[1], "passing"))
           return ExprError();
 
@@ -4442,10 +4443,10 @@
       // For class as left operand for assignment or compound assigment operator
       // do not fall through to handling in built-in, but report that no overloaded
       // assignment operator found
-      if (LHS->getType()->isRecordType() && Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) {
+      if (Args[0]->getType()->isRecordType() && Opc >= BinaryOperator::Assign && Opc <= BinaryOperator::OrAssign) {
         Diag(OpLoc,  diag::err_ovl_no_viable_oper)
              << BinaryOperator::getOpcodeStr(Opc)
-             << LHS->getSourceRange() << RHS->getSourceRange();
+             << Args[0]->getSourceRange() << Args[1]->getSourceRange();
         return ExprError();
       }
       // No viable function; fall through to handling this as a
@@ -4455,7 +4456,7 @@
     case OR_Ambiguous:
       Diag(OpLoc,  diag::err_ovl_ambiguous_oper)
           << BinaryOperator::getOpcodeStr(Opc)
-          << LHS->getSourceRange() << RHS->getSourceRange();
+          << Args[0]->getSourceRange() << Args[1]->getSourceRange();
       PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
       return ExprError();
 
@@ -4463,7 +4464,7 @@
       Diag(OpLoc, diag::err_ovl_deleted_oper)
         << Best->Function->isDeleted()
         << BinaryOperator::getOpcodeStr(Opc)
-        << LHS->getSourceRange() << RHS->getSourceRange();
+        << Args[0]->getSourceRange() << Args[1]->getSourceRange();
       PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
       return ExprError();
     }
@@ -4471,7 +4472,7 @@
   // Either we found no viable overloaded operator or we matched a
   // built-in operator. In either case, try to build a built-in
   // operation.
-  return CreateBuiltinBinOp(OpLoc, Opc, LHS, RHS);
+  return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
 }
 
 /// BuildCallToMemberFunction - Build a call to a member

Added: cfe/trunk/test/SemaCXX/overload-binop-implicitconvert.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/overload-binop-implicitconvert.cpp?rev=80112&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/overload-binop-implicitconvert.cpp (added)
+++ cfe/trunk/test/SemaCXX/overload-binop-implicitconvert.cpp Wed Aug 26 12:08:25 2009
@@ -0,0 +1,22 @@
+// RUN: clang-cc %s -emit-llvm
+class T
+{};
+
+void print(const char *t);
+
+T& operator<< (T& t,const char* c)
+{
+  print(c);
+  return t;
+}
+
+
+int main()
+{
+  T t;
+  print("foo");
+  t<<"foo";
+  
+  return 0;
+}
+  





More information about the cfe-commits mailing list