diagnostics: fix end-points of ranges within macros (PR c++/79300)

gcc/ChangeLog:
	PR c++/79300
	* diagnostic-show-locus.c (layout::layout): Use start and finish
	spelling location for the start and finish of each range.
	* genmatch.c (linemap_client_expand_location_to_spelling_point):
	Add unused aspect param.
	* input.c (expand_location_1): Add "aspect" param, and use it
	to access the correct part of the location.
	(expand_location): Pass LOCATION_ASPECT_CARET to new param of
	expand_location_1.
	(expand_location_to_spelling_point): Likewise.
	(linemap_client_expand_location_to_spelling_point): Add "aspect"
	param, and pass it to expand_location_1.

gcc/testsuite/ChangeLog:
	PR c++/79300
	* c-c++-common/Wmisleading-indentation-3.c (fn_14): Update
	expected underlining within macro expansion.
	* c-c++-common/pr70264.c: Likewise.
	* g++.dg/plugin/diagnostic-test-expressions-1.C
	(test_within_macro_1): New test.
	(test_within_macro_2): Likewise.
	(test_within_macro_3): Likewise.
	(test_within_macro_4): Likewise.
	* gcc.dg/format/diagnostic-ranges.c (test_macro_3): Update
	expected underlining within macro expansion.
	(test_macro_4): Likewise.
	* gcc.dg/plugin/diagnostic-test-expressions-1.c
	(test_within_macro_1): New test.
	(test_within_macro_2): Likewise.
	(test_within_macro_3): Likewise.
	(test_within_macro_4): Likewise.
	* gcc.dg/spellcheck-fields-2.c (test_macro): Update expected
	underlining within macro expansion.

libcpp/ChangeLog:
	PR c++/79300
	* include/line-map.h (enum location_aspect): New enum.
	(linemap_client_expand_location_to_spelling_point): Add
	enum location_aspect param.
	* line-map.c (rich_location::get_expanded_location): Update for
	new param of linemap_client_expand_location_to_spelling_point.
	(rich_location::maybe_add_fixit): Likewise.
	(fixit_hint::affects_line_p): Likewise.

From-SVN: r250022
This commit is contained in:
David Malcolm 2017-07-06 14:17:24 +00:00 committed by David Malcolm
parent 32aaf6ef10
commit c471c6edcb
14 changed files with 284 additions and 25 deletions

View File

