warn.py revision f38297325073f2c5f109175bf0270d43d282bda7
1#!/usr/bin/env python 2# This file uses the following encoding: utf-8 3 4import argparse 5import sys 6import re 7 8parser = argparse.ArgumentParser(description='Convert a build log into HTML') 9parser.add_argument('--url', 10 help='Root URL of an Android source code tree prefixed ' 11 'before files in warnings') 12parser.add_argument('--separator', 13 help='Separator between the end of a URL and the line ' 14 'number argument. e.g. #') 15parser.add_argument(dest='buildlog', metavar='build.log', 16 help='Path to build.log file') 17args = parser.parse_args() 18 19# if you add another level, don't forget to give it a color below 20class severity: 21 UNKNOWN=0 22 SKIP=100 23 FIXMENOW=1 24 HIGH=2 25 MEDIUM=3 26 LOW=4 27 TIDY=5 28 HARMLESS=6 29 30def colorforseverity(sev): 31 if sev == severity.FIXMENOW: 32 return 'fuchsia' 33 if sev == severity.HIGH: 34 return 'red' 35 if sev == severity.MEDIUM: 36 return 'orange' 37 if sev == severity.LOW: 38 return 'yellow' 39 if sev == severity.TIDY: 40 return 'peachpuff' 41 if sev == severity.HARMLESS: 42 return 'limegreen' 43 if sev == severity.UNKNOWN: 44 return 'lightblue' 45 return 'grey' 46 47def headerforseverity(sev): 48 if sev == severity.FIXMENOW: 49 return 'Critical warnings, fix me now' 50 if sev == severity.HIGH: 51 return 'High severity warnings' 52 if sev == severity.MEDIUM: 53 return 'Medium severity warnings' 54 if sev == severity.LOW: 55 return 'Low severity warnings' 56 if sev == severity.HARMLESS: 57 return 'Harmless warnings' 58 if sev == severity.TIDY: 59 return 'Clang-Tidy warnings' 60 if sev == severity.UNKNOWN: 61 return 'Unknown warnings' 62 return 'Unhandled warnings' 63 64warnpatterns = [ 65 { 'category':'make', 'severity':severity.MEDIUM, 'members':[], 'option':'', 66 'description':'make: overriding commands/ignoring old commands', 67 'patterns':[r".*: warning: overriding commands for target .+", 68 r".*: warning: ignoring old commands for target .+"] }, 69 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wimplicit-function-declaration', 70 'description':'Implicit function declaration', 71 'patterns':[r".*: warning: implicit declaration of function .+"] }, 72 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'', 73 'description':'', 74 'patterns':[r".*: warning: conflicting types for '.+'"] }, 75 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wtype-limits', 76 'description':'Expression always evaluates to true or false', 77 'patterns':[r".*: warning: comparison is always .+ due to limited range of data type", 78 r".*: warning: comparison of unsigned .*expression .+ is always true", 79 r".*: warning: comparison of unsigned .*expression .+ is always false"] }, 80 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'', 81 'description':'Potential leak of memory, bad free, use after free', 82 'patterns':[r".*: warning: Potential leak of memory", 83 r".*: warning: Potential memory leak", 84 r".*: warning: Memory allocated by .+ should be deallocated by .+ not .+", 85 r".*: warning: 'delete' applied to a pointer that was allocated", 86 r".*: warning: Use of memory after it is freed", 87 r".*: warning: Argument to .+ is the address of .+ variable", 88 r".*: warning: Argument to free\(\) is offset by .+ of memory allocated by", 89 r".*: warning: Attempt to .+ released memory"] }, 90 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'', 91 'description':'Return address of stack memory', 92 'patterns':[r".*: warning: Address of stack memory .+ returned to caller", 93 r".*: warning: Address of stack memory .+ will be a dangling reference"] }, 94 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'', 95 'description':'Problem with vfork', 96 'patterns':[r".*: warning: This .+ is prohibited after a successful vfork", 97 r".*: warning: Call to function 'vfork' is insecure "] }, 98 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'infinite-recursion', 99 'description':'Infinite recursion', 100 'patterns':[r".*: warning: all paths through this function will call itself"] }, 101 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'', 102 'description':'Potential buffer overflow', 103 'patterns':[r".*: warning: Size argument is greater than .+ the destination buffer", 104 r".*: warning: Potential buffer overflow.", 105 r".*: warning: String copy function overflows destination buffer"] }, 106 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 107 'description':'Incompatible pointer types', 108 'patterns':[r".*: warning: assignment from incompatible pointer type", 109 r".*: warning: return from incompatible pointer type", 110 r".*: warning: passing argument [0-9]+ of '.*' from incompatible pointer type", 111 r".*: warning: initialization from incompatible pointer type"] }, 112 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-fno-builtin', 113 'description':'Incompatible declaration of built in function', 114 'patterns':[r".*: warning: incompatible implicit declaration of built-in function .+"] }, 115 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-parameter', 116 'description':'Unused parameter', 117 'patterns':[r".*: warning: unused parameter '.*'"] }, 118 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused', 119 'description':'Unused function, variable or label', 120 'patterns':[r".*: warning: '.+' defined but not used", 121 r".*: warning: unused function '.+'", 122 r".*: warning: private field '.+' is not used", 123 r".*: warning: unused variable '.+'"] }, 124 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-value', 125 'description':'Statement with no effect or result unused', 126 'patterns':[r".*: warning: statement with no effect", 127 r".*: warning: expression result unused"] }, 128 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunused-result', 129 'description':'Ignoreing return value of function', 130 'patterns':[r".*: warning: ignoring return value of function .+Wunused-result"] }, 131 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-field-initializers', 132 'description':'Missing initializer', 133 'patterns':[r".*: warning: missing initializer"] }, 134 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 135 'description':'', 136 'patterns':[r".*: warning: \(near initialization for '.+'\)"] }, 137 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat', 138 'description':'Format string does not match arguments', 139 'patterns':[r".*: warning: format '.+' expects type '.+', but argument [0-9]+ has type '.+'", 140 r".*: warning: more '%' conversions than data arguments", 141 r".*: warning: data argument not used by format string", 142 r".*: warning: incomplete format specifier", 143 r".*: warning: format .+ expects .+ but argument .+Wformat=", 144 r".*: warning: field precision should have .+ but argument has .+Wformat", 145 r".*: warning: format specifies type .+ but the argument has .*type .+Wformat"] }, 146 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat-extra-args', 147 'description':'Too many arguments for format string', 148 'patterns':[r".*: warning: too many arguments for format"] }, 149 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wformat-invalid-specifier', 150 'description':'Invalid format specifier', 151 'patterns':[r".*: warning: invalid .+ specifier '.+'.+format-invalid-specifier"] }, 152 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-compare', 153 'description':'Comparison between signed and unsigned', 154 'patterns':[r".*: warning: comparison between signed and unsigned", 155 r".*: warning: comparison of promoted \~unsigned with unsigned", 156 r".*: warning: signed and unsigned type in conditional expression"] }, 157 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 158 'description':'Comparison between enum and non-enum', 159 'patterns':[r".*: warning: enumeral and non-enumeral type in conditional expression"] }, 160 { 'category':'libpng', 'severity':severity.MEDIUM, 'members':[], 'option':'', 161 'description':'libpng: zero area', 162 'patterns':[r".*libpng warning: Ignoring attempt to set cHRM RGB triangle with zero area"] }, 163 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'', 164 'description':'aapt: no comment for public symbol', 165 'patterns':[r".*: warning: No comment for public symbol .+"] }, 166 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-braces', 167 'description':'Missing braces around initializer', 168 'patterns':[r".*: warning: missing braces around initializer.*"] }, 169 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'', 170 'description':'No newline at end of file', 171 'patterns':[r".*: warning: no newline at end of file"] }, 172 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wcast-qual', 173 'description':'Qualifier discarded', 174 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' discards qualifiers from pointer target type", 175 r".*: warning: assignment discards qualifiers from pointer target type", 176 r".*: warning: passing .+ to parameter of type .+ discards qualifiers", 177 r".*: warning: assigning to .+ from .+ discards qualifiers", 178 r".*: warning: return discards qualifiers from pointer target type"] }, 179 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes', 180 'description':'Attribute ignored', 181 'patterns':[r".*: warning: '_*packed_*' attribute ignored"] }, 182 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wattributes', 183 'description':'Visibility mismatch', 184 'patterns':[r".*: warning: '.+' declared with greater visibility than the type of its field '.+'"] }, 185 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 186 'description':'Shift count greater than width of type', 187 'patterns':[r".*: warning: (left|right) shift count >= width of type"] }, 188 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 189 'description':'extern <foo> is initialized', 190 'patterns':[r".*: warning: '.+' initialized and declared 'extern'"] }, 191 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wold-style-declaration', 192 'description':'Old style declaration', 193 'patterns':[r".*: warning: 'static' is not at beginning of declaration"] }, 194 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wuninitialized', 195 'description':'Variable may be used uninitialized', 196 'patterns':[r".*: warning: '.+' may be used uninitialized in this function"] }, 197 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wuninitialized', 198 'description':'Variable is used uninitialized', 199 'patterns':[r".*: warning: '.+' is used uninitialized in this function", 200 r".*: warning: variable '.+' is uninitialized when used here"] }, 201 { 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'-fshort-enums', 202 'description':'ld: possible enum size mismatch', 203 'patterns':[r".*: warning: .* uses variable-size enums yet the output is to use 32-bit enums; use of enum values across objects may fail"] }, 204 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-sign', 205 'description':'Pointer targets differ in signedness', 206 'patterns':[r".*: warning: pointer targets in initialization differ in signedness", 207 r".*: warning: pointer targets in assignment differ in signedness", 208 r".*: warning: pointer targets in return differ in signedness", 209 r".*: warning: pointer targets in passing argument [0-9]+ of '.+' differ in signedness"] }, 210 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-overflow', 211 'description':'Assuming overflow does not occur', 212 'patterns':[r".*: warning: assuming signed overflow does not occur when assuming that .* is always (true|false)"] }, 213 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wempty-body', 214 'description':'Suggest adding braces around empty body', 215 'patterns':[r".*: warning: suggest braces around empty body in an 'if' statement", 216 r".*: warning: empty body in an if-statement", 217 r".*: warning: suggest braces around empty body in an 'else' statement", 218 r".*: warning: empty body in an else-statement"] }, 219 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wparentheses', 220 'description':'Suggest adding parentheses', 221 'patterns':[r".*: warning: suggest explicit braces to avoid ambiguous 'else'", 222 r".*: warning: suggest parentheses around arithmetic in operand of '.+'", 223 r".*: warning: suggest parentheses around comparison in operand of '.+'", 224 r".*: warning: logical not is only applied to the left hand side of this comparison", 225 r".*: warning: using the result of an assignment as a condition without parentheses", 226 r".*: warning: .+ has lower precedence than .+ be evaluated first .+Wparentheses", 227 r".*: warning: suggest parentheses around '.+?' .+ '.+?'", 228 r".*: warning: suggest parentheses around assignment used as truth value"] }, 229 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 230 'description':'Static variable used in non-static inline function', 231 'patterns':[r".*: warning: '.+' is static but used in inline function '.+' which is not static"] }, 232 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wimplicit int', 233 'description':'No type or storage class (will default to int)', 234 'patterns':[r".*: warning: data definition has no type or storage class"] }, 235 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 236 'description':'Null pointer', 237 'patterns':[r".*: warning: Dereference of null pointer", 238 r".*: warning: Called .+ pointer is null", 239 r".*: warning: Forming reference to null pointer", 240 r".*: warning: Returning null reference", 241 r".*: warning: Null pointer passed as an argument to a 'nonnull' parameter", 242 r".*: warning: .+ results in a null pointer dereference", 243 r".*: warning: Access to .+ results in a dereference of a null pointer", 244 r".*: warning: Null pointer argument in"] }, 245 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 246 'description':'', 247 'patterns':[r".*: warning: type defaults to 'int' in declaration of '.+'"] }, 248 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 249 'description':'', 250 'patterns':[r".*: warning: parameter names \(without types\) in function declaration"] }, 251 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-aliasing', 252 'description':'Dereferencing <foo> breaks strict aliasing rules', 253 'patterns':[r".*: warning: dereferencing .* break strict-aliasing rules"] }, 254 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-to-int-cast', 255 'description':'Cast from pointer to integer of different size', 256 'patterns':[r".*: warning: cast from pointer to integer of different size"] }, 257 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wint-to-pointer-cast', 258 'description':'Cast to pointer from integer of different size', 259 'patterns':[r".*: warning: cast to pointer from integer of different size"] }, 260 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 261 'description':'Symbol redefined', 262 'patterns':[r".*: warning: "".+"" redefined"] }, 263 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 264 'description':'', 265 'patterns':[r".*: warning: this is the location of the previous definition"] }, 266 { 'category':'ld', 'severity':severity.MEDIUM, 'members':[], 'option':'', 267 'description':'ld: type and size of dynamic symbol are not defined', 268 'patterns':[r".*: warning: type and size of dynamic symbol `.+' are not defined"] }, 269 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 270 'description':'Pointer from integer without cast', 271 'patterns':[r".*: warning: assignment makes pointer from integer without a cast"] }, 272 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 273 'description':'Pointer from integer without cast', 274 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes pointer from integer without a cast"] }, 275 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 276 'description':'Integer from pointer without cast', 277 'patterns':[r".*: warning: assignment makes integer from pointer without a cast"] }, 278 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 279 'description':'Integer from pointer without cast', 280 'patterns':[r".*: warning: passing argument [0-9]+ of '.+' makes integer from pointer without a cast"] }, 281 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 282 'description':'Integer from pointer without cast', 283 'patterns':[r".*: warning: return makes integer from pointer without a cast"] }, 284 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wunknown-pragmas', 285 'description':'Ignoring pragma', 286 'patterns':[r".*: warning: ignoring #pragma .+"] }, 287 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered', 288 'description':'Variable might be clobbered by longjmp or vfork', 289 'patterns':[r".*: warning: variable '.+' might be clobbered by 'longjmp' or 'vfork'"] }, 290 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wclobbered', 291 'description':'Argument might be clobbered by longjmp or vfork', 292 'patterns':[r".*: warning: argument '.+' might be clobbered by 'longjmp' or 'vfork'"] }, 293 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wredundant-decls', 294 'description':'Redundant declaration', 295 'patterns':[r".*: warning: redundant redeclaration of '.+'"] }, 296 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 297 'description':'', 298 'patterns':[r".*: warning: previous declaration of '.+' was here"] }, 299 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wswitch-enum', 300 'description':'Enum value not handled in switch', 301 'patterns':[r".*: warning: .*enumeration value.* not handled in switch.+Wswitch"] }, 302 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'-encoding', 303 'description':'Java: Non-ascii characters used, but ascii encoding specified', 304 'patterns':[r".*: warning: unmappable character for encoding ascii"] }, 305 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 306 'description':'Java: Non-varargs call of varargs method with inexact argument type for last parameter', 307 'patterns':[r".*: warning: non-varargs call of varargs method with inexact argument type for last parameter"] }, 308 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 309 'description':'Java: Unchecked method invocation', 310 'patterns':[r".*: warning: \[unchecked\] unchecked method invocation: .+ in class .+"] }, 311 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 312 'description':'Java: Unchecked conversion', 313 'patterns':[r".*: warning: \[unchecked\] unchecked conversion"] }, 314 315 # Warnings from error prone. 316 { 'category':'java', 'severity':severity.LOW, 'members':[], 'option':'', 317 'description':'Java: Long literal suffix', 318 'patterns':[r".*: warning: \[LongLiteralLowerCaseSuffix\] Prefer 'L' to 'l' for the suffix to long literal"] }, 319 { 'category':'java', 'severity':severity.LOW, 'members':[], 'option':'', 320 'description':'Java: Missing @Deprecated', 321 'patterns':[r".*: warning: \[DepAnn\] Deprecated item is not annotated with @Deprecated"] }, 322 { 'category':'java', 'severity':severity.LOW, 'members':[], 'option':'', 323 'description':'Java: Use of deprecated member', 324 'patterns':[r".*: warning: \[deprecation\] .+ in .+ has been deprecated"] }, 325 { 'category':'java', 'severity':severity.LOW, 'members':[], 'option':'', 326 'description':'Java: Missing hashCode method', 327 'patterns':[r".*: warning: \[EqualsHashCode\] Classes that override equals should also override hashCode."] }, 328 { 'category':'java', 'severity':severity.LOW, 'members':[], 'option':'', 329 'description':'Java: Hashtable contains is a legacy method', 330 'patterns':[r".*: warning: \[HashtableContains\] contains\(\) is a legacy method that is equivalent to containsValue\(\)"] }, 331 { 'category':'java', 'severity':severity.LOW, 'members':[], 'option':'', 332 'description':'Java: Type parameter used only for return type', 333 'patterns':[r".*: warning: \[TypeParameterUnusedInFormals\] Declaring a type parameter that is only used in the return type is a misuse of generics: operations on the type parameter are unchecked, it hides unsafe casts at invocations of the method, and it interacts badly with method overload resolution."] }, 334 335 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 336 'description':'Java: reference equality used on arrays', 337 'patterns':[r".*: warning: \[ArrayEquals\] Reference equality used to compare arrays"] }, 338 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 339 'description':'Java: hashcode used on array', 340 'patterns':[r".*: warning: \[ArrayHashCode\] hashcode method on array does not hash array contents"] }, 341 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 342 'description':'Java: toString used on an array', 343 'patterns':[r".*: warning: \[ArrayToStringConcatenation\] Implicit toString used on an array \(String \+ Array\)", 344 r".*: warning: \[ArrayToString\] Calling toString on an array does not provide useful information"] }, 345 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 346 'description':'Java: Exception created but not thrown', 347 'patterns':[r".*: warning: \[DeadException\] Exception created but not thrown"] }, 348 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 349 'description':'Java: Return or throw from a finally', 350 'patterns':[r".*: warning: \[Finally\] If you return or throw from a finally, then values returned or thrown from the try-catch block will be ignored. Consider using try-with-resources instead."] }, 351 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 352 'description':'Java: Erroneous use of @GuardedBy', 353 'patterns':[r".*: warning: \[GuardedByChecker\] This access should be guarded by '.+'; instead found: '.+'", 354 r".*: warning: \[GuardedByChecker\] This access should be guarded by '.+', which is not currently held"] }, 355 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 356 'description':'Java: Mislabeled Android string', 357 'patterns':[r".*: warning: \[MislabeledAndroidString\] .+ is not \".+\" but \".+\"; prefer .+ for clarity"] }, 358 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 359 'description':'Java: Missing cases in enum switch', 360 'patterns':[r".*: warning: \[MissingCasesInEnumSwitch\] Non-exhaustive switch, expected cases for: .+"] }, 361 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 362 'description':'Java: Multiple top-level classes (inhibits bug analysis)', 363 'patterns':[r".*: warning: \[MultipleTopLevelClasses\] Expected at most one top-level class declaration, instead found: .+"] }, 364 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 365 'description':'Java: equals method doesn\'t override Object.equals', 366 'patterns':[r".*: warning: \[NonOverridingEquals\] equals method doesn't override Object\.equals.*"] }, 367 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 368 'description':'Java: Update of a volatile variable is non-atomic', 369 'patterns':[r".*: warning: \[NonAtomicVolatileUpdate\] This update of a volatile variable is non-atomic"] }, 370 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 371 'description':'Java: Return value ignored', 372 'patterns':[r".*: warning: \[ReturnValueIgnored\] Return value of this method must be used", 373 r".*: warning: \[RectIntersectReturnValueIgnored\] Return value of android.graphics.Rect.intersect\(\) must be checked"] }, 374 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 375 'description':'Java: Static variable accessed from an object instance', 376 'patterns':[r".*: warning: \[StaticAccessedFromInstance\] Static (method|variable) .+ should not be accessed from an object instance; instead use .+"] }, 377 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 378 'description':'Java: Static guarded by instance', 379 'patterns':[r".*: warning: \[StaticGuardedByInstance\] Write to static variable should not be guarded by instance lock '.+'"] }, 380 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 381 'description':'Java: String reference equality', 382 'patterns':[r".*: warning: \[StringEquality\] String comparison using reference equality instead of value equality"] }, 383 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 384 'description':'Java: Synchronization on non-final field', 385 'patterns':[r".*: warning: \[SynchronizeOnNonFinalField\] Synchronizing on non-final fields is not safe: if the field is ever updated, different threads may end up locking on different objects."] }, 386 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 387 'description':'Java: Catch masks fail or assert', 388 'patterns':[r".*: warning: \[TryFailThrowable\] Catching Throwable/Error masks failures from fail\(\) or assert\*\(\) in the try block"] }, 389 { 'category':'java', 'severity':severity.MEDIUM, 'members':[], 'option':'', 390 'description':'Java: Wait not in a loop', 391 'patterns':[r".*: warning: \[WaitNotInLoop\] Because of spurious wakeups, a?wait.*\(.*\) must always be called in a loop"] }, 392 393 { 'category':'java', 'severity':severity.UNKNOWN, 'members':[], 'option':'', 394 'description':'Java: Unclassified/unrecognized warnings', 395 'patterns':[r".*: warning: \[.+\] .+"] }, 396 397 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'', 398 'description':'aapt: No default translation', 399 'patterns':[r".*: warning: string '.+' has no default translation in .*"] }, 400 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'', 401 'description':'aapt: Missing default or required localization', 402 'patterns':[r".*: warning: \*\*\*\* string '.+' has no default or required localization for '.+' in .+"] }, 403 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'', 404 'description':'aapt: String marked untranslatable, but translation exists', 405 'patterns':[r".*: warning: string '.+' in .* marked untranslatable but exists in locale '??_??'"] }, 406 { 'category':'aapt', 'severity':severity.MEDIUM, 'members':[], 'option':'', 407 'description':'aapt: empty span in string', 408 'patterns':[r".*: warning: empty '.+' span found in text '.+"] }, 409 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 410 'description':'Taking address of temporary', 411 'patterns':[r".*: warning: taking address of temporary"] }, 412 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 413 'description':'Possible broken line continuation', 414 'patterns':[r".*: warning: backslash and newline separated by space"] }, 415 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Warray-bounds', 416 'description':'Array subscript out of bounds', 417 'patterns':[r".*: warning: array subscript is above array bounds", 418 r".*: warning: Array subscript is undefined", 419 r".*: warning: array subscript is below array bounds"] }, 420 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 421 'description':'Excess elements in initializer', 422 'patterns':[r".*: warning: excess elements in .+ initializer"] }, 423 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 424 'description':'Decimal constant is unsigned only in ISO C90', 425 'patterns':[r".*: warning: this decimal constant is unsigned only in ISO C90"] }, 426 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmain', 427 'description':'main is usually a function', 428 'patterns':[r".*: warning: 'main' is usually a function"] }, 429 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 430 'description':'Typedef ignored', 431 'patterns':[r".*: warning: 'typedef' was ignored in this declaration"] }, 432 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Waddress', 433 'description':'Address always evaluates to true', 434 'patterns':[r".*: warning: the address of '.+' will always evaluate as 'true'"] }, 435 { 'category':'C/C++', 'severity':severity.FIXMENOW, 'members':[], 'option':'', 436 'description':'Freeing a non-heap object', 437 'patterns':[r".*: warning: attempt to free a non-heap object '.+'"] }, 438 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wchar-subscripts', 439 'description':'Array subscript has type char', 440 'patterns':[r".*: warning: array subscript .+ type 'char'.+Wchar-subscripts"] }, 441 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 442 'description':'Constant too large for type', 443 'patterns':[r".*: warning: integer constant is too large for '.+' type"] }, 444 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow', 445 'description':'Constant too large for type, truncated', 446 'patterns':[r".*: warning: large integer implicitly truncated to unsigned type"] }, 447 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Woverflow', 448 'description':'Overflow in implicit constant conversion', 449 'patterns':[r".*: warning: overflow in implicit constant conversion"] }, 450 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 451 'description':'Declaration does not declare anything', 452 'patterns':[r".*: warning: declaration 'class .+' does not declare anything"] }, 453 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wreorder', 454 'description':'Initialization order will be different', 455 'patterns':[r".*: warning: '.+' will be initialized after", 456 r".*: warning: field .+ will be initialized after .+Wreorder"] }, 457 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 458 'description':'', 459 'patterns':[r".*: warning: '.+'"] }, 460 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 461 'description':'', 462 'patterns':[r".*: warning: base '.+'"] }, 463 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 464 'description':'', 465 'patterns':[r".*: warning: when initialized here"] }, 466 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wmissing-parameter-type', 467 'description':'Parameter type not specified', 468 'patterns':[r".*: warning: type of '.+' defaults to 'int'"] }, 469 { 'category':'gcc', 'severity':severity.MEDIUM, 'members':[], 'option':'', 470 'description':'Invalid option for C file', 471 'patterns':[r".*: warning: command line option "".+"" is valid for C\+\+\/ObjC\+\+ but not for C"] }, 472 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 473 'description':'User warning', 474 'patterns':[r".*: warning: #warning "".+"""] }, 475 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra', 476 'description':'Dereferencing void*', 477 'patterns':[r".*: warning: dereferencing 'void \*' pointer"] }, 478 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wextra', 479 'description':'Comparison of pointer to zero', 480 'patterns':[r".*: warning: ordered comparison of pointer with integer zero"] }, 481 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wwrite-strings', 482 'description':'Conversion of string constant to non-const char*', 483 'patterns':[r".*: warning: deprecated conversion from string constant to '.+'"] }, 484 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wstrict-prototypes', 485 'description':'Function declaration isn''t a prototype', 486 'patterns':[r".*: warning: function declaration isn't a prototype"] }, 487 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wignored-qualifiers', 488 'description':'Type qualifiers ignored on function return value', 489 'patterns':[r".*: warning: type qualifiers ignored on function return type", 490 r".*: warning: .+ type qualifier .+ has no effect .+Wignored-qualifiers"] }, 491 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 492 'description':'<foo> declared inside parameter list, scope limited to this definition', 493 'patterns':[r".*: warning: '.+' declared inside parameter list"] }, 494 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 495 'description':'', 496 'patterns':[r".*: warning: its scope is only this definition or declaration, which is probably not what you want"] }, 497 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wcomment', 498 'description':'Line continuation inside comment', 499 'patterns':[r".*: warning: multi-line comment"] }, 500 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wcomment', 501 'description':'Comment inside comment', 502 'patterns':[r".*: warning: "".+"" within comment"] }, 503 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'', 504 'description':'Value stored is never read', 505 'patterns':[r".*: warning: Value stored to .+ is never read"] }, 506 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wdeprecated-declarations', 507 'description':'Deprecated declarations', 508 'patterns':[r".*: warning: .+ is deprecated.+deprecated-declarations"] }, 509 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wdeprecated-register', 510 'description':'Deprecated register', 511 'patterns':[r".*: warning: 'register' storage class specifier is deprecated"] }, 512 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wpointer-sign', 513 'description':'Converts between pointers to integer types with different sign', 514 'patterns':[r".*: warning: .+ converts between pointers to integer types with different sign"] }, 515 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'', 516 'description':'Extra tokens after #endif', 517 'patterns':[r".*: warning: extra tokens at end of #endif directive"] }, 518 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wenum-compare', 519 'description':'Comparison between different enums', 520 'patterns':[r".*: warning: comparison between '.+' and '.+'.+Wenum-compare"] }, 521 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wconversion', 522 'description':'Implicit conversion of negative number to unsigned type', 523 'patterns':[r".*: warning: converting negative value '.+' to '.+'"] }, 524 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 525 'description':'Passing NULL as non-pointer argument', 526 'patterns':[r".*: warning: passing NULL to non-pointer argument [0-9]+ of '.+'"] }, 527 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy', 528 'description':'Class seems unusable because of private ctor/dtor' , 529 'patterns':[r".*: warning: all member functions in class '.+' are private"] }, 530 # skip this next one, because it only points out some RefBase-based classes where having a private destructor is perfectly fine 531 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'-Wctor-dtor-privacy', 532 'description':'Class seems unusable because of private ctor/dtor' , 533 'patterns':[r".*: warning: 'class .+' only defines a private destructor and has no friends"] }, 534 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wctor-dtor-privacy', 535 'description':'Class seems unusable because of private ctor/dtor' , 536 'patterns':[r".*: warning: 'class .+' only defines private constructors and has no friends"] }, 537 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wgnu-static-float-init', 538 'description':'In-class initializer for static const float/double' , 539 'patterns':[r".*: warning: in-class initializer for static data member of .+const (float|double)"] }, 540 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wpointer-arith', 541 'description':'void* used in arithmetic' , 542 'patterns':[r".*: warning: pointer of type 'void \*' used in (arithmetic|subtraction)", 543 r".*: warning: arithmetic on .+ to void is a GNU extension.*Wpointer-arith", 544 r".*: warning: wrong type argument to increment"] }, 545 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'-Wsign-promo', 546 'description':'Overload resolution chose to promote from unsigned or enum to signed type' , 547 'patterns':[r".*: warning: passing '.+' chooses 'int' over '.* int'"] }, 548 { 'category':'cont.', 'severity':severity.SKIP, 'members':[], 'option':'', 549 'description':'', 550 'patterns':[r".*: warning: in call to '.+'"] }, 551 { 'category':'C/C++', 'severity':severity.HIGH, 'members':[], 'option':'-Wextra', 552 'description':'Base should be explicitly initialized in copy constructor', 553 'patterns':[r".*: warning: base class '.+' should be explicitly initialized in the copy constructor"] }, 554 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 555 'description':'Converting from <type> to <other type>', 556 'patterns':[r".*: warning: converting to '.+' from '.+'"] }, 557 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 558 'description':'VLA has zero or negative size', 559 'patterns':[r".*: warning: Declared variable-length array \(VLA\) has .+ size"] }, 560 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 561 'description':'Return value from void function', 562 'patterns':[r".*: warning: 'return' with a value, in function returning void"] }, 563 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'multichar', 564 'description':'Multi-character character constant', 565 'patterns':[r".*: warning: multi-character character constant"] }, 566 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'writable-strings', 567 'description':'Conversion from string literal to char*', 568 'patterns':[r".*: warning: .+ does not allow conversion from string literal to 'char \*'"] }, 569 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'', 570 'description':'Useless specifier', 571 'patterns':[r".*: warning: useless storage class specifier in empty declaration"] }, 572 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Wduplicate-decl-specifier', 573 'description':'Duplicate declaration specifier', 574 'patterns':[r".*: warning: duplicate '.+' declaration specifier"] }, 575 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'', 576 'description':'Duplicate logtag', 577 'patterns':[r".*: warning: tag \".+\" \(.+\) duplicated in .+"] }, 578 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'typedef-redefinition', 579 'description':'Typedef redefinition', 580 'patterns':[r".*: warning: redefinition of typedef '.+' is a C11 feature"] }, 581 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'gnu-designator', 582 'description':'GNU old-style field designator', 583 'patterns':[r".*: warning: use of GNU old-style field designator extension"] }, 584 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'missing-field-initializers', 585 'description':'Missing field initializers', 586 'patterns':[r".*: warning: missing field '.+' initializer"] }, 587 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'missing-braces', 588 'description':'Missing braces', 589 'patterns':[r".*: warning: suggest braces around initialization of", 590 r".*: warning: too many braces around scalar initializer .+Wmany-braces-around-scalar-init", 591 r".*: warning: braces around scalar initializer"] }, 592 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'sign-compare', 593 'description':'Comparison of integers of different signs', 594 'patterns':[r".*: warning: comparison of integers of different signs.+sign-compare"] }, 595 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'dangling-else', 596 'description':'Add braces to avoid dangling else', 597 'patterns':[r".*: warning: add explicit braces to avoid dangling else"] }, 598 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'initializer-overrides', 599 'description':'Initializer overrides prior initialization', 600 'patterns':[r".*: warning: initializer overrides prior initialization of this subobject"] }, 601 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'self-assign', 602 'description':'Assigning value to self', 603 'patterns':[r".*: warning: explicitly assigning value of .+ to itself"] }, 604 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'gnu-variable-sized-type-not-at-end', 605 'description':'GNU extension, variable sized type not at end', 606 'patterns':[r".*: warning: field '.+' with variable sized type '.+' not at the end of a struct or class"] }, 607 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'tautological-constant-out-of-range-compare', 608 'description':'Comparison of constant is always false/true', 609 'patterns':[r".*: comparison of .+ is always .+Wtautological-constant-out-of-range-compare"] }, 610 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'overloaded-virtual', 611 'description':'Hides overloaded virtual function', 612 'patterns':[r".*: '.+' hides overloaded virtual function"] }, 613 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'incompatible-pointer-types', 614 'description':'Incompatible pointer types', 615 'patterns':[r".*: warning: incompatible pointer types .+Wincompatible-pointer-types"] }, 616 { 'category':'logtags', 'severity':severity.LOW, 'members':[], 'option':'asm-operand-widths', 617 'description':'ASM value size does not match register size', 618 'patterns':[r".*: warning: value size does not match register size specified by the constraint and modifier"] }, 619 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'literal-suffix', 620 'description':'Needs a space between literal and string macro', 621 'patterns':[r".*: warning: invalid suffix on literal.+ requires a space .+Wliteral-suffix"] }, 622 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'#warnings', 623 'description':'Warnings from #warning', 624 'patterns':[r".*: warning: .+-W#warnings"] }, 625 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'absolute-value', 626 'description':'Using float/int absolute value function with int/float argument', 627 'patterns':[r".*: warning: using .+ absolute value function .+ when argument is .+ type .+Wabsolute-value"] }, 628 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'', 629 'description':'Refers to implicitly defined namespace', 630 'patterns':[r".*: warning: using directive refers to implicitly-defined namespace .+"] }, 631 { 'category':'C/C++', 'severity':severity.LOW, 'members':[], 'option':'-Winvalid-pp-token', 632 'description':'Invalid pp token', 633 'patterns':[r".*: warning: missing .+Winvalid-pp-token"] }, 634 635 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 636 'description':'Operator new returns NULL', 637 'patterns':[r".*: warning: 'operator new' must not return NULL unless it is declared 'throw\(\)' .+"] }, 638 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 639 'description':'NULL used in arithmetic', 640 'patterns':[r".*: warning: NULL used in arithmetic"] }, 641 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'header-guard', 642 'description':'Misspelled header guard', 643 'patterns':[r".*: warning: '.+' is used as a header guard .+ followed by .+ different macro"] }, 644 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'empty-body', 645 'description':'Empty loop body', 646 'patterns':[r".*: warning: .+ loop has empty body"] }, 647 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'enum-conversion', 648 'description':'Implicit conversion from enumeration type', 649 'patterns':[r".*: warning: implicit conversion from enumeration type '.+'"] }, 650 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'switch', 651 'description':'case value not in enumerated type', 652 'patterns':[r".*: warning: case value not in enumerated type '.+'"] }, 653 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 654 'description':'Undefined result', 655 'patterns':[r".*: warning: The result of .+ is undefined", 656 r".*: warning: 'this' pointer cannot be null in well-defined C\+\+ code;", 657 r".*: warning: shifting a negative signed value is undefined"] }, 658 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 659 'description':'Division by zero', 660 'patterns':[r".*: warning: Division by zero"] }, 661 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 662 'description':'Use of deprecated method', 663 'patterns':[r".*: warning: '.+' is deprecated .+"] }, 664 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 665 'description':'Use of garbage or uninitialized value', 666 'patterns':[r".*: warning: .+ is a garbage value", 667 r".*: warning: Function call argument is an uninitialized value", 668 r".*: warning: Undefined or garbage value returned to caller", 669 r".*: warning: Called .+ pointer is.+uninitialized", 670 r".*: warning: Called .+ pointer is.+uninitalized", # match a typo in compiler message 671 r".*: warning: Use of zero-allocated memory", 672 r".*: warning: Dereference of undefined pointer value", 673 r".*: warning: Passed-by-value .+ contains uninitialized data", 674 r".*: warning: Branch condition evaluates to a garbage value", 675 r".*: warning: The .+ of .+ is an uninitialized value.", 676 r".*: warning: .+ is used uninitialized whenever .+sometimes-uninitialized", 677 r".*: warning: Assigned value is garbage or undefined"] }, 678 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 679 'description':'Result of malloc type incompatible with sizeof operand type', 680 'patterns':[r".*: warning: Result of '.+' is converted to .+ incompatible with sizeof operand type"] }, 681 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 682 'description':'Return value not checked', 683 'patterns':[r".*: warning: The return value from .+ is not checked"] }, 684 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 685 'description':'Possible heap pollution', 686 'patterns':[r".*: warning: .*Possible heap pollution from .+ type .+"] }, 687 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 688 'description':'Allocation size of 0 byte', 689 'patterns':[r".*: warning: Call to .+ has an allocation size of 0 byte"] }, 690 { 'category':'C/C++', 'severity':severity.MEDIUM, 'members':[], 'option':'', 691 'description':'Result of malloc type incompatible with sizeof operand type', 692 'patterns':[r".*: warning: Result of '.+' is converted to .+ incompatible with sizeof operand type"] }, 693 694 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'', 695 'description':'Discarded qualifier from pointer target type', 696 'patterns':[r".*: warning: .+ discards '.+' qualifier from pointer target type"] }, 697 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'', 698 'description':'Use snprintf instead of sprintf', 699 'patterns':[r".*: warning: .*sprintf is often misused; please use snprintf"] }, 700 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'', 701 'description':'Unsupported optimizaton flag', 702 'patterns':[r".*: warning: optimization flag '.+' is not supported"] }, 703 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'', 704 'description':'Extra or missing parentheses', 705 'patterns':[r".*: warning: equality comparison with extraneous parentheses", 706 r".*: warning: .+ within .+Wlogical-op-parentheses"] }, 707 { 'category':'C/C++', 'severity':severity.HARMLESS, 'members':[], 'option':'mismatched-tags', 708 'description':'Mismatched class vs struct tags', 709 'patterns':[r".*: warning: '.+' defined as a .+ here but previously declared as a .+mismatched-tags", 710 r".*: warning: .+ was previously declared as a .+mismatched-tags"] }, 711 712 # these next ones are to deal with formatting problems resulting from the log being mixed up by 'make -j' 713 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'', 714 'description':'', 715 'patterns':[r".*: warning: ,$"] }, 716 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'', 717 'description':'', 718 'patterns':[r".*: warning: $"] }, 719 { 'category':'C/C++', 'severity':severity.SKIP, 'members':[], 'option':'', 720 'description':'', 721 'patterns':[r".*: warning: In file included from .+,"] }, 722 723 # warnings from clang-tidy 724 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 725 'description':'clang-tidy readability', 726 'patterns':[r".*: .+\[readability-.+\]$"] }, 727 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 728 'description':'clang-tidy c++ core guidelines', 729 'patterns':[r".*: .+\[cppcoreguidelines-.+\]$"] }, 730 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 731 'description':'clang-tidy google-runtime', 732 'patterns':[r".*: .+\[google-runtime-.+\]$"] }, 733 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 734 'description':'clang-tidy google-build', 735 'patterns':[r".*: .+\[google-build-.+\]$"] }, 736 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 737 'description':'clang-tidy google-explicit', 738 'patterns':[r".*: .+\[google-explicit-.+\]$"] }, 739 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 740 'description':'clang-tidy google-readability', 741 'patterns':[r".*: .+\[google-readability-.+\]$"] }, 742 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 743 'description':'clang-tidy google-global', 744 'patterns':[r".*: .+\[google-global-.+\]$"] }, 745 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 746 'description':'clang-tidy modernize', 747 'patterns':[r".*: .+\[modernize-.+\]$"] }, 748 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 749 'description':'clang-tidy misc', 750 'patterns':[r".*: .+\[misc-.+\]$"] }, 751 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 752 'description':'clang-tidy CERT', 753 'patterns':[r".*: .+\[cert-.+\]$"] }, 754 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 755 'description':'clang-tidy llvm', 756 'patterns':[r".*: .+\[llvm-.+\]$"] }, 757 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 758 'description':'clang-tidy clang-diagnostic', 759 'patterns':[r".*: .+\[clang-diagnostic-.+\]$"] }, 760 { 'category':'C/C++', 'severity':severity.TIDY, 'members':[], 'option':'', 761 'description':'clang-tidy clang-analyzer', 762 'patterns':[r".*: .+\[clang-analyzer-.+\]$", 763 r".*: Call Path : .+$"] }, 764 765 # catch-all for warnings this script doesn't know about yet 766 { 'category':'C/C++', 'severity':severity.UNKNOWN, 'members':[], 'option':'', 767 'description':'Unclassified/unrecognized warnings', 768 'patterns':[r".*: warning: .+"] }, 769] 770 771anchor = 0 772cur_row_color = 0 773row_colors = [ 'e0e0e0', 'd0d0d0' ] 774 775def output(text): 776 print text, 777 778def htmlbig(param): 779 return '<font size="+2">' + param + '</font>' 780 781def dumphtmlprologue(title): 782 output('<html>\n<head>\n<title>' + title + '</title>\n<body>\n') 783 output('<a name="PageTop">') 784 output(htmlbig(title)) 785 output('<p>\n') 786 787def tablerow(text): 788 global cur_row_color 789 output('<tr bgcolor="' + row_colors[cur_row_color] + '"><td colspan="2">',) 790 cur_row_color = 1 - cur_row_color 791 output(text,) 792 output('</td></tr>\n') 793 794def begintable(text, backgroundcolor, extraanchor): 795 global anchor 796 output('<table border="1" rules="cols" frame="box" width="100%" bgcolor="black"><tr bgcolor="' + 797 backgroundcolor + '"><a name="anchor' + str(anchor) + '">') 798 if extraanchor: 799 output('<a name="' + extraanchor + '">') 800 output('<td>') 801 output(htmlbig(text[0]) + '<br>') 802 for i in text[1:]: 803 output(i + '<br>') 804 output('</td>') 805 output('<td width="100" bgcolor="grey">' + 806 '<a align="right" href="#PageTop">top</a><br>' + 807 '<a align="right" href="#anchor' + str(anchor-1) + '">previous</a><br>' + 808 '<a align="right" href="#anchor' + str(anchor+1) + '">next</a>') 809 output('</td></a></tr>') 810 anchor += 1 811 812def endtable(): 813 output('</table><p>') 814 815 816# dump some stats about total number of warnings and such 817def dumpstats(): 818 known = 0 819 unknown = 0 820 for i in warnpatterns: 821 i['members'] = sorted(set(i['members'])) 822 if i['severity'] == severity.UNKNOWN: 823 unknown += len(i['members']) 824 elif i['severity'] != severity.SKIP: 825 known += len(i['members']) 826 output('\nNumber of classified warnings: <b>' + str(known) + '</b><br>' ) 827 output('\nNumber of unclassified warnings: <b>' + str(unknown) + '</b><br>') 828 total = unknown + known 829 output('\nTotal number of warnings: <b>' + str(total) + '</b>') 830 if total < 1000: 831 output('(low count may indicate incremental build)') 832 output('\n<p>\n') 833 834# dump count of warnings of a given severity in TOC 835def dumpcount(sev): 836 first = True 837 for i in warnpatterns: 838 if i['severity'] == sev and len(i['members']) > 0: 839 if first: 840 output(headerforseverity(sev) + ':\n<blockquote>' + 841 '<table border="1" frame="box" width="100%">') 842 output('<tr bgcolor="' + colorforseverity(sev) + '">' + 843 '<td><a href="#' + i['anchor'] + '">' + descriptionfor(i) + 844 ' (' + str(len(i['members'])) + ')</a></td></tr>\n') 845 first = False 846 if not first: 847 output('</table></blockquote>\n') 848 849# dump table of content, list of all warning patterns 850def dumptoc(): 851 n = 1 852 output('<blockquote>\n') 853 for i in warnpatterns: 854 i['anchor'] = 'Warning' + str(n) 855 n += 1 856 dumpcount(severity.FIXMENOW) 857 dumpcount(severity.HIGH) 858 dumpcount(severity.MEDIUM) 859 dumpcount(severity.LOW) 860 dumpcount(severity.TIDY) 861 dumpcount(severity.HARMLESS) 862 dumpcount(severity.UNKNOWN) 863 output('</blockquote>\n<p>\n') 864 865def allpatterns(cat): 866 pats = '' 867 for i in cat['patterns']: 868 pats += i 869 pats += ' / ' 870 return pats 871 872def descriptionfor(cat): 873 if cat['description'] != '': 874 return cat['description'] 875 return allpatterns(cat) 876 877 878# show which warnings no longer occur 879def dumpfixed(): 880 tablestarted = False 881 for i in warnpatterns: 882 if len(i['members']) == 0 and i['severity'] != severity.SKIP: 883 if tablestarted == False: 884 tablestarted = True 885 begintable(['Fixed warnings', 'No more occurences. Please consider turning these in to errors if possible, before they are reintroduced in to the build'], 'blue', '') 886 tablerow(i['description'] + ' (' + allpatterns(i) + ') ' + i['option']) 887 if tablestarted: 888 endtable() 889 890def warningwithurl(line): 891 if not args.url: 892 return line 893 m = re.search( r'^([^ :]+):(\d+):(.+)', line, re.M|re.I) 894 if not m: 895 return line 896 filepath = m.group(1) 897 linenumber = m.group(2) 898 warning = m.group(3) 899 if args.separator: 900 return '<a href="' + args.url + '/' + filepath + args.separator + linenumber + '">' + filepath + ':' + linenumber + '</a>:' + warning 901 else: 902 return '<a href="' + args.url + '/' + filepath + '">' + filepath + '</a>:' + linenumber + ':' + warning 903 904# dump a category, provided it is not marked as 'SKIP' and has more than 0 occurrences 905def dumpcategory(cat): 906 if cat['severity'] != severity.SKIP and len(cat['members']) != 0: 907 header = [descriptionfor(cat),str(len(cat['members'])) + ' occurences:'] 908 if cat['option'] != '': 909 header[1:1] = [' (related option: ' + cat['option'] +')'] 910 begintable(header, colorforseverity(cat['severity']), cat['anchor']) 911 for i in cat['members']: 912 tablerow(warningwithurl(i)) 913 endtable() 914 915 916# dump everything for a given severity 917def dumpseverity(sev): 918 for i in warnpatterns: 919 if i['severity'] == sev: 920 dumpcategory(i) 921 922 923def classifywarning(line): 924 for i in warnpatterns: 925 for cpat in i['compiledpatterns']: 926 if cpat.match(line): 927 i['members'].append(line) 928 return 929 else: 930 # If we end up here, there was a problem parsing the log 931 # probably caused by 'make -j' mixing the output from 932 # 2 or more concurrent compiles 933 pass 934 935# precompiling every pattern speeds up parsing by about 30x 936def compilepatterns(): 937 for i in warnpatterns: 938 i['compiledpatterns'] = [] 939 for pat in i['patterns']: 940 i['compiledpatterns'].append(re.compile(pat)) 941 942infile = open(args.buildlog, 'r') 943warnings = [] 944 945platformversion = 'unknown' 946targetproduct = 'unknown' 947targetvariant = 'unknown' 948linecounter = 0 949 950warningpattern = re.compile('.* warning:.*') 951compilepatterns() 952 953# read the log file and classify all the warnings 954lastmatchedline = '' 955for line in infile: 956 # replace fancy quotes with plain ol' quotes 957 line = line.replace("‘", "'"); 958 line = line.replace("’", "'"); 959 if warningpattern.match(line): 960 if line != lastmatchedline: 961 classifywarning(line) 962 lastmatchedline = line 963 else: 964 # save a little bit of time by only doing this for the first few lines 965 if linecounter < 50: 966 linecounter +=1 967 m = re.search('(?<=^PLATFORM_VERSION=).*', line) 968 if m != None: 969 platformversion = m.group(0) 970 m = re.search('(?<=^TARGET_PRODUCT=).*', line) 971 if m != None: 972 targetproduct = m.group(0) 973 m = re.search('(?<=^TARGET_BUILD_VARIANT=).*', line) 974 if m != None: 975 targetvariant = m.group(0) 976 977 978# dump the html output to stdout 979dumphtmlprologue('Warnings for ' + platformversion + ' - ' + targetproduct + ' - ' + targetvariant) 980dumpstats() 981# sort table based on number of members once dumpstats has deduplicated the 982# members. 983warnpatterns.sort(reverse=True, key=lambda i: len(i['members'])) 984dumptoc() 985dumpseverity(severity.FIXMENOW) 986dumpseverity(severity.HIGH) 987dumpseverity(severity.MEDIUM) 988dumpseverity(severity.LOW) 989dumpseverity(severity.TIDY) 990dumpseverity(severity.HARMLESS) 991dumpseverity(severity.UNKNOWN) 992dumpfixed() 993