Hi. This is actually not a question, this is a bug report. Visual Studios's bugtracker is broken for me, so it is not possible to send a bug through bugtracker, so I send it here. If boost recursive variant is used VS 2015 14.0.25422.01 Update 3 generates
incorrect code for ARM platform in release build. Steps to reproduce:
1) Take boost 1.60.0. It is essential because boost::detail::variant::forced_return_no_return is an empty function in this version. If the function has non empty body (std:;sbort() or volatile int i = 0), then templates are inlined in a different way
and bug goes away.
2) In a windows runtime component write following code. It is essential that this code is in a library, if it is placed in an application, then problem does not reproduce.
3) Call that code from an application.
4) Build Release build and run it on an ARM phone.
The application will crash either with access violation or with stack overflow error. This happens because function body is trucated, execution reaches end of part which is present and continues to execute code which belongs to the next function. Here is
what happens in disassembly:
// We enter in-to a function here
6F7E230C F7FF F8D0 bl __security_pop_cookie (6F7E14B0h)
6F7E2310 E8BD 0870 pop {r4-r6,r11}
6F7E2314 F85D FB14 ldr pc,[sp],#0x14
226: {
227:
228: // ...applying the appropriate case:
229: # define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
230: case (Which::value + (N)): \
231: return (visitation_impl_invoke)( \
232: internal_which, visitor, storage \
233: , static_cast<BOOST_PP_CAT(T,N)*>(0) \
234: , no_backup_flag, 1L \
235: ); \
236: /**/
237:
238: BOOST_PP_REPEAT(
6F7E2318 6813 ldr r3,[r2]
6F7E231A 6819 ldr r1,[r3]
6F7E231C 680A ldr r2,[r1]
6F7E231E 2A00 cmp r2,#0
226: {
227:
228: // ...applying the appropriate case:
229: # define BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE(z, N, _) \
230: case (Which::value + (N)): \
231: return (visitation_impl_invoke)( \
232: internal_which, visitor, storage \
233: , static_cast<BOOST_PP_CAT(T,N)*>(0) \
234: , no_backup_flag, 1L \
235: ); \
236: /**/
237:
238: BOOST_PP_REPEAT(
6F7E2320 DA00 bge boost::detail::variant::visitation_impl<boost::mpl::int_<0>,boost::detail::variant::visitation_impl_step<boost::mpl::l_iter<boost::mpl::l_item<boost::mpl::long_<4>,int,boost::mpl::l_item<boost::mpl::long_<3>,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,boost::mpl::l_item<boost::mpl::long_<2>,std::vector<unsigned char,std::allocator<unsigned char> >,boost::mpl::l_item<boost::mpl::long_<1>,boost::recursive_wrapper<std::vector<boost::variant<boost::detail::variant::recursive_flag<int>,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::vector<unsigned char,std::allocator<unsigned char> >,std::vector<boost::recursive_variant_,std::allocator<boost::recursive_variant_> >,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boo+0DCh (6F7E2324h)
6F7E2322 43D2 mvns r2,r2
// Here is a problem. This tbb instruction is broken. If r2 is 1 then everything is OK. But otherwice we jump to 6F7E234E
6F7E2324 E8DF F002 tbb [pc,r2]
6F7E2328 1309 asrs r1,r1,#0xC
6F7E232A 1313 asrs r3,r2,#0xC
6F7E232C 1313 asrs r3,r2,#0xC
6F7E232E 1313 asrs r3,r2,#0xC
6F7E2330 1313 asrs r3,r2,#0xC
6F7E2332 1313 asrs r3,r2,#0xC
6F7E2334 1313 asrs r3,r2,#0xC
6F7E2336 1313 asrs r3,r2,#0xC
6F7E2338 0909 lsrs r1,r1,#4
6F7E233A 6848 ldr r0,[r1,#4]
6F7E233C 6821 ldr r1,[r4]
6F7E233E F000 F969 bl std::operator==<boost::variant<boost::detail::variant::recursive_flag<int>,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::vector<unsigned char,std::allocator<unsigned char> >,std::vector<boost::recursive_variant_,std::allocator<boost::recursive_variant_> >,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_,boost::detail::variant::void_>,std::allocator<boost::variant<boost::detail::variant::recursive_flag<int>,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::vector<unsigned char,std::allocator<unsigned char> >,std::vector<boost::recursive_variant_,std::allocator<boos (6F7E2614h)
239: BOOST_VARIANT_VISITATION_UNROLLING_LIMIT
240: , BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
241: , _
242: )
243:
244: # undef BOOST_VARIANT_AUX_APPLY_VISITOR_STEP_CASE
245:
246: default: break;
247: }
248:
249: // If not handled in this iteration, continue unrolling:
250: typedef mpl::int_<
251: Which::value + (BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
252: > next_which;
253:
254: typedef BOOST_PP_CAT(step, BOOST_VARIANT_VISITATION_UNROLLING_LIMIT)
255: next_step;
256:
257: typedef typename next_step::type next_type;
258: typedef typename is_same< next_type,apply_visitor_unrolled >::type
259: is_apply_visitor_unrolled;
260:
261: return visitation_impl(
262: internal_which, logical_which
263: , visitor, storage
264: , is_apply_visitor_unrolled()
265: , no_backup_flag
266: , static_cast<next_which*>(0), static_cast<next_step*>(0)
267: );
268: }
6F7E2342 F7FF F8B5 bl __security_pop_cookie (6F7E14B0h)
6F7E2346 E8BD 0870 pop {r4-r6,r11}
6F7E234A F85D FB14 ldr pc,[sp],#0x14
--- No source file -------------------------------------------------------------
// We jump here. This is not a function, this is just portion of junk followed by next function.
$LN1100:
6F7E234E 0000 movs r0,r0
6F7E2350 0000 movs r0,r0
6F7E2352 0000 movs r0,r0
6F7E2354 0000 movs r0,r0
6F7E2356 0000 movs r0,r0
6F7E2358 0000 movs r0,r0
6F7E235A 0000 movs r0,r0
6F7E235C 0000 movs r0,r0
6F7E235E 0000 movs r0,r0
--- c:\users\kibergus\documents\visual studio 2015\projects\vs_bug_example\runtimecomponent\boost\variant\detail\visitation_impl.hpp
168: }
169:
170: ///////////////////////////////////////////////////////////////////////////////
171: // (detail) function template visitation_impl
172: //
173: // Invokes the given visitor on the type in the given variant storage.
174: //
175:
176: template <
177: typename W, typename S
178: , typename Visitor, typename VPCV
179: , typename NBF
180: >
181: inline
182: BOOST_VARIANT_AUX_GENERIC_RESULT_TYPE(typename Visitor::result_type)
183: visitation_impl(
184: int, int, Visitor&, VPCV
185: , mpl::true_ // is_apply_visitor_unrolled
186: , NBF, W* = 0, S* = 0
187: )
188: {
6F7E2360 E92D 4800 push {r11,lr}
6F7E2364 46EB mov r11,sp
189: // should never be here at runtime!
190: typedef typename Visitor::result_type result_type;
191: return ::boost::detail::variant::forced_return< result_type >();
6F7E2366 F000 F83B bl boost::detail::variant::forced_return<void> (6F7E23E0h)