Fixing crash that happened when reporting a lint issue in a templated method.

Reviewed By: jberdine

Differential Revision: D5699672

fbshipit-source-id: 230c232
master
Dulma Churchill 7 years ago committed by Facebook Github Bot
parent 02c2e2b5bf
commit 5ead13a225

@ -27,7 +27,9 @@ let strip_template_args quals =
let append_template_args_to_last quals ~args = let append_template_args_to_last quals ~args =
match quals with match quals with
| [last; _] when String.contains last '<' | [last; _] when String.contains last '<'
-> failwith "expected qualified name without template args" -> failwithf
"expected qualified name without template args, but got %s, the last qualifier of %s" last
(String.concat ~sep:", " quals)
| last :: rest | last :: rest
-> (last ^ args) :: rest -> (last ^ args) :: rest
| [] | []

@ -177,9 +177,10 @@ and get_record_as_typevar (definition_decl: Clang_ast_t.decl) =
as it defaults to Typ.NoTemplate *) as it defaults to Typ.NoTemplate *)
and get_record_typename ?tenv decl = and get_record_typename ?tenv decl =
let open Clang_ast_t in let open Clang_ast_t in
let linters_mode = match tenv with Some _ -> false | None -> true in
match (decl, tenv) with match (decl, tenv) with
| RecordDecl (_, name_info, opt_type, _, _, _, _), _ | RecordDecl (_, name_info, opt_type, _, _, _, _), _
-> CAst_utils.get_qualified_name name_info |> create_c_record_typename opt_type -> CAst_utils.get_qualified_name ~linters_mode name_info |> create_c_record_typename opt_type
| ClassTemplateSpecializationDecl (_, _, _, _, _, _, _, _, spec_info), Some tenv | ClassTemplateSpecializationDecl (_, _, _, _, _, _, _, _, spec_info), Some tenv
-> let tname = -> let tname =
match CAst_utils.get_decl spec_info.tsi_template_decl with match CAst_utils.get_decl spec_info.tsi_template_decl with
@ -200,7 +201,8 @@ and get_record_typename ?tenv decl =
| ClassTemplateSpecializationDecl (_, name_info, _, _, _, _, _, _, _), _ | ClassTemplateSpecializationDecl (_, name_info, _, _, _, _, _, _, _), _
-> (* we use Typ.CppClass for C++ because we expect Typ.CppClass from *) -> (* we use Typ.CppClass for C++ because we expect Typ.CppClass from *)
(* types that have methods. And in C++ struct/class/union can have methods *) (* types that have methods. And in C++ struct/class/union can have methods *)
Typ.Name.Cpp.from_qual_name Typ.NoTemplate (CAst_utils.get_qualified_name name_info) Typ.Name.Cpp.from_qual_name Typ.NoTemplate
(CAst_utils.get_qualified_name ~linters_mode name_info)
| ObjCInterfaceDecl (_, name_info, _, _, _), _ | ObjCInterfaceDecl (_, name_info, _, _, _), _
| ObjCImplementationDecl (_, name_info, _, _, _), _ | ObjCImplementationDecl (_, name_info, _, _, _), _
| ObjCProtocolDecl (_, name_info, _, _, _), _ | ObjCProtocolDecl (_, name_info, _, _, _), _

@ -22,7 +22,16 @@ let sanitize_name = Str.global_replace (Str.regexp "[/ ]") "_"
let get_qual_name qual_name_list = let get_qual_name qual_name_list =
List.map ~f:sanitize_name qual_name_list |> QualifiedCppName.of_rev_list List.map ~f:sanitize_name qual_name_list |> QualifiedCppName.of_rev_list
let get_qualified_name name_info = get_qual_name name_info.Clang_ast_t.ni_qual_name let get_qualified_name ?(linters_mode= false) name_info =
if not linters_mode then get_qual_name name_info.Clang_ast_t.ni_qual_name
else
(* Because we are in linters mode, we can't get precise info about templates,
so we strip the template characters to not upset invariants in the system. *)
let replace_template_chars qual_name =
String.tr ~target:'<' ~replacement:'_' qual_name |> String.tr ~target:'>' ~replacement:'_'
in
let qual_names = List.map ~f:replace_template_chars name_info.Clang_ast_t.ni_qual_name in
get_qual_name qual_names
let get_unqualified_name name_info = let get_unqualified_name name_info =
let name = let name =

@ -38,7 +38,7 @@ val add_enum_constant : Clang_ast_t.pointer -> Clang_ast_t.pointer option -> uni
val get_enum_constant_exp : Clang_ast_t.pointer -> Clang_ast_t.pointer option * Exp.t option val get_enum_constant_exp : Clang_ast_t.pointer -> Clang_ast_t.pointer option * Exp.t option
val get_qualified_name : Clang_ast_t.named_decl_info -> QualifiedCppName.t val get_qualified_name : ?linters_mode:bool -> Clang_ast_t.named_decl_info -> QualifiedCppName.t
(** returns sanitized, fully qualified name given name info *) (** returns sanitized, fully qualified name given name info *)
val get_unqualified_name : Clang_ast_t.named_decl_info -> string val get_unqualified_name : Clang_ast_t.named_decl_info -> string

@ -0,0 +1,15 @@
/*
* 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 <Foundation/NSObject.h>
#import <functional>
template <>
struct std::hash<NSObject*> {
size_t operator()(const NSObject* const& obj1) const { return [obj1 hash]; }
};

@ -12,3 +12,4 @@ codetoanalyze/objcpp/linters-for-test-only/TestParamterLabelsChecks.mm, buttonCo
codetoanalyze/objcpp/linters-for-test-only/TestParamterLabelsChecks.mm, buttonComponent, 31, TEST_PARAMETER_LABEL_REGEXP, [] codetoanalyze/objcpp/linters-for-test-only/TestParamterLabelsChecks.mm, buttonComponent, 31, TEST_PARAMETER_LABEL_REGEXP, []
codetoanalyze/objcpp/linters-for-test-only/TestParamterLabelsChecks.mm, foo, 54, TEST_PARAMETER_SELECTOR, [] codetoanalyze/objcpp/linters-for-test-only/TestParamterLabelsChecks.mm, foo, 54, TEST_PARAMETER_SELECTOR, []
codetoanalyze/objcpp/linters-for-test-only/TestParamterLabelsChecks.mm, foo, 56, TEST_PARAMETER_SELECTOR, [] codetoanalyze/objcpp/linters-for-test-only/TestParamterLabelsChecks.mm, foo, 56, TEST_PARAMETER_SELECTOR, []
codetoanalyze/objcpp/linters-for-test-only/hash_test.mm, std::hash_NSObject_*__operator(), 14, DISCOURAGED_HASH_METHOD_INVOCATION, []

@ -102,3 +102,8 @@ DEFINE-CHECKER TEST_PARAMETER_SELECTOR = {
HOLDS-IN-NODE ObjCMessageExpr; HOLDS-IN-NODE ObjCMessageExpr;
SET message = "Do not construct the Component action with a selector only...`"; SET message = "Do not construct the Component action with a selector only...`";
}; };
DEFINE-CHECKER DISCOURAGED_HASH_METHOD_INVOCATION = {
SET report_when = call_method("hash");
SET message = "Don't use the hash method";
};

Loading…
Cancel
Save