Commit 3d0a5393 by David Malcolm Committed by David Malcolm

Fix ICE in get_substring_ranges_for_loc on __FILE__ (PR c++/87721)

PR c++/87721 reports a crash in get_substring_ranges_for_loc introduced
by r265271, my fix for PR 87562.

The new issue occurs when attempting to get a location with a string
literal inside a macro in which the first token is __FILE__ (formed via
concatenation).  Attempting to get the spelling location of __FILE__
fails, leading to NULL for start_ord_map and final_ord_map, and thus
a NULL pointer dereference.

Given that our "on-demand" substring locations approach reparses the
string literals, there isn't a good way to access the locations inside
such string literals: attempting to reparse __FILE__ fails with a
"missing open quote".

This patch applies the easy fix by gracefully rejecting the case where
the spelling locations for the start or finish give us NULL maps.

gcc/ChangeLog:
	PR c++/87721
	* input.c (get_substring_ranges_for_loc): Detect if
	linemap_resolve_location gives us a NULL map, and reject
	this case.

gcc/testsuite/ChangeLog:
	PR c++/87721
	* c-c++-common/substring-location-PR-87721.c: New test.
	* gcc.dg/plugin/diagnostic-test-string-literals-1.c: Add test for
	PR 87721.
	* gcc.dg/plugin/diagnostic_plugin_test_string_literals.c
	(test_string_literals): Fold the index arguments before checking
	for INTEGER_CST.

From-SVN: r265611
parent 7e2de6df
2018-10-29 David Malcolm <dmalcolm@redhat.com>
PR c++/87721
* input.c (get_substring_ranges_for_loc): Detect if
linemap_resolve_location gives us a NULL map, and reject
this case.
2018-10-29 Iain Buclaw <ibuclaw@gdcproject.org>
* config.gcc (xstormy16-*-elf): Set tm_d_file.
......@@ -1463,6 +1463,8 @@ get_substring_ranges_for_loc (cpp_reader *pfile,
const line_map_ordinary *final_ord_map;
linemap_resolve_location (line_table, src_range.m_finish,
LRK_SPELLING_LOCATION, &final_ord_map);
if (start_ord_map == NULL || final_ord_map == NULL)
return "failed to get ordinary maps";
/* Bulletproofing. We ought to only have different ordinary maps
for start vs finish due to line-length jumps. */
if (start_ord_map != final_ord_map
......
2018-10-29 David Malcolm <dmalcolm@redhat.com>
PR c++/87721
* c-c++-common/substring-location-PR-87721.c: New test.
* gcc.dg/plugin/diagnostic-test-string-literals-1.c: Add test for
PR 87721.
* gcc.dg/plugin/diagnostic_plugin_test_string_literals.c
(test_string_literals): Fold the index arguments before checking
for INTEGER_CST.
2018-10-29 David Malcolm <dmalcolm@redhat.com>
* c-c++-common/spellcheck-reserved.c: Update expected output for
C++ for merger of "did you mean" suggestions into the error
message.
......
# define DBG_ERROR(dbg_logger, format, args...) if (1){\
char dbg_buffer[256]; \
__builtin_snprintf(dbg_buffer, sizeof(dbg_buffer)-1,\
__FILE__":%5d: " format , __LINE__ , ## args); \
};
void testPasswordStore1(int argc, char **argv) {
const char *pw1="Secret1";
char pw[256];
DBG_ERROR(0, "Bad password, expected [%s], got [%s].", pw1, pw);
}
......@@ -319,3 +319,33 @@ pr87652 (const char *stem, int counter)
^~
{ dg-end-multiline-output "" } */
}
/* Reproducer for PR 87721. */
# define OFFSET __builtin_strlen (__FILE__) + __builtin_strlen(":%5d: ")
# define DBG_ERROR(format, caret_idx, start_idx, end_idx) \
do { \
__emit_string_literal_range(__FILE__":%5d: " format, \
OFFSET + caret_idx, \
OFFSET + start_idx, \
OFFSET + end_idx); \
} while (0)
/* { dg-error "unable to read substring location: failed to get ordinary maps" "" { target *-*-* } 329 } */
/* { dg-begin-multiline-output "" }
__emit_string_literal_range(__FILE__":%5d: " format, \
^~~~~~~~
{ dg-end-multiline-output "" { target c } } */
/* { dg-begin-multiline-output "" }
__emit_string_literal_range(__FILE__":%5d: " format, \
^
{ dg-end-multiline-output "" { target c++ } } */
void pr87721 (void) {
DBG_ERROR("Bad password, expected [%s], got [%s].", 24, 24, 25); /* { dg-message "in expansion of macro 'DBG_ERROR'" } */
/* { dg-begin-multiline-output "" }
DBG_ERROR("Bad password, expected [%s], got [%s].", 24, 24, 25);
^~~~~~~~~
{ dg-end-multiline-output "" } */
}
......@@ -140,7 +140,7 @@ test_string_literals (gimple *stmt)
return;
}
tree t_caret_idx = gimple_call_arg (call, 1);
tree t_caret_idx = fold (gimple_call_arg (call, 1));
if (TREE_CODE (t_caret_idx) != INTEGER_CST)
{
error_at (call->location, "integer constant required for arg 2");
......@@ -148,7 +148,7 @@ test_string_literals (gimple *stmt)
}
int caret_idx = TREE_INT_CST_LOW (t_caret_idx);
tree t_start_idx = gimple_call_arg (call, 2);
tree t_start_idx = fold (gimple_call_arg (call, 2));
if (TREE_CODE (t_start_idx) != INTEGER_CST)
{
error_at (call->location, "integer constant required for arg 3");
......@@ -156,7 +156,7 @@ test_string_literals (gimple *stmt)
}
int start_idx = TREE_INT_CST_LOW (t_start_idx);
tree t_end_idx = gimple_call_arg (call, 3);
tree t_end_idx = fold (gimple_call_arg (call, 3));
if (TREE_CODE (t_end_idx) != INTEGER_CST)
{
error_at (call->location, "integer constant required for arg 4");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment