Whitelist comparison operators and their equivalent functors in <functional>

Reviewed By: akotulski

Differential Revision: D5449231

fbshipit-source-id: b6a946d
master
Jia Chen 7 years ago committed by Facebook Github Bot
parent 6c874957d0
commit 217363f5d6

@ -76,7 +76,14 @@ module Match = struct
(* Fail if we detect templates in the fuzzy name. Template instantiations are not taken into
account when fuzzy matching, and templates may produce wrong results when parsing qualified
names. *)
if String.contains qual_name '<' then
let filtered_qual_name =
(* Filter out the '<' in operator< and operator<= *)
let operator_less_length = 14 in
if String.is_prefix qual_name ~prefix:"std::operator<" then
String.drop_prefix qual_name operator_less_length
else qual_name
in
if String.contains filtered_qual_name '<' then
failwithf "Unexpected template in fuzzy qualified name %s." qual_name ;
of_qual_string qual_name

@ -257,6 +257,12 @@ let whitelisted_cpp_methods =
; "std::max"
; "std::min"
; "std::move"
; "std::operator!="
; "std::operator<"
; "std::operator<="
; "std::operator=="
; "std::operator>"
; "std::operator>="
; "std::swap" ]
let whitelisted_cpp_classes =
@ -265,6 +271,12 @@ let whitelisted_cpp_classes =
; "std::__wrap_iter" (* libc++ internal name of vector iterator *)
; "std::__get_pair" (* libc++ internal support class for std::get<std::pair> *)
; "std::__pair_get" (* libstdc++ internal support class for std::get<std::pair> *)
; "std::equal_to"
; "std::greater"
; "std::greater_equal"
; "std::less"
; "std::less_equal"
; "std::not_equal_to"
; "std::pair" ]
type dynamic_dispatch_policy = [`None | `Interface | `Sound | `Lazy]

