2013-05-22 20:41:22 +00:00
|
|
|
#!/usr/bin/env perl
|
2008-09-19 21:39:49 +00:00
|
|
|
# Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
# Use of this source code is governed by a BSD-style
|
|
|
|
# license that can be found in the LICENSE file.
|
|
|
|
|
2010-12-07 20:28:21 +00:00
|
|
|
# This script checks that the compilers emit the errors which we expect.
|
|
|
|
# Usage: errchk COMPILER [OPTS] SOURCEFILES. This will run the command
|
|
|
|
# COMPILER [OPTS] SOURCEFILES. The compilation is expected to fail; if
|
|
|
|
# it succeeds, this script will report an error. The stderr output of
|
|
|
|
# the compiler will be matched against comments in SOURCEFILES. For each
|
|
|
|
# line of the source files which should generate an error, there should
|
|
|
|
# be a comment of the form // ERROR "regexp". If the compiler generates
|
|
|
|
# an error for a line which has no such comment, this script will report
|
|
|
|
# an error. Likewise if the compiler does not generate an error for a
|
|
|
|
# line which has a comment, or if the error message does not match the
|
|
|
|
# <regexp>. The <regexp> syntax is Perl but its best to stick to egrep.
|
2008-09-19 21:39:49 +00:00
|
|
|
|
2009-10-09 07:39:32 +00:00
|
|
|
use POSIX;
|
2008-09-19 21:39:49 +00:00
|
|
|
|
2011-08-02 19:19:44 +00:00
|
|
|
my $exitcode = 1;
|
|
|
|
|
|
|
|
if(@ARGV >= 1 && $ARGV[0] eq "-0") {
|
|
|
|
$exitcode = 0;
|
|
|
|
shift;
|
|
|
|
}
|
|
|
|
|
2009-10-09 07:39:32 +00:00
|
|
|
if(@ARGV < 1) {
|
2010-12-07 20:28:21 +00:00
|
|
|
print STDERR "Usage: errchk COMPILER [OPTS] SOURCEFILES\n";
|
2009-10-09 07:39:32 +00:00
|
|
|
exit 1;
|
|
|
|
}
|
2008-09-19 21:39:49 +00:00
|
|
|
|
2010-12-07 20:28:21 +00:00
|
|
|
# Grab SOURCEFILES
|
|
|
|
foreach(reverse 0 .. @ARGV-1) {
|
2013-03-22 19:14:40 +00:00
|
|
|
unless($ARGV[$_] =~ /\.(go|s)$/) {
|
2010-12-07 20:28:21 +00:00
|
|
|
@file = @ARGV[$_+1 .. @ARGV-1];
|
|
|
|
last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach $file (@file) {
|
|
|
|
open(SRC, $file) || die "BUG: errchk: open $file: $!";
|
|
|
|
$src{$file} = [<SRC>];
|
|
|
|
close(SRC);
|
|
|
|
}
|
2008-10-30 19:43:32 +00:00
|
|
|
|
2009-10-09 07:39:32 +00:00
|
|
|
# Run command
|
|
|
|
$cmd = join(' ', @ARGV);
|
2009-10-09 23:44:40 +00:00
|
|
|
open(CMD, "exec $cmd </dev/null 2>&1 |") || die "BUG: errchk: run $cmd: $!";
|
2010-06-20 19:05:43 +00:00
|
|
|
|
2015-06-23 23:50:12 +00:00
|
|
|
# gc error messages continue onto additional lines with leading tabs.
|
2010-06-20 19:05:43 +00:00
|
|
|
# Split the output at the beginning of each line that doesn't begin with a tab.
|
|
|
|
$out = join('', <CMD>);
|
|
|
|
@out = split(/^(?!\t)/m, $out);
|
|
|
|
|
2009-10-09 07:39:32 +00:00
|
|
|
close CMD;
|
2008-09-19 21:39:49 +00:00
|
|
|
|
2011-08-02 19:19:44 +00:00
|
|
|
if($exitcode != 0 && $? == 0) {
|
2009-10-09 07:39:32 +00:00
|
|
|
print STDERR "BUG: errchk: command succeeded unexpectedly\n";
|
|
|
|
print STDERR @out;
|
|
|
|
exit 0;
|
|
|
|
}
|
2009-08-22 00:41:18 +00:00
|
|
|
|
2011-08-02 19:19:44 +00:00
|
|
|
if($exitcode == 0 && $? != 0) {
|
|
|
|
print STDERR "BUG: errchk: command failed unexpectedly\n";
|
|
|
|
print STDERR @out;
|
|
|
|
exit 0;
|
|
|
|
}
|
|
|
|
|
2009-10-09 07:39:32 +00:00
|
|
|
if(!WIFEXITED($?)) {
|
|
|
|
print STDERR "BUG: errchk: compiler crashed\n";
|
2009-10-09 23:44:40 +00:00
|
|
|
print STDERR @out, "\n";
|
2009-10-09 07:39:32 +00:00
|
|
|
exit 0;
|
|
|
|
}
|
2009-08-22 00:41:18 +00:00
|
|
|
|
2009-10-09 07:39:32 +00:00
|
|
|
sub bug() {
|
|
|
|
if(!$bug++) {
|
|
|
|
print STDERR "BUG: ";
|
|
|
|
}
|
|
|
|
}
|
2008-09-19 21:39:49 +00:00
|
|
|
|
2010-12-07 20:28:21 +00:00
|
|
|
sub chk {
|
|
|
|
my $file = shift;
|
|
|
|
my $line = 0;
|
|
|
|
my $regexp;
|
|
|
|
my @errmsg;
|
|
|
|
my @match;
|
|
|
|
foreach my $src (@{$src{$file}}) {
|
|
|
|
$line++;
|
2011-01-31 23:36:28 +00:00
|
|
|
next if $src =~ m|////|; # double comment disables ERROR
|
2010-12-07 20:28:21 +00:00
|
|
|
next unless $src =~ m|// (GC_)?ERROR (.*)|;
|
2011-08-16 15:14:26 +00:00
|
|
|
my $all = $2;
|
|
|
|
if($all !~ /^"([^"]*)"/) {
|
2010-12-07 20:28:21 +00:00
|
|
|
print STDERR "$file:$line: malformed regexp\n";
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
@errmsg = grep { /$file:$line[:[]/ } @out;
|
|
|
|
@out = grep { !/$file:$line[:[]/ } @out;
|
|
|
|
if(@errmsg == 0) {
|
|
|
|
bug();
|
2011-08-16 15:14:26 +00:00
|
|
|
print STDERR "errchk: $file:$line: missing expected error: '$all'\n";
|
2010-12-07 20:28:21 +00:00
|
|
|
next;
|
|
|
|
}
|
2011-08-16 15:14:26 +00:00
|
|
|
foreach my $regexp ($all =~ /"([^"]*)"/g) {
|
|
|
|
# Turn relative line number in message into absolute line number.
|
|
|
|
if($regexp =~ /LINE(([+-])([0-9]+))?/) {
|
|
|
|
my $n = $line;
|
|
|
|
if(defined($1)) {
|
|
|
|
if($2 eq "+") {
|
|
|
|
$n += int($3);
|
|
|
|
} else {
|
|
|
|
$n -= int($3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$regexp = "$`$file:$n$'";
|
|
|
|
}
|
|
|
|
|
|
|
|
@match = grep { /$regexp/ } @errmsg;
|
|
|
|
if(@match == 0) {
|
|
|
|
bug();
|
|
|
|
print STDERR "errchk: $file:$line: error messages do not match '$regexp'\n";
|
|
|
|
next;
|
|
|
|
}
|
|
|
|
@errmsg = grep { !/$regexp/ } @errmsg;
|
|
|
|
}
|
|
|
|
if(@errmsg != 0) {
|
2010-12-07 20:28:21 +00:00
|
|
|
bug();
|
2011-08-16 15:14:26 +00:00
|
|
|
print STDERR "errchk: $file:$line: unmatched error messages:\n";
|
2011-06-20 18:06:00 +00:00
|
|
|
foreach my $l (@errmsg) {
|
|
|
|
print STDERR "> $l";
|
|
|
|
}
|
2010-12-07 20:28:21 +00:00
|
|
|
}
|
2009-10-09 07:39:32 +00:00
|
|
|
}
|
2008-10-17 14:41:18 +00:00
|
|
|
}
|
|
|
|
|
2010-12-07 20:28:21 +00:00
|
|
|
foreach $file (@file) {
|
|
|
|
chk($file)
|
|
|
|
}
|
|
|
|
|
2009-10-09 07:39:32 +00:00
|
|
|
if(@out != 0) {
|
|
|
|
bug();
|
2010-12-07 20:28:21 +00:00
|
|
|
print STDERR "errchk: unmatched error messages:\n";
|
2009-10-09 07:39:32 +00:00
|
|
|
print STDERR "==================================================\n";
|
|
|
|
print STDERR @out;
|
|
|
|
print STDERR "==================================================\n";
|
|
|
|
}
|
2008-09-19 21:39:49 +00:00
|
|
|
|
2009-10-09 07:39:32 +00:00
|
|
|
exit 0;
|