Code Duplication    Length = 115-115 lines in 2 locations

core/build-support/cpplint.py 1 location

@@ 5307-5421 (lines=115) @@
5304
            ReplaceAll(' *<', '<', parameter))
5305
5306
5307
def CheckCasts(filename, clean_lines, linenum, error):
5308
  """Various cast related checks.
5309
5310
  Args:
5311
    filename: The name of the current file.
5312
    clean_lines: A CleansedLines instance containing the file.
5313
    linenum: The number of the line to check.
5314
    error: The function to call with any errors found.
5315
  """
5316
  line = clean_lines.elided[linenum]
5317
5318
  # Check to see if they're using an conversion function cast.
5319
  # I just try to capture the most common basic types, though there are more.
5320
  # Parameterless conversion functions, such as bool(), are allowed as they are
5321
  # probably a member operator declaration or default constructor.
5322
  match = Search(
5323
      r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b'
5324
      r'(int|float|double|bool|char|int32|uint32|int64|uint64)'
5325
      r'(\([^)].*)', line)
5326
  expecting_function = ExpectingFunctionArgs(clean_lines, linenum)
5327
  if match and not expecting_function:
5328
    matched_type = match.group(2)
5329
5330
    # matched_new_or_template is used to silence two false positives:
5331
    # - New operators
5332
    # - Template arguments with function types
5333
    #
5334
    # For template arguments, we match on types immediately following
5335
    # an opening bracket without any spaces.  This is a fast way to
5336
    # silence the common case where the function type is the first
5337
    # template argument.  False negative with less-than comparison is
5338
    # avoided because those operators are usually followed by a space.
5339
    #
5340
    #   function<double(double)>   // bracket + no space = false positive
5341
    #   value < double(42)         // bracket + space = true positive
5342
    matched_new_or_template = match.group(1)
5343
5344
    # Avoid arrays by looking for brackets that come after the closing
5345
    # parenthesis.
5346
    if Match(r'\([^()]+\)\s*\[', match.group(3)):
5347
      return
5348
5349
    # Other things to ignore:
5350
    # - Function pointers
5351
    # - Casts to pointer types
5352
    # - Placement new
5353
    # - Alias declarations
5354
    matched_funcptr = match.group(3)
5355
    if (matched_new_or_template is None and
5356
        not (matched_funcptr and
5357
             (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(',
5358
                    matched_funcptr) or
5359
              matched_funcptr.startswith('(*)'))) and
5360
        not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and
5361
        not Search(r'new\(\S+\)\s*' + matched_type, line)):
5362
      error(filename, linenum, 'readability/casting', 4,
5363
            'Using deprecated casting style.  '
5364
            'Use static_cast<%s>(...) instead' %
5365
            matched_type)
5366
5367
  if not expecting_function:
5368
    CheckCStyleCast(filename, clean_lines, linenum, 'static_cast',
5369
                    r'\((int|float|double|bool|char|u?int(16|32|64))\)', error)
5370
5371
  # This doesn't catch all cases. Consider (const char * const)"hello".
5372
  #
5373
  # (char *) "foo" should always be a const_cast (reinterpret_cast won't
5374
  # compile).
5375
  if CheckCStyleCast(filename, clean_lines, linenum, 'const_cast',
5376
                     r'\((char\s?\*+\s?)\)\s*"', error):
5377
    pass
5378
  else:
5379
    # Check pointer casts for other than string constants
5380
    CheckCStyleCast(filename, clean_lines, linenum, 'reinterpret_cast',
5381
                    r'\((\w+\s?\*+\s?)\)', error)
5382
5383
  # In addition, we look for people taking the address of a cast.  This
5384
  # is dangerous -- casts can assign to temporaries, so the pointer doesn't
5385
  # point where you think.
5386
  #
5387
  # Some non-identifier character is required before the '&' for the
5388
  # expression to be recognized as a cast.  These are casts:
5389
  #   expression = &static_cast<int*>(temporary());
5390
  #   function(&(int*)(temporary()));
5391
  #
5392
  # This is not a cast:
5393
  #   reference_type&(int* function_param);
5394
  match = Search(
5395
      r'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|'
5396
      r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line)
5397
  if match:
5398
    # Try a better error message when the & is bound to something
5399
    # dereferenced by the casted pointer, as opposed to the casted
5400
    # pointer itself.
5401
    parenthesis_error = False
5402
    match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line)
5403
    if match:
5404
      _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1)))
5405
      if x1 >= 0 and clean_lines.elided[y1][x1] == '(':
5406
        _, y2, x2 = CloseExpression(clean_lines, y1, x1)
5407
        if x2 >= 0:
5408
          extended_line = clean_lines.elided[y2][x2:]
5409
          if y2 < clean_lines.NumLines() - 1:
5410
            extended_line += clean_lines.elided[y2 + 1]
5411
          if Match(r'\s*(?:->|\[)', extended_line):
5412
            parenthesis_error = True
5413
5414
    if parenthesis_error:
5415
      error(filename, linenum, 'readability/casting', 4,
5416
            ('Are you taking an address of something dereferenced '
5417
             'from a cast?  Wrapping the dereferenced expression in '
5418
             'parentheses will make the binding more obvious'))
5419
    else:
5420
      error(filename, linenum, 'runtime/casting', 4,
5421
            ('Are you taking an address of a cast?  '
5422
             'This is dangerous: could be a temp var.  '
5423
             'Take the address before doing the cast, rather than after'))
5424

sdk/build-support/cpplint.py 1 location

@@ 5307-5421 (lines=115) @@
5304
            ReplaceAll(' *<', '<', parameter))
