https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69092

            Bug ID: 69092
           Summary: basic_string constructor and throwing iterators
           Product: gcc
           Version: 6.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rs2740 at gmail dot com
  Target Milestone: ---

basic_string(ForwardIt, ForwardIt) eventually calls _S_copy_chars(), which is
marked _GLIBCXX_NOEXCEPT, so an exception thrown from an iterator operation
inside _S_copy_chars() results in a call to std::terminate().

For instance:

#include<string>
#include<iterator>

struct hate_T_iterator : std::iterator<std::forward_iterator_tag, char> {
    explicit hate_T_iterator(char* p) : p(p) {}
    char* p;
    hate_T_iterator& operator++() { ++p; return *this; }
    hate_T_iterator operator++(int) { auto r = *this; ++*this; return r; }
    char& operator*() const { if(*p == 'T') throw 1; else return *p; }
    char* operator->() const { return p; }
    bool operator== (hate_T_iterator other) const { return p == other.p;}
    bool operator!= (hate_T_iterator other) const { return p != other.p;}
};

int main(){
    char test_str[4] = "ATA";
    try {
        std::string s(hate_T_iterator{test_str}, hate_T_iterator{test_str+3});
    }
    catch(...) {
    }
}

Reply via email to