1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192(**************************************************************************)(* *)(* This file is part of Frama-C. *)(* *)(* Copyright (C) 2007-2023 *)(* CEA (Commissariat à l'énergie atomique et aux énergies *)(* alternatives) *)(* *)(* you can redistribute it and/or modify it under the terms of the GNU *)(* Lesser General Public License as published by the Free Software *)(* Foundation, version 2.1. *)(* *)(* It is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)(* GNU Lesser General Public License for more details. *)(* *)(* See the GNU Lesser General Public License version 2.1 *)(* for more details (enclosed in the file licenses/LGPLv2.1). *)(* *)(**************************************************************************)openDive_typestypet=node_rangeletfkind_limits=letmax_single=float_of_string"0x1.fffffep+127"andmax_double=float_of_string"0x1.fffffffffffffp+1023"infunction|Cil_types.FFloat->max_single|FDouble|FLongDouble->max_doubleletikind_limitsikind=letopenCilinletbits=bitsSizeOfIntikindinifisSignedikindthen(min_signed_numberbits,max_signed_numberbits)else(Integer.zero,max_unsigned_numberbits)letlogscalexlimit=Float.(to_int(min100.(100.*.log(maxx1.)/.loglimit)))letlog2scalexlimit=assert(x>0.);assert(limit>0.);Float.(logscale(logx)(loglimit))letcardinal_rangecardinallimit=lets=log2scale(Integer.to_floatcardinal)(Integer.to_floatlimit)inifs>98thenWideelseNormalsletinteger_rangecardinalikind=let_,limit=ikind_limitsikindincardinal_rangecardinallimitletfloat_rangefkindlu=letlimit=fkind_limitsfkindandl=Fval.F.to_floatlandu=Fval.F.to_floatuinletrange=if(l<0.0)=(u<0.0)then(* if bounds have same sign *)u-.lelseFloat.(max(absu)(absl))inlets=log2scalerangelimitinifs>98thenWideelseNormalsletevaluatecvaluetyp=letcardinal=Cvalue.V.cardinalcvalueinmatchtyp,cardinalwith|_,SomecardwhenInteger.is_zerocard->Empty|_,SomecardwhenInteger.is_onecard->Singleton|Cil_types.TInt(ikind,_),Somecardinal->integer_rangecardinalikind|Cil_types.TFloat(fkind,_),_->beginmatchIval.min_and_max_float(Cvalue.V.project_ivalcvalue)with|Some(l,u),_can_be_nan->float_rangefkindlu|_,_->Wide|exceptionCvalue.V.Not_based_on_null->Wide|exceptionAbstract_interp.Error_Bottom->Emptyend|_,Somecardinal->cardinal_rangecardinal(Integer.of_int100)(* arbitrary limit for pointers *)|_,None->Wideletupper_boundr1r2=matchr1,r2with|Empty,r|r,Empty->r|Singleton,r|r,Singleton->r|Normali1,Normali2->Normal(maxi1i2)|Wide,_|_,Wide->Wide