From 461bd691ce8251c19b4c96402285c44ee64ffa82 Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Thu, 23 Feb 2017 07:00:06 -0800 Subject: [PATCH] [clang] Translate nullable annotations of return types of methods Reviewed By: sblackshear Differential Revision: D4579234 fbshipit-source-id: 62cadf1 --- infer/src/clang/cMethod_trans.ml | 25 ++++---- .../tests/codetoanalyze/objc/errors/Makefile | 1 + .../codetoanalyze/objc/errors/issues.exp | 1 + .../objc/frontend/noarc/Makefile | 1 + .../shared/annotations/nullable_annotations.m | 48 ++++++++++++++ .../annotations/nullable_annotations.m.dot | 62 +++++++++++++++++++ 6 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 infer/tests/codetoanalyze/objc/shared/annotations/nullable_annotations.m create mode 100644 infer/tests/codetoanalyze/objc/shared/annotations/nullable_annotations.m.dot diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index de34b8069..c397c6a09 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -341,22 +341,20 @@ let should_create_procdesc cfg procname defined = else false | None -> true -let sil_method_annotation_of_args args : Annot.Method.t = +let sil_method_annotation_of_args args method_type : Annot.Method.t = let default_visibility = true in - let mk_annot param_name annot_name = - let annot = { Annot.class_name = annot_name; parameters = [param_name]; } in + let mk_annot annot_name = + let annot = { Annot.class_name = annot_name; parameters = []; } in annot, default_visibility in - let arg_to_sil_annot (arg_mangled, {Clang_ast_t.qt_type_ptr}) acc = - let arg_name = Mangled.to_string arg_mangled in - if CAst_utils.is_type_nullable qt_type_ptr then - [mk_annot arg_name Annotations.nullable] :: acc - else Annot.Item.empty::acc in - let param_annots = List.fold_right ~f:arg_to_sil_annot args ~init:[] in - (* TODO: parse annotations on return value *) - let retval_annot = [] in + let sil_annot_of_type type_ptr = + if CAst_utils.is_type_nullable type_ptr then + [mk_annot Annotations.nullable] + else Annot.Item.empty in + let args_types = List.map ~f:(fun (_, qt) -> qt.Clang_ast_t.qt_type_ptr) args in + let param_annots = List.map ~f:sil_annot_of_type args_types in + let retval_annot = sil_annot_of_type method_type in retval_annot, param_annots - let is_pointer_to_const type_ptr = match CAst_utils.get_type type_ptr with | Some PointerType (_, {Clang_ast_t.qt_is_const}) | Some ObjCObjectPointerType (_, {Clang_ast_t.qt_is_const}) @@ -387,8 +385,9 @@ let create_local_procdesc trans_unit_ctx cfg tenv ms fbody captured is_objc_inst let proc_name = CMethod_signature.ms_get_name ms in let pname = Procname.to_string proc_name in let attributes = sil_func_attributes_of_attributes (CMethod_signature.ms_get_attributes ms) in + let method_ret_type = CMethod_signature.ms_get_ret_type ms in let method_annotation = - sil_method_annotation_of_args (CMethod_signature.ms_get_args ms) in + sil_method_annotation_of_args (CMethod_signature.ms_get_args ms) method_ret_type in let is_cpp_inst_method = CMethod_signature.ms_is_instance ms && CFrontend_config.equal_clang_lang (CMethod_signature.ms_get_lang ms) CFrontend_config.CPP in diff --git a/infer/tests/codetoanalyze/objc/errors/Makefile b/infer/tests/codetoanalyze/objc/errors/Makefile index 445672ce2..e48b364ce 100644 --- a/infer/tests/codetoanalyze/objc/errors/Makefile +++ b/infer/tests/codetoanalyze/objc/errors/Makefile @@ -50,6 +50,7 @@ SOURCES_DEFAULT = \ shared/property/PropertyAttributes.m \ shared/protocol_procdesc/Bicycle.m \ shared/protocol_procdesc/main.c \ + shared/annotations/nullable_annotations.m \ taint/sources.m \ taint/viewController.m \ diff --git a/infer/tests/codetoanalyze/objc/errors/issues.exp b/infer/tests/codetoanalyze/objc/errors/issues.exp index b32758643..9c8d1b79c 100644 --- a/infer/tests/codetoanalyze/objc/errors/issues.exp +++ b/infer/tests/codetoanalyze/objc/errors/issues.exp @@ -113,6 +113,7 @@ codetoanalyze/objc/errors/taint/sources.m, testNSHTTPCookie2, 5, TAINTED_VALUE_R codetoanalyze/objc/errors/taint/sources.m, testNSHTTPCookie3, 5, TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION, [start of procedure testNSHTTPCookie3()] codetoanalyze/objc/errors/taint/sources.m, testNSHTTPCookie4, 5, TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION, [start of procedure testNSHTTPCookie4()] codetoanalyze/objc/errors/taint/viewController.m, ExampleDelegate_application:openURL:sourceApplication:annotation:, 7, TAINTED_VALUE_REACHING_SENSITIVE_FUNCTION, [start of procedure application:openURL:sourceApplication:annotation:,start of procedure init,return from a call to VCA_init,start of procedure ExampleSanitizer(),Condition is false,return from a call to ExampleSanitizer,Condition is false,Condition is true] +codetoanalyze/objc/shared/annotations/nullable_annotations.m, User_otherUserName, 2, NULL_DEREFERENCE, [start of procedure otherUserName] codetoanalyze/objc/shared/block/block-it.m, MyBlock_array, 3, RETURN_VALUE_IGNORED, [start of procedure array,Condition is true] codetoanalyze/objc/shared/block/block-it.m, __objc_anonymous_block_MyBlock_array______1, 5, UNINITIALIZED_VALUE, [start of procedure block,Condition is false] codetoanalyze/objc/shared/block/block-it.m, __objc_anonymous_block_MyBlock_array_trans______2, 4, UNINITIALIZED_VALUE, [start of procedure block,Condition is false] diff --git a/infer/tests/codetoanalyze/objc/frontend/noarc/Makefile b/infer/tests/codetoanalyze/objc/frontend/noarc/Makefile index 189253c03..baf928bf5 100644 --- a/infer/tests/codetoanalyze/objc/frontend/noarc/Makefile +++ b/infer/tests/codetoanalyze/objc/frontend/noarc/Makefile @@ -66,5 +66,6 @@ SOURCES = \ ../vardecl/aclass.m \ ../vardecl/aclass_2.m \ ../vardecl/last_af.m \ + ../shared/annotations/nullable_annotations.m \ include $(TESTS_DIR)/clang-frontend.make diff --git a/infer/tests/codetoanalyze/objc/shared/annotations/nullable_annotations.m b/infer/tests/codetoanalyze/objc/shared/annotations/nullable_annotations.m new file mode 100644 index 000000000..cc4456d47 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/shared/annotations/nullable_annotations.m @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#import + +@interface User : NSObject + +- (nullable instancetype)initWithName:(nullable NSString*)name; + +- (nullable NSString*)tellMeSomething; + +- (nullable User*)otherUser; + +@property(strong, nonatomic) NSString* name; + +@end + +@implementation User + +- (nullable instancetype)initWithName:(nullable NSString*)name { + return self; +} + +- (nullable NSString*)tellMeSomething { + return @"Hi"; +} + +- (NSString*)tellMeSomethingNotNullable { + return @"Hi"; +} + +- (NSString*)tellMeSomething:(NSString*)s1 + and:(NSString*)s2 + and:(nullable NSString*)s3 + and:(NSString*)s4 { + return @"Hi"; +} + +- (NSString*)otherUserName { + User* ou = [self otherUser]; + return ou->_name; +} +@end diff --git a/infer/tests/codetoanalyze/objc/shared/annotations/nullable_annotations.m.dot b/infer/tests/codetoanalyze/objc/shared/annotations/nullable_annotations.m.dot new file mode 100644 index 000000000..20fe892e2 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/shared/annotations/nullable_annotations.m.dot @@ -0,0 +1,62 @@ +/* @generated */ +digraph iCFG { +"User_tellMeSomethinginstance.b54f02b8c304dfa023d23f9f4df4c2e1_1" [label="1: Start User_tellMeSomething\nFormals: self:class User*\nLocals: \nAnnotation: <_Nullable> User_tellMeSomething(<>) \n DECLARE_LOCALS(&return); [line 29]\n " color=yellow style=filled] + + + "User_tellMeSomethinginstance.b54f02b8c304dfa023d23f9f4df4c2e1_1" -> "User_tellMeSomethinginstance.b54f02b8c304dfa023d23f9f4df4c2e1_3" ; +"User_tellMeSomethinginstance.b54f02b8c304dfa023d23f9f4df4c2e1_2" [label="2: Exit User_tellMeSomething \n " color=yellow style=filled] + + +"User_tellMeSomethinginstance.b54f02b8c304dfa023d23f9f4df4c2e1_3" [label="3: Return Stmt \n n$1=_fun_NSString_stringWithUTF8String:(\"Hi\":char*) [line 30]\n *&return:class NSString*=n$1 [line 30]\n " shape="box"] + + + "User_tellMeSomethinginstance.b54f02b8c304dfa023d23f9f4df4c2e1_3" -> "User_tellMeSomethinginstance.b54f02b8c304dfa023d23f9f4df4c2e1_2" ; +"User_tellMeSomethingNotNullableinstance.a40d0ee63f3aeb90706900a49136196b_1" [label="1: Start User_tellMeSomethingNotNullable\nFormals: self:class User*\nLocals: \n DECLARE_LOCALS(&return); [line 33]\n " color=yellow style=filled] + + + "User_tellMeSomethingNotNullableinstance.a40d0ee63f3aeb90706900a49136196b_1" -> "User_tellMeSomethingNotNullableinstance.a40d0ee63f3aeb90706900a49136196b_3" ; +"User_tellMeSomethingNotNullableinstance.a40d0ee63f3aeb90706900a49136196b_2" [label="2: Exit User_tellMeSomethingNotNullable \n " color=yellow style=filled] + + +"User_tellMeSomethingNotNullableinstance.a40d0ee63f3aeb90706900a49136196b_3" [label="3: Return Stmt \n n$2=_fun_NSString_stringWithUTF8String:(\"Hi\":char*) [line 34]\n *&return:class NSString*=n$2 [line 34]\n " shape="box"] + + + "User_tellMeSomethingNotNullableinstance.a40d0ee63f3aeb90706900a49136196b_3" -> "User_tellMeSomethingNotNullableinstance.a40d0ee63f3aeb90706900a49136196b_2" ; +"User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_1" [label="1: Start User_otherUserName\nFormals: self:class User*\nLocals: ou:class User* \n DECLARE_LOCALS(&return,&ou); [line 44]\n " color=yellow style=filled] + + + "User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_1" -> "User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_4" ; +"User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_2" [label="2: Exit User_otherUserName \n " color=yellow style=filled] + + +"User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_3" [label="3: Return Stmt \n n$4=*&ou:class User* [line 46]\n n$5=*n$4._name:class NSString* [line 46]\n *&return:class NSString*=n$5 [line 46]\n " shape="box"] + + + "User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_3" -> "User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_2" ; +"User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_4" [label="4: DeclStmt \n n$6=*&self:class User* [line 45]\n n$7=_fun_User_otherUser(n$6:class User*) virtual [line 45]\n *&ou:class User*=n$7 [line 45]\n " shape="box"] + + + "User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_4" -> "User_otherUserNameinstance.d96d9ea375a633021df5bfc33fa4c63c_3" ; +"User_initWithName:instance.9593030a12738a1c563396f127eaaa37_1" [label="1: Start User_initWithName:\nFormals: self:class User* name:class NSString*\nLocals: \nAnnotation: <_Nullable> User_initWithName:(<> <_Nullable>) \n DECLARE_LOCALS(&return); [line 25]\n " color=yellow style=filled] + + + "User_initWithName:instance.9593030a12738a1c563396f127eaaa37_1" -> "User_initWithName:instance.9593030a12738a1c563396f127eaaa37_3" ; +"User_initWithName:instance.9593030a12738a1c563396f127eaaa37_2" [label="2: Exit User_initWithName: \n " color=yellow style=filled] + + +"User_initWithName:instance.9593030a12738a1c563396f127eaaa37_3" [label="3: Return Stmt \n n$0=*&self:class User* [line 26]\n *&return:struct objc_object*=n$0 [line 26]\n " shape="box"] + + + "User_initWithName:instance.9593030a12738a1c563396f127eaaa37_3" -> "User_initWithName:instance.9593030a12738a1c563396f127eaaa37_2" ; +"User_tellMeSomething:and:and:and:instance.12fb98968dde54a144a6102e598bee03_1" [label="1: Start User_tellMeSomething:and:and:and:\nFormals: self:class User* s1:class NSString* s2:class NSString* s3:class NSString* s4:class NSString*\nLocals: \nAnnotation: <> User_tellMeSomething:and:and:and:(<> <> <> <_Nullable> <>) \n DECLARE_LOCALS(&return); [line 37]\n " color=yellow style=filled] + + + "User_tellMeSomething:and:and:and:instance.12fb98968dde54a144a6102e598bee03_1" -> "User_tellMeSomething:and:and:and:instance.12fb98968dde54a144a6102e598bee03_3" ; +"User_tellMeSomething:and:and:and:instance.12fb98968dde54a144a6102e598bee03_2" [label="2: Exit User_tellMeSomething:and:and:and: \n " color=yellow style=filled] + + +"User_tellMeSomething:and:and:and:instance.12fb98968dde54a144a6102e598bee03_3" [label="3: Return Stmt \n n$3=_fun_NSString_stringWithUTF8String:(\"Hi\":char*) [line 41]\n *&return:class NSString*=n$3 [line 41]\n " shape="box"] + + + "User_tellMeSomething:and:and:and:instance.12fb98968dde54a144a6102e598bee03_3" -> "User_tellMeSomething:and:and:and:instance.12fb98968dde54a144a6102e598bee03_2" ; +}