Bug 59568 - complex type operator>> does not set eofbit for input streams.
Summary: complex type operator>> does not set eofbit for input streams.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.8.1
: P3 minor
Target Milestone: 6.5
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-12-20 21:57 UTC by Physeterm
Modified: 2017-12-14 12:03 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 6.4.0, 7.2.0
Last reconfirmed: 2017-12-12 00:00:00


Attachments
g++ -v (589 bytes, text/plain)
2013-12-20 21:57 UTC, Physeterm
Details
test program (394 bytes, text/x-c++src)
2013-12-20 21:59 UTC, Physeterm
Details
input test file (92 bytes, text/plain)
2013-12-20 22:01 UTC, Physeterm
Details
output (124 bytes, text/plain)
2013-12-20 22:02 UTC, Physeterm
Details
make command (229 bytes, text/plain)
2013-12-20 22:03 UTC, Physeterm
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Physeterm 2013-12-20 21:57:16 UTC
Created attachment 31489 [details]
g++ -v

(Actually, it is set, it's just cleared before the return to caller)

The problem as I understand it is that the call to __is.putback(__ch)
resets the eofbit to 0, (in C++11) after a valid eof has been detected.
The next extraction operation fails on attempting to get a char type
but the eofbit is not set to 1.

This precludes the ability to do error checking on input files.

A simple solution I think would be to test for the eofbit before
attempting the putback. ie:

   else 
   {
      if (! __is.eof()) {
         __is.putback(__ch);
         __is >> __re_x;
         __x = __re_x;
      }
   }
   return __is;
}

in file /usr/include/c++/4.8.1/complex (This only fixes int types)
Comment 1 Physeterm 2013-12-20 21:59:59 UTC
Created attachment 31490 [details]
test program
Comment 2 Physeterm 2013-12-20 22:01:09 UTC
Created attachment 31491 [details]
input test file
Comment 3 Physeterm 2013-12-20 22:02:29 UTC
Created attachment 31492 [details]
output
Comment 4 Physeterm 2013-12-20 22:03:31 UTC
Created attachment 31493 [details]
make command
Comment 5 Jonathan Wakely 2017-12-12 19:26:48 UTC
Reduced:

#include <sstream>
#include <complex>
#include <assert.h>

int main ()
{
  std::istringstream in;
  std::complex<double> c;
  in >> c;
  assert(in.fail());
  assert(in.eof());
}
Comment 6 Jonathan Wakely 2017-12-13 11:20:29 UTC
The simplest fix is just:

--- a/libstdc++-v3/include/std/complex
+++ b/libstdc++-v3/include/std/complex
@@ -495,6 +495,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _Tp __re_x, __im_x;
       _CharT __ch;
       __is >> __ch;
+      if (!__is)
+       return __is;
       if (__ch == '(')
        {
          __is >> __re_x >> __ch;


i.e. don't use putback if we didn't extract a character, so don't clear the eofbit unless there's actually something to putback.

But the current implementation has other problems, like not doing a putback for the character extracted when a ',' or ')' is not found.

This is closely related to https://wg21.link/lwg2714
Comment 7 Jonathan Wakely 2017-12-13 17:02:46 UTC
Author: redi
Date: Wed Dec 13 17:02:14 2017
New Revision: 255608

URL: https://gcc.gnu.org/viewcvs?rev=255608&root=gcc&view=rev
Log:
PR libstdc++/59568 fix error handling for std::complex stream extraction

	PR libstdc++/59568
	* include/std/complex (operator>>): Implement proposed resolution to
	LWG 2714. Use putback if and only if a character has been successfully
	extracted but isn't a delimiter. Use ctype::widen and traits::eq when
	testing if extracted characters match delimiters.
	* testsuite/26_numerics/complex/dr2714.cc: New test.

Added:
    trunk/libstdc++-v3/testsuite/26_numerics/complex/dr2714.cc
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/std/complex
Comment 8 Jonathan Wakely 2017-12-13 17:08:08 UTC
Fixed for GCC 8.
Comment 9 Jonathan Wakely 2017-12-14 11:53:34 UTC
Author: redi
Date: Thu Dec 14 11:53:02 2017
New Revision: 255633

URL: https://gcc.gnu.org/viewcvs?rev=255633&root=gcc&view=rev
Log:
PR libstdc++/59568 don't use putback or update value when extraction fails

	PR libstdc++/59568
	* include/std/complex (operator>>): Only use putback if a character
	was successfully extracted and only set the value if a number was
	successfully extracted.
	* testsuite/26_numerics/complex/inserters_extractors/char/59568.cc:
	New test.

Added:
    branches/gcc-7-branch/libstdc++-v3/testsuite/26_numerics/complex/inserters_extractors/char/59568.cc
Modified:
    branches/gcc-7-branch/libstdc++-v3/ChangeLog
    branches/gcc-7-branch/libstdc++-v3/include/std/complex
Comment 10 Jonathan Wakely 2017-12-14 12:02:12 UTC
Author: redi
Date: Thu Dec 14 12:01:40 2017
New Revision: 255634

URL: https://gcc.gnu.org/viewcvs?rev=255634&root=gcc&view=rev
Log:
PR libstdc++/59568 don't use putback or update value when extraction fails

	PR libstdc++/59568
	* include/std/complex (operator>>): Only use putback if a character
	was successfully extracted and only set the value if a number was
	successfully extracted.
	* testsuite/26_numerics/complex/inserters_extractors/char/59568.cc:
	New test.

Added:
    branches/gcc-6-branch/libstdc++-v3/testsuite/26_numerics/complex/inserters_extractors/char/59568.cc
Modified:
    branches/gcc-6-branch/libstdc++-v3/ChangeLog
    branches/gcc-6-branch/libstdc++-v3/include/std/complex
Comment 11 Jonathan Wakely 2017-12-14 12:03:43 UTC
Also fixed for 6.5 and 7.3