Summary:
If a race exists in two or more overloads of the same method and we use only the class and method name in the report text, then the current bug hashing algorithm will identify the two reports as duplicates.
To avoid this, the report had the class, method and list of type parameters. This is unreadable, however, and redundant (the report is already located within the method in question). So at the risk of duplicates, use only class+method names.
Also, fix a bug in `Procname.pp_simplified ~withclass` where `withclass` was ignored for C++/ObjC methods.
Now:
> Read/Write race. Non-private method `FrescoVitoImageSpec.onCreateInitialState(...)` indirectly reads with synchronization from `factory.AnimatedFactoryProvider.sImpl`. Potentially races with unsynchronized write in method `FrescoVitoImageSpec.onEnteredWorkingRange(...)`.@ [Litho components are required to be thread safe because of multi-threaded layout](https://fburl.com/background-layout). Reporting because current class is annotated `MountSpec`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).
Before
> Read/Write race. Non-private method `void FrescoVitoImageSpec.onCreateInitialState(ComponentContext,StateValue,StateValue,Uri,MultiUri,ImageOptions,FrescoContext,Object,ImageListener)` indirectly reads with synchronization from `factory.AnimatedFactoryProvider.sImpl`. Potentially races with unsynchronized write in method `FrescoVitoImageSpec.onEnteredWorkingRange(...)`.@ [Litho components are required to be thread safe because of multi-threaded layout](https://fburl.com/background-layout). Reporting because current class is annotated `MountSpec`, so we assume that this method can run in parallel with other non-private methods in the class (including itself).
Reviewed By: artempyanykh
Differential Revision: D19462277
fbshipit-source-id: aebc20d89
master
Nikos Gorogiannis5 years agocommitted byFacebook Github Bot
codetoanalyze/cpp/nullable/method.cpp, assignNullableValueBad, 2, NULL_DEREFERENCE, B2, ERROR, [start of procedure assignNullableValueBad(),start of procedure mayReturnNullPointer,Taking true branch,return from a call to T::mayReturnNullPointer]
codetoanalyze/cpp/nullable/method.cpp, avoidDoubleReportingBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of p,assignment of the nullable value,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, avoidDoubleReportingBad, 2, NULL_DEREFERENCE, B2, ERROR, [start of procedure avoidDoubleReportingBad(),start of procedure mayReturnNullObject,Taking true branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, callMethodOnNullableObjectBad, 1, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, callMethodOnNullableObjectBad, 1, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, callMethodOnNullableObjectBad, 1, NULL_DEREFERENCE, B5, ERROR, [start of procedure callMethodOnNullableObjectBad(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, callMethodOnNullableObjectOkay, 2, NULL_TEST_AFTER_DEREFERENCE, no_bucket, WARNING, [start of procedure callMethodOnNullableObjectOkay(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking false branch]
codetoanalyze/cpp/nullable/method.cpp, dereferenceFieldOfNullableObjectBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of p,assignment of the nullable value,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, methodCheckedForNullOkay, 1, NULL_TEST_AFTER_DEREFERENCE, no_bucket, WARNING, [start of procedure methodCheckedForNullOkay(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking false branch]
codetoanalyze/cpp/nullable/method.cpp, methodCheckedForNullOkay, 2, NULL_DEREFERENCE, B5, ERROR, [start of procedure methodCheckedForNullOkay(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking true branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, methodNotAlwaysCheckedForNullBad, 1, NULL_TEST_AFTER_DEREFERENCE, no_bucket, WARNING, [start of procedure methodNotAlwaysCheckedForNullBad(),Taking false branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking false branch]
codetoanalyze/cpp/nullable/method.cpp, methodNotAlwaysCheckedForNullBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, methodNotAlwaysCheckedForNullBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, methodNotAlwaysCheckedForNullBad, 2, NULL_DEREFERENCE, B5, ERROR, [start of procedure methodNotAlwaysCheckedForNullBad(),Taking false branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking true branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, methodTestedForNullOkay, 1, NULL_TEST_AFTER_DEREFERENCE, no_bucket, WARNING, [start of procedure methodTestedForNullOkay(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking false branch]
codetoanalyze/cpp/nullable/method.cpp, methodTestedForNullOkay, 2, NULL_DEREFERENCE, B5, ERROR, [start of procedure methodTestedForNullOkay(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking true branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, nullableAssignmentInOneBranchBad, 7, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of p,assignment of the nullable value,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, nullableAssignmentInOneBranchBad, 7, NULL_DEREFERENCE, B2, ERROR, [start of procedure nullableAssignmentInOneBranchBad(),Taking true branch,start of procedure mayReturnNullObject,Taking true branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, onlyReportOnceBad, 1, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, onlyReportOnceBad, 1, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, onlyReportOnceBad, 1, NULL_DEREFERENCE, B5, ERROR, [start of procedure onlyReportOnceBad(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, onlyReportOnceBad, 3, NULL_DEREFERENCE, B5, ERROR, [start of procedure onlyReportOnceBad(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,start of procedure doSomething,return from a call to T::doSomething,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, pointerTestBad, 2, NULL_TEST_AFTER_DEREFERENCE, no_bucket, WARNING, [start of procedure pointerTestBad(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking false branch]
codetoanalyze/cpp/nullable/method.cpp, reassigningNullablePointerOkay, 1, DEAD_STORE, no_bucket, ERROR, [Write of unused value]
codetoanalyze/cpp/nullable/method.cpp, reassigningNullablePointerToNullOkay, 1, DEAD_STORE, no_bucket, ERROR, [Write of unused value]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNotNullElseBranchBad, 1, NULL_TEST_AFTER_DEREFERENCE, no_bucket, WARNING, [start of procedure reportsViolationInNotNullElseBranchBad(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking false branch]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNotNullElseBranchBad, 3, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNotNullElseBranchBad, 3, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNotNullElseBranchBad, 3, NULL_DEREFERENCE, B5, ERROR, [start of procedure reportsViolationInNotNullElseBranchBad(),start of procedure mayReturnNullObject,Taking true branch,return from a call to T::mayReturnNullObject,Taking false branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNullBranchBad, 1, NULL_TEST_AFTER_DEREFERENCE, no_bucket, WARNING, [start of procedure reportsViolationInNullBranchBad(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking false branch]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNullBranchBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNullBranchBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNullBranchBad, 2, NULL_DEREFERENCE, B5, ERROR, [start of procedure reportsViolationInNullBranchBad(),start of procedure mayReturnNullObject,Taking true branch,return from a call to T::mayReturnNullObject,Taking true branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 1, NULL_TEST_AFTER_DEREFERENCE, no_bucket, WARNING, [start of procedure reportsViolationOutsideOfNullCheckBad(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking false branch]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 2, NULL_DEREFERENCE, B5, ERROR, [start of procedure reportsViolationOutsideOfNullCheckBad(),start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject,Taking true branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 4, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 4, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::mayReturnNullObject,definition of mayReturnNullObject]
codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 4, NULL_DEREFERENCE, B5, ERROR, [start of procedure reportsViolationOutsideOfNullCheckBad(),start of procedure mayReturnNullObject,Taking true branch,return from a call to T::mayReturnNullObject,Taking false branch,start of procedure mayReturnNullObject,Taking false branch,return from a call to T::mayReturnNullObject]
codetoanalyze/cpp/racerd/basics.cpp, basics::Basic::get4, 43, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this->suspiciously_read`,<Write trace>,access to `this->suspiciously_read`]
codetoanalyze/cpp/racerd/basics.cpp, basics::Basic::get5, 45, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to basics::Basic::get_private_suspiciously_read,access to `this->suspiciously_read`,<Write trace>,access to `this->suspiciously_read`]
codetoanalyze/cpp/racerd/basics.cpp, basics::Basic::test_double_lock_bad, 81, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,access to `this->single_lock_suspiciously_read`,<Write trace>,access to `this->single_lock_suspiciously_read`]
codetoanalyze/cpp/racerd/dereferencing.cpp, dereferencing::Basic::call1, 51, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->w`,<Write trace>,call to dereferencing::Basic::call1,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->w`]
codetoanalyze/cpp/racerd/dereferencing.cpp, dereferencing::Basic::call1, 51, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to dereferencing::Basic::mixed_deref_race,access to `*(this->x.x2)->a.b.c`,<Write trace>,call to dereferencing::Basic::call1,call to dereferencing::Basic::mixed_deref_race,access to `*(this->x.x2)->a.b.c`]
codetoanalyze/cpp/racerd/dereferencing.cpp, dereferencing::Basic::call1, 51, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->w`,<Write trace>,call to dereferencing::Basic::call1,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->w`]
codetoanalyze/cpp/racerd/dereferencing.cpp, dereferencing::Basic::call1, 51, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->u`,<Write trace>,call to dereferencing::Basic::call1,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->u`]
codetoanalyze/cpp/racerd/dereferencing.cpp, dereferencing::Basic::test_unlock, 59, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to dereferencing::Basic::call1,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->w`,<Write trace>,call to dereferencing::Basic::call1,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->w`]
codetoanalyze/cpp/racerd/dereferencing.cpp, dereferencing::Basic::test_unlock, 59, LOCK_CONSISTENCY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to dereferencing::Basic::call1,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->u`,<Write trace>,call to dereferencing::Basic::call1,call to dereferencing::Basic::mixed_deref_race,access to `this->x.x1->u`]
codetoanalyze/objc/nullable/Examples.m, T::FP_dereferenceNonnullFieldAfterTestForNullOkay, 1, NULLSAFE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field nonnullField is compared to null here]
codetoanalyze/objc/nullable/Examples.m, T::addNullableObjectInMutableArrayBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::addNullableObjectInMutableArrayBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::createArrayByAddingNilBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::createArrayByAddingNilBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::dereferenceNullableFunctionBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of p,assignment of the nullable value,definition of returnsNull]
codetoanalyze/objc/nullable/Examples.m, T::dereferenceNullableLibraryMethodBad:, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableObject,assignment of the nullable value,definition of nullableLibraryMethod]
codetoanalyze/objc/nullable/Examples.m, T::dereferenceUnnanotatedFieldAfterTestForNullBad, 1, NULLSAFE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field unnanotatedField is compared to null here]
codetoanalyze/objc/nullable/Examples.m, T::indirectNullableKeyInNSDictionaryBad, 3, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableKeyString,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::insertNullableObjectInMutableArrayBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::insertNullableObjectInMutableArrayBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullableKeyInNSDictionaryBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableKey,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullableKeyInNSDictionaryInitBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableKey,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullableKeyInNSDictionaryInitLiteralBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableKey,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullableObjectInNSArrayBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableObject,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullablePropertyInNSArrayBad, 1, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullablePropertyInNSArrayBad, 1, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullableValueInNSDictionaryBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableValue,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullableValueInNSDictionaryInitBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableValue,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::nullableValueInNSDictionaryInitLiteralBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableValue,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::propagateNullabilityOnMethodCallBad, 4, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableString,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::secondElementNullableObjectInNSArrayBad, 3, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of nullableObject,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::setNullableObjectInDictionaryBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::setNullableObjectInDictionaryBad, 2, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of T::nullableMethod,assignment of the nullable value,definition of nullableMethod]
codetoanalyze/objc/nullable/Examples.m, T::shouldPropagateNullabilityOnPointerTypeBad, 3, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereference of s,assignment of the nullable value,definition of nullableT]
codetoanalyze/objc/nullable/Examples.m, T::testNonnullFieldForNullBad, 1, NULLSAFE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field nonnullField is compared to null here]
codetoanalyze/objc/nullable/Examples.m, T::testUnnanotatedFieldForNullBad, 1, NULLSAFE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [Field unnanotatedField is compared to null here]
codetoanalyze/objcpp/nullable/Examples.mm, stdStringBad, 1, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of toString,assignment of the nullable value,definition of toString]
codetoanalyze/objcpp/nullable/Examples.mm, stdStringBad, 1, NULLSAFE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [dereferencing the return of A::toString,assignment of the nullable value,definition of toString]