Fix various lint false positives.

* C++11: Expressions related to type_traits templates. Cherry-pick of
  internal cl/477737746.
* C++20: requires-expressions. Cherry pick of internal cl/450768176.
* C++20: `co_return *p;`. Unique to Chromium (cpplint_chromium.py).

Bug: 1284275
Change-Id: I06ede7b708dfe71308f669a2d6c37d00ded6c086
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4226465
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Reviewed-by: Gavin Mak <gavinmak@google.com>
Commit-Queue: Peter Kasting <pkasting@chromium.org>
changes/65/4226465/4
Peter Kasting 2 years ago committed by LUCI CQ
parent f15baeae48
commit 0074158bf6

274
cpplint.py vendored

@ -418,6 +418,231 @@ _CPP_HEADERS = frozenset([
'cwctype', 'cwctype',
]) ])
# List of functions from <type_traits>. See [meta.type.synop]
_TYPE_TRAITS = [
# 23.15.3, helper class
'integral_constant',
# 23.15.4.1, primary type categories
'is_void',
'is_null_pointer',
'is_integral',
'is_floating_point',
'is_array',
'is_pointer',
'is_lvalue_reference',
'is_rvalue_reference',
'is_member_object_pointer',
'is_member_function_pointer',
'is_enum',
'is_union',
'is_class',
'is_function',
# 23.15.4.2, composite type categories
'is_reference',
'is_arithmetic',
'is_fundamental',
'is_object',
'is_scalar',
'is_compound',
'is_member_pointer',
# 23.15.4.3, type properties
'is_const',
'is_volatile',
'is_trivial',
'is_trivially_copyable',
'is_standard_layout',
'is_pod',
'is_empty',
'is_polymorphic',
'is_abstract',
'is_final',
'is_aggregate',
'is_signed',
'is_unsigned',
'is_constructible',
'is_default_constructible',
'is_copy_constructible',
'is_move_constructible',
'is_assignable',
'is_copy_assignable',
'is_move_assignable',
'is_swappable_with',
'is_swappable',
'is_destructible',
'is_trivially_constructible',
'is_trivially_default_constructible',
'is_trivially_copy_constructible',
'is_trivially_move_constructible',
'is_trivially_assignable',
'is_trivially_copy_assignable',
'is_trivially_move_assignable',
'is_trivially_destructible',
'is_nothrow_constructible',
'is_nothrow_default_constructible',
'is_nothrow_copy_constructible',
'is_nothrow_move_constructible',
'is_nothrow_assignable',
'is_nothrow_copy_assignable',
'is_nothrow_move_assignable',
'is_nothrow_swappable_with',
'is_nothrow_swappable',
'is_nothrow_destructible',
'has_virtual_destructor',
'has_unique_object_representations',
# 23.15.5, type property queries
'alignment_of',
'rank',
'extent',
# 23.15.6, type relations
'is_same',
'is_base_of',
'is_convertible',
'is_invocable',
'is_invocable_r',
'is_nothrow_invocable',
'is_nothrow_invocable_r',
# 23.15.7.1, const-volatile modifications
'remove_const',
'remove_volatile',
'remove_cv',
'add_const',
'add_volatile',
'add_cv',
'remove_const_t',
'remove_volatile_t',
'remove_cv_t',
'add_const_t',
'add_volatile_t',
'add_cv_t',
# 23.15.7.2, reference modifications
'remove_reference',
'add_lvalue_reference',
'add_rvalue_reference',
'remove_reference_t',
'add_lvalue_reference_t',
'add_rvalue_reference_t',
# 23.15.7.3, sign modifications
'make_signed',
'make_unsigned',
'make_signed_t',
'make_unsigned_t',
# 23.15.7.4, array modifications
'remove_extent',
'remove_all_extents',
'remove_extent_t',
'remove_all_extents_t',
# 23.15.7.5, pointer modifications
'remove_pointer',
'add_pointer',
'remove_pointer_t',
'add_pointer_t',
# 23.15.7.6, other transformations
'aligned_storage',
'aligned_union',
'decay',
'enable_if',
'conditional',
'common_type',
'underlying_type',
'invoke_result',
'aligned_storage_t',
'aligned_union_t',
'decay_t',
'enable_if_t',
'conditional_t',
'common_type_t',
'underlying_type_t',
'invoke_result_t',
'void_t',
# 23.15.8, logical operator traits
'conjunction',
'disjunction',
'negation',
# 23.15.4.1, primary type categories
'is_void_v',
'is_null_pointer_v',
'is_integral_v',
'is_floating_point_v',
'is_array_v',
'is_pointer_v',
'is_lvalue_reference_v',
'is_rvalue_reference_v',
'is_member_object_pointer_v',
'is_member_function_pointer_v',
'is_enum_v',
'is_union_v',
'is_class_v',
'is_function_v',
# 23.15.4.2, composite type categories
'is_reference_v',
'is_arithmetic_v',
'is_fundamental_v',
'is_object_v',
'is_scalar_v',
'is_compound_v',
'is_member_pointer_v',
# 23.15.4.3, type properties
'is_const_v',
'is_volatile_v',
'is_trivial_v',
'is_trivially_copyable_v',
'is_standard_layout_v',
'is_pod_v',
'is_empty_v',
'is_polymorphic_v',
'is_abstract_v',
'is_final_v',
'is_aggregate_v',
'is_signed_v',
'is_unsigned_v',
'is_constructible_v',
'is_default_constructible_v',
'is_copy_constructible_v',
'is_move_constructible_v',
'is_assignable_v',
'is_copy_assignable_v',
'is_move_assignable_v',
'is_swappable_with_v',
'is_swappable_v',
'is_destructible_v',
'is_trivially_constructible_v',
'is_trivially_default_constructible_v',
'is_trivially_copy_constructible_v',
'is_trivially_move_constructible_v',
'is_trivially_assignable_v',
'is_trivially_copy_assignable_v',
'is_trivially_move_assignable_v',
'is_trivially_destructible_v',
'is_nothrow_constructible_v',
'is_nothrow_default_constructible_v',
'is_nothrow_copy_constructible_v',
'is_nothrow_move_constructible_v',
'is_nothrow_assignable_v',
'is_nothrow_copy_assignable_v',
'is_nothrow_move_assignable_v',
'is_nothrow_swappable_with_v',
'is_nothrow_swappable_v',
'is_nothrow_destructible_v',
'has_virtual_destructor_v',
'has_unique_object_representations_v',
# 23.15.5, type property queries
'alignment_of_v',
'rank_v',
'extent_v',
'is_same_v',
'is_base_of_v',
'is_convertible_v',
'is_invocable_v',
'is_invocable_r_v',
'is_nothrow_invocable_v',
'is_nothrow_invocable_r_v',
# 23.15.8, logical operator traits
'conjunction_v',
'disjunction_v',
'negation_v',
]
_TYPE_TRAITS_RE = re.compile(r'\b::(?:' + ('|'.join(_TYPE_TRAITS)) + ')<')
# Type names # Type names
_TYPES = re.compile( _TYPES = re.compile(
r'^(?:' r'^(?:'
@ -3832,10 +4057,10 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
line = clean_lines.elided[linenum] line = clean_lines.elided[linenum]
# Block bodies should not be followed by a semicolon. Due to C++11 # Block bodies should not be followed by a semicolon. Due to C++11
# brace initialization, there are more places where semicolons are # brace initialization and C++20 concepts, there are more places
# required than not, so we use an allowlist approach to check these # where semicolons are required than not. Places that are
# rather than a blocklist. These are the places where "};" should # recognized as true positives are listed below.
# be replaced by just "}": #
# 1. Some flavor of block following closing parenthesis: # 1. Some flavor of block following closing parenthesis:
# for (;;) {}; # for (;;) {};
# while (...) {}; # while (...) {};
@ -3903,6 +4128,10 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
# - Lambdas # - Lambdas
# - alignas specifier with anonymous structs # - alignas specifier with anonymous structs
# - decltype # - decltype
# - Type casts with parentheses, e.g.: var = (Type){value};
# - Return type casts with parentheses, e.g.: return (Type){value};
# - Function pointers with initializer list, e.g.: int (*f)(){};
# - Requires expression, e.g. C = requires(){};
closing_brace_pos = match.group(1).rfind(')') closing_brace_pos = match.group(1).rfind(')')
opening_parenthesis = ReverseCloseExpression( opening_parenthesis = ReverseCloseExpression(
clean_lines, linenum, closing_brace_pos) clean_lines, linenum, closing_brace_pos)
@ -3910,15 +4139,17 @@ def CheckTrailingSemicolon(filename, clean_lines, linenum, error):
line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]] line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]]
macro = Search(r'\b([A-Z_][A-Z0-9_]*)\s*$', line_prefix) macro = Search(r'\b([A-Z_][A-Z0-9_]*)\s*$', line_prefix)
func = Match(r'^(.*\])\s*$', line_prefix) func = Match(r'^(.*\])\s*$', line_prefix)
if ((macro and if ((macro and macro.group(1) not in
macro.group(1) not in ( ('TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST',
'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST', 'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED',
'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED', 'LOCKS_EXCLUDED', 'INTERFACE_DEF'))
'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or or (func and not Search(r'\boperator\s*\[\s*\]', func.group(1)))
(func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or or Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix)
Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or or Search(r'\b(decltype|requires)$', line_prefix)
Search(r'\bdecltype$', line_prefix) or or Search(r'(?:\s+=|\breturn)\s*$', line_prefix)
Search(r'\s+=\s*$', line_prefix)): or (Match(r'^\s*$', line_prefix) and Search(
r'(?:\s+=|\breturn)\s*$', clean_lines.elided[linenum - 1]))
or Search(r'\(\*\w+\)$', line_prefix)):
match = None match = None
if (match and if (match and
opening_parenthesis[1] > 1 and opening_parenthesis[1] > 1 and
@ -5285,14 +5516,15 @@ def ExpectingFunctionArgs(clean_lines, linenum):
of function types. of function types.
""" """
line = clean_lines.elided[linenum] line = clean_lines.elided[linenum]
return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line)
(linenum >= 2 and or _TYPE_TRAITS_RE.search(line)
(Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$', or (linenum >= 2 and
clean_lines.elided[linenum - 1]) or (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$',
Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$', clean_lines.elided[linenum - 1])
clean_lines.elided[linenum - 2]) or or Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$',
Search(r'\bstd::m?function\s*\<\s*$', clean_lines.elided[linenum - 2])
clean_lines.elided[linenum - 1])))) or Search(r'\b(::function|base::FunctionRef)\s*\<\s*$',
clean_lines.elided[linenum - 1]))))
_HEADERS_CONTAINING_TEMPLATES = ( _HEADERS_CONTAINING_TEMPLATES = (

@ -31,7 +31,9 @@ import re
# Matches Foo *foo declarations. # Matches Foo *foo declarations.
_RE_PATTERN_POINTER_DECLARATION_WHITESPACE = re.compile( _RE_PATTERN_POINTER_DECLARATION_WHITESPACE = re.compile(
r'\s*\w+(?<!\breturn|\bdelete)\s+(?P<pointer_operator>\*|\&)\w+') r'\s*\w+((?<!\breturn|\bdelete)(?<!\bco_return))\s+'
r'(?P<pointer_operator>\*|\&)\w+')
def CheckPointerDeclarationWhitespace(filename, clean_lines, linenum, error): def CheckPointerDeclarationWhitespace(filename, clean_lines, linenum, error):
"""Checks for Foo *foo declarations. """Checks for Foo *foo declarations.

Loading…
Cancel
Save