@ -16,6 +16,18 @@ codetoanalyze/cpp/errors/include_header/header2.h, header2::div0_templ<int>, 1,
codetoanalyze/cpp/errors/memory_leaks/array_leak.cpp, leak, 4, MEMORY_LEAK, [start of procedure leak()]
codetoanalyze/cpp/errors/memory_leaks/object_leak.cpp, object_leak, 0, MEMORY_LEAK, [start of procedure object_leak(),start of procedure Rectangle,return from a call to Rectangle_Rectangle]
codetoanalyze/cpp/errors/memory_leaks/raii_malloc.cpp, memory_leak, 0, MEMORY_LEAK, [start of procedure memory_leak()]
codetoanalyze/cpp/errors/models/cmp.cpp, operator_eq_bad, 4, NULL_DEREFERENCE, [start of procedure operator_eq_bad(),start of procedure operator==(),Condition is true,Condition is true,return from a call to operator==,Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, operator_ge_bad, 4, NULL_DEREFERENCE, [start of procedure operator_ge_bad(),start of procedure operator>=(),start of procedure operator<(),Condition is false,Condition is false,Condition is false,return from a call to operator<,Condition is false,return from a call to operator>=,Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, operator_gt_bad, 4, NULL_DEREFERENCE, [start of procedure operator_gt_bad(),start of procedure operator>(),start of procedure operator<(),Condition is false,Condition is false,Condition is true,return from a call to operator<,return from a call to operator>,Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, operator_le_bad, 4, NULL_DEREFERENCE, [start of procedure operator_le_bad(),start of procedure operator<=(),start of procedure operator<(),Condition is false,Condition is false,Condition is false,return from a call to operator<,Condition is false,return from a call to operator<=,Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, operator_lt_bad, 4, NULL_DEREFERENCE, [start of procedure operator_lt_bad(),start of procedure operator<(),Condition is false,Condition is false,Condition is true,return from a call to operator<,Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, operator_neq_bad, 4, NULL_DEREFERENCE, [start of procedure operator_neq_bad(),start of procedure operator!=(),start of procedure operator==(),Condition is true,Condition is true,return from a call to operator==,Condition is true,return from a call to operator!=,Condition is false,Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, std_equal_to_bad, 4, NULL_DEREFERENCE, [start of procedure std_equal_to_bad(),Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, std_greater_bad, 4, NULL_DEREFERENCE, [start of procedure std_greater_bad(),Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, std_greater_equal_bad, 4, NULL_DEREFERENCE, [start of procedure std_greater_equal_bad(),Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, std_less_bad, 4, NULL_DEREFERENCE, [start of procedure std_less_bad(),Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, std_less_equal_bad, 4, NULL_DEREFERENCE, [start of procedure std_less_equal_bad(),Condition is true]
codetoanalyze/cpp/errors/models/cmp.cpp, std_not_equal_to_bad, 4, NULL_DEREFERENCE, [start of procedure std_not_equal_to_bad(),Condition is false,Condition is true]
codetoanalyze/cpp/errors/models/move.cpp, move::div0_moved_from, 3, DIVIDE_BY_ZERO, [start of procedure move::div0_moved_from(),start of procedure X,return from a call to move::X_X,start of procedure X,return from a call to move::X_X]
codetoanalyze/cpp/errors/models/move.cpp, move::div0_moved_to, 3, DIVIDE_BY_ZERO, [start of procedure move::div0_moved_to(),start of procedure X,return from a call to move::X_X,start of procedure X,return from a call to move::X_X]
codetoanalyze/cpp/errors/models/pair.cpp, pair::deref_pair_null0_bad, 3, NULL_DEREFERENCE, [start of procedure pair::deref_pair_null0_bad(),start of procedure pair::pairOfZeroNull(),return from a call to pair::pairOfZeroNull]

@ -0,0 +1,197 @@
/*
* 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.
*/
#include <functional>
struct A {
int x, y;
};
bool operator==(const A& lhs, const A& rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y;
}
bool operator!=(const A& lhs, const A& rhs) { return !(lhs == rhs); }
bool operator<(const A& lhs, const A& rhs) {
if (lhs.x < rhs.x)
return true;
else if (lhs.x > rhs.x)
return false;
else
return lhs.y < rhs.y;
}
bool operator>(const A& lhs, const A& rhs) { return rhs < lhs; }
bool operator>=(const A& lhs, const A& rhs) { return !(lhs < rhs); }
bool operator<=(const A& lhs, const A& rhs) { return !(rhs < lhs); }
void operator_eq_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y};
if (!(a == b))
*p = 42;
}
void operator_eq_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y};
if (a == b)
*p = 42;
}
void operator_neq_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y};
if (a != b)
*p = 42;
}
void operator_neq_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y};
if (!(a != b))
*p = 42;
}
void std_equal_to_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y};
if (!(std::equal_to<A>()(a, b)))
*p = 42;
}
void std_not_equal_to_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y};
if (std::not_equal_to<A>()(a, b))
*p = 42;
}
void std_equal_to_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y};
if (std::equal_to<A>()(a, b))
*p = 42;
}
void std_not_equal_to_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y};
if (!(std::not_equal_to<A>()(a, b)))
*p = 42;
}
void operator_lt_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y + 1};
if (!(a < b))
*p = 42;
}
void operator_lt_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y + 1};
if (a < b)
*p = 42;
}
void operator_le_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y + 1};
if (!(a <= b))
*p = 42;
}
void operator_le_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y + 1};
if (a <= b)
*p = 42;
}
void operator_gt_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y - 1};
if (!(a > b))
*p = 42;
}
void operator_gt_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y - 1};
if (a > b)
*p = 42;
}
void operator_ge_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y - 1};
if (!(a >= b))
*p = 42;
}
void operator_ge_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y - 1};
if (a >= b)
*p = 42;
}
void std_less_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y + 1};
if (!(std::less<A>()(a, b)))
*p = 42;
}
void std_less_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y + 1};
if (std::less<A>()(a, b))
*p = 42;
}
void std_less_equal_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y + 1};
if (!(std::less_equal<A>()(a, b)))
*p = 42;
}
void std_less_equal_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y + 1};
if (std::less_equal<A>()(a, b))
*p = 42;
}
void std_greater_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y - 1};
if (!(std::greater<A>()(a, b)))
*p = 42;
}
void std_greater_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y - 1};
if (std::greater<A>()(a, b))
*p = 42;
}
void std_greater_equal_ok(const A& a) {
int* p = nullptr;
A b{a.x, a.y - 1};
if (!(std::greater_equal<A>()(a, b)))
*p = 42;
}
void std_greater_equal_bad(const A& a) {
int* p = nullptr;
A b{a.x, a.y - 1};
if (std::greater_equal<A>()(a, b))
*p = 42;
}
Loading…
Cancel
Save