blob: e89d759508819a9f05e64cc7b2ac45e358da9802 [file] [log] [blame]
Russ Coxd8b461d2009-10-09 00:39:32 -07001#!/usr/bin/perl
Ian Lance Taylor66b261a2008-09-19 14:39:49 -07002# Copyright 2009 The Go Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style
4# license that can be found in the LICENSE file.
5
Eoghan Sherry802360e2010-12-07 15:28:21 -05006# This script checks that the compilers emit the errors which we expect.
7# Usage: errchk COMPILER [OPTS] SOURCEFILES. This will run the command
8# COMPILER [OPTS] SOURCEFILES. The compilation is expected to fail; if
9# it succeeds, this script will report an error. The stderr output of
10# the compiler will be matched against comments in SOURCEFILES. For each
11# line of the source files which should generate an error, there should
12# be a comment of the form // ERROR "regexp". If the compiler generates
13# an error for a line which has no such comment, this script will report
14# an error. Likewise if the compiler does not generate an error for a
15# line which has a comment, or if the error message does not match the
16# <regexp>. The <regexp> syntax is Perl but its best to stick to egrep.
Ian Lance Taylor66b261a2008-09-19 14:39:49 -070017
Russ Coxd8b461d2009-10-09 00:39:32 -070018use POSIX;
Ian Lance Taylor66b261a2008-09-19 14:39:49 -070019
Russ Coxd8b461d2009-10-09 00:39:32 -070020if(@ARGV < 1) {
Eoghan Sherry802360e2010-12-07 15:28:21 -050021 print STDERR "Usage: errchk COMPILER [OPTS] SOURCEFILES\n";
Russ Coxd8b461d2009-10-09 00:39:32 -070022 exit 1;
Russ Cox925454e2008-10-17 07:41:18 -070023}
24
Eoghan Sherry802360e2010-12-07 15:28:21 -050025# Grab SOURCEFILES
26foreach(reverse 0 .. @ARGV-1) {
27 unless($ARGV[$_] =~ /\.go$/) {
28 @file = @ARGV[$_+1 .. @ARGV-1];
29 last;
30 }
31}
32
33foreach $file (@file) {
34 open(SRC, $file) || die "BUG: errchk: open $file: $!";
35 $src{$file} = [<SRC>];
36 close(SRC);
37}
Ian Lance Taylor66b261a2008-09-19 14:39:49 -070038
Russ Coxd8b461d2009-10-09 00:39:32 -070039# Run command
40$cmd = join(' ', @ARGV);
Russ Cox7b5da352009-10-09 16:44:40 -070041open(CMD, "exec $cmd </dev/null 2>&1 |") || die "BUG: errchk: run $cmd: $!";
Russ Cox37c531f2010-06-20 12:05:43 -070042
43# 6g error messages continue onto additional lines with leading tabs.
44# Split the output at the beginning of each line that doesn't begin with a tab.
45$out = join('', <CMD>);
46@out = split(/^(?!\t)/m, $out);
47
Russ Coxd8b461d2009-10-09 00:39:32 -070048close CMD;
Ian Lance Taylor66b261a2008-09-19 14:39:49 -070049
Russ Coxd8b461d2009-10-09 00:39:32 -070050if($? == 0) {
51 print STDERR "BUG: errchk: command succeeded unexpectedly\n";
52 print STDERR @out;
53 exit 0;
54}
55
56if(!WIFEXITED($?)) {
57 print STDERR "BUG: errchk: compiler crashed\n";
Russ Cox7b5da352009-10-09 16:44:40 -070058 print STDERR @out, "\n";
Russ Coxd8b461d2009-10-09 00:39:32 -070059 exit 0;
60}
61
62sub bug() {
63 if(!$bug++) {
64 print STDERR "BUG: ";
65 }
66}
67
Eoghan Sherry802360e2010-12-07 15:28:21 -050068sub chk {
69 my $file = shift;
70 my $line = 0;
71 my $regexp;
72 my @errmsg;
73 my @match;
74 foreach my $src (@{$src{$file}}) {
75 $line++;
Russ Coxf4e76d82011-01-31 18:36:28 -050076 next if $src =~ m|////|; # double comment disables ERROR
Eoghan Sherry802360e2010-12-07 15:28:21 -050077 next unless $src =~ m|// (GC_)?ERROR (.*)|;
78 $regexp = $2;
79 if($regexp !~ /^"([^"]*)"/) {
80 print STDERR "$file:$line: malformed regexp\n";
81 next;
82 }
83 $regexp = $1;
Russ Coxe0a61742011-06-20 14:06:00 -040084
85 # Turn relative line number in message into absolute line number.
86 if($regexp =~ /LINE(([+-])([0-9]+))?/) {
87 my $n = $line;
88 if(defined($1)) {
89 if($2 eq "+") {
90 $n += int($3);
91 } else {
92 $n -= int($3);
93 }
94 }
95 $regexp = "$`$file:$n$'";
96 }
Russ Coxd8b461d2009-10-09 00:39:32 -070097
Eoghan Sherry802360e2010-12-07 15:28:21 -050098 @errmsg = grep { /$file:$line[:[]/ } @out;
99 @out = grep { !/$file:$line[:[]/ } @out;
100 if(@errmsg == 0) {
101 bug();
102 print STDERR "errchk: $file:$line: missing expected error: '$regexp'\n";
103 next;
104 }
105 @match = grep { /$regexp/ } @errmsg;
106 if(@match == 0) {
107 bug();
108 print STDERR "errchk: $file:$line: error message does not match '$regexp'\n";
Russ Coxe0a61742011-06-20 14:06:00 -0400109 foreach my $l (@errmsg) {
110 print STDERR "> $l";
111 }
Eoghan Sherry802360e2010-12-07 15:28:21 -0500112 next;
113 }
Russ Coxd8b461d2009-10-09 00:39:32 -0700114 }
Eoghan Sherry802360e2010-12-07 15:28:21 -0500115}
116
117foreach $file (@file) {
118 chk($file)
Russ Coxd8b461d2009-10-09 00:39:32 -0700119}
120
121if(@out != 0) {
122 bug();
Eoghan Sherry802360e2010-12-07 15:28:21 -0500123 print STDERR "errchk: unmatched error messages:\n";
Russ Coxd8b461d2009-10-09 00:39:32 -0700124 print STDERR "==================================================\n";
125 print STDERR @out;
126 print STDERR "==================================================\n";
127}
128
129exit 0;