]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add 'dg-note', 'dg-lto-note'
authorThomas Schwinge <thomas@codesourcery.com>
Thu, 6 May 2021 09:59:42 +0000 (11:59 +0200)
committerThomas Schwinge <thomas@codesourcery.com>
Tue, 18 May 2021 10:39:57 +0000 (12:39 +0200)
That's 'dg-message "note: [...]"' with a twist: inhibit default notes pruning,
such that "if 'dg-note' is used at least once in a testcase, [notes] are not
pruned and instead must *all* be handled explicitly".

The rationale is that either you're not interested in notes at all (default
behavior of pruning all notes), but often, when you're interested in one note,
you're in fact interested in all notes, and especially interested if
*additional* notes appear over time, as GCC evolves.

gcc/testsuite/
* lib/gcc-dg.exp: Implement 'dg-note'.
* lib/prune.exp: Likewise.
* gcc.dg/vect/nodump-vect-opt-info-2.c: Use 'dg-note', and
'dg-prune-output "note: ".
* gfortran.dg/goacc/routine-external-level-of-parallelism-2.f: Use
'dg-note', match up additional notes, one class of them with
XFAILed 'dg-bogus'.
* lib/lto.exp: Implement 'dg-lto-note'.
* g++.dg/lto/odr-1_0.C: Use 'dg-lto-note', match up additional
notes.
* g++.dg/lto/odr-1_1.C: Likewise.
* g++.dg/lto/odr-2_1.C: Likewise.
libstdc++-v3/
* testsuite/lib/prune.exp: Add note about 'dg-note'.
gcc/
* doc/sourcebuild.texi: Document 'dg-note'.

gcc/doc/sourcebuild.texi
gcc/testsuite/g++.dg/lto/odr-1_0.C
gcc/testsuite/g++.dg/lto/odr-1_1.C
gcc/testsuite/g++.dg/lto/odr-2_1.C
gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c
gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2.f
gcc/testsuite/lib/gcc-dg.exp
gcc/testsuite/lib/lto.exp
gcc/testsuite/lib/prune.exp
libstdc++-v3/testsuite/lib/prune.exp

index ceb6b995283eb6206e89cb23d3e5c30a6fdfade9..ed811d103a5734ccf8d8a95a55734afc571c459f 100644 (file)
@@ -1217,6 +1217,21 @@ If there is no message for that line or if the text of that message is
 not matched by @var{regexp} then the check fails and @var{comment} is
 included in the @code{FAIL} message.
 
+@item @{ dg-note @var{regexp} [@var{comment} [@{ target/xfail @var{selector} @} [@var{line}] ]] @}
+The line is expected to get a @samp{note} message.
+If there is no message for that line or if the text of that message is
+not matched by @var{regexp} then the check fails and @var{comment} is
+included in the @code{FAIL} message.
+
+By default, any @emph{excess} @samp{note} messages are pruned, meaning
+their appearance doesn't trigger @emph{excess errors}.
+However, if @samp{dg-note} is used at least once in a testcase,
+they're not pruned and instead must @emph{all} be handled explicitly.
+Thus, if looking for just single instances of messages with
+@samp{note: } prefixes without caring for all of them, use
+@samp{dg-message "note: [@dots{}]"} instead of @samp{dg-note}, or use
+@samp{dg-note} together with @samp{dg-prune-output "note: "}.
+
 @item @{ dg-bogus @var{regexp} [@var{comment} [@{ target/xfail @var{selector} @} [@var{line}] ]] @}
 This DejaGnu directive appears on a source line that should not get a
 message matching @var{regexp}, or else specifies the source line
@@ -1227,7 +1242,8 @@ targets.
 @item @{ dg-line @var{linenumvar} @}
 This DejaGnu directive sets the variable @var{linenumvar} to the line number of
 the source line.  The variable @var{linenumvar} can then be used in subsequent
-@code{dg-error}, @code{dg-warning}, @code{dg-message} and @code{dg-bogus}
+@code{dg-error}, @code{dg-warning}, @code{dg-message}, @code{dg-note}
+and @code{dg-bogus}
 directives.  For example:
 
 @smallexample
