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)
| 5150 | |
| 5151 | |
| 5152 | def CheckCasts(filename, clean_lines, linenum, error): |
| 5153 | """Various cast related checks. |
| 5154 | |
| 5155 | Args: |
| 5156 | filename: The name of the current file. |
| 5157 | clean_lines: A CleansedLines instance containing the file. |
| 5158 | linenum: The number of the line to check. |
| 5159 | error: The function to call with any errors found. |
| 5160 | """ |
| 5161 | line = clean_lines.elided[linenum] |
| 5162 | |
| 5163 | # Check to see if they're using an conversion function cast. |
| 5164 | # I just try to capture the most common basic types, though there are more. |
| 5165 | # Parameterless conversion functions, such as bool(), are allowed as they are |
| 5166 | # probably a member operator declaration or default constructor. |
| 5167 | match = Search( |
| 5168 | r'(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b' |
| 5169 | r'(int|float|double|bool|char|int32|uint32|int64|uint64)' |
| 5170 | r'(\([^)].*)', line) |
| 5171 | expecting_function = ExpectingFunctionArgs(clean_lines, linenum) |
| 5172 | if match and not expecting_function: |
| 5173 | matched_type = match.group(2) |
| 5174 | |
| 5175 | # matched_new_or_template is used to silence two false positives: |
| 5176 | # - New operators |
| 5177 | # - Template arguments with function types |
| 5178 | # |
| 5179 | # For template arguments, we match on types immediately following |
| 5180 | # an opening bracket without any spaces. This is a fast way to |
| 5181 | # silence the common case where the function type is the first |
| 5182 | # template argument. False negative with less-than comparison is |
| 5183 | # avoided because those operators are usually followed by a space. |
| 5184 | # |
| 5185 | # function<double(double)> // bracket + no space = false positive |
| 5186 | # value < double(42) // bracket + space = true positive |
| 5187 | matched_new_or_template = match.group(1) |
| 5188 | |
| 5189 | # Avoid arrays by looking for brackets that come after the closing |
| 5190 | # parenthesis. |
| 5191 | if Match(r'\([^()]+\)\s*\[', match.group(3)): |
| 5192 | return |
| 5193 | |
| 5194 | # Other things to ignore: |
| 5195 | # - Function pointers |
| 5196 | # - Casts to pointer types |
| 5197 | # - Placement new |
| 5198 | # - Alias declarations |
| 5199 | matched_funcptr = match.group(3) |
| 5200 | if (matched_new_or_template is None and |
| 5201 | not (matched_funcptr and |
| 5202 | (Match(r'\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(', |
| 5203 | matched_funcptr) or |
| 5204 | matched_funcptr.startswith('(*)'))) and |
| 5205 | not Match(r'\s*using\s+\S+\s*=\s*' + matched_type, line) and |
| 5206 | not Search(r'new\(\S+\)\s*' + matched_type, line)): |
| 5207 | error(filename, linenum, 'readability/casting', 4, |
| 5208 | 'Using deprecated casting style. ' |
| 5209 | 'Use static_cast<%s>(...) instead' % |
no test coverage detected