+2019-03-25 Thomas Otto <thomas.otto@pdv-fs.de>
+
+ * dwarf2out.c (comp_dir_string): cached_wd could be set to both a
+ heap string and a gc string, but since this variable is unknown to
+ ggc the gc string might get reused and corrupted. Fixed by always
+ using a heap string.
+
2019-03-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/89779
comp_dir_string (void)
{
const char *wd;
- char *wd1;
+ char *wd_plus_sep = NULL;
static const char *cached_wd = NULL;
if (cached_wd != NULL)
if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR)
{
- int wdlen;
-
- wdlen = strlen (wd);
- wd1 = ggc_vec_alloc<char> (wdlen + 2);
- strcpy (wd1, wd);
- wd1 [wdlen] = DIR_SEPARATOR;
- wd1 [wdlen + 1] = 0;
- wd = wd1;
+ size_t wdlen = strlen (wd);
+ wd_plus_sep = XNEWVEC (char, wdlen + 2);
+ strcpy (wd_plus_sep, wd);
+ wd_plus_sep [wdlen] = DIR_SEPARATOR;
+ wd_plus_sep [wdlen + 1] = 0;
+ wd = wd_plus_sep;
}
cached_wd = remap_debug_filename (wd);
+
+ /* remap_debug_filename can just pass through wd or return a new gc string.
+ These two types can't be both stored in a GTY(())-tagged string, but since
+ the cached value lives forever just copy it if needed. */
+ if (cached_wd != wd)
+ {
+ cached_wd = xstrdup (cached_wd);
+ if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR && wd_plus_sep != NULL)
+ free (wd_plus_sep);
+ }
+
return cached_wd;
}