[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