[PATCH] Fix PR diagnostic/25923: garbled diagnostics with -O -Wuninitialized

Simon Martin simartin@users.sourceforge.net
Sun Apr 22 09:32:00 GMT 2007


Hi all.

The following snippet, compiled with "-O -Wuninitialized"

=== cut here ===
module foo
implicit none
  type bar
    integer :: yr
    integer :: mth
    integer :: day
  end type
contains
  function baz(arg) result(res)
    type(bar), intent(in) :: arg
    type(bar) :: res
    logical, external:: some_func
    if (.not. some_func(arg)) then
      call fatal('arg not valid')
    else
      res = arg
    end if
  end function baz
end module foo
=== cut here ===

gives the following warning messages:

=== cut here ===
'res.daybugtest.f90: In function 'baz':
bugtest.f90:12: warning: ' may be used uninitialized in this function
'res.mthbugtest.f90:12: warning: ' may be used uninitialized in this function
'res.yrbugtest.f90:12: warning: ' may be used uninitialized in this function
=== cut here ===

This is the result of a call to 'warning' with "%H%qD may be used 
uninitialized in this function" as argument (see tree-ssa.c:1215), so what 
seems to happen is that the "%H%qD" part is flushed to stderr too early.

In the case of Fortran, the "%qD" part is handled by 'default_tree_printer', 
which calls 'dump_generic_node' in this case. At the very end of this 
function, there is a call to 'pp_write_text_to_stream', that writes the 
obtained formatted text (here, "'res.day" for instance) into the FILE* we're 
working with (here, stderr).

The attached patch introduces a new control on the tree dump machinery,
TDF_DIAGNOSTIC, that specifies that we're dumping something in order to 
obtain a text to be put in a diagnostic message (as opposed to a dump in a 
file), and skips the call to 'pp_write_text_to_stream' when this control is 
on (in that case, the text will be written into stderr when the full message 
is built). Moreover, it makes 'default_tree_printer' pass this new control to 
'dump_generic_node', which fixes this PR.

I have regtested C, C++, Java and Fortran with no new regression on 
i686-pc-linux-gnu. Is this patch OK for mainline? For 4.2?

Best regards,
Simon

PS: This problem does not happen with C/C++ because they don't use 
'default_tree_printer', but a customized function that does not call 
'dump_generic_node'.

PS2: I guess that this can also fix PR 28216 (the same problem for Ada), but I 
don't have Ada setup so I cannot tell for sure...

:ADDPATCH diagnostic:
-------------- next part --------------
2007-04-23  Simon Martin  <simartin@users.sourceforge.net>

	PR diagnostic/25923
	* tree-pass.h (TDF_DIAGNOSTIC): New dump control to specify that a
	diagnostic message is being built.
	* tree-pretty-print.c (dump_generic_node): Only write the formatted text
	into BUFFER's stream if we are not building a diagnostic message.
	* toplev.c (default_tree_printer): Pass TDF_DIAGNOSTIC to
	dump_generic_node.
	* Makefile.in (toplev.o): Depend on tree-pass.h.
-------------- next part --------------
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	(revision 124020)
+++ gcc/tree-pretty-print.c	(working copy)
@@ -431,8 +431,8 @@ dump_symbols (pretty_printer *buffer, bi
 
 
 /* Dump the node NODE on the pretty_printer BUFFER, SPC spaces of indent.
-   FLAGS specifies details to show in the dump (see TDF_* in tree.h).  If
-   IS_STMT is true, the object printed is considered to be a statement
+   FLAGS specifies details to show in the dump (see TDF_* in tree-pass.h).
+   If IS_STMT is true, the object printed is considered to be a statement
    and it is terminated by ';' if appropriate.  */
 
 int
@@ -2055,7 +2055,11 @@ dump_generic_node (pretty_printer *buffe
 
   if (is_stmt && is_expr)
     pp_semicolon (buffer);
-  pp_write_text_to_stream (buffer);
+
+  /* If we're building a diagnostic, the formatted text will be written
+     into BUFFER's stream by the caller; otherwise, write it now.  */
+  if (!(flags & TDF_DIAGNOSTIC))
+    pp_write_text_to_stream (buffer);
 
   return spc;
 }
Index: gcc/tree-pass.h
===================================================================
--- gcc/tree-pass.h	(revision 124020)
+++ gcc/tree-pass.h	(working copy)
@@ -71,6 +71,9 @@ enum tree_dump_index
 #define TDF_MEMSYMS	(1 << 14)	/* display memory symbols in expr.
                                            Implies TDF_VOPS.  */
 
+#define TDF_DIAGNOSTIC	(1 << 15)	/* A dump to be put in a diagnostic
+					   message.  */
+
 extern char *get_dump_file_name (enum tree_dump_index);
 extern int dump_enabled_p (enum tree_dump_index);
 extern int dump_initialized_p (enum tree_dump_index);
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 124020)
+++ gcc/toplev.c	(working copy)
@@ -82,6 +82,7 @@ Software Foundation, 51 Franklin Street,
 #include "value-prof.h"
 #include "alloc-pool.h"
 #include "tree-mudflap.h"
+#include "tree-pass.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
 #include "dwarf2out.h"
@@ -1567,7 +1568,7 @@ default_tree_printer (pretty_printer * p
       pp_string (pp, n);
     }
   else
-    dump_generic_node (pp, t, 0, 0, 0);
+    dump_generic_node (pp, t, 0, TDF_DIAGNOSTIC, 0);
 
   return true;
 }
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 124020)
+++ gcc/Makefile.in	(working copy)
@@ -2227,7 +2227,7 @@ toplev.o : toplev.c $(CONFIG_H) $(SYSTEM
    value-prof.h $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \
    langhooks.h insn-flags.h $(CFGLAYOUT_H) $(CFGLOOP_H) hosthooks.h \
    $(CGRAPH_H) $(COVERAGE_H) alloc-pool.h $(GGC_H) $(INTEGRATE_H) \
-   $(CPPLIB_H) opts.h params.def tree-mudflap.h $(REAL_H)
+   $(CPPLIB_H) opts.h params.def tree-mudflap.h $(REAL_H) tree-pass.h
 	$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \
 	  -DTARGET_NAME=\"$(target_noncanonical)\" \
 	  -c $(srcdir)/toplev.c $(OUTPUT_OPTION)
-------------- next part --------------
2007-04-23  Simon Martin  <simartin@users.sourceforge.net>

	PR diagnostic/25923
	* gfortran.dg/pr25923.f90: New test.
-------------- next part --------------
! { dg-do compile }
! { dg-options "-O -Wuninitialized" }

module foo
implicit none

  type bar
    integer :: yr
  end type

contains

  function baz(arg) result(res) ! { dg-warning "res.yr' may be" }
    type(bar), intent(in) :: arg
    type(bar) :: res
    logical, external:: some_func
    if (.not. some_func(arg)) then
      call fatal('arg not valid')
    else
      res = arg
    end if
  end function baz

end module foo


More information about the Gcc-patches mailing list