From 9066e5bd0802a87bd5c4a28f9259fac8d2371fbe Mon Sep 17 00:00:00 2001 From: Sam Blackshear Date: Thu, 16 Mar 2017 14:09:35 -0700 Subject: [PATCH] [thread-safety] account for ownership via reflective allocation Reviewed By: jeremydubreil Differential Revision: D4722711 fbshipit-source-id: 3b52ef5 --- infer/src/checkers/ThreadSafety.ml | 3 +++ .../java/threadsafety/Ownership.java | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/infer/src/checkers/ThreadSafety.ml b/infer/src/checkers/ThreadSafety.ml index 7a73dcc61..290c4ec76 100644 --- a/infer/src/checkers/ThreadSafety.ml +++ b/infer/src/checkers/ThreadSafety.ml @@ -320,6 +320,9 @@ module TransferFunctions (CFG : ProcCfg.S) = struct | "javax.inject.Provider", "get" -> (* in dependency injection, the library allocates fresh values behind the scenes *) true + | ("java.lang.Class" | "java.lang.reflect.Constructor"), "newInstance" -> + (* reflection can perform allocations *) + true | "java.lang.ThreadLocal", "get" -> (* ThreadLocal prevents sharing between threads behind the scenes *) true diff --git a/infer/tests/codetoanalyze/java/threadsafety/Ownership.java b/infer/tests/codetoanalyze/java/threadsafety/Ownership.java index 51cb91473..1ff2c4dc6 100644 --- a/infer/tests/codetoanalyze/java/threadsafety/Ownership.java +++ b/infer/tests/codetoanalyze/java/threadsafety/Ownership.java @@ -9,6 +9,10 @@ package codetoanalyze.java.checkers; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + + import javax.annotation.concurrent.ThreadSafe; import javax.inject.Inject; import javax.inject.Provider; @@ -353,6 +357,20 @@ public class Ownership { castThenReturn(o).f = new Object(); } + void ownViaReflectionOk1() throws InstantiationException, IllegalAccessException { + Class oClass = Obj.class; + Obj o = oClass.newInstance(); + o.f = new Object(); + } + + void ownViaReflectionOk2() + throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException { + Class oClass = Obj.class; + Constructor oConstructor = oClass.getConstructor(); + Obj o = oConstructor.newInstance(); + o.f = new Object(); + } + }