summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard@metafoo.co.uk>2020-01-30 17:11:47 -0800
committerRichard Smith <richard@metafoo.co.uk>2020-02-04 12:25:40 -0800
commit7a94fc09d17bc317032eb9605eba05dced8c87e5 (patch)
treedf6513fb5b8d64f4340ab0f0e3c9983e420baf50 /clang/lib/Sema/SemaDeclCXX.cpp
parent300cbdc59da05756f7a0334338076124536df03d (diff)
downloadbcm5719-llvm-7a94fc09d17bc317032eb9605eba05dced8c87e5.tar.gz
bcm5719-llvm-7a94fc09d17bc317032eb9605eba05dced8c87e5.zip
PR44721: Don't consider overloaded operators for built-in comparisons
when building a defaulted comparison. As a convenient way of asking whether `x @ y` is valid and building it, we previouly always performed overload resolution and built an overloaded expression, which would both end up picking a builtin operator candidate when given a non-overloadable type. But that's not quite right, because it can result in our finding a user-declared operator overload, which we should never do when applying operators non-overloadable types. Handle this more correctly: skip overload resolution when building `x @ y` if the operands are not overloadable. But still perform overload resolution (considering only builtin candidates) when checking validity, as we don't have any other good way to ask whether a binary operator expression would be valid. (cherry picked from commit 1f3f8c369a5067a132c871f33a955a7feaea8534)
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp29
1 files changed, 22 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 19403e05085..831e55046e8 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7373,7 +7373,14 @@ private:
/// resolution [...]
CandidateSet.exclude(FD);
- S.LookupOverloadedBinOp(CandidateSet, OO, Fns, Args);
+ if (Args[0]->getType()->isOverloadableType())
+ S.LookupOverloadedBinOp(CandidateSet, OO, Fns, Args);
+ else {
+ // FIXME: We determine whether this is a valid expression by checking to
+ // see if there's a viable builtin operator candidate for it. That isn't
+ // really what the rules ask us to do, but should give the right results.
+ S.AddBuiltinOperatorCandidates(OO, FD->getLocation(), Args, CandidateSet);
+ }
Result R;
@@ -7851,10 +7858,14 @@ private:
return StmtError();
OverloadedOperatorKind OO = FD->getOverloadedOperator();
- ExprResult Op = S.CreateOverloadedBinOp(
- Loc, BinaryOperator::getOverloadedOpcode(OO), Fns,
- Obj.first.get(), Obj.second.get(), /*PerformADL=*/true,
- /*AllowRewrittenCandidates=*/true, FD);
+ BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO);
+ ExprResult Op;
+ if (Type->isOverloadableType())
+ Op = S.CreateOverloadedBinOp(Loc, Opc, Fns, Obj.first.get(),
+ Obj.second.get(), /*PerformADL=*/true,
+ /*AllowRewrittenCandidates=*/true, FD);
+ else
+ Op = S.CreateBuiltinBinOp(Loc, Opc, Obj.first.get(), Obj.second.get());
if (Op.isInvalid())
return StmtError();
@@ -7894,8 +7905,12 @@ private:
llvm::APInt ZeroVal(S.Context.getIntWidth(S.Context.IntTy), 0);
Expr *Zero =
IntegerLiteral::Create(S.Context, ZeroVal, S.Context.IntTy, Loc);
- ExprResult Comp = S.CreateOverloadedBinOp(Loc, BO_NE, Fns, VDRef.get(),
- Zero, true, true, FD);
+ ExprResult Comp;
+ if (VDRef.get()->getType()->isOverloadableType())
+ Comp = S.CreateOverloadedBinOp(Loc, BO_NE, Fns, VDRef.get(), Zero, true,
+ true, FD);
+ else
+ Comp = S.CreateBuiltinBinOp(Loc, BO_NE, VDRef.get(), Zero);
if (Comp.isInvalid())
return StmtError();
Sema::ConditionResult Cond = S.ActOnCondition(
OpenPOWER on IntegriCloud