diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2020-08-13 16:37:32 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-08-14 09:40:08 +0200 |
| commit | 424dd8e7b52828cad44ce653a5d4ac30670f5e2c (patch) | |
| tree | 55f116b53a92ee8de3f1d5aafbba9566f777e869 /executor/style_test.go | |
| parent | 54ce1ed6b9fcb3b8d77c43dd4b3533e70cade414 (diff) | |
executor: warn about C89-style var declarations
We generally use the newer C99 var declarations combined with initialization because:
- declarations are more local, reduced scope
- fewer lines of code
- less potential for using uninit vars and other bugs
However, we have some relic code from times when we did not understand
if we need to stick with C89 or not. Also some external contributions
that don't follow style around.
Add a static check for C89-style declarations and fix existing precedents.
Akaros toolchain uses -std=gnu89 (or something) and does not allow
variable declarations inside of for init statement. And we can't switch
it to -std=c99 because Akaros headers are C89 themselves.
So in common.h we need to declare loop counters outside of for.
Diffstat (limited to 'executor/style_test.go')
| -rw-r--r-- | executor/style_test.go | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/executor/style_test.go b/executor/style_test.go index 9e09709ff..488752626 100644 --- a/executor/style_test.go +++ b/executor/style_test.go @@ -51,6 +51,47 @@ if (foo) `//foo`, }, }, + { + // This detects C89-style variable declarations in the beginning of block in a best-effort manner. + // Struct fields look exactly as C89 variable declarations, to filter them out we look for "{" + // at the beginning of the line. + pattern: ` +{[^{]* +\s+((unsigned )?[a-zA-Z][a-zA-Z0-9_]+\s*\*?|(struct )?[a-zA-Z][a-zA-Z0-9_]+\*)\s+([a-zA-Z][a-zA-Z0-9_]*(,\s*)?)+; +`, + suppression: `return |goto |va_list |pthread_|zx_`, + message: "Don't use C89 var declarations. Declare vars where they are needed and combine with initialization", + tests: []string{ + ` +{ + int i; +`, + ` +{ + socklen_t optlen; +`, + ` +{ + int fd, rv; +`, + ` +{ + int fd, rv; +`, + ` +{ + struct nlattr* attr; +`, + ` +{ + int* i; +`, + ` +{ + DIR* dp; +`, + }, + }, } for _, check := range checks { re := regexp.MustCompile(check.pattern) @@ -72,13 +113,15 @@ if (foo) re := regexp.MustCompile(check.pattern) supp := regexp.MustCompile(check.suppression) for _, match := range re.FindAllIndex(data, -1) { - start, end := match[0], match[1] - for check.pattern[0] != '\n' && start != 0 && data[start-1] != '\n' { - start-- - } - for check.pattern[len(check.pattern)-1] != '\n' && end != len(data) && data[end] != '\n' { + // Locate the last line of the match, that's where we assume the error is. + end := match[1] - 1 + for end != len(data) && data[end] != '\n' { end++ } + start := end - 1 + for start != 0 && data[start-1] != '\n' { + start-- + } if check.suppression != "" && supp.Match(data[start:end]) { continue } |
