diff --git a/infer/src/checkers/NullabilityCheck.ml b/infer/src/checkers/NullabilityCheck.ml index c4c20d859..8b176ab95 100644 --- a/infer/src/checkers/NullabilityCheck.ml +++ b/infer/src/checkers/NullabilityCheck.ml @@ -7,6 +7,7 @@ * of patent rights can be found in the PATENTS file in the same directory. *) +module F = Format module L = Logging module MF = MarkupFormatter module CallSites = AbstractDomain.FiniteSet (CallSite) @@ -38,22 +39,29 @@ module TransferFunctions (CFG : ProcCfg.S) = struct "Expecting a least one element in the set of call sites when analyzing %a" Typ.Procname.pp pname in - let message = + let simplified_pname = + Typ.Procname.to_simplified_string ~withclass:true (CallSite.pname call_site) + in + let is_direct_dereference = match ap with | (Var.LogicalVar _, _), _ -> - (* direct dereference without intermediate variable *) - Format.asprintf - "The return value of %s is annotated with %a and is dereferenced without being checked for null at %a" - (MF.monospaced_to_string - (Typ.Procname.to_simplified_string ~withclass:true (CallSite.pname call_site))) - MF.pp_monospaced annotation Location.pp loc - | _ -> - (* dereference with intermediate variable *) - Format.asprintf - "Variable %a is indirectly annotated with %a (source %a) and is dereferenced without being checked for null at %a" - (MF.wrap_monospaced AccessPath.pp) - ap MF.pp_monospaced annotation (MF.wrap_monospaced CallSite.pp) call_site Location.pp - loc + true + | (Var.ProgramVar pvar, _), _ -> + Pvar.is_frontend_tmp pvar + in + let message = + if is_direct_dereference then + (* direct dereference without intermediate variable *) + F.asprintf + "The return value of %s is annotated with %a and is dereferenced without being checked for null at %a" + (MF.monospaced_to_string simplified_pname) + MF.pp_monospaced annotation Location.pp loc + else + (* dereference with intermediate variable *) + F.asprintf + "Variable %a is indirectly annotated with %a (source %a) and is dereferenced without being checked for null at %a" + (MF.wrap_monospaced AccessPath.pp) + ap MF.pp_monospaced annotation (MF.wrap_monospaced CallSite.pp) call_site Location.pp loc in let exn = Exceptions.Checkers (issue_kind, Localise.verbatim_desc message) in let summary = extras in @@ -65,7 +73,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct [] | Some attributes -> let description = - Format.asprintf "definition of %s" (Typ.Procname.get_method callee_pname) + F.asprintf "definition of %s" (Typ.Procname.get_method callee_pname) in let trace_element = Errlog.make_trace_element 1 attributes.ProcAttributes.loc description [] @@ -82,7 +90,11 @@ module TransferFunctions (CFG : ProcCfg.S) = struct trace_element :: with_origin_site in let dereference_site = - let description = Format.asprintf "deference of %a" AccessPath.pp ap in + let description = + if is_direct_dereference then + F.asprintf "dereferencing the return of %s" simplified_pname + else F.asprintf "dereference of %a" AccessPath.pp ap + in Errlog.make_trace_element 0 loc description [] in dereference_site :: with_assignment_site diff --git a/infer/tests/codetoanalyze/cpp/nullable/issues.exp b/infer/tests/codetoanalyze/cpp/nullable/issues.exp index a8c2923d7..a5a5c7861 100644 --- a/infer/tests/codetoanalyze/cpp/nullable/issues.exp +++ b/infer/tests/codetoanalyze/cpp/nullable/issues.exp @@ -7,38 +7,38 @@ codetoanalyze/cpp/nullable/example.cpp, T_dereference_unnanotated_field_after_te codetoanalyze/cpp/nullable/example.cpp, T_dereference_unnanotated_field_after_test_for_null_bad, 2, NULL_DEREFERENCE, [start of procedure dereference_unnanotated_field_after_test_for_null_bad,Condition is true] codetoanalyze/cpp/nullable/example.cpp, T_test_nonnull_field_for_null_bad, 1, FIELD_SHOULD_BE_NULLABLE, [Field nonnull_field is compared to null here] codetoanalyze/cpp/nullable/example.cpp, T_test_unnanotated_field_for_null_bad, 1, FIELD_SHOULD_BE_NULLABLE, [Field unnanotated_field is compared to null here] -codetoanalyze/cpp/nullable/method.cpp, assignNullableValueBad, 2, NULLABLE_DEREFERENCE, [deference of &p,assignment of the nullable value,definition of mayReturnNullPointer] +codetoanalyze/cpp/nullable/method.cpp, assignNullableValueBad, 2, NULLABLE_DEREFERENCE, [dereference of &p,assignment of the nullable value,definition of mayReturnNullPointer] codetoanalyze/cpp/nullable/method.cpp, assignNullableValueBad, 2, NULL_DEREFERENCE, [start of procedure assignNullableValueBad(),start of procedure mayReturnNullPointer,Condition is true,return from a call to T_mayReturnNullPointer] -codetoanalyze/cpp/nullable/method.cpp, avoidDoubleReportingBad, 2, NULLABLE_DEREFERENCE, [deference of &p,assignment of the nullable value,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, avoidDoubleReportingBad, 2, NULLABLE_DEREFERENCE, [dereference of &p,assignment of the nullable value,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, avoidDoubleReportingBad, 2, NULL_DEREFERENCE, [start of procedure avoidDoubleReportingBad(),start of procedure mayReturnNullObject,Condition is true,return from a call to T_mayReturnNullObject] -codetoanalyze/cpp/nullable/method.cpp, callMethodOnNullableObjectBad, 1, NULLABLE_DEREFERENCE, [deference of n$2,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, callMethodOnNullableObjectBad, 1, NULLABLE_DEREFERENCE, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, callMethodOnNullableObjectBad, 1, NULL_DEREFERENCE, [start of procedure callMethodOnNullableObjectBad(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, callMethodOnNullableObjectOkay, 2, NULL_TEST_AFTER_DEREFERENCE, [start of procedure callMethodOnNullableObjectOkay(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is false] -codetoanalyze/cpp/nullable/method.cpp, dereferenceFieldOfNullableObjectBad, 2, NULLABLE_DEREFERENCE, [deference of &p,assignment of the nullable value,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, dereferenceFieldOfNullableObjectBad, 2, NULLABLE_DEREFERENCE, [dereference of &p,assignment of the nullable value,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, dereferenceFieldOfNullableObjectBad, 2, NULL_DEREFERENCE, [start of procedure dereferenceFieldOfNullableObjectBad(),start of procedure mayReturnNullObject,Condition is true,return from a call to T_mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, methodAlwaysCheckedForNullOkay, 1, NULL_TEST_AFTER_DEREFERENCE, [start of procedure methodAlwaysCheckedForNullOkay(),Condition is true,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is false] codetoanalyze/cpp/nullable/method.cpp, methodAlwaysCheckedForNullOkay, 2, NULL_DEREFERENCE, [start of procedure methodAlwaysCheckedForNullOkay(),Condition is true,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is true,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] -codetoanalyze/cpp/nullable/method.cpp, methodCallOnFieldOfNullableObjectBad, 2, NULLABLE_DEREFERENCE, [deference of &p,assignment of the nullable value,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, methodCallOnFieldOfNullableObjectBad, 2, NULLABLE_DEREFERENCE, [dereference of &p,assignment of the nullable value,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, methodCallOnFieldOfNullableObjectBad, 2, NULL_DEREFERENCE, [start of procedure methodCallOnFieldOfNullableObjectBad(),start of procedure mayReturnNullObject,Condition is true,return from a call to T_mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, methodCheckedForNullOkay, 1, NULL_TEST_AFTER_DEREFERENCE, [start of procedure methodCheckedForNullOkay(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is false] codetoanalyze/cpp/nullable/method.cpp, methodCheckedForNullOkay, 2, NULL_DEREFERENCE, [start of procedure methodCheckedForNullOkay(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is true,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, methodNotAlwaysCheckedForNullBad, 1, NULL_TEST_AFTER_DEREFERENCE, [start of procedure methodNotAlwaysCheckedForNullBad(),Condition is false,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is false] -codetoanalyze/cpp/nullable/method.cpp, methodNotAlwaysCheckedForNullBad, 2, NULLABLE_DEREFERENCE, [deference of n$6,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, methodNotAlwaysCheckedForNullBad, 2, NULLABLE_DEREFERENCE, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, methodNotAlwaysCheckedForNullBad, 2, NULL_DEREFERENCE, [start of procedure methodNotAlwaysCheckedForNullBad(),Condition is false,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is true,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] -codetoanalyze/cpp/nullable/method.cpp, nullableAssignmentInOneBranchBad, 7, NULLABLE_DEREFERENCE, [deference of &p,assignment of the nullable value,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, nullableAssignmentInOneBranchBad, 7, NULLABLE_DEREFERENCE, [dereference of &p,assignment of the nullable value,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, nullableAssignmentInOneBranchBad, 7, NULL_DEREFERENCE, [start of procedure nullableAssignmentInOneBranchBad(),Condition is true,start of procedure mayReturnNullObject,Condition is true,return from a call to T_mayReturnNullObject] -codetoanalyze/cpp/nullable/method.cpp, onlyReportOnceBad, 1, NULLABLE_DEREFERENCE, [deference of n$6,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, onlyReportOnceBad, 1, NULLABLE_DEREFERENCE, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, onlyReportOnceBad, 1, NULL_DEREFERENCE, [start of procedure onlyReportOnceBad(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, onlyReportOnceBad, 3, NULL_DEREFERENCE, [start of procedure onlyReportOnceBad(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,start of procedure doSomething,return from a call to T_doSomething,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, reassigningNullablePointerOkay, 1, DEAD_STORE, [Write of unused value] codetoanalyze/cpp/nullable/method.cpp, reassigningNullablePointerToNullOkay, 1, DEAD_STORE, [Write of unused value] codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNotNullElseBranchBad, 1, NULL_TEST_AFTER_DEREFERENCE, [start of procedure reportsViolationInNotNullElseBranchBad(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is false] -codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNotNullElseBranchBad, 3, NULLABLE_DEREFERENCE, [deference of n$5,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNotNullElseBranchBad, 3, NULLABLE_DEREFERENCE, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNotNullElseBranchBad, 3, NULL_DEREFERENCE, [start of procedure reportsViolationInNotNullElseBranchBad(),start of procedure mayReturnNullObject,Condition is true,return from a call to T_mayReturnNullObject,Condition is false,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNullBranchBad, 1, NULL_TEST_AFTER_DEREFERENCE, [start of procedure reportsViolationInNullBranchBad(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is false] -codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNullBranchBad, 2, NULLABLE_DEREFERENCE, [deference of n$5,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNullBranchBad, 2, NULLABLE_DEREFERENCE, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, reportsViolationInNullBranchBad, 2, NULL_DEREFERENCE, [start of procedure reportsViolationInNullBranchBad(),start of procedure mayReturnNullObject,Condition is true,return from a call to T_mayReturnNullObject,Condition is true,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 1, NULL_TEST_AFTER_DEREFERENCE, [start of procedure reportsViolationOutsideOfNullCheckBad(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is false] codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 2, NULL_DEREFERENCE, [start of procedure reportsViolationOutsideOfNullCheckBad(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is true,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] -codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 4, NULLABLE_DEREFERENCE, [deference of n$2,definition of mayReturnNullObject] +codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 4, NULLABLE_DEREFERENCE, [dereferencing the return of mayReturnNullObject,definition of mayReturnNullObject] codetoanalyze/cpp/nullable/method.cpp, reportsViolationOutsideOfNullCheckBad, 4, NULL_DEREFERENCE, [start of procedure reportsViolationOutsideOfNullCheckBad(),start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,Condition is true,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject,start of procedure doSomething,return from a call to T_doSomething,start of procedure mayReturnNullObject,Condition is false,return from a call to T_mayReturnNullObject] diff --git a/infer/tests/codetoanalyze/java/checkers/issues.exp b/infer/tests/codetoanalyze/java/checkers/issues.exp index b558e5c8e..702f99561 100644 --- a/infer/tests/codetoanalyze/java/checkers/issues.exp +++ b/infer/tests/codetoanalyze/java/checkers/issues.exp @@ -39,11 +39,11 @@ codetoanalyze/java/checkers/NullableSuggest.java, void NullableSuggest.assignNul codetoanalyze/java/checkers/NullableSuggest.java, void NullableSuggest.assignNullToFieldTransitiveLoopBad(int), 7, FIELD_SHOULD_BE_NULLABLE, [Field obj0 could be assigned here,Some array element could be assigned here,Variable is assigned null here] codetoanalyze/java/checkers/NullableSuggest.java, void NullableSuggest.compareNullToFieldBad(), 2, FIELD_SHOULD_BE_NULLABLE, [Field obj0 is compared to null here] codetoanalyze/java/checkers/NullableSuggest.java, void NullableSuggest.multipleChainsAlwaysSelectShortestBad(boolean), 6, FIELD_SHOULD_BE_NULLABLE, [Field obj0 could be assigned here,Variable is assigned null here] -codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableMethodBad(), 1, NULLABLE_DEREFERENCE, [deference of n$0,definition of returnsNullable] -codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableMethodInElseBranchBad(), 3, NULLABLE_DEREFERENCE, [deference of n$2,definition of returnsNullable] -codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableMethodIncorrectlyCheckedForNullBad(), 2, NULLABLE_DEREFERENCE, [deference of n$2,definition of returnsNullable] -codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableMethodNotAlwaysCheckedForNullBad(), 2, NULLABLE_DEREFERENCE, [deference of n$6,definition of returnsNullable] -codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableReturnValueBad(), 2, NULLABLE_DEREFERENCE, [deference of &t,assignment of the nullable value,definition of returnsNullable] +codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableMethodBad(), 1, NULLABLE_DEREFERENCE, [dereferencing the return of NullableViolation.returnsNullable(),definition of returnsNullable] +codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableMethodInElseBranchBad(), 3, NULLABLE_DEREFERENCE, [dereferencing the return of NullableViolation.returnsNullable(),definition of returnsNullable] +codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableMethodIncorrectlyCheckedForNullBad(), 2, NULLABLE_DEREFERENCE, [dereferencing the return of NullableViolation.returnsNullable(),definition of returnsNullable] +codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableMethodNotAlwaysCheckedForNullBad(), 2, NULLABLE_DEREFERENCE, [dereferencing the return of NullableViolation.returnsNullable(),definition of returnsNullable] +codetoanalyze/java/checkers/NullableViolation.java, void NullableViolation.dereferenceNullableReturnValueBad(), 2, NULLABLE_DEREFERENCE, [dereference of &t,assignment of the nullable value,definition of returnsNullable] codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.formatStringIsNotLiteral(PrintStream), 2, CHECKERS_PRINTF_ARGS, [Format string must be string literal] codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.stringInsteadOfInteger(PrintStream), 1, printf(...) at line 40: parameter 2 is expected to be of type java.lang.Integer but java.lang.String was given., [] codetoanalyze/java/checkers/PrintfArgsChecker.java, void PrintfArgsChecker.wrongNumberOfArguments(PrintStream), 1, format string arguments don't mach provided arguments in printf(...) at line 44, [] diff --git a/infer/tests/codetoanalyze/objc/checkers/issues.exp b/infer/tests/codetoanalyze/objc/checkers/issues.exp index 4063d3f21..408b5a290 100644 --- a/infer/tests/codetoanalyze/objc/checkers/issues.exp +++ b/infer/tests/codetoanalyze/objc/checkers/issues.exp @@ -3,7 +3,7 @@ codetoanalyze/objc/checkers/Nullable.m, T_FP_dereferenceNonnullFieldAfterTestFor codetoanalyze/objc/checkers/Nullable.m, T_assignNonnullFieldToNullBad, 1, FIELD_SHOULD_BE_NULLABLE, [Field nonnullField is assigned null here] codetoanalyze/objc/checkers/Nullable.m, T_assignUnnanotatedFieldToNullBad, 1, FIELD_SHOULD_BE_NULLABLE, [Field unnanotatedField is assigned null here] codetoanalyze/objc/checkers/Nullable.m, T_dereferenceNullableFieldBad, 1, NULL_DEREFERENCE, [start of procedure dereferenceNullableFieldBad] -codetoanalyze/objc/checkers/Nullable.m, T_dereferenceNullableFunctionBad, 2, NULLABLE_DEREFERENCE, [deference of &p,assignment of the nullable value,definition of returnsNull] +codetoanalyze/objc/checkers/Nullable.m, T_dereferenceNullableFunctionBad, 2, NULLABLE_DEREFERENCE, [dereference of &p,assignment of the nullable value,definition of returnsNull] codetoanalyze/objc/checkers/Nullable.m, T_dereferenceNullableFunctionBad, 2, NULL_DEREFERENCE, [start of procedure dereferenceNullableFunctionBad,Skipping returnsNull(): function or method not found] codetoanalyze/objc/checkers/Nullable.m, T_dereferenceUnnanotatedFieldAfterTestForNullBad, 1, FIELD_SHOULD_BE_NULLABLE, [Field unnanotatedField is compared to null here] codetoanalyze/objc/checkers/Nullable.m, T_dereferenceUnnanotatedFieldAfterTestForNullBad, 2, NULL_DEREFERENCE, [start of procedure dereferenceUnnanotatedFieldAfterTestForNullBad,Condition is true]