diff options
author | Chandler Carruth <chandlerc@gmail.com> | 2014-10-11 11:03:30 +0000 |
---|---|---|
committer | Chandler Carruth <chandlerc@gmail.com> | 2014-10-11 11:03:30 +0000 |
commit | b29a74389190d649aeb96a5d1f949a3aaf4e744a (patch) | |
tree | 7ea9510a8565841541f2d2ceb2f9198eba797244 /clang/lib/AST/ExprConstant.cpp | |
parent | 8d57d2510fe71c37dda0d3219a3411ffad0cee3e (diff) | |
download | bcm5719-llvm-b29a74389190d649aeb96a5d1f949a3aaf4e744a.tar.gz bcm5719-llvm-b29a74389190d649aeb96a5d1f949a3aaf4e744a.zip |
[complex] Teach the other two binary operators on complex numbers (==
and !=) to support mixed complex and real operand types.
This requires removing an assert from SemaChecking, and adding support
both to the constant evaluator and the code generator to synthesize the
imaginary part when needed. This seemed somewhat cleaner than having
just the comparison operators force real-to-complex conversions.
I've added test cases for these operations. I'm really terrified that
there were *no* tests in-tree which exercised this.
This turned up when trying to build R after my change to the complex
type lowering.
llvm-svn: 219570
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index db300c4fec4..532720666bc 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -6780,15 +6780,27 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { QualType LHSTy = E->getLHS()->getType(); QualType RHSTy = E->getRHS()->getType(); - if (LHSTy->isAnyComplexType()) { - assert(RHSTy->isAnyComplexType() && "Invalid comparison"); + if (LHSTy->isAnyComplexType() || RHSTy->isAnyComplexType()) { ComplexValue LHS, RHS; - - bool LHSOK = EvaluateComplex(E->getLHS(), LHS, Info); + bool LHSOK; + if (E->getLHS()->getType()->isRealFloatingType()) { + LHSOK = EvaluateFloat(E->getLHS(), LHS.FloatReal, Info); + if (LHSOK) { + LHS.makeComplexFloat(); + LHS.FloatImag = APFloat(LHS.FloatReal.getSemantics()); + } + } else { + LHSOK = EvaluateComplex(E->getLHS(), LHS, Info); + } if (!LHSOK && !Info.keepEvaluatingAfterFailure()) return false; - if (!EvaluateComplex(E->getRHS(), RHS, Info) || !LHSOK) + if (E->getRHS()->getType()->isRealFloatingType()) { + if (!EvaluateFloat(E->getRHS(), RHS.FloatReal, Info) || !LHSOK) + return false; + RHS.makeComplexFloat(); + RHS.FloatImag = APFloat(RHS.FloatReal.getSemantics()); + } else if (!EvaluateComplex(E->getRHS(), RHS, Info) || !LHSOK) return false; if (LHS.isComplexFloat()) { |