title: g++: -O1 -fdevirtualize -flto leading to problems on ifstream::widen
body: <p>If I place the following code in test.cpp</p>
  
  <pre><code>#include &lt;fstream&gt;
  int main(int argc, char ** argv) {
      std::ifstream a;
      do{
          a.widen('\n');
      }while(true);
  }
  </code></pre>
  
  <p>and invoke g++ with</p>
  
  <pre><code>g++ -O1 -fdevirtualize -flto -m64 -o out Tergiversative.cpp
  </code></pre>
  
  <p>on g++ version 5.1.0, then the produced executable crashes on the first call to <code>a.widen</code>. This doesn't happen if I wrap it in (for instance)</p>
  
  <pre><code>do{
      a.widen('\n');
  }while(false);
  </code></pre>
  
  <p>because it's just "flattened", but it does occur in any other loop, like</p>
  
  <pre><code>int i=2;
  do{
      a.widen('\n');
      i--;
  }while(i&gt;0);
  </code></pre>
  
  <p>Specifically, inside of <code>ctype&lt;char&gt;</code>'s <code>widen</code>, it gets to (from <code>locale_facets.h</code>)</p>
  
  <pre><code>widen(char __c) const{
    if (_M_widen_ok)
      return _M_widen[static_cast&lt;unsigned char&gt;(__c)];
    this-&gt;_M_widen_init();
    return this-&gt;do_widen(__c);
  }
  </code></pre>
  
  <p>it makes the virtual call to <code>do_widen</code>. When any of the above three flags are disabled, this works fine; when all three are enabled, then the vtable isn't populated correctly somehow, and the do_widen pointer is left NULL, giving a SIGSEGV at runtime. When it's not placed in a loop (or a trivial loop, like the do/while(false) ) then g++ transforms the above into a call to <code>std::basic_ios&lt;char,std::char_traits&lt;char&gt;&gt;::widen('\n')</code>, and nothing bad happens.</p>
  
  <p>Is there something wrong with my code that is invoking undefined behavior? Or is this a weird edge-case in some optimization that I'm triggering? I've only gotten it to occur when building 64-bit executable (<code>-m32</code> makes it run fine), and only with all of <code>-O1 -fdevirtualize -flto</code>. I checked each of the subflags turned by <code>-O1</code>, and they don't trigger it, so it must one of the "invisible" optimizations that checks the <code>-On</code> level directly. The <code>-fdevirtualize</code> being relevant would make sense given that it's a virtual call that's failing -- <strong><em>but</em></strong> the call hasn't been devirtualized. The vtable is just unpopulated.</p>
  
  <p>Any help understanding this would be appreciated!</p>