From 8a844ab67f1f3d0a93d13a6f3d7673f243121251 Mon Sep 17 00:00:00 2001 From: Qianyi Shu Date: Thu, 17 Sep 2020 05:19:11 -0700 Subject: [PATCH] [cost] add differential cost test for objc Summary: When inspecting silent introduced issues, we found that an introduced issue is about a complexity increase of a block that is only created in the current diff. Based on the trace view, we find out that this is caused by infer mistakingly consider another block that exists in the previous diff as the same block that is newly created in the current diff. This diff adds a test case that reproduces this case, and this will be fixed in the next diff. facebook Trace view: https://www.internalfb.com/intern/traceview/?id=109896337 Reviewed By: ezgicicek Differential Revision: D23681550 fbshipit-source-id: 78341268b --- Makefile | 5 +- .../Makefile | 0 .../costs_summary.json.exp | 0 .../fixed.exp | 0 .../introduced.exp | 0 .../loom_test.json | 0 .../preexisting.exp | 0 .../src/DiffExample.java.current | 0 .../src/DiffExample.java.previous | 0 .../src/DiffExampleUIThread.java.current | 0 .../src/DiffExampleUIThread.java.previous | 0 .../Makefile | 26 ++++++++ .../costs_summary.json.exp | 1 + .../fixed.exp | 0 .../introduced.exp | 1 + .../preexisting.exp | 0 .../src/DiffBlock.m | 51 +++++++++++++++ .../src/DiffBlock.m.current | 63 +++++++++++++++++++ .../src/DiffBlock.m.previous | 51 +++++++++++++++ 19 files changed, 196 insertions(+), 2 deletions(-) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/Makefile (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/costs_summary.json.exp (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/fixed.exp (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/introduced.exp (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/loom_test.json (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/preexisting.exp (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/src/DiffExample.java.current (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/src/DiffExample.java.previous (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/src/DiffExampleUIThread.java.current (100%) rename infer/tests/build_systems/{differential_of_costs_report => differential_of_costs_report_java}/src/DiffExampleUIThread.java.previous (100%) create mode 100644 infer/tests/build_systems/differential_of_costs_report_objc/Makefile create mode 100644 infer/tests/build_systems/differential_of_costs_report_objc/costs_summary.json.exp create mode 100644 infer/tests/build_systems/differential_of_costs_report_objc/fixed.exp create mode 100644 infer/tests/build_systems/differential_of_costs_report_objc/introduced.exp create mode 100644 infer/tests/build_systems/differential_of_costs_report_objc/preexisting.exp create mode 100644 infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m create mode 100644 infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m.current create mode 100644 infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m.previous diff --git a/Makefile b/Makefile index 7e2467322..874825267 100644 --- a/Makefile +++ b/Makefile @@ -94,7 +94,8 @@ BUILD_SYSTEMS_TESTS += \ objc_getters_setters \ objc_missing_fld \ objc_retain_cycles \ - objc_retain_cycles_weak + objc_retain_cycles_weak \ + differential_of_costs_report_objc \ DIRECT_TESTS += \ objc_autoreleasepool \ @@ -130,7 +131,7 @@ endif # BUILD_C_ANALYZERS ifeq ($(BUILD_JAVA_ANALYZERS),yes) BUILD_SYSTEMS_TESTS += \ differential_interesting_paths_filter \ - differential_of_costs_report \ + differential_of_costs_report_java \ incremental_analysis_cost_change \ differential_skip_anonymous_class_renamings \ differential_skip_duplicated_types_on_filenames \ diff --git a/infer/tests/build_systems/differential_of_costs_report/Makefile b/infer/tests/build_systems/differential_of_costs_report_java/Makefile similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/Makefile rename to infer/tests/build_systems/differential_of_costs_report_java/Makefile diff --git a/infer/tests/build_systems/differential_of_costs_report/costs_summary.json.exp b/infer/tests/build_systems/differential_of_costs_report_java/costs_summary.json.exp similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/costs_summary.json.exp rename to infer/tests/build_systems/differential_of_costs_report_java/costs_summary.json.exp diff --git a/infer/tests/build_systems/differential_of_costs_report/fixed.exp b/infer/tests/build_systems/differential_of_costs_report_java/fixed.exp similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/fixed.exp rename to infer/tests/build_systems/differential_of_costs_report_java/fixed.exp diff --git a/infer/tests/build_systems/differential_of_costs_report/introduced.exp b/infer/tests/build_systems/differential_of_costs_report_java/introduced.exp similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/introduced.exp rename to infer/tests/build_systems/differential_of_costs_report_java/introduced.exp diff --git a/infer/tests/build_systems/differential_of_costs_report/loom_test.json b/infer/tests/build_systems/differential_of_costs_report_java/loom_test.json similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/loom_test.json rename to infer/tests/build_systems/differential_of_costs_report_java/loom_test.json diff --git a/infer/tests/build_systems/differential_of_costs_report/preexisting.exp b/infer/tests/build_systems/differential_of_costs_report_java/preexisting.exp similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/preexisting.exp rename to infer/tests/build_systems/differential_of_costs_report_java/preexisting.exp diff --git a/infer/tests/build_systems/differential_of_costs_report/src/DiffExample.java.current b/infer/tests/build_systems/differential_of_costs_report_java/src/DiffExample.java.current similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/src/DiffExample.java.current rename to infer/tests/build_systems/differential_of_costs_report_java/src/DiffExample.java.current diff --git a/infer/tests/build_systems/differential_of_costs_report/src/DiffExample.java.previous b/infer/tests/build_systems/differential_of_costs_report_java/src/DiffExample.java.previous similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/src/DiffExample.java.previous rename to infer/tests/build_systems/differential_of_costs_report_java/src/DiffExample.java.previous diff --git a/infer/tests/build_systems/differential_of_costs_report/src/DiffExampleUIThread.java.current b/infer/tests/build_systems/differential_of_costs_report_java/src/DiffExampleUIThread.java.current similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/src/DiffExampleUIThread.java.current rename to infer/tests/build_systems/differential_of_costs_report_java/src/DiffExampleUIThread.java.current diff --git a/infer/tests/build_systems/differential_of_costs_report/src/DiffExampleUIThread.java.previous b/infer/tests/build_systems/differential_of_costs_report_java/src/DiffExampleUIThread.java.previous similarity index 100% rename from infer/tests/build_systems/differential_of_costs_report/src/DiffExampleUIThread.java.previous rename to infer/tests/build_systems/differential_of_costs_report_java/src/DiffExampleUIThread.java.previous diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/Makefile b/infer/tests/build_systems/differential_of_costs_report_objc/Makefile new file mode 100644 index 000000000..2e4b05a92 --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report_objc/Makefile @@ -0,0 +1,26 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +# E2E test for differential of costs + +TESTS_DIR = ../.. +SOURCES = src/DiffBlock.m.current src/DiffBlock.m.previous +CLANG_OPTIONS = -c $(OBJC_CLANG_OPTIONS) +include $(TESTS_DIR)/differential.make +include $(TESTS_DIR)/objc.make +INFERPRINT_ISSUES_FIELDS = \ + "bug_type,bucket,file,procedure,line_offset,bug_trace" + +$(CURRENT_REPORT) $(PREVIOUS_REPORT): $(OBJC_DEPS) + +$(CURRENT_REPORT): + $(QUIET)$(COPY) src/DiffBlock.m.current src/DiffBlock.m + $(QUIET)$(call silent_on_success,Testing Cost Differential: current,\ + $(INFER_BIN) --enable-issue-type INFINITE_EXECUTION_TIME --cost-only -o $(CURRENT_DIR) -- clang $(CLANG_OPTIONS) src/*.m) + +$(PREVIOUS_REPORT): + $(QUIET)$(COPY) src/DiffBlock.m.previous src/DiffBlock.m + $(QUIET)$(call silent_on_success,Testing Cost Differential: previous,\ + $(INFER_BIN) --debug --enable-issue-type INFINITE_EXECUTION_TIME --cost-only -o $(PREVIOUS_DIR) -- clang $(CLANG_OPTIONS) src/*.m) diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/costs_summary.json.exp b/infer/tests/build_systems/differential_of_costs_report_objc/costs_summary.json.exp new file mode 100644 index 000000000..e486f3c0e --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report_objc/costs_summary.json.exp @@ -0,0 +1 @@ +{"top":{"current":0,"previous":0},"unreachable":{"current":0,"previous":0},"zero":{"current":0,"previous":0},"degrees":[{"degree":0,"current":20,"previous":15},{"degree":100,"current":4,"previous":1}]} \ No newline at end of file diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/fixed.exp b/infer/tests/build_systems/differential_of_costs_report_objc/fixed.exp new file mode 100644 index 000000000..e69de29bb diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/introduced.exp b/infer/tests/build_systems/differential_of_costs_report_objc/introduced.exp new file mode 100644 index 000000000..a2c944f4a --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report_objc/introduced.exp @@ -0,0 +1 @@ +EXECUTION_TIME_COMPLEXITY_INCREASE, no_bucket, src/DiffBlock.m, objc_blockHandler.create_block_here:array:call:_2, 0, [Previous Cost of objc_blockHandler.func_linear_1 is 22 (degree is 0),Updated Cost of objc_blockHandler.create_block_here:array:call:_2 is 5 + 5 ⋅ array->elements.length + 4 ⋅ (array->elements.length + 1) (degree is 1),{array->elements.length + 1},Loop] diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/preexisting.exp b/infer/tests/build_systems/differential_of_costs_report_objc/preexisting.exp new file mode 100644 index 000000000..e69de29bb diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m b/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m new file mode 100644 index 000000000..c4ec0c836 --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m @@ -0,0 +1,51 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +@interface CallBlocks : NSObject + +- (void)take_two_blocks:(NSInteger*)n + block1:(void (^)(NSInteger*))block1 + block2:(void (^)(NSInteger*))block2; + +@end + +@implementation CallBlocks + +- (id)init { + return self; +} + +- (void)take_two_blocks:(NSInteger*)n + block1:(void (^)(NSInteger*))block1 + block2:(void (^)(NSInteger*))block2 { + block1(n); + block2(n); +} + +@end + +@interface Handler : NSObject +@end + +@implementation Handler + +- (void (^)(NSString*))func_linear { + return ^(NSString* str) { + NSLog(@"Report error : %@ \n", str); + }; +} + +- (void)func_linear:(NSArray*)array { + for (id value in array) { + } +} + +@end + +int main() { return 0; } diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m.current b/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m.current new file mode 100644 index 000000000..925182a2c --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m.current @@ -0,0 +1,63 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#import + +@interface CallBlocks : NSObject + +- (void)take_two_blocks:(NSInteger*)n + block1:(void (^)(NSInteger*))block1 + block2:(void (^)(NSInteger*))block2; + +@end + +@implementation CallBlocks + +- (id)init { + return self; +} + +- (void)take_two_blocks:(NSInteger*)n + block1:(void (^)(NSInteger*))block1 + block2:(void (^)(NSInteger*))block2 { + block1(n); + block2(n); +} + +@end + +@interface Handler : NSObject +@end + +@implementation Handler + +- (void (^)(NSString*))func_linear { + return ^(NSString* str) { + NSLog(@"Report error : %@ \n", str); + }; +} + +- (void)func_linear:(NSArray*)array { + for (id value in array) { + } +} + +- (void)create_block_here:(NSInteger*)n + array:(NSArray*)array + call:(CallBlocks*)call { + [call take_two_blocks:n + block1:^(NSInteger* n) { + for (id value in array) { + n += [value integerValue]; + } + } + block2:^(NSInteger* n) { + NSLog(@"Report error"); + }]; +} +@end + +int main() { return 0; } diff --git a/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m.previous b/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m.previous new file mode 100644 index 000000000..c4ec0c836 --- /dev/null +++ b/infer/tests/build_systems/differential_of_costs_report_objc/src/DiffBlock.m.previous @@ -0,0 +1,51 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +@interface CallBlocks : NSObject + +- (void)take_two_blocks:(NSInteger*)n + block1:(void (^)(NSInteger*))block1 + block2:(void (^)(NSInteger*))block2; + +@end + +@implementation CallBlocks + +- (id)init { + return self; +} + +- (void)take_two_blocks:(NSInteger*)n + block1:(void (^)(NSInteger*))block1 + block2:(void (^)(NSInteger*))block2 { + block1(n); + block2(n); +} + +@end + +@interface Handler : NSObject +@end + +@implementation Handler + +- (void (^)(NSString*))func_linear { + return ^(NSString* str) { + NSLog(@"Report error : %@ \n", str); + }; +} + +- (void)func_linear:(NSArray*)array { + for (id value in array) { + } +} + +@end + +int main() { return 0; }