5305
5306
5307
def CheckCasts(filename, clean_lines, linenum, error):
5308
  """Various cast related checks.
5309
5310
  Args:
5311
    filename: The name of the current file.
5312
    clean_lines: A CleansedLines instance containing the file.
5313
    linenum: The number of the line to check.
5314
    error: The function to call with any errors found.
5315
  """
5316
  line = clean_lines.elided[linenum]
5317
5318
  # Check to see if they're using an conversion function cast.
5319
  # I just try to capture the most common basic types, though there are more.
5320
  # Parameterless conversion functions, such as bool(), are allowed as they are
5321
  # probably a member operator declaration or default constructor.
5322
  match = Search(
5323
      r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b'
5324
      r'(int|float|double|bool|char|int32|uint32|int64|uint64)'
5325
      r'(\([^)].*)', line)
5326
  expecting_function = ExpectingFunctionArgs(clean_lines, linenum)
5327
  if match and not expecting_function:
5328
    matched_type = match.group(2)
5329
5330
    # matched_new_or_template is used to silence two false positives:
5331
    # - New operators
5332
    # - Template arguments with function types
5333
    #
5334
    # For template arguments, we match on types immediately following
5335
    # an opening bracket without any spaces.  This is a fast way to
5336
    # silence the common case where the function type is the first
5337
    # template argument.  False negative with less-than comparison is
5338
    # avoided because those operators are usually followed by a space.
5339
    #
5340
    #   function<double(double)>   // bracket + no space = false positive
5341
    #   value < double(42)         // bracket + space = true positive
5342
    matched_new_or_template = match.group(1)
5343
5344
    # Avoid arrays by looking for brackets that come after the closing
5345
    # parenthesis.
5346
    if Match(r'\([^()]+\)\s*\[', match.group(3)):
5347
      return
5348
5349
    # Other things to ignore:
5350
    # - Function pointers
5351
    # - Casts to pointer types
5352
    # - Placement new
5353
    # - Alias declarations
5354
    matched_funcptr = match.group(3)
5355
    if (matched_new_or_template is None and
5356
        not (matched_funcptr and
5357
             (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(',
5358
                    matched_funcptr) or
5359
              matched_funcptr.startswith('(*)'))) and
5360
        not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and
5361
        not Search(r'new\(\S+\)\s*' + matched_type, line)):
5362
      error(filename, linenum, 'readability/casting', 4,
5363
            'Using deprecated casting style.  '
5364
            'Use static_cast<%s>(...) instead' %
5365
            matched_type)
5366
5367
  if not expecting_function:
5368
    CheckCStyleCast(filename, clean_lines, linenum, 'static_cast',
5369
                    r'\((int|float|double|bool|char|u?int(16|32|64))\)', error)
5370
5371
  # This doesn't catch all cases. Consider (const char * const)"hello".
5372
  #
5373
  # (char *) "foo" should always be a const_cast (reinterpret_cast won't
5374
  # compile).
5375
  if CheckCStyleCast(filename, clean_lines, linenum, 'const_cast',
5376
                     r'\((char\s?\*+\s?)\)\s*"', error):
5377
    pass
5378
  else:
5379
    # Check pointer casts for other than string constants
5380
    CheckCStyleCast(filename, clean_lines, linenum, 'reinterpret_cast',
5381
                    r'\((\w+\s?\*+\s?)\)', error)
5382
5383
  # In addition, we look for people taking the address of a cast.  This
5384
  # is dangerous -- casts can assign to temporaries, so the pointer doesn't
5385
  # point where you think.
5386
  #
5387
  # Some non-identifier character is required before the '&' for the
5388
  # expression to be recognized as a cast.  These are casts:
5389
  #   expression = &static_cast<int*>(temporary());
5390
  #   function(&(int*)(temporary()));
5391
  #
5392
  # This is not a cast:
5393
  #   reference_type&(int* function_param);
5394
  match = Search(
5395
      r'(?:[^\w]&\(([^)*][^)]*)\)[\w(])|'
5396
      r'(?:[^\w]&(static|dynamic|down|reinterpret)_cast\b)', line)
5397
  if match:
5398
    # Try a better error message when the & is bound to something
5399
    # dereferenced by the casted pointer, as opposed to the casted
5400
    # pointer itself.
5401
    parenthesis_error = False
5402
    match = Match(r'^(.*&(?:static|dynamic|down|reinterpret)_cast\b)<', line)
5403
    if match:
5404
      _, y1, x1 = CloseExpression(clean_lines, linenum, len(match.group(1)))
5405
      if x1 >= 0 and clean_lines.elided[y1][x1] == '(':
5406
        _, y2, x2 = CloseExpression(clean_lines, y1, x1)
5407
        if x2 >= 0:
5408
          extended_line = clean_lines.elided[y2][x2:]
5409
          if y2 < clean_lines.NumLines() - 1:
5410
            extended_line += clean_lines.elided[y2 + 1]
5411
          if Match(r'\s*(?:->|\[)', extended_line):
5412
            parenthesis_error = True
5413
5414
    if parenthesis_error:
5415
      error(filename, linenum, 'readability/casting', 4,
5416
            ('Are you taking an address of something dereferenced '
5417
             'from a cast?  Wrapping the dereferenced expression in '
5418
             'parentheses will make the binding more obvious'))
5419
    else:
5420
      error(filename, linenum, 'runtime/casting', 4,
5421
            ('Are you taking an address of a cast?  '
5422
             'This is dangerous: could be a temp var.  '
5423
             'Take the address before doing the cast, rather than after'))
5424