* builtins.c (expand_builtin, expand_builtin_object_size,
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Sep 2007 07:24:58 +0000 (07:24 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 27 Sep 2007 07:24:58 +0000 (07:24 +0000)
expand_builtin_memory_chk, maybe_emit_chk_warning,
maybe_emit_sprintf_chk_warning): Use new %K format string specifier
for diagnostics.
* expr.c (expand_expr_real_1): Likewise.
* langhooks-def.h (struct diagnostic_info): Add forward decl.
(lhd_print_error_function): Add third argument.
* langhooks.h (struct diagnostic_info): Add forward decl.
(struct lang_hooks): Add third argument to print_error_function.
* diagnostic.h (diagnostic_info): Add abstract_origin field.
(diagnostic_last_function_changed, diagnostic_set_last_function): Add
second argument.
(diagnostic_report_current_function): Likewise.
* toplev.c (announce_function): Pass NULL as second argument to
diagnostic_set_last_function.
* diagnostic.c (diagnostic_report_current_function): Add second
argument, pass it as third argument to lang_hooks.print_error_function.
(default_diagnostic_starter): Pass DIAGNOSTIC as second argument
to diagnostic_report_current_function.
(diagnostic_report_diagnostic): Initialize diagnostic->abstract_origin
and message.abstract_origin.
(verbatim): Initialize abstract_origin.
* pretty-print.h (text_info): Add abstract_origin field.
* pretty-print.c (pp_base_format): Handle %K.
* langhooks.c (lhd_print_error_function): Add third argument.  If
diagnostic->abstract_origin, print virtual backtrace.
* c-format.c (gcc_diag_char_table, gcc_tdiag_char_table,
gcc_cdiag_char_table, gcc_cxxdiag_char_table): Support %K.
(init_dynamic_diag_info): Likewise.
cp/
* error.c (cxx_print_error_function): Add third argument, pass
it over to lhd_print_error_function.
(cp_print_error_function): If diagnostic->abstract_origin, print
virtual backtrace.
* cp-tree.h (struct diagnostic_info): New forward decl.
(cxx_print_error_function): Add third argument.
java/
* lang.c (java_print_error_function): Add third argument.
testsuite/
* lib/prune.exp: Prune also "^In function .*$" lines and
"^    inlined from .*$" lines.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@128830 138bc75d-0d04-0410-961f-82ee72b054a4

19 files changed:
gcc/ChangeLog
gcc/builtins.c
gcc/c-format.c
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/error.c
gcc/diagnostic.c
gcc/diagnostic.h
gcc/expr.c
gcc/java/ChangeLog
gcc/java/lang.c
gcc/langhooks-def.h
gcc/langhooks.c
gcc/langhooks.h
gcc/pretty-print.c
gcc/pretty-print.h
gcc/testsuite/ChangeLog
gcc/testsuite/lib/prune.exp
gcc/toplev.c

index 2147ded..f6768d8 100644 (file)
@@ -1,3 +1,35 @@
+2007-09-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * builtins.c (expand_builtin, expand_builtin_object_size,
+       expand_builtin_memory_chk, maybe_emit_chk_warning,
+       maybe_emit_sprintf_chk_warning): Use new %K format string specifier
+       for diagnostics.
+       * expr.c (expand_expr_real_1): Likewise.
+       * langhooks-def.h (struct diagnostic_info): Add forward decl.
+       (lhd_print_error_function): Add third argument.
+       * langhooks.h (struct diagnostic_info): Add forward decl.
+       (struct lang_hooks): Add third argument to print_error_function.
+       * diagnostic.h (diagnostic_info): Add abstract_origin field.
+       (diagnostic_last_function_changed, diagnostic_set_last_function): Add
+       second argument.
+       (diagnostic_report_current_function): Likewise.
+       * toplev.c (announce_function): Pass NULL as second argument to
+       diagnostic_set_last_function.
+       * diagnostic.c (diagnostic_report_current_function): Add second
+       argument, pass it as third argument to lang_hooks.print_error_function.
+       (default_diagnostic_starter): Pass DIAGNOSTIC as second argument
+       to diagnostic_report_current_function.
+       (diagnostic_report_diagnostic): Initialize diagnostic->abstract_origin
+       and message.abstract_origin.
+       (verbatim): Initialize abstract_origin.
+       * pretty-print.h (text_info): Add abstract_origin field.
+       * pretty-print.c (pp_base_format): Handle %K.
+       * langhooks.c (lhd_print_error_function): Add third argument.  If
+       diagnostic->abstract_origin, print virtual backtrace.
+       * c-format.c (gcc_diag_char_table, gcc_tdiag_char_table,
+       gcc_cdiag_char_table, gcc_cxxdiag_char_table): Support %K.
+       (init_dynamic_diag_info): Likewise.
+
 2007-09-26  David Daney  <ddaney@avtrex.com>
 
        PR target/33479
index bb43ab6..bafdce0 100644 (file)
@@ -6273,13 +6273,13 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
     case BUILT_IN_VA_ARG_PACK:
       /* All valid uses of __builtin_va_arg_pack () are removed during
         inlining.  */
-      error ("invalid use of %<__builtin_va_arg_pack ()%>");
+      error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
       return const0_rtx;
 
     case BUILT_IN_VA_ARG_PACK_LEN:
       /* All valid uses of __builtin_va_arg_pack_len () are removed during
         inlining.  */
-      error ("invalid use of %<__builtin_va_arg_pack_len ()%>");
+      error ("%Kinvalid use of %<__builtin_va_arg_pack_len ()%>", exp);
       return const0_rtx;
 
       /* Return the address of the first anonymous stack arg.  */
@@ -11466,12 +11466,11 @@ expand_builtin_object_size (tree exp)
   tree ost;
   int object_size_type;
   tree fndecl = get_callee_fndecl (exp);
-  location_t locus = EXPR_LOCATION (exp);
 
   if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
     {
-      error ("%Hfirst argument of %D must be a pointer, second integer constant",
-            &locus, fndecl);
+      error ("%Kfirst argument of %D must be a pointer, second integer constant",
+            exp, fndecl);
       expand_builtin_trap ();
       return const0_rtx;
     }
@@ -11483,8 +11482,8 @@ expand_builtin_object_size (tree exp)
       || tree_int_cst_sgn (ost) < 0
       || compare_tree_int (ost, 3) > 0)
     {
-      error ("%Hlast argument of %D is not integer constant between 0 and 3",
-            &locus, fndecl);
+      error ("%Klast argument of %D is not integer constant between 0 and 3",
+            exp, fndecl);
       expand_builtin_trap ();
       return const0_rtx;
     }
