Repository: FreeCAD/FreeCAD
File: src/Mod/Part/App/AttachExtension.cpp (C++)

Code before:
            }
            else if (oid == oidY) {
                exprY = expr;
            }
            else if (oid == oidYaw) {
                exprYaw = expr;
            }
        }

        // convert placement and expressions according to the dominant axis
        auto makeRotatedExpression =
            [owner](const App::Expression* expr, double angle) -> App::Expression* {
            if (!expr) {
                return nullptr;
            }

            std::string s = "(" + expr->toString() + ")";
            if (angle >= 0) {
                s += " + " + std::to_string(angle);
            }
            else {
                s += " - " + std::to_string(-angle);
            }

            if (const App::Expression* simple = expr->eval()) {
                if (auto ue = dynamic_cast<const App::UnitExpression*>(simple)) {
                    const auto& q = ue->getQuantity();
                    if (q.getUnit() == Base::Unit::Angle) {
                        s += " deg";
                    }
                }
            }

            return App::ExpressionParser::parse(owner, s.c_str());
        };
        App::Expression* newExprX = nullptr;
        App::Expression* newExprY = nullptr;
        App::Expression* newExprYaw = nullptr;
        if (axis == 0) {  // normal mostly X
            // values
            std::swap(position.x, position.y);
            position.x = -position.x;
            rotation.setYawPitchRoll(yaw + 90, pitch, roll);

            // expressions
            if (exprX) {
                newExprY = App::ExpressionParser::parse(owner, exprX->toString().c_str());
            }
            if (exprY) {
                std::string expr = "-1 * (" + exprY->toString() + ")";
                newExprX = App::ExpressionParser::parse(owner, expr.c_str());

Review comment (suggestion):
In cases where you're casting FreeCAD's types, use `freecad_cast` instead of `dynamic_cast`.

Code after:
            }
            else if (oid == oidY) {
                exprY = expr;
            }
            else if (oid == oidYaw) {
                exprYaw = expr;
            }
        }

        // convert placement and expressions according to the dominant axis
        auto makeRotatedExpression =
            [owner](const App::Expression* expr, double angle) -> App::Expression* {
            if (!expr) {
                return nullptr;
            }

            std::string unitSafeExprStr = "(" + expr->toString() + ")";
            if (angle >= 0) {
                unitSafeExprStr += " + " + std::to_string(angle);
            }
            else {
                unitSafeExprStr += " - " + std::to_string(-angle);
            }

            if (const App::Expression* simple = expr->eval()) {
                if (auto ue = dynamic_cast<const App::UnitExpression*>(simple)) {
                    const auto& q = ue->getQuantity();
                    if (q.getUnit() == Base::Unit::Angle) {
                        unitSafeExprStr += " deg";
                    }
                }
            }

            return App::ExpressionParser::parse(owner, unitSafeExprStr.c_str());
        };
        App::Expression* newExprX = nullptr;
        App::Expression* newExprY = nullptr;
        App::Expression* newExprYaw = nullptr;
        if (axis == 0) {  // normal mostly X
            // values
            std::swap(position.x, position.y);
            position.x = -position.x;
            rotation.setYawPitchRoll(yaw + 90, pitch, roll);

            // expressions
            if (exprX) {
                newExprY = App::ExpressionParser::parse(owner, exprX->toString().c_str());
            }
            if (exprY) {
                std::string expr = "-1 * (" + exprY->toString() + ")";
                newExprX = App::ExpressionParser::parse(owner, expr.c_str());