aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/basic-block.h5
-rw-r--r--gcc/cfghooks.cc1
-rw-r--r--gcc/cp/module.cc5
-rw-r--r--gcc/final.cc26
-rw-r--r--gcc/gimple-pretty-print.cc2
-rw-r--r--gcc/gimple-streamer-in.cc1
-rw-r--r--gcc/gimple-streamer-out.cc1
-rw-r--r--gcc/input.cc36
-rw-r--r--gcc/input.h4
-rw-r--r--gcc/lto-streamer-in.cc19
-rw-r--r--gcc/lto-streamer-out.cc7
-rw-r--r--gcc/lto-streamer.h3
-rw-r--r--gcc/print-rtl.cc4
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr85213.c7
-rw-r--r--gcc/tree-cfg.cc49
-rw-r--r--gcc/tree-pretty-print.cc6
-rw-r--r--gcc/tree.cc10
-rw-r--r--libcpp/include/line-map.h10
-rw-r--r--libcpp/lex.cc7
-rw-r--r--libcpp/line-map.cc38
21 files changed, 187 insertions, 55 deletions
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index c9d1fc9..1eae03d 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -148,11 +148,6 @@ struct GTY((chain_next ("%h.next_bb"), chain_prev ("%h.prev_bb"))) basic_block_d
/* Expected number of executions: calculated in profile.cc. */
profile_count count;
-
- /* The discriminator for this block. The discriminator distinguishes
- among several basic blocks that share a common locus, allowing for
- more accurate sample-based profiling. */
- int discriminator;
};
/* This ensures that struct gimple_bb_info is smaller than
diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc
index c6ac953..29ded57 100644
--- a/gcc/cfghooks.cc
+++ b/gcc/cfghooks.cc
@@ -541,7 +541,6 @@ split_block_1 (basic_block bb, void *i)
return NULL;
new_bb->count = bb->count;
- new_bb->discriminator = bb->discriminator;
if (dom_info_available_p (CDI_DOMINATORS))
{
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 7496df5..d965017 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -15777,6 +15777,8 @@ module_state::write_location (bytes_out &sec, location_t loc)
range.m_start = UNKNOWN_LOCATION;
write_location (sec, range.m_start);
write_location (sec, range.m_finish);
+ unsigned discriminator = get_discriminator_from_adhoc_loc (line_table, loc);
+ sec.u (discriminator);
}
else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
{
@@ -15902,8 +15904,9 @@ module_state::read_location (bytes_in &sec) const
if (range.m_start == UNKNOWN_LOCATION)
range.m_start = locus;
range.m_finish = read_location (sec);
+ unsigned discriminator = sec.u ();
if (locus != loc && range.m_start != loc && range.m_finish != loc)
- locus = get_combined_adhoc_loc (line_table, locus, range, NULL);
+ locus = get_combined_adhoc_loc (line_table, locus, range, NULL, discriminator);
}
break;
diff --git a/gcc/final.cc b/gcc/final.cc
index c0bfdf6..eea5722 100644
--- a/gcc/final.cc
+++ b/gcc/final.cc
@@ -118,18 +118,10 @@ static int last_columnnum;
/* Discriminator written to assembly. */
static int last_discriminator;
-/* Discriminator to be written to assembly for current instruction.
+/* Compute discriminator to be written to assembly for current instruction.
Note: actual usage depends on loc_discriminator_kind setting. */
-static int discriminator;
static inline int compute_discriminator (location_t loc);
-/* Discriminator identifying current basic block among others sharing
- the same locus. */
-static int bb_discriminator;
-
-/* Basic block discriminator for previous instruction. */
-static int last_bb_discriminator;
-
/* Highest line number in current block. */
static int high_block_linenum;
@@ -1688,8 +1680,7 @@ final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen,
last_filename = LOCATION_FILE (prologue_location);
last_linenum = LOCATION_LINE (prologue_location);
last_columnnum = LOCATION_COLUMN (prologue_location);
- last_discriminator = discriminator = 0;
- last_bb_discriminator = bb_discriminator = 0;
+ last_discriminator = 0;
force_source_line = false;
high_block_linenum = high_function_linenum = last_linenum;
@@ -2234,7 +2225,6 @@ final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
if (targetm.asm_out.unwind_emit)
targetm.asm_out.unwind_emit (asm_out_file, insn);
- bb_discriminator = NOTE_BASIC_BLOCK (insn)->discriminator;
break;
case NOTE_INSN_EH_REGION_BEG:
@@ -2939,7 +2929,7 @@ compute_discriminator (location_t loc)
int discriminator;
if (!decl_to_instance_map)
- discriminator = bb_discriminator;
+ discriminator = get_discriminator_from_loc (loc);
else
{
tree block = LOCATION_BLOCK (loc);
@@ -2963,6 +2953,13 @@ compute_discriminator (location_t loc)
return discriminator;
}
+/* Return discriminator of the statement that produced this insn. */
+int
+insn_discriminator (const rtx_insn *insn)
+{
+ return compute_discriminator (INSN_LOCATION (insn));
+}
+
/* Return whether a source line note needs to be emitted before INSN.
Sets IS_STMT to TRUE if the line should be marked as a possible
breakpoint location. */
@@ -2972,6 +2969,7 @@ notice_source_line (rtx_insn *insn, bool *is_stmt)
{
const char *filename;
int linenum, columnnum;
+ int discriminator;
if (NOTE_MARKER_P (insn))
{
@@ -3001,7 +2999,7 @@ notice_source_line (rtx_insn *insn, bool *is_stmt)
filename = xloc.file;
linenum = xloc.line;
columnnum = xloc.column;
- discriminator = compute_discriminator (INSN_LOCATION (insn));
+ discriminator = insn_discriminator (insn);
}
else
{
diff --git a/gcc/gimple-pretty-print.cc b/gcc/gimple-pretty-print.cc
index f18baec..a87e2ae 100644
--- a/gcc/gimple-pretty-print.cc
+++ b/gcc/gimple-pretty-print.cc
@@ -2875,8 +2875,6 @@ dump_gimple_bb_header (FILE *outf, basic_block bb, int indent,
indent, "", get_lineno (gsi_stmt (gsi)));
break;
}
- if (bb->discriminator)
- fprintf (outf, ", discriminator %i", bb->discriminator);
fputc ('\n', outf);
}
}
diff --git a/gcc/gimple-streamer-in.cc b/gcc/gimple-streamer-in.cc
index e7f3256..ea8891e 100644
--- a/gcc/gimple-streamer-in.cc
+++ b/gcc/gimple-streamer-in.cc
@@ -267,7 +267,6 @@ input_bb (class lto_input_block *ib, enum LTO_tags tag,
bb->count
= bb->count.apply_scale (count_materialization_scale, REG_BR_PROB_BASE);
bb->flags = streamer_read_hwi (ib);
- bb->discriminator = streamer_read_hwi (ib);
/* LTO_bb1 has statements. LTO_bb0 does not. */
if (tag == LTO_bb0)
diff --git a/gcc/gimple-streamer-out.cc b/gcc/gimple-streamer-out.cc
index 3336525..4583254 100644
--- a/gcc/gimple-streamer-out.cc
+++ b/gcc/gimple-streamer-out.cc
@@ -208,7 +208,6 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn)
streamer_write_uhwi (ob, bb->index);
bb->count.stream_out (ob);
streamer_write_hwi (ob, bb->flags);
- streamer_write_hwi (ob, bb->discriminator);
if (!gsi_end_p (bsi) || phi_nodes (bb))
{
diff --git a/gcc/input.cc b/gcc/input.cc
index 060ca16..a28abfa 100644
--- a/gcc/input.cc
+++ b/gcc/input.cc
@@ -1082,7 +1082,8 @@ make_location (location_t caret, location_t start, location_t finish)
location_t combined_loc = COMBINE_LOCATION_DATA (line_table,
pure_loc,
src_range,
- NULL);
+ NULL,
+ 0);
return combined_loc;
}
@@ -1092,7 +1093,7 @@ location_t
make_location (location_t caret, source_range src_range)
{
location_t pure_loc = get_pure_location (caret);
- return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, NULL);
+ return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, NULL, 0);
}
/* An expanded_location stores the column in byte units. This function
@@ -1766,6 +1767,37 @@ get_location_within_string (cpp_reader *pfile,
return NULL;
}
+/* Associate the DISCRIMINATOR with LOCUS, and return a new locus. */
+
+location_t
+location_with_discriminator (location_t locus, int discriminator)
+{
+ tree block = LOCATION_BLOCK (locus);
+ source_range src_range = get_range_from_loc (line_table, locus);
+ locus = get_pure_location (locus);
+
+ if (locus == UNKNOWN_LOCATION)
+ return locus;
+
+ return COMBINE_LOCATION_DATA (line_table, locus, src_range, block, discriminator);
+}
+
+/* Return TRUE if LOCUS represents a location with a discriminator. */
+
+bool
+has_discriminator (location_t locus)
+{
+ return get_discriminator_from_loc (locus) != 0;
+}
+
+/* Return the discriminator for LOCUS. */
+
+int
+get_discriminator_from_loc (location_t locus)
+{
+ return get_discriminator_from_loc (line_table, locus);
+}
+
#if CHECKING_P
namespace selftest {
diff --git a/gcc/input.h b/gcc/input.h
index f1ae3ae..11c571d 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -165,6 +165,10 @@ extern location_t expansion_point_location (location_t);
extern location_t input_location;
+extern location_t location_with_discriminator (location_t, int);
+extern bool has_discriminator (location_t);
+extern int get_discriminator_from_loc (location_t);
+
#define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
#define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
#define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
diff --git a/gcc/lto-streamer-in.cc b/gcc/lto-streamer-in.cc
index a7dad70..fa89634 100644
--- a/gcc/lto-streamer-in.cc
+++ b/gcc/lto-streamer-in.cc
@@ -409,6 +409,8 @@ lto_location_cache::cmp_loc (const void *pa, const void *pb)
return a->line - b->line;
if (a->col != b->col)
return a->col - b->col;
+ if (a->discr != b->discr)
+ return a->discr - b->discr;
if ((a->block == NULL_TREE) != (b->block == NULL_TREE))
return a->block ? 1 : -1;
if (a->block)
@@ -460,6 +462,8 @@ lto_location_cache::apply_location_cache ()
current_loc = linemap_position_for_column (line_table, loc.col);
if (loc.block)
current_loc = set_block (current_loc, loc.block);
+ if (loc.discr)
+ current_loc = location_with_discriminator (current_loc, loc.discr);
}
else if (current_block != loc.block)
{
@@ -467,12 +471,17 @@ lto_location_cache::apply_location_cache ()
current_loc = set_block (current_loc, loc.block);
else
current_loc = LOCATION_LOCUS (current_loc);
+ if (loc.discr)
+ current_loc = location_with_discriminator (current_loc, loc.discr);
}
+ else if (current_discr != loc.discr)
+ current_loc = location_with_discriminator (current_loc, loc.discr);
*loc.loc = current_loc;
current_line = loc.line;
prev_file = current_file = loc.file;
current_col = loc.col;
current_block = loc.block;
+ current_discr = loc.discr;
}
loc_cache.truncate (0);
accepted_length = 0;
@@ -512,6 +521,7 @@ lto_location_cache::input_location_and_block (location_t *loc,
static int stream_col;
static bool stream_sysp;
static tree stream_block;
+ static unsigned stream_discr;
static const char *stream_relative_path_prefix;
gcc_assert (current_cache == this);
@@ -538,6 +548,7 @@ lto_location_cache::input_location_and_block (location_t *loc,
*loc = RESERVED_LOCATION_COUNT;
bool line_change = bp_unpack_value (bp, 1);
bool column_change = bp_unpack_value (bp, 1);
+ bool discr_change = bp_unpack_value (bp, 1);
if (file_change)
{
@@ -563,6 +574,9 @@ lto_location_cache::input_location_and_block (location_t *loc,
if (column_change)
stream_col = bp_unpack_var_len_unsigned (bp);
+ if (discr_change)
+ stream_discr = bp_unpack_var_len_unsigned (bp);
+
tree block = NULL_TREE;
if (ib)
{
@@ -578,7 +592,8 @@ lto_location_cache::input_location_and_block (location_t *loc,
if (current_file == stream_file
&& current_line == stream_line
&& current_col == stream_col
- && current_sysp == stream_sysp)
+ && current_sysp == stream_sysp
+ && current_discr == stream_discr)
{
if (current_block == block)
*loc = current_loc;
@@ -590,7 +605,7 @@ lto_location_cache::input_location_and_block (location_t *loc,
}
struct cached_location entry
- = {stream_file, loc, stream_line, stream_col, stream_sysp, block};
+ = {stream_file, loc, stream_line, stream_col, stream_sysp, block, stream_discr};
loc_cache.safe_push (entry);
}
diff --git a/gcc/lto-streamer-out.cc b/gcc/lto-streamer-out.cc
index 1bc3f55..2e7af03 100644
--- a/gcc/lto-streamer-out.cc
+++ b/gcc/lto-streamer-out.cc
@@ -67,6 +67,7 @@ clear_line_info (struct output_block *ob)
so that the first location with block in a function etc.
always streams a change_block bit and the first block. */
ob->current_block = void_node;
+ ob->current_discr = UINT_MAX;
}
@@ -194,6 +195,7 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp,
if (loc >= RESERVED_LOCATION_COUNT)
{
expanded_location xloc = expand_location (loc);
+ unsigned discr = get_discriminator_from_loc (orig_loc);
if (ob->reset_locus)
{
@@ -216,6 +218,7 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp,
bp_pack_value (bp, ob->current_line != xloc.line, 1);
bp_pack_value (bp, ob->current_col != xloc.column, 1);
+ bp_pack_value (bp, ob->current_discr != discr, 1);
if (ob->current_file != xloc.file)
{
@@ -242,6 +245,10 @@ lto_output_location_1 (struct output_block *ob, struct bitpack_d *bp,
if (ob->current_col != xloc.column)
bp_pack_var_len_unsigned (bp, xloc.column);
ob->current_col = xloc.column;
+
+ if (ob->current_discr != discr)
+ bp_pack_var_len_unsigned (bp, discr);
+ ob->current_discr = discr;
}
else
bp_pack_int_in_range (bp, 0, RESERVED_LOCATION_COUNT + 1, loc);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 597e9e4..2e3abd9 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -311,6 +311,7 @@ private:
int line, col;
bool sysp;
tree block;
+ unsigned discr;
};
/* The location cache. */
@@ -333,6 +334,7 @@ private:
bool current_sysp;
location_t current_loc;
tree current_block;
+ unsigned current_discr;
};
/* Structure used as buffer for reading an LTO file. */
@@ -723,6 +725,7 @@ struct output_block
bool reset_locus;
bool emit_pwd;
tree current_block;
+ unsigned current_discr;
/* Cache of nodes written in this section. */
struct streamer_tree_cache_d *writer_cache;
diff --git a/gcc/print-rtl.cc b/gcc/print-rtl.cc
index 60c8454..e115f98 100644
--- a/gcc/print-rtl.cc
+++ b/gcc/print-rtl.cc
@@ -453,6 +453,10 @@ rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx)
expanded_location xloc = insn_location (in_insn);
fprintf (m_outfile, " \"%s\":%i:%i", xloc.file, xloc.line,
xloc.column);
+ int discriminator = insn_discriminator (in_insn);
+ if (discriminator)
+ fprintf (m_outfile, " discrim %d", discriminator);
+
}
#endif
}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 645c009..7a8c470 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3369,6 +3369,7 @@ extern int insn_line (const rtx_insn *);
extern const char * insn_file (const rtx_insn *);
extern tree insn_scope (const rtx_insn *);
extern expanded_location insn_location (const rtx_insn *);
+extern int insn_discriminator (const rtx_insn *);
extern location_t prologue_location, epilogue_location;
/* In jump.cc */
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr85213.c b/gcc/testsuite/c-c++-common/ubsan/pr85213.c
index 8a6be81..e903e97 100644
--- a/gcc/testsuite/c-c++-common/ubsan/pr85213.c
+++ b/gcc/testsuite/c-c++-common/ubsan/pr85213.c
@@ -1,6 +1,11 @@
/* PR sanitizer/85213 */
/* { dg-do compile } */
-/* { dg-options "-O1 -fsanitize=undefined -fcompare-debug" } */
+/* Pass -gno-statement-frontiers to work around
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100733 :
+ without it the IR coming from the front end may be different with and without
+ debug information turned on. That may cause e.g., different discriminator values
+ and -fcompare-debug failures. */
+/* { dg-options "-O1 -fsanitize=undefined -fcompare-debug -gno-statement-frontiers" } */
int
foo (int x)
diff --git a/gcc/tree-cfg.cc b/gcc/tree-cfg.cc
index 53be0c2..ade66c5 100644
--- a/gcc/tree-cfg.cc
+++ b/gcc/tree-cfg.cc
@@ -1166,7 +1166,33 @@ same_line_p (location_t locus1, expanded_location *from, location_t locus2)
&& filename_cmp (from->file, to.file) == 0);
}
-/* Assign discriminators to each basic block. */
+/* Assign a unique discriminator value to all statements in block bb that
+ have the same line number as locus. */
+
+static void
+assign_discriminator (location_t locus, basic_block bb)
+{
+ gimple_stmt_iterator gsi;
+ int discriminator;
+
+ if (locus == UNKNOWN_LOCATION)
+ return;
+
+ expanded_location locus_e = expand_location (locus);
+
+ discriminator = next_discriminator_for_locus (locus_e.line);
+
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple *stmt = gsi_stmt (gsi);
+ location_t stmt_locus = gimple_location (stmt);
+ if (same_line_p (locus, &locus_e, stmt_locus))
+ gimple_set_location (stmt,
+ location_with_discriminator (stmt_locus, discriminator));
+ }
+}
+
+/* Assign discriminators to statement locations. */
static void
assign_discriminators (void)
@@ -1189,17 +1215,22 @@ assign_discriminators (void)
{
gimple *first = first_non_label_stmt (e->dest);
gimple *last = last_stmt (e->dest);
- if ((first && same_line_p (locus, &locus_e,
+
+ gimple *stmt_on_same_line = NULL;
+ if (first && same_line_p (locus, &locus_e,
gimple_location (first)))
- || (last && same_line_p (locus, &locus_e,
- gimple_location (last))))
+ stmt_on_same_line = first;
+ else if (last && same_line_p (locus, &locus_e,
+ gimple_location (last)))
+ stmt_on_same_line = last;
+
+ if (stmt_on_same_line)
{
- if (e->dest->discriminator != 0 && bb->discriminator == 0)
- bb->discriminator
- = next_discriminator_for_locus (locus_e.line);
+ if (has_discriminator (gimple_location (stmt_on_same_line))
+ && !has_discriminator (locus))
+ assign_discriminator (locus, bb);
else
- e->dest->discriminator
- = next_discriminator_for_locus (locus_e.line);
+ assign_discriminator (locus, e->dest);
}
}
}
diff --git a/gcc/tree-pretty-print.cc b/gcc/tree-pretty-print.cc
index 33b12c7..e7a8c94 100644
--- a/gcc/tree-pretty-print.cc
+++ b/gcc/tree-pretty-print.cc
@@ -1455,6 +1455,7 @@ void
dump_location (pretty_printer *pp, location_t loc)
{
expanded_location xloc = expand_location (loc);
+ int discriminator = get_discriminator_from_loc (loc);
pp_left_bracket (pp);
if (xloc.file)
@@ -1465,6 +1466,11 @@ dump_location (pretty_printer *pp, location_t loc)
pp_decimal_int (pp, xloc.line);
pp_colon (pp);
pp_decimal_int (pp, xloc.column);
+ if (discriminator)
+ {
+ pp_string (pp, " discrim ");
+ pp_decimal_int (pp, discriminator);
+ }
pp_string (pp, "] ");
}
diff --git a/gcc/tree.cc b/gcc/tree.cc
index 756c14f..f8d24b5 100644
--- a/gcc/tree.cc
+++ b/gcc/tree.cc
@@ -14253,7 +14253,8 @@ set_block (location_t loc, tree block)
{
location_t pure_loc = get_pure_location (loc);
source_range src_range = get_range_from_loc (line_table, loc);
- return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, block);
+ unsigned discriminator = get_discriminator_from_loc (line_table, loc);
+ return COMBINE_LOCATION_DATA (line_table, pure_loc, src_range, block, discriminator);
}
location_t
@@ -14271,11 +14272,14 @@ set_source_range (tree expr, source_range src_range)
if (!EXPR_P (expr))
return UNKNOWN_LOCATION;
- location_t pure_loc = get_pure_location (EXPR_LOCATION (expr));
+ location_t expr_location = EXPR_LOCATION (expr);
+ location_t pure_loc = get_pure_location (expr_location);
+ unsigned discriminator = get_discriminator_from_loc (expr_location);
location_t adhoc = COMBINE_LOCATION_DATA (line_table,
pure_loc,
src_range,
- NULL);
+ NULL,
+ discriminator);
SET_EXPR_LOCATION (expr, adhoc);
return adhoc;
}
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 9bdd5b9..50207ca 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -757,6 +757,7 @@ struct GTY(()) location_adhoc_data {
location_t locus;
source_range src_range;
void * GTY((skip)) data;
+ unsigned discriminator;
};
struct htab;
@@ -1034,12 +1035,14 @@ LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set)
}
extern location_t get_combined_adhoc_loc (line_maps *, location_t,
- source_range, void *);
+ source_range, void *, unsigned);
extern void *get_data_from_adhoc_loc (const line_maps *, location_t);
+extern unsigned get_discriminator_from_adhoc_loc (const line_maps *, location_t);
extern location_t get_location_from_adhoc_loc (const line_maps *,
location_t);
extern source_range get_range_from_loc (line_maps *set, location_t loc);
+extern unsigned get_discriminator_from_loc (line_maps *set, location_t loc);
/* Get whether location LOC is a "pure" location, or
whether it is an ad-hoc location, or embeds range information. */
@@ -1058,9 +1061,10 @@ inline location_t
COMBINE_LOCATION_DATA (class line_maps *set,
location_t loc,
source_range src_range,
- void *block)
+ void *block,
+ unsigned discriminator)
{
- return get_combined_adhoc_loc (set, loc, src_range, block);
+ return get_combined_adhoc_loc (set, loc, src_range, block, discriminator);
}
extern void rebuild_location_adhoc_htab (class line_maps *);
diff --git a/libcpp/lex.cc b/libcpp/lex.cc
index 41f905de..a429a3d 100644
--- a/libcpp/lex.cc
+++ b/libcpp/lex.cc
@@ -1362,7 +1362,8 @@ get_location_for_byte_range_in_cur_line (cpp_reader *pfile,
location_t combined_loc = COMBINE_LOCATION_DATA (pfile->line_table,
start_loc,
src_range,
- NULL);
+ NULL,
+ 0);
return combined_loc;
}
@@ -2028,7 +2029,7 @@ warn_about_normalization (cpp_reader *pfile,
CPP_BUF_COLUMN (pfile->buffer,
pfile->buffer->cur));
loc = COMBINE_LOCATION_DATA (pfile->line_table,
- loc, tok_range, NULL);
+ loc, tok_range, NULL, 0);
}
encoding_rich_location rich_loc (pfile, loc);
@@ -4256,7 +4257,7 @@ _cpp_lex_direct (cpp_reader *pfile)
result->src_loc = COMBINE_LOCATION_DATA (pfile->line_table,
result->src_loc,
- tok_range, NULL);
+ tok_range, NULL, 0);
}
return result;
diff --git a/libcpp/line-map.cc b/libcpp/line-map.cc
index 391f1d4..50e8043 100644
--- a/libcpp/line-map.cc
+++ b/libcpp/line-map.cc
@@ -67,7 +67,8 @@ location_adhoc_data_hash (const void *l)
return ((hashval_t) lb->locus
+ (hashval_t) lb->src_range.m_start
+ (hashval_t) lb->src_range.m_finish
- + (size_t) lb->data);
+ + (size_t) lb->data
+ + lb->discriminator);
}
/* Compare function for location_adhoc_data hashtable. */
@@ -82,7 +83,8 @@ location_adhoc_data_eq (const void *l1, const void *l2)
return (lb1->locus == lb2->locus
&& lb1->src_range.m_start == lb2->src_range.m_start
&& lb1->src_range.m_finish == lb2->src_range.m_finish
- && lb1->data == lb2->data);
+ && lb1->data == lb2->data
+ && lb1->discriminator == lb2->discriminator);
}
/* Update the hashtable when location_adhoc_data_map::data is reallocated.
@@ -127,13 +129,17 @@ static bool
can_be_stored_compactly_p (line_maps *set,
location_t locus,
source_range src_range,
- void *data)
+ void *data,
+ unsigned discriminator)
{
/* If there's an ad-hoc pointer, we can't store it directly in the
location_t, we need the lookaside. */
if (data)
return false;
+ if (discriminator != 0)
+ return false;
+
/* We only store ranges that begin at the locus and that are sufficiently
"sane". */
if (src_range.m_start != locus)
@@ -168,7 +174,8 @@ location_t
get_combined_adhoc_loc (line_maps *set,
location_t locus,
source_range src_range,
- void *data)
+ void *data,
+ unsigned discriminator)
{
struct location_adhoc_data lb;
struct location_adhoc_data **slot;
@@ -186,7 +193,7 @@ get_combined_adhoc_loc (line_maps *set,
|| pure_location_p (set, locus));
/* Consider short-range optimization. */
- if (can_be_stored_compactly_p (set, locus, src_range, data))
+ if (can_be_stored_compactly_p (set, locus, src_range, data, discriminator))
{
/* The low bits ought to be clear. */
linemap_assert (pure_location_p (set, locus));
@@ -206,15 +213,16 @@ get_combined_adhoc_loc (line_maps *set,
when locus == start == finish (and data is NULL). */
if (locus == src_range.m_start
&& locus == src_range.m_finish
- && !data)
+ && !data && discriminator == 0)
return locus;
- if (!data)
+ if (!data && discriminator == 0)
set->num_unoptimized_ranges++;
lb.locus = locus;
lb.src_range = src_range;
lb.data = data;
+ lb.discriminator = discriminator;
slot = (struct location_adhoc_data **)
htab_find_slot (set->location_adhoc_data_map.htab, &lb, INSERT);
if (*slot == NULL)
@@ -261,6 +269,13 @@ get_data_from_adhoc_loc (const class line_maps *set, location_t loc)
return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].data;
}
+unsigned
+get_discriminator_from_adhoc_loc (const class line_maps *set, location_t loc)
+{
+ linemap_assert (IS_ADHOC_LOC (loc));
+ return set->location_adhoc_data_map.data[loc & MAX_LOCATION_T].discriminator;
+}
+
/* Return the location for the adhoc loc. */
location_t
@@ -306,6 +321,15 @@ get_range_from_loc (line_maps *set,
return source_range::from_location (loc);
}
+unsigned
+get_discriminator_from_loc (line_maps *set,
+ location_t loc)
+{
+ if (IS_ADHOC_LOC (loc))
+ return get_discriminator_from_adhoc_loc (set, loc);
+ return 0;
+}
+
/* Get whether location LOC is a "pure" location, or
whether it is an ad-hoc location, or embeds range information. */