[inferbo] Add model of Class.getCanonicalName

Summary: Similarly to Enum.name, we model Class.getCanonicalName as returning an arbitrary non-empty string.

Reviewed By: ngorogiannis

Differential Revision: D21207120

fbshipit-source-id: 1e2dbd1fd
master
Sungkeun Cho 5 years ago committed by Facebook GitHub Bot
parent 0b6c5172a8
commit 3aaf260b8b

@ -522,10 +522,15 @@ module ArrObjCommon = struct
Sem.eval_array_locs_length (deref_of model_env exp ~fn mem) mem Sem.eval_array_locs_length (deref_of model_env exp ~fn mem) mem
let size_exec exp ~fn model_env ~ret:(id, _) mem = let size_exec exp ~fn ({integer_type_widths} as model_env) ~ret:(id, _) mem =
let arr_locs = deref_of model_env exp ~fn mem in let locs = Sem.eval integer_type_widths exp mem |> Dom.Val.get_all_locs in
let mem = Dom.Mem.add_stack (Loc.of_id id) (Sem.eval_array_locs_length arr_locs mem) mem in match PowLoc.is_singleton_or_more locs with
load_size_alias id arr_locs mem | Singleton (Loc.Allocsite (Allocsite.LiteralString s)) ->
model_by_value (Dom.Val.of_int (String.length s)) id mem
| _ ->
let arr_locs = deref_of model_env exp ~fn mem in
let mem = Dom.Mem.add_stack (Loc.of_id id) (Sem.eval_array_locs_length arr_locs mem) mem in
load_size_alias id arr_locs mem
let at arr_exp ~fn index_exp = let at arr_exp ~fn index_exp =
@ -1183,18 +1188,16 @@ module JavaString = struct
{exec; check= no_check} {exec; check= no_check}
let copy_constructor_constant tgt_exp s = copy_constructor tgt_exp (Exp.Const (Const.Cstr s)) let empty_constructor tgt_exp = copy_constructor tgt_exp (Exp.Const (Const.Cstr ""))
let empty_constructor tgt_exp = copy_constructor_constant tgt_exp ""
(* We model Enum.name as returing a constant name, rather than getting real field names. We did (* We model Enum.name or Class.getCanonicalName as returning an arbitrary constant name, rather
this because we couldn't think of any big gains from getting the real names. *) than getting real names. We did this because we couldn't think of any big gains from getting
let enum_name tgt_exp = the real names in terms of analysis precision. *)
let {exec= constructor_exec} = copy_constructor_constant tgt_exp "EnumName" in let inferbo_constant_string =
let exec ({integer_type_widths} as model_env) ~ret:((ret_id, _) as ret) mem = let constant_string_val =
let v = Sem.eval integer_type_widths tgt_exp mem in Loc.of_allocsite (Allocsite.literal_string "__constant_string") |> Dom.Val.of_loc
constructor_exec model_env ~ret mem |> model_by_value v ret_id
in in
let exec _model_env ~ret:(ret_id, _) mem = model_by_value constant_string_val ret_id mem in
{exec; check= no_check} {exec; check= no_check}
@ -1564,5 +1567,7 @@ module Call = struct
; +PatternMatch.implements_lang "Math" ; +PatternMatch.implements_lang "Math"
&:: "min" <>$ capt_exp $+ capt_exp &:: "min" <>$ capt_exp $+ capt_exp
$--> eval_binop ~f:(Itv.min_sem ~use_minmax_bound:true) $--> eval_binop ~f:(Itv.min_sem ~use_minmax_bound:true)
; +PatternMatch.implements_lang "Enum" &:: "name" <>$ capt_exp $--> JavaString.enum_name ] ; +PatternMatch.implements_lang "Enum" &:: "name" &::.*--> JavaString.inferbo_constant_string
; +PatternMatch.implements_lang "Class"
&:: "getCanonicalName" &::.*--> JavaString.inferbo_constant_string ]
end end

@ -108,4 +108,8 @@ class StringTest {
i = j; i = j;
} }
} }
void class_get_canonical_name_constant(Integer a) {
for (int i = 0; i < a.getClass().getCanonicalName().length(); i++) {}
}
} }

