Bug 79694

Summary: libstdc++ headers: explicit specialization of function must precede its first use
Product: [Retired] Red Hat Linux Reporter: Sysoltsev Slawa <vyatcheslav.sysoltsev>
Component: gcc3Assignee: Jakub Jelinek <jakub>
Status: CLOSED UPSTREAM QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 8.0CC: bkoz
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2004-10-01 14:57:26 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
Patch with changes to <fstream> to made it more correct according C++ standard none

Description Sysoltsev Slawa 2002-12-15 13:21:04 UTC
Description of problem:
In file /usr/include/c++/3.2/fstream:292 there is declaration:
  template<>
    basic_filebuf<char>::int_type
    basic_filebuf<char>::_M_underflow_common(bool __bump);

which is explicit specialization of std::basic_filebuf<_CharT, 
_Traits>::_M_underflow_common member function.

But this function is used previously in this file in virtual int_type underflow
() function in its body (line 140):
      virtual int_type
      underflow() { return _M_underflow_common(false); }


This is violation of ISO C++ standards, paragraph 14.7.3, clause 6:

 If a template, a member template or the member of a class template is 
explicitly specialized then that specialization shall be declared before the 
first use of that specialization that would cause an implicit instantiation
to take place, in every translation unit in which such a use occurs; no 
diagnostic is required. If the program does not provide a definition for an 
explicit specialization and either the specialization is used in a way that 
would cause an implicit instantiation to take place or the member is a virtual 
member function, the program is illformed, no diagnostic required. 

It is ambiguous what method will be called from underflow function  
implicitly instantiated common _M_underflow_common or consequent 
specialization  thats why such code should be restricted by C++ compiler.

GNU C++ compiler accepts this code violating C++ standards, but bigger problem 
here is that erroneous code is in system headers. Custom compiler couldn't 
compile this.

Error here has to be worked around to increase Red Hat linux portability: in 
header /usr/include/c++/3.2/fstream you should provide bodies for underflow 
and uflow functions after _M_underflow_common specialization (after line 299) 
or not to provide them at all.


Version-Release number of selected component (if applicable):


How reproducible:
Every time

Steps to Reproduce:
1. GNU C++ compiler allow described construction, you won't be able to 
reproduce it with standart compiler.
    
Actual results:
compilation error compiling test case which uses <fstream>:
/usr/include/c++/3.2/fstream(292): error: explicit specialization of 
function "std::basic_filebuf<_CharT, _Traits>::_M_underflow_c
ommon [with _CharT=char, _Traits=std::char_traits<char>]" must precede its 
first use
      basic_filebuf<char>::_M_underflow_common(bool __bump);


Expected results:
Succesfull compilation with using <fstream> header.

Additional info:
I'll try to attach patch for <fstream> with changes I was speaking about.

Comment 1 Sysoltsev Slawa 2002-12-15 14:03:32 UTC
Created attachment 88743 [details]
Patch with changes to <fstream> to made it more correct according C++ standard

Comment 2 Benjamin Kosnik 2003-01-11 01:21:43 UTC
This patch applies to gcc-3_3-branch and gcc-3_2-branch, but not mainline.

2003-01-10  Benjamin Kosnik  <bkoz>
	    Sysoltsev Slawa  <Vyatcheslav.Sysoltsev>

	PR libstdc++/
	* include/std/std_fstream.h (basic_filebuf::uflow): Declare.
	(basic_filebuf::underflow): Declare.
	Move definitions.


Index: include/std/std_fstream.h
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/include/std/std_fstream.h,v
retrieving revision 1.15
diff -c -p -r1.15 std_fstream.h
*** include/std/std_fstream.h	27 Dec 2002 23:03:03 -0000	1.15
--- include/std/std_fstream.h	11 Jan 2003 00:51:37 -0000
*************** namespace std
*** 234,244 ****
  
        // [documentation is inherited]
        virtual int_type
!       underflow() { return _M_underflow_common(false); }
  
        // [documentation is inherited]
        virtual int_type
!       uflow() { return _M_underflow_common(true); }
  
        // [documentation is inherited]
        virtual int_type
--- 234,244 ----
  
        // [documentation is inherited]
        virtual int_type
!       underflow();
  
        // [documentation is inherited]
        virtual int_type
!       uflow();
  
        // [documentation is inherited]
        virtual int_type
*************** namespace std
*** 431,437 ****
        }
      };
  
!   // Explicit specializations, defined in src/fstream.cc.
    template<> 
      basic_filebuf<char>::int_type 
      basic_filebuf<char>::_M_underflow_common(bool __bump);
--- 431,437 ----
        }
      };
  
!   // Explicit specialization declarations, defined in src/fstream.cc.
    template<> 
      basic_filebuf<char>::int_type 
      basic_filebuf<char>::_M_underflow_common(bool __bump);
*************** namespace std
*** 441,446 ****
--- 441,458 ----
      basic_filebuf<wchar_t>::int_type 
      basic_filebuf<wchar_t>::_M_underflow_common(bool __bump);
   #endif
+ 
+   // Generic definitions.
+   template <typename _CharT, typename _Traits>
+     basic_filebuf<_CharT, _Traits>::int_type
+     basic_filebuf<_CharT, _Traits>::underflow() 
+     { return _M_underflow_common(false); }
+ 
+   template <typename _CharT, typename _Traits>
+     basic_filebuf<_CharT, _Traits>::int_type
+     basic_filebuf<_CharT, _Traits>::uflow() 
+     { return _M_underflow_common(true); }
+ 
  
    // [27.8.1.5] Template class basic_ifstream
    /**


Comment 3 Benjamin Kosnik 2004-10-01 14:57:26 UTC
Fixed in gcc-3.4.x. Intel compilers are much more strict about this.

I believe this was fixed in 3.3.x as well. 

Closing, reopen if believe I am in error.

-benjamin