@ -1,3 +1,18 @@
2017-07-06 David Malcolm <dmalcolm@redhat.com>
PR c++/79300
* diagnostic-show-locus.c (layout::layout): Use start and finish
spelling location for the start and finish of each range.
* genmatch.c (linemap_client_expand_location_to_spelling_point):
Add unused aspect param.
* input.c (expand_location_1): Add "aspect" param, and use it
to access the correct part of the location.
(expand_location): Pass LOCATION_ASPECT_CARET to new param of
expand_location_1.
(expand_location_to_spelling_point): Likewise.
(linemap_client_expand_location_to_spelling_point): Add "aspect"
param, and pass it to expand_location_1.
2017-07-06 Sebastian Peryt <sebastian.peryt@intel.com> 2017-07-06 Sebastian Peryt <sebastian.peryt@intel.com>
* config/i386/avx512fintrin.h (_mm_mask_getexp_round_ss, * config/i386/avx512fintrin.h (_mm_mask_getexp_round_ss,

View File

@ -788,11 +788,14 @@ layout::layout (diagnostic_context * context,
/* Expand the various locations. */ /* Expand the various locations. */
expanded_location start expanded_location start
= linemap_client_expand_location_to_spelling_point (src_range.m_start); = linemap_client_expand_location_to_spelling_point
(src_range.m_start, LOCATION_ASPECT_START);
expanded_location finish expanded_location finish
= linemap_client_expand_location_to_spelling_point (src_range.m_finish); = linemap_client_expand_location_to_spelling_point
(src_range.m_finish, LOCATION_ASPECT_FINISH);
expanded_location caret expanded_location caret
= linemap_client_expand_location_to_spelling_point (loc_range->m_loc); = linemap_client_expand_location_to_spelling_point
(loc_range->m_loc, LOCATION_ASPECT_CARET);
/* If any part of the range isn't in the same file as the primary /* If any part of the range isn't in the same file as the primary
location of this diagnostic, ignore the range. */ location of this diagnostic, ignore the range. */

View File

@ -61,7 +61,8 @@ static struct line_maps *line_table;
This is the implementation for genmatch. */ This is the implementation for genmatch. */
expanded_location expanded_location
linemap_client_expand_location_to_spelling_point (source_location loc) linemap_client_expand_location_to_spelling_point (source_location loc,
enum location_aspect)
{ {
const struct line_map_ordinary *map; const struct line_map_ordinary *map;
loc = linemap_resolve_location (line_table, loc, LRK_SPELLING_LOCATION, &map); loc = linemap_resolve_location (line_table, loc, LRK_SPELLING_LOCATION, &map);

View File

@ -147,11 +147,14 @@ static const size_t fcache_line_record_size = 100;
associated line/column) in the context of a macro expansion, the associated line/column) in the context of a macro expansion, the
returned location is the first one (while unwinding the macro returned location is the first one (while unwinding the macro
location towards its expansion point) that is in real source location towards its expansion point) that is in real source
code. */ code.
ASPECT controls which part of the location to use. */
static expanded_location static expanded_location
expand_location_1 (source_location loc, expand_location_1 (source_location loc,
bool expansion_point_p) bool expansion_point_p,
enum location_aspect aspect)
{ {
expanded_location xloc; expanded_location xloc;
const line_map_ordinary *map; const line_map_ordinary *map;
@ -181,8 +184,36 @@ expand_location_1 (source_location loc,
loc, NULL); loc, NULL);
lrk = LRK_SPELLING_LOCATION; lrk = LRK_SPELLING_LOCATION;
} }
loc = linemap_resolve_location (line_table, loc, loc = linemap_resolve_location (line_table, loc, lrk, &map);
lrk, &map);
/* loc is now either in an ordinary map, or is a reserved location.
If it is a compound location, the caret is in a spelling location,
but the start/finish might still be a virtual location.
Depending of what the caller asked for, we may need to recurse
one level in order to resolve any virtual locations in the
end-points. */
switch (aspect)
{
default:
gcc_unreachable ();
/* Fall through. */
case LOCATION_ASPECT_CARET:
break;
case LOCATION_ASPECT_START:
{
source_location start = get_start (loc);
if (start != loc)
return expand_location_1 (start, expansion_point_p, aspect);
}
break;
case LOCATION_ASPECT_FINISH:
{
source_location finish = get_finish (loc);
if (finish != loc)
return expand_location_1 (finish, expansion_point_p, aspect);
}
break;
}
xloc = linemap_expand_location (line_table, map, loc); xloc = linemap_expand_location (line_table, map, loc);
} }
@ -773,7 +804,8 @@ is_location_from_builtin_token (source_location loc)
expanded_location expanded_location
expand_location (source_location loc) expand_location (source_location loc)
{ {
return expand_location_1 (loc, /*expansion_point_p=*/true); return expand_location_1 (loc, /*expansion_point_p=*/true,
LOCATION_ASPECT_CARET);
} }
/* Expand the source location LOC into a human readable location. If /* Expand the source location LOC into a human readable location. If
@ -785,7 +817,8 @@ expand_location (source_location loc)
expanded_location expanded_location
expand_location_to_spelling_point (source_location loc) expand_location_to_spelling_point (source_location loc)
{ {
return expand_location_1 (loc, /*expansion_point_p=*/false); return expand_location_1 (loc, /*expansion_point_p=*/false,
LOCATION_ASPECT_CARET);
} }
/* The rich_location class within libcpp requires a way to expand /* The rich_location class within libcpp requires a way to expand
@ -795,12 +828,13 @@ expand_location_to_spelling_point (source_location loc)
to do this. to do this.
This is the implementation for libcommon.a (all host binaries), This is the implementation for libcommon.a (all host binaries),
which simply calls into expand_location_to_spelling_point. */ which simply calls into expand_location_1. */
expanded_location expanded_location
linemap_client_expand_location_to_spelling_point (source_location loc) linemap_client_expand_location_to_spelling_point (source_location loc,
enum location_aspect aspect)
{ {
return expand_location_to_spelling_point (loc); return expand_location_1 (loc, /*expansion_point_p=*/false, aspect);
} }