@@ -1239,7 +1255,9 @@ float a; /* @{ dg-error "conflicting types of" @} */
 @item @{ dg-excess-errors @var{comment} [@{ target/xfail @var{selector} @}] @}
 This DejaGnu directive indicates that the test is expected to fail due
 to compiler messages that are not handled by @samp{dg-error},
-@samp{dg-warning} or @samp{dg-bogus}.  For this directive @samp{xfail}
+@samp{dg-warning}, @code{dg-message}, @samp{dg-note} or
+@samp{dg-bogus}.
+For this directive @samp{xfail}
 has the same effect as @samp{target}.
 
 @item @{ dg-prune-output @var{regexp} @}
index 6fff88844c302f24e670661a72614b163c511641..318a047cb70f19b25af389b4306cd6d229e16bc4 100644 (file)
@@ -1,8 +1,10 @@
 // PR c++/82414
 // { dg-lto-do link }
 enum vals {aa,cc}; // { dg-lto-warning "6: type 'vals' violates the C\\+\\+ One Definition Rule" }
+// { dg-lto-note "name 'cc' differs from name 'bb' defined in another translation unit" "" { target *-*-* } .-1 }
 struct a { // { dg-lto-warning "8: type 'struct a' violates the C\\+\\+ One Definition Rule" }
-  struct b *ptr; // { dg-lto-message "13: the first difference of corresponding definitions is field 'ptr'" }
+  struct b *ptr; // { dg-lto-note "13: the first difference of corresponding definitions is field 'ptr'" }
+  // { dg-lto-note "the incompatible type defined in another translation unit" "" { target *-*-* } .-1 }
   enum vals vals;
 };
 void test(struct a *a)
index 494436a46c6547e1d23128bbdb04e0a067752c9a..a57bb3898aaf2009feeae0ae84ef78d8089c2b9e 100644 (file)
@@ -1,9 +1,10 @@
 namespace {
-  struct b; // { dg-lto-message "type 'struct b' defined in anonymous namespace cannot match across the translation unit boundary" }
+  struct b; // { dg-lto-note "type 'struct b' defined in anonymous namespace cannot match across the translation unit boundary" }
  }
