From 1719c9ded4d02889f44944f70d3d32512c5a539c Mon Sep 17 00:00:00 2001 From: Virgile Prevosto <virgile.prevosto@m4x.org> Date: Thu, 11 Jun 2020 15:30:04 +0200 Subject: [PATCH] [kernel] fix issue in emitter filtering when emitter is not usable When loading some state, it may happen that some annotations are found to have been emitted by emitters that are no longer usable. This commit let the kernel adopt them, keeping them available as was the case before refactoring `Annotations.code_annot` to use `Annotations.code_annot_emitter`. --- src/kernel_services/ast_data/annotations.ml | 9 ++++- tests/misc/my_visitor.c | 3 +- tests/misc/my_visitor.ml | 41 ++++++++++++--------- tests/misc/oracle/my_visitor.0.res.oracle | 17 +++++++++ tests/misc/oracle/my_visitor.1.res.oracle | 23 ++++++++++++ 5 files changed, 74 insertions(+), 19 deletions(-) create mode 100644 tests/misc/oracle/my_visitor.0.res.oracle create mode 100644 tests/misc/oracle/my_visitor.1.res.oracle diff --git a/src/kernel_services/ast_data/annotations.ml b/src/kernel_services/ast_data/annotations.ml index 616667b0f30..1eb538ec66d 100644 --- a/src/kernel_services/ast_data/annotations.ml +++ b/src/kernel_services/ast_data/annotations.ml @@ -352,7 +352,14 @@ let code_annot_emitter ?filter stmt = try let tbl = Code_annots.find stmt in let filter e l acc = - let e = Emitter.Usable_emitter.get e in + let e = + try Emitter.Usable_emitter.get e + with Not_found -> + (* in some cases, e.g. when loading a state with a different set + of plugins loaded, the original emitter might not be available, + leading to discarding annotations. Let the kernel adopt them. *) + Emitter.kernel + in match filter with | None -> List.map (fun a -> a, e) l @ acc | Some f -> diff --git a/tests/misc/my_visitor.c b/tests/misc/my_visitor.c index 29355fd152e..9ce70834706 100644 --- a/tests/misc/my_visitor.c +++ b/tests/misc/my_visitor.c @@ -1,7 +1,8 @@ /* run.config EXECNOW: make -s @PTEST_DIR@/@PTEST_NAME@.cmxs EXECNOW: LOG my_visitor_sav.res LOG my_visitor_sav.err BIN my_visitor.sav FRAMAC_PLUGIN=./lib/plugins @frama-c@ @PTEST_FILE@ -no-autoload-plugins -load-module @PTEST_DIR@/@PTEST_NAME@.cmxs -main f -save @PTEST_DIR@/@PTEST_NAME@.sav > @PTEST_DIR@/result/@PTEST_NAME@_sav.res 2> @PTEST_DIR@/result/@PTEST_NAME@_sav.err -OPT: -load @PTEST_DIR@/@PTEST_NAME@.sav -print +OPT: -load @PTEST_DIR@/@PTEST_NAME@.sav -no-autoload-plugins -load-module @PTEST_DIR@/@PTEST_NAME@.cmxs -no-my-visitor -print +OPT: -load @PTEST_DIR@/@PTEST_NAME@.sav -no-autoload-plugins -print */ int f() { int y = 0; diff --git a/tests/misc/my_visitor.ml b/tests/misc/my_visitor.ml index 4e2a100c4cb..09545f270ae 100644 --- a/tests/misc/my_visitor.ml +++ b/tests/misc/my_visitor.ml @@ -16,6 +16,9 @@ module S = module S2 = P.False(struct let option_name = "-s2" let help = "" end) +module Enabled = + P.True(struct let option_name = "-my-visitor" let help = "" end) + let emitter1 = Emitter.create "emitter1" [ Emitter.Code_annot ] ~correctness:[ S.parameter ] ~tuning:[] @@ -64,28 +67,32 @@ let print () = Kernel.log "================================" let main () = - (* The initial AST *) - print (); - let file = Ast.get () in - ignore (Cil.visitCilFileSameGlobals (new foo:>cilVisitor) file); - (* The AST with all asserts *) - print (); - Kernel.SafeArrays.set false; - Project.clear - ~selection:(State_selection.Static.with_dependencies S.self) (); - (* The AST with 1/2 asserts *) - print () + if Enabled.get() then begin + (* The initial AST *) + print (); + let file = Ast.get () in + ignore (Cil.visitCilFileSameGlobals (new foo:>cilVisitor) file); + (* The AST with all asserts *) + print (); + Kernel.SafeArrays.set false; + Project.clear + ~selection:(State_selection.Static.with_dependencies S.self) (); + (* The AST with 1/2 asserts *) + print () + end let () = Db.Main.extend main (* This other main is a simple test for deep copy. *) let main () = - let p = File.create_project_from_visitor "param" (new Visitor.frama_c_copy) in - let selection = State_selection.singleton Kernel.LibEntry.self in - Project.copy ~selection p; - Kernel.LibEntry.on (); - assert (Kernel.LibEntry.get ()); - assert (Project.on p ~selection (fun () -> not (Kernel.LibEntry.get ())) ()) + if Enabled.get() then begin + let p = File.create_project_from_visitor "param" (new Visitor.frama_c_copy) in + let selection = State_selection.singleton Kernel.LibEntry.self in + Project.copy ~selection p; + Kernel.LibEntry.on (); + assert (Kernel.LibEntry.get ()); + assert (Project.on p ~selection (fun () -> not (Kernel.LibEntry.get ())) ()) + end let () = Db.Main.extend main diff --git a/tests/misc/oracle/my_visitor.0.res.oracle b/tests/misc/oracle/my_visitor.0.res.oracle new file mode 100644 index 00000000000..757a20ca369 --- /dev/null +++ b/tests/misc/oracle/my_visitor.0.res.oracle @@ -0,0 +1,17 @@ +[kernel] Warning: ignoring source files specified on the command line while loading a global initial context. +/* Generated by Frama-C */ +int f(void) +{ + int __retres; + /*@ assert emitter2: ∀ ℤ x; x ≡ x; */ + int y = 0; + y ++; + /*@ assert y ≡ 1; */ + /*@ assert emitter2: ∀ ℤ x; x ≡ x; */ + ; + __retres = 0; + /*@ assert emitter2: ∀ ℤ x; x ≡ x; */ + return __retres; +} + + diff --git a/tests/misc/oracle/my_visitor.1.res.oracle b/tests/misc/oracle/my_visitor.1.res.oracle new file mode 100644 index 00000000000..14717c12726 --- /dev/null +++ b/tests/misc/oracle/my_visitor.1.res.oracle @@ -0,0 +1,23 @@ +[kernel] Warning: emitter emitter1: correctness parameter -s does not exist anymore. Ignored. +[kernel] Warning: emitter emitter2: correctness parameter -s2 does not exist anymore. Ignored. +[kernel] Warning: 15 states in saved file ignored. They are invalid in this Frama-C configuration. +[kernel] Warning: emitter emitter1: correctness parameter -s does not exist anymore. Ignored. +[kernel] Warning: emitter emitter2: correctness parameter -s2 does not exist anymore. Ignored. +[kernel] Warning: 15 states in saved file ignored. They are invalid in this Frama-C configuration. +[kernel] Warning: ignoring source files specified on the command line while loading a global initial context. +/* Generated by Frama-C */ +int f(void) +{ + int __retres; + /*@ assert emitter2: ∀ ℤ x; x ≡ x; */ + int y = 0; + y ++; + /*@ assert y ≡ 1; */ + /*@ assert emitter2: ∀ ℤ x; x ≡ x; */ + ; + __retres = 0; + /*@ assert emitter2: ∀ ℤ x; x ≡ x; */ + return __retres; +} + + -- GitLab