summaryrefslogtreecommitdiff
path: root/gcc/dwarf2out.c
diff options
context:
space:
mode:
authorThomas Otto <thomas.otto@pdv-fs.de>2019-03-25 13:50:46 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-03-25 13:50:46 +0000
commitbe5ce04a6135e0aee4187ec1a1f167f403e0f856 (patch)
tree4b095e26986c7cb2a68e1c7f2f9da479827bc8ba /gcc/dwarf2out.c
parentd03f6e7bf321767f80c8474fb5aa8c60226bf445 (diff)
dwarf2out.c (comp_dir_string): cached_wd could be set to both a heap string and a gc string...
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. From-SVN: r269916
Diffstat (limited to 'gcc/dwarf2out.c')
-rw-r--r--gcc/dwarf2out.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 251fff7b9ae..ae8bdee9981 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -20702,7 +20702,7 @@ static const char *
comp_dir_string (void)
{
const char *wd;
- char *wd1;
+ char *wd_plus_sep = NULL;
static const char *cached_wd = NULL;
if (cached_wd != NULL)
@@ -20714,17 +20714,26 @@ comp_dir_string (void)
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;
}