From ccef48f2c81f704686164b5a9990034eed7c195c Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Fri, 8 Mar 2019 15:48:31 +0100 Subject: [PATCH] [typing] Keep trace of all libc includes that contribute to a var definition Fixes issue #614 --- src/kernel_internals/typing/cabs2cil.ml | 12 ++++++++++-- src/kernel_internals/typing/mergecil.ml | 11 +++++++++++ src/kernel_services/ast_printing/cil_printer.ml | 4 +--- tests/libc/oracle/fc_libc.0.res.oracle | 6 ++++++ tests/syntax/libc_defs.h | 2 ++ tests/syntax/oracle/libc_defs.res.oracle | 5 +++++ 6 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 tests/syntax/libc_defs.h create mode 100644 tests/syntax/oracle/libc_defs.res.oracle diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml index 320b570ab51..6cd61cd0df7 100644 --- a/src/kernel_internals/typing/cabs2cil.ml +++ b/src/kernel_internals/typing/cabs2cil.ml @@ -325,8 +325,15 @@ let process_stdlib_pragma name args = let fc_stdlib_attribute attrs = let s = get_current_stdheader () in if s = "" then attrs - else Cil.addAttribute (Attr (fc_stdlib, [AStr s])) attrs - + else begin + let payload, attrs = + if Cil.hasAttribute fc_stdlib attrs then begin + AStr s :: Cil.findAttribute fc_stdlib attrs, + Cil.dropAttribute fc_stdlib attrs + end else [AStr s], attrs + in + Cil.addAttribute (Attr (fc_stdlib, payload)) attrs + end (* ICC align/noalign pragmas (not supported by GCC/MSVC with this syntax). Implemented by translating them to 'aligned' attributes. Currently, only default and noalign are supported, not explicit alignment values. @@ -3004,6 +3011,7 @@ let makeGlobalVarinfo (isadef: bool) (vi: varinfo) : varinfo * bool = (* always favor the location of the definition.*) oldvi.vdecl <- vi.vdecl; oldvi.vdefined <- true; + oldvi.vattr <- fc_stdlib_attribute oldvi.vattr end; (* notice that [vtemp] is immutable, and cannot be updated. Hopefully, temporaries have sufficiently fresh names that this is not a problem *) diff --git a/src/kernel_internals/typing/mergecil.ml b/src/kernel_internals/typing/mergecil.ml index ca79f462689..f6b1012b319 100644 --- a/src/kernel_internals/typing/mergecil.ml +++ b/src/kernel_internals/typing/mergecil.ml @@ -1743,6 +1743,17 @@ let oneFilePass1 (f:file) : unit = end else Kernel.abort "%s" msg (* Fail if both variables are used. *) end in + if Cil.hasAttribute "fc_stdlib" oldvi.vattr then begin + let attrprm = Cil.findAttribute "fc_stdlib" oldvi.vattr in + let attrprm = + if Cil.hasAttribute "fc_stdlib" vi.vattr then begin + Cil.findAttribute "fc_stdlib" vi.vattr @ attrprm + end else attrprm + in + let attrs = Cil.dropAttribute "fc_stdlib" newrep.ndata.vattr in + let attrs = Cil.addAttribute (Attr ("fc_stdlib", attrprm)) attrs in + newrep.ndata.vattr <- attrs; + end; newrep.ndata.vdefined <- vi.vdefined || oldvi.vdefined; newrep.ndata.vreferenced <- vi.vreferenced || oldvi.vreferenced; (* We do not want to turn non-"const" globals into "const" one. That diff --git a/src/kernel_services/ast_printing/cil_printer.ml b/src/kernel_services/ast_printing/cil_printer.ml index c395c874ff0..c84b8efd2cc 100644 --- a/src/kernel_services/ast_printing/cil_printer.ml +++ b/src/kernel_services/ast_printing/cil_printer.ml @@ -109,9 +109,7 @@ let print_std_includes fmt globs = in let add_file acc g = let attrs = Cil_datatype.Global.attr g in - match Cil.findAttribute "fc_stdlib" attrs with - | [ arg ] -> extract_file acc arg - | _ -> acc + List.fold_left extract_file acc (Cil.findAttribute "fc_stdlib" attrs) in let includes = List.fold_left add_file Datatype.String.Set.empty globs in let print_one_include s = Format.fprintf fmt "#include \"%s\"@." s in diff --git a/tests/libc/oracle/fc_libc.0.res.oracle b/tests/libc/oracle/fc_libc.0.res.oracle index 15885d81a20..ea255ba6278 100644 --- a/tests/libc/oracle/fc_libc.0.res.oracle +++ b/tests/libc/oracle/fc_libc.0.res.oracle @@ -190,15 +190,20 @@ #include "alloca.h" #include "assert.c" #include "assert.h" +#include "ctype.c" #include "ctype.h" #include "dirent.h" +#include "errno.c" #include "errno.h" #include "fcntl.h" #include "fenv.c" #include "fenv.h" +#include "getopt.c" #include "getopt.h" +#include "glob.c" #include "glob.h" #include "iconv.h" +#include "inttypes.c" #include "inttypes.h" #include "libgen.h" #include "locale.c" @@ -235,6 +240,7 @@ #include "termios.h" #include "time.h" #include "unistd.h" +#include "wchar.c" #include "wchar.h" void main(void) { diff --git a/tests/syntax/libc_defs.h b/tests/syntax/libc_defs.h new file mode 100644 index 00000000000..f2c38aa03a6 --- /dev/null +++ b/tests/syntax/libc_defs.h @@ -0,0 +1,2 @@ +#include <errno.h> +#include <errno.c> diff --git a/tests/syntax/oracle/libc_defs.res.oracle b/tests/syntax/oracle/libc_defs.res.oracle new file mode 100644 index 00000000000..0705f794ef5 --- /dev/null +++ b/tests/syntax/oracle/libc_defs.res.oracle @@ -0,0 +1,5 @@ +[kernel] Parsing tests/syntax/libc_defs.h (with preprocessing) +/* Generated by Frama-C */ +#include "errno.c" +#include "errno.h" + -- GitLab