From f60fd6f47f4b0c50bd8dbf21b947d007f6772787 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Mon, 19 Nov 2018 14:58:57 +0300 Subject: [PATCH 1/2] Add special case for std::set template usage Avoid false positive for [build/include_what_you_use] in case of `foo.set` and `foo->set` usage --- cpplint.py | 7 ++++++- cpplint_unittest.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/cpplint.py b/cpplint.py index 8ca6471..d61f294 100755 --- a/cpplint.py +++ b/cpplint.py @@ -5533,7 +5533,7 @@ def ExpectingFunctionArgs(clean_lines, linenum): ('', ('allocator', 'make_shared', 'make_unique', 'shared_ptr', 'unique_ptr', 'weak_ptr')), ('', ('queue', 'priority_queue',)), - ('', ('set', 'multiset',)), + ('', ('multiset',)), ('', ('stack',)), ('', ('char_traits', 'basic_string',)), ('', ('tuple',)), @@ -5567,6 +5567,11 @@ def ExpectingFunctionArgs(clean_lines, linenum): (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'), _template, _header)) +# Match set, but not foo->set, foo.set +_re_pattern_headers_maybe_templates.append( + (re.compile(r'[^>.]\bset\s*\<'), + 'set<>', + '')) # Other scripts may reach in and modify this pattern. _re_pattern_templates = [] diff --git a/cpplint_unittest.py b/cpplint_unittest.py index 30cc660..343ffd0 100755 --- a/cpplint_unittest.py +++ b/cpplint_unittest.py @@ -1112,6 +1112,19 @@ def testIncludeWhatYouUse(self): """, 'Add #include for swap' ' [build/include_what_you_use] [4]') + # False positive for std::set + self.TestIncludeWhatYouUse( + """ + #include + struct Foo { + template + void set(const std::string& name, const T& value); + }; + Foo bar; + Foo* pbar = &bar; + bar.set("int", 5); + pbar->set("bool", false);""", + '') # Test the UpdateIncludeState code path. mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"'] From 21356fcfbfa1e6d892b6dd4c103c8d8b19d28e29 Mon Sep 17 00:00:00 2001 From: Vladislav Vinogradov Date: Thu, 25 Jul 2019 10:41:47 +0300 Subject: [PATCH 2/2] Add special case for std::map template usage Avoid false positive for [build/include_what_you_use] in case of `map` is user defined function --- cpplint.py | 7 ++++++- cpplint_unittest.py | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/cpplint.py b/cpplint.py index d61f294..3344a29 100755 --- a/cpplint.py +++ b/cpplint.py @@ -5529,7 +5529,7 @@ def ExpectingFunctionArgs(clean_lines, linenum): )), ('', ('numeric_limits',)), ('', ('list',)), - ('', ('map', 'multimap',)), + ('', ('multimap',)), ('', ('allocator', 'make_shared', 'make_unique', 'shared_ptr', 'unique_ptr', 'weak_ptr')), ('', ('queue', 'priority_queue',)), @@ -5572,6 +5572,11 @@ def ExpectingFunctionArgs(clean_lines, linenum): (re.compile(r'[^>.]\bset\s*\<'), 'set<>', '')) +# Match 'map var' and 'std::map(...)', but not 'map(...)'' +_re_pattern_headers_maybe_templates.append( + (re.compile(r'(std\b::\bmap\s*\<)|(^(std\b::\b)map\b\(\s*\<)'), + 'map<>', + '')) # Other scripts may reach in and modify this pattern. _re_pattern_templates = [] diff --git a/cpplint_unittest.py b/cpplint_unittest.py index 343ffd0..0acedee 100755 --- a/cpplint_unittest.py +++ b/cpplint_unittest.py @@ -1125,6 +1125,22 @@ def testIncludeWhatYouUse(self): bar.set("int", 5); pbar->set("bool", false);""", '') + # False positive for std::map + self.TestIncludeWhatYouUse( + """ + template + struct Foo { + T t; + }; + template + Foo map(T t) { + return Foo{ t }; + } + struct Bar { + }; + auto res = map(); + """, + '') # Test the UpdateIncludeState code path. mock_header_contents = ['#include "blah/foo.h"', '#include "blah/bar.h"']