#! /bin/sh -e

# DP: Fix PR other/28322, GCC new warnings and compatibility.

dir=
if [ $# -eq 3 -a "$2" = '-d' ]; then
    pdir="-d $3"
    dir="$3/"
elif [ $# -ne 1 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch)
        patch $pdir -f --no-backup-if-mismatch -p0 < $0
        ;;
    -unpatch)
        patch $pdir -f --no-backup-if-mismatch -R -p0 < $0
        ;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0

gcc/

2008-02-26  Manuel Lopez-Ibanez <manu@gcc.gnu.org>

	PR other/28322
	* toplev.c (toplev_main): If there are warnings or error, print
	errors for ignored options.
	* opts.c (ignored_options): New static variable.
	(postpone_unknown_option_error): New.
	(print_ignored_options): New.
	(handle_option): Postpone errors for unknown -Wno-* options.
	* opts.h (print_ignored_options): Declare.

gcc/testsuite/

2008-02-26  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

	PR other/28322
	* gcc.dg/pr28322.c: New.
	* gcc.dg/pr28322-2.c: New.
	* lib/prune.exp: Ignore "At top level" even if there is no ':'
	preceding it.

Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 132801)
+++ gcc/toplev.c	(working copy)
@@ -2278,6 +2278,9 @@
   if (!exit_after_options)
     do_compile ();
 
+  if (warningcount || errorcount) 
+    print_ignored_options ();
+
   if (errorcount || sorrycount)
     return (FATAL_EXIT_CODE);
 
Index: gcc/testsuite/lib/prune.exp
===================================================================
--- gcc/testsuite/lib/prune.exp	(revision 132801)
+++ gcc/testsuite/lib/prune.exp	(working copy)
@@ -21,7 +21,7 @@
     #send_user "Before:$text\n"
 
     regsub -all "(^|\n)(\[^\n\]*: )?In ((static member )?function|member|method|(copy )?constructor|destructor|instantiation|program|subroutine|block-data) \[^\n\]*" $text "" text
-    regsub -all "(^|\n)\[^\n\]*: At (top level|global scope):\[^\n\]*" $text "" text
+    regsub -all "(^|\n)\[^\n\]*(: )?At (top level|global scope):\[^\n\]*" $text "" text
     regsub -all "(^|\n)\[^\n\]*:   instantiated from \[^\n\]*" $text "" text
     regsub -all "(^|\n)    inlined from \[^\n\]*" $text "" text
     regsub -all "(^|\n)collect2: ld returned \[^\n\]*" $text "" text
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 132801)
+++ gcc/opts.c	(working copy)
@@ -356,6 +356,12 @@
 static VEC(char_p,heap) *flag_instrument_functions_exclude_functions;
 static VEC(char_p,heap) *flag_instrument_functions_exclude_files;
 
+typedef const char *const_char_p; /* For DEF_VEC_P.  */
+DEF_VEC_P(const_char_p);
+DEF_VEC_ALLOC_P(const_char_p,heap);
+
+static VEC(const_char_p,heap) *ignored_options;
+
 /* Input file names.  */
 const char **in_fnames;
 unsigned num_in_fnames;
@@ -434,6 +440,33 @@
   free (bad_lang);
 }
 
+/* Buffer the unknown option described by the string OPT.  Currently,
+   we only complain about unknown -Wno-* options if they may have
+   prevented a diagnostic. Otherwise, we just ignore them.  */
+
+static void postpone_unknown_option_error(const char *opt)
+{
+  VEC_safe_push (const_char_p, heap, ignored_options, opt);
+}
+
+/* Produce an error for each option previously buffered.  */
+
+void print_ignored_options (void)
+{
+  location_t saved_loc = input_location;
+
+  input_location = 0;
+
+  while (!VEC_empty (const_char_p, ignored_options))
+    {
+      const char *opt;
+      opt = VEC_pop (const_char_p, ignored_options);
+      error ("unrecognized command line option \"%s\"", opt);
+    }
+
+  input_location = saved_loc;
+}
+
 /* Handle the switch beginning at ARGV for the language indicated by
    LANG_MASK.  Returns the number of switches consumed.  */
 static unsigned int
@@ -463,6 +496,14 @@
       opt = dup;
       value = 0;
       opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
+      if (opt_index == cl_options_count && opt[1] == 'W')
+	{
+	  /* We don't generate errors for unknown -Wno-* options
+             unless we issue diagnostics.  */
+	  postpone_unknown_option_error (argv[0]);
+	  result = 1;
+	  goto done;
+	}
     }
 
   if (opt_index == cl_options_count)
Index: gcc/opts.h
===================================================================
--- gcc/opts.h	(revision 132801)
+++ gcc/opts.h	(working copy)
@@ -105,4 +105,5 @@
 
 extern void enable_warning_as_error (const char *arg, int value,
 				     unsigned int lang_mask);
+extern void print_ignored_options (void);
 #endif
