This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/33504] New: redundant temporary object is created
- From: "alexey dot starovoytov at sun dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 19 Sep 2007 21:43:00 -0000
- Subject: [Bug c++/33504] New: redundant temporary object is created
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
looks like there is an ugly bug in g++ front-end.
the problem can be demonstrated by the existing testcase:
ext/pb_ds/regression/trie_data_map_rand.cc
if you apply the following diff:
.../libstdc++-v3/testsuite/util/regression/rand/assoc/detail/ $ svn di
Index: insert_fn_imps.hpp
===================================================================
--- insert_fn_imps.hpp (revision 10694)
+++ insert_fn_imps.hpp (working copy)
@@ -58,6 +58,7 @@
value_type v = test_traits::generate_value(m_g, m_m);
m_alloc.set_throw_prob(m_tp);
const_key_reference r_k = test_traits::extract_key(v);
+ std::cerr << (int*)0xDEADbeaf << std::endl;
typename cntnr::const_point_iterator found_it = m_p_c->find(r_k);
const bool existed = (found_it != m_p_c->end());
const std::pair<typename cntnr::point_iterator, bool> ins_ret =
m_p_c->insert(v);
trie_data_map_rand.cc will fail on sparc and x86 after random number
of 'deadbeaf' printouts compiled with -O0.
Looks like at least 4.2.x and most recent trunk are affected.
The above extra diff to the existing testcase just uncovers the problem.
Looks like the bug was there for long time and folks were lucky
not to hit it earlier.
Look into the -fdump-tree-gimple dump for the following function:
static typename Cntnr::const_key_reference
pb_ds::test::detail::regression_test_type_traits<Cntnr>::extract_key
(typename Cntnr::const_reference)
there you'll see that temporary object of 'struct pair' is created
and it's address passed into extract_key_imp() function.
The source code comes from here:
.../libstdc++-v3/testsuite/util/regression/trait/assoc/ $ svn di
Index: type_trait.hpp
===================================================================
--- type_trait.hpp (revision 10694)
+++ type_trait.hpp (working copy)
@@ -79,7 +79,7 @@
static const_key_reference
extract_key(const_reference r_val)
- { return extract_key_imp(r_val); }
+ { return extract_key_imp(r_val); } // bug here
private:
typedef typename cntnr::allocator::template rebind<basic_type>::other
The mechanism of the bug is the following:
"r_k = test_traits::extract_key(v);" in insert_fn_imps.hpp eventually calls
"extract_key()" from type_trait.hpp above which creates a temp variable of
type "struct pair<basic_type,basic_type>" on stack and calls extract_key_imp()
with the address of that variable.
The returned address is actually the address of that stack temp variable,
so at the end 'r_k' points to already freed stack space.
Without '0xDEADbeaf' printout "m_p_c->find(r_k);" has a shorter
call chain than "extract_key()" and "find(r_k)" doesn't overwrite that
stack space, 'r_k' value is valid and everything works.
'deadbeaf' printout reuses that stack space and when it comes to
"m_p_c->find(r_k)", 'r_k' points to trash and 'find' sooner or later
coredumps.
Unfortunately I wasn't able to create a shorter testcase out of
trie_data_map_rand.cc
Various combination of
detail::regression_test_type_traits<s>::extract_key (ref);
with different 's' and 'ref' didn't expose the creation of such
extra temp variable.
As the summary 'extract_key' is supposed to look like:
static typename Cntnr::const_key_reference
pb_ds::test::detail::regression_test_type_traits<Cntnr>::extract_key
(typename Cntnr::const_reference) [with Cntnr = ...] (r_val)
{
const struct basic_type & D.82957;
const struct basic_type & D.82958;
D.82958 = extract_key_imp (r_val);
D.82957 = D.82958;
return D.82957;
}
incorrect 'extract_key' may look like:
static typename Cntnr::const_key_reference
pb_ds::test::detail::regression_test_type_traits<Cntnr>::extract_key
(typename Cntnr::const_reference) [with Cntnr = ...] (r_val)
{
const struct basic_type & D.107098;
const struct pair D.107097;
struct pair * D.107099;
const struct basic_type & D.107100;
__comp_ctor (&D.107097, r_val);
try
{
D.107100 = extract_key_imp (&D.107097);
D.107098 = D.107100;
return D.107098;
}
finally
{
D.107099 = (struct pair *) &D.107097;
__comp_dtor (D.107099);
}
}
--
Summary: redundant temporary object is created
Product: gcc
Version: 4.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: alexey dot starovoytov at sun dot com
GCC build triplet: sll
GCC host triplet: all
GCC target triplet: all
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33504