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)
| 5072 | |
| 5073 | |
| 5074 | def CheckCasts(filename, clean_lines, linenum, error): |
| 5075 | """Various cast related checks. |
| 5076 | |
| 5077 | Args: |
| 5078 | filename: The name of the current file. |
| 5079 | clean_lines: A CleansedLines instance containing the file. |
| 5080 | linenum: The number of the line to check. |
| 5081 | error: The function to call with any errors found. |
| 5082 | """ |
| 5083 | line = clean_lines.elided[linenum] |
| 5084 | |
| 5085 | # Check to see if they're using an conversion function cast. |
| 5086 | # I just try to capture the most common basic types, though there are more. |
| 5087 | # Parameterless conversion functions, such as bool(), are allowed as they are |
| 5088 | # probably a member operator declaration or default constructor. |
| 5089 | match = Search( |
| 5090 | r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b' |
| 5091 | r'(int|float|double|bool|char|int32|uint32|int64|uint64)' |
| 5092 | r'(\([^)].*)', line) |
| 5093 | expecting_function = ExpectingFunctionArgs(clean_lines, linenum) |
| 5094 | if match and not expecting_function: |
| 5095 | matched_type = match.group(2) |
| 5096 | |
| 5097 | # matched_new_or_template is used to silence two false positives: |
| 5098 | # - New operators |
| 5099 | # - Template arguments with function types |
| 5100 | # |
| 5101 | # For template arguments, we match on types immediately following |
| 5102 | # an opening bracket without any spaces. This is a fast way to |
| 5103 | # silence the common case where the function type is the first |
| 5104 | # template argument. False negative with less-than comparison is |
| 5105 | # avoided because those operators are usually followed by a space. |
| 5106 | # |
| 5107 | # function<double(double)> // bracket + no space = false positive |
| 5108 | # value < double(42) // bracket + space = true positive |
| 5109 | matched_new_or_template = match.group(1) |
| 5110 | |
| 5111 | # Avoid arrays by looking for brackets that come after the closing |
| 5112 | # parenthesis. |
| 5113 | if Match(r'\([^()]+\)\s*\[', match.group(3)): |
| 5114 | return |
| 5115 | |
| 5116 | # Other things to ignore: |
| 5117 | # - Function pointers |
| 5118 | # - Casts to pointer types |
| 5119 | # - Placement new |
| 5120 | # - Alias declarations |
| 5121 | matched_funcptr = match.group(3) |
| 5122 | if (matched_new_or_template is None and |
| 5123 | not (matched_funcptr and |
| 5124 | (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', |
| 5125 | matched_funcptr) or |
| 5126 | matched_funcptr.startswith('(*)'))) and |
| 5127 | not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and |
| 5128 | not Search(r'new\(\S+\)\s*' + matched_type, line)): |
| 5129 | error(filename, linenum, 'readability/casting', 4, |
| 5130 | 'Using deprecated casting style. ' |
| 5131 | 'Use static_cast<%s>(...) instead' % |
no test coverage detected