@@ -11527,9 +11526,8 @@ expand_builtin_memory_chk (tree exp, rtx target, enum machine_mode mode,
 
       if (! integer_all_onesp (size) && tree_int_cst_lt (size, len))
        {
-         location_t locus = EXPR_LOCATION (exp);
-         warning (0, "%Hcall to %D will always overflow destination buffer",
-                  &locus, get_callee_fndecl (exp));
+         warning (0, "%Kcall to %D will always overflow destination buffer",
+                  exp, get_callee_fndecl (exp));
          return NULL_RTX;
        }
 
@@ -11636,7 +11634,6 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
 {
   int is_strlen = 0;
   tree len, size;
-  location_t locus;
 
   switch (fcode)
     {
@@ -11683,9 +11680,8 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
       src = c_strlen (src, 1);
       if (! src || ! host_integerp (src, 1))
        {
-         locus = EXPR_LOCATION (exp);
-         warning (0, "%Hcall to %D might overflow destination buffer",
-                  &locus, get_callee_fndecl (exp));
+         warning (0, "%Kcall to %D might overflow destination buffer",
+                  exp, get_callee_fndecl (exp));
          return;
        }
       else if (tree_int_cst_lt (src, size))
@@ -11694,9 +11690,8 @@ maybe_emit_chk_warning (tree exp, enum built_in_function fcode)
   else if (! host_integerp (len, 1) || ! tree_int_cst_lt (size, len))
     return;
 
-  locus = EXPR_LOCATION (exp);
-  warning (0, "%Hcall to %D will always overflow destination buffer",
-          &locus, get_callee_fndecl (exp));
+  warning (0, "%Kcall to %D will always overflow destination buffer",
+          exp, get_callee_fndecl (exp));
 }
 
 /* Emit warning if a buffer overflow is detected at compile time
@@ -11754,9 +11749,8 @@ maybe_emit_sprintf_chk_warning (tree exp, enum built_in_function fcode)
 
   if (! tree_int_cst_lt (len, size))
     {
-      location_t locus = EXPR_LOCATION (exp);
-      warning (0, "%Hcall to %D will always overflow destination buffer",
-              &locus, get_callee_fndecl (exp));
+      warning (0, "%Kcall to %D will always overflow destination buffer",
+              exp, get_callee_fndecl (exp));
     }
 }
 
index b703e47..9eaaefa 100644 (file)
@@ -561,7 +561,7 @@ static const format_char_info gcc_diag_char_table[] =
   { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
 
   /* These will require a "tree" at runtime.  */
-  { "J", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",    "",   NULL },
+  { "JK", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",    "",   NULL },
 
   { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
@@ -584,7 +584,7 @@ static const format_char_info gcc_tdiag_char_table[] =
   { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
 
   /* These will require a "tree" at runtime.  */
-  { "DFJT", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
+  { "DFJKT", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
 
   { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
@@ -607,7 +607,7 @@ static const format_char_info gcc_cdiag_char_table[] =
   { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
 
   /* These will require a "tree" at runtime.  */
-  { "DEFJT", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
+  { "DEFJKT", 0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
 
   { "<>'", 0, STD_C89, NOARGUMENTS, "",      "",   NULL },
   { "m",   0, STD_C89, NOARGUMENTS, "q",     "",   NULL },
@@ -630,7 +630,7 @@ static const format_char_info gcc_cxxdiag_char_table[] =
   { "H",   0, STD_C89, { T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
 
   /* These will require a "tree" at runtime.  */
-  { "ADEFJTV",0,STD_C89,{ T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+#",   "",   NULL },
+  { "ADEFJKTV",0,STD_C89,{ T89_V,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+#",   "",   NULL },
 
   /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.)  */
   { "CLOPQ",0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
@@ -2611,6 +2611,9 @@ init_dynamic_diag_info (void)
          i = find_char_info_specifier_index (diag_fci, 'J');
          diag_fci[i].types[0].type = &t;
          diag_fci[i].pointer_count = 1;
+         i = find_char_info_specifier_index (diag_fci, 'K');
+         diag_fci[i].types[0].type = &t;
+         diag_fci[i].pointer_count = 1;
        }
 
       /* Handle the __gcc_tdiag__ format specifics.  */
@@ -2635,6 +2638,9 @@ init_dynamic_diag_info (void)
          i = find_char_info_specifier_index (tdiag_fci, 'J');
          tdiag_fci[i].types[0].type = &t;
          tdiag_fci[i].pointer_count = 1;
+         i = find_char_info_specifier_index (tdiag_fci, 'K');
+         tdiag_fci[i].types[0].type = &t;
+         tdiag_fci[i].pointer_count = 1;
        }
 
       /* Handle the __gcc_cdiag__ format specifics.  */
@@ -2659,6 +2665,9 @@ init_dynamic_diag_info (void)
          i = find_char_info_specifier_index (cdiag_fci, 'J');
          cdiag_fci[i].types[0].type = &t;
          cdiag_fci[i].pointer_count = 1;
+         i = find_char_info_specifier_index (cdiag_fci, 'K');
+         cdiag_fci[i].types[0].type = &t;
+         cdiag_fci[i].pointer_count = 1;
        }
 
       /* Handle the __gcc_cxxdiag__ format specifics.  */
@@ -2683,6 +2692,9 @@ init_dynamic_diag_info (void)
          i = find_char_info_specifier_index (cxxdiag_fci, 'J');
          cxxdiag_fci[i].types[0].type = &t;
          cxxdiag_fci[i].pointer_count = 1;
+         i = find_char_info_specifier_index (cxxdiag_fci, 'K');
+         cxxdiag_fci[i].types[0].type = &t;
+         cxxdiag_fci[i].pointer_count = 1;
        }
     }
 }
index b47c802..915ac9e 100644 (file)
@@ -1,3 +1,12 @@
+2007-09-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * error.c (cxx_print_error_function): Add third argument, pass
+       it over to lhd_print_error_function.
+       (cp_print_error_function): If diagnostic->abstract_origin, print
+       virtual backtrace.
+       * cp-tree.h (struct diagnostic_info): New forward decl.
+       (cxx_print_error_function): Add third argument.
+
 2007-09-25  Simon Martin  <simartin@users.sourceforge.net>
 
        PR c++/33207
index 83f4d42..f28e965 100644 (file)
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "c-common.h"
 #include "name-lookup.h"
 struct diagnostic_context;
+struct diagnostic_info;
 
 /* Usage of TREE_LANG_FLAG_?:
    0: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
@@ -4138,7 +4139,8 @@ extern void cxx_print_decl                        (FILE *, tree, int);
 extern void cxx_print_type                     (FILE *, tree, int);
 extern void cxx_print_identifier               (FILE *, tree, int);
 extern void cxx_print_error_function   (struct diagnostic_context *,
-                                                const char *);
+                                                const char *,
+                                                struct diagnostic_info *);
 extern void build_self_reference               (void);
 extern int same_signature_p                    (const_tree, const_tree);
 extern void maybe_add_class_template_decl_list (tree, tree, int);
index 602426a..24f1d83 100644 (file)
@@ -2329,9 +2329,10 @@ cv_to_string (tree p, int v)
 
 /* Langhook for print_error_function.  */
 void
-cxx_print_error_function (diagnostic_context *context, const char *file)
+cxx_print_error_function (diagnostic_context *context, const char *file,
+                         diagnostic_info *diagnostic)
 {
-  lhd_print_error_function (context, file);
+  lhd_print_error_function (context, file, diagnostic);
   pp_base_set_prefix (context->printer, file);
   maybe_print_instantiation_context (context);
 }
@@ -2359,23 +2360,105 @@ static void
 cp_print_error_function (diagnostic_context *context,
                         diagnostic_info *diagnostic)
 {
-  if (diagnostic_last_function_changed (context))
+  if (diagnostic_last_function_changed (context, diagnostic))
     {
       const char *old_prefix = context->printer->prefix;
       const char *file = LOCATION_FILE (diagnostic->location);
-      char *new_prefix = file ? file_name_as_prefix (file) : NULL;
+      tree abstract_origin = diagnostic->abstract_origin;
+      char *new_prefix = (file && abstract_origin == NULL)
+                        ? file_name_as_prefix (file) : NULL;
 
       pp_base_set_prefix (context->printer, new_prefix);
 
       if (current_function_decl == NULL)
        pp_base_string (context->printer, "At global scope:");
       else
-       pp_printf (context->printer, "In %s %qs:",
-                  function_category (current_function_decl),
-                  cxx_printable_name (current_function_decl, 2));
+       {
+         tree fndecl, ao;
+
+         if (abstract_origin)
+           {
+             ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
+             while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+               ao = BLOCK_ABSTRACT_ORIGIN (ao);
+             gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
+             fndecl = ao;
+           }
+         else
+           fndecl = current_function_decl;
+
+         pp_printf (context->printer, "In %s %qs",
+                    function_category (fndecl),
+                    cxx_printable_name (fndecl, 2));
+
+         while (abstract_origin)
+           {
+             location_t *locus;
+             tree block = abstract_origin;
+
+             locus = &BLOCK_SOURCE_LOCATION (block);
+             fndecl = NULL;
+             block = BLOCK_SUPERCONTEXT (block);
+             while (block && TREE_CODE (block) == BLOCK
+                    && BLOCK_ABSTRACT_ORIGIN (block))
+               {
+                 ao = BLOCK_ABSTRACT_ORIGIN (block);
+
+                 while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+                   ao = BLOCK_ABSTRACT_ORIGIN (ao);
+
+                 if (TREE_CODE (ao) == FUNCTION_DECL)
+                   {
+                     fndecl = ao;
+                     break;
+                   }
+                 else if (TREE_CODE (ao) != BLOCK)
+                   break;
+
+                 block = BLOCK_SUPERCONTEXT (block);
+               }
+             if (fndecl)
+               abstract_origin = block;
+             else
+               {
+                 while (block && TREE_CODE (block) == BLOCK)
+                   block = BLOCK_SUPERCONTEXT (block);
+
+                 if (TREE_CODE (block) == FUNCTION_DECL)
+                   fndecl = block;
+                 abstract_origin = NULL;
+               }
+             if (fndecl)
+               {
+                 expanded_location s = expand_location (*locus);
+                 pp_base_character (context->printer, ',');
+                 pp_base_newline (context->printer);
+                 if (s.file != NULL)
+                   {
+#ifdef USE_MAPPED_LOCATION
+                     if (flag_show_column && s.column != 0)
+                       pp_printf (context->printer,
+                                  "    inlined from %qs at %s:%d:%d",
+                                  cxx_printable_name (fndecl, 2),
+                                  s.file, s.line, s.column);
+                     else
+#endif
+                       pp_printf (context->printer,
+                                  "    inlined from %qs at %s:%d",
+                                  cxx_printable_name (fndecl, 2),
+                                  s.file, s.line);
+
+                   }
+                 else
+                   pp_printf (context->printer, "    inlined from %qs",
+                              cxx_printable_name (fndecl, 2));
+               }
+           }
+         pp_base_character (context->printer, ':');
+       }
       pp_base_newline (context->printer);
 
-      diagnostic_set_last_function (context);
+      diagnostic_set_last_function (context, diagnostic);
       pp_base_destroy_prefix (context->printer);
       context->printer->prefix = old_prefix;
     }
index c712608..6bbfe9a 100644 (file)
@@ -261,10 +261,11 @@ diagnostic_action_after_output (diagnostic_context *context,
 /* Prints out, if necessary, the name of the current function
    that caused an error.  Called from all error and warning functions.  */
 void
-diagnostic_report_current_function (diagnostic_context *context)
+diagnostic_report_current_function (diagnostic_context *context,
+                                   diagnostic_info *diagnostic)
 {
   diagnostic_report_current_module (context);
-  lang_hooks.print_error_function (context, input_filename);
+  lang_hooks.print_error_function (context, input_filename, diagnostic);
 }
 
 void
@@ -302,7 +303,7 @@ static void
 default_diagnostic_starter (diagnostic_context *context,
                            diagnostic_info *diagnostic)
 {
-  diagnostic_report_current_function (context);
+  diagnostic_report_current_function (context, diagnostic);
   pp_set_prefix (context->printer, diagnostic_build_prefix (diagnostic));
 }
 
@@ -414,6 +415,8 @@ diagnostic_report_diagnostic (diagnostic_context *context,
                      " [", cl_options[diagnostic->option_index].opt_text, "]", NULL));
 
       diagnostic->message.locus = &diagnostic->location;
+      diagnostic->message.abstract_origin = &diagnostic->abstract_origin;
+      diagnostic->abstract_origin = NULL;
       pp_format (context->printer, &diagnostic->message);
       (*diagnostic_starter (context)) (context, diagnostic);
       pp_output_formatted_text (context->printer);
@@ -421,6 +424,7 @@ diagnostic_report_diagnostic (diagnostic_context *context,
       pp_flush (context->printer);
       diagnostic_action_after_output (context, diagnostic);
       diagnostic->message.format_spec = saved_format_spec;
+      diagnostic->abstract_origin = NULL;
     }
 
   context->lock--;
@@ -472,6 +476,7 @@ verbatim (const char *gmsgid, ...)
   text.args_ptr = &ap;
   text.format_spec = _(gmsgid);
   text.locus = NULL;
+  text.abstract_origin = NULL;
   pp_format_verbatim (global_dc->printer, &text);
   pp_flush (global_dc->printer);
   va_end (ap);
index 94e5f32..02e43bd 100644 (file)
@@ -37,10 +37,13 @@ typedef enum
 /* A diagnostic is described by the MESSAGE to send, the FILE and LINE of
    its context and its KIND (ice, error, warning, note, ...)  See complete
    list in diagnostic.def.  */
-typedef struct
+typedef struct diagnostic_info
 {
   text_info message;
   location_t location;
+  /* TREE_BLOCK if the diagnostic is to be reported in some inline
+     function inlined into other function, otherwise NULL.  */
+  tree abstract_origin;
   /* The kind of diagnostic it is about.  */
   diagnostic_t kind;
   /* Which OPT_* directly controls this diagnostic.  */
@@ -137,13 +140,15 @@ struct diagnostic_context
 
 /* True if the last function in which a diagnostic was reported is
    different from the current one.  */
-#define diagnostic_last_function_changed(DC) \
-  ((DC)->last_function != current_function_decl)
+#define diagnostic_last_function_changed(DC, DI) \
+  ((DC)->last_function != ((DI)->abstract_origin \
+                          ? (DI)->abstract_origin : current_function_decl))
 
 /* Remember the current function as being the last one in which we report
    a diagnostic.  */
-#define diagnostic_set_last_function(DC) \
-  (DC)->last_function = current_function_decl
+#define diagnostic_set_last_function(DC, DI) \
+  (DC)->last_function = (((DI) && (DI)->abstract_origin) \
+                        ? (DI)->abstract_origin : current_function_decl)
 
 /* True if the last module or file in which a diagnostic was reported is
    different from the current one.  */
@@ -185,7 +190,8 @@ extern diagnostic_context *global_dc;
 /* Diagnostic related functions.  */
 extern void diagnostic_initialize (diagnostic_context *);
 extern void diagnostic_report_current_module (diagnostic_context *);
-extern void diagnostic_report_current_function (diagnostic_context *);
+extern void diagnostic_report_current_function (diagnostic_context *,
+                                               diagnostic_info *);
 
 /* Force diagnostics controlled by OPTIDX to be kind KIND.  */
 extern diagnostic_t diagnostic_classify_diagnostic (diagnostic_context *,
index afd01ac..ff3258d 100644 (file)
@@ -8001,21 +8001,21 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       /* All valid uses of __builtin_va_arg_pack () are removed during
         inlining.  */
       if (CALL_EXPR_VA_ARG_PACK (exp))
-       error ("invalid use of %<__builtin_va_arg_pack ()%>");
+       error ("%Kinvalid use of %<__builtin_va_arg_pack ()%>", exp);
       {
        tree fndecl = get_callee_fndecl (exp), attr;
 
        if (fndecl
            && (attr = lookup_attribute ("error",
                                         DECL_ATTRIBUTES (fndecl))) != NULL)
-         error ("call to %qs declared with attribute error: %s",
-                lang_hooks.decl_printable_name (fndecl, 1),
+         error ("%Kcall to %qs declared with attribute error: %s",
+                exp, lang_hooks.decl_printable_name (fndecl, 1),
                 TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
        if (fndecl
            && (attr = lookup_attribute ("warning",
                                         DECL_ATTRIBUTES (fndecl))) != NULL)
-         warning (0, "call to %qs declared with attribute warning: %s",
-                  lang_hooks.decl_printable_name (fndecl, 1),
+         warning (0, "%Kcall to %qs declared with attribute warning: %s",
+                  exp, lang_hooks.decl_printable_name (fndecl, 1),
                   TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))));
 
        /* Check for a built-in function.  */
index 630e9b8..bb22fdc 100644 (file)
@@ -1,3 +1,7 @@
+2007-09-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * lang.c (java_print_error_function): Add third argument.
+
 2007-09-15  Tom Tromey  <tromey@redhat.com>
 
        * java-tree.h (struct lang_decl_func) <function_decl_body>:
index 333eb8c..4258906 100644 (file)
@@ -54,7 +54,8 @@ static bool java_post_options (const char **);
 static int java_handle_option (size_t scode, const char *arg, int value);
 static void put_decl_string (const char *, int);
 static void put_decl_node (tree);
-static void java_print_error_function (diagnostic_context *, const char *);
+static void java_print_error_function (diagnostic_context *, const char *,
+                                      diagnostic_info *);
 static int merge_init_test_initialization (void * *, void *);
 static int inline_init_test_initialization (void * *, void *);
 static bool java_dump_tree (void *, tree);
@@ -489,7 +490,8 @@ static GTY(()) tree last_error_function_context;
 static GTY(()) tree last_error_function;
 static void
 java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
-                          const char *file)
+                          const char *file,
+                          diagnostic_info *diagnostic ATTRIBUTE_UNUSED)
 {
   /* Don't print error messages with bogus function prototypes.  */
   if (inhibit_error_function_printing)
index 28efd6b..6eca2f0 100644 (file)
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "hooks.h"
 
 struct diagnostic_context;
+struct diagnostic_info;
 
 /* Note to creators of new hooks:
 
@@ -53,7 +54,7 @@ extern int lhd_types_compatible_p (tree, tree);
 extern rtx lhd_expand_expr (tree, rtx, enum machine_mode, int, rtx *);
 extern int lhd_expand_decl (tree);
 extern void lhd_print_error_function (struct diagnostic_context *,
-                                     const char *);
+                                     const char *, struct diagnostic_info *);
 extern void lhd_set_decl_assembler_name (tree);
 extern bool lhd_warn_unused_global_decl (const_tree);
 extern void lhd_incomplete_type_error (const_tree, const_tree);
index b8e7aaa..4682514 100644 (file)
@@ -381,12 +381,15 @@ lhd_initialize_diagnostics (struct diagnostic_context *ctx ATTRIBUTE_UNUSED)
 /* The default function to print out name of current function that caused
    an error.  */
 void
-lhd_print_error_function (diagnostic_context *context, const char *file)
+lhd_print_error_function (diagnostic_context *context, const char *file,
+                         diagnostic_info *diagnostic)
 {
-  if (diagnostic_last_function_changed (context))
+  if (diagnostic_last_function_changed (context, diagnostic))
     {
       const char *old_prefix = context->printer->prefix;
-      char *new_prefix = file ? file_name_as_prefix (file) : NULL;
+      tree abstract_origin = diagnostic->abstract_origin;
+      char *new_prefix = (file && abstract_origin == NULL)
+                        ? file_name_as_prefix (file) : NULL;
 
       pp_set_prefix (context->printer, new_prefix);
 
@@ -394,17 +397,95 @@ lhd_print_error_function (diagnostic_context *context, const char *file)
        pp_printf (context->printer, _("At top level:"));
       else
        {
-         if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
+         tree fndecl, ao;
+
+         if (abstract_origin)
+           {
+             ao = BLOCK_ABSTRACT_ORIGIN (abstract_origin);
+             while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+               ao = BLOCK_ABSTRACT_ORIGIN (ao);
+             gcc_assert (TREE_CODE (ao) == FUNCTION_DECL);
+             fndecl = ao;
+           }
+         else
+           fndecl = current_function_decl;
+
+         if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE)
            pp_printf
-             (context->printer, _("In member function %qs:"),
-              lang_hooks.decl_printable_name (current_function_decl, 2));
+             (context->printer, _("In member function %qs"),
+              lang_hooks.decl_printable_name (fndecl, 2));
          else
            pp_printf
-             (context->printer, _("In function %qs:"),
-              lang_hooks.decl_printable_name (current_function_decl, 2));
+             (context->printer, _("In function %qs"),
+              lang_hooks.decl_printable_name (fndecl, 2));
+
+         while (abstract_origin)
+           {
+             location_t *locus;
+             tree block = abstract_origin;
+
+             locus = &BLOCK_SOURCE_LOCATION (block);
+             fndecl = NULL;
+             block = BLOCK_SUPERCONTEXT (block);
+             while (block && TREE_CODE (block) == BLOCK
+                    && BLOCK_ABSTRACT_ORIGIN (block))
+               {
+                 ao = BLOCK_ABSTRACT_ORIGIN (block);
+
+                 while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+                   ao = BLOCK_ABSTRACT_ORIGIN (ao);
+
+                 if (TREE_CODE (ao) == FUNCTION_DECL)
+                   {
+                     fndecl = ao;
+                     break;
+                   }
+                 else if (TREE_CODE (ao) != BLOCK)
+                   break;
+
+                 block = BLOCK_SUPERCONTEXT (block);
+               }
+             if (fndecl)
+               abstract_origin = block;
+             else
+               {
+                 while (block && TREE_CODE (block) == BLOCK)
+                   block = BLOCK_SUPERCONTEXT (block);
+
+                 if (TREE_CODE (block) == FUNCTION_DECL)
+                   fndecl = block;
+                 abstract_origin = NULL;
+               }
+             if (fndecl)
+               {
+                 expanded_location s = expand_location (*locus);
+                 pp_character (context->printer, ',');
+                 pp_newline (context->printer);
+                 if (s.file != NULL)
+                   {
+#ifdef USE_MAPPED_LOCATION
+                     if (flag_show_column && s.column != 0)
+                       pp_printf (context->printer,
+                                  _("    inlined from %qs at %s:%d:%d"),
+                                  lang_hooks.decl_printable_name (fndecl, 2),
+                                  s.file, s.line, s.column);
+                     else
+#endif
+                       pp_printf (context->printer,
+                                  _("    inlined from %qs at %s:%d"),
+                                  lang_hooks.decl_printable_name (fndecl, 2),
+                                  s.file, s.line);
+
+                   }
+                 else
+                   pp_printf (context->printer, _("    inlined from %qs"),
+                              lang_hooks.decl_printable_name (fndecl, 2));
+               }
+           }
+         pp_character (context->printer, ':');
        }
 
-      diagnostic_set_last_function (context);
+      diagnostic_set_last_function (context, diagnostic);
       pp_flush (context->printer);
       context->printer->prefix = old_prefix;
       free ((char*) new_prefix);
index 7efe742..8a44275 100644 (file)
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3.  If not see
 /* This file should be #include-d after tree.h.  */
 
 struct diagnostic_context;
+struct diagnostic_info;
 
 struct gimplify_omp_ctx;
 
@@ -367,7 +368,8 @@ struct lang_hooks
   tree (*lang_get_callee_fndecl) (const_tree);
 
   /* Called by report_error_function to print out function name.  */
-  void (*print_error_function) (struct diagnostic_context *, const char *);
+  void (*print_error_function) (struct diagnostic_context *, const char *,
+                               struct diagnostic_info *);
 
   /* Called from expr_size to calculate the size of the value of an
      expression in a language-dependent way.  Returns a tree for the size
index 8f55df2..c4de15d 100644 (file)
@@ -187,6 +187,7 @@ pp_base_indent (pretty_printer *pp)
    %Ns: likewise, but length specified as constant in the format string.
    %H: location_t.
    %J: a decl tree, from which DECL_SOURCE_LOCATION will be recorded.
+   %K: a statement, from which EXPR_LOCATION and TREE_BLOCK will be recorded.
    Flag 'q': quote formatted text (must come immediately after '%').
 
    Arguments can be used sequentially, or through %N$ resp. *N$
@@ -486,6 +487,33 @@ pp_base_format (pretty_printer *pp, text_info *text)
          }
          break;
 
+       case 'K':
+         {
+           tree t = va_arg (*text->args_ptr, tree), block;
+           gcc_assert (text->locus != NULL);
+           *text->locus = EXPR_LOCATION (t);
+           gcc_assert (text->abstract_origin != NULL);
+           block = TREE_BLOCK (t);
+           *text->abstract_origin = NULL;
+           while (block
+                  && TREE_CODE (block) == BLOCK
+                  && BLOCK_ABSTRACT_ORIGIN (block))
+             {
+               tree ao = BLOCK_ABSTRACT_ORIGIN (block);
+
+               while (TREE_CODE (ao) == BLOCK && BLOCK_ABSTRACT_ORIGIN (ao))
+                 ao = BLOCK_ABSTRACT_ORIGIN (ao);
+
+               if (TREE_CODE (ao) == FUNCTION_DECL)
+                 {
+                   *text->abstract_origin = block;
+                   break;
+                 }
+               block = BLOCK_SUPERCONTEXT (block);
+             }
+         }
+         break;
+
        case '.':
          {
            int n;
index 585b1d5..039058e 100644 (file)
@@ -35,6 +35,7 @@ typedef struct
   va_list *args_ptr;
   int err_no;  /* for %m */
   location_t *locus;
+  tree *abstract_origin;
 } text_info;
 
 /* How often diagnostics are prefixed by their locations:
index 22bdef2..ec014ea 100644 (file)
@@ -1,3 +1,8 @@
+2007-09-27  Jakub Jelinek  <jakub@redhat.com>
+
+       * lib/prune.exp: Prune also "^In function .*$" lines and
+       "^    inlined from .*$" lines.
+
 2007-09-26  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/33563
index cfce9c2..2e901a0 100644 (file)
 proc prune_gcc_output { text } {
     #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\]*: )?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\]*:   instantiated from \[^\n\]*" $text "" text
+    regsub -all "(^|\n)    inlined from \[^\n\]*" $text "" text
     regsub -all "(^|\n)collect2: ld returned \[^\n\]*" $text "" text
     regsub -all "(^|\n)collect: re(compiling|linking)\[^\n\]*" $text "" text
     regsub -all "(^|\n)Please submit.*instructions\[^\n\]*" $text "" text
index 8c6a68a..0d8c82b 100644 (file)
@@ -434,7 +434,7 @@ announce_function (tree decl)
        fprintf (stderr, " %s", lang_hooks.decl_printable_name (decl, 2));
       fflush (stderr);
       pp_needs_newline (global_dc->printer) = true;
-      diagnostic_set_last_function (global_dc);
+      diagnostic_set_last_function (global_dc, (diagnostic_info *) NULL);
     }
 }