aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-04-07 08:38:23 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-04-07 08:38:23 +0000
commit308173e30bff3cb179f75fdf4b96310482dc6846 (patch)
treec873482c24ce3a1ea1806d1b868c0d6d7ce57885
parentf2e9b72b1a987adc31f0c0f56c7e2610de60fc43 (diff)
downloadgcc-308173e30bff3cb179f75fdf4b96310482dc6846.zip
gcc-308173e30bff3cb179f75fdf4b96310482dc6846.tar.gz
gcc-308173e30bff3cb179f75fdf4b96310482dc6846.tar.bz2
re PR c++/60750 (double free after std::move on string inside throw when compiled with optimization)
2014-04-07 Richard Biener <rguenther@suse.de> PR middle-end/60750 * tree-ssa-operands.c (maybe_add_call_vops): Also add VDEFs for noreturn calls. * tree-cfgcleanup.c (fixup_noreturn_call): Do not remove VDEFs. * g++.dg/torture/pr60750.C: New testcase. * gcc.dg/tree-ssa/20040517-1.c: Adjust. From-SVN: r209179
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/torture/pr60750.C21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c5
-rw-r--r--gcc/tree-cfgcleanup.c3
-rw-r--r--gcc/tree-ssa-operands.c6
6 files changed, 39 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 80a39f8..91ec83b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2014-04-07 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/60750
+ * tree-ssa-operands.c (maybe_add_call_vops): Also add VDEFs
+ for noreturn calls.
+ * tree-cfgcleanup.c (fixup_noreturn_call): Do not remove VDEFs.
+
2014-04-06 John David Anglin <danglin@gcc.gnu.org>
PR debug/55794
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7df316e..a7c7c78 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2014-04-07 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/60750
+ * g++.dg/torture/pr60750.C: New testcase.
+ * gcc.dg/tree-ssa/20040517-1.c: Adjust.
+
2014-04-06 Andreas Schwab <schwab@linux-m68k.org>
* gcc.c-torture/compile/pr60655-1.c: Use __SIZE_TYPE__ for size_t.
diff --git a/gcc/testsuite/g++.dg/torture/pr60750.C b/gcc/testsuite/g++.dg/torture/pr60750.C
new file mode 100644
index 0000000..a344bd7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr60750.C
@@ -0,0 +1,21 @@
+// { dg-do run }
+// { dg-options "-std=c++11" }
+
+#include <string>
+#include <stdexcept>
+
+const std::string err_prefix = "Problem: ";
+void thrower (std::string msg)
+{
+ throw std::runtime_error(err_prefix + std::move(msg));
+}
+
+int main(int argc, char **argv)
+{
+ try {
+ std::string base = "hello";
+ thrower(std::move(base));
+ } catch (const std::runtime_error &e) {
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c
index 99b27ce..b49cf64 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c
@@ -16,6 +16,7 @@ void bar (void)
/* We used to treat malloc functions like pure and const functions, but
malloc functions may clobber global memory. Only the function result
does not alias any other pointer.
- Hence, we must have a VDEF for a before and after the call to foo(). */
-/* { dg-final { scan-tree-dump-times "VDEF" 2 "alias"} } */
+ Hence, we must have a VDEF for a before and after the call to foo().
+ And one after the call to abort(). */
+/* { dg-final { scan-tree-dump-times "VDEF" 3 "alias"} } */
/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 08401dd..b7882cf 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -586,9 +586,6 @@ fixup_noreturn_call (gimple stmt)
update_stmt (stmt);
changed = true;
}
- /* Similarly remove VDEF if there is any. */
- else if (gimple_vdef (stmt))
- update_stmt (stmt);
return changed;
}
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 352ccca4..c525fe5 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -648,10 +648,8 @@ maybe_add_call_vops (struct function *fn, gimple stmt)
call-clobbered. */
if (!(call_flags & ECF_NOVOPS))
{
- /* A 'pure' or a 'const' function never call-clobbers anything.
- A 'noreturn' function might, but since we don't return anyway
- there is no point in recording that. */
- if (!(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
+ /* A 'pure' or a 'const' function never call-clobbers anything. */
+ if (!(call_flags & (ECF_PURE | ECF_CONST)))
add_virtual_operand (fn, stmt, opf_def);
else if (!(call_flags & ECF_CONST))
add_virtual_operand (fn, stmt, opf_use);