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>
diff --git a/cpplint.py b/cpplint.py
index 209c3ac..0e7f4a8 100755
--- a/cpplint.py
+++ b/cpplint.py
@@ -418,6 +418,231 @@
     '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
 _TYPES = re.compile(
     r'^(?:'
@@ -3832,10 +4057,10 @@
   line = clean_lines.elided[linenum]
 
   # Block bodies should not be followed by a semicolon.  Due to C++11
-  # brace initialization, there are more places where semicolons are
-  # required than not, so we use an allowlist approach to check these
-  # rather than a blocklist.  These are the places where "};" should
-  # be replaced by just "}":
+  # brace initialization and C++20 concepts, there are more places
+  # where semicolons are required than not.  Places that are
+  # recognized as true positives are listed below.
+  #
   # 1. Some flavor of block following closing parenthesis:
   #    for (;;) {};
   #    while (...) {};
@@ -3903,6 +4128,10 @@
     #  - Lambdas
     #  - alignas specifier with anonymous structs
     #  - 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(')')
     opening_parenthesis = ReverseCloseExpression(
         clean_lines, linenum, closing_brace_pos)
@@ -3910,15 +4139,17 @@
       line_prefix = opening_parenthesis[0][0:opening_parenthesis[2]]
       macro = Search(r'\b([A-Z_][A-Z0-9_]*)\s*$', line_prefix)
       func = Match(r'^(.*\])\s*$', line_prefix)
-      if ((macro and
-           macro.group(1) not in (
-               'TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST',
-               'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED',
-               'LOCKS_EXCLUDED', 'INTERFACE_DEF')) or
-          (func and not Search(r'\boperator\s*\[\s*\]', func.group(1))) or
-          Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix) or
-          Search(r'\bdecltype$', line_prefix) or
-          Search(r'\s+=\s*$', line_prefix)):
+      if ((macro and macro.group(1) not in
+           ('TEST', 'TEST_F', 'MATCHER', 'MATCHER_P', 'TYPED_TEST',
+            'EXCLUSIVE_LOCKS_REQUIRED', 'SHARED_LOCKS_REQUIRED',
+            'LOCKS_EXCLUDED', 'INTERFACE_DEF'))
+          or (func and not Search(r'\boperator\s*\[\s*\]', func.group(1)))
+          or Search(r'\b(?:struct|union)\s+alignas\s*$', line_prefix)
+          or Search(r'\b(decltype|requires)$', line_prefix)
+          or Search(r'(?:\s+=|\breturn)\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
     if (match and
         opening_parenthesis[1] > 1 and
@@ -5285,14 +5516,15 @@
     of function types.
   """
   line = clean_lines.elided[linenum]
-  return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or
-          (linenum >= 2 and
-           (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$',
-                  clean_lines.elided[linenum - 1]) or
-            Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$',
-                  clean_lines.elided[linenum - 2]) or
-            Search(r'\bstd::m?function\s*\<\s*$',
-                   clean_lines.elided[linenum - 1]))))
+  return (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line)
+          or _TYPE_TRAITS_RE.search(line)
+          or (linenum >= 2 and
+              (Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\((?:\S+,)?\s*$',
+                     clean_lines.elided[linenum - 1])
+               or Match(r'^\s*MOCK_(?:CONST_)?METHOD\d+(?:_T)?\(\s*$',
+                        clean_lines.elided[linenum - 2])
+               or Search(r'\b(::function|base::FunctionRef)\s*\<\s*$',
+                         clean_lines.elided[linenum - 1]))))
 
 
 _HEADERS_CONTAINING_TEMPLATES = (