summaryrefslogtreecommitdiff
path: root/gcc/testsuite/lib/gfortran-dg.exp
blob: 6f190092f28ec861d6fcb3d78ccf0a756994c6f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#   Copyright (C) 2004-2017 Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3.  If not see
# <http://www.gnu.org/licenses/>.

load_lib gcc-dg.exp
load_lib torture-options.exp

# Define gfortran callbacks for dg.exp.

proc gfortran-dg-test { prog do_what extra_tool_flags } {
    set result \
	[gcc-dg-test-1 gfortran_target_compile $prog $do_what $extra_tool_flags]
    
    set comp_output [lindex $result 0]
    set output_file [lindex $result 1]

    # gcc's default is to print the caret and source code, but
    # most test cases implicitly use the flag -fno-diagnostics-show-caret
    # to disable caret (and source code) printing.
    #
    # However, a few test cases override this back to the default by
    # explicily supplying "-fdiagnostics-show-caret", so that we can have
    # test coverage for caret/source code printing.
    #
    # gfortran error messages with caret-printing look like this:
    #     [name]:[locus]:
    #
    #        some code
    #              1
    #     Error: Some error at (1)
    # or
    #     [name]:[locus]:
    #
    #       some code
    #              1
    #     [name]:[locus2]:
    #
    #       some other code
    #         2
    #     Error: Some error at (1) and (2)
    # or
    #     [name]:[locus]:
    #
    #       some code and some more code
    #              1       2
    #     Error: Some error at (1) and (2)
    #
    # If this is such a test case, skip the rest of this function, so
    # that the test case can explicitly verify the output that it expects.
    if {[string first "-fdiagnostics-show-caret" $extra_tool_flags] >= 0} {
	return [list $comp_output $output_file]
    }

    # Otherwise, caret-printing is disabled.
    # gfortran errors with caret-printing disabled look like this:
    #     [name]:[locus]: Error: Some error
    # or
    #     [name]:[locus]: Error: (1)
    #     [name]:[locus2]: Error: Some error at (1) and (2)
    #
    # Where [locus] is either [line] or [line].[column] or
    # [line].[column]-[column] .
    #
    # We collapse these to look like:
    #  [name]:[line]:[column]: Error: Some error at (1) and (2)
    # or
    #  [name]:[line]:[column]: Error: Some error at (1) and (2)
    #  [name]:[line2]:[column]: Error: Some error at (1) and (2)
    #
    # Note that these regexps only make sense in the combinations used below.
    # Note also that is imperative that we first deal with the form with
    # two loci.
    set locus_regexp "(\[^\n\]+:\[0-9\]+)\[\.:\](\[0-9\]+)(-\[0-9\]+)?:\n\n\[^\n\]+\n\[^\n\]+\n"
    set diag_regexp "(\[^\n\]+)\n"

    # We proceed in steps:

    # 1. We add first a column number if none exists.
    # (Some Fortran diagnostics have the locus after Warning|Error)
    set colnum_regexp "(^|\n)(Warning: |Error: )?(\[^:\n\]+:\[0-9\]+):(\[ \n\])"
    regsub -all $colnum_regexp $comp_output "\\1\\3:0:\\4\\2" comp_output
    verbose "comput_output0:\n$comp_output"

    # 2. We deal with the form with two different locus lines,
    set two_loci "(^|\n)$locus_regexp$locus_regexp$diag_regexp"
    regsub -all $two_loci $comp_output "\\1\\2:\\3: \\8\n\\5\:\\6: \\8\n" comp_output
    verbose "comput_output1:\n$comp_output"

    set locus_prefix "(\[^:\n\]+:\[0-9\]+:\[0-9\]+: )(Warning: |Error: )"
    set two_loci2 "(^|\n)$locus_prefix\\(1\\)\n$locus_prefix$diag_regexp"
    regsub -all $two_loci2 $comp_output "\\1\\2\\3\\6\n\\4\\5\\6\n" comp_output
    verbose "comput_output2:\n$comp_output"

    # 3. then with the form with only one locus line.
    set single_locus "(^|\n)$locus_regexp$diag_regexp"
    regsub -all $single_locus $comp_output "\\1\\2:\\3: \\5\n" comp_output
    verbose "comput_output3:\n$comp_output"

    # 4. Add a line number if none exists
    regsub -all "(^|\n)(Warning: |Error: )" $comp_output "\\1:0:0: \\2" comp_output
    verbose "comput_output4:\n$comp_output"
    return [list $comp_output $output_file]
}

