PageRenderTime 39ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/win/new_analyze_warnings/warning_diff.py

https://gitlab.com/jonnialva90/iridium-browser
Python | 165 lines | 135 code | 9 blank | 21 comment | 14 complexity | 0fd1543c9533f4baba3a90df930df4ec MD5 | raw file
  1. # Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file.
  4. """
  5. This script takes two warning summary files and reports on the new warnings
  6. and the fixed warnings. The warning summaries are created by
  7. warnings_by_type.py.
  8. A warning is identified by the source file and the warning text, without the
  9. Lines component or any line 'xxx' references within the warning.
  10. All warnings with the same signature are grouped together (duplicates are
  11. assumed to have been removed already).
  12. If a file contains multiple warnings with the same signature then a report
  13. will be generated for each warning when the warning count changes.
  14. """
  15. import sys
  16. import re
  17. # Some sample warnings:
  18. # sctp_bsd_addr.c(182) : warning C28125: The function
  19. # 'InitializeCriticalSection' must be called from within a try/except block:
  20. # The requirement might be conditional.
  21. # exception_handler.cc(813) : warning C6387: 'child_thread_handle' could be '0':
  22. # this does not adhere to the specification for the function 'CloseHandle'. :
  23. # Lines: 773, 774, 775, 776, 777, 784, 802, 804, 809, 813
  24. # unistr.cpp(1823) : warning C28193: 'temporary value' holds a value that must
  25. # be examined.: Lines: 1823, 1824
  26. # Note "line '1428'" in this warning, and 'count went from 3 to 2':
  27. # scheduler.cc(1452) : warning C6246: Local declaration of 'node' hides
  28. # declaration of the same name in outer scope. For additional information, see
  29. # previous declaration at line '1428' of 'scheduler.cc'.: count went from 3 to 2
  30. # Note "line 454" in this warning:
  31. # gurl.cc(449) : warning C28112: A variable (empty_gurl) which is accessed via
  32. # an Interlocked function must always be accessed via an Interlocked function.
  33. # See line 454: It is not always safe to access a variable which is accessed
  34. # via the Interlocked* family of functions in any other way.
  35. warningsToIgnore = [
  36. # We assume that memory allocations never fail
  37. "C6255", # _alloca indicates failure by raising a stack overflow exception.
  38. "C6308", # 'realloc' might return null pointer, leaking memory
  39. "C6387", # Param could be '0': this does not adhere to the specification for
  40. # the function
  41. # I have yet to see errors caused by passing 'char' to isspace and friends
  42. "C6330", # 'char' passed as _Param_(1) when 'unsigned char' is required
  43. # This warning needs to be in clang to make it effective
  44. "C6262", # Function uses too much stack
  45. # Triggers on isnan, isinf, and template metaprogramming.
  46. "C6334", # sizeof operator applied to an expression with an operator might
  47. # yield unexpected results:
  48. ]
  49. warningRe = re.compile(r"(.*)\(\d+\) : warning (C\d{4,5}): (.*)")
  50. warningRefLine = re.compile(r"(.*line ')\d+('.*)")
  51. warningRefLine2 = re.compile(r"(.*line )\d+(:.*)")
  52. def RemoveExtraneous(line):
  53. """
  54. Remove extraneous data such as the optional 'Lines:' block at the end of some
  55. warnings, and line ending characters.
  56. This ensures better matching and makes for less cluttered results.
  57. """
  58. linesOffset = line.find(": Lines:")
  59. if linesOffset >= 0:
  60. line = line[:linesOffset]
  61. return line.strip()
  62. def SummarizeWarnings(filename):
  63. """
  64. This function reads the file and looks for warning messages. It creates a
  65. dictionary with the keys being the filename, warning number, and warning text,
  66. and returns this.
  67. The warning summary at the end is ignored because it doesn't match the regex
  68. due to the 'C' being stripped from the warnings, for just this purpose.
  69. """
  70. warnings = {}
  71. for line in open(filename).readlines():
  72. line = line.replace(r"\chromium\src", r"\analyze_chromium\src")
  73. line = line.replace(r"\chromium2\src", r"\analyze_chromium\src")
  74. line = RemoveExtraneous(line)
  75. match = warningRe.match(line)
  76. if match:
  77. file, warningNumber, description = match.groups()
  78. ignore = False
  79. if warningNumber in warningsToIgnore:
  80. ignore = True
  81. glesTest = "gles2_implementation_unittest"
  82. if warningNumber == "C6001" and line.count(glesTest) > 0:
  83. ignore = True # Many spurious warnings of this form
  84. if not ignore:
  85. # See if the description contains line numbers, so that we can
  86. # remove them.
  87. matchLine = warningRefLine.match(description)
  88. if not matchLine:
  89. matchLine = warningRefLine2.match(description)
  90. if matchLine:
  91. # Replace referenced line numbers with #undef so that they don't cause
  92. # mismatches.
  93. description = "#undef".join(matchLine.groups())
  94. # Look for "the readable size is " and "the writable size is " because
  95. # these are often followed by sizes that vary in uninteresting ways,
  96. # especially between 32-bit and 64-bit builds.
  97. readableText = "the readable size is "
  98. writableText = "the writable size is "
  99. if description.find(readableText) >= 0:
  100. description = description[:description.find(readableText)]
  101. if description.find(writableText) >= 0:
  102. description = description[:description.find(writableText)]
  103. key = (file, warningNumber, description)
  104. if not key in warnings:
  105. warnings[key] = []
  106. warnings[key].append(line.strip())
  107. return warnings
  108. def PrintAdditions(oldResults, newResults, message, invert):
  109. results = []
  110. for key in newResults.keys():
  111. if oldResults.has_key(key):
  112. # Check to see if the warning count has changed
  113. old = oldResults[key]
  114. new = newResults[key]
  115. if len(new) > len(old):
  116. # If the warning count has increased then we don't know which ones are
  117. # new. Sigh... Report the new ones, up to some maximum:
  118. for warning in newResults[key]:
  119. if invert:
  120. results.append(warning + ": count went from %d to %d" % \
  121. (len(newResults[key]), len(oldResults[key])))
  122. else:
  123. results.append(warning + ": count went from %d to %d" % \
  124. (len(oldResults[key]), len(newResults[key])))
  125. else:
  126. # Totally new (or fixed) warning.
  127. results += newResults[key]
  128. # This sort is not perfect because it is alphabetic and it needs to switch to
  129. # numeric when it encounters digits. Later.
  130. results.sort()
  131. print "%s (%d total)" % (message, len(results))
  132. for line in results:
  133. print line
  134. if len(sys.argv) < 3:
  135. print "Usage: %s oldsummary.txt newsummary.txt" % sys.argv[0]
  136. print "Prints the changes in warnings between two /analyze runs."
  137. sys.exit(0)
  138. oldFilename = sys.argv[1]
  139. newFilename = sys.argv[2]
  140. oldResults = SummarizeWarnings(oldFilename)
  141. newResults = SummarizeWarnings(newFilename)
  142. PrintAdditions(oldResults, newResults, "New warnings", False)
  143. print
  144. print
  145. PrintAdditions(newResults, oldResults, "Fixed warnings", True)