@@ -9325,6 +9325,13 @@ bool PointerExprEvaluator::VisitCastExpr(const CastExpr *E) {
93259325 Result.IsNullPtr = false;
93269326 return true;
93279327 } else {
9328+ // In rare instances, the value isn't an lvalue.
9329+ // For example, when the value is the difference between the addresses of
9330+ // two labels. We reject that as a constant expression because we can't
9331+ // compute a valid offset to convert into a pointer.
9332+ if (!Value.isLValue())
9333+ return false;
9334+
93289335 // Cast is of an lvalue, no need to change value.
93299336 Result.setFrom(Info.Ctx, Value);
93309337 return true;
@@ -15126,6 +15133,62 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
1512615133 llvm_unreachable("unknown cast resulting in complex value");
1512715134}
1512815135
15136+ void HandleComplexComplexMul(APFloat A, APFloat B, APFloat C, APFloat D,
15137+ APFloat &ResR, APFloat &ResI) {
15138+ // This is an implementation of complex multiplication according to the
15139+ // constraints laid out in C11 Annex G. The implementation uses the
15140+ // following naming scheme:
15141+ // (a + ib) * (c + id)
15142+
15143+ APFloat AC = A * C;
15144+ APFloat BD = B * D;
15145+ APFloat AD = A * D;
15146+ APFloat BC = B * C;
15147+ ResR = AC - BD;
15148+ ResI = AD + BC;
15149+ if (ResR.isNaN() && ResI.isNaN()) {
15150+ bool Recalc = false;
15151+ if (A.isInfinity() || B.isInfinity()) {
15152+ A = APFloat::copySign(APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0),
15153+ A);
15154+ B = APFloat::copySign(APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0),
15155+ B);
15156+ if (C.isNaN())
15157+ C = APFloat::copySign(APFloat(C.getSemantics()), C);
15158+ if (D.isNaN())
15159+ D = APFloat::copySign(APFloat(D.getSemantics()), D);
15160+ Recalc = true;
15161+ }
15162+ if (C.isInfinity() || D.isInfinity()) {
15163+ C = APFloat::copySign(APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0),
15164+ C);
15165+ D = APFloat::copySign(APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0),
15166+ D);
15167+ if (A.isNaN())
15168+ A = APFloat::copySign(APFloat(A.getSemantics()), A);
15169+ if (B.isNaN())
15170+ B = APFloat::copySign(APFloat(B.getSemantics()), B);
15171+ Recalc = true;
15172+ }
15173+ if (!Recalc && (AC.isInfinity() || BD.isInfinity() || AD.isInfinity() ||
15174+ BC.isInfinity())) {
15175+ if (A.isNaN())
15176+ A = APFloat::copySign(APFloat(A.getSemantics()), A);
15177+ if (B.isNaN())
15178+ B = APFloat::copySign(APFloat(B.getSemantics()), B);
15179+ if (C.isNaN())
15180+ C = APFloat::copySign(APFloat(C.getSemantics()), C);
15181+ if (D.isNaN())
15182+ D = APFloat::copySign(APFloat(D.getSemantics()), D);
15183+ Recalc = true;
15184+ }
15185+ if (Recalc) {
15186+ ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
15187+ ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
15188+ }
15189+ }
15190+ }
15191+
1512915192bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1513015193 if (E->isPtrMemOp() || E->isAssignmentOp() || E->getOpcode() == BO_Comma)
1513115194 return ExprEvaluatorBaseTy::VisitBinaryOperator(E);
@@ -15225,55 +15288,7 @@ bool ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
1522515288 !handleFloatFloatBinOp(Info, E, ResI, BO_Mul, B))
1522615289 return false;
1522715290 } else {
15228- // In the fully general case, we need to handle NaNs and infinities
15229- // robustly.
15230- APFloat AC = A * C;
15231- APFloat BD = B * D;
15232- APFloat AD = A * D;
15233- APFloat BC = B * C;
15234- ResR = AC - BD;
15235- ResI = AD + BC;
15236- if (ResR.isNaN() && ResI.isNaN()) {
15237- bool Recalc = false;
15238- if (A.isInfinity() || B.isInfinity()) {
15239- A = APFloat::copySign(
15240- APFloat(A.getSemantics(), A.isInfinity() ? 1 : 0), A);
15241- B = APFloat::copySign(
15242- APFloat(B.getSemantics(), B.isInfinity() ? 1 : 0), B);
15243- if (C.isNaN())
15244- C = APFloat::copySign(APFloat(C.getSemantics()), C);
15245- if (D.isNaN())
15246- D = APFloat::copySign(APFloat(D.getSemantics()), D);
15247- Recalc = true;
15248- }
15249- if (C.isInfinity() || D.isInfinity()) {
15250- C = APFloat::copySign(
15251- APFloat(C.getSemantics(), C.isInfinity() ? 1 : 0), C);
15252- D = APFloat::copySign(
15253- APFloat(D.getSemantics(), D.isInfinity() ? 1 : 0), D);
15254- if (A.isNaN())
15255- A = APFloat::copySign(APFloat(A.getSemantics()), A);
15256- if (B.isNaN())
15257- B = APFloat::copySign(APFloat(B.getSemantics()), B);
15258- Recalc = true;
15259- }
15260- if (!Recalc && (AC.isInfinity() || BD.isInfinity() ||
15261- AD.isInfinity() || BC.isInfinity())) {
15262- if (A.isNaN())
15263- A = APFloat::copySign(APFloat(A.getSemantics()), A);
15264- if (B.isNaN())
15265- B = APFloat::copySign(APFloat(B.getSemantics()), B);
15266- if (C.isNaN())
15267- C = APFloat::copySign(APFloat(C.getSemantics()), C);
15268- if (D.isNaN())
15269- D = APFloat::copySign(APFloat(D.getSemantics()), D);
15270- Recalc = true;
15271- }
15272- if (Recalc) {
15273- ResR = APFloat::getInf(A.getSemantics()) * (A * C - B * D);
15274- ResI = APFloat::getInf(A.getSemantics()) * (A * D + B * C);
15275- }
15276- }
15291+ HandleComplexComplexMul(A, B, C, D, ResR, ResI);
1527715292 }
1527815293 } else {
1527915294 ComplexValue LHS = Result;
0 commit comments