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
This commit is contained in:
Richard Biener 2014-04-07 08:38:23 +00:00 committed by Richard Biener
parent f2e9b72b1a
commit 308173e30b
6 changed files with 39 additions and 9 deletions

View File

@ -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

View File

@ -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.

View File

@ -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;
}

View File

@ -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" } } */

View File

@ -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;
}

View File

@ -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);