[cfe-commits] r120990 - in /cfe/trunk: lib/AST/ExprClassification.cpp lib/Sema/SemaExpr.cpp test/SemaTemplate/enum-argument.cpp test/SemaTemplate/member-access-expr.cpp

John McCall rjmccall at apple.com
Sun Dec 5 21:26:58 PST 2010


Author: rjmccall
Date: Sun Dec  5 23:26:58 2010
New Revision: 120990

URL: http://llvm.org/viewvc/llvm-project?rev=120990&view=rev
Log:
Clarify the logic for when to build an overloaded binop.  In particular,
build one when either of the operands calls itself type-dependent;
previously we were building when one of the operand types was dependent,
which is not always the same thing and which can lead to unfortunate
inconsistencies later.  Fixes PR8739.


Modified:
    cfe/trunk/lib/AST/ExprClassification.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/test/SemaTemplate/enum-argument.cpp
    cfe/trunk/test/SemaTemplate/member-access-expr.cpp

Modified: cfe/trunk/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprClassification.cpp?rev=120990&r1=120989&r2=120990&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprClassification.cpp (original)
+++ cfe/trunk/lib/AST/ExprClassification.cpp Sun Dec  5 23:26:58 2010
@@ -515,7 +515,7 @@
 
   // Records with any const fields (recursively) are not modifiable.
   if (const RecordType *R = CT->getAs<RecordType>()) {
-    assert((isa<ObjCPropertyRefExpr>(E) ||
+    assert((E->getObjectKind() == OK_ObjCProperty ||
             !Ctx.getLangOptions().CPlusPlus) &&
            "C++ struct assignment should be resolved by the "
            "copy assignment operator.");

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=120990&r1=120989&r2=120990&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Dec  5 23:26:58 2010
@@ -7684,24 +7684,34 @@
 ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
                             BinaryOperatorKind Opc,
                             Expr *lhs, Expr *rhs) {
-  if (getLangOptions().CPlusPlus &&
-      (!isa<ObjCPropertyRefExpr>(lhs)
-       || rhs->isTypeDependent() || Opc != BO_Assign) &&
-      (lhs->getType()->isOverloadableType() ||
-       rhs->getType()->isOverloadableType())) {
-    // Find all of the overloaded operators visible from this
-    // point. We perform both an operator-name lookup from the local
-    // scope and an argument-dependent lookup based on the types of
-    // the arguments.
-    UnresolvedSet<16> Functions;
-    OverloadedOperatorKind OverOp = BinaryOperator::getOverloadedOperator(Opc);
-    if (S && OverOp != OO_None)
-      LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
-                                   Functions);
+  if (getLangOptions().CPlusPlus) {
+    bool UseBuiltinOperator;
+
+    if (lhs->isTypeDependent() || rhs->isTypeDependent()) {
+      UseBuiltinOperator = false;
+    } else if (Opc == BO_Assign && lhs->getObjectKind() == OK_ObjCProperty) {
+      UseBuiltinOperator = true;
+    } else {
+      UseBuiltinOperator = !lhs->getType()->isOverloadableType() &&
+                           !rhs->getType()->isOverloadableType();
+    }
 
-    // Build the (potentially-overloaded, potentially-dependent)
-    // binary operation.
-    return CreateOverloadedBinOp(OpLoc, Opc, Functions, lhs, rhs);
+    if (!UseBuiltinOperator) {
+      // Find all of the overloaded operators visible from this
+      // point. We perform both an operator-name lookup from the local
+      // scope and an argument-dependent lookup based on the types of
+      // the arguments.
+      UnresolvedSet<16> Functions;
+      OverloadedOperatorKind OverOp
+        = BinaryOperator::getOverloadedOperator(Opc);
+      if (S && OverOp != OO_None)
+        LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
+                                     Functions);
+
+      // Build the (potentially-overloaded, potentially-dependent)
+      // binary operation.
+      return CreateOverloadedBinOp(OpLoc, Opc, Functions, lhs, rhs);
+    }
   }
 
   // Build a built-in binary operation.

Modified: cfe/trunk/test/SemaTemplate/enum-argument.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/enum-argument.cpp?rev=120990&r1=120989&r2=120990&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/enum-argument.cpp (original)
+++ cfe/trunk/test/SemaTemplate/enum-argument.cpp Sun Dec  5 23:26:58 2010
@@ -30,7 +30,7 @@
     unsigned long long bitfield : e0;
 
     void f(int j) {
-      bitfield + j; // expected-warning {{expression result unused}}
+      bitfield + j;
     }
   };
 }

Modified: cfe/trunk/test/SemaTemplate/member-access-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/member-access-expr.cpp?rev=120990&r1=120989&r2=120990&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/member-access-expr.cpp (original)
+++ cfe/trunk/test/SemaTemplate/member-access-expr.cpp Sun Dec  5 23:26:58 2010
@@ -132,3 +132,18 @@
     }
   };
 }
+
+// PR8739
+namespace test6 {
+  struct A {};
+  struct B {};
+  template <class T> class Base;
+  template <class T> class Derived : public Base<T> {
+    A *field;
+    void get(B **ptr) {
+      // It's okay if at some point we figure out how to diagnose this
+      // at instantiation time.
+      *ptr = field;
+    }
+  };
+}





More information about the cfe-commits mailing list