[ownership] special-case frontend-generated inner destructors.

Reviewed By: da319

Differential Revision: D7189239

fbshipit-source-id: 7975603
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 2edc1d8581
commit 6976181b77

@ -762,6 +762,11 @@ module Procname = struct
is_objc_dealloc name.method_name
let is_inner_destructor ({method_name} as pname) =
is_destructor pname
&& String.is_prefix ~prefix:Config.clang_inner_destructor_prefix method_name
let is_constexpr = function {kind= CPPConstructor {is_constexpr= true}} -> true | _ -> false
let is_cpp_lambda {method_name} = String.is_substring ~substring:"operator()" method_name

@ -386,6 +386,9 @@ module Procname : sig
val is_destructor : t -> bool
(** Check if this is a dealloc method. *)
val is_inner_destructor : t -> bool
(** Check if this is a frontend-generated "inner" destructor (see D5834555/D7189239) *)
val is_constexpr : t -> bool
(** Check if this is a constexpr function. *)

@ -209,6 +209,10 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
match pname with
| Typ.Procname.ObjC_Cpp clang_pname ->
Typ.Procname.ObjC_Cpp.is_destructor clang_pname
&& not
(* Our frontend generates synthetic inner destructors to model invocation of base class
destructors correctly; see D5834555/D7189239 *)
(Typ.Procname.ObjC_Cpp.is_inner_destructor clang_pname)
| _ ->
false

@ -1,13 +1,13 @@
codetoanalyze/cpp/ownership/closures.cpp, implicit_ref_capture_destroy_invoke_bad, 6, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/closures.cpp, reassign_lambda_capture_destroy_invoke_bad, 7, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/closures.cpp, ref_capture_destroy_invoke_bad, 6, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, delete_in_branch_bad, 5, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, delete_in_loop_bad, 3, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, deref_deleted_bad, 3, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, double_delete_bad, 3, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, reassign_field_of_deleted_bad, 3, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, return_deleted_bad, 3, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, use_in_branch_bad, 4, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, use_in_loop_bad, 4, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_destructor.cpp, double_destructor_bad, 5, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_destructor.cpp, use_after_destructor_bad, 3, USE_AFTER_LIFETIME, [Use of invalid variable]
codetoanalyze/cpp/ownership/closures.cpp, implicit_ref_capture_destroy_invoke_bad, 6, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/closures.cpp, reassign_lambda_capture_destroy_invoke_bad, 7, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/closures.cpp, ref_capture_destroy_invoke_bad, 6, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, delete_in_branch_bad, 5, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, delete_in_loop_bad, 3, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, deref_deleted_bad, 3, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, double_delete_bad, 3, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, reassign_field_of_deleted_bad, 3, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, return_deleted_bad, 3, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, use_in_branch_bad, 4, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_delete.cpp, use_in_loop_bad, 4, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_destructor.cpp, double_destructor_bad, 5, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]
codetoanalyze/cpp/ownership/use_after_destructor.cpp, use_after_destructor_bad, 3, USE_AFTER_LIFETIME, ERROR, [Use of invalid variable]

@ -96,3 +96,20 @@ void destruct_twice_ok() {
p = tmp;
} // destructor for tmp
} // destructor for p runs here, but it's harmless
class Subclass : virtual POD {
int* f;
Subclass() { f = new int; }
/** frontend code for this destructor will be:
* ~Subclass:
* __infer_inner_destructor_~Subclass(this)
* __infer_inner_destructor_~POD(this)
*
* __infer_inner_destructor_~Subclass:
* delete f;
*
* We need to be careful not to warn that this has been double-destructed
*/
~Subclass() { delete f; }
};

Loading…
Cancel
Save