-enum vals {aa,bb,cc}; // { dg-lto-message "an enum with different value name is defined in another translation unit" }
-struct a { // { dg-lto-message "a different type is defined in another translation unit" }
-  struct b *ptr; // { dg-lto-message "a field of same name but different type is defined in another translation unit" }
+enum vals {aa,bb,cc}; // { dg-lto-note "an enum with different value name is defined in another translation unit" }
+// { dg-lto-note "mismatching definition" "" { target *-*-* } .-1 }
+struct a { // { dg-lto-note "a different type is defined in another translation unit" }
+  struct b *ptr; // { dg-lto-note "a field of same name but different type is defined in another translation unit" }
   enum vals vals;
 } a;
 void test(struct a *);
index f384ae893b79e9a9aeb8225cddbd6573c061dda9..23cfccc241b77bf85b61dd3f4c62d9ca03b4bc6b 100644 (file)
@@ -1,4 +1,4 @@
-class a { // { dg-lto-message "a different type is defined in another translation unit" }
+class a { // { dg-lto-note "a different type is defined in another translation unit" }
   int *b() const;
 };
 int *a::b() const { return 0; }
index 23a3b39fbb321501e703759543f9b6a98106bc97..bcdf7f076715a4b7af59af6b1e469cd8a5ea1779 100644 (file)
@@ -3,7 +3,9 @@
 
 extern void accumulate (int x, int *a);
 
-int test_missing_function_defn (int *arr, int n) /* { dg-message "vectorized 0 loops in function" } */
+int test_missing_function_defn (int *arr, int n) /* { dg-note "5: vectorized 0 loops in function" } */
+/* { dg-prune-output "note: " } as we're not interested in matching any further
+   notes.  */
 {
   int sum = 0;
   for (int i = 0; i < n; ++i) /* { dg-missed "21: couldn't vectorize loop" } */
index 0e8dfb19e2b43f37671aae80e6121dd83736f4e5..04d507fef9a6ab29c39cf615c0b19dbca9c69030 100644 (file)
@@ -22,6 +22,8 @@
 ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
          do j = 1, n
             call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+! { dg-bogus "note: routine 'workerr' declared here" "TODO" { xfail { ! offloading_enabled } } .-1 }
+! { dg-bogus "note: routine 'workerr_' declared here" "TODO" { xfail offloading_enabled } .-2 }
          end do
       end do
 !$acc end parallel loop
 ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
       do i = 1, n
 !$acc loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
          do j = 1, n
             call gangr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+! { dg-bogus "note: routine 'gangr' declared here" "TODO" { xfail { ! offloading_enabled } } .-2 }
+! { dg-bogus "note: routine 'gangr_' declared here" "TODO" { xfail offloading_enabled } .-3 }
          end do
       end do
 !$acc end parallel loop
@@ -83,6 +88,7 @@
 !$acc end parallel loop
 
 !$acc parallel loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          call gangr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
@@ -90,6 +96,7 @@
 !$acc end parallel loop
 
 !$acc parallel loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          call gangr (a, n) ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc end parallel loop
 
 !$acc parallel loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          call gangr (a, n) ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc end parallel loop
 
 !$acc parallel loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          call workerr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc end parallel loop
 
 !$acc parallel loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc parallel loop ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
       do i = 1, n
          call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-bogus "note: routine 'vectorr' declared here" "TODO" { xfail { ! offloading_enabled } } .-1 }
+! { dg-bogus "note: routine 'vectorr_' declared here" "TODO" { xfail offloading_enabled } .-2 }
       end do
 !$acc end parallel loop
 
 !$acc end parallel loop
 
 !$acc parallel loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
          do j = 1, n
             a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+! { dg-bogus "note: routine 'workerf' declared here" "TODO" { xfail { ! offloading_enabled } } .-1 }
+! { dg-bogus "note: routine 'workerf_' declared here" "TODO" { xfail offloading_enabled } .-2 }
          end do
       end do
 !$acc end parallel loop
 ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
       do i = 1, n
 !$acc loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
          do j = 1, n
             a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+! { dg-bogus "note: routine 'gangf' declared here" "TODO" { xfail { ! offloading_enabled } } .-2 }
+! { dg-bogus "note: routine 'gangf_' declared here" "TODO" { xfail offloading_enabled } .-3 }
          end do
       end do
 !$acc end parallel loop
 !$acc end parallel loop
 
 !$acc parallel loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc end parallel loop
 
 !$acc parallel loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc end parallel loop
 
 !$acc parallel loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc end parallel loop
 
 !$acc parallel loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc end parallel loop
 
 !$acc parallel loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
 !$acc parallel loop ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
       do i = 1, n
          a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-bogus "note: routine 'vectorf' declared here" "TODO" { xfail { ! offloading_enabled } } .-1 }
+! { dg-bogus "note: routine 'vectorf_' declared here" "TODO" { xfail offloading_enabled } .-2 }
       end do
 !$acc end parallel loop
 
 !$acc end parallel loop
 
 !$acc parallel loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
       do i = 1, n
          a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
index e48a184f99137e6c500976176494083a68ffb05f..fce0989cd9ce32b1a41055335a4622540e80d593 100644 (file)
@@ -1012,6 +1012,8 @@ if { [info procs saved-dg-test] == [list] } {
            }
            unset save_linenr_varnames
        }
