PR c/68473: sanitize source range-printing within certain macro expansions

gcc/ChangeLog:
	PR c/68473
	* diagnostic-show-locus.c (layout::layout): Make loc_range const.
	Sanitize the layout_range against ranges that finish before they
	start.

gcc/testsuite/ChangeLog:
	PR c/68473
	* gcc.dg/plugin/diagnostic-test-expressions-1.c (fminl): New decl.
	(TEST_EQ): New macro.
	(test_macro): New function.
	* gcc.target/i386/pr68473-1.c: New test case.

From-SVN: r231919
This commit is contained in:
David Malcolm 2015-12-22 22:27:45 +00:00 committed by David Malcolm
parent 329590d704
commit 070856cc13
5 changed files with 84 additions and 6 deletions

View File

@ -1,3 +1,10 @@
2015-12-22 David Malcolm <dmalcolm@redhat.com>
PR c/68473
* diagnostic-show-locus.c (layout::layout): Make loc_range const.
Sanitize the layout_range against ranges that finish before they
start.
2015-12-22 Jeff Law <law@redhat.com>
* gimple-ssa-split-paths.c (split_paths): Avoid unnecessary block

View File

@ -444,7 +444,7 @@ layout::layout (diagnostic_context * context,
{
/* This diagnostic printer can only cope with "sufficiently sane" ranges.
Ignore any ranges that are awkward to handle. */
location_range *loc_range = richloc->get_range (idx);
const location_range *loc_range = richloc->get_range (idx);
/* If any part of the range isn't in the same file as the primary
location of this diagnostic, ignore the range. */
@ -456,16 +456,38 @@ layout::layout (diagnostic_context * context,
if (loc_range->m_caret.file != m_exploc.file)
continue;
/* Everything is now known to be in the correct source file,
but it may require further sanitization. */
layout_range ri (loc_range);
/* If we have a range that finishes before it starts (perhaps
from something built via macro expansion), printing the
range is likely to be nonsensical. Also, attempting to do so
breaks assumptions within the printing code (PR c/68473). */
if (loc_range->m_start.line > loc_range->m_finish.line)
{
/* Is this the primary location? */
if (m_layout_ranges.length () == 0)
{
/* We want to print the caret for the primary location, but
we must sanitize away m_start and m_finish. */
ri.m_start = ri.m_caret;
ri.m_finish = ri.m_caret;
}
else
/* This is a non-primary range; ignore it. */
continue;
}
/* Passed all the tests; add the range to m_layout_ranges so that
it will be printed. */
layout_range ri (loc_range);
m_layout_ranges.safe_push (ri);
/* Update m_first_line/m_last_line if necessary. */
if (loc_range->m_start.line < m_first_line)
m_first_line = loc_range->m_start.line;
if (loc_range->m_finish.line > m_last_line)
m_last_line = loc_range->m_finish.line;
if (ri.m_start.m_line < m_first_line)
m_first_line = ri.m_start.m_line;
if (ri.m_finish.m_line > m_last_line)
m_last_line = ri.m_finish.m_line;
}
/* Adjust m_x_offset.

View File

@ -1,3 +1,11 @@
2015-12-22 David Malcolm <dmalcolm@redhat.com>
PR c/68473
* gcc.dg/plugin/diagnostic-test-expressions-1.c (fminl): New decl.
(TEST_EQ): New macro.
(test_macro): New function.
* gcc.target/i386/pr68473-1.c: New test case.
2015-12-22 Jakub Jelinek <jakub@redhat.com>
PR c++/67376

View File

@ -618,3 +618,20 @@ void test_quadratic (double a, double b, double c)
{ dg-end-multiline-output "" } */
}
/* Reproducer for PR c/68473. */
extern long double fminl (long double __x, long double __y);
#define TEST_EQ(FUNC) FUNC##l(xl,xl)
void test_macro (long double xl)
{
__emit_expression_range (0, TEST_EQ (fmin) ); /* { dg-warning "range" } */
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, TEST_EQ (fmin) );
^
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
#define TEST_EQ(FUNC) FUNC##l(xl,xl)
^~~~
{ dg-end-multiline-output "" } */
}

View File

@ -0,0 +1,24 @@
/* { dg-options "-fdiagnostics-show-caret -mno-fp-ret-in-387" } */
extern long double fminl (long double __x, long double __y);
#define TEST_EQ(FUNC) do { \
if ((long)FUNC##l(xl,xl) != (long)xl) \
return; \
} while (0)
void
foo (long double xl)
{
TEST_EQ (fmin); /* { dg-error "x87 register return with x87 disabled" } */
}
/* { dg-begin-multiline-output "" }
TEST_EQ (fmin);
^
{ dg-end-multiline-output "" } */
/* { dg-begin-multiline-output "" }
if ((long)FUNC##l(xl,xl) != (long)xl) \
^~~~
{ dg-end-multiline-output "" } */