@@ -2255,7 +2255,7 @@ exprt c_typecheck_baset::do_special_functions(
2255
2255
isnan_exprt isnan_expr (expr.arguments ().front ());
2256
2256
isnan_expr.add_source_location ()=source_location;
2257
2257
2258
- return isnan_expr;
2258
+ return typecast_exprt::conditional_cast ( isnan_expr, expr. type ()) ;
2259
2259
}
2260
2260
else if (identifier==CPROVER_PREFIX " isfinitef" ||
2261
2261
identifier==CPROVER_PREFIX " isfinited" ||
@@ -2271,7 +2271,7 @@ exprt c_typecheck_baset::do_special_functions(
2271
2271
isfinite_exprt isfinite_expr (expr.arguments ().front ());
2272
2272
isfinite_expr.add_source_location ()=source_location;
2273
2273
2274
- return isfinite_expr;
2274
+ return typecast_exprt::conditional_cast ( isfinite_expr, expr. type ()) ;
2275
2275
}
2276
2276
else if (identifier==CPROVER_PREFIX " inf" ||
2277
2277
identifier==" __builtin_inf" )
@@ -2343,30 +2343,64 @@ exprt c_typecheck_baset::do_special_functions(
2343
2343
if (expr.arguments ().size ()!=1 )
2344
2344
{
2345
2345
err_location (f_op);
2346
- error () << " isinf expects one operand" << eom;
2346
+ error () << identifier << " expects one operand" << eom;
2347
2347
throw 0 ;
2348
2348
}
2349
2349
2350
2350
isinf_exprt isinf_expr (expr.arguments ().front ());
2351
2351
isinf_expr.add_source_location ()=source_location;
2352
2352
2353
- return isinf_expr;
2353
+ return typecast_exprt::conditional_cast (isinf_expr, expr.type ());
2354
+ }
2355
+ else if (identifier == " __builtin_isinf_sign" )
2356
+ {
2357
+ if (expr.arguments ().size () != 1 )
2358
+ {
2359
+ err_location (f_op);
2360
+ error () << identifier << " expects one operand" << eom;
2361
+ throw 0 ;
2362
+ }
2363
+
2364
+ // returns 1 for +inf and -1 for -inf, and 0 otherwise
2365
+
2366
+ const exprt &fp_value = expr.arguments ().front ();
2367
+
2368
+ isinf_exprt isinf_expr (fp_value);
2369
+ isinf_expr.add_source_location () = source_location;
2370
+
2371
+ return if_exprt (
2372
+ isinf_exprt (fp_value),
2373
+ if_exprt (
2374
+ sign_exprt (fp_value),
2375
+ from_integer (-1 , expr.type ()),
2376
+ from_integer (1 , expr.type ())),
2377
+ from_integer (0 , expr.type ()));
2354
2378
}
2355
- else if (identifier==CPROVER_PREFIX " isnormalf" ||
2356
- identifier==CPROVER_PREFIX " isnormald" ||
2357
- identifier==CPROVER_PREFIX " isnormalld" )
2379
+ else if (identifier == CPROVER_PREFIX " isnormalf" ||
2380
+ identifier == CPROVER_PREFIX " isnormald" ||
2381
+ identifier == CPROVER_PREFIX " isnormalld" ||
2382
+ identifier == " __builtin_isnormal" )
2358
2383
{
2359
2384
if (expr.arguments ().size ()!=1 )
2360
2385
{
2361
2386
err_location (f_op);
2362
- error () << " isnormal expects one operand" << eom;
2387
+ error () << identifier << " expects one operand" << eom;
2388
+ throw 0 ;
2389
+ }
2390
+
2391
+ const exprt &fp_value = expr.arguments ()[0 ];
2392
+
2393
+ if (fp_value.type ().id () != ID_floatbv)
2394
+ {
2395
+ err_location (fp_value);
2396
+ error () << " non-floating-point argument for " << identifier << eom;
2363
2397
throw 0 ;
2364
2398
}
2365
2399
2366
2400
isnormal_exprt isnormal_expr (expr.arguments ().front ());
2367
2401
isnormal_expr.add_source_location ()=source_location;
2368
2402
2369
- return isnormal_expr;
2403
+ return typecast_exprt::conditional_cast ( isnormal_expr, expr. type ()) ;
2370
2404
}
2371
2405
else if (identifier==CPROVER_PREFIX " signf" ||
2372
2406
identifier==CPROVER_PREFIX " signd" ||
@@ -2378,14 +2412,14 @@ exprt c_typecheck_baset::do_special_functions(
2378
2412
if (expr.arguments ().size ()!=1 )
2379
2413
{
2380
2414
err_location (f_op);
2381
- error () << " sign expects one operand" << eom;
2415
+ error () << identifier << " expects one operand" << eom;
2382
2416
throw 0 ;
2383
2417
}
2384
2418
2385
2419
sign_exprt sign_expr (expr.arguments ().front ());
2386
2420
sign_expr.add_source_location ()=source_location;
2387
2421
2388
- return sign_expr;
2422
+ return typecast_exprt::conditional_cast ( sign_expr, expr. type ()) ;
2389
2423
}
2390
2424
else if (identifier==" __builtin_popcount" ||
2391
2425
identifier==" __builtin_popcountl" ||
0 commit comments