diff --git a/convert.ml b/convert.ml index 2d3529962075fd941631d0dffdd83541eb15f0be..c251a175190468813a87a5d093c75ab6897d1e73 100644 --- a/convert.ml +++ b/convert.ml @@ -40,6 +40,8 @@ let make_lambda_cons_name s1 = s1 ^ "_cons" let fc_implicit_attr = "__fc_implicit" +let fc_pure_template_decl_attr = "__fc_pure_template_decl" + let capture_name_type env = function | Cap_id (s, typ, is_ref) -> @@ -3494,6 +3496,9 @@ let constify_receiver kind args = this :: args | _ -> args +let is_pure_templated_decl kind body has_further_definition = + kind <> TStandard && body = None && not has_further_definition + let rec collect_class_components env body = List.fold_left convert_class_component (env,[],[],[],[]) (reorder_implicit body) @@ -3541,6 +3546,8 @@ and convert_class_component (env, implicits, types, fields, others) meth = let name = if implicit then (n,dt,(fc_implicit_attr,[])::a,loc) + else if is_pure_templated_decl tkind body has_further_definition then + (n,dt, (fc_pure_template_decl_attr,[])::a,loc) else name in let has_virtual_base = Class.has_virtual_base_class class_name in @@ -4149,7 +4156,7 @@ let convert_ast file = Frama_Clang_option.debug ~dkey "Before reordering:@\n%a" Cprint.printFile res; Reorder_defs.reorder res -let remove_implicit file = +let remove_unneeded file = let open Cil_types in let destructors = ref Datatype.String.Set.empty in let rec add_name = function @@ -4169,8 +4176,9 @@ let remove_implicit file = Cil.visitCilFileSameGlobals collect_destructors file; let isRoot = function | GFunDecl(_,v,_) | GFun ({svar = v},_) -> - not (Cil.hasAttribute fc_implicit_attr v.vattr) - || Datatype.String.Set.mem v.vname !destructors + not (Cil.hasAttribute fc_pure_template_decl_attr v.vattr) && + (not (Cil.hasAttribute fc_implicit_attr v.vattr) + || Datatype.String.Set.mem v.vname !destructors) | _ -> true in Rmtmps.removeUnused ~isRoot file diff --git a/convert.mli b/convert.mli index 987382943598f8fe4060fe56f7a7d1e31819200d..931700b0763448b1854fa7cab5c66cede04e6773 100644 --- a/convert.mli +++ b/convert.mli @@ -26,10 +26,19 @@ open Intermediate_format by Frama-Clang. *) val fc_implicit_attr: string +(** attribute decorating templated member functions that are never defined + (i.e. fully instantiated). Their presence in the AST tends to be + dependent on the clang version used for type-checking. +*) +val fc_pure_template_decl_attr: string + (** creates the name of the field corresponding to a direct base class. *) val create_base_field_name: Convert_env.env -> qualified_name -> tkind -> string - + val convert_ast: Intermediate_format.file -> Cabs.file -(** remove unused implicit definitions. *) -val remove_implicit: Cil_types.file -> unit +(** remove unneeded definitions and declarations. Notably: + - unused implicit definitions + - templated member functions that are not defined and never used. +*) +val remove_unneeded: Cil_types.file -> unit diff --git a/frama_Clang_register.ml b/frama_Clang_register.ml index de3b86f72a293be405a8670f907c2836cc2f738d..ebb6281abfaad93c346314cc3d72cd4168cc143a 100644 --- a/frama_Clang_register.ml +++ b/frama_Clang_register.ml @@ -133,6 +133,7 @@ let init_cxx_normalization () = if not !is_initialized then begin is_initialized:=true; Cil_printer.register_shallow_attribute Convert.fc_implicit_attr; + Cil_printer.register_shallow_attribute Convert.fc_pure_template_decl_attr; Printer.update_printer (module Cxx_printer); (* enable exception removal unless it has explicitely been set to false on the command line. @@ -175,7 +176,7 @@ let parse_cxx file = Frama_Clang_option.feedback ~dkey "Generated Cabs code:@\n%a" Cprint.printFile cabs; let cil = Cabs2cil.convFile cabs in - Convert.remove_implicit cil; + Convert.remove_unneeded cil; (cil, cabs) let cxx_suffixes = [ ".cpp"; ".C"; ".cxx"; ".c++"; ".cc"; ".ii" ] diff --git a/tests/stl/oracle/stl_shared_ptr_mistake10.res.oracle b/tests/stl/oracle/stl_shared_ptr_mistake10.res.oracle index d155ac18a8a844ebe73a7649fa9ceddf59a0274a..4adbb86fb77dcb1e41d4ff3db69e1c6b31813007 100644 --- a/tests/stl/oracle/stl_shared_ptr_mistake10.res.oracle +++ b/tests/stl/oracle/stl_shared_ptr_mistake10.res.oracle @@ -1734,27 +1734,6 @@ void shared_ptr<Aircraft>::Ctor(struct shared_ptr<Aircraft> const *this) void shared_ptr<Aircraft>::Ctor(struct shared_ptr<Aircraft> const *this, struct Aircraft *p); -/*@ requires \separated(this, r); - requires \valid_read(this); - requires \valid_read(r); - */ -void shared_ptr<Aircraft>::Ctor(struct shared_ptr<Aircraft> const *this, - struct shared_ptr<Aircraft> const *r); - -/*@ requires \separated(this, r); - requires \valid_read(this); - requires \valid(r); - */ -void shared_ptr<Aircraft>::Ctor(struct shared_ptr<Aircraft> const *this, - struct shared_ptr<Aircraft> *r) -{ - this->__ptr = r->__ptr; - this->_ref = r->_ref; - r->__ptr = (struct Aircraft *)0; - r->_ref = (struct __shared_ref_base *)0; - return; -} - void shared_ptr<Aircraft>::Ctor(struct shared_ptr<Aircraft> const *this, struct weak_ptr<Aircraft> const *r); @@ -2073,18 +2052,6 @@ void weak_ptr<Aircraft>::Ctor(struct weak_ptr<Aircraft> const *this) return; } -/*@ requires \valid_read(this); - requires \valid_read(r); */ -void weak_ptr<Aircraft>::Ctor(struct weak_ptr<Aircraft> const *this, - struct shared_ptr<Aircraft> const *r); - -/*@ requires \separated(this, r); - requires \valid_read(this); - requires \valid_read(r); - */ -void weak_ptr<Aircraft>::Ctor(struct weak_ptr<Aircraft> const *this, - struct weak_ptr<Aircraft> const *r); - /*@ requires \valid_read(this); */ void weak_ptr<Aircraft>::Dtor(struct weak_ptr<Aircraft> const *this) { @@ -2105,12 +2072,6 @@ void weak_ptr<Aircraft>::Dtor(struct weak_ptr<Aircraft> const *this) struct weak_ptr<Aircraft> *operator=(struct weak_ptr<Aircraft> *this, struct weak_ptr<Aircraft> const *r); -/*@ requires \valid(this); - requires \valid_read(r); - ensures \valid(\result); */ -struct weak_ptr<Aircraft> *operator=<Aircraft,void>(struct weak_ptr<Aircraft> *this, - struct weak_ptr<Aircraft> const *r); - /*@ requires \valid(this); requires \valid_read(r); ensures __fc_exn.exn_uncaught ≡ 0 ⇒ \valid(\result); diff --git a/tests/stl/oracle/stl_shared_ptr_mistake5.res.oracle b/tests/stl/oracle/stl_shared_ptr_mistake5.res.oracle index 62dc277cc040a88d2573c803f90b11ef0c438ef4..4402c8aeace38b401b7dbb1c1b7f795ae5ec241a 100644 --- a/tests/stl/oracle/stl_shared_ptr_mistake5.res.oracle +++ b/tests/stl/oracle/stl_shared_ptr_mistake5.res.oracle @@ -2014,13 +2014,6 @@ void weak_ptr<Aircraft>::Ctor(struct weak_ptr<Aircraft> const *this) return; } -/*@ requires \separated(this, r); - requires \valid_read(this); - requires \valid_read(r); - */ -void weak_ptr<Aircraft>::Ctor(struct weak_ptr<Aircraft> const *this, - struct weak_ptr<Aircraft> const *r); - /*@ requires \valid_read(this); */ void weak_ptr<Aircraft>::Dtor(struct weak_ptr<Aircraft> const *this) { @@ -2039,12 +2032,6 @@ void weak_ptr<Aircraft>::Dtor(struct weak_ptr<Aircraft> const *this) struct weak_ptr<Aircraft> *operator=(struct weak_ptr<Aircraft> *this, struct weak_ptr<Aircraft> const *r); -/*@ requires \valid(this); - requires \valid_read(r); - ensures \valid(\result); */ -struct weak_ptr<Aircraft> *operator=<Aircraft,void>(struct weak_ptr<Aircraft> *this, - struct weak_ptr<Aircraft> const *r); - /*@ requires \valid(this); requires \valid(r); */ void swap(struct weak_ptr<Aircraft> *this, struct weak_ptr<Aircraft> *r); diff --git a/tests/stl/oracle/stl_shared_ptr_mistake6.res.oracle b/tests/stl/oracle/stl_shared_ptr_mistake6.res.oracle index 9d26c14a70048ce5ca6e1723e0baf41afeffc227..8784981af35674592d6b5c0686f87545ddda83b4 100644 --- a/tests/stl/oracle/stl_shared_ptr_mistake6.res.oracle +++ b/tests/stl/oracle/stl_shared_ptr_mistake6.res.oracle @@ -2020,13 +2020,6 @@ void weak_ptr<Aircraft>::Ctor(struct weak_ptr<Aircraft> const *this) return; } -/*@ requires \separated(this, r); - requires \valid_read(this); - requires \valid_read(r); - */ -void weak_ptr<Aircraft>::Ctor(struct weak_ptr<Aircraft> const *this, - struct weak_ptr<Aircraft> const *r); - /*@ requires \valid_read(this); */ void weak_ptr<Aircraft>::Dtor(struct weak_ptr<Aircraft> const *this) { @@ -2045,12 +2038,6 @@ void weak_ptr<Aircraft>::Dtor(struct weak_ptr<Aircraft> const *this) struct weak_ptr<Aircraft> *operator=(struct weak_ptr<Aircraft> *this, struct weak_ptr<Aircraft> const *r); -/*@ requires \valid(this); - requires \valid_read(r); - ensures \valid(\result); */ -struct weak_ptr<Aircraft> *operator=<Aircraft,void>(struct weak_ptr<Aircraft> *this, - struct weak_ptr<Aircraft> const *r); - /*@ requires \valid(this); requires \valid(r); */ void swap(struct weak_ptr<Aircraft> *this, struct weak_ptr<Aircraft> *r); diff --git a/tests/stl/oracle/stl_utility.res.oracle b/tests/stl/oracle/stl_utility.res.oracle index 69dc88fa52bb4dab6386e234cc99df078bb6d365..2b79ae2cd02f09ea67f0031741708f01dba38dad 100644 --- a/tests/stl/oracle/stl_utility.res.oracle +++ b/tests/stl/oracle/stl_utility.res.oracle @@ -950,29 +950,6 @@ void pair<int&,bool>::Ctor(struct pair<int&,bool> const *this, int *x, return; } -/*@ requires \valid_read(this); - requires \valid_read(p); */ -void pair<int&,bool>::Ctor(struct pair<int&,bool> const *this, - struct pair<int,bool> const *p); - -/*@ requires \valid(this); - requires \valid_read(p); - ensures \valid(\result); */ -struct pair<int&,bool> *operator=<int&,bool,void>(struct pair<int&,bool> *this, - struct pair<int&,bool> const *p); - -/*@ requires \valid(this); - requires \valid_read(p); - ensures \valid(\result); */ -struct pair<int&,bool> *operator=<int,bool,void>(struct pair<int&,bool> *this, - struct pair<int,bool> const *p); - -/*@ requires \valid(this); - requires \valid(p); - ensures \valid(\result); */ -struct pair<int&,bool> *operator=<int&,bool,void>(struct pair<int&,bool> *this, - struct pair<int&,bool> *p); - struct pair<int&,bool> *operator=<int,bool,void>(struct pair<int&,bool> *this, struct pair<int,bool> *p);