Description
- Goblint: goblint/analyzer@206f204
- OpenSSL: https://github.com/openssl/openssl/tree/0fcf2351ecff5db21cba431704e4da631b74904a
Attempt 1
./Configure
bear -- make
goblint -v .
Error:
Frontc is parsing /home/simmo/Desktop/openssl/.goblint/preprocessed/engines/e_afalg.i
/usr/include/stdlib.h[140:8-16] : syntax error
Parsing errorFatal error: exception Frontc.ParseError("Parse error")
The problem is _Float32
here:
# 140 "/usr/include/stdlib.h" 3 4
extern _Float32 strtof32 (const char *__restrict __nptr,
char **__restrict __endptr)
__attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
In engines/e_afalg.c
:
/* Required for vmsplice */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
_GNU_SOURCE
enables (through a number of intermediates) the following in the unpreprocessed stdlib.h
:
#if __HAVE_FLOAT32 && __GLIBC_USE (IEC_60559_TYPES_EXT)
extern _Float32 strtof32 (const char *__restrict __nptr,
char **__restrict __endptr)
__THROW __nonnull ((1));
#endif
I think OpenSSL itself doesn't even use _Float32
or that function, but it just gets pulled in with _GNU_SOURCE
among tons of other GNU-specific things.
Attempt 2
In floatn-common.h
there is the following typedef:
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef float _Float32;
# endif
So in an extremely crude hack to bypass that and cause the typedef to be used in the standard headers, I tried the following to pretend to be GCC 6.0 for the purposes of preprocessing:
goblint -v . --set cppflags[+] '-D__GNUC__=6' --set cppflags[+] '-D__GNUC_MINOR__=0'
Error:
Frontc is parsing /home/simmo/Desktop/openssl/.goblint/preprocessed/engines/e_afalg.i
include/openssl/crypto.h[413:0-0] : syntax error
Parsing errorFatal error: exception Frontc.ParseError("Parse error")
The problem is the _Noreturn
here:
# 413 "include/openssl/crypto.h"
_Noreturn void OPENSSL_die(const char *assertion, const char *file, int line);
_Noreturn
is a C11 feature that CIL doesn't support (goblint/cil#13).
Attempt 3
In an even more desperate attempt, I tried to just preprocess that keyword away (it's just extra information that technically shouldn't matter):
goblint -v . --set cppflags[+] '-D__GNUC__=6' --set cppflags[+] '-D__GNUC_MINOR__=0' --set cppflags[+] '-D_Noreturn='
Error:
/usr/include/x86_64-linux-gnu/bits/floatn.h:86: Error: Invalid combination of type specifiers
Error on A.TYPEDEF (Errormsg.Error)
Frontc is parsing /home/simmo/Desktop/openssl/.goblint/preprocessed/engines/e_capi.i
Error: There were parsing errors in /home/simmo/Desktop/openssl/.goblint/preprocessed/engines/e_capi.i
Fatal error: exception Errormsg.Error
The problematic code is __float128
:
/* The type _Float128 exists only since GCC 7.0. */
# if !__GNUC_PREREQ (7, 0) || defined __cplusplus
typedef __float128 _Float128;
# endif
CIL has has some kind of support for it (goblint/cil#8), but it defines both __float128
and _Float128
as builtin type names, so maybe that's screwing with the parsing of this.
I think that aspect of CIL has been updated for GCC >=7.0, so my version hack above is probably causing this one to happen. The appropriate solution would be to handle the other GNU float types directly as well.
TODO
- Add GNU extended floating-point types to CIL (Add support for additional float types cil#60).
- Add
_Noreturn
support to CIL (Support for C11_Noreturn
cil#58). - Add
_Atomic
support to CIL (Support for_Atomic
cil#61).