forked from OSchip/llvm-project
Be sure to build a dependent expression when we see
a binary operator involving a dependently-typed overload set. llvm-svn: 143172
This commit is contained in:
parent
16dab1bada
commit
9a43e12117
|
@ -8007,6 +8007,12 @@ static ExprResult BuildOverloadedBinOp(Sema &S, Scope *Sc, SourceLocation OpLoc,
|
|||
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 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
|
|||
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 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
|
|||
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 @@ ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
|
|||
}
|
||||
|
||||
if (getLangOptions().CPlusPlus) {
|
||||
bool UseBuiltinOperator;
|
||||
// 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 (LHSExpr->isTypeDependent() || RHSExpr->isTypeDependent()) {
|
||||
UseBuiltinOperator = false;
|
||||
} else {
|
||||
UseBuiltinOperator = !LHSExpr->getType()->isOverloadableType() &&
|
||||
!RHSExpr->getType()->isOverloadableType();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,3 +17,14 @@ void f(int i, int j) {
|
|||
// 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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue