detect-mismatched-virtual-const 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/perl -w
  2. # Copyright (C) 2008 Apple Inc. All rights reserved.
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions
  6. # are met:
  7. #
  8. # 1. Redistributions of source code must retain the above copyright
  9. # notice, this list of conditions and the following disclaimer.
  10. # 2. Redistributions in binary form must reproduce the above copyright
  11. # notice, this list of conditions and the following disclaimer in the
  12. # documentation and/or other materials provided with the distribution.
  13. # 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  14. # its contributors may be used to endorse or promote products derived
  15. # from this software without specific prior written permission.
  16. #
  17. # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  18. # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  21. # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. #
  28. # This script attempts to find instances of a problem where the signatures
  29. # of virtual methods fail to match because one is defined 'const', and another
  30. # is not. For example:
  31. # virtual void Base::doStuff() const;
  32. # virtual void Derived::doStuff();
  33. #
  34. # The lack of 'const' on the derived class gives it a different signature, and
  35. # it will therefore not be called when doStuff() is called on a derived object
  36. # via a base class pointer.
  37. #
  38. # Limitations of this script:
  39. # * It only works on things in the WebCore namespace
  40. # * Not all templatized methods may be found correctly
  41. # * It doesn't know anything about inheritance, or if methods are actually virtual
  42. # * It has lots of false positives (should add a whitelist for known-good signatures,
  43. # and specific methods)
  44. # * It's rather slow
  45. #
  46. # Added by Simon Fraser <simon.fraser@apple.com>
  47. #
  48. # Run the script like this:
  49. # WebKitTools/Scripts/detect-mismatched-virtual-const WebKitBuild/Debug/WebCore.framework/WebCore
  50. #
  51. # Output consists of a series of warnings like this:
  52. #
  53. # Both const and non-const versions of bgColor():
  54. # HTMLDocument::bgColor()
  55. # HTMLBodyElement::bgColor() const
  56. # HTMLTableElement::bgColor() const
  57. # HTMLTableRowElement::bgColor() const
  58. # HTMLTableCellElement::bgColor() const
  59. #
  60. use strict;
  61. no warnings qw /syntax/;
  62. my $file = $ARGV[0];
  63. print "Looking for unmatched const methods in $file\n";
  64. if (!open NM, "(nm '$file' | c++filt | sed 's/^/STDOUT:/') 2>&1 |") {
  65. die "Could not open $file\n";
  66. }
  67. my $nestedParens;
  68. $nestedParens = qr /
  69. [(]
  70. [^()]*
  71. (?:
  72. (??{ $nestedParens })
  73. [^()]*
  74. )*
  75. [)]/x;
  76. my $nestedAngleBrackets;
  77. $nestedAngleBrackets = qr /
  78. [<]
  79. [^<>]*
  80. (?:
  81. (??{ $nestedAngleBrackets })
  82. [^<>]*
  83. )*
  84. [>]/x;
  85. my $bal;
  86. $bal = qr /([^:]+
  87. (??{ $nestedAngleBrackets })?
  88. (??{ $nestedParens }))
  89. ([^()]*)$/x;
  90. my %signature_map = ();
  91. while (<NM>) {
  92. my $line = $_;
  93. chomp($line);
  94. if ($line =~ m/ [tT] WebCore::(.+)$/) {
  95. my $method = $1;
  96. if ($method =~ /$bal/) {
  97. my $signature = $1;
  98. my $const = $2 eq " const";
  99. my $class = substr($method, 0, length($method) - length($signature) - ($const ? 6 : 0));
  100. # print "line: $line\nclass: $class\nmethod: $method\nsignature: $signature\nconst: $const\n\n";
  101. my %method_info = (
  102. 'class' => $class,
  103. 'const' => $const,
  104. 'method' => $method,
  105. );
  106. push @{$signature_map{$signature}}, \%method_info;
  107. } else {
  108. print "unmatched line $method\n\n"
  109. }
  110. }
  111. }
  112. close NM;
  113. my $sig;
  114. for $sig (keys %signature_map) {
  115. #print "\n$sig\n";
  116. my @entries = @{$signature_map{$sig}};
  117. # print "$#entries\n";
  118. my $num_const = 0;
  119. my $num_not_const = 0;
  120. my $i;
  121. for $i (0 .. $#entries) {
  122. my $entry = @entries[$i];
  123. my $class = $entry->{'class'};
  124. my $const = $entry->{'const'};
  125. if ($const) {
  126. $num_const++;
  127. } else {
  128. $num_not_const++;
  129. }
  130. }
  131. if ($#entries > 1 && $num_const > 0 && $num_not_const > 0) {
  132. print "Both const and non-const versions of $sig:\n";
  133. for $i (0 .. $#entries) {
  134. my $entry = @entries[$i];
  135. my $method = $entry->{'method'};
  136. print "\t$method\n";
  137. }
  138. }
  139. }