@@ 4998-5056 (lines=59) @@ | ||
4995 | ' for more information.') |
|
4996 | ||
4997 | ||
4998 | def CheckGlobalStatic(filename, clean_lines, linenum, error): |
|
4999 | """Check for unsafe global or static objects. |
|
5000 | ||
5001 | Args: |
|
5002 | filename: The name of the current file. |
|
5003 | clean_lines: A CleansedLines instance containing the file. |
|
5004 | linenum: The number of the line to check. |
|
5005 | error: The function to call with any errors found. |
|
5006 | """ |
|
5007 | line = clean_lines.elided[linenum] |
|
5008 | ||
5009 | # Match two lines at a time to support multiline declarations |
|
5010 | if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line): |
|
5011 | line += clean_lines.elided[linenum + 1].strip() |
|
5012 | ||
5013 | # Check for people declaring static/global STL strings at the top level. |
|
5014 | # This is dangerous because the C++ language does not guarantee that |
|
5015 | # globals with constructors are initialized before the first access, and |
|
5016 | # also because globals can be destroyed when some threads are still running. |
|
5017 | # TODO(unknown): Generalize this to also find static unique_ptr instances. |
|
5018 | # TODO(unknown): File bugs for clang-tidy to find these. |
|
5019 | match = Match( |
|
5020 | r'((?:|static +)(?:|const +))(?::*std::)?string( +const)? +' |
|
5021 | r'([a-zA-Z0-9_:]+)\b(.*)', |
|
5022 | line) |
|
5023 | ||
5024 | # Remove false positives: |
|
5025 | # - String pointers (as opposed to values). |
|
5026 | # string *pointer |
|
5027 | # const string *pointer |
|
5028 | # string const *pointer |
|
5029 | # string *const pointer |
|
5030 | # |
|
5031 | # - Functions and template specializations. |
|
5032 | # string Function<Type>(... |
|
5033 | # string Class<Type>::Method(... |
|
5034 | # |
|
5035 | # - Operators. These are matched separately because operator names |
|
5036 | # cross non-word boundaries, and trying to match both operators |
|
5037 | # and functions at the same time would decrease accuracy of |
|
5038 | # matching identifiers. |
|
5039 | # string Class::operator*() |
|
5040 | if (match and |
|
5041 | not Search(r'\bstring\b(\s+const)?\s*[\*\&]\s*(const\s+)?\w', line) and |
|
5042 | not Search(r'\boperator\W', line) and |
|
5043 | not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(4))): |
|
5044 | if Search(r'\bconst\b', line): |
|
5045 | error(filename, linenum, 'runtime/string', 4, |
|
5046 | 'For a static/global string constant, use a C style string ' |
|
5047 | 'instead: "%schar%s %s[]".' % |
|
5048 | (match.group(1), match.group(2) or '', match.group(3))) |
|
5049 | else: |
|
5050 | error(filename, linenum, 'runtime/string', 4, |
|
5051 | 'Static/global string variables are not permitted.') |
|
5052 | ||
5053 | if (Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line) or |
|
5054 | Search(r'\b([A-Za-z0-9_]*_)\(CHECK_NOTNULL\(\1\)\)', line)): |
|
5055 | error(filename, linenum, 'runtime/init', 4, |
|
5056 | 'You seem to be initializing a member variable with itself.') |
|
5057 | ||
5058 | ||
5059 | def CheckPrintf(filename, clean_lines, linenum, error): |
@@ 4998-5056 (lines=59) @@ | ||
4995 | ' for more information.') |
|
4996 | ||
4997 | ||
4998 | def CheckGlobalStatic(filename, clean_lines, linenum, error): |
|
4999 | """Check for unsafe global or static objects. |
|
5000 | ||
5001 | Args: |
|
5002 | filename: The name of the current file. |
|
5003 | clean_lines: A CleansedLines instance containing the file. |
|
5004 | linenum: The number of the line to check. |
|
5005 | error: The function to call with any errors found. |
|
5006 | """ |
|
5007 | line = clean_lines.elided[linenum] |
|
5008 | ||
5009 | # Match two lines at a time to support multiline declarations |
|
5010 | if linenum + 1 < clean_lines.NumLines() and not Search(r'[;({]', line): |
|
5011 | line += clean_lines.elided[linenum + 1].strip() |
|
5012 | ||
5013 | # Check for people declaring static/global STL strings at the top level. |
|
5014 | # This is dangerous because the C++ language does not guarantee that |
|
5015 | # globals with constructors are initialized before the first access, and |
|
5016 | # also because globals can be destroyed when some threads are still running. |
|
5017 | # TODO(unknown): Generalize this to also find static unique_ptr instances. |
|
5018 | # TODO(unknown): File bugs for clang-tidy to find these. |
|
5019 | match = Match( |
|
5020 | r'((?:|static +)(?:|const +))(?::*std::)?string( +const)? +' |
|
5021 | r'([a-zA-Z0-9_:]+)\b(.*)', |
|
5022 | line) |
|
5023 | ||
5024 | # Remove false positives: |
|
5025 | # - String pointers (as opposed to values). |
|
5026 | # string *pointer |
|
5027 | # const string *pointer |
|
5028 | # string const *pointer |
|
5029 | # string *const pointer |
|
5030 | # |
|
5031 | # - Functions and template specializations. |
|
5032 | # string Function<Type>(... |
|
5033 | # string Class<Type>::Method(... |
|
5034 | # |
|
5035 | # - Operators. These are matched separately because operator names |
|
5036 | # cross non-word boundaries, and trying to match both operators |
|
5037 | # and functions at the same time would decrease accuracy of |
|
5038 | # matching identifiers. |
|
5039 | # string Class::operator*() |
|
5040 | if (match and |
|
5041 | not Search(r'\bstring\b(\s+const)?\s*[\*\&]\s*(const\s+)?\w', line) and |
|
5042 | not Search(r'\boperator\W', line) and |
|
5043 | not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)*\s*\(([^"]|$)', match.group(4))): |
|
5044 | if Search(r'\bconst\b', line): |
|
5045 | error(filename, linenum, 'runtime/string', 4, |
|
5046 | 'For a static/global string constant, use a C style string ' |
|
5047 | 'instead: "%schar%s %s[]".' % |
|
5048 | (match.group(1), match.group(2) or '', match.group(3))) |
|
5049 | else: |
|
5050 | error(filename, linenum, 'runtime/string', 4, |
|
5051 | 'Static/global string variables are not permitted.') |
|
5052 | ||
5053 | if (Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line) or |
|
5054 | Search(r'\b([A-Za-z0-9_]*_)\(CHECK_NOTNULL\(\1\)\)', line)): |
|
5055 | error(filename, linenum, 'runtime/init', 4, |
|
5056 | 'You seem to be initializing a member variable with itself.') |
|
5057 | ||
5058 | ||
5059 | def CheckPrintf(filename, clean_lines, linenum, error): |