diff --git a/infer/tests/codetoanalyze/hack/pulse/builder.hack b/infer/tests/codetoanalyze/hack/pulse/builder.hack index e2d0aeb5f0..21f5c6575c 100644 --- a/infer/tests/codetoanalyze/hack/pulse/builder.hack +++ b/infer/tests/codetoanalyze/hack/pulse/builder.hack @@ -101,6 +101,20 @@ class BuilderTester { } } + public static function FP_builderWithoutCallsOk(bool $flag): void { + $changes_made = false; + $b = new MyBuilder(0); + + if ($flag) { + $b->setA(42); + $changes_made = true; + } + + if ($changes_made) { + $b->saveX(); + } + } + // now check builders recognised from the .inferconfig file public static function testConfigBad(): void { $b = new NoBuilderSuffix(); diff --git a/infer/tests/codetoanalyze/hack/pulse/issues.exp b/infer/tests/codetoanalyze/hack/pulse/issues.exp index eb8d3ce177..c0440cb827 100644 --- a/infer/tests/codetoanalyze/hack/pulse/issues.exp +++ b/infer/tests/codetoanalyze/hack/pulse/issues.exp @@ -28,6 +28,7 @@ booleans.hack, $root.Booleans::testBoolBad, 3, TAINT_ERROR, no_bucket, ERROR, [s booleans.hack, $root.Booleans::testNullBad, 3, TAINT_ERROR, no_bucket, ERROR, [source of the taint here: value passed as argument `#0` to `$root.Booleans::testNullBad` with kind `Simple`,flows to this sink: value passed as argument `#0` to `$root.Level1::taintSink` with kind `Simple`], source: $root.Booleans::testNullBad, sink: $root.Level1::taintSink, tainted expression: $sc booleans.hack, $root.Booleans::testNotNullBad, 3, TAINT_ERROR, no_bucket, ERROR, [source of the taint here: value passed as argument `#0` to `$root.Booleans::testNotNullBad` with kind `Simple`,flows to this sink: value passed as argument `#0` to `$root.Level1::taintSink` with kind `Simple`], source: $root.Booleans::testNotNullBad, sink: $root.Level1::taintSink, tainted expression: $sc builder.hack, BuilderTester$static.builderUserBad, 3, PULSE_UNFINISHED_BUILDER, no_bucket, ERROR, [allocation part of the trace starts here,allocated by constructor `MyBuilder()` here,builder object becomes unreachable here] +builder.hack, BuilderTester$static.FP_builderWithoutCallsOk, 9, PULSE_UNFINISHED_BUILDER, no_bucket, ERROR, [allocation part of the trace starts here,allocated by constructor `MyBuilder()` here,builder object becomes unreachable here] builder.hack, BuilderTester$static.testConfigBad, 2, PULSE_UNFINISHED_BUILDER, no_bucket, ERROR, [allocation part of the trace starts here,allocated by constructor `NoBuilderSuffix()` here,builder object becomes unreachable here] builder.hack, BuilderTester$static.testConfigBad2, 3, PULSE_UNFINISHED_BUILDER, no_bucket, ERROR, [allocation part of the trace starts here,allocated by constructor `NoBuilderSuffix()` here,builder object becomes unreachable here] builder.hack, BuilderTester2$static.testCreateBad, 3, PULSE_UNFINISHED_BUILDER, no_bucket, ERROR, [allocation part of the trace starts here,when calling `BuilderTester2$static.create` here,when calling `MyBuilder$static.__factory` here,allocated by constructor `MyBuilder()` here,builder object becomes unreachable here]