From e5d8f501f448c2ed2da641e01c53cd7939355815 Mon Sep 17 00:00:00 2001 From: Nikos Gorogiannis Date: Wed, 20 Jun 2018 13:21:16 -0700 Subject: [PATCH] [starvation] fix conversions of int literals which need 64 bit ints Summary: Trying to convert a large int literal to an OCaml int raises an exception. The use case here actually needed a float anyway, so add an API for that. Reviewed By: jeremydubreil Differential Revision: D8550410 fbshipit-source-id: 382495b --- infer/src/IR/IntLit.ml | 2 ++ infer/src/IR/IntLit.mli | 3 +++ infer/src/concurrency/RacerDConfig.ml | 2 +- infer/tests/codetoanalyze/java/starvation/FutureGet.java | 7 +++++++ infer/tests/codetoanalyze/java/starvation/issues.exp | 1 + 5 files changed, 14 insertions(+), 1 deletion(-) diff --git a/infer/src/IR/IntLit.ml b/infer/src/IR/IntLit.ml index bf061b3ea..f293de05e 100644 --- a/infer/src/IR/IntLit.ml +++ b/infer/src/IR/IntLit.ml @@ -61,6 +61,8 @@ let of_int i = of_int64 (Int64.of_int i) let to_int (_, i, _) = Int64.to_int_exn i +let to_float (_, i, _) = Int64.to_float i + let null = (false, 0L, true) let zero = of_int 0 diff --git a/infer/src/IR/IntLit.mli b/infer/src/IR/IntLit.mli index 56072d06e..b4c7bd056 100644 --- a/infer/src/IR/IntLit.mli +++ b/infer/src/IR/IntLit.mli @@ -88,6 +88,9 @@ val shift_right : t -> t -> t val sub : t -> t -> t val to_int : t -> int +(** throws exception if literal is not representable as an OCaml int *) + +val to_float : t -> float val to_signed : t -> t option diff --git a/infer/src/concurrency/RacerDConfig.ml b/infer/src/concurrency/RacerDConfig.ml index 3ba625e63..f4e7cbecf 100644 --- a/infer/src/concurrency/RacerDConfig.ml +++ b/infer/src/concurrency/RacerDConfig.ml @@ -632,7 +632,7 @@ module Models = struct | _, [AccessPath.FieldAccess field] when String.equal "java.util.concurrent.TimeUnit" (Typ.Fieldname.Java.get_class field) -> let fieldname = Typ.Fieldname.Java.get_field field in - let duration = float_of_int (IntLit.to_int duration_lit) in + let duration = IntLit.to_float duration_lit in String.Map.find time_units fieldname |> Option.value_map ~default:false ~f:(fun unit_in_secs -> unit_in_secs *. duration >. android_anr_time_limit ) diff --git a/infer/tests/codetoanalyze/java/starvation/FutureGet.java b/infer/tests/codetoanalyze/java/starvation/FutureGet.java index 6ae7879a3..21b20c177 100644 --- a/infer/tests/codetoanalyze/java/starvation/FutureGet.java +++ b/infer/tests/codetoanalyze/java/starvation/FutureGet.java @@ -76,4 +76,11 @@ class FutureGet { future.get(5000001L, TimeUnit.MICROSECONDS); } catch (TimeoutException e) {} } + + @UiThread + void getTimeout64BitsBad() throws InterruptedException, ExecutionException { + try { + future.get(9223372036854775807L, TimeUnit.MICROSECONDS); + } catch (TimeoutException e) {} + } } diff --git a/infer/tests/codetoanalyze/java/starvation/issues.exp b/infer/tests/codetoanalyze/java/starvation/issues.exp index a5e5d98ff..62a5b67cc 100644 --- a/infer/tests/codetoanalyze/java/starvation/issues.exp +++ b/infer/tests/codetoanalyze/java/starvation/issues.exp @@ -15,6 +15,7 @@ codetoanalyze/java/starvation/Dedup.java, void Dedup.oneWayBad(), 36, DEADLOCK, codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getDirectBad(), 20, STARVATION, no_bucket, ERROR, [`void FutureGet.getDirectBad()`,calls `Object Future.get()` from `void FutureGet.getDirectBad()`] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getIndirectBad(), 25, STARVATION, no_bucket, ERROR, [[Trace 1] `void FutureGet.getIndirectBad()`,locks `this.FutureGet.lock` in class `FutureGet*`,[Trace 2] `void FutureGet.getUnderLock()`,locks `this.FutureGet.lock` in class `FutureGet*`,calls `Object Future.get()` from `void FutureGet.getUnderLock()`] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeout50000001MicroSecondsBad(), 76, STARVATION, no_bucket, ERROR, [`void FutureGet.getTimeout50000001MicroSecondsBad()`,calls `Object Future.get(long,TimeUnit)` from `void FutureGet.getTimeout50000001MicroSecondsBad()`] +codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeout64BitsBad(), 83, STARVATION, no_bucket, ERROR, [`void FutureGet.getTimeout64BitsBad()`,calls `Object Future.get(long,TimeUnit)` from `void FutureGet.getTimeout64BitsBad()`] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeoutOneDayBad(), 41, STARVATION, no_bucket, ERROR, [`void FutureGet.getTimeoutOneDayBad()`,calls `Object Future.get(long,TimeUnit)` from `void FutureGet.getTimeoutOneDayBad()`] codetoanalyze/java/starvation/FutureGet.java, void FutureGet.getTimeoutOneHourBad(), 55, STARVATION, no_bucket, ERROR, [`void FutureGet.getTimeoutOneHourBad()`,calls `Object Future.get(long,TimeUnit)` from `void FutureGet.getTimeoutOneHourBad()`] codetoanalyze/java/starvation/IndirectBlock.java, void IndirectBlock.takeExpensiveLockOnUiThreadBad(), 22, STARVATION, no_bucket, ERROR, [[Trace 1] `void IndirectBlock.takeExpensiveLockOnUiThreadBad()`,locks `this.IndirectBlock.expensiveLock` in class `IndirectBlock*`,[Trace 2] `void IndirectBlock.doTransactUnderLock()`,locks `this.IndirectBlock.expensiveLock` in class `IndirectBlock*`,calls `boolean Binder.transact(int,Parcel,Parcel,int)` from `void IndirectBlock.doTransactUnderLock()`]