759 lines
29 KiB
Diff
759 lines
29 KiB
Diff
|
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.
|
||
|
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.
|
||
|
testsuite/
|
||
|
* lib/prune.exp: Prune also "^In function .*$" lines and
|
||
|
"^ inlined from .*$" lines.
|
||
|
java/
|
||
|
* lang.c (java_print_error_function): Add third argument.
|
||
|
|
||
|
--- gcc/java/lang.c.jj 2007-02-20 22:35:09.000000000 +0100
|
||
|
+++ gcc/java/lang.c 2007-09-28 22:47:38.000000000 +0200
|
||
|
@@ -55,7 +55,8 @@ static bool java_post_options (const cha
|
||
|
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 tree java_tree_inlining_walk_subtrees (tree *, int *, walk_tree_fn,
|
||
|
void *, struct pointer_set_t *);
|
||
|
static int merge_init_test_initialization (void * *, void *);
|
||
|
@@ -511,7 +512,8 @@ static GTY(()) tree last_error_function_
|
||
|
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)
|
||
|
--- gcc/diagnostic.c.jj 2007-02-20 22:39:12.000000000 +0100
|
||
|
+++ gcc/diagnostic.c 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -272,10 +272,11 @@ diagnostic_action_after_output (diagnost
|
||
|
/* 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
|
||
|
@@ -313,7 +314,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));
|
||
|
}
|
||
|
|
||
|
@@ -361,6 +362,8 @@ diagnostic_report_diagnostic (diagnostic
|
||
|
" [", 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);
|
||
|
@@ -368,6 +371,7 @@ diagnostic_report_diagnostic (diagnostic
|
||
|
pp_flush (context->printer);
|
||
|
diagnostic_action_after_output (context, diagnostic);
|
||
|
diagnostic->message.format_spec = saved_format_spec;
|
||
|
+ diagnostic->abstract_origin = NULL;
|
||
|
}
|
||
|
|
||
|
context->lock--;
|
||
|
@@ -419,6 +423,7 @@ verbatim (const char *gmsgid, ...)
|
||
|
text.args_ptr = ≈
|
||
|
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);
|
||
|
--- gcc/builtins.c.jj 2007-09-25 12:26:50.000000000 +0200
|
||
|
+++ gcc/builtins.c 2007-09-28 22:47:00.000000000 +0200
|
||
|
@@ -5982,13 +5982,13 @@ expand_builtin (tree exp, rtx target, rt
|
||
|
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. */
|
||
|
@@ -10286,12 +10286,11 @@ expand_builtin_object_size (tree exp)
|
||
|
int object_size_type;
|
||
|
tree fndecl = get_callee_fndecl (exp);
|
||
|
tree arglist = TREE_OPERAND (exp, 1);
|
||
|
- location_t locus = EXPR_LOCATION (exp);
|
||
|
|
||
|
if (!validate_arglist (arglist, 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;
|
||
|
}
|
||
|
@@ -10303,8 +10302,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;
|
||
|
}
|
||
|
@@ -10348,9 +10347,8 @@ expand_builtin_memory_chk (tree exp, rtx
|
||
|
|
||
|
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 0;
|
||
|
}
|
||
|
|
||
|
@@ -10463,7 +10461,6 @@ maybe_emit_chk_warning (tree exp, enum b
|
||
|
int arg_mask, is_strlen = 0;
|
||
|
tree arglist = TREE_OPERAND (exp, 1), a;
|
||
|
tree len, size;
|
||
|
- location_t locus;
|
||
|
|
||
|
switch (fcode)
|
||
|
{
|
||
|
@@ -10525,9 +10522,8 @@ maybe_emit_chk_warning (tree exp, enum b
|
||
|
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))
|
||
|
@@ -10536,9 +10532,8 @@ maybe_emit_chk_warning (tree exp, enum b
|
||
|
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
|
||
|
@@ -10604,9 +10599,8 @@ maybe_emit_sprintf_chk_warning (tree exp
|
||
|
|
||
|
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));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
--- gcc/diagnostic.h.jj 2007-02-20 22:39:12.000000000 +0100
|
||
|
+++ gcc/diagnostic.h 2007-09-28 22:45:58.000000000 +0200
|
||
|
@@ -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. */
|
||
|
@@ -130,13 +133,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. */
|
||
|
@@ -178,7 +183,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 *);
|
||
|
extern void diagnostic_report_diagnostic (diagnostic_context *,
|
||
|
diagnostic_info *);
|
||
|
#ifdef ATTRIBUTE_GCC_DIAG
|
||
|
--- gcc/toplev.c.jj 2007-04-03 13:18:27.000000000 +0200
|
||
|
+++ gcc/toplev.c 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -448,7 +448,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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
--- gcc/pretty-print.c.jj 2007-02-20 22:39:12.000000000 +0100
|
||
|
+++ gcc/pretty-print.c 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -188,6 +188,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$
|
||
|
@@ -487,6 +488,33 @@ pp_base_format (pretty_printer *pp, 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;
|
||
|
--- gcc/pretty-print.h.jj 2007-02-20 22:39:12.000000000 +0100
|
||
|
+++ gcc/pretty-print.h 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -36,6 +36,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:
|
||
|
--- gcc/testsuite/lib/prune.exp.jj 2007-02-20 22:37:09.000000000 +0100
|
||
|
+++ gcc/testsuite/lib/prune.exp 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -19,9 +19,10 @@
|
||
|
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
|
||
|
--- gcc/cp/error.c.jj 2007-09-25 11:15:31.000000000 +0200
|
||
|
+++ gcc/cp/error.c 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -2150,9 +2150,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);
|
||
|
}
|
||
|
@@ -2180,23 +2181,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;
|
||
|
}
|
||
|
--- gcc/cp/cp-tree.h.jj 2007-09-25 11:45:25.000000000 +0200
|
||
|
+++ gcc/cp/cp-tree.h 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -32,6 +32,7 @@ Boston, MA 02110-1301, USA. */
|
||
|
#include "c-common.h"
|
||
|
#include "name-lookup.h"
|
||
|
struct diagnostic_context;
|
||
|
+struct diagnostic_info;
|
||
|
|
||
|
/* Usage of TREE_LANG_FLAG_?:
|
||
|
0: IDENTIFIER_MARKED (IDENTIFIER_NODEs)
|
||
|
@@ -3832,7 +3833,8 @@ extern void cxx_print_decl (FILE *, tr
|
||
|
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 (tree, tree);
|
||
|
extern void warn_hidden (tree);
|
||
|
--- gcc/c-format.c.jj 2007-09-25 12:27:55.000000000 +0200
|
||
|
+++ gcc/c-format.c 2007-09-28 22:50:35.000000000 +0200
|
||
|
@@ -547,7 +547,7 @@ static const format_char_info gcc_diag_c
|
||
|
{ "H", 0, STD_C89, { T89_V, 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 }, "q", "", NULL },
|
||
|
+ { "JK", 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 },
|
||
|
@@ -570,7 +570,7 @@ static const format_char_info gcc_tdiag_
|
||
|
{ "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 },
|
||
|
@@ -593,7 +593,7 @@ static const format_char_info gcc_cdiag_
|
||
|
{ "H", 0, STD_C89, { T89_V, 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 }, "q+", "", NULL },
|
||
|
+ { "DEFJKT", 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 },
|
||
|
@@ -616,7 +616,7 @@ static const format_char_info gcc_cxxdia
|
||
|
{ "H", 0, STD_C89, { T89_V, 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 }, "q+#", "", NULL },
|
||
|
+ { "ADEFJKTV",0,STD_C89,{ T89_V, 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 }, "q", "", NULL },
|
||
|
@@ -2601,6 +2601,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. */
|
||
|
@@ -2625,6 +2628,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. */
|
||
|
@@ -2649,6 +2655,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. */
|
||
|
@@ -2673,6 +2682,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;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
--- gcc/expr.c.jj 2007-09-25 15:19:15.000000000 +0200
|
||
|
+++ gcc/expr.c 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -7512,21 +7512,21 @@ expand_expr_real_1 (tree exp, rtx target
|
||
|
/* 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. */
|
||
|
--- gcc/langhooks.c.jj 2007-02-20 22:39:12.000000000 +0100
|
||
|
+++ gcc/langhooks.c 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -494,12 +494,15 @@ lhd_initialize_diagnostics (struct diagn
|
||
|
/* 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);
|
||
|
|
||
|
@@ -507,17 +510,95 @@ lhd_print_error_function (diagnostic_con
|
||
|
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);
|
||
|
--- gcc/langhooks.h.jj 2007-02-20 22:39:12.000000000 +0100
|
||
|
+++ gcc/langhooks.h 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -24,6 +24,7 @@ Boston, MA 02110-1301, USA. */
|
||
|
/* This file should be #include-d after tree.h. */
|
||
|
|
||
|
struct diagnostic_context;
|
||
|
+struct diagnostic_info;
|
||
|
|
||
|
struct gimplify_omp_ctx;
|
||
|
|
||
|
@@ -391,7 +392,8 @@ struct lang_hooks
|
||
|
tree (*lang_get_callee_fndecl) (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
|
||
|
--- gcc/langhooks-def.h.jj 2007-02-20 22:39:13.000000000 +0100
|
||
|
+++ gcc/langhooks-def.h 2007-09-28 22:45:19.000000000 +0200
|
||
|
@@ -25,6 +25,7 @@ Boston, MA 02110-1301, USA. */
|
||
|
#include "hooks.h"
|
||
|
|
||
|
struct diagnostic_context;
|
||
|
+struct diagnostic_info;
|
||
|
|
||
|
/* Provide a hook routine for alias sets that always returns 1. This is
|
||
|
used by languages that haven't deal with alias sets yet. */
|
||
|
@@ -57,7 +58,7 @@ extern int lhd_types_compatible_p (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_can_use_bit_fields_p (void);
|
||
|
extern bool lhd_warn_unused_global_decl (tree);
|