View File

@ -1,3 +1,25 @@
2017-07-06 David Malcolm <dmalcolm@redhat.com>
PR c++/79300
* c-c++-common/Wmisleading-indentation-3.c (fn_14): Update
expected underlining within macro expansion.
* c-c++-common/pr70264.c: Likewise.
* g++.dg/plugin/diagnostic-test-expressions-1.C
(test_within_macro_1): New test.
(test_within_macro_2): Likewise.
(test_within_macro_3): Likewise.
(test_within_macro_4): Likewise.
* gcc.dg/format/diagnostic-ranges.c (test_macro_3): Update
expected underlining within macro expansion.
(test_macro_4): Likewise.
* gcc.dg/plugin/diagnostic-test-expressions-1.c
(test_within_macro_1): New test.
(test_within_macro_2): Likewise.
(test_within_macro_3): Likewise.
(test_within_macro_4): Likewise.
* gcc.dg/spellcheck-fields-2.c (test_macro): Update expected
underlining within macro expansion.
2017-07-06 Sebastian Peryt <sebastian.peryt@intel.com> 2017-07-06 Sebastian Peryt <sebastian.peryt@intel.com>
* gcc.target/i386/avx512f-vgetexpsd-1.c (_mm_mask_getexp_sd, * gcc.target/i386/avx512f-vgetexpsd-1.c (_mm_mask_getexp_sd,

View File

@ -68,7 +68,7 @@ void fn_14 (void)
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
for ((VAR) = (START); (VAR) < (STOP); (VAR++)) for ((VAR) = (START); (VAR) < (STOP); (VAR++))
^ ^~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
FOR_EACH (i, 0, 10) FOR_EACH (i, 0, 10)

View File

@ -5,7 +5,7 @@ X
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
#define X __LINE__ #define X __LINE__
^ ^~~~~~~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
X X

View File

@ -880,3 +880,81 @@ void test_typeid (int i)
~~~~~~~~~~~~^~~ ~~~~~~~~~~~~^~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
} }
/* Various tests of locations involving macros. */
void test_within_macro_1 (int lhs, int rhs)
{
#define MACRO_1(EXPR) EXPR
__emit_expression_range (0, MACRO_1 (lhs == rhs));
/* { dg-warning "range" "" { target *-*-* } .-2 } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_1 (lhs == rhs));
~~~~^~~~~~
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
#define MACRO_1(EXPR) EXPR
^~~~
{ dg-end-multiline-output "" } */
#undef MACRO_1
}
void test_within_macro_2 (int lhs, int rhs)
{
#define MACRO_2(EXPR) EXPR
__emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
/* { dg-warning "range" "" { target *-*-* } .-2 } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
~~~~^~~~~~
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
^~~~~~~
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
#define MACRO_2(EXPR) EXPR
^~~~
{ dg-end-multiline-output "" } */
#undef MACRO_2
}
void test_within_macro_3 (int lhs, int rhs)
{
#define MACRO_3(EXPR) EXPR
__emit_expression_range (0, MACRO_3 (lhs) == MACRO_3 (rhs));
/* { dg-warning "range" "" { target *-*-* } .-2 } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_3 (lhs) == MACRO_3 (rhs));
^
{ dg-end-multiline-output "" } */
#undef MACRO_3
}
void test_within_macro_4 (int lhs, int rhs)
{
#define MACRO_4(EXPR) EXPR
__emit_expression_range (0, MACRO_4 (MACRO_4 (lhs) == MACRO_4 (rhs)));
/* { dg-warning "range" "" { target *-*-* } .-2 } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_4 (MACRO_4 (lhs) == MACRO_4 (rhs)));
^
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
#define MACRO_4(EXPR) EXPR
^~~~
{ dg-end-multiline-output "" } */
#undef MACRO_4
}

View File

@ -278,7 +278,7 @@ void test_macro_3 (const char *msg)
printf(FMT_STRING, msg); /* { dg-message "10: in expansion of macro 'FMT_STRING" } */ printf(FMT_STRING, msg); /* { dg-message "10: in expansion of macro 'FMT_STRING" } */
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
#define FMT_STRING "hello %i world" #define FMT_STRING "hello %i world"
^ ^~~~~~~~~~~~~~~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
printf(FMT_STRING, msg); printf(FMT_STRING, msg);
@ -293,7 +293,7 @@ void test_macro_4 (const char *msg)
printf(FMT_STRING "\n", msg); /* { dg-message "10: in expansion of macro 'FMT_STRING" } */ printf(FMT_STRING "\n", msg); /* { dg-message "10: in expansion of macro 'FMT_STRING" } */
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
#define FMT_STRING "hello %i world" #define FMT_STRING "hello %i world"
^ ^~~~~~~~~~~~~~~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
printf(FMT_STRING "\n", msg); printf(FMT_STRING "\n", msg);

View File

@ -708,3 +708,82 @@ baz");
~~~~ ~~~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
} }
/* Various tests of locations involving macros. */
void test_within_macro_1 (int lhs, int rhs)
{
#define MACRO_1(EXPR) EXPR
__emit_expression_range (0, MACRO_1 (lhs == rhs));
/* { dg-warning "range" "" { target *-*-* } .-2 } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_1 (lhs == rhs));
~~~~^~~~~~
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
#define MACRO_1(EXPR) EXPR
^~~~
{ dg-end-multiline-output "" } */
#undef MACRO_1
}
void test_within_macro_2 (int lhs, int rhs)
{
#define MACRO_2(EXPR) EXPR
__emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
/* { dg-warning "range" "" { target *-*-* } .-2 } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
~~~~^~~~~~
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_2 (MACRO_2 (lhs == rhs)));
^~~~~~~
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
#define MACRO_2(EXPR) EXPR
^~~~
{ dg-end-multiline-output "" } */
#undef MACRO_2
}
void test_within_macro_3 (int lhs, int rhs)
{
#define MACRO_3(EXPR) EXPR
__emit_expression_range (0, MACRO_3 (lhs) == MACRO_3 (rhs));
/* { dg-warning "range" "" { target *-*-* } .-2 } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_3 (lhs) == MACRO_3 (rhs));
^
{ dg-end-multiline-output "" } */
#undef MACRO_3
}
void test_within_macro_4 (int lhs, int rhs)
{
#define MACRO_4(EXPR) EXPR
__emit_expression_range (0, MACRO_4 (MACRO_4 (lhs) == MACRO_4 (rhs)));
/* { dg-warning "range" "" { target *-*-* } .-2 } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, MACRO_4 (MACRO_4 (lhs) == MACRO_4 (rhs)));
^
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
#define MACRO_4(EXPR) EXPR
^~~~
{ dg-end-multiline-output "" } */
#undef MACRO_4
}

View File

@ -28,7 +28,7 @@ int test_macro (union u *ptr)
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }
#define FIELD colour #define FIELD colour
^ ^~~~~~
{ dg-end-multiline-output "" } */ { dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" } /* { dg-begin-multiline-output "" }

View File

@ -1,3 +1,14 @@
2017-07-06 David Malcolm <dmalcolm@redhat.com>
PR c++/79300
* include/line-map.h (enum location_aspect): New enum.
(linemap_client_expand_location_to_spelling_point): Add
enum location_aspect param.
* line-map.c (rich_location::get_expanded_location): Update for
new param of linemap_client_expand_location_to_spelling_point.
(rich_location::maybe_add_fixit): Likewise.
(fixit_hint::affects_line_p): Likewise.
2017-06-21 Jakub Jelinek <jakub@redhat.com> 2017-06-21 Jakub Jelinek <jakub@redhat.com>
* line-map.c (location_adhoc_data_update): Perform addition in * line-map.c (location_adhoc_data_update): Perform addition in

View File

@ -1905,6 +1905,15 @@ void linemap_dump (FILE *, struct line_maps *, unsigned, bool);
specifies how many macro maps to dump. */ specifies how many macro maps to dump. */
void line_table_dump (FILE *, struct line_maps *, unsigned int, unsigned int); void line_table_dump (FILE *, struct line_maps *, unsigned int, unsigned int);
/* An enum for distinguishing the various parts within a source_location. */
enum location_aspect
{
LOCATION_ASPECT_CARET,
LOCATION_ASPECT_START,
LOCATION_ASPECT_FINISH
};
/* The rich_location class requires a way to expand source_location instances. /* The rich_location class requires a way to expand source_location instances.
We would directly use expand_location_to_spelling_point, which is We would directly use expand_location_to_spelling_point, which is
implemented in gcc/input.c, but we also need to use it for rich_location implemented in gcc/input.c, but we also need to use it for rich_location
@ -1912,6 +1921,7 @@ void line_table_dump (FILE *, struct line_maps *, unsigned int, unsigned int);
Hence we require client code of libcpp to implement the following Hence we require client code of libcpp to implement the following
symbol. */ symbol. */
extern expanded_location extern expanded_location
linemap_client_expand_location_to_spelling_point (source_location ); linemap_client_expand_location_to_spelling_point (source_location,
enum location_aspect);
#endif /* !LIBCPP_LINE_MAP_H */ #endif /* !LIBCPP_LINE_MAP_H */

View File

@ -2066,7 +2066,8 @@ rich_location::get_expanded_location (unsigned int idx)
if (!m_have_expanded_location) if (!m_have_expanded_location)
{ {
m_expanded_location m_expanded_location
= linemap_client_expand_location_to_spelling_point (get_loc (0)); = linemap_client_expand_location_to_spelling_point
(get_loc (0), LOCATION_ASPECT_CARET);
if (m_column_override) if (m_column_override)
m_expanded_location.column = m_column_override; m_expanded_location.column = m_column_override;
m_have_expanded_location = true; m_have_expanded_location = true;
@ -2075,7 +2076,8 @@ rich_location::get_expanded_location (unsigned int idx)
return m_expanded_location; return m_expanded_location;
} }
else else
return linemap_client_expand_location_to_spelling_point (get_loc (idx)); return linemap_client_expand_location_to_spelling_point
(get_loc (idx), LOCATION_ASPECT_CARET);
} }
/* Set the column of the primary location, with 0 meaning /* Set the column of the primary location, with 0 meaning
@ -2331,9 +2333,11 @@ rich_location::maybe_add_fixit (source_location start,
/* Only allow fix-it hints that affect a single line in one file. /* Only allow fix-it hints that affect a single line in one file.
Compare the end-points. */ Compare the end-points. */
expanded_location exploc_start expanded_location exploc_start
= linemap_client_expand_location_to_spelling_point (start); = linemap_client_expand_location_to_spelling_point (start,
LOCATION_ASPECT_START);
expanded_location exploc_next_loc expanded_location exploc_next_loc
= linemap_client_expand_location_to_spelling_point (next_loc); = linemap_client_expand_location_to_spelling_point (next_loc,
LOCATION_ASPECT_START);
/* They must be within the same file... */ /* They must be within the same file... */
if (exploc_start.file != exploc_next_loc.file) if (exploc_start.file != exploc_next_loc.file)
{ {
@ -2407,13 +2411,15 @@ bool
fixit_hint::affects_line_p (const char *file, int line) const fixit_hint::affects_line_p (const char *file, int line) const
{ {
expanded_location exploc_start expanded_location exploc_start
= linemap_client_expand_location_to_spelling_point (m_start); = linemap_client_expand_location_to_spelling_point (m_start,
LOCATION_ASPECT_START);
if (file != exploc_start.file) if (file != exploc_start.file)
return false; return false;
if (line < exploc_start.line) if (line < exploc_start.line)
return false; return false;
expanded_location exploc_next_loc expanded_location exploc_next_loc
= linemap_client_expand_location_to_spelling_point (m_next_loc); = linemap_client_expand_location_to_spelling_point (m_next_loc,
LOCATION_ASPECT_START);
if (file != exploc_next_loc.file) if (file != exploc_next_loc.file)
return false; return false;
if (line > exploc_next_loc.line) if (line > exploc_next_loc.line)