diff --git a/Makefile b/Makefile index e1ca59aa35eb257c0cb24bda1552537f7e364e54..9ba399bd7896b5a8cf2b6bbde0f1d5038c1ed411 100644 --- a/Makefile +++ b/Makefile @@ -317,7 +317,7 @@ DISTRIB_FILES:=\ opam/opam \ # Test files to be included in the distribution (without header checking). -# Plug-ins should use PLUGIN_DISTRIB_TESTS to export their test files. +# Plug-ins should use PLUGIN_DISTRIB_TESTS to export their test files. DISTRIB_TESTS=$(shell git ls-files \ tests \ src/plugins/aorai/tests \ @@ -518,6 +518,7 @@ KERNEL_CMO=\ src/kernel_services/ast_queries/logic_const.cmo \ src/kernel_services/visitors/visitor_behavior.cmo \ src/kernel_services/ast_queries/cil.cmo \ + src/kernel_services/ast_queries/cil_builtins.cmo \ src/kernel_internals/parsing/errorloc.cmo \ src/kernel_services/ast_printing/cil_printer.cmo \ src/kernel_services/ast_printing/cil_descriptive_printer.cmo \ @@ -2375,7 +2376,7 @@ DISTRIB_FILES += $(wildcard $(PLUGIN_DISTRIBUTED_LIST) \ DISTRIB_FILES:=$(filter-out $(GENERATED) $(PLUGIN_GENERATED_LIST),\ $(DISTRIB_FILES)) -DISTRIB_TESTS += $(wildcard $(PLUGIN_DIST_TESTS_LIST)) +DISTRIB_TESTS += $(wildcard $(PLUGIN_DIST_TESTS_LIST)) SPECIFIED_OPEN_SOURCE:=$(OPEN_SOURCE) diff --git a/headers/header_spec.txt b/headers/header_spec.txt index ed8bc97009e08a81c67fdf22e9b27724a2f4a80f..3b8202ed0b9b9aede788497ef1b7e4c9a8f80bb1 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -541,6 +541,8 @@ src/kernel_services/ast_queries/ast_info.ml: CEA_LGPL src/kernel_services/ast_queries/ast_info.mli: CEA_LGPL src/kernel_services/ast_queries/cil.ml: CIL src/kernel_services/ast_queries/cil.mli: CIL +src/kernel_services/ast_queries/cil_builtins.ml: CIL +src/kernel_services/ast_queries/cil_builtins.mli: CIL src/kernel_services/ast_queries/cil_const.ml: CIL src/kernel_services/ast_queries/cil_const.mli: CIL src/kernel_services/ast_queries/cil_datatype.ml: CEA_LGPL diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index 41d52ba50f1fb79a2bc6d155d71a5b7271a14e8f..fd327796b0b2d13459f7fabe0f203da3d65ef50a 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -453,7 +453,6 @@ let typeHasAttributeMemoryBlock a (ty:typ): bool = try visit ty; false with Exit -> true -let typeAddVolatile typ = typeAddAttributes [Attr ("volatile", [])] typ let typeAddGhost typ = if not (typeHasAttribute "ghost" typ) then typeAddAttributes [Attr ("ghost", [])] typ @@ -4862,643 +4861,6 @@ let interpret_character_constant char_list = end let invalidStmt = mkStmt (Instr (Skip Location.unknown)) -module Frama_c_builtins = - State_builder.Hashtbl - (Datatype.String.Hashtbl) - (Cil_datatype.Varinfo) - (struct - let name = "Cil.Frama_c_Builtins" - let dependencies = [] - let size = 3 - end) - -let () = dependency_on_ast Frama_c_builtins.self - -let is_builtin v = hasAttribute "FC_BUILTIN" v.vattr - -let is_unused_builtin v = is_builtin v && not v.vreferenced - - -(* [VP] Should we projectify this ?*) -let special_builtins_table = ref Datatype.String.Set.empty -let special_builtins = Queue.create () - -let is_special_builtin s = - Queue.fold (fun res f -> res || f s) false special_builtins - -let add_special_builtin_family f = Queue.add f special_builtins - -let add_special_builtin s = - special_builtins_table := Datatype.String.Set.add s !special_builtins_table - -let () = add_special_builtin_family - (fun s -> Datatype.String.Set.mem s !special_builtins_table) - -let () = List.iter add_special_builtin - [ "__builtin_stdarg_start"; "__builtin_va_arg"; - "__builtin_va_start"; "__builtin_expect"; "__builtin_next_arg"; ] - -module Builtin_functions = - State_builder.Hashtbl - (Datatype.String.Hashtbl) - (Datatype.Triple(Typ)(Datatype.List(Typ))(Datatype.Bool)) - (struct - let name = "Builtin_functions" - let dependencies = [ TheMachine.self ] - let size = 49 - end) - -(* [add_builtin ?prefix s t l b] adds the function [prefix ^ s] to the list of - built-ins. [t] is the return type and [l] is the list of parameter types. - [b] is true if the built-in is variadic, false otherwise. *) -let add_builtin ?(prefix="__builtin_") s t l b = - Builtin_functions.add (prefix ^ s) (t, l, b) - -let () = registerAttribute "FC_BUILTIN" (AttrName true) - -(* Initialize the builtin functions after the machine has been initialized. *) -let initGccBuiltins () : unit = - (* Complex types are unsupported so the following built-ins can't be added : - - cabs, cabsf, cabsh - - cacos, cacosf, cacosl, cacosh, cacoshf, cacoshl - - carg, cargf, cargl - - casin, casinf, casinl, casinh, casinhf, casinhl - - catan, catanf, catanl, catanh, catanhf, catanhl - - ccos, ccosf, ccosl, ccosh, ccoshf, ccoshl - - cexp, cexpf, cexpl - - cimag, cimagf, cimagl - - clog, clogf, clogl - - conj, conjf, conjl - - cpow, cpowf, cpowl - - cproj, cprojf, cprojl - - creal, crealf, creall - - csin, csinf, csinl, csinh, csinhf, csinhl - - csqrt, csqrtf, csqrtl - - ctan, ctanf, ctanl, ctanh, ctanhf, ctanhl - *) - - (* [wint_t] isn't specified in [theMachine] so the following built-ins that - use this type can't be added : - - iswalnum - - iswalpha - - iswblank - - iswcntrl - - iswdigit - - iswgraph - - iswlower - - iswprint - - iswpunct - - iswspace - - iswupper - - iswxdigit - - towlower - - towupper - *) - - let sizeType = theMachine.upointType in - let add = add_builtin in - add "__fprintf_chk" - intType - (* first argument is really FILE*, not void*, but we don't want to build in - the definition for FILE *) - [ voidPtrType; intType; charConstPtrType ] - true; - add "__memcpy_chk" - voidPtrType - [ voidPtrType; voidConstPtrType; sizeType; sizeType ] - false; - add "__memmove_chk" - voidPtrType [ voidPtrType; voidConstPtrType; sizeType; sizeType ] false; - add "__mempcpy_chk" - voidPtrType [ voidPtrType; voidConstPtrType; sizeType; sizeType ] false; - add "__memset_chk" - voidPtrType [ voidPtrType; intType; sizeType; sizeType ] false; - add "__printf_chk" intType [ intType; charConstPtrType ] true; - add "__snprintf_chk" - intType [ charPtrType; sizeType; intType; sizeType; charConstPtrType ] - true; - add "__sprintf_chk" - intType [ charPtrType; intType; sizeType; charConstPtrType ] true; - add "__stpcpy_chk" - charPtrType [ charPtrType; charConstPtrType; sizeType ] false; - add "__strcat_chk" - charPtrType [ charPtrType; charConstPtrType; sizeType ] false; - add "__strcpy_chk" - charPtrType [ charPtrType; charConstPtrType; sizeType ] false; - add "__strncat_chk" - charPtrType [ charPtrType; charConstPtrType; sizeType; sizeType ] false; - add "__strncpy_chk" - charPtrType [ charPtrType; charConstPtrType; sizeType; sizeType ] false; - add "__vfprintf_chk" - intType - (* first argument is really FILE*, not void*, but we don't want to build in - the definition for FILE *) - [ voidPtrType; intType; charConstPtrType; TBuiltin_va_list [] ] - false; - add "__vprintf_chk" - intType [ intType; charConstPtrType; TBuiltin_va_list [] ] false; - add "__vsnprintf_chk" - intType - [ charPtrType; sizeType; intType; sizeType; charConstPtrType; - TBuiltin_va_list [] ] - false; - add "__vsprintf_chk" - intType - [ charPtrType; intType; sizeType; charConstPtrType; TBuiltin_va_list [] ] - false; - - add "_Exit" voidType [ intType ] false; - add "exit" voidType [ intType ] false; - - add "alloca" voidPtrType [ sizeType ] false; - - add "malloc" voidPtrType [ sizeType ] false; - add "calloc" voidPtrType [ sizeType; sizeType ] false; - add "realloc" voidPtrType [ voidPtrType; sizeType ] false; - add "free" voidType [ voidPtrType ] false; - - add "abs" intType [ intType ] false; - add "labs" longType [ longType ] false; - add "llabs" longLongType [ longLongType] false; - (* Can't add imaxabs because it takes intmax_t as parameter *) - - add "acos" doubleType [ doubleType ] false; - add "acosf" floatType [ floatType ] false; - add "acosl" longDoubleType [ longDoubleType ] false; - add "acosh" doubleType [ doubleType ] false; - add "acoshf" floatType [ floatType ] false; - add "acoshl" longDoubleType [ longDoubleType ] false; - - add "asin" doubleType [ doubleType ] false; - add "asinf" floatType [ floatType ] false; - add "asinl" longDoubleType [ longDoubleType ] false; - add "asinh" doubleType [ doubleType ] false; - add "asinhf" floatType [ floatType ] false; - add "asinhl" longDoubleType [ longDoubleType ] false; - - add "atan" doubleType [ doubleType ] false; - add "atanf" floatType [ floatType ] false; - add "atanl" longDoubleType [ longDoubleType ] false; - add "atanh" doubleType [ doubleType ] false; - add "atanhf" floatType [ floatType ] false; - add "atanhl" longDoubleType [ longDoubleType ] false; - - add "atan2" doubleType [ doubleType; doubleType ] false; - add "atan2f" floatType [ floatType; floatType ] false; - add "atan2l" longDoubleType [ longDoubleType; - longDoubleType ] false; - - let uint16t = uint16_t () in - add "bswap16" uint16t [uint16t] false; - - let uint32t = uint32_t () in - add "bswap32" uint32t [uint32t] false; - - let uint64t = uint64_t () in - add "bswap64" uint64t [uint64t] false; - - add "cbrt" doubleType [ doubleType ] false; - add "cbrtf" floatType [ floatType ] false; - add "cbrtl" longDoubleType [ longDoubleType ] false; - - add "ceil" doubleType [ doubleType ] false; - add "ceilf" floatType [ floatType ] false; - add "ceill" longDoubleType [ longDoubleType ] false; - - add "cos" doubleType [ doubleType ] false; - add "cosf" floatType [ floatType ] false; - add "cosl" longDoubleType [ longDoubleType ] false; - - add "cosh" doubleType [ doubleType ] false; - add "coshf" floatType [ floatType ] false; - add "coshl" longDoubleType [ longDoubleType ] false; - - add "constant_p" intType [ intType ] false; - - add "copysign" doubleType [ doubleType; doubleType ] false; - add "copysignf" floatType [ floatType; floatType ] false; - add "copysignl" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "erfc" doubleType [ doubleType ] false; - add "erfcf" floatType [ floatType ] false; - add "erfcl" longDoubleType [ longDoubleType ] false; - - add "erf" doubleType [ doubleType ] false; - add "erff" floatType [ floatType ] false; - add "erfl" longDoubleType [ longDoubleType ] false; - - add "exp" doubleType [ doubleType ] false; - add "expf" floatType [ floatType ] false; - add "expl" longDoubleType [ longDoubleType ] false; - - add "exp2" doubleType [ doubleType ] false; - add "exp2f" floatType [ floatType ] false; - add "exp2l" longDoubleType [ longDoubleType ] false; - - add "expm1" doubleType [ doubleType ] false; - add "expm1f" floatType [ floatType ] false; - add "expm1l" longDoubleType [ longDoubleType ] false; - - add "expect" longType [ longType; longType ] false; - - add "fabs" doubleType [ doubleType ] false; - add "fabsf" floatType [ floatType ] false; - add "fabsl" longDoubleType [ longDoubleType ] false; - - add "fdim" doubleType [ doubleType; doubleType ] false; - add "fdimf" floatType [ floatType; floatType ] false; - add "fdiml" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "ffs" intType [ uintType ] false; - add "ffsl" intType [ ulongType ] false; - add "ffsll" intType [ ulongLongType ] false; - add "frame_address" voidPtrType [ uintType ] false; - - add "floor" doubleType [ doubleType ] false; - add "floorf" floatType [ floatType ] false; - add "floorl" longDoubleType [ longDoubleType ] false; - - add "fma" doubleType [ doubleType; doubleType; doubleType ] false; - add "fmaf" floatType [ floatType; floatType; floatType ] false; - add "fmal" - longDoubleType [ longDoubleType; longDoubleType; longDoubleType ] false; - - add "fmax" doubleType [ doubleType; doubleType ] false; - add "fmaxf" floatType [ floatType; floatType ] false; - add "fmaxl" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "fmin" doubleType [ doubleType; doubleType ] false; - add "fminf" floatType [ floatType; floatType ] false; - add "fminl" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "huge_val" doubleType [] false; - add "huge_valf" floatType [] false; - add "huge_vall" longDoubleType [] false; - - add "hypot" doubleType [ doubleType; doubleType ] false; - add "hypotf" floatType [ floatType; floatType ] false; - add "hypotl" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "ia32_lfence" voidType [] false; - add "ia32_mfence" voidType [] false; - add "ia32_sfence" voidType [] false; - - add "ilogb" doubleType [ doubleType ] false; - add "ilogbf" floatType [ floatType ] false; - add "ilogbl" longDoubleType [ longDoubleType ] false; - - add "inf" doubleType [] false; - add "inff" floatType [] false; - add "infl" longDoubleType [] false; - - add "isblank" intType [ intType ] false; - add "isalnum" intType [ intType ] false; - add "isalpha" intType [ intType ] false; - add "iscntrl" intType [ intType ] false; - add "isdigit" intType [ intType ] false; - add "isgraph" intType [ intType ] false; - add "islower" intType [ intType ] false; - add "isprint" intType [ intType ] false; - add "ispunct" intType [ intType ] false; - add "isspace" intType [ intType ] false; - add "isupper" intType [ intType ] false; - add "isxdigit" intType [ intType ] false; - - add "fmod" doubleType [ doubleType ] false; - add "fmodf" floatType [ floatType ] false; - add "fmodl" longDoubleType [ longDoubleType ] false; - - add "frexp" doubleType [ doubleType; intPtrType ] false; - add "frexpf" floatType [ floatType; intPtrType ] false; - add "frexpl" longDoubleType [ longDoubleType; intPtrType ] false; - - add "ldexp" doubleType [ doubleType; intType ] false; - add "ldexpf" floatType [ floatType; intType ] false; - add "ldexpl" longDoubleType [ longDoubleType; intType ] false; - - add "lgamma" doubleType [ doubleType ] false; - add "lgammaf" floatType [ floatType ] false; - add "lgammal" longDoubleType [ longDoubleType ] false; - - add "llrint" longLongType [ doubleType ] false; - add "llrintf" longLongType [ floatType ] false; - add "llrintl" longLongType [ longDoubleType ] false; - - add "llround" longLongType [ doubleType ] false; - add "llroundf" longLongType [ floatType ] false; - add "llroundl" longLongType [ longDoubleType ] false; - - add "log" doubleType [ doubleType ] false; - add "logf" floatType [ floatType ] false; - add "logl" longDoubleType [ longDoubleType ] false; - - add "log10" doubleType [ doubleType ] false; - add "log10f" floatType [ floatType ] false; - add "log10l" longDoubleType [ longDoubleType ] false; - - add "log1p" doubleType [ doubleType ] false; - add "log1pf" floatType [ floatType ] false; - add "log1pl" longDoubleType [ longDoubleType ] false; - - add "log2" doubleType [ doubleType ] false; - add "log2f" floatType [ floatType ] false; - add "log2l" longDoubleType [ longDoubleType ] false; - - add "logb" doubleType [ doubleType ] false; - add "logbf" floatType [ floatType ] false; - add "logbl" longDoubleType [ longDoubleType ] false; - - add "lrint" longType [ doubleType ] false; - add "lrintf" longType [ floatType ] false; - add "lrintl" longType [ longDoubleType ] false; - - add "lround" longType [ doubleType ] false; - add "lroundf" longType [ floatType ] false; - add "lroundl" longType [ longDoubleType ] false; - - add "memchr" voidPtrType [ voidConstPtrType; intType; sizeType ] false; - add "memcmp" intType [ voidConstPtrType; voidConstPtrType; sizeType ] false; - add "memcpy" voidPtrType [ voidPtrType; voidConstPtrType; sizeType ] false; - add "mempcpy" voidPtrType [ voidPtrType; voidConstPtrType; sizeType ] false; - add "memset" voidPtrType [ voidPtrType; intType; sizeType ] false; - - add "modf" doubleType [ doubleType; TPtr(doubleType,[]) ] false; - add "modff" floatType [ floatType; TPtr(floatType,[]) ] false; - add "modfl" - longDoubleType [ longDoubleType; TPtr(longDoubleType, []) ] false; - - add "nan" doubleType [ charConstPtrType ] false; - add "nanf" floatType [ charConstPtrType ] false; - add "nanl" longDoubleType [ charConstPtrType ] false; - add "nans" doubleType [ charConstPtrType ] false; - add "nansf" floatType [ charConstPtrType ] false; - add "nansl" longDoubleType [ charConstPtrType ] false; - - add "nearbyint" doubleType [ doubleType ] false; - add "nearbyintf" floatType [ floatType ] false; - add "nearbyintl" longDoubleType [ longDoubleType ] false; - - add "nextafter" doubleType [ doubleType; doubleType ] false; - add "nextafterf" floatType [ floatType; floatType ] false; - add "nextafterl" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "nexttoward" doubleType [ doubleType; longDoubleType ] false; - add "nexttowardf" floatType [ floatType; longDoubleType ] false; - add "nexttowardl" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "object_size" sizeType [ voidPtrType; intType ] false; - - add "parity" intType [ uintType ] false; - add "parityl" intType [ ulongType ] false; - add "parityll" intType [ ulongLongType ] false; - - add "pow" doubleType [ doubleType; doubleType ] false; - add "powf" floatType [ floatType; floatType ] false; - add "powl" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "powi" doubleType [ doubleType; intType ] false; - add "powif" floatType [ floatType; intType ] false; - add "powil" longDoubleType [ longDoubleType; intType ] false; - - add "prefetch" voidType [ voidConstPtrType ] true; - - add "printf" intType [ charConstPtrType ] true; - add "vprintf" intType [ charConstPtrType; TBuiltin_va_list [] ] false; - (* For [fprintf] and [vfprintf] the first argument is really FILE*, not void*, - but we don't want to build in the definition for FILE. *) - add "fprintf" intType [ voidPtrType; charConstPtrType ] true; - add "vfprintf" - intType [ voidPtrType; charConstPtrType; TBuiltin_va_list [] ] false; - add "sprintf" intType [ charPtrType; charConstPtrType ] true; - add "vsprintf" - intType [ charPtrType; charConstPtrType; TBuiltin_va_list [] ] false; - add "snprintf" intType [ charPtrType; sizeType; charConstPtrType ] true; - add "vsnprintf" - intType - [ charPtrType; sizeType; charConstPtrType; TBuiltin_va_list [] ] - false; - - add "putchar" intType [ intType ] false; - - add "puts" intType [ charConstPtrType ] false; - (* The second argument of [fputs] is really FILE*, not void*, but we - don't want to build in the definition for FILE. *) - add "fputs" intType [ charConstPtrType; voidPtrType ] false; - - add "remainder" doubleType [ doubleType; doubleType ] false; - add "remainderf" floatType [ floatType; floatType ] false; - add "remainderl" longDoubleType [ longDoubleType; longDoubleType ] false; - - add "remquo" doubleType [ doubleType; doubleType; intPtrType ] false; - add "remquof" floatType [ floatType; floatType; intPtrType ] false; - add "remquol" - longDoubleType [ longDoubleType; longDoubleType; intPtrType ] false; - - add "return" voidType [ voidConstPtrType ] false; - add "return_address" voidPtrType [ uintType ] false; - - add "rint" doubleType [ doubleType ] false; - add "rintf" floatType [ floatType ] false; - add "rintl" longDoubleType [ longDoubleType ] false; - - add "round" doubleType [ doubleType ] false; - add "roundf" floatType [ floatType ] false; - add "roundl" longDoubleType [ longDoubleType ] false; - - add "scalbln" doubleType [ doubleType; longType ] false; - add "scalblnf" floatType [ floatType; longType ] false; - add "scalblnl" longDoubleType [ longDoubleType; longType ] false; - - add "scalbn" doubleType [ doubleType; intType ] false; - add "scalbnf" floatType [ floatType; intType ] false; - add "scalbnl" longDoubleType [ longDoubleType; intType ] false; - - add "scanf" intType [ charConstPtrType ] true; - add "vscanf" intType [ charConstPtrType; TBuiltin_va_list [] ] false; - (* For [fscanf] and [vfscanf] the first argument is really FILE*, not void*, - but we don't want to build in the definition for FILE. *) - add "fscanf" intType [ voidPtrType; charConstPtrType ] true; - add "vfscanf" - intType [ voidPtrType; charConstPtrType; TBuiltin_va_list [] ] false; - add "sscanf" intType [ charConstPtrType; charConstPtrType ] true; - add "vsscanf" - intType [ charConstPtrType; charConstPtrType; TBuiltin_va_list [] ] false; - - add "sin" doubleType [ doubleType ] false; - add "sinf" floatType [ floatType ] false; - add "sinl" longDoubleType [ longDoubleType ] false; - - add "sinh" doubleType [ doubleType ] false; - add "sinhf" floatType [ floatType ] false; - add "sinhl" longDoubleType [ longDoubleType ] false; - - add "sqrt" doubleType [ doubleType ] false; - add "sqrtf" floatType [ floatType ] false; - add "sqrtl" longDoubleType [ longDoubleType ] false; - - add "stpcpy" charPtrType [ charPtrType; charConstPtrType ] false; - add "strcat" charPtrType [ charPtrType; charConstPtrType ] false; - add "strchr" charPtrType [ charPtrType; intType ] false; - add "strcmp" intType [ charConstPtrType; charConstPtrType ] false; - add "strcpy" charPtrType [ charPtrType; charConstPtrType ] false; - add "strcspn" sizeType [ charConstPtrType; charConstPtrType ] false; - add "strlen" sizeType [ charConstPtrType ] false; - add "strncat" charPtrType [ charPtrType; charConstPtrType; sizeType ] false; - add "strncmp" intType [ charConstPtrType; charConstPtrType; sizeType ] false; - add "strncpy" charPtrType [ charPtrType; charConstPtrType; sizeType ] false; - add "strspn" sizeType [ charConstPtrType; charConstPtrType ] false; - add "strpbrk" charPtrType [ charConstPtrType; charConstPtrType ] false; - add "strrchr" charPtrType [ charConstPtrType; intType ] false; - add "strstr" charPtrType [ charConstPtrType; charConstPtrType ] false; - (* When we parse builtin_types_compatible_p, we change its interface *) - add "types_compatible_p" - intType - [ theMachine.typeOfSizeOf;(* Sizeof the type *) - theMachine.typeOfSizeOf (* Sizeof the type *) ] - false; - add "tan" doubleType [ doubleType ] false; - add "tanf" floatType [ floatType ] false; - add "tanl" longDoubleType [ longDoubleType ] false; - - add "tanh" doubleType [ doubleType ] false; - add "tanhf" floatType [ floatType ] false; - add "tanhl" longDoubleType [ longDoubleType ] false; - - add "tgamma" doubleType [ doubleType ] false; - add "tgammaf" floatType [ floatType ] false; - add "tgammal" longDoubleType [ longDoubleType ] false; - - add "tolower" intType [ intType ] false; - add "toupper" intType [ intType ] false; - - add "trunc" doubleType [ doubleType ] false; - add "truncf" floatType [ floatType ] false; - add "truncl" longDoubleType [ longDoubleType ] false; - - add "unreachable" voidType [ ] false; - - let int8_t = Some scharType in - let int16_t = try Some (int16_t ()) with Not_found -> None in - let int32_t = try Some (int32_t ()) with Not_found -> None in - let int64_t = try Some (int64_t ()) with Not_found -> None in - let uint8_t = Some ucharType in - let uint16_t = try Some (uint16_t ()) with Not_found -> None in - let uint32_t = try Some (uint32_t ()) with Not_found -> None in - let uint64_t = try Some (uint64_t ()) with Not_found -> None in - - (* Binary monomorphic versions of atomic builtins *) - let atomic_instances = - [int8_t, "_int8_t"; - int16_t,"_int16_t"; - int32_t,"_int32_t"; - int64_t,"_int64_t"; - uint8_t, "_uint8_t"; - uint16_t,"_uint16_t"; - uint32_t,"_uint32_t"; - uint64_t,"_uint64_t"] - in - let add_sync (typ,name) f = - match typ with - | Some typ -> - add ~prefix:"__sync_" (f^name) typ [ TPtr(typeAddVolatile typ,[]); typ] true - | None -> () - in - let add_sync f = - List.iter (fun typ -> add_sync typ f) atomic_instances - in - add_sync "fetch_and_add"; - add_sync "fetch_and_sub"; - add_sync "fetch_and_or"; - add_sync "fetch_and_and"; - add_sync "fetch_and_xor"; - add_sync "fetch_and_nand"; - add_sync "add_and_fetch"; - add_sync "sub_and_fetch"; - add_sync "or_and_fetch"; - add_sync "and_and_fetch"; - add_sync "xor_and_fetch"; - add_sync "nand_and_fetch"; - add_sync "lock_test_and_set"; - List.iter (fun (typ,n) -> - match typ with - | Some typ -> - add ~prefix:"" ("__sync_bool_compare_and_swap"^n) - intType - [ TPtr(typeAddVolatile typ,[]); typ ; typ] - true - | None -> ()) - atomic_instances; - List.iter (fun (typ,n) -> - match typ with - | Some typ -> - add ~prefix:"" ("__sync_val_compare_and_swap"^n) - typ - [ TPtr(typeAddVolatile typ,[]); typ ; typ] - true - | None -> ()) - atomic_instances; - List.iter (fun (typ,n) -> - match typ with - | Some typ -> - add ~prefix:"" ("__sync_lock_release"^n) - voidType - [ TPtr(typeAddVolatile typ,[]) ] - true; - | None -> ()) - atomic_instances; - add ~prefix:"" "__sync_synchronize" voidType [] true -;; - -(* Builtins related to va_list. Added to all non-msvc machdeps, because - Cabs2cil supposes they exist. *) -let initVABuiltins () = - let hasbva = theMachine.theMachine.has__builtin_va_list in - let add = add_builtin in - add "next_arg" - (* When we parse builtin_next_arg we drop the second argument *) - (if hasbva then TBuiltin_va_list [] else voidPtrType) [] false; - if hasbva then begin - add "va_end" voidType [ TBuiltin_va_list [] ] false; - add "varargs_start" voidType [ TBuiltin_va_list [] ] false; - (* When we parse builtin_{va,stdarg}_start, we drop the second argument *) - add "va_start" voidType [ TBuiltin_va_list [] ] false; - add "stdarg_start" voidType [ TBuiltin_va_list [] ] false; - (* When we parse builtin_va_arg we change its interface *) - add "va_arg" - voidType - [ TBuiltin_va_list []; - theMachine.typeOfSizeOf;(* Sizeof the type *) - voidPtrType (* Ptr to res *) ] - false; - add "va_copy" voidType [ TBuiltin_va_list []; TBuiltin_va_list [] ] false; - end - -let initMsvcBuiltins () : unit = - (** Take a number of wide string literals *) - Builtin_functions.add "__annotation" (voidType, [ ], true) - -let init_common_builtins () = - add_builtin - "offsetof" - theMachine.typeOfSizeOf - [ theMachine.typeOfSizeOf ] - false - -let init_builtins () = - if not (TheMachine.is_computed ()) then - Kernel.fatal ~current:true "You must call initCIL before init_builtins" ; - if Builtin_functions.length () <> 0 then - Kernel.fatal ~current:true "Cil builtins already initialized." ; - init_common_builtins (); - if msvcMode () then - initMsvcBuiltins () - else begin - initVABuiltins (); - if gccMode () then initGccBuiltins (); - end - -(** This is used as the location of the prototypes of builtin functions. *) -let builtinLoc: location = Location.unknown let range_loc loc1 loc2 = fst loc1, snd loc2 @@ -6865,6 +6227,8 @@ let is_case_label l = match l with | Case _ | Default _ -> true | _ -> false +let init_builtins_ref : (unit -> unit) ref = Extlib.mk_fun "init_builtins_ref" + let initCIL ~initLogicBuiltins machdep = if not (TheMachine.is_computed ()) then begin (* Set the machine *) @@ -6926,7 +6290,7 @@ let initCIL ~initLogicBuiltins machdep = (* projectify theMachine *) copyMachine theMachine !theMachineProject; - init_builtins (); + !init_builtins_ref (); Logic_env.Builtins.extend initLogicBuiltins; diff --git a/src/kernel_services/ast_queries/cil.mli b/src/kernel_services/ast_queries/cil.mli index 60d2376a79df9ff31ac26fa6f68d96753423999d..4b74ee936bb7666e86ea6793117cbd0a11563fe3 100644 --- a/src/kernel_services/ast_queries/cil.mli +++ b/src/kernel_services/ast_queries/cil.mli @@ -51,46 +51,6 @@ open Cil_types open Cil_datatype -(* ************************************************************************* *) -(** {2 Builtins management} *) -(* ************************************************************************* *) - -(** This module associates the name of a built-in function that might be used - during elaboration with the corresponding varinfo. This is done when - parsing ${FRAMAC_SHARE}/libc/__fc_builtins.h, which is always performed - before processing the actual list of files provided on the command line (see - {!File.init_from_c_files}). Actual list of such built-ins is managed in - {!Cabs2cil}. *) -module Frama_c_builtins: - State_builder.Hashtbl with type key = string and type data = Cil_types.varinfo - -val is_builtin: Cil_types.varinfo -> bool -(** @return true if the given variable refers to a Frama-C builtin. - @since Fluorine-20130401 *) - -val is_unused_builtin: Cil_types.varinfo -> bool -(** @return true if the given variable refers to a Frama-C builtin that - is not used in the current program. Plugins may (and in fact should) - hide this builtin from their outputs *) - -val is_special_builtin: string -> bool -(** @return [true] if the given name refers to a special built-in function. - A special built-in function can have any number of arguments. It is up to - the plug-ins to know what to do with it. - @since Carbon-20101201 *) - -(** register a new special built-in function *) -val add_special_builtin: string -> unit - -(** register a new family of special built-in functions. - @since Carbon-20101201 -*) -val add_special_builtin_family: (string -> bool) -> unit - -(** initialize the C built-ins. Should be called once per project, after the - machine has been set. *) -val init_builtins: unit -> unit - (** Call this function to perform some initialization, and only after you have set [Cil.msvcMode]. [initLogicBuiltins] is the function to call to init logic builtins. The [Machdeps] argument is a description of the hardware @@ -266,20 +226,6 @@ val pushGlobal: global -> types: global list ref (** An empty statement. Used in pretty printing *) val invalidStmt: stmt -(** A list of the built-in functions for the current compiler (GCC or - * MSVC, depending on [!msvcMode]). Maps the name to the - * result and argument types, and whether it is vararg. - * Initialized by {!Cil.initCIL} - * - * This map replaces [gccBuiltins] and [msvcBuiltins] in previous - * versions of CIL.*) -module Builtin_functions : - State_builder.Hashtbl with type key = string - and type data = typ * typ list * bool - -(** This is used as the location of the prototypes of builtin functions. *) -val builtinLoc: location - (** Returns a location that ranges over the two locations in arguments. *) val range_loc: location -> location -> location @@ -351,10 +297,34 @@ val ulongType: typ (** unsigned long long *) val ulongLongType: typ +(** Any signed integer type of size 16 bits. + It is equivalent to the ISO C int16_t type but without using the + corresponding header. + Must only be called if such type exists in the current architecture. + @since Frama-C+dev +*) +val int16_t: unit -> typ + +(** Any signed integer type of size 32 bits. + It is equivalent to the ISO C int32_t type but without using the + corresponding header. + Must only be called if such type exists in the current architecture. + @since Frama-C+dev +*) +val int32_t: unit -> typ + +(** Any signed integer type of size 64 bits. + It is equivalent to the ISO C int64_t type but without using the + corresponding header. + Must only be called if such type exists in the current architecture. + @since Frama-C+dev +*) +val int64_t: unit -> typ + (** Any unsigned integer type of size 16 bits. It is equivalent to the ISO C uint16_t type but without using the corresponding header. - Shall not be called if not such type exists in the current architecture. + Must only be called if such type exists in the current architecture. @since Nitrogen-20111001 *) val uint16_t: unit -> typ @@ -362,7 +332,7 @@ val uint16_t: unit -> typ (** Any unsigned integer type of size 32 bits. It is equivalent to the ISO C uint32_t type but without using the corresponding header. - Shall not be called if not such type exists in the current architecture. + Must only be called if such type exists in the current architecture. @since Nitrogen-20111001 *) val uint32_t: unit -> typ @@ -370,7 +340,7 @@ val uint32_t: unit -> typ (** Any unsigned integer type of size 64 bits. It is equivalent to the ISO C uint64_t type but without using the corresponding header. - Shall not be called if no such type exists in the current architecture. + Must only be called if such type exists in the current architecture. @since Nitrogen-20111001 *) val uint64_t: unit -> typ @@ -2354,6 +2324,12 @@ val set_deprecated_extension_handler: (cilVisitor -> acsl_extension_kind -> acsl_extension_kind visitAction) -> unit) -> unit +(* ***********************************************************************) +(** {2 Forward references} *) +(* ***********************************************************************) + +val init_builtins_ref: (unit -> unit) ref + (* Local Variables: compile-command: "make -C ../../.." diff --git a/src/kernel_services/ast_queries/cil_builtins.ml b/src/kernel_services/ast_queries/cil_builtins.ml new file mode 100644 index 0000000000000000000000000000000000000000..94d8a3a62efb9e5a14bcda569a26f697ecf8ad9d --- /dev/null +++ b/src/kernel_services/ast_queries/cil_builtins.ml @@ -0,0 +1,705 @@ +(****************************************************************************) +(* *) +(* Copyright (C) 2001-2003 *) +(* George C. Necula <necula@cs.berkeley.edu> *) +(* Scott McPeak <smcpeak@cs.berkeley.edu> *) +(* Wes Weimer <weimer@cs.berkeley.edu> *) +(* Ben Liblit <liblit@cs.berkeley.edu> *) +(* All rights reserved. *) +(* *) +(* Redistribution and use in source and binary forms, with or without *) +(* modification, are permitted provided that the following conditions *) +(* are met: *) +(* *) +(* 1. Redistributions of source code must retain the above copyright *) +(* notice, this list of conditions and the following disclaimer. *) +(* *) +(* 2. Redistributions in binary form must reproduce the above copyright *) +(* notice, this list of conditions and the following disclaimer in the *) +(* documentation and/or other materials provided with the distribution. *) +(* *) +(* 3. The names of the contributors may not be used to endorse or *) +(* promote products derived from this software without specific prior *) +(* written permission. *) +(* *) +(* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *) +(* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *) +(* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *) +(* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *) +(* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *) +(* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *) +(* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *) +(* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *) +(* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *) +(* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *) +(* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *) +(* POSSIBILITY OF SUCH DAMAGE. *) +(* *) +(* File modified by CEA (Commissariat à l'énergie atomique et aux *) +(* énergies alternatives) *) +(* and INRIA (Institut National de Recherche en Informatique *) +(* et Automatique). *) +(****************************************************************************) + +open Cil_datatype +open Cil_types + +let typeAddVolatile typ = Cil.typeAddAttributes [Attr ("volatile", [])] typ + +module Frama_c_builtins = + State_builder.Hashtbl + (Datatype.String.Hashtbl) + (Cil_datatype.Varinfo) + (struct + let name = "Cil.Frama_c_Builtins" + let dependencies = [] + let size = 3 + end) + +let () = Cil.dependency_on_ast Frama_c_builtins.self + +let is_builtin v = Cil.hasAttribute "FC_BUILTIN" v.vattr + +let is_unused_builtin v = is_builtin v && not v.vreferenced + + +(* [VP] Should we projectify this ?*) +let special_builtins_table = ref Datatype.String.Set.empty +let special_builtins = Queue.create () + +let is_special_builtin s = + Queue.fold (fun res f -> res || f s) false special_builtins + +let add_special_builtin_family f = Queue.add f special_builtins + +let add_special_builtin s = + special_builtins_table := Datatype.String.Set.add s !special_builtins_table + +let () = add_special_builtin_family + (fun s -> Datatype.String.Set.mem s !special_builtins_table) + +let () = List.iter add_special_builtin + [ "__builtin_stdarg_start"; "__builtin_va_arg"; + "__builtin_va_start"; "__builtin_expect"; "__builtin_next_arg"; ] + +module Builtin_functions = + State_builder.Hashtbl + (Datatype.String.Hashtbl) + (Datatype.Triple(Typ)(Datatype.List(Typ))(Datatype.Bool)) + (struct + let name = "Builtin_functions" + let dependencies = [ Cil.selfMachine ] + let size = 49 + end) + +(* [add_builtin ?prefix s t l b] adds the function [prefix ^ s] to the list of + built-ins. [t] is the return type and [l] is the list of parameter types. + [b] is true if the built-in is variadic, false otherwise. *) +let add_builtin ?(prefix="__builtin_") s t l b = + Builtin_functions.add (prefix ^ s) (t, l, b) + +let () = Cil.registerAttribute "FC_BUILTIN" (AttrName true) + +let intType = Cil.intType +let voidPtrType = Cil.voidPtrType +let charConstPtrType = Cil.charConstPtrType +let voidConstPtrType = Cil.voidConstPtrType +let charPtrType = Cil.charPtrType +let voidType = Cil.voidType +let floatType = Cil.floatType +let doubleType = Cil.doubleType +let longDoubleType = Cil.longDoubleType +let longType = Cil.longType +let longLongType = Cil.longLongType +let uintType = Cil.uintType +let ulongType = Cil.ulongType +let ulongLongType = Cil.ulongLongType +let intPtrType = Cil.intPtrType + +(* Initialize the builtin functions after the machine has been initialized. *) +let initGccBuiltins () : unit = + (* Complex types are unsupported so the following built-ins can't be added : + - cabs, cabsf, cabsh + - cacos, cacosf, cacosl, cacosh, cacoshf, cacoshl + - carg, cargf, cargl + - casin, casinf, casinl, casinh, casinhf, casinhl + - catan, catanf, catanl, catanh, catanhf, catanhl + - ccos, ccosf, ccosl, ccosh, ccoshf, ccoshl + - cexp, cexpf, cexpl + - cimag, cimagf, cimagl + - clog, clogf, clogl + - conj, conjf, conjl + - cpow, cpowf, cpowl + - cproj, cprojf, cprojl + - creal, crealf, creall + - csin, csinf, csinl, csinh, csinhf, csinhl + - csqrt, csqrtf, csqrtl + - ctan, ctanf, ctanl, ctanh, ctanhf, ctanhl + *) + + (* [wint_t] isn't specified in [theMachine] so the following built-ins that + use this type can't be added : + - iswalnum + - iswalpha + - iswblank + - iswcntrl + - iswdigit + - iswgraph + - iswlower + - iswprint + - iswpunct + - iswspace + - iswupper + - iswxdigit + - towlower + - towupper + *) + + let sizeType = Cil.theMachine.upointType in + let add = add_builtin in + + add "__fprintf_chk" + intType + (* first argument is really FILE*, not void*, but we don't want to build in + the definition for FILE *) + [ voidPtrType; intType; charConstPtrType ] + true; + add "__memcpy_chk" + voidPtrType + [ voidPtrType; voidConstPtrType; sizeType; sizeType ] + false; + add "__memmove_chk" + voidPtrType [ voidPtrType; voidConstPtrType; sizeType; sizeType ] false; + add "__mempcpy_chk" + voidPtrType [ voidPtrType; voidConstPtrType; sizeType; sizeType ] false; + add "__memset_chk" + voidPtrType [ voidPtrType; intType; sizeType; sizeType ] false; + add "__printf_chk" intType [ intType; charConstPtrType ] true; + add "__snprintf_chk" + intType [ charPtrType; sizeType; intType; sizeType; charConstPtrType ] + true; + add "__sprintf_chk" + intType [ charPtrType; intType; sizeType; charConstPtrType ] true; + add "__stpcpy_chk" + charPtrType [ charPtrType; charConstPtrType; sizeType ] false; + add "__strcat_chk" + charPtrType [ charPtrType; charConstPtrType; sizeType ] false; + add "__strcpy_chk" + charPtrType [ charPtrType; charConstPtrType; sizeType ] false; + add "__strncat_chk" + charPtrType [ charPtrType; charConstPtrType; sizeType; sizeType ] false; + add "__strncpy_chk" + charPtrType [ charPtrType; charConstPtrType; sizeType; sizeType ] false; + add "__vfprintf_chk" + intType + (* first argument is really FILE*, not void*, but we don't want to build in + the definition for FILE *) + [ voidPtrType; intType; charConstPtrType; TBuiltin_va_list [] ] + false; + add "__vprintf_chk" + intType [ intType; charConstPtrType; TBuiltin_va_list [] ] false; + add "__vsnprintf_chk" + intType + [ charPtrType; sizeType; intType; sizeType; charConstPtrType; + TBuiltin_va_list [] ] + false; + add "__vsprintf_chk" + intType + [ charPtrType; intType; sizeType; charConstPtrType; TBuiltin_va_list [] ] + false; + + add "_Exit" voidType [ intType ] false; + add "exit" voidType [ intType ] false; + + add "alloca" voidPtrType [ sizeType ] false; + + add "malloc" voidPtrType [ sizeType ] false; + add "calloc" voidPtrType [ sizeType; sizeType ] false; + add "realloc" voidPtrType [ voidPtrType; sizeType ] false; + add "free" voidType [ voidPtrType ] false; + + add "abs" intType [ intType ] false; + add "labs" longType [ longType ] false; + add "llabs" longLongType [ longLongType] false; + (* Can't add imaxabs because it takes intmax_t as parameter *) + + add "acos" doubleType [ doubleType ] false; + add "acosf" floatType [ floatType ] false; + add "acosl" longDoubleType [ longDoubleType ] false; + add "acosh" doubleType [ doubleType ] false; + add "acoshf" floatType [ floatType ] false; + add "acoshl" longDoubleType [ longDoubleType ] false; + + add "asin" doubleType [ doubleType ] false; + add "asinf" floatType [ floatType ] false; + add "asinl" longDoubleType [ longDoubleType ] false; + add "asinh" doubleType [ doubleType ] false; + add "asinhf" floatType [ floatType ] false; + add "asinhl" longDoubleType [ longDoubleType ] false; + + add "atan" doubleType [ doubleType ] false; + add "atanf" floatType [ floatType ] false; + add "atanl" longDoubleType [ longDoubleType ] false; + add "atanh" doubleType [ doubleType ] false; + add "atanhf" floatType [ floatType ] false; + add "atanhl" longDoubleType [ longDoubleType ] false; + + add "atan2" doubleType [ doubleType; doubleType ] false; + add "atan2f" floatType [ floatType; floatType ] false; + add "atan2l" longDoubleType [ longDoubleType; + longDoubleType ] false; + + let uint16t = Cil.uint16_t () in + add "bswap16" uint16t [uint16t] false; + + let uint32t = Cil.uint32_t () in + add "bswap32" uint32t [uint32t] false; + + let uint64t = Cil.uint64_t () in + add "bswap64" uint64t [uint64t] false; + + add "cbrt" doubleType [ doubleType ] false; + add "cbrtf" floatType [ floatType ] false; + add "cbrtl" longDoubleType [ longDoubleType ] false; + + add "ceil" doubleType [ doubleType ] false; + add "ceilf" floatType [ floatType ] false; + add "ceill" longDoubleType [ longDoubleType ] false; + + add "cos" doubleType [ doubleType ] false; + add "cosf" floatType [ floatType ] false; + add "cosl" longDoubleType [ longDoubleType ] false; + + add "cosh" doubleType [ doubleType ] false; + add "coshf" floatType [ floatType ] false; + add "coshl" longDoubleType [ longDoubleType ] false; + + add "constant_p" intType [ intType ] false; + + add "copysign" doubleType [ doubleType; doubleType ] false; + add "copysignf" floatType [ floatType; floatType ] false; + add "copysignl" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "erfc" doubleType [ doubleType ] false; + add "erfcf" floatType [ floatType ] false; + add "erfcl" longDoubleType [ longDoubleType ] false; + + add "erf" doubleType [ doubleType ] false; + add "erff" floatType [ floatType ] false; + add "erfl" longDoubleType [ longDoubleType ] false; + + add "exp" doubleType [ doubleType ] false; + add "expf" floatType [ floatType ] false; + add "expl" longDoubleType [ longDoubleType ] false; + + add "exp2" doubleType [ doubleType ] false; + add "exp2f" floatType [ floatType ] false; + add "exp2l" longDoubleType [ longDoubleType ] false; + + add "expm1" doubleType [ doubleType ] false; + add "expm1f" floatType [ floatType ] false; + add "expm1l" longDoubleType [ longDoubleType ] false; + + add "expect" longType [ longType; longType ] false; + + add "fabs" doubleType [ doubleType ] false; + add "fabsf" floatType [ floatType ] false; + add "fabsl" longDoubleType [ longDoubleType ] false; + + add "fdim" doubleType [ doubleType; doubleType ] false; + add "fdimf" floatType [ floatType; floatType ] false; + add "fdiml" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "ffs" intType [ uintType ] false; + add "ffsl" intType [ ulongType ] false; + add "ffsll" intType [ ulongLongType ] false; + add "frame_address" voidPtrType [ uintType ] false; + + add "floor" doubleType [ doubleType ] false; + add "floorf" floatType [ floatType ] false; + add "floorl" longDoubleType [ longDoubleType ] false; + + add "fma" doubleType [ doubleType; doubleType; doubleType ] false; + add "fmaf" floatType [ floatType; floatType; floatType ] false; + add "fmal" + longDoubleType [ longDoubleType; longDoubleType; longDoubleType ] false; + + add "fmax" doubleType [ doubleType; doubleType ] false; + add "fmaxf" floatType [ floatType; floatType ] false; + add "fmaxl" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "fmin" doubleType [ doubleType; doubleType ] false; + add "fminf" floatType [ floatType; floatType ] false; + add "fminl" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "huge_val" doubleType [] false; + add "huge_valf" floatType [] false; + add "huge_vall" longDoubleType [] false; + + add "hypot" doubleType [ doubleType; doubleType ] false; + add "hypotf" floatType [ floatType; floatType ] false; + add "hypotl" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "ia32_lfence" voidType [] false; + add "ia32_mfence" voidType [] false; + add "ia32_sfence" voidType [] false; + + add "ilogb" doubleType [ doubleType ] false; + add "ilogbf" floatType [ floatType ] false; + add "ilogbl" longDoubleType [ longDoubleType ] false; + + add "inf" doubleType [] false; + add "inff" floatType [] false; + add "infl" longDoubleType [] false; + + add "isblank" intType [ intType ] false; + add "isalnum" intType [ intType ] false; + add "isalpha" intType [ intType ] false; + add "iscntrl" intType [ intType ] false; + add "isdigit" intType [ intType ] false; + add "isgraph" intType [ intType ] false; + add "islower" intType [ intType ] false; + add "isprint" intType [ intType ] false; + add "ispunct" intType [ intType ] false; + add "isspace" intType [ intType ] false; + add "isupper" intType [ intType ] false; + add "isxdigit" intType [ intType ] false; + + add "fmod" doubleType [ doubleType ] false; + add "fmodf" floatType [ floatType ] false; + add "fmodl" longDoubleType [ longDoubleType ] false; + + add "frexp" doubleType [ doubleType; intPtrType ] false; + add "frexpf" floatType [ floatType; intPtrType ] false; + add "frexpl" longDoubleType [ longDoubleType; intPtrType ] false; + + add "ldexp" doubleType [ doubleType; intType ] false; + add "ldexpf" floatType [ floatType; intType ] false; + add "ldexpl" longDoubleType [ longDoubleType; intType ] false; + + add "lgamma" doubleType [ doubleType ] false; + add "lgammaf" floatType [ floatType ] false; + add "lgammal" longDoubleType [ longDoubleType ] false; + + add "llrint" longLongType [ doubleType ] false; + add "llrintf" longLongType [ floatType ] false; + add "llrintl" longLongType [ longDoubleType ] false; + + add "llround" longLongType [ doubleType ] false; + add "llroundf" longLongType [ floatType ] false; + add "llroundl" longLongType [ longDoubleType ] false; + + add "log" doubleType [ doubleType ] false; + add "logf" floatType [ floatType ] false; + add "logl" longDoubleType [ longDoubleType ] false; + + add "log10" doubleType [ doubleType ] false; + add "log10f" floatType [ floatType ] false; + add "log10l" longDoubleType [ longDoubleType ] false; + + add "log1p" doubleType [ doubleType ] false; + add "log1pf" floatType [ floatType ] false; + add "log1pl" longDoubleType [ longDoubleType ] false; + + add "log2" doubleType [ doubleType ] false; + add "log2f" floatType [ floatType ] false; + add "log2l" longDoubleType [ longDoubleType ] false; + + add "logb" doubleType [ doubleType ] false; + add "logbf" floatType [ floatType ] false; + add "logbl" longDoubleType [ longDoubleType ] false; + + add "lrint" longType [ doubleType ] false; + add "lrintf" longType [ floatType ] false; + add "lrintl" longType [ longDoubleType ] false; + + add "lround" longType [ doubleType ] false; + add "lroundf" longType [ floatType ] false; + add "lroundl" longType [ longDoubleType ] false; + + add "memchr" voidPtrType [ voidConstPtrType; intType; sizeType ] false; + add "memcmp" intType [ voidConstPtrType; voidConstPtrType; sizeType ] false; + add "memcpy" voidPtrType [ voidPtrType; voidConstPtrType; sizeType ] false; + add "mempcpy" voidPtrType [ voidPtrType; voidConstPtrType; sizeType ] false; + add "memset" voidPtrType [ voidPtrType; intType; sizeType ] false; + + add "modf" doubleType [ doubleType; TPtr(doubleType,[]) ] false; + add "modff" floatType [ floatType; TPtr(floatType,[]) ] false; + add "modfl" + longDoubleType [ longDoubleType; TPtr(longDoubleType, []) ] false; + + add "nan" doubleType [ charConstPtrType ] false; + add "nanf" floatType [ charConstPtrType ] false; + add "nanl" longDoubleType [ charConstPtrType ] false; + add "nans" doubleType [ charConstPtrType ] false; + add "nansf" floatType [ charConstPtrType ] false; + add "nansl" longDoubleType [ charConstPtrType ] false; + + add "nearbyint" doubleType [ doubleType ] false; + add "nearbyintf" floatType [ floatType ] false; + add "nearbyintl" longDoubleType [ longDoubleType ] false; + + add "nextafter" doubleType [ doubleType; doubleType ] false; + add "nextafterf" floatType [ floatType; floatType ] false; + add "nextafterl" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "nexttoward" doubleType [ doubleType; longDoubleType ] false; + add "nexttowardf" floatType [ floatType; longDoubleType ] false; + add "nexttowardl" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "object_size" sizeType [ voidPtrType; intType ] false; + + add "parity" intType [ uintType ] false; + add "parityl" intType [ ulongType ] false; + add "parityll" intType [ ulongLongType ] false; + + add "pow" doubleType [ doubleType; doubleType ] false; + add "powf" floatType [ floatType; floatType ] false; + add "powl" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "powi" doubleType [ doubleType; intType ] false; + add "powif" floatType [ floatType; intType ] false; + add "powil" longDoubleType [ longDoubleType; intType ] false; + + add "prefetch" voidType [ voidConstPtrType ] true; + + add "printf" intType [ charConstPtrType ] true; + add "vprintf" intType [ charConstPtrType; TBuiltin_va_list [] ] false; + (* For [fprintf] and [vfprintf] the first argument is really FILE*, not void*, + but we don't want to build in the definition for FILE. *) + add "fprintf" intType [ voidPtrType; charConstPtrType ] true; + add "vfprintf" + intType [ voidPtrType; charConstPtrType; TBuiltin_va_list [] ] false; + add "sprintf" intType [ charPtrType; charConstPtrType ] true; + add "vsprintf" + intType [ charPtrType; charConstPtrType; TBuiltin_va_list [] ] false; + add "snprintf" intType [ charPtrType; sizeType; charConstPtrType ] true; + add "vsnprintf" + intType + [ charPtrType; sizeType; charConstPtrType; TBuiltin_va_list [] ] + false; + + add "putchar" intType [ intType ] false; + + add "puts" intType [ charConstPtrType ] false; + (* The second argument of [fputs] is really FILE*, not void*, but we + don't want to build in the definition for FILE. *) + add "fputs" intType [ charConstPtrType; voidPtrType ] false; + + add "remainder" doubleType [ doubleType; doubleType ] false; + add "remainderf" floatType [ floatType; floatType ] false; + add "remainderl" longDoubleType [ longDoubleType; longDoubleType ] false; + + add "remquo" doubleType [ doubleType; doubleType; intPtrType ] false; + add "remquof" floatType [ floatType; floatType; intPtrType ] false; + add "remquol" + longDoubleType [ longDoubleType; longDoubleType; intPtrType ] false; + + add "return" voidType [ voidConstPtrType ] false; + add "return_address" voidPtrType [ uintType ] false; + + add "rint" doubleType [ doubleType ] false; + add "rintf" floatType [ floatType ] false; + add "rintl" longDoubleType [ longDoubleType ] false; + + add "round" doubleType [ doubleType ] false; + add "roundf" floatType [ floatType ] false; + add "roundl" longDoubleType [ longDoubleType ] false; + + add "scalbln" doubleType [ doubleType; longType ] false; + add "scalblnf" floatType [ floatType; longType ] false; + add "scalblnl" longDoubleType [ longDoubleType; longType ] false; + + add "scalbn" doubleType [ doubleType; intType ] false; + add "scalbnf" floatType [ floatType; intType ] false; + add "scalbnl" longDoubleType [ longDoubleType; intType ] false; + + add "scanf" intType [ charConstPtrType ] true; + add "vscanf" intType [ charConstPtrType; TBuiltin_va_list [] ] false; + (* For [fscanf] and [vfscanf] the first argument is really FILE*, not void*, + but we don't want to build in the definition for FILE. *) + add "fscanf" intType [ voidPtrType; charConstPtrType ] true; + add "vfscanf" + intType [ voidPtrType; charConstPtrType; TBuiltin_va_list [] ] false; + add "sscanf" intType [ charConstPtrType; charConstPtrType ] true; + add "vsscanf" + intType [ charConstPtrType; charConstPtrType; TBuiltin_va_list [] ] false; + + add "sin" doubleType [ doubleType ] false; + add "sinf" floatType [ floatType ] false; + add "sinl" longDoubleType [ longDoubleType ] false; + + add "sinh" doubleType [ doubleType ] false; + add "sinhf" floatType [ floatType ] false; + add "sinhl" longDoubleType [ longDoubleType ] false; + + add "sqrt" doubleType [ doubleType ] false; + add "sqrtf" floatType [ floatType ] false; + add "sqrtl" longDoubleType [ longDoubleType ] false; + + add "stpcpy" charPtrType [ charPtrType; charConstPtrType ] false; + add "strcat" charPtrType [ charPtrType; charConstPtrType ] false; + add "strchr" charPtrType [ charPtrType; intType ] false; + add "strcmp" intType [ charConstPtrType; charConstPtrType ] false; + add "strcpy" charPtrType [ charPtrType; charConstPtrType ] false; + add "strcspn" sizeType [ charConstPtrType; charConstPtrType ] false; + add "strlen" sizeType [ charConstPtrType ] false; + add "strncat" charPtrType [ charPtrType; charConstPtrType; sizeType ] false; + add "strncmp" intType [ charConstPtrType; charConstPtrType; sizeType ] false; + add "strncpy" charPtrType [ charPtrType; charConstPtrType; sizeType ] false; + add "strspn" sizeType [ charConstPtrType; charConstPtrType ] false; + add "strpbrk" charPtrType [ charConstPtrType; charConstPtrType ] false; + add "strrchr" charPtrType [ charConstPtrType; intType ] false; + add "strstr" charPtrType [ charConstPtrType; charConstPtrType ] false; + (* When we parse builtin_types_compatible_p, we change its interface *) + add "types_compatible_p" + intType + [ Cil.theMachine.typeOfSizeOf;(* Sizeof the type *) + Cil.theMachine.typeOfSizeOf (* Sizeof the type *) ] + false; + add "tan" doubleType [ doubleType ] false; + add "tanf" floatType [ floatType ] false; + add "tanl" longDoubleType [ longDoubleType ] false; + + add "tanh" doubleType [ doubleType ] false; + add "tanhf" floatType [ floatType ] false; + add "tanhl" longDoubleType [ longDoubleType ] false; + + add "tgamma" doubleType [ doubleType ] false; + add "tgammaf" floatType [ floatType ] false; + add "tgammal" longDoubleType [ longDoubleType ] false; + + add "tolower" intType [ intType ] false; + add "toupper" intType [ intType ] false; + + add "trunc" doubleType [ doubleType ] false; + add "truncf" floatType [ floatType ] false; + add "truncl" longDoubleType [ longDoubleType ] false; + + add "unreachable" voidType [ ] false; + + let int8_t = Some Cil.scharType in + let int16_t = try Some (Cil.int16_t ()) with Not_found -> None in + let int32_t = try Some (Cil.int32_t ()) with Not_found -> None in + let int64_t = try Some (Cil.int64_t ()) with Not_found -> None in + let uint8_t = Some Cil.ucharType in + let uint16_t = try Some (Cil.uint16_t ()) with Not_found -> None in + let uint32_t = try Some (Cil.uint32_t ()) with Not_found -> None in + let uint64_t = try Some (Cil.uint64_t ()) with Not_found -> None in + + (* Binary monomorphic versions of atomic builtins *) + let atomic_instances = + [int8_t, "_int8_t"; + int16_t,"_int16_t"; + int32_t,"_int32_t"; + int64_t,"_int64_t"; + uint8_t, "_uint8_t"; + uint16_t,"_uint16_t"; + uint32_t,"_uint32_t"; + uint64_t,"_uint64_t"] + in + let add_sync (typ,name) f = + match typ with + | Some typ -> + add ~prefix:"__sync_" (f^name) typ [ TPtr(typeAddVolatile typ,[]); typ] true + | None -> () + in + let add_sync f = + List.iter (fun typ -> add_sync typ f) atomic_instances + in + add_sync "fetch_and_add"; + add_sync "fetch_and_sub"; + add_sync "fetch_and_or"; + add_sync "fetch_and_and"; + add_sync "fetch_and_xor"; + add_sync "fetch_and_nand"; + add_sync "add_and_fetch"; + add_sync "sub_and_fetch"; + add_sync "or_and_fetch"; + add_sync "and_and_fetch"; + add_sync "xor_and_fetch"; + add_sync "nand_and_fetch"; + add_sync "lock_test_and_set"; + List.iter (fun (typ,n) -> + match typ with + | Some typ -> + add ~prefix:"" ("__sync_bool_compare_and_swap"^n) + intType + [ TPtr(typeAddVolatile typ,[]); typ ; typ] + true + | None -> ()) + atomic_instances; + List.iter (fun (typ,n) -> + match typ with + | Some typ -> + add ~prefix:"" ("__sync_val_compare_and_swap"^n) + typ + [ TPtr(typeAddVolatile typ,[]); typ ; typ] + true + | None -> ()) + atomic_instances; + List.iter (fun (typ,n) -> + match typ with + | Some typ -> + add ~prefix:"" ("__sync_lock_release"^n) + voidType + [ TPtr(typeAddVolatile typ,[]) ] + true; + | None -> ()) + atomic_instances; + add ~prefix:"" "__sync_synchronize" voidType [] true +;; + +(* Builtins related to va_list. Added to all non-msvc machdeps, because + Cabs2cil supposes they exist. *) +let initVABuiltins () = + let hasbva = Cil.theMachine.theMachine.has__builtin_va_list in + let add = add_builtin in + add "next_arg" + (* When we parse builtin_next_arg we drop the second argument *) + (if hasbva then TBuiltin_va_list [] else voidPtrType) [] false; + if hasbva then begin + add "va_end" voidType [ TBuiltin_va_list [] ] false; + add "varargs_start" voidType [ TBuiltin_va_list [] ] false; + (* When we parse builtin_{va,stdarg}_start, we drop the second argument *) + add "va_start" voidType [ TBuiltin_va_list [] ] false; + add "stdarg_start" voidType [ TBuiltin_va_list [] ] false; + (* When we parse builtin_va_arg we change its interface *) + add "va_arg" + voidType + [ TBuiltin_va_list []; + Cil.theMachine.typeOfSizeOf;(* Sizeof the type *) + voidPtrType (* Ptr to res *) ] + false; + add "va_copy" voidType [ TBuiltin_va_list []; TBuiltin_va_list [] ] false; + end + +let initMsvcBuiltins () : unit = + (** Take a number of wide string literals *) + Builtin_functions.add "__annotation" (voidType, [ ], true) + +let init_common_builtins () = + add_builtin + "offsetof" + Cil.theMachine.typeOfSizeOf + [ Cil.theMachine.typeOfSizeOf ] + false + +let init_builtins () = + if not (Cil.selfMachine_is_computed ()) then + Kernel.fatal ~current:true "You must call initCIL before init_builtins" ; + if Builtin_functions.length () <> 0 then + Kernel.fatal ~current:true "Cil builtins already initialized." ; + init_common_builtins (); + if Cil.msvcMode () then + initMsvcBuiltins () + else begin + initVABuiltins (); + if Cil.gccMode () then initGccBuiltins (); + end + +(** This is used as the location of the prototypes of builtin functions. *) +let builtinLoc: location = Location.unknown + +let () = + Cil.init_builtins_ref := init_builtins diff --git a/src/kernel_services/ast_queries/cil_builtins.mli b/src/kernel_services/ast_queries/cil_builtins.mli new file mode 100644 index 0000000000000000000000000000000000000000..adb9caf1eb57e165b9e9ba0d56d9bf8e9dce3670 --- /dev/null +++ b/src/kernel_services/ast_queries/cil_builtins.mli @@ -0,0 +1,98 @@ +(****************************************************************************) +(* *) +(* Copyright (C) 2001-2003 *) +(* George C. Necula <necula@cs.berkeley.edu> *) +(* Scott McPeak <smcpeak@cs.berkeley.edu> *) +(* Wes Weimer <weimer@cs.berkeley.edu> *) +(* Ben Liblit <liblit@cs.berkeley.edu> *) +(* All rights reserved. *) +(* *) +(* Redistribution and use in source and binary forms, with or without *) +(* modification, are permitted provided that the following conditions *) +(* are met: *) +(* *) +(* 1. Redistributions of source code must retain the above copyright *) +(* notice, this list of conditions and the following disclaimer. *) +(* *) +(* 2. Redistributions in binary form must reproduce the above copyright *) +(* notice, this list of conditions and the following disclaimer in the *) +(* documentation and/or other materials provided with the distribution. *) +(* *) +(* 3. The names of the contributors may not be used to endorse or *) +(* promote products derived from this software without specific prior *) +(* written permission. *) +(* *) +(* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *) +(* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *) +(* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *) +(* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *) +(* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *) +(* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *) +(* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *) +(* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *) +(* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *) +(* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *) +(* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *) +(* POSSIBILITY OF SUCH DAMAGE. *) +(* *) +(* File modified by CEA (Commissariat à l'énergie atomique et aux *) +(* énergies alternatives) *) +(* and INRIA (Institut National de Recherche en Informatique *) +(* et Automatique). *) +(****************************************************************************) + +open Cil_types + +(* ************************************************************************* *) +(** {2 Builtins management} *) +(* ************************************************************************* *) + +(** This module associates the name of a built-in function that might be used + during elaboration with the corresponding varinfo. This is done when + parsing ${FRAMAC_SHARE}/libc/__fc_builtins.h, which is always performed + before processing the actual list of files provided on the command line (see + {!File.init_from_c_files}). Actual list of such built-ins is managed in + {!Cabs2cil}. *) +module Frama_c_builtins: + State_builder.Hashtbl with type key = string and type data = varinfo + +val is_builtin: varinfo -> bool +(** @return true if the given variable refers to a Frama-C builtin. + @since Fluorine-20130401 *) + +val is_unused_builtin: varinfo -> bool +(** @return true if the given variable refers to a Frama-C builtin that + is not used in the current program. Plugins may (and in fact should) + hide this builtin from their outputs *) + +val is_special_builtin: string -> bool +(** @return [true] if the given name refers to a special built-in function. + A special built-in function can have any number of arguments. It is up to + the plug-ins to know what to do with it. + @since Carbon-20101201 *) + +(** register a new special built-in function *) +val add_special_builtin: string -> unit + +(** register a new family of special built-in functions. + @since Carbon-20101201 +*) +val add_special_builtin_family: (string -> bool) -> unit + +(** initialize the C built-ins. Should be called once per project, after the + machine has been set. *) +val init_builtins: unit -> unit + +(** A list of the built-in functions for the current compiler (GCC or + * MSVC, depending on [!msvcMode]). Maps the name to the + * result and argument types, and whether it is vararg. + * Initialized by {!Cil.initCIL} + * + * This map replaces [gccBuiltins] and [msvcBuiltins] in previous + * versions of CIL.*) +module Builtin_functions : + State_builder.Hashtbl with type key = string + and type data = typ * typ list * bool + +(** This is used as the location of the prototypes of builtin functions. *) +val builtinLoc: location