proc gfortran-dg-prune { system text } {
    return [gcc-dg-prune $system $text]
}

# Utility routines.

# Modified dg-runtest that can cycle through a list of optimization options
# as c-torture does.
proc gfortran-dg-runtest { testcases flags default-extra-flags } {
    global runtests
    global DG_TORTURE_OPTIONS torture_with_loops

    torture-init
    set-torture-options $DG_TORTURE_OPTIONS

    foreach test $testcases {
	# If we're only testing specific files and this isn't one of
	# them, skip it.
	if ![runtest_file_p $runtests $test] {
	    continue
        }

	# look if this is dg-do-run test, in which case
	# we cycle through the option list, otherwise we don't
	if [expr [search_for $test "dg-do run"]] {
	    set option_list $torture_with_loops
	} else {
	    set option_list [list { -O } ]
	}

	set nshort [file tail [file dirname $test]]/[file tail $test]
	list-module-names $test

	foreach flags_t $option_list {
	    verbose "Testing $nshort, $flags $flags_t" 1
	    dg-test $test "$flags $flags_t" ${default-extra-flags}
	    cleanup-modules ""
	}
    }

    torture-finish
}

proc gfortran-dg-debug-runtest { target_compile trivial opt_opts testcases } {
    global srcdir subdir DEBUG_TORTURE_OPTIONS

    if ![info exists DEBUG_TORTURE_OPTIONS] {
       set DEBUG_TORTURE_OPTIONS ""
       set type_list [list "-gstabs" "-gstabs+" "-gxcoff" "-gxcoff+" "-gdwarf-2" ]
       foreach type $type_list {
           set comp_output [$target_compile \
                   "$srcdir/$subdir/$trivial" "trivial.S" assembly \
                   "additional_flags=$type"]
           if { [string match "exit status *" $comp_output] } {
               continue
           }
           if { [string match \
                       "* target system does not support the * debug format*" \
                       $comp_output]
           } {
               continue
           }
           remove-build-file "trivial.S"
           foreach level {1 "" 3} {
	       if { ($type == "-gdwarf-2") && ($level != "") } {
		   lappend DEBUG_TORTURE_OPTIONS [list "${type}" "-g${level}"]
		   foreach opt $opt_opts {
		       lappend DEBUG_TORTURE_OPTIONS \
			       [list "${type}" "-g${level}" "$opt" ]
		   }
	       } else {
		   lappend DEBUG_TORTURE_OPTIONS [list "${type}${level}"]
		   foreach opt $opt_opts {
		       lappend DEBUG_TORTURE_OPTIONS \
			       [list "${type}${level}" "$opt" ]
		   }
               }
           }
       }
    }

    verbose -log "Using options $DEBUG_TORTURE_OPTIONS"

    global runtests

    foreach test $testcases {
       # If we're only testing specific files and this isn't one of 
       # them, skip it.
       if ![runtest_file_p $runtests $test] {
           continue
       }

       set nshort [file tail [file dirname $test]]/[file tail $test]
	list-module-names $test

       foreach flags $DEBUG_TORTURE_OPTIONS {
           set doit 1
           # gcc-specific checking removed here

           if { $doit } {
               verbose -log "Testing $nshort, $flags" 1
               dg-test $test $flags ""
		cleanup-modules ""
           }
       }
    }
}