diff options
author | John McCall <rjmccall@apple.com> | 2011-10-28 01:04:34 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-10-28 01:04:34 +0000 |
commit | ac51650d054c2eaada48d54dba52c08153d2daed (patch) | |
tree | 160e66f96bbf8603534edd7f09c6e8b9990eb8b7 /lib/Sema/SemaExpr.cpp | |
parent | 55733de16f492dadbf5f4d2809d6c610ba6d86ae (diff) |
Be sure to build a dependent expression when we see
a binary operator involving a dependently-typed overload set.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143172 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 880199bc7a..a733b81361 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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 (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); } |