diff --git a/facebook-clang-plugins b/facebook-clang-plugins index 2c6cbaf41..858e754e7 160000 --- a/facebook-clang-plugins +++ b/facebook-clang-plugins @@ -1 +1 @@ -Subproject commit 2c6cbaf4188192795af55b472882c09975e65901 +Subproject commit 858e754e7dcc148637dfae8e42d041c238b8bc9b diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index 17bda73ad..2b5ca77f1 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -1303,3 +1303,12 @@ let is_cxx_copy_constructor an = xcei.xcei_is_copy_constructor | _ -> false + + +let is_init_expr_cxx11_constant an = + let open Clang_ast_t in + match an with + | Ctl_parser_types.Decl (VarDecl (_, _, _, vdi)) -> + vdi.vdi_is_init_expr_cxx11_constant + | _ -> + false diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index b87d764c4..ed56db65e 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -460,3 +460,6 @@ val is_method_called_by_superclass : Ctl_parser_types.ast_node -> bool val is_cxx_copy_constructor : Ctl_parser_types.ast_node -> bool (** true if the current node is a C++ copy constructor *) + +val is_init_expr_cxx11_constant : Ctl_parser_types.ast_node -> bool +(** true if the current node is classified as C++11 constant expression by the AST. It works only for VarDecl init expr *) diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index cdbcf1d99..bbcc41749 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -1142,6 +1142,8 @@ let rec eval_Atomic pred_name_ args an lcxt = CPredicates.is_method_called_by_superclass an | "is_cxx_copy_constructor", [], an -> CPredicates.is_cxx_copy_constructor an + | "is_init_expr_cxx11_constant", [], an -> + CPredicates.is_init_expr_cxx11_constant an | _ -> L.(die ExternalError) "Undefined Predicate or wrong set of arguments: '%s'" pred_name diff --git a/infer/tests/codetoanalyze/cpp/linters/extracopy.al b/infer/tests/codetoanalyze/cpp/linters/extracopy.al index 43724b4c1..4bc50e55c 100644 --- a/infer/tests/codetoanalyze/cpp/linters/extracopy.al +++ b/infer/tests/codetoanalyze/cpp/linters/extracopy.al @@ -46,3 +46,15 @@ DEFINE-CHECKER ITERATOR = { SET mode = "ON"; }; + +DEFINE-CHECKER CXX11_CONSTANT_EXPR = { + + SET report_when = + WHEN + is_init_expr_cxx11_constant() + HOLDS-IN-NODE VarDecl; + + SET message = "Found cxx11 constant expression"; + SET mode = "ON"; + +}; diff --git a/infer/tests/codetoanalyze/cpp/linters/extracopy.cpp b/infer/tests/codetoanalyze/cpp/linters/extracopy.cpp index e5221e887..2af074a1a 100644 --- a/infer/tests/codetoanalyze/cpp/linters/extracopy.cpp +++ b/infer/tests/codetoanalyze/cpp/linters/extracopy.cpp @@ -44,3 +44,13 @@ void test_map() { std::cout << p.first << "->" << p.second << std::endl; } } + +int helper_ce(int x) { return 2 * x; } + +int test_const_exp(int x) { + int i = helper_ce(x); // notconst exp + int j = helper_ce(2); // not const exp + int k = 2 * 3; // const exp + int y = x + x; // not const exp + return 0; +} diff --git a/infer/tests/codetoanalyze/cpp/linters/issues.exp b/infer/tests/codetoanalyze/cpp/linters/issues.exp index 8317e439d..23b8f981b 100644 --- a/infer/tests/codetoanalyze/cpp/linters/issues.exp +++ b/infer/tests/codetoanalyze/cpp/linters/issues.exp @@ -1,6 +1,21 @@ +codetoanalyze/cpp/linters/extracopy.cpp, Linters_dummy_method, 33, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, get_a, 21, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, get_a_ref, 16, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_a, 26, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_a, 27, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] codetoanalyze/cpp/linters/extracopy.cpp, test_a, 27, EXTRA_COPY, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_a, 28, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_a, 29, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_const_exp, 54, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_const_exp, 55, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_map, 36, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_map, 37, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] codetoanalyze/cpp/linters/extracopy.cpp, test_map, 37, EXTRA_COPY, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_map, 40, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/extracopy.cpp, test_map, 43, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/iter.cpp, test, 10, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] codetoanalyze/cpp/linters/iter.cpp, test, 11, ITERATOR, no_bucket, WARNING, [] codetoanalyze/cpp/linters/iter.cpp, test, 12, EXTRA_COPY, no_bucket, WARNING, [] codetoanalyze/cpp/linters/iter.cpp, test, 12, ITERATOR, no_bucket, WARNING, [] +codetoanalyze/cpp/linters/type_namespace.cpp, test, 11, CXX11_CONSTANT_EXPR, no_bucket, WARNING, [] codetoanalyze/cpp/linters/type_namespace.cpp, test, 11, NAMESPACE_STRING, no_bucket, WARNING, []