Check for unsafe global or static objects. 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)
| 6258 | |
| 6259 | |
| 6260 | def CheckGlobalStatic(filename, clean_lines, linenum, error): |
| 6261 | """Check for unsafe global or static objects. |
| 6262 | |
| 6263 | Args: |
| 6264 | filename: The name of the current file. |
| 6265 | clean_lines: A CleansedLines instance containing the file. |
| 6266 | linenum: The number of the line to check. |
| 6267 | error: The function to call with any errors found. |
| 6268 | """ |
| 6269 | line = clean_lines.elided[linenum] |
| 6270 | |
| 6271 | # Match two lines at a time to support multiline declarations |
| 6272 | if linenum + 1 < clean_lines.NumLines() and not re.search(r"[;({]", line): |
| 6273 | line += clean_lines.elided[linenum + 1].strip() |
| 6274 | |
| 6275 | # Check for people declaring static/global STL strings at the top level. |
| 6276 | # This is dangerous because the C++ language does not guarantee that |
| 6277 | # globals with constructors are initialized before the first access, and |
| 6278 | # also because globals can be destroyed when some threads are still running. |
| 6279 | # TODO(google): Generalize this to also find static unique_ptr instances. |
| 6280 | # TODO(google): File bugs for clang-tidy to find these. |
| 6281 | match = re.match( |
| 6282 | r"((?:|static +)(?:|const +))(?::*std::)?string( +const)? +" |
| 6283 | r"([a-zA-Z0-9_:]+)\b(.*)", |
| 6284 | line, |
| 6285 | ) |
| 6286 | |
| 6287 | # Remove false positives: |
| 6288 | # - String pointers (as opposed to values). |
| 6289 | # string *pointer |
| 6290 | # const string *pointer |
| 6291 | # string const *pointer |
| 6292 | # string *const pointer |
| 6293 | # |
| 6294 | # - Functions and template specializations. |
| 6295 | # string Function<Type>(... |
| 6296 | # string Class<Type>::Method(... |
| 6297 | # |
| 6298 | # - Operators. These are matched separately because operator names |
| 6299 | # cross non-word boundaries, and trying to match both operators |
| 6300 | # and functions at the same time would decrease accuracy of |
| 6301 | # matching identifiers. |
| 6302 | # string Class::operator*() |
| 6303 | if ( |
| 6304 | match |
| 6305 | and not re.search(r"\bstring\b(\s+const)?\s*[\*\&]\s*(const\s+)?\w", line) |
| 6306 | and not re.search(r"\boperator\W", line) |
| 6307 | and not re.match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(4)) |
| 6308 | ): |
| 6309 | if re.search(r"\bconst\b", line): |
| 6310 | error( |
| 6311 | filename, |
| 6312 | linenum, |
| 6313 | "runtime/string", |
| 6314 | 4, |
| 6315 | "For a static/global string constant, use a C style string instead:" |
| 6316 | f' "{match.group(1)}char{match.group(2) or ""} {match.group(3)}[]".', |
| 6317 | ) |
no test coverage detected
searching dependent graphs…