From e19550a43b5ff650624a0a36038c02ddecab3e46 Mon Sep 17 00:00:00 2001 From: Ryan Rhee Date: Wed, 24 Aug 2016 02:59:43 -0700 Subject: [PATCH] Handle l-value refs correctly Reviewed By: jvillard Differential Revision: D3757766 fbshipit-source-id: 12edcfc --- infer/src/clang/ComponentKit.ml | 7 ++++++- .../codetoanalyze/objcpp/componentkit/Test.mm | 14 ++++++++++++++ .../componentkit/MutableLocalVariableTest.java | 4 ++-- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/infer/src/clang/ComponentKit.ml b/infer/src/clang/ComponentKit.ml index 9e7c66762..70863aaf5 100644 --- a/infer/src/clang/ComponentKit.ml +++ b/infer/src/clang/ComponentKit.ml @@ -77,11 +77,16 @@ let mutable_local_vars_advice context decl = let open CFrontend_utils.Ast_utils in match decl with | Clang_ast_t.VarDecl(decl_info, _, qual_type, _) -> + let is_const_ref = match Ast_utils.get_type qual_type.qt_type_ptr with + | Some LValueReferenceType (_, {Clang_ast_t.qt_is_const}) -> + qt_is_const + | _ -> false in + let is_const = qual_type.qt_is_const || is_const_ref in let condition = context.CLintersContext.is_ck_translation_unit && is_in_main_file decl && (is_objc () || is_objcpp ()) && (not (is_syntactically_global_var decl)) - && (not qual_type.qt_is_const) in + && (not is_const) in if condition then Some { CIssue.issue = CIssue.Mutable_local_variable_in_component_file; diff --git a/infer/tests/codetoanalyze/objcpp/componentkit/Test.mm b/infer/tests/codetoanalyze/objcpp/componentkit/Test.mm index cc1d64057..03d332b0e 100644 --- a/infer/tests/codetoanalyze/objcpp/componentkit/Test.mm +++ b/infer/tests/codetoanalyze/objcpp/componentkit/Test.mm @@ -92,3 +92,17 @@ typedef struct { int thisStructIsEmpty; } CKSize; size:{}]]; } @end + +typedef struct { int a; } BarStruct; + +@interface BarComponent : CKCompositeComponent +@end +@implementation BarComponent ++ (instancetype) new { + // C++ structs + BarStruct s1; // error + const BarStruct& s2 = s1; // no error + BarStruct& s3 = s1; // error + const BarStruct s4 = {.a = 3}; // no error +} +@end diff --git a/infer/tests/endtoend/objcpp/componentkit/MutableLocalVariableTest.java b/infer/tests/endtoend/objcpp/componentkit/MutableLocalVariableTest.java index 08f056550..e76a75206 100644 --- a/infer/tests/endtoend/objcpp/componentkit/MutableLocalVariableTest.java +++ b/infer/tests/endtoend/objcpp/componentkit/MutableLocalVariableTest.java @@ -10,7 +10,7 @@ package endtoend.objcpp.componentkit; import static org.hamcrest.MatcherAssert.assertThat; -import static utils.matchers.ResultContainsLineNumbers.containsLines; +import static utils.matchers.ResultContainsLineNumbers.containsOnlyLines; import static utils.matchers.ResultContainsErrorInMethod.contains; import com.google.common.collect.ImmutableList; @@ -51,7 +51,7 @@ public class MutableLocalVariableTest { assertThat( "Results should contain " + MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE, inferResults, - containsLines(new int[]{58, 69, 74, 76, 80, 85})); + containsOnlyLines(new int[]{58, 69, 74, 76, 80, 85, 103, 105})); } @Test