[Eradicate] Fix issue in Eradicate's check for field initialization

Summary:
Eradicate currently considers a field initialized if it's simply accessed (not written to),
or initialized with another initialized field.
This fixes the issue.

Reviewed By: jvillard

Differential Revision: D4449541

fbshipit-source-id: 06265a8
master
Cristiano Calcagno 8 years ago committed by Facebook Github Bot
parent f79a53e1c8
commit 3f8ee7df49

@ -259,10 +259,20 @@ let check_constructor_initialization tenv
list in
let may_be_assigned_in_final_typestate =
let origin_is_initialized = function
| TypeOrigin.Undef ->
false
| TypeOrigin.Field (f, _) ->
(* field initialized with another field needing initialization *)
let circular =
IList.exists (fun (f', _, _) -> Ident.equal_fieldname f f') fields in
not circular
| _ ->
true in
final_type_annotation_with
false
(Lazy.force final_initializer_typestates)
(fun ta -> TypeAnnotation.get_origin ta <> TypeOrigin.Undef) in
(fun ta -> origin_is_initialized (TypeAnnotation.get_origin ta)) in
let may_be_nullable_in_final_typestate () =
final_type_annotation_with

@ -44,4 +44,56 @@ public class FieldNotInitialized {
f = null; // OK the framework could write null into the field
g = null; // OK the framework could write null into the field
}
class OnlyRead {
Object o;
OnlyRead() {
Object x = o; // not initialized
}
}
class WriteItself {
Object o;
WriteItself() {
o = o; // not initialized
}
}
class Swap {
Object o1;
Object o2;
Swap() {
o1 = o2; // not initialized
o2 = new Object();
}
}
class SwapOK {
Object o1;
Object o2;
SwapOK() {
o1 = new Object();
o2 = o1;
}
}
class OnlyReadIndirect {
Object o1;
Object o2;
private void indirect() {
Object x = o1; // not initialized
o2 = new Object();
}
OnlyReadIndirect() {
indirect();
}
}
}

@ -1,4 +1,8 @@
codetoanalyze/java/eradicate/ActivityFieldNotInitialized.java, ActivityFieldNotInitialized$BadActivityWithOnCreate.<init>(ActivityFieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, [Field `ActivityFieldNotInitialized$BadActivityWithOnCreate.field` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/eradicate/FieldNotInitialized.java, FieldNotInitialized$OnlyRead.<init>(FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, [Field `FieldNotInitialized$OnlyRead.o` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/eradicate/FieldNotInitialized.java, FieldNotInitialized$OnlyReadIndirect.<init>(FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, [Field `FieldNotInitialized$OnlyReadIndirect.o1` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/eradicate/FieldNotInitialized.java, FieldNotInitialized$Swap.<init>(FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, [Field `FieldNotInitialized$Swap.o1` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/eradicate/FieldNotInitialized.java, FieldNotInitialized$WriteItself.<init>(FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, [Field `FieldNotInitialized$WriteItself.o` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/eradicate/FieldNotInitialized.java, FieldNotInitialized.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, [Field `FieldNotInitialized.a` is not initialized in the constructor and is not declared `@Nullable`]
codetoanalyze/java/eradicate/FieldNotNullable.java, FieldNotNullable.<init>(Integer), -25, ERADICATE_FIELD_NOT_NULLABLE, [origin,Field `FieldNotNullable.static_s` can be null but is not declared `@Nullable`. (Origin: null constant at line 39)]
codetoanalyze/java/eradicate/FieldNotNullable.java, FieldNotNullable.<init>(String), -2, ERADICATE_FIELD_NOT_NULLABLE, [origin,Field `FieldNotNullable.static_s` can be null but is not declared `@Nullable`. (Origin: null constant at line 39)]

Loading…
Cancel
Save