@ -194,6 +194,8 @@ codetoanalyze/java/performance/PreconditionTest.java, PreconditionTest.checkNotN
codetoanalyze/java/performance/StringBuilderTest.java, StringBuilderTest.append_linear(java.lang.String):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 25 + 5 ⋅ (s.length + 2) + 3 ⋅ (s.length + 3), O(s.length), degree = 1,{s.length + 3},call to void StringBuilderTest.new_linear(String),Loop at line 13,{s.length + 2},call to void StringBuilderTest.new_linear(String),Loop at line 13] codetoanalyze/java/performance/StringBuilderTest.java, StringBuilderTest.append_linear(java.lang.String):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 25 + 5 ⋅ (s.length + 2) + 3 ⋅ (s.length + 3), O(s.length), degree = 1,{s.length + 3},call to void StringBuilderTest.new_linear(String),Loop at line 13,{s.length + 2},call to void StringBuilderTest.new_linear(String),Loop at line 13]
codetoanalyze/java/performance/StringBuilderTest.java, StringBuilderTest.new_linear(java.lang.String):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 9 + 5 ⋅ s.length + 3 ⋅ (s.length + 1), O(s.length), degree = 1,{s.length + 1},Loop at line 13,{s.length},Loop at line 13] codetoanalyze/java/performance/StringBuilderTest.java, StringBuilderTest.new_linear(java.lang.String):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 9 + 5 ⋅ s.length + 3 ⋅ (s.length + 1), O(s.length), degree = 1,{s.length + 1},Loop at line 13,{s.length},Loop at line 13]
codetoanalyze/java/performance/StringTest.java, StringTest.byte_array_constructor_linear(byte[]):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ data.length + 3 ⋅ (data.length + 1), O(data.length), degree = 1,{data.length + 1},Loop at line 55,{data.length},Loop at line 55] codetoanalyze/java/performance/StringTest.java, StringTest.byte_array_constructor_linear(byte[]):void, 2, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 6 + 5 ⋅ data.length + 3 ⋅ (data.length + 1), O(data.length), degree = 1,{data.length + 1},Loop at line 55,{data.length},Loop at line 55]
codetoanalyze/java/performance/StringTest.java, StringTest.class_get_canonical_name_constant(java.lang.Integer):void, 1, BUFFER_OVERRUN_U5, no_bucket, ERROR, [<Length trace>,Unknown value from: Class Object.getClass(),Assignment,Array access: Offset: [-oo, +oo] Size: [0, +oo]]
codetoanalyze/java/performance/StringTest.java, StringTest.class_get_canonical_name_constant(java.lang.Integer):void, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 249, O(1), degree = 0]
codetoanalyze/java/performance/StringTest.java, StringTest.index_substring_linear():java.lang.String, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 9 + this.mId.length, O(this.mId.length), degree = 1,{this.mId.length},call to int StringTest.indexof_linear(String),Modeled call to String.indexOf] codetoanalyze/java/performance/StringTest.java, StringTest.index_substring_linear():java.lang.String, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 9 + this.mId.length, O(this.mId.length), degree = 1,{this.mId.length},call to int StringTest.indexof_linear(String),Modeled call to String.indexOf]
codetoanalyze/java/performance/StringTest.java, StringTest.indexof_from_linear(java.lang.String,int):int, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 3 + (-j + m.length), O((-j + m.length)), degree = 1,{-j + m.length},Modeled call to String.indexOf] codetoanalyze/java/performance/StringTest.java, StringTest.indexof_from_linear(java.lang.String,int):int, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 3 + (-j + m.length), O((-j + m.length)), degree = 1,{-j + m.length},Modeled call to String.indexOf]
codetoanalyze/java/performance/StringTest.java, StringTest.indexof_linear(java.lang.String):int, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 2 + m.length, O(m.length), degree = 1,{m.length},Modeled call to String.indexOf] codetoanalyze/java/performance/StringTest.java, StringTest.indexof_linear(java.lang.String):int, 1, EXPENSIVE_EXECUTION_TIME, no_bucket, ERROR, [with estimated cost 2 + m.length, O(m.length), degree = 1,{m.length},Modeled call to String.indexOf]

Loading…
Cancel
Save