Various cast related checks. Args: filename: The name of the current file. clean_lines: A CleansedLines instance containing the file. linenum: The number of the line to check. error: The function to call with any errors found.
(filename, clean_lines, linenum, error)
| 5691 | |
| 5692 | |
| 5693 | def CheckCasts(filename, clean_lines, linenum, error): |
| 5694 | """Various cast related checks. |
| 5695 | |
| 5696 | Args: |
| 5697 | filename: The name of the current file. |
| 5698 | clean_lines: A CleansedLines instance containing the file. |
| 5699 | linenum: The number of the line to check. |
| 5700 | error: The function to call with any errors found. |
| 5701 | """ |
| 5702 | line = clean_lines.elided[linenum] |
| 5703 | |
| 5704 | # Check to see if they're using an conversion function cast. |
| 5705 | # I just try to capture the most common basic types, though there are more. |
| 5706 | # Parameterless conversion functions, such as bool(), are allowed as they are |
| 5707 | # probably a member operator declaration or default constructor. |
| 5708 | match = Search( |
| 5709 | r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b' |
| 5710 | r'(int|float|double|bool|char|int32|uint32|int64|uint64)' |
| 5711 | r'(\([^)].*)', line) |
| 5712 | expecting_function = ExpectingFunctionArgs(clean_lines, linenum) |
| 5713 | if match and not expecting_function: |
| 5714 | matched_type = match.group(2) |
| 5715 | |
| 5716 | # matched_new_or_template is used to silence two false positives: |
| 5717 | # - New operators |
| 5718 | # - Template arguments with function types |
| 5719 | # |
| 5720 | # For template arguments, we match on types immediately following |
| 5721 | # an opening bracket without any spaces. This is a fast way to |
| 5722 | # silence the common case where the function type is the first |
| 5723 | # template argument. False negative with less-than comparison is |
| 5724 | # avoided because those operators are usually followed by a space. |
| 5725 | # |
| 5726 | # function<double(double)> // bracket + no space = false positive |
| 5727 | # value < double(42) // bracket + space = true positive |
| 5728 | matched_new_or_template = match.group(1) |
| 5729 | |
| 5730 | # Avoid arrays by looking for brackets that come after the closing |
| 5731 | # parenthesis. |
| 5732 | if Match(r'\([^()]+\)\s*\[', match.group(3)): |
| 5733 | return |
| 5734 | |
| 5735 | # Other things to ignore: |
| 5736 | # - Function pointers |
| 5737 | # - Casts to pointer types |
| 5738 | # - Placement new |
| 5739 | # - Alias declarations |
| 5740 | matched_funcptr = match.group(3) |
| 5741 | if (matched_new_or_template is None and |
| 5742 | not (matched_funcptr and |
| 5743 | (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', |
| 5744 | matched_funcptr) or |
| 5745 | matched_funcptr.startswith('(*)'))) and |
| 5746 | not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and |
| 5747 | not Search(r'new\(\S+\)\s*' + matched_type, line)): |
| 5748 | error(filename, linenum, 'readability/casting', 4, |
| 5749 | 'Using deprecated casting style. ' |
| 5750 | 'Use static_cast<%s>(...) instead' % |
no test coverage detected