https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98753
--- Comment #15 from Martin Sebor <msebor at gcc dot gnu.org> --- The problem in attachment 50081 is different from the one reported in comment #0. The warning there is issued for the call to operator delete in the IL below as a result of the the test in bb 4 not being folded to false. The reason for that is that the call to std::__uninitialized_copy_a.isra() is not inlined. Forcing it to expand inline (e.g., by bumping up the -finline-limit= value) ends up with the desired result. The inability to propagate constant values across out-of-line function calls is a general problem, not something specific to this warning (or any others), and as far as I know doing something about it isn't on anyone's radar. What the IL does suggest though is that functions like __uninitialized_copy_a() might benefit from an annotation indicating that they have no effects unless the range delineated by their arguments is nonempty. With that, the call below could be eliminated altogether even without inlining. I'm not sure if it would be realistic to expect the IPA optimizer to do this without an annotation. GCC doesn't have such an annotation yet so the only way to avoid the warning here is by changing the code or compiler options. Using #pragma GCC diagnostic to suppress the warning should work. An alternative might be to explore providing an inline specialization of the std::uninitialized_copy template for the small_vector::iterator (which would mean defining it as a user-defined type) that returns when the range is empty. I didn't take the time to try that. Yet another possibility is to change libstdc++ to either declare std::__uninitialized_copy_a() inline, or change it to an inline wrapper around an std::__uninitialized_copy_a_impl() that returns immediately when the range is empty or calls the _impl() otherwise. Both seem to work. <bb 2> [local count: 1073741824]: sv_sv_ints ={v} {CLOBBER}; MEM[(struct _Vector_impl *)&sv_sv_ints + 48B].D.19786.buf_ = &sv_sv_ints.D.20517; MEM[(struct _Vector_impl_data *)&sv_sv_ints + 56B] ={v} {CLOBBER}; MEM[(struct _Vector_impl_data *)&sv_sv_ints + 56B]._M_start = 0B; MEM[(struct _Vector_impl_data *)&sv_sv_ints + 56B]._M_finish = 0B; MEM[(struct _Vector_impl_data *)&sv_sv_ints + 56B]._M_end_of_storage = 0B; MEM[(struct buffer_type *)&sv_sv_ints].free_ = 0; std::__uninitialized_copy_a.isra (0B, 0B, &MEM[(struct buffer_type *)&sv_sv_ints].data_); <bb 3> [local count: 354334802]: _29 = MEM[(struct vector *)&sv_sv_ints + 48B].D.20479._M_impl.D.19787._M_finish; _30 = MEM[(struct vector *)&sv_sv_ints + 48B].D.20479._M_impl.D.19787._M_start; if (_29 != _30) goto <bb 9>; [89.00%] else goto <bb 15>; [11.00%] <bb 4> [count: 0]: <L5>: _48 = __builtin_eh_pointer (11); __cxa_begin_catch (_48); _57 = MEM[(struct small_allocator *)&sv_sv_ints + 48B].buf_; if (&sv_sv_ints == _57) goto <bb 5>; [0.00%] else goto <bb 6>; [0.00%] <bb 5> [count: 0]: MEM[(struct buffer_type *)&sv_sv_ints].free_ = 1; goto <bb 7>; [0.00%] <bb 6> [count: 0]: operator delete (&MEM[(struct buffer_type *)&sv_sv_ints].data_); <bb 7> [count: 0]: __cxa_rethrow ();