dwarf2out.c (comp_dir_string): cached_wd could be set to both a heap string and a...
authorThomas Otto <thomas.otto@pdv-fs.de>
Mon, 25 Mar 2019 13:50:46 +0000 (13:50 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 25 Mar 2019 13:50:46 +0000 (13:50 +0000)
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

gcc/ChangeLog
gcc/dwarf2out.c

index 0a93882d6daf7a4927899b18c270e94cb78b2f95..d2db34b7189f58bbe7fdd366883532907015239b 100644 (file)
@@ -1,3 +1,10 @@
+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
index 251fff7b9ae961cd49196077624129ad45db58be..ae8bdee99818e7a59a4c961026897cb7d8c13918 100644 (file)
@@ -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;
 }