+
+       initialize_prune_notes
     }
 
     proc dg-test { args } {
@@ -1245,6 +1247,36 @@ proc dg-missed { args } {
     process-message saved-dg-warning "missed:" "$args"
 }
 
+# Look for messages with 'note: ' prefixes.
+# In addition to standard compiler diagnostics ('DK_NOTE', 'inform' functions,
+# "for additional details on an error message"),
+# this also includes output from '-fopt-info' for 'MSG_NOTE':
+# a general optimization info.
+# By default, any *excess* notes are pruned, meaning their appearance doesn't
+# trigger *excess errors*.  However, if 'dg-note' is used at least once in a
+# testcase, they're not pruned and instead must *all* be handled explicitly.
+# Thus, if looking for just single instances of messages with 'note: ' prefixes
+# without caring for all of them, use 'dg-message "note: [...]"' instead of
+# 'dg-note', or use 'dg-note' together with 'dg-prune-output "note: "'.
+
+variable prune_notes
+
+proc initialize_prune_notes { } {
+    global prune_notes
+    set prune_notes 1
+}
+
+initialize_prune_notes
+
+proc dg-note { args } {
+    upvar dg-messages dg-messages
+
+    global prune_notes
+    set prune_notes 0
+
+    process-message saved-dg-warning "note:" "$args"
+}
+
 # Check the existence of a gdb in the path, and return true if there
 # is one.
 #
index 77919e8443bf893092d80d2ebca5df3b68f431da..d0e0dc60138f866cc1c28651f39be3721c783146 100644 (file)
@@ -161,9 +161,13 @@ proc lto_prune_warns { text } {
 
     # Ignore missing jobserver for tests that do more than 1 LTRANS unit
     regsub -all "(^|\n)\[^\n\]*: warning: using serial compilation of \[^\n\]*" $text "" text
+    regsub -all "(^|\n)\[^\n\]*: note: see the \[^\n\]*'-flto' option documentation\[^\n\]* for more information" $text "" text
 
-    # Ignore informational notes.
-    regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text
+    global prune_notes
+    if { $prune_notes } {
+       # Ignore informational notes.
+       regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text
+    }
 
     verbose "lto_prune_warns: exit: $text" 2
 
@@ -390,8 +394,8 @@ proc lto-can-handle-directive { op } {
     # A list of directives to recognize, and a list of directives
     # to remap them to.
     # For example, "dg-lto-warning" is implemented by calling "dg-warning".
-    set directives { dg-lto-warning dg-lto-message }
-    set remapped_directives { dg-warning dg-message }
+    set directives { dg-lto-warning dg-lto-message dg-lto-note }
+    set remapped_directives { dg-warning dg-message dg-note }
 
     set idx [lsearch -exact $directives $cmd]
     if { $idx != -1 } {
@@ -597,7 +601,7 @@ proc lto-get-options { src } {
 #
 # SRC1 is the full pathname of the main file of the testcase.
 # SID identifies a test suite in the names of temporary files.
-proc lto-execute { src1 sid } {
+proc lto-execute-1 { src1 sid } {
     global srcdir tmpdir
     global lto_option_list
     global tool
@@ -811,6 +815,14 @@ proc lto-execute { src1 sid } {
     }
 }
 
+proc lto-execute { src1 sid } {
+    lto-execute-1 $src1 $sid
+
+    # LTO testing doesn't use 'dg-runtest'/'dg-test', and thus doesn't call
+    # 'cleanup-after-saved-dg-test', so we have to clean up manually.
+    initialize_prune_notes
+}
+
 # Call pass if object readelf is ok, otherwise fail.
 # example: /* { dg-final { object-readelf Tag_ABI_enum_size int} } */
 proc object-readelf { args } {
index 2809f88b16f519fd302a614dd5839e6d36dc97cd..91f165bec3805f8f9e7d47c7558954809ff6fd06 100644 (file)
@@ -54,8 +54,11 @@ proc prune_gcc_output { text } {
     regsub -all "(^|\n)\[ \]+from \[^\n\]*" $text "" text
     regsub -all "(^|\n)(In|of) module( \[^\n \]*,)? imported at \[^\n\]*" $text "" text
 
-    # Ignore informational notes.
-    regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text
+    global prune_notes
+    if { $prune_notes } {
+       # Ignore informational notes.
+       regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text
+    }
 
     # Ignore harmless -fpic warnings.
     regsub -all "(^|\n)\[^\n\]*: warning: -f(pic|PIC) ignored for target\[^\n\]*" $text "" text
index 45c77d210d71a810634a516bfe981600b802305a..fd4a0ac7f97bf2d90d6a3c4e947bee6577f1914e 100644 (file)
@@ -52,6 +52,8 @@ proc libstdc++-dg-prune { system text } {
     regsub -all "(^|\n)\[ \t\]*from \[^\n\]*" $text "" text
 
     # Ignore informational notes.
+    #TODO As this isn't even using 'gcc-dg.exp', cannot consider its
+    # 'variable prune_notes' (for 'dg-note') here.
     regsub -all "(^|\n)\[^\n\]*: note: \[^\n\]*" $text "" text
 
     # Ignore errata warning from IA64 assembler.