@@ -2567,6 +2567,54 @@ exprt c_typecheck_baset::do_special_functions(
25672567
25682568 return std::move (abs_expr);
25692569 }
2570+ else if (
2571+ identifier == CPROVER_PREFIX " fmod" ||
2572+ identifier == CPROVER_PREFIX " fmodf" ||
2573+ identifier == CPROVER_PREFIX " fmodl" )
2574+ {
2575+ if (expr.arguments ().size () != 2 )
2576+ {
2577+ error ().source_location = f_op.source_location ();
2578+ error () << " fmod-functions expect two operands" << eom;
2579+ throw 0 ;
2580+ }
2581+
2582+ typecheck_function_call_arguments (expr);
2583+
2584+ // Note that the semantics differ from the
2585+ // "floating point remainder" operation as defined by IEEE.
2586+ // Note that these do not take a rounding mode.
2587+ binary_exprt fmod_expr (
2588+ expr.arguments ()[0 ], ID_floatbv_mod, expr.arguments ()[1 ]);
2589+
2590+ fmod_expr.add_source_location () = source_location;
2591+
2592+ return std::move (fmod_expr);
2593+ }
2594+ else if (
2595+ identifier == CPROVER_PREFIX " remainder" ||
2596+ identifier == CPROVER_PREFIX " remainderf" ||
2597+ identifier == CPROVER_PREFIX " remainderl" )
2598+ {
2599+ if (expr.arguments ().size () != 2 )
2600+ {
2601+ error ().source_location = f_op.source_location ();
2602+ error () << " remainder-functions expect two operands" << eom;
2603+ throw 0 ;
2604+ }
2605+
2606+ typecheck_function_call_arguments (expr);
2607+
2608+ // The semantics of these functions is meant to match the
2609+ // "floating point remainder" operation as defined by IEEE.
2610+ // Note that these do not take a rounding mode.
2611+ binary_exprt floatbv_rem_expr (
2612+ expr.arguments ()[0 ], ID_floatbv_rem, expr.arguments ()[1 ]);
2613+
2614+ floatbv_rem_expr.add_source_location () = source_location;
2615+
2616+ return std::move (floatbv_rem_expr);
2617+ }
25702618 else if (identifier==CPROVER_PREFIX " allocate" )
25712619 {
25722620 if (expr.arguments ().size ()!=2 )
0 commit comments