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)
| 6599 | |
| 6600 | |
| 6601 | def CheckCasts(filename, clean_lines, linenum, error): |
| 6602 | """Various cast related checks. |
| 6603 | |
| 6604 | Args: |
| 6605 | filename: The name of the current file. |
| 6606 | clean_lines: A CleansedLines instance containing the file. |
| 6607 | linenum: The number of the line to check. |
| 6608 | error: The function to call with any errors found. |
| 6609 | """ |
| 6610 | line = clean_lines.elided[linenum] |
| 6611 | |
| 6612 | # Check to see if they're using an conversion function cast. |
| 6613 | # I just try to capture the most common basic types, though there are more. |
| 6614 | # Parameterless conversion functions, such as bool(), are allowed as they are |
| 6615 | # probably a member operator declaration or default constructor. |
| 6616 | match = re.search( |
| 6617 | r"(\bnew\s+(?:const\s+)?|\S<\s*(?:const\s+)?)?\b" |
| 6618 | r"(int|float|double|bool|char|int16_t|uint16_t|int32_t|uint32_t|int64_t|uint64_t)" |
| 6619 | r"(\([^)].*)", |
| 6620 | line, |
| 6621 | ) |
| 6622 | expecting_function = ExpectingFunctionArgs(clean_lines, linenum) |
| 6623 | if match and not expecting_function: |
| 6624 | matched_type = match.group(2) |
| 6625 | |
| 6626 | # matched_new_or_template is used to silence two false positives: |
| 6627 | # - New operators |
| 6628 | # - Template arguments with function types |
| 6629 | # |
| 6630 | # For template arguments, we match on types immediately following |
| 6631 | # an opening bracket without any spaces. This is a fast way to |
| 6632 | # silence the common case where the function type is the first |
| 6633 | # template argument. False negative with less-than comparison is |
| 6634 | # avoided because those operators are usually followed by a space. |
| 6635 | # |
| 6636 | # function<double(double)> // bracket + no space = false positive |
| 6637 | # value < double(42) // bracket + space = true positive |
| 6638 | matched_new_or_template = match.group(1) |
| 6639 | |
| 6640 | # Avoid arrays by looking for brackets that come after the closing |
| 6641 | # parenthesis. |
| 6642 | if re.match(r"\([^()]+\)\s*\[", match.group(3)): |
| 6643 | return |
| 6644 | |
| 6645 | # Other things to ignore: |
| 6646 | # - Function pointers |
| 6647 | # - Casts to pointer types |
| 6648 | # - Placement new |
| 6649 | # - Alias declarations |
| 6650 | matched_funcptr = match.group(3) |
| 6651 | if ( |
| 6652 | matched_new_or_template is None |
| 6653 | and not ( |
| 6654 | matched_funcptr |
| 6655 | and ( |
| 6656 | re.match(r"\((?:[^() ]+::\s*\*\s*)?[^() ]+\)\s*\(", matched_funcptr) |
| 6657 | or matched_funcptr.startswith("(*)") |
| 6658 | ) |
no test coverage detected
searching dependent graphs…