diff --git a/Makefile b/Makefile index c54f39e399b32a633f7813b61110e81211f1ad1e..c4185f9379adc3ba190abf24083fada13956da0a 100644 --- a/Makefile +++ b/Makefile @@ -291,6 +291,8 @@ DISTRIB_FILES:=\ share/_frama-c \ share/compliance/c11_functions.json \ share/compliance/c11_headers.json \ + share/compliance/compiler_builtins.json \ + share/compliance/gcc_builtins.json \ share/compliance/glibc_functions.json \ share/compliance/nonstandard_identifiers.json \ share/compliance/posix_identifiers.json \ @@ -2007,6 +2009,8 @@ install:: install-lib-$(OCAMLBEST) $(MKDIR) $(FRAMAC_DATADIR)/compliance $(CP) share/compliance/c11_functions.json \ share/compliance/c11_headers.json \ + share/compliance/compiler_builtins.json \ + share/compliance/gcc_builtins.json \ share/compliance/glibc_functions.json \ share/compliance/nonstandard_identifiers.json \ share/compliance/posix_identifiers.json \ diff --git a/headers/header_spec.txt b/headers/header_spec.txt index 3c013f74b22470bbbd8b35de055ce034a8b8f281..75a8014972c92d933188bcb17480f0c050a7ab7f 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -148,6 +148,8 @@ share/analysis-scripts/summary.py: CEA_LGPL share/analysis-scripts/template.mk: .ignore share/compliance/c11_functions.json: .ignore share/compliance/c11_headers.json: .ignore +share/compliance/compiler_builtins.json: .ignore +share/compliance/gcc_builtins.json: .ignore share/compliance/glibc_functions.json: .ignore share/compliance/nonstandard_identifiers.json: .ignore share/compliance/posix_identifiers.json: .ignore diff --git a/share/compliance/compiler_builtins.json b/share/compliance/compiler_builtins.json new file mode 100644 index 0000000000000000000000000000000000000000..165d82ddd38486cf81fa435d8f0115223ae8cc6c --- /dev/null +++ b/share/compliance/compiler_builtins.json @@ -0,0 +1,57 @@ +{ + "description":"Compiler builtins supported by Frama-C (for GCC builtins, see gcc_builtins.json)", + "notes": { + "compiler":"When present, indicates this builtin is only available in Frama-C machdeps with this compiler. Allowed values: msvc, !msvc (the latter meaning: 'available in machdeps with compilers other than MSVC').", + "rettype":"Return type of the builtin. Whitespace is important: types are matched as exact strings, with a single space between components.", + "args":"List of the types of the builtin arguments. Whitespace is important: types are matched as exact strings, with a single space between components.", + "variadic":"When present, this builtin behaves as a variadic function.", + "_comment": "Adding new types to fields 'rettype' or 'args' requires updating the list of recognized types in 'src/kernel_services/ast_queries/cil_builtins.ml'." + }, + "data":{ + "__builtin__annotation": { + "compiler":"msvc", + "rettype":"void", + "args": [], + "variadic":true + }, + "__builtin_next_arg": { + "compiler":"!msvc", + "rettype":"__builtin_va_list", + "args": [] + }, + "__builtin_offsetof": { + "rettype":"size_t", + "args": ["size_t"] + }, + "__builtin_stdarg_start": { + "compiler":"!msvc", + "rettype":"void", + "args": ["__builtin_va_list"] + }, + "__builtin_va_arg": { + "compiler":"!msvc", + "rettype":"void", + "args": ["__builtin_va_list","size_t","void *"] + }, + "__builtin_va_copy": { + "compiler":"!msvc", + "rettype":"void", + "args": ["__builtin_va_list","__builtin_va_list"] + }, + "__builtin_va_end": { + "compiler":"!msvc", + "rettype":"void", + "args": ["__builtin_va_list"] + }, + "__builtin_va_start": { + "compiler":"!msvc", + "rettype":"void", + "args": ["__builtin_va_list"] + }, + "__builtin_varargs_start": { + "compiler":"!msvc", + "rettype":"void", + "args": ["__builtin_va_list"] + } + } +} diff --git a/share/compliance/gcc_builtins.json b/share/compliance/gcc_builtins.json new file mode 100644 index 0000000000000000000000000000000000000000..9e240b0ab214c0592e667880d6fa06ba64dcc252 --- /dev/null +++ b/share/compliance/gcc_builtins.json @@ -0,0 +1,1336 @@ +{ + "description":"GCC builtins supported by Frama-C", + "source":"Mostly https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html, from pages with 'Builtins' in their title", + "notes": { + "rettype":"Return type of the builtin. Whitespace is important: types are matched as exact strings, with a single space between components.", + "args":"List of the types of the builtin arguments. Whitespace is important: types are matched as exact strings, with a single space between components. The full list of 'known' type names is available in cil_builtins.ml.", + "types":"When present, a list indicating that this is a builtin template, to be instantiated for each type in the list. Instantiation is the replacement of each occurrence of 'type' in 'rettype' and 'args' with the elements of this list.", + "variadic":"When present, this builtin behaves as a variadic function.", + "_comment": [ + "Complex types are unsupported, so the following builtins cannot 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", + "Also, the type 'wint_t' is not specified in 'theMachine', so the following builtins that use it cannot be added:", + "iswalnum", + "iswalpha", + "iswblank", + "iswcntrl", + "iswdigit", + "iswgraph", + "iswlower", + "iswprint", + "iswpunct", + "iswspace", + "iswupper", + "iswxdigit", + "towlower", + "towupper" + ] + }, + "data":{ + "__builtin__Exit": { + "rettype":"void", + "args": ["int"] + }, + "__builtin___fprintf_chk": { + "rettype":"int", + "args": ["void *","int","char const *"], + "variadic":true + }, + "__builtin___memcpy_chk": { + "rettype":"void *", + "args": ["void *","void const *","size_t","size_t"] + }, + "__builtin___memmove_chk": { + "rettype":"void *", + "args": ["void *","void const *","size_t","size_t"] + }, + "__builtin___mempcpy_chk": { + "rettype":"void *", + "args": ["void *","void const *","size_t","size_t"] + }, + "__builtin___memset_chk": { + "rettype":"void *", + "args": ["void *","int","size_t","size_t"] + }, + "__builtin___printf_chk": { + "rettype":"int", + "args": ["int","char const *"], + "variadic":true + }, + "__builtin___snprintf_chk": { + "rettype":"int", + "args": ["char *","size_t","int","size_t","char const *"], + "variadic":true + }, + "__builtin___sprintf_chk": { + "rettype":"int", + "args": ["char *","int","size_t","char const *"], + "variadic":true + }, + "__builtin___stpcpy_chk": { + "rettype":"char *", + "args": ["char *","char const *","size_t"] + }, + "__builtin___strcat_chk": { + "rettype":"char *", + "args": ["char *","char const *","size_t"] + }, + "__builtin___strcpy_chk": { + "rettype":"char *", + "args": ["char *","char const *","size_t"] + }, + "__builtin___strncat_chk": { + "rettype":"char *", + "args": ["char *","char const *","size_t","size_t"] + }, + "__builtin___strncpy_chk": { + "rettype":"char *", + "args": ["char *","char const *","size_t","size_t"] + }, + "__builtin___vfprintf_chk": { + "rettype":"int", + "args": ["void *","int","char const *","__builtin_va_list"] + }, + "__builtin___vprintf_chk": { + "rettype":"int", + "args": ["int","char const *","__builtin_va_list"] + }, + "__builtin___vsnprintf_chk": { + "rettype":"int", + "args": ["char *","size_t","int","size_t","char const *","__builtin_va_list"] + }, + "__builtin___vsprintf_chk": { + "rettype":"int", + "args": ["char *","int","size_t","char const *","__builtin_va_list"] + }, + "__builtin_abs": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_acos": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_acosf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_acosh": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_acoshf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_acoshl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_acosl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_alloca": { + "rettype":"void *", + "args": ["size_t"] + }, + "__builtin_asin": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_asinf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_asinh": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_asinhf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_asinhl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_asinl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_atan": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_atan2": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_atan2f": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_atan2l": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_atanf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_atanh": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_atanhf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_atanhl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_atanl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_bswap16": { + "rettype":"uint16_t", + "args": ["uint16_t"] + }, + "__builtin_bswap32": { + "rettype":"uint32_t", + "args": ["uint32_t"] + }, + "__builtin_bswap64": { + "rettype":"uint64_t", + "args": ["uint64_t"] + }, + "__builtin_calloc": { + "rettype":"void *", + "args": ["size_t","size_t"] + }, + "__builtin_cbrt": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_cbrtf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_cbrtl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_ceil": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_ceilf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_ceill": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_constant_p": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_copysign": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_copysignf": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_copysignl": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_cos": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_cosf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_cosh": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_coshf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_coshl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_cosl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_erf": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_erfc": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_erfcf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_erfcl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_erff": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_erfl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_exit": { + "rettype":"void", + "args": ["int"] + }, + "__builtin_exp": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_exp2": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_exp2f": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_exp2l": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_expect": { + "rettype":"long", + "args": ["long","long"] + }, + "__builtin_expf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_expl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_expm1": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_expm1f": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_expm1l": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_fabs": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_fabsf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_fabsl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_fdim": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_fdimf": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_fdiml": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_ffs": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_ffsl": { + "rettype":"int", + "args": ["long"] + }, + "__builtin_ffsll": { + "rettype":"int", + "args": ["long long"] + }, + "__builtin_floor": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_floorf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_floorl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_fma": { + "rettype":"double", + "args": ["double","double","double"] + }, + "__builtin_fmaf": { + "rettype":"float", + "args": ["float","float","float"] + }, + "__builtin_fmal": { + "rettype":"long double", + "args": ["long double","long double","long double"] + }, + "__builtin_fmax": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_fmaxf": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_fmaxl": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_fmin": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_fminf": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_fminl": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_fmod": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_fmodf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_fmodl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_fprintf": { + "rettype":"int", + "args": ["void *","char const *"], + "variadic":true + }, + "__builtin_fputs": { + "rettype":"int", + "args": ["char const *","void *"] + }, + "__builtin_frame_address": { + "rettype":"void *", + "args": ["unsigned int"] + }, + "__builtin_free": { + "rettype":"void", + "args": ["void *"] + }, + "__builtin_frexp": { + "rettype":"double", + "args": ["double","int *"] + }, + "__builtin_frexpf": { + "rettype":"float", + "args": ["float","int *"] + }, + "__builtin_frexpl": { + "rettype":"long double", + "args": ["long double","int *"] + }, + "__builtin_fscanf": { + "rettype":"int", + "args": ["void *","char const *"], + "variadic":true + }, + "__builtin_huge_val": { + "rettype":"double", + "args": [] + }, + "__builtin_huge_valf": { + "rettype":"float", + "args": [] + }, + "__builtin_huge_vall": { + "rettype":"long double", + "args": [] + }, + "__builtin_hypot": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_hypotf": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_hypotl": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_ia32_lfence": { + "rettype":"void", + "args": [] + }, + "__builtin_ia32_mfence": { + "rettype":"void", + "args": [] + }, + "__builtin_ia32_sfence": { + "rettype":"void", + "args": [] + }, + "__builtin_ilogb": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_ilogbf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_ilogbl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_inf": { + "rettype":"double", + "args": [] + }, + "__builtin_inff": { + "rettype":"float", + "args": [] + }, + "__builtin_infl": { + "rettype":"long double", + "args": [] + }, + "__builtin_isalnum": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_isalpha": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_isblank": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_iscntrl": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_isdigit": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_isgraph": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_islower": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_isprint": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_ispunct": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_isspace": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_isupper": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_isxdigit": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_labs": { + "rettype":"long", + "args": ["long"] + }, + "__builtin_ldexp": { + "rettype":"double", + "args": ["double","int"] + }, + "__builtin_ldexpf": { + "rettype":"float", + "args": ["float","int"] + }, + "__builtin_ldexpl": { + "rettype":"long double", + "args": ["long double","int"] + }, + "__builtin_lgamma": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_lgammaf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_lgammal": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_llabs": { + "rettype":"long long", + "args": ["long long"] + }, + "__builtin_llrint": { + "rettype":"long long", + "args": ["double"] + }, + "__builtin_llrintf": { + "rettype":"long long", + "args": ["float"] + }, + "__builtin_llrintl": { + "rettype":"long long", + "args": ["long double"] + }, + "__builtin_llround": { + "rettype":"long long", + "args": ["double"] + }, + "__builtin_llroundf": { + "rettype":"long long", + "args": ["float"] + }, + "__builtin_llroundl": { + "rettype":"long long", + "args": ["long double"] + }, + "__builtin_log": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_log10": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_log10f": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_log10l": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_log1p": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_log1pf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_log1pl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_log2": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_log2f": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_log2l": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_logb": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_logbf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_logbl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_logf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_logl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_lrint": { + "rettype":"long", + "args": ["double"] + }, + "__builtin_lrintf": { + "rettype":"long", + "args": ["float"] + }, + "__builtin_lrintl": { + "rettype":"long", + "args": ["long double"] + }, + "__builtin_lround": { + "rettype":"long", + "args": ["double"] + }, + "__builtin_lroundf": { + "rettype":"long", + "args": ["float"] + }, + "__builtin_lroundl": { + "rettype":"long", + "args": ["long double"] + }, + "__builtin_malloc": { + "rettype":"void *", + "args": ["size_t"] + }, + "__builtin_memchr": { + "rettype":"void *", + "args": ["void const *","int","size_t"] + }, + "__builtin_memcmp": { + "rettype":"int", + "args": ["void const *","void const *","size_t"] + }, + "__builtin_memcpy": { + "rettype":"void *", + "args": ["void *","void const *","size_t"] + }, + "__builtin_mempcpy": { + "rettype":"void *", + "args": ["void *","void const *","size_t"] + }, + "__builtin_memset": { + "rettype":"void *", + "args": ["void *","int","size_t"] + }, + "__builtin_modf": { + "rettype":"double", + "args": ["double","double *"] + }, + "__builtin_modff": { + "rettype":"float", + "args": ["float","float *"] + }, + "__builtin_modfl": { + "rettype":"long double", + "args": ["long double","long double *"] + }, + "__builtin_nan": { + "rettype":"double", + "args": ["char const *"] + }, + "__builtin_nanf": { + "rettype":"float", + "args": ["char const *"] + }, + "__builtin_nanl": { + "rettype":"long double", + "args": ["char const *"] + }, + "__builtin_nans": { + "rettype":"double", + "args": ["char const *"] + }, + "__builtin_nansf": { + "rettype":"float", + "args": ["char const *"] + }, + "__builtin_nansl": { + "rettype":"long double", + "args": ["char const *"] + }, + "__builtin_nearbyint": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_nearbyintf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_nearbyintl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_nextafter": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_nextafterf": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_nextafterl": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_nexttoward": { + "rettype":"double", + "args": ["double","long double"] + }, + "__builtin_nexttowardf": { + "rettype":"float", + "args": ["float","long double"] + }, + "__builtin_nexttowardl": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_object_size": { + "rettype":"size_t", + "args": ["void *","int"] + }, + "__builtin_offsetof": { + "rettype":"size_t", + "args": ["size_t"] + }, + "__builtin_parity": { + "rettype":"int", + "args": ["unsigned int"] + }, + "__builtin_parityl": { + "rettype":"int", + "args": ["unsigned long"] + }, + "__builtin_parityll": { + "rettype":"int", + "args": ["unsigned long long"] + }, + "__builtin_pow": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_powf": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_powi": { + "rettype":"double", + "args": ["double","int"] + }, + "__builtin_powif": { + "rettype":"float", + "args": ["float","int"] + }, + "__builtin_powil": { + "rettype":"long double", + "args": ["long double","int"] + }, + "__builtin_powl": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_prefetch": { + "rettype":"void", + "args": ["void const *"], + "variadic":true + }, + "__builtin_printf": { + "rettype":"int", + "args": ["char const *"], + "variadic":true + }, + "__builtin_putchar": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_puts": { + "rettype":"int", + "args": ["char const *"] + }, + "__builtin_realloc": { + "rettype":"void *", + "args": ["void *","size_t"] + }, + "__builtin_remainder": { + "rettype":"double", + "args": ["double","double"] + }, + "__builtin_remainderf": { + "rettype":"float", + "args": ["float","float"] + }, + "__builtin_remainderl": { + "rettype":"long double", + "args": ["long double","long double"] + }, + "__builtin_remquo": { + "rettype":"double", + "args": ["double","double","int *"] + }, + "__builtin_remquof": { + "rettype":"float", + "args": ["float","float","int *"] + }, + "__builtin_remquol": { + "rettype":"long double", + "args": ["long double","long double","int *"] + }, + "__builtin_return": { + "rettype":"void", + "args": ["void const *"] + }, + "__builtin_return_address": { + "rettype":"void *", + "args": ["unsigned int"] + }, + "__builtin_rint": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_rintf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_rintl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_round": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_roundf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_roundl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_scalbln": { + "rettype":"double", + "args": ["double","long"] + }, + "__builtin_scalblnf": { + "rettype":"float", + "args": ["float","long"] + }, + "__builtin_scalblnl": { + "rettype":"long double", + "args": ["long double","long"] + }, + "__builtin_scalbn": { + "rettype":"double", + "args": ["double","int"] + }, + "__builtin_scalbnf": { + "rettype":"float", + "args": ["float","int"] + }, + "__builtin_scalbnl": { + "rettype":"long double", + "args": ["long double","int"] + }, + "__builtin_scanf": { + "rettype":"int", + "args": ["char const *"], + "variadic":true + }, + "__builtin_sin": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_sinf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_sinh": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_sinhf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_sinhl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_sinl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_snprintf": { + "rettype":"int", + "args": ["char *","size_t","char const *"], + "variadic":true + }, + "__builtin_sprintf": { + "rettype":"int", + "args": ["char *","char const *"], + "variadic":true + }, + "__builtin_sqrt": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_sqrtf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_sqrtl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_sscanf": { + "rettype":"int", + "args": ["char const *","char const *"], + "variadic":true + }, + "__builtin_stdarg_start": { + "rettype":"void", + "args": ["__builtin_va_list"] + }, + "__builtin_stpcpy": { + "rettype":"char *", + "args": ["char *","char const *"] + }, + "__builtin_strcat": { + "rettype":"char *", + "args": ["char *","char const *"] + }, + "__builtin_strchr": { + "rettype":"char *", + "args": ["char *","int"] + }, + "__builtin_strcmp": { + "rettype":"int", + "args": ["char const *","char const *"] + }, + "__builtin_strcpy": { + "rettype":"char *", + "args": ["char *","char const *"] + }, + "__builtin_strcspn": { + "rettype":"size_t", + "args": ["char const *","char const *"] + }, + "__builtin_strlen": { + "rettype":"size_t", + "args": ["char const *"] + }, + "__builtin_strncat": { + "rettype":"char *", + "args": ["char *","char const *","size_t"] + }, + "__builtin_strncmp": { + "rettype":"int", + "args": ["char const *","char const *","size_t"] + }, + "__builtin_strncpy": { + "rettype":"char *", + "args": ["char *","char const *","size_t"] + }, + "__builtin_strpbrk": { + "rettype":"char *", + "args": ["char const *","char const *"] + }, + "__builtin_strrchr": { + "rettype":"char *", + "args": ["char const *","int"] + }, + "__builtin_strspn": { + "rettype":"size_t", + "args": ["char const *","char const *"] + }, + "__builtin_strstr": { + "rettype":"char *", + "args": ["char const *","char const *"] + }, + "__builtin_tan": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_tanf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_tanh": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_tanhf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_tanhl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_tanl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_tgamma": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_tgammaf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_tgammal": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_tolower": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_toupper": { + "rettype":"int", + "args": ["int"] + }, + "__builtin_trunc": { + "rettype":"double", + "args": ["double"] + }, + "__builtin_truncf": { + "rettype":"float", + "args": ["float"] + }, + "__builtin_truncl": { + "rettype":"long double", + "args": ["long double"] + }, + "__builtin_types_compatible_p": { + "rettype":"int", + "args": ["size_t","size_t"] + }, + "__builtin_unreachable": { + "rettype":"void", + "args": [] + }, + "__builtin_vfprintf": { + "rettype":"int", + "args": ["void *","char const *","__builtin_va_list"] + }, + "__builtin_vfscanf": { + "rettype":"int", + "args": ["void *","char const *","__builtin_va_list"] + }, + "__builtin_vprintf": { + "rettype":"int", + "args": ["char const *","__builtin_va_list"] + }, + "__builtin_vscanf": { + "rettype":"int", + "args": ["char const *","__builtin_va_list"] + }, + "__builtin_vsnprintf": { + "rettype":"int", + "args": ["char *","size_t","char const *","__builtin_va_list"] + }, + "__builtin_vsprintf": { + "rettype":"int", + "args": ["char *","char const *","__builtin_va_list"] + }, + "__builtin_vsscanf": { + "rettype":"int", + "args": ["char const *","char const *","__builtin_va_list"] + }, + "__sync_add_and_fetch": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_and_and_fetch": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_bool_compare_and_swap": { + "rettype":"int", + "args": ["T volatile *", "T", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_fetch_and_add": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_fetch_and_and": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_fetch_and_nand": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_fetch_and_or": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_fetch_and_sub": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_fetch_and_xor": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_lock_release": { + "rettype":"void", + "args": ["T volatile *"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_lock_test_and_set": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_nand_and_fetch": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_or_and_fetch": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_sub_and_fetch": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_val_compare_and_swap": { + "rettype":"T", + "args": ["T volatile *","T","T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + }, + "__sync_xor_and_fetch": { + "rettype":"T", + "args": ["T volatile *", "T"], + "types":["int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t"], + "variadic":true + } + } +} diff --git a/src/kernel_internals/runtime/special_hooks.ml b/src/kernel_internals/runtime/special_hooks.ml index 0363e6ffa8aa2cf372c856c446b81edac0630a94..95cd3898f7e219c8f942cc710317e1c7300f2166 100644 --- a/src/kernel_internals/runtime/special_hooks.ml +++ b/src/kernel_internals/runtime/special_hooks.ml @@ -246,14 +246,31 @@ let () = Cmdline.run_after_exiting_stage run_list_all_plugin_options (* Hooks independent from cmdline ordering *) (**************************************************************************) +let warn_if_another_compiler_builtin name = + try + (* Before warning, we must make sure the builtins from other compilers + are loaded. *) + if not (Cil_builtins.Gcc_builtin_templates_loaded.get ()) then + Cil_builtins.init_gcc_builtin_templates (); + let bt = Cil_builtins.Builtin_templates.find name in + let compiler = Option.get bt.compiler in + Kernel.warning ~wkey:Kernel.wkey_implicit_function_declaration + ~current:true ~once:true + "%s is a compiler builtin, %s" name + (Cil.allowed_machdep (Cil_builtins.string_of_compiler compiler)); + true + with Not_found -> false + (* This hook cannot be registered directly in Kernel or Cabs2cil, as it depends on Ast_info *) let on_call_to_undeclared_function vi = let name = vi.Cil_types.vname in - if not (Ast_info.is_frama_c_builtin name) then - Kernel.warning ~wkey:Kernel.wkey_implicit_function_declaration - ~current:true ~once:true - "Calling undeclared function %s. Old style K&R code?" name + if not (Ast_info.is_frama_c_builtin name) then begin + if not (warn_if_another_compiler_builtin name) then + Kernel.warning ~wkey:Kernel.wkey_implicit_function_declaration + ~current:true ~once:true + "Calling undeclared function %s. Old style K&R code?" name + end let () = Cabs2cil.register_implicit_prototype_hook on_call_to_undeclared_function diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index ca1847c257adda363197d1c5bf583f2eee49073f..d7a95024779daa31e2a2c069307f9f3818b672b1 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -1223,8 +1223,12 @@ class cil_printer () = object (self) | Some vi -> let formals = Cil.getFormalsDecl vi in match List.rev formals with - | [] -> assert false (* Typing error, this function is variadic and should - have at least one argument *) + | [] -> + (* Typing error, this function should + have at least one named argument *) + Kernel.abort ~current:true + "%s should have at least one named argument" + vi.vname | f :: _ -> Cil.new_exp ~loc:f.vdecl (Lval (Cil.var f)) (**** STATEMENTS ****) diff --git a/src/kernel_services/ast_queries/cil.ml b/src/kernel_services/ast_queries/cil.ml index bdf9ad830c3992722787f154cb9b959a18e87840..43579c3d1661338d015733e3e3ce843268992ed4 100644 --- a/src/kernel_services/ast_queries/cil.ml +++ b/src/kernel_services/ast_queries/cil.ml @@ -171,8 +171,8 @@ let acceptEmptyCompinfo () = let allowed_machdep machdep = Format.asprintf - "only allowed for %s machdeps;@ see option -machdep or@ \ - run '-machdep help' for the list of available machdeps" + "only allowed for %s machdeps; see option -machdep or \ + run 'frama-c -machdep help' for the list of available machdeps" machdep let theMachineProject = ref (createMachine ()) diff --git a/src/kernel_services/ast_queries/cil_builtins.ml b/src/kernel_services/ast_queries/cil_builtins.ml index b990e16a029101eeb3a1762514523a6ba30e7914..4d0545f91f3f05c0e4251f395a25a5748f373bbe 100644 --- a/src/kernel_services/ast_queries/cil_builtins.ml +++ b/src/kernel_services/ast_queries/cil_builtins.ml @@ -100,484 +100,154 @@ let add_builtin ?(prefix="__builtin_") 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 custom_builtins = Queue.create () + +let add_custom_builtin f = Queue.add f custom_builtins + +let register_custom_builtin (name, rt, prms, isva) = + Builtin_functions.add name (rt,prms,isva) + +(* Table Builtin_templates is similar to Builtin_functions, + but with a few differences: + 1. it lists all _known_ builtins, even those not registered (available) + under the current machdep. + 2. It lists the 'generic' builtin names, not their 'typed' versions, + e.g. '__sync_add_and_fetch' instead of '__sync_add_and_fetch_int32_t'. + 3. It can refer to "generic" type 'type', as in GCC's docs, since its types + are only strings, not actual CIL types. + This table mirrors the contents of the 'data' field of file + 'compiler_builtins.json'. +*) + +type compiler = GCC | MSVC | Not_MSVC + +type builtin_template = { + name: string; + compiler: compiler option; + rettype: string; + args: string list; + types: string list option; + variadic: bool; +} + +let to_compiler s = + if s = "gcc" then GCC + else if s = "msvc" then MSVC + else if s = "!msvc" then Not_MSVC + else + Kernel.fatal "invalid compiler '%s' in compiler_builtins JSON" s + +let string_of_compiler = function + | GCC -> "GCC-based" + | MSVC -> "MSVC-based" + | Not_MSVC -> "not MSVC-based" + +module Builtin_template = struct + let dummy = + { name = ""; + compiler = None; + rettype = ""; + args = []; + types = None; + variadic = false; + } + include Datatype.Make_with_collections + (struct + type t = builtin_template + let name = "Builtin_template" + let reprs = [ dummy ] + let compare b1 b2 = String.compare b1.name b2.name + let hash b = Datatype.String.hash b.name + let equal b1 b2 = b1.name = b2.name + let copy = Datatype.identity + let internal_pretty_code = Datatype.undefined + let pretty fmt b = + Format.fprintf fmt "%s %s(%a%s)" + b.rettype b.name + (Pretty_utils.pp_list ~sep:", " Format.pp_print_string) b.args + (if b.variadic then ", ..." else "") + let rehash = Datatype.identity + let structural_descr = Structural_descr.t_abstract + let mem_project = Datatype.never_any_project + let varname b = "_cb_" ^ b.name + end) +end +module Builtin_templates = + State_builder.Hashtbl + (Datatype.String.Hashtbl) + (Builtin_template) + (struct + let name = "Builtin_templates" + let dependencies = [] + let size = 200 + end) +module Gcc_builtin_templates_loaded = + State_builder.Ref + (Datatype.Bool) + (struct + let name = "Cil_builtins.Gcc_builtin_templates_loaded" + let dependencies = [ Builtin_templates.self ] + let default () = false + end) + +(* An actual instance of a builtin_template, with actual types. *) +type builtin = { + name: string; + compiler: compiler option; + rettype: typ option; + args: typ option list; + variadic: bool; +} + +module Json = +struct + open Yojson.Basic + open Util + + let parse fp = + Kernel.feedback ~dkey:Kernel.dkey_builtins "Parsing builtins file: %a" + Datatype.Filepath.pretty fp; + let json = Json.from_file fp in + member "data" json + + let init_builtin_templates ?default_compiler fp = + let json = parse fp in + List.iter (fun (name, entry) -> + let compiler = + if default_compiler <> None then default_compiler + else + entry |> member "compiler" |> to_string_option |> + Option.map to_compiler + in + let rettype = entry |> member "rettype" |> to_string in + let args = entry |> member "args" |> to_list |> List.map to_string in + let variadic = + entry |> member "variadic" |> to_bool_option |> Option.is_some + in + let types = + match entry |> member "types" with + | `Null -> None + | `List l -> Some (List.map to_string l) + | _ -> + Kernel.fatal "invalid 'types': expected list (in %a)" + Datatype.Filepath.pretty fp + in + let cb = { name; compiler; rettype; args; types; variadic} in + Builtin_templates.replace name cb + ) (json |> to_assoc) + +end + +(* For performance, this table provides O(1) lookups between type names + and the underlying Cil types. Some types may be unavailable in some + machdeps, so the table returns an option type. + Note that the type strings must follow a strict format (also used + in gcc_builtins.json), with a single space between type names and + asterisks (for pointers); otherwise we would have to do some expensive + matching. +*) +let build_type_table () : (string, typ option) Hashtbl.t = 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 @@ -586,126 +256,169 @@ let initGccBuiltins () : unit = 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 + let ptr_of = Option.map (fun t -> TPtr(t,[])) in + let volatile_ptr_of = Option.map (fun t -> TPtr(typeAddVolatile t,[])) in + let types = + [ + ("__builtin_va_list", + Some (if Cil.theMachine.theMachine.has__builtin_va_list + then TBuiltin_va_list [] + else Cil.voidPtrType)); + ("char *", Some Cil.charPtrType); + ("char const *", Some Cil.charConstPtrType); + ("double", Some Cil.doubleType); + ("double *", Some (TPtr(Cil.doubleType,[]))); + ("float", Some Cil.floatType); + ("float *", Some (TPtr(Cil.floatType,[]))); + ("int", Some Cil.intType); + ("int *", Some Cil.intPtrType); + ("int volatile *", Some (TPtr(typeAddVolatile Cil.intType,[]))); + ("long", Some Cil.longType); + ("long double", Some Cil.longDoubleType); + ("long double *", Some (TPtr(Cil.longDoubleType,[]))); + ("long long", Some Cil.longLongType); + ("long long volatile *", Some (TPtr(typeAddVolatile Cil.longLongType,[]))); + ("short", Some Cil.shortType); + ("short volatile *", Some (TPtr(typeAddVolatile Cil.shortType,[]))); + ("signed char", Some Cil.scharType); + ("signed char volatile *", Some (TPtr(typeAddVolatile Cil.scharType,[]))); + ("unsigned char", Some Cil.ucharType); + ("unsigned char volatile *", Some (TPtr(typeAddVolatile Cil.ucharType,[]))); + ("unsigned int", Some Cil.uintType); + ("unsigned int volatile *", Some (TPtr(typeAddVolatile Cil.uintType,[]))); + ("unsigned long", Some Cil.ulongType); + ("unsigned long long", Some Cil.ulongLongType); + ("unsigned long long volatile *", Some (TPtr(typeAddVolatile Cil.ulongLongType,[]))); + ("unsigned short", Some Cil.ushortType); + ("unsigned short volatile *", Some (TPtr(typeAddVolatile Cil.ushortType,[]))); + ("void", Some Cil.voidType); + ("void *", Some Cil.voidPtrType); + ("void const *", Some Cil.voidConstPtrType); + ("size_t", Some Cil.theMachine.typeOfSizeOf); + ("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); + ("int8_t *", ptr_of int8_t); + ("int16_t *", ptr_of int16_t); + ("int32_t *", ptr_of int32_t); + ("int64_t *", ptr_of int64_t); + ("uint8_t *", ptr_of uint8_t); + ("uint16_t *", ptr_of uint16_t); + ("uint32_t *", ptr_of uint32_t); + ("uint64_t *", ptr_of uint64_t); + ("int8_t volatile *", volatile_ptr_of int8_t); + ("int16_t volatile *", volatile_ptr_of int16_t); + ("int32_t volatile *", volatile_ptr_of int32_t); + ("int64_t volatile *", volatile_ptr_of int64_t); + ("uint8_t volatile *", volatile_ptr_of uint8_t); + ("uint16_t volatile *", volatile_ptr_of uint16_t); + ("uint32_t volatile *", volatile_ptr_of uint32_t); + ("uint64_t volatile *", volatile_ptr_of uint64_t); + ] in + Hashtbl.of_seq (List.to_seq types) + +(* Note that [s] (the type string) follows a stricter format than the ones + allowed by the C standard w.r.t. type names; a single space must be + present between type names and asterisks. *) +let parse_type ?(template="") type_table s = + try + if String.get s 0 == 'T' then + (* replace 'T' (always at the beginning) with the template *) + let typ = template ^ (String.sub s 1 (String.length s - 1)) in + Hashtbl.find type_table typ + else + Hashtbl.find type_table s + with Not_found -> + Kernel.fatal "invalid type '%s' in compiler_builtins JSON" s + +let is_machdep_active compiler = + match compiler, Cil.gccMode (), Cil.msvcMode () with + | None, _, _ (* always active *) + | Some GCC, true, _ + | Some MSVC, _, true + | Some Not_MSVC, _, false -> true + | _, _, _ -> false + +let add_builtin_if_active b = + if is_machdep_active b.compiler then begin + Kernel.feedback ~dkey:Kernel.dkey_builtins + "adding builtin: %a %s(%a%s)" + Cil_datatype.Typ.pretty (Option.get b.rettype) b.name + (Pretty_utils.pp_list ~sep:", " Cil_datatype.Typ.pretty) + (List.map Option.get b.args) + (if b.variadic then ", ..." else "") + ; + add_builtin ~prefix:"" b.name (Option.get b.rettype) + ((List.map Option.get) b.args) b.variadic + end - (* 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"] +(* Instantiates builtins according to the types in the template. + In some machdeps, there may be missing types (e.g. int16_t); + such elements are not instantiated in the resulting list. + If the template has no 'types' member, at most a single + builtin will be instantiated. *) +let instantiate_available_templates type_table name (entry : builtin_template) = + let compiler = entry.compiler in + let variadic = entry.variadic in + let make_builtin_as_list ?template name = + let to_type_opt = parse_type ?template type_table in + let rettype = to_type_opt entry.rettype in + let args = List.map to_type_opt entry.args in + if rettype = None || List.exists (fun arg -> arg = None) args + then (* unavailable type: skip builtin *) [] + else + let name = + Option.fold ~none:name ~some:(fun t -> name ^ "_" ^ t) template + in + [{ name; compiler; rettype; args; variadic }] in - let add_sync (typ,name) f = - match typ with - | Some typ -> - add ~prefix:"__sync_" (f^name) typ [ TPtr(typeAddVolatile typ,[]); typ] true - | None -> () + match entry.types with + | Some types -> + List.fold_left (fun acc template -> + (make_builtin_as_list ~template name) @ acc + ) [] types + | None -> + make_builtin_as_list name + +let init_gcc_builtin_templates () = + let fp = + Datatype.Filepath.concat ~existence:Filepath.Must_exist + Fc_config.datadir "compliance/gcc_builtins.json" 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; - (* __sync_synchronize has been declared non-variadic and a spec was added - to __fc_gcc_builtins.h; to avoid issues with pretty-printing, we removed - it from this list. *) -;; - -(* 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 + Json.init_builtin_templates ~default_compiler:GCC fp; + Gcc_builtin_templates_loaded.set true -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 custom_builtins = Queue.create () - -let add_custom_builtin f = Queue.add f custom_builtins - -let register_custom_builtin (name, rt, prms, isva) = - Builtin_functions.add name (rt,prms,isva) +let init_other_builtin_templates () = + let fp = + Datatype.Filepath.concat ~existence:Filepath.Must_exist + Fc_config.datadir "compliance/compiler_builtins.json" + in + Json.init_builtin_templates fp + +let init_builtins_from_json () = + (* For performance reasons, we avoid loading GCC builtins unless we are + using a GCC machdep *) + if Cil.gccMode () then init_gcc_builtin_templates (); + init_other_builtin_templates (); + let type_table = build_type_table () in + Builtin_templates.iter (fun name entry -> + (* In the JSON file, each entry is possibly a template for + several type-specialized functions *) + let builtins = instantiate_available_templates type_table name entry in + List.iter add_builtin_if_active builtins + ) 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; + init_builtins_from_json (); Queue.iter (fun f -> register_custom_builtin (f())) custom_builtins (** This is used as the location of the prototypes of builtin functions. *) diff --git a/src/kernel_services/ast_queries/cil_builtins.mli b/src/kernel_services/ast_queries/cil_builtins.mli index 3c08e8507bcfa5c0cf69869f7b19d4ff4575eba2..ebbebbbde4dfe3bb30cb2f4f8eb59d258aafbc16 100644 --- a/src/kernel_services/ast_queries/cil_builtins.mli +++ b/src/kernel_services/ast_queries/cil_builtins.mli @@ -95,6 +95,27 @@ module Builtin_functions : State_builder.Hashtbl with type key = string and type data = typ * typ list * bool +type compiler = GCC | MSVC | Not_MSVC + +val string_of_compiler : compiler -> string + +type builtin_template = { + name: string; + compiler: compiler option; + rettype: string; + args: string list; + types: string list option; + variadic: bool; +} + +module Builtin_templates : + State_builder.Hashtbl with type key = string + and type data = builtin_template + +module Gcc_builtin_templates_loaded : State_builder.Ref with type data = bool + +val init_gcc_builtin_templates : unit -> unit + (** Register a new builtin. The function will be called after setting the machdep and initializing machine-dependent builtins. Hence, types such {!Cil.uint16_t} might be used if needed. diff --git a/src/kernel_services/plugin_entry_points/kernel.ml b/src/kernel_services/plugin_entry_points/kernel.ml index 9b4ae61a64246bc9d7aefa81625d64de917c09b3..79d3b8c13ee0971dcb5998151e3518a3ed9e62bf 100644 --- a/src/kernel_services/plugin_entry_points/kernel.ml +++ b/src/kernel_services/plugin_entry_points/kernel.ml @@ -46,6 +46,8 @@ let dkey_asm_contracts = register_category "asm:contracts" let dkey_ast = register_category "ast" +let dkey_builtins = register_category "builtins" + let dkey_check = register_category "check" let dkey_constfold = register_category "constfold" diff --git a/src/kernel_services/plugin_entry_points/kernel.mli b/src/kernel_services/plugin_entry_points/kernel.mli index 8c74bc0b8673d5e28856e00545395b1a00151c48..aa8edb92053a3a009ba32c0039308314e88e52da 100644 --- a/src/kernel_services/plugin_entry_points/kernel.mli +++ b/src/kernel_services/plugin_entry_points/kernel.mli @@ -41,6 +41,8 @@ val dkey_asm_contracts: category val dkey_ast: category +val dkey_builtins: category + val dkey_check: category val dkey_constfold: category diff --git a/tests/compliance/check-json.i b/tests/compliance/check-json.i index c9e5ac23e74804d60a2ce769d98841a80b8f1ce0..cce5ee0c72fd8bfff0f6616323d476924a45e012 100644 --- a/tests/compliance/check-json.i +++ b/tests/compliance/check-json.i @@ -1,9 +1,11 @@ /*run.config MACRO: SHARE @FRAMAC_SHARE@/compliance NOFRAMAC: - EXECNOW: LOG json_@PTEST_NAME@_1.txt python3 -m json.tool < @SHARE@/c11_functions.json | head -n 2 > @PTEST_RESULT@/json_@PTEST_NAME@_1.txt 2> @DEV_NULL@ - EXECNOW: LOG json_@PTEST_NAME@_2.txt python3 -m json.tool < @SHARE@/glibc_functions.json | head -n 2 > @PTEST_RESULT@/json_@PTEST_NAME@_2.txt 2> @DEV_NULL@ - EXECNOW: LOG json_@PTEST_NAME@_3.txt python3 -m json.tool < @SHARE@/nonstandard_identifiers.json | head -n 2 > @PTEST_RESULT@/json_@PTEST_NAME@_3.txt 2> @DEV_NULL@ - EXECNOW: LOG json_@PTEST_NAME@_4.txt python3 -m json.tool < @SHARE@/posix_identifiers.json | head -n 2 > @PTEST_RESULT@/json_@PTEST_NAME@_4.txt 2> @DEV_NULL@ - EXECNOW: LOG json_@PTEST_NAME@_5.txt python3 @PTEST_DIR@/sanity-checks.py @SHARE@ > @PTEST_RESULT@/json_@PTEST_NAME@_5.txt 2> @DEV_NULL@ + EXECNOW: LOG json_@PTEST_NAME@_1.txt python3 -m json.tool < @SHARE@/c11_functions.json | head -n 2 | tail -n 1 > @PTEST_RESULT@/json_@PTEST_NAME@_1.txt 2> @DEV_NULL@ + EXECNOW: LOG json_@PTEST_NAME@_2.txt python3 -m json.tool < @SHARE@/glibc_functions.json | head -n 2 | tail -n 1 > @PTEST_RESULT@/json_@PTEST_NAME@_2.txt 2> @DEV_NULL@ + EXECNOW: LOG json_@PTEST_NAME@_3.txt python3 -m json.tool < @SHARE@/nonstandard_identifiers.json | head -n 2 | tail -n 1 > @PTEST_RESULT@/json_@PTEST_NAME@_3.txt 2> @DEV_NULL@ + EXECNOW: LOG json_@PTEST_NAME@_4.txt python3 -m json.tool < @SHARE@/posix_identifiers.json | head -n 2 | tail -n 1 > @PTEST_RESULT@/json_@PTEST_NAME@_4.txt 2> @DEV_NULL@ + EXECNOW: LOG json_@PTEST_NAME@_5.txt python3 -m json.tool < @SHARE@/compiler_builtins.json | head -n 2 | tail -n 1 > @PTEST_RESULT@/json_@PTEST_NAME@_5.txt 2> @DEV_NULL@ + EXECNOW: LOG json_@PTEST_NAME@_6.txt python3 -m json.tool < @SHARE@/gcc_builtins.json | head -n 2 | tail -n 1 > @PTEST_RESULT@/json_@PTEST_NAME@_6.txt 2> @DEV_NULL@ + EXECNOW: LOG json_@PTEST_NAME@_7.txt python3 @PTEST_DIR@/sanity-checks.py @SHARE@ > @PTEST_RESULT@/json_@PTEST_NAME@_7.txt 2> @DEV_NULL@ */ diff --git a/tests/compliance/oracle/json_check-json_1.txt b/tests/compliance/oracle/json_check-json_1.txt index 1b5870264ab3d7511f6c0ec3cce36b2ddf76554c..53e785991f5381a46f4610e816316649ccae7e5e 100644 --- a/tests/compliance/oracle/json_check-json_1.txt +++ b/tests/compliance/oracle/json_check-json_1.txt @@ -1,2 +1 @@ -{ "description": "C11 reserved function and macro identifiers", diff --git a/tests/compliance/oracle/json_check-json_2.txt b/tests/compliance/oracle/json_check-json_2.txt index a7490e8d444cf0359541826585e85c435704ea3e..24ce34e11953f9c80a6861f91fcfc97fe6f70171 100644 --- a/tests/compliance/oracle/json_check-json_2.txt +++ b/tests/compliance/oracle/json_check-json_2.txt @@ -1,2 +1 @@ -{ "description": "Function and macro identifiers defined in the GNU C Library", diff --git a/tests/compliance/oracle/json_check-json_3.txt b/tests/compliance/oracle/json_check-json_3.txt index 0b2f8f38fd6866c709dd788271b9c62fe2a52bf0..567fa7bd16e3060df956746d155eb99beecf0acf 100644 --- a/tests/compliance/oracle/json_check-json_3.txt +++ b/tests/compliance/oracle/json_check-json_3.txt @@ -1,2 +1 @@ -{ "description": "Non-ISO C, Non-POSIX identifiers known to the Frama-C standard library", diff --git a/tests/compliance/oracle/json_check-json_4.txt b/tests/compliance/oracle/json_check-json_4.txt index cdf3ccde431a21b0e3e97353e314452444a135a1..ba1f81a5fad309e92a7b2db78855d59bd595be79 100644 --- a/tests/compliance/oracle/json_check-json_4.txt +++ b/tests/compliance/oracle/json_check-json_4.txt @@ -1,2 +1 @@ -{ "description": "POSIX.1-2008 reserved function identifiers (plus a few legacy POSIX identifiers)", diff --git a/tests/compliance/oracle/json_check-json_5.txt b/tests/compliance/oracle/json_check-json_5.txt index 295b7a131d220022bb1905180900314974130baa..41629175862962f64941c7ec80ef2948a41e695a 100644 --- a/tests/compliance/oracle/json_check-json_5.txt +++ b/tests/compliance/oracle/json_check-json_5.txt @@ -1,2 +1 @@ -posix_identifiers.json checked. -c11_functions.json checked. + "description": "Compiler builtins supported by Frama-C (for GCC builtins, see gcc_builtins.json)", diff --git a/tests/compliance/oracle/json_check-json_6.txt b/tests/compliance/oracle/json_check-json_6.txt new file mode 100644 index 0000000000000000000000000000000000000000..6984653217284e726bb24afefc98bf10d49420a2 --- /dev/null +++ b/tests/compliance/oracle/json_check-json_6.txt @@ -0,0 +1 @@ + "description": "GCC builtins supported by Frama-C", diff --git a/tests/compliance/oracle/json_check-json_7.txt b/tests/compliance/oracle/json_check-json_7.txt new file mode 100644 index 0000000000000000000000000000000000000000..295b7a131d220022bb1905180900314974130baa --- /dev/null +++ b/tests/compliance/oracle/json_check-json_7.txt @@ -0,0 +1,2 @@ +posix_identifiers.json checked. +c11_functions.json checked. diff --git a/tests/misc/oracle/function_ptr_alignof.res.oracle b/tests/misc/oracle/function_ptr_alignof.res.oracle index fa223563fb4e588997e95f7fee1b314ec2c92b0e..c25dcf5f2d7b15f305cca1a86fb38435120a3078 100644 --- a/tests/misc/oracle/function_ptr_alignof.res.oracle +++ b/tests/misc/oracle/function_ptr_alignof.res.oracle @@ -1,6 +1,5 @@ [kernel] Parsing function_ptr_alignof.i (no preprocessing) [kernel] function_ptr_alignof.i:13: User Error: - alignof() called on function only allowed for GCC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + alignof() called on function only allowed for GCC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] User Error: stopping on file "function_ptr_alignof.i" that has errors. [kernel] Frama-C aborted: invalid user input. diff --git a/tests/misc/oracle/function_ptr_sizeof.res.oracle b/tests/misc/oracle/function_ptr_sizeof.res.oracle index 06996432c675f999cba76b50b0b13b2e72083267..3f66d533ba61c68d95e83705e0ba3ca5ad41afc3 100644 --- a/tests/misc/oracle/function_ptr_sizeof.res.oracle +++ b/tests/misc/oracle/function_ptr_sizeof.res.oracle @@ -1,6 +1,5 @@ [kernel] Parsing function_ptr_sizeof.i (no preprocessing) [kernel] function_ptr_sizeof.i:13: User Error: - sizeof() called on function only allowed for GCC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + sizeof() called on function only allowed for GCC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] User Error: stopping on file "function_ptr_sizeof.i" that has errors. [kernel] Frama-C aborted: invalid user input. diff --git a/tests/syntax/compiler_builtins.c b/tests/syntax/compiler_builtins.c new file mode 100644 index 0000000000000000000000000000000000000000..175483a73c1cc5eea357932151b7e59e0e79d7d4 --- /dev/null +++ b/tests/syntax/compiler_builtins.c @@ -0,0 +1,28 @@ +/* run.config + STDOPT: + STDOPT: +"-machdep gcc_x86_32" + STDOPT: +"-machdep msvc_x86_64" + */ + +#include <stdarg.h> + +struct st { + char a; + int b; +}; + +void fva(int a, ...) { + va_list ap; + __builtin_va_start(ap, a); // Non-MSVC-specific + __builtin_va_end(ap); // Non-MSVC-specific +} + +int main() { + int x = 0; + if (__builtin_expect(x++, x)) { // GCC-specific + int y = x; + } + __builtin__annotation("a", 1); // MSVC-specific + fva(1); + __builtin_offsetof(struct st,b); // Generic builtin (always available) +} diff --git a/tests/syntax/oracle/check_builtin_bts1440.res.oracle b/tests/syntax/oracle/check_builtin_bts1440.res.oracle index 32d925b4bfe4c3c97c19d67815d1f978afa4b0b1..d115b107f7d2ae95a82989316364464b299d9ba3 100644 --- a/tests/syntax/oracle/check_builtin_bts1440.res.oracle +++ b/tests/syntax/oracle/check_builtin_bts1440.res.oracle @@ -183,11 +183,11 @@ long double __builtin_fdiml(long double __x0, long double __x1); - int __builtin_ffs(unsigned int __x0); + int __builtin_ffs(int __x0); - int __builtin_ffsl(unsigned long __x0); + int __builtin_ffsl(long __x0); - int __builtin_ffsll(unsigned long long __x0); + int __builtin_ffsll(long long __x0); double __builtin_floor(double __x0); diff --git a/tests/syntax/oracle/compiler_builtins.0.res.oracle b/tests/syntax/oracle/compiler_builtins.0.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..962db45f53cb5561a0deb60970e2613d548793c1 --- /dev/null +++ b/tests/syntax/oracle/compiler_builtins.0.res.oracle @@ -0,0 +1,41 @@ +[kernel] Parsing compiler_builtins.c (with preprocessing) +[kernel:typing:implicit-function-declaration] compiler_builtins.c:22: Warning: + __builtin_expect is a compiler builtin, only allowed for GCC-based machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps +[kernel:typing:implicit-function-declaration] compiler_builtins.c:25: Warning: + __builtin__annotation is a compiler builtin, only allowed for MSVC-based machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps +/* Generated by Frama-C */ +#include "stdarg.h" +/* compiler builtin: + void __builtin_va_end(__builtin_va_list); */ +/* compiler builtin: + void __builtin_va_start(__builtin_va_list); */ +void fva(int a , ...) +{ + va_list ap; + __builtin_va_start(ap,a); + __builtin_va_end(ap); + return; +} + +extern int ( /* missing proto */ __builtin__annotation)(char const *x_0, + int x_1); + +int main(void) +{ + int __retres; + int tmp; + int x = 0; + ; + tmp = x; + x ++; + ; + if (tmp) { + int y = x; + } + __builtin__annotation("a",1); + fva(1); + __retres = 0; + return __retres; +} + + diff --git a/tests/syntax/oracle/compiler_builtins.1.res.oracle b/tests/syntax/oracle/compiler_builtins.1.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..d3cf8ba1bb5ad1cc0fe1cdac0ccb120a283ab22d --- /dev/null +++ b/tests/syntax/oracle/compiler_builtins.1.res.oracle @@ -0,0 +1,39 @@ +[kernel] Parsing compiler_builtins.c (with preprocessing) +[kernel:typing:implicit-function-declaration] compiler_builtins.c:25: Warning: + __builtin__annotation is a compiler builtin, only allowed for MSVC-based machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps +/* Generated by Frama-C */ +#include "stdarg.h" +/* compiler builtin: + void __builtin_va_end(__builtin_va_list); */ +/* compiler builtin: + void __builtin_va_start(__builtin_va_list); */ +void fva(int a , ...) +{ + va_list ap; + __builtin_va_start(ap,a); + __builtin_va_end(ap); + return; +} + +extern int ( /* missing proto */ __builtin__annotation)(char const *x_0, + int x_1); + +int main(void) +{ + int __retres; + int tmp; + int x = 0; + ; + tmp = x; + x ++; + ; + if ((long)tmp) { + int y = x; + } + __builtin__annotation("a",1); + fva(1); + __retres = 0; + return __retres; +} + + diff --git a/tests/syntax/oracle/compiler_builtins.2.res.oracle b/tests/syntax/oracle/compiler_builtins.2.res.oracle new file mode 100644 index 0000000000000000000000000000000000000000..cc838d9c9cda183f69fbda4630ecf2522fd5f223 --- /dev/null +++ b/tests/syntax/oracle/compiler_builtins.2.res.oracle @@ -0,0 +1,42 @@ +[kernel] Parsing compiler_builtins.c (with preprocessing) +[kernel:typing:implicit-function-declaration] compiler_builtins.c:16: Warning: + __builtin_va_start is a compiler builtin, only allowed for not MSVC-based machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps +[kernel:typing:implicit-function-declaration] compiler_builtins.c:17: Warning: + __builtin_va_end is a compiler builtin, only allowed for not MSVC-based machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps +[kernel:typing:implicit-function-declaration] compiler_builtins.c:22: Warning: + __builtin_expect is a compiler builtin, only allowed for GCC-based machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps +/* Generated by Frama-C */ +#include "stdarg.h" +/* compiler builtin: + void __builtin__annotation(...); */ +extern int ( /* missing proto */ __builtin_va_start)(); + +extern int ( /* missing proto */ __builtin_va_end)(char *x_0); + +void fva(int a , ...) +{ + va_list ap; + __builtin_va_start(ap,a); + __builtin_va_end(ap); + return; +} + +int main(void) +{ + int __retres; + int tmp; + int x = 0; + ; + tmp = x; + x ++; + ; + if (tmp) { + int y = x; + } + __builtin__annotation("a",1); + fva(1); + __retres = 0; + return __retres; +} + + diff --git a/tests/syntax/oracle/flexible_array_member_invalid5.res.oracle b/tests/syntax/oracle/flexible_array_member_invalid5.res.oracle index 8f91488188b6cb3016ee725eb2f25ea96c38bd2f..22cf6e91dadcdb16d2f811aa88e9247b8b4730c4 100644 --- a/tests/syntax/oracle/flexible_array_member_invalid5.res.oracle +++ b/tests/syntax/oracle/flexible_array_member_invalid5.res.oracle @@ -1,6 +1,5 @@ [kernel] Parsing flexible_array_member_invalid5.i (no preprocessing) [kernel] flexible_array_member_invalid5.i:15: User Error: - field `f' declared with a type containing a flexible array member only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps. + field `f' declared with a type containing a flexible array member only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps. [kernel] User Error: stopping on file "flexible_array_member_invalid5.i" that has errors. [kernel] Frama-C aborted: invalid user input. diff --git a/tests/syntax/oracle/sizeof_void.0.res.oracle b/tests/syntax/oracle/sizeof_void.0.res.oracle index 03f35c1ead217d855a3261324725e1624285c621..9ad43d07487edb653606707fc19113361b096509 100644 --- a/tests/syntax/oracle/sizeof_void.0.res.oracle +++ b/tests/syntax/oracle/sizeof_void.0.res.oracle @@ -1,16 +1,12 @@ [kernel] Parsing sizeof_void.c (with preprocessing) [kernel] sizeof_void.c:9: User Error: - sizeof on void type only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + sizeof on void type only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] sizeof_void.c:16: User Error: - sizeof() on void type only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + sizeof() on void type only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] sizeof_void.c:21: User Error: - alignof on void type only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + alignof on void type only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] sizeof_void.c:28: User Error: - alignof() on void type only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + alignof() on void type only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] User Error: stopping on file "sizeof_void.c" that has errors. Add '-kernel-msg-key pp' for preprocessing command. [kernel] Frama-C aborted: invalid user input. diff --git a/tests/value/oracle/array_zero_length.2.res.oracle b/tests/value/oracle/array_zero_length.2.res.oracle index 985351e9ac4efd6f3aef9393e0a6980017dfc493..5ed5a2552d7bdc8bf214e134b0f66d1bb4b00e55 100644 --- a/tests/value/oracle/array_zero_length.2.res.oracle +++ b/tests/value/oracle/array_zero_length.2.res.oracle @@ -1,16 +1,13 @@ [kernel] Parsing array_zero_length.i (no preprocessing) [kernel] array_zero_length.i:9: User Error: - zero-length arrays only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + zero-length arrays only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] array_zero_length.i:11: User Error: - zero-length arrays only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + zero-length arrays only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] array_zero_length.i:11: User Error: declaration of array of 'zero-length arrays' ('char [0]`); zero-length arrays are not allowed in C99 [kernel] array_zero_length.i:13: User Error: - empty initializers only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + empty initializers only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps 11 char W[][0]; 12 13 char T1[] = {}; diff --git a/tests/value/oracle/empty_base.1.res.oracle b/tests/value/oracle/empty_base.1.res.oracle index 446b635cc2cd1897e645b94688a5ece3a0e6bc81..019c09a82d65b2fb085b5c5523accd75088742c0 100644 --- a/tests/value/oracle/empty_base.1.res.oracle +++ b/tests/value/oracle/empty_base.1.res.oracle @@ -1,13 +1,10 @@ [kernel] Parsing empty_base.c (with preprocessing) [kernel] empty_base.c:13: User Error: - empty structs only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + empty structs only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] empty_base.c:48: User Error: - zero-length arrays only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + zero-length arrays only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps [kernel] empty_base.c:50: User Error: - empty initializers only allowed for GCC/MSVC machdeps; see option -machdep or - run '-machdep help' for the list of available machdeps + empty initializers only allowed for GCC/MSVC machdeps; see option -machdep or run 'frama-c -machdep help' for the list of available machdeps 48 struct empty empty_array_of_empty[0]; 49 struct empty array_of_empty[1]; 50 struct empty many_empty[3] = {{}};