testsuite: Introduce dg-ice.
authorMarek Polacek <polacek@redhat.com>
Fri, 24 Jul 2020 02:20:37 +0000 (22:20 -0400)
committerMarek Polacek <polacek@redhat.com>
Mon, 10 Aug 2020 21:01:47 +0000 (17:01 -0400)
This patch adds a new DejaGNU directive, dg-ice, as outlined in the
proposal here:
https://gcc.gnu.org/pipermail/gcc-patches/2020-July/550913.html

It means that it's expected that the compiler crashes with an internal
compiler error when compiling test with such a directive.

A minor optimization could be to use -pass-exit-codes and then check for
ICE_EXIT_CODE return code instead of using string match.

gcc/ChangeLog:

* doc/sourcebuild.texi: Document dg-ice.

gcc/testsuite/ChangeLog:

* lib/gcc-dg.exp (gcc-dg-test-1): Handle dg-ice.
(cleanup-after-saved-dg-test): Reset expect_ice.
* lib/prune.exp (prune_ices): New.
* lib/target-supports-dg.exp (dg-ice): New.

gcc/doc/sourcebuild.texi
gcc/testsuite/lib/gcc-dg.exp
gcc/testsuite/lib/prune.exp
gcc/testsuite/lib/target-supports-dg.exp

index 63216a0daba48ed3aefb9e2df59cd2268439c11e..967cb135cb46b899306389d83bdd89d2e5c49e13 100644 (file)
@@ -1172,6 +1172,16 @@ Expect the execute step of a test to fail if the conditions (which are
 the same as for @code{dg-skip-if}) are met.
 @end table
 
+@subsubsection Expect the compiler to crash
+
+@table @code
+@item  @{ dg-ice @var{comment} [@{ @var{selector} @} [@{ @var{include-opts} @} [@{ @var{exclude-opts} @}]]] @}
+Expect the compiler to crash with an internal compiler error and return
+a nonzero exit status if the conditions (which are the same as for
+@code{dg-skip-if}) are met.  Used for tests that test bugs that have not been
+fixed yet.
+@end table
+
 @subsubsection Expect the test executable to fail
 
 @table @code
index 45d97024883f62c7b62b42b6a697a181a0dd9279..e8ad3052657e20bd2e96d799a96d3526e46df0fa 100644 (file)
@@ -308,13 +308,27 @@ proc gcc-dg-test-1 { target_compile prog do_what extra_tool_flags } {
     verbose "$target_compile $prog $output_file $compile_type $options" 4
     set comp_output [$target_compile "$prog" "$output_file" "$compile_type" $options]
 
+    global expect_ice
     # Look for an internal compiler error, which sometimes masks the fact
     # that we didn't get an expected error message.  XFAIL an ICE via
     # dg-xfail-if and use { dg-prune-output ".*internal compiler error.*" }
     # to avoid a second failure for excess errors.
-    if [string match "*internal compiler error*" $comp_output] {
+    # "Error reporting routines re-entered" ICE says "Internal" rather than
+    # "internal", so match that too.
+    if [string match {*[Ii]nternal compiler error*} $comp_output] {
        upvar 2 name name
-       fail "$name (internal compiler error)"
+       if { $expect_ice == 0 } {
+         fail "$name (internal compiler error)"
+       } else {
+         # We expected an ICE and we got it.
+         xfail "$name (internal compiler error)"
+         # Prune the ICE from the output.
+         set comp_output [prune_ices $comp_output]
+       }
+    } elseif { $expect_ice == 1 } {
+       upvar 2 name name
+       # We expected an ICE but we didn't get it.
+       xpass "$name (internal compiler error)"
     }
 
     if { $do_what == "repo" } {
@@ -939,6 +953,7 @@ if { [info procs saved-dg-test] == [list] } {
        global additional_prunes
        global compiler_conditional_xfail_data
        global shouldfail
+       global expect_ice
        global testname_with_flags
        global set_target_env_var
        global set_compiler_env_var
@@ -954,6 +969,7 @@ if { [info procs saved-dg-test] == [list] } {
        set additional_sources_used ""
        set additional_prunes ""
        set shouldfail 0
+       set expect_ice 0
        if [info exists set_target_env_var] {
            unset set_target_env_var
        }
index 1c776249f1af6d519095ff5b365cd9b81fbd1c01..58a739684a5d86796538a70337433a563cdea46c 100644 (file)
@@ -118,6 +118,15 @@ proc prune_file_path { text } {
     return $text
 }
 
+# Prune internal compiler error messages, including the "Please submit..."
+# footnote.
+
+proc prune_ices { text } {
+  regsub -all "(^|\n)\[^\n\]*: internal compiler error:.*for instructions\[^\n\]*" $text "" text
+  regsub -all "(^|\n|')*Internal compiler error:.*for instructions\[^\n\]*" $text "" text
+  return $text
+}
+
 # Provide a definition of this if missing (delete after next dejagnu release).
 
 if { [info procs prune_warnings] == "" } then {
index 2a21424b8905d82bc2cceb62dc0987da6bd1e28e..5bb99f4e8f9f480b043f28eba42f0315d5421ee6 100644 (file)
@@ -495,6 +495,34 @@ proc dg-shouldfail { args } {
     }
 }
 
+# Record whether the compiler is expected (at the moment) to ICE.
+# Used for tests that test bugs that have not been fixed yet.
+
+set expect_ice 0
+
+proc dg-ice { args } {
+    # Don't bother if we're already skipping the test.
+    upvar dg-do-what dg-do-what
+    if { [lindex ${dg-do-what} 1] == "N" } {
+      return
+    }
+
+    global expect_ice
+
+    set args [lreplace $args 0 0]
+    if { [llength $args] > 1 } {
+       set selector [list target [lindex $args 1]]
+       if { [dg-process-target-1 $selector] == "S" } {
+           # The target matches, now check the flags.
+           if [check-flags $args] {
+               set expect_ice 1
+           }
+       }
+    } else {
+       set expect_ice 1
+    }
+}
+
 # Intercept the call to the DejaGnu version of dg-process-target to
 # support use of an effective-target keyword in place of a list of
 # target triplets to xfail or skip a test.