[cfe-commits] r143172 - in /cfe/trunk: lib/Sema/SemaExpr.cpp test/CodeGenCXX/assign-operator.cpp

John McCall rjmccall at apple.com
Thu Oct 27 18:04:34 PDT 2011


Author: rjmccall
Date: Thu Oct 27 20:04:34 2011
New Revision: 143172

URL: http://llvm.org/viewvc/llvm-project?rev=143172&view=rev
Log:
Be sure to build a dependent expression when we see
a binary operator involving a dependently-typed overload set.


Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/CodeGenCXX/assign-operator.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=143172&r1=143171&r2=143172&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Oct 27 20:04:34 2011
@@ -8007,6 +8007,12 @@
 ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
                             BinaryOperatorKind Opc,
                             Expr *LHSExpr, Expr *RHSExpr) {
+  // We want to end up calling one of checkPseudoObjectAssignment
+  // (if the LHS is a pseudo-object), BuildOverloadedBinOp (if
+  // both expressions are overloadable or either is type-dependent),
+  // or CreateBuiltinBinOp (in any other case).  We also want to get
+  // any placeholder types out of the way.
+
   // Handle pseudo-objects in the LHS.
   if (const BuiltinType *pty = LHSExpr->getType()->getAsPlaceholderType()) {
     // Assignments with a pseudo-object l-value need special analysis.
@@ -8018,12 +8024,15 @@
     if (pty->getKind() == BuiltinType::Overload) {
       // We can't actually test that if we still have a placeholder,
       // though.  Fortunately, none of the exceptions we see in that
-      // code below are valid when the LHS is an overload set.
+      // code below are valid when the LHS is an overload set.  Note
+      // that an overload set can be dependently-typed, but it never
+      // instantiates to having an overloadable type.
       ExprResult resolvedRHS = CheckPlaceholderExpr(RHSExpr);
       if (resolvedRHS.isInvalid()) return ExprError();
       RHSExpr = resolvedRHS.take();
 
-      if (RHSExpr->getType()->isOverloadableType())
+      if (RHSExpr->isTypeDependent() ||
+          RHSExpr->getType()->isOverloadableType())
         return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
     }
         
@@ -8036,8 +8045,12 @@
   if (const BuiltinType *pty = RHSExpr->getType()->getAsPlaceholderType()) {
     // An overload in the RHS can potentially be resolved by the type
     // being assigned to.
-    if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload)
+    if (Opc == BO_Assign && pty->getKind() == BuiltinType::Overload) {
+      if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent())
+        return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
+
       return CreateBuiltinBinOp(OpLoc, Opc, LHSExpr, RHSExpr);
+    }
 
     // Don't resolve overloads if the other type is overloadable.
     if (pty->getKind() == BuiltinType::Overload &&
@@ -8050,16 +8063,15 @@
   }
 
   if (getLangOptions().CPlusPlus) {
-    bool UseBuiltinOperator;
-
-    if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent()) {
-      UseBuiltinOperator = false;
-    } else {
-      UseBuiltinOperator = !LHSExpr->getType()->isOverloadableType() &&
-                           !RHSExpr->getType()->isOverloadableType();
-    }
+    // If either expression is type-dependent, always build an
+    // overloaded op.
+    if (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent())
+      return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
 
-    if (!UseBuiltinOperator)
+    // Otherwise, build an overloaded op if either expression has an
+    // overloadable type.
+    if (LHSExpr->getType()->isOverloadableType() ||
+        RHSExpr->getType()->isOverloadableType())
       return BuildOverloadedBinOp(*this, S, OpLoc, Opc, LHSExpr, RHSExpr);
   }
 

Modified: cfe/trunk/test/CodeGenCXX/assign-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/assign-operator.cpp?rev=143172&r1=143171&r2=143172&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/assign-operator.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/assign-operator.cpp Thu Oct 27 20:04:34 2011
@@ -17,3 +17,14 @@
   // CHECK: ret
   (i += j) = 17;
 }
+
+// Taken from g++.old-deja/g++.jason/net.C
+namespace test1 {
+  template <class T> void fn (T t) { }
+  template <class T> struct A {
+    void (*p)(T);
+    A() { p = fn; }
+  };
+
+  A<int> a;
+}





More information about the cfe-commits mailing list