diagnostics: fix excessive range-printing involving macros [PR97932]
PR c/97932 describes a bug in which diagnostic_show_locus prints most of a source file. The issue is that it prints a range in which the start and end locations are part of the same macro map, but the start location is for a token in the definition of the macro, whereas the end location is for a token in an argument of the macro. This patch extends compatible_locations_p to require that range-printing of macro maps requires the location to either be both for the definition of the macro, or both for the arguments of the macro (not one of each), fixing the issue. gcc/ChangeLog: PR c/97932 * diagnostic-show-locus.c (compatible_locations_p): Require locations in the same macro map to be either both from the macro definition, or both from the macro arguments. gcc/testsuite/ChangeLog: PR c/97932 * gcc.dg/pr97932.c: New test.
This commit is contained in:
parent
26fd3bf75b
commit
65c1cb3589
@ -905,6 +905,15 @@ compatible_locations_p (location_t loc_a, location_t loc_b)
|
||||
/* Are both within the same macro expansion? */
|
||||
if (linemap_macro_expansion_map_p (map_a))
|
||||
{
|
||||
/* If so, then they're only compatible if either both are
|
||||
from the macro definition, or both from the macro arguments. */
|
||||
bool loc_a_from_defn
|
||||
= linemap_location_from_macro_definition_p (line_table, loc_a);
|
||||
bool loc_b_from_defn
|
||||
= linemap_location_from_macro_definition_p (line_table, loc_b);
|
||||
if (loc_a_from_defn != loc_b_from_defn)
|
||||
return false;
|
||||
|
||||
/* Expand each location towards the spelling location, and
|
||||
recurse. */
|
||||
const line_map_macro *macro_map = linemap_check_macro (map_a);
|
||||
|
125
gcc/testsuite/gcc.dg/pr97932.c
Normal file
125
gcc/testsuite/gcc.dg/pr97932.c
Normal file
@ -0,0 +1,125 @@
|
||||
/* Verify that we don't emit ranges that span both
|
||||
a macro definition location and a macro expansion location. */
|
||||
|
||||
/* { dg-options "-fdiagnostics-show-caret" } */
|
||||
|
||||
/* Various cases involving the ranges of the LHS and RHS operands to "-". */
|
||||
|
||||
/* Case 1
|
||||
start token is in macro definition ("&"),
|
||||
end token is in macro invocation ("a" and "b"). */
|
||||
|
||||
#define M1(A, B) &A - &B /* { dg-error "invalid operands" } */
|
||||
|
||||
/* Intervening
|
||||
material
|
||||
that
|
||||
ought
|
||||
not
|
||||
to
|
||||
be
|
||||
printed. */
|
||||
|
||||
int test_1 (float a, int b)
|
||||
{
|
||||
return M1(a, b); /* { dg-message "in expansion of macro 'M1'" } */
|
||||
}
|
||||
|
||||
/* { dg-begin-multiline-output "" }
|
||||
#define M1(A, B) &A - &B
|
||||
^
|
||||
{ dg-end-multiline-output "" } */
|
||||
/* { dg-begin-multiline-output "" }
|
||||
return M1(a, b);
|
||||
^~
|
||||
{ dg-end-multiline-output "" } */
|
||||
|
||||
/* Case 2:
|
||||
start and end tokens are both in macro invocation ("&", and "a"/"b"). */
|
||||
|
||||
#define M2(A, B) A - B /* { dg-error "invalid operands" } */
|
||||
|
||||
/* Intervening
|
||||
material
|
||||
that
|
||||
ought
|
||||
not
|
||||
to
|
||||
be
|
||||
printed. */
|
||||
|
||||
int test_2 (float a, int b)
|
||||
{
|
||||
return M2(&a, &b); /* { dg-message "in expansion of macro 'M2'" } */
|
||||
}
|
||||
|
||||
/* { dg-begin-multiline-output "" }
|
||||
#define M2(A, B) A - B
|
||||
^
|
||||
{ dg-end-multiline-output "" } */
|
||||
/* { dg-begin-multiline-output "" }
|
||||
return M2(&a, &b);
|
||||
^~
|
||||
{ dg-end-multiline-output "" } */
|
||||
|
||||
/* Case 3:
|
||||
start token is in macro invocation ("&"),
|
||||
end token is in macro definition ("a"). */
|
||||
|
||||
#define M3(OP) OP a - OP b /* { dg-error "invalid operands" } */
|
||||
|
||||
/* Intervening
|
||||
material
|
||||
that
|
||||
ought
|
||||
not
|
||||
to
|
||||
be
|
||||
printed. */
|
||||
|
||||
int test_3 (float a, int b)
|
||||
{
|
||||
return M3(&); /* { dg-message "in expansion of macro 'M3'" } */
|
||||
}
|
||||
|
||||
/* { dg-begin-multiline-output "" }
|
||||
#define M3(OP) OP a - OP b
|
||||
^
|
||||
{ dg-end-multiline-output "" } */
|
||||
/* { dg-begin-multiline-output "" }
|
||||
return M3(&);
|
||||
^~
|
||||
{ dg-end-multiline-output "" } */
|
||||
|
||||
|
||||
/* Case 4:
|
||||
start and end tokens are both in macro definition ("&a"). */
|
||||
|
||||
#define M4 &a - &b /* { dg-error "invalid operands" } */
|
||||
|
||||
/* Intervening
|
||||
material
|
||||
that
|
||||
ought
|
||||
not
|
||||
to
|
||||
be
|
||||
printed. */
|
||||
|
||||
int test_4 (float a, int b)
|
||||
{
|
||||
return M4; /* { dg-message "in expansion of macro 'M4'" } */
|
||||
}
|
||||
|
||||
/* { dg-begin-multiline-output "" }
|
||||
#define M4 &a - &b
|
||||
~~ ^ ~~
|
||||
| |
|
||||
| int *
|
||||
float *
|
||||
{ dg-end-multiline-output "" } */
|
||||
/* { dg-begin-multiline-output "" }
|
||||
return M4;
|
||||
^~
|
||||
{ dg-end-multiline-output "" } */
|
||||
|
Loading…
Reference in New Issue
Block a user