Boost logo

Boost :

Subject: [boost] Help tracking down a GCC codegen issue
From: Matt Fischer (mattfischer84_at_[hidden])
Date: 2011-08-17 12:21:50


Hi all. I'm trying to compile boost under GCC for ARM, and am running
into an instance of some bad assembly code being generated. The
actual problem seems likely to be an issue with GCC itself, or
possibly some kind of modification that the vendor, CodeSourcery, made
to it. I've contacted them about the problem [1], but in order to
diagnose it, they need a reduced test case that doesn't involve the
boost library. I'm attempting to dig out the relevant code and use it
to construct a test case, but I'm having some trouble navigating the
boost codebase, and was wondering if anybody could provide some
assistance.

A program that illustrates the problem is the following (compiled on
Windows, using GCC 4.5.2 with Boost 1.40):

-----------------------------------------------------------

#include <boost/signal.hpp>

bool func()
{
 return false;
}

int main(int argc, char *argv[])
{
 boost::signal<bool ()> sig;
 sig.connect(func);
 bool result = sig();
}

-----------------------------------------------------------

Normally this works fine, but if I compile for GCC under ARM with
-mthumb -Os, one of the instantiated template functions has some bogus
assembly code in it (prepare for wall-of-text):

00000000 <boost::detail::postfix_increment_result<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool, bool
const&, boost::single_pass_traversal_tag>::type
boost::operator++<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool,
boost::single_pass_traversal_tag, bool const&, int
(boost::iterator_facade<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool,
boost::single_pass_traversal_tag, bool const&,
int>&, int)>:
   0: b537 push {r0, r1, r2, r4, r5, lr}
   2: 1c05 adds r5, r0, #0
   4: ac01 add r4, sp, #4
   6: 1c29 adds r1, r5, #0
   8: 1c20 adds r0, r4, #0
   a: f7ff fffe bl 0
<boost::detail::postfix_increment_result<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool, bool
const&, boost::single_pass_traversal_tag>::type
boost::operator++<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool,
boost::single_pass_traversal_tag, bool const&,
int>(boost::iterator_facade<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool,
boost::single_pass_traversal_tag, bool const&, int>&, int)>
   e: 1c28 adds r0, r5, #0
  10: f7ff fffe bl 0
<boost::detail::postfix_increment_result<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool, bool
const&, boost::single_pass_traversal_tag>::type
boost::operator++<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool,
boost::single_pass_traversal_tag, bool const&,
int>(boost::iterator_facade<boost::signals::detail::slot_call_iterator<boost::signals::detail::call_bound0<bool>::caller<boost::function<bool
()()> >, boost::signals::detail::named_slot_map_iterator>, bool,
boost::single_pass_traversal_tag, bool const&, int>&, int)>
  14: 7820 ldrb r0, [r4, #0]
  16: bc37 pop {r0, r1, r2, r4, r5}
  18: bc02 pop {r1}
  1a: 4708 bx r1

The error is on line 14 and 16: we load up the return value from this
function (a bool) into r0 in preparation for return, but then turn
around and pop off a bunch of values from the stack, placing one into
r0, which overwrites the return value and causes garbage to be
returned to the caller.

If I can produce a standalone test function that illustrates the
problem, the compiler folks can probably figure it out. I've been
trying to make one, but all of the template magic is making it
difficult for me to track down where this function is coming from in
the source code, and what a suitable standalone equivalent might be.
Is there anybody who is familiar with all of the slot code that might
be able to help out with this?

Thanks,
Matt

1. Original posting at
http://www.codesourcery.com/archives/arm-gnu/msg04302.html


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk