
			        ProCompiler C++ 3.0.1

		  File: /opt/SUNWspro/SC2.0.1/README/c++_software
		  General information and Software Problems

==========================================================================

ProCompiler C++ 3.0.1  runs under Solaris 2.0 for x86 or later. 
This release of ProCompiler C++ 3.0.1 patch 101205-01 includes the 
bug fixes from C++ 3.0.2 and is based on USL Cfront, release 3.0.2.

=========================================================================
***************************************************************************
*                                NOTE                                     *
*                                                                         *
* See Section F, for important template information.                      *
*                                                                         *
* See Section G, "USL README for Cfront 3.0.2" at the end of this README   *
* for relevant information from USL's Cfront 3.0.2 README file.           *
***************************************************************************


A.  CHANGES FROM C++ 2.1 to C++ 3.0.1.
__________________________________________________________________________

1.  Two new options, -g0 and -nolib, have been added to C++ 3.0.1.  These
    options were not available in C++ 2.1 and C++ 3.0.  Refer to the man
    pages for details of these two options.

2.  Behavior Change: Debugging Optimized Code
    (this does not apply to ProCompiler C++ 3.0.1 )
    
    You can now compile using both the -g and the -O options. 
    There are some side effects:

    o   The next and step commands do not work, but the 
	cont command does.

    o   If you have make files that rely on -g overriding -O, 
	then you will have to revise those make files.

    o   If you have make files that check for a warning message 
	that -g overrides -O, you must revise those make files.

	Special Case: -04 -g

 	The combination -04 -g (or "-g -04") turns off the in-lining 
	that you usually get with -04.


3.  Sun C++ 3.0.1 is based on the Unix System Laboratories (USL) translator,
    cfront, version 3.0.1.  The following is a list of new features
    introduced in this release.

	o Support of template classes and functions.

	o Release 3.0.1 completes the implementation of true nested
	  scopes introduced in Release 2.1.  The transition is
	  no longer supported.

	o Release 3.0.1 implements various Release 2.1 Reference Manual
	  upgrades, including allowing constructors in which all
	  parameters have default arguments to be used as the
	  default constructor in initializing arrays, overloaded
	  prefix and postfix increment, and extension of
	  dominance to data.

	o Most anachronisms that were warned about by default in Release
	  2.1 are treated as errors in Release 3.0.1.  Those that generated
	  warning messages under +w are generally being warned by default in
	  Release 3.0.1 and may be disabled in future releases.


4. Most of the Sun C++ 2.1 tools have been incorporated into the traditional
   Unix tools.  The tools include lex++, yacc++, prof++, gprof++, nm++,
   ctags++, and rpcgen.   For C++ 3.0.1, the "++" suffix has been removed from 
   the names of these tools.  They are now called lex, yacc, prof, 
   grpof, nm, ctags, and rpcgen.    For prof, gprof, and nm, use "-C" to
   invoke C++ support.  These tools are either part of the
   package or bundled with SunOS 5.0.


5. C++ 3.0.1 supports "volatile" type specifiers up to the level of the 
   C language. For example, the following is a legal C++ program:

        	volatile int *a; 
        	volatile float *volatile b;
        	int *volatile c;
        	volatile long d;

        	struct A {
               		int i;
                	double o;
        	};

        	volatile A e;
 
        	void foo(volatile float *volatile f, volatile A ss)
        	{
                	/* ... */
        	}
 
        	void bar(void)
        	{
                	foo(b, e);
        	}

   However, C++ 3.0.1 doesn't support volatile member functions.  This
   implies that volatile class objects will not be supported correctly.
   For example, the following program:

        	class A {
        	public:
                	A(int, char *);
        	};

        	volatile A a(5, "chair");
	
   When compiled, generates the following warning message:

		% CC -c test.cc
		"test.cc", line 6: warning: argument is incompatible with
		prototype: arg #1
		%

   The warning message is emitted by the C compiler.  It is emitted
   because cfront generates the following C code:

		struct A *__ct__1AFiPc (struct A *__0this , int , char *);

		volatile struct A a = { 0 } ;
		...
		__ct__1AFiPc ( &a , 5 , (char *)"chair" );


6. C++ 3.0.1 issues an error 'jump past initializer' if there
   is an initializer statement in a switch statement and
   is not enclosed within braces; C++ 2.1 allowed this. The
   following code fragment will not compile with C++ 3.0.1:

   switch (j) {
     case 1:
       int i = 1;
       break;
     case 2:
       break;
   }

   The fix is to enclose the initialization statement within 
   braces as follows:

   switch (j) {
     case 1:
       {
         int i = 1;
       }
       break; 
     case 2:
       break;
   }

7. C++ 3.0.1 does not allow defining a nested typedef before
   defining the class; C++ 2.1 allowed this. The following
   program will not compile with C++ 3.0.1:

   class A;
   typedef void A::f(int*);
   class A {
   public:
       A(int);
       virtual ~A();

   private:
       int i;
   }; 

   The fix is to define the typedef after the class definition,
   as follows:

   class A;
   class A {
   public:
       A(int);
       virtual ~A();
   private:
       int i;
   }; 
   typedef void A::f(int*);

7. Using an enum in place of an int is not allowed as an index
   in a for loop by C++ 3.0.1. The following program compiles with 
   C++ 2.1 but not with C++ 3.0.1:

   enum E { a, b, c};
   main()
   {
     E  n;

     for (n=1; n<3; n++) {

     }
   }

   The fix is to use an int variable as an index:

   enum E { a, b, c};
   main()
   {
     int  n;
 
     for (n=1; n<3; n++) {
 
     }
   }

9. On SunOS 5.0, all static constructors and destructors are called from
   the .init and .fini sections respectively. All static constructors in
   a shared library linked to an application will be called before main()
   is executed. This behaviour is slightly different from that on 
   SunOS 4.x where only the static constructors from library modules used
   by the application are called.

        ______________________________________________________________________
        For information on the transition from C++ 2.1 to C++ 3.0.1 see
	the "ProCompiler C++ 3.0.1 Language System Release Notes" (part
	number 801-3899-05).
       ______________________________________________________________________ 
        C++ does not support SCP (Source Compatibility Package),the header 
        files under /usr/ucbinclude have not been modified to be compilable by
        C++.
        ______________________________________________________________________
        C++ Runtime Libraries
   
        cg89/libm.a
        cg89/libp/libm.a
        libC.a       
        libC.so
        libp/libC.a 
        libcomplex.a
        libcomplex.so
        libp/libcomplex.a
        libtask.a
        libp/libtask.a
         
            
B. GENERAL KNOWN PROBLEMS 
__________________________________________________________________________

Note:  Also see the "ProCompiler C++ 3.0.1 Language System Release Notes",
Appendix A `Known Problems' for other information on C++ 3.0.1.

1.  +d Option

	If you use the +d option, cfront will sometimes produce
	incorrect C code.  This causes the compilation to fail, although
	it would otherwise compile if the +d option was not used.

	Since the -g option implies the +d option in C++ 3.0.1, this problem
	may also surface when the -g option is used.  See the description of
	bug 1075964 under Section D below.

	Also, cfront may not update .d files correctly when the +d ooption is
	used together with -a.

2.  Library not found during execution

	You may get the following error message while executing a
	program:

		ld.so: library not found

 	This happens during the run of a.out, not during compilation or 
	while building the executable file.

    	This can happen for several reasons.  One of these reasons is described
	below, along with two ways to fix the problem.

	Executables that are dynamically linked with the SC2.0 compiler are
	linked to the library that is usually in the /opt/SUNWspro/SC2.0/ 
	directory.  If when you installed SC2.0.1, you removed the SC2.0 
	package (maybe to save disk space), then you also removed the dynamic 
	library that the executable file needs to run.

	Fix: You can fix the problem in either one of these two ways.

   i)   The SC2.0.1 dynamic libraries that are included in the SC2.0.1 
 	directory are compatible with the SC2.0 libraries that you used 
	earlier. Set up the SC2.0 directory and set up links for the libraries 
	to point into the SC2.0.1 area.

  ii)   Set LD_LIBRARY_PATH to include the /opt/SUNWspro/SC2.0.1 directory
	as follows:
		
	If using csh:

   	setenv LD_LIBRARY_PATH $LD_LIBRARY_PATH :/opt/SUNWspro/SC2.0.1

	If using sh:

	LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/SUNWspro/SC2.0.1; export 
	LD_LIBRARY_PATH

    	Note:
		Dynamic libraries from SC2.0.1 onwards reside in a directory 
		that does not depend on the version of the compiler. You will 
		find them in the /opt/SUNWspro/lib/ directory. They exist as 
		links in this area. This way your executable files do not have 
		wired into them the version of the compiler used to create them.
	
3.	Use the CC driver for linking instead of using ld directly.

	If you are building an executable or a shared library, then you should 
	use the CC driver for linking instead of using ld directly. This will 
	ensure that code for static constructors/destructors in the 
	.init/.fini sections will be executed correctly. The CC driver 
	links in crti.o for this purpose. If you wish to use ld directly, 
	then you should first use CC with -v option and note the options 
	it passes to ld and then use these options in the ld command.

4.  c_varieties.h provided for backward compatibility purpose only

	The c_varieties.h file is provided in this release for backward
	compatibility purposes only.  It will be phased out in the
	future releases of ProCompiler C++.  No new code should be
	written with the macros defined in the file.  Existing code
	should be modified to ensure forward compatibility.

5.  Template support

	There is no source browser support for generic templates
	(instantiated templates are supported).  The debugger support
	for templates is partial.  Full debugger support for the
	feature will be provided in the future releases.

6.  Static data member

	The following anachronism:

	"The definition of a static data member of a class for which
	initialization by default to all zeros applies (s8.4, s9.4)
	may be omitted."

	is no longer supported in ProCompiler C++ 3.0.1.

	C++ 3.0.1 will enforce the rule according to section 9.4
	"Static Members" of the ProCompiler C++ 3.0.1 Product Reference
	Manual:

	"The declaration of a static data member in its class
	declaration is not a definition.  A definition is
	required elsewhere; ..."

	This means that if you have a class definition Foo:
 
		class Foo {
			int i;
			static int j;
		};
 
	you need to define Foo::j in file scope in the same way
	as any other global data object,  e.g.
 
		int Foo::j = 1;

7.	-g Option

	This option implies +d, that is, inline functions can also be
	debugged.

8.	-g0 Option

	This option is the same as the -g option, except that it does not
	imply +d.  That is, inline functions cannot be debugged when
	using the -g0 option.  This option produces smaller binaries and
	reduces compile time as compared to the -g option.

9.      The following options do not work:
	-ql and   -a.


        The following options are specific to the ProCompiler C++ 3.0.1 release. 
	-386 , -486 ,-nolib ,-fstore ,-nofstore.
	
10.	The following options which were not available in the FCS are release are
	now available in  the patch 101205-01 release :

	The -g option now works with the -O -On options.
	The -xF Option  works for this release.

	Libtask is available in this release	

	This release also fixes the  priority 1 bugs :

	1.1133160
	2.1133162
	3.1133163

11.  	Due to a bug in SunOS 5.0 /usr/include/alloca.h, you may have
	a problem in using alloca().  For example, the following program:
	
		#include <alloca.h>
		main() { char *p = (char *)alloca(100); }

	When compiled, generates the following error message:

	"test.cc", line3:  error:  undefined function_builtin_alloca called
	Compilation failed

	The reason for this error message is that alloca() is defined as
	a macro calling builtin_alloca() in alloca.h, while the latter is
	not declared in the header file.

	The fix is to add the following line to your program:

		extern "C" char *_builtin_alloca(int);

12.	No demangler support in lprof:

	For some options, lprof prints symbol names used in a user program. 
	For C++ programs it will print mangled names. To obtain the demangled 
	names as used in the C++ program, you may pipe the output of lprof 
	through c++filt.

      	Example:

          lprof -s -c test.cnt -o test | c++filt

13. 	-bsdmalloc Option

	The -bsdmalloc option works on SunOS 4.1.2 and 4.1.3 only, not on SunOS 5.0.


 


C.  LIST OF BUGS
__________________________________________________________________________


BugId	  Category	Description
=====	  ========	==============================================

1076802	   C++		Accessing member of a virtual parent class causes
			program to crash at runtime.
1047060	   C++		Objects representing virtual base classes get
			assigned more than once.
1066150	   C++		Pointer-to-nested-class-member declarations not
			parsed.
1075615    C++          Compiler does not allow explicit call to destructor.
1082198	   C++		cfront generates wrong C code for array with initializers.
1083627    C++          -a produces different .d file when also using -sb.
1047451	   C++ 		Multiple access with permission denied by cfront.
1077967    C++          Incorrect error messages: CAST is not a permitted 
                        struct/union operation.
1075964    C++          Undefined symbol with +d option; local class member  
                        unable to access global.
1074181    C++          Destructor calls emitted in unreachable sections of
			the program.
1099775    C++          cfront confused regarding multiple virtual inheritance.
1101336    C++          Problems with overloaded virtual functions with 
                        multiple inheritance.
1092587    C++          Template formal parameter not supported as base 
                        class of template class.
1092799    C++          Access declarations (adjustments) for unions within 
                        classes treated incorrectly.
1097234    C++          Type conversion for local classes not done in 
                        comparison expression.
1100945    C++          Nested enumerations within template class don't work
1080360    C++          Function templates -- args must be used.


--------------------------------------------------------------------------
Intel specific BUGS 


BugId	 Category	Description
====	 =======	===================================================
1116740	  c++		cfront produces a dubious lineno directive



---------------------------------------------------------------------------


D.  C++ BUG DESCRIPTIONS
__________________________________________________________________________


BugId		Synopsis
=========================================================================

1076802		Accessing a member of a virtual parent class causes the program
		to crash at runtime.

		For example, the following program:

		#include <stdio.h>

		class A {
		public:
			int i;
			virtual void f()
			{
				printf("A::f() %08X\n", this);
				printf("i=%d\n", i);
			}
			void g()
			{
				printf("A::g()\n");
				f();
			}
			A()
			{
				printf("A::A() %08X\n", this);
				i = 1965;
			}
		};

		class B: public virtual A {
			int j;
		public:
			void f()
			{
				printf("B::f() %08X\n", this);
				printf("i=%d\n", i);
			}
			B()
			{
				printf("B::B() %08X\n", this);
				g();
			}
		};

		class C: public B {
			int k; // no sigsegv without this line
		public:
			C()
			{
				printf("C::C()\n");
				g();
			}
		};

		main()
		{
			C c;
		}


		When compiled and run, will generate the following output:

		% CC test.cc
		% a.out
		A::A() F7FFFB88
		B::B() F7FFFB78
		A::g()
		B::f() F7FFFB7C
		Segmentation fault (core dumped)

		Work Around:  Don't call virtual functions from constructors.

________________________________________________________________________ 

1047060		According to the Product Reference Manual, objects 
		representing virtual base classes will be assigned only 
		once by the generated assignment operator.  This, however, 
		is not always true in C++ 3.0.1.

		For example, the following program:

		#include <stdio.h>
		
		class A {
			int a;
		public:
			A(int i) : a(i) {}
			A& operator = (const A& foo) {
				a = foo.a;
				printf("A::operator=()!\n");
				return *this;
			}
		};
		
		
		class B : public virtual A {
			int b;
		public:
			B(int i) : A(i), b(i) {}
		};
		 
		
		class C : public virtual A {
			int c;
		public:
			C(int i) : A(i), c(i) {}
		};
		
		
		class D : public B, public C {
			int d;
		public:
			D(int i) : A(i), B(i), C(i), d(i) {}
		};
		
		main()
		{
		        D d1(9);
		        D d2(2);
		        d1 = d2;
		}

		When compiled and run:

		% CC test.cc
		% a.out
		A::operator=()!
		A::operator=()!
		%

__________________________________________________________________________ 
1066150		C++ emits syntax errors for pointer-to-nested-class-
		member declarations.

		For example, the following program:

		struct X {
		        void f();
		        struct Y {
				void f();
			};
		};
		
		void X::f() {}
		void X::Y::f() {}
		
		void foo() {
		        void (X::*xptmf)();
		        xptmf = ( void (X::*)() ) 0;
		
		        void (X::Y::*yptmf)();
		        yptmf = ( void (X::Y::*)() ) 0;
		}

		When compiled, gives the following errors:

		% CC test.cc
		"test.cc", line 15: error: syntax error
		Compilation failed
		%


__________________________________________________________________________ 
1075615		Calling a destructor for a type that does not have a 
		destructor is not allowed by the compiler.

		According to the Product Reference Manual, Special 
		Member Functions, chapter 12.4, this should be allowed to 
		enable people to write code without having to know if a 
		destructor exists for a given type.

		This code contains two examples; the first for a class 
		without a defined destructor, the second for a simple type.


		class XX
		{
		public:
		  int i;
		};

		void foo()
		{
		  XX *p = new XX;
		  p->XX::~XX();     // call destructor
		}

		main()
		{
		  int *p;

		  p->int::~int();    // call destructor
		  return 0;
		}

		When compiled, it gives the following error:

		% CC test.cc
		"test.cc", line 10:  error:  qualified name
		XX:: destructor not found in XX

 		WORK AROUND:  don't call a destructor explicitly if it is
                              not defined in the class.

__________________________________________________________________________
1082198		cfront can generate incorrect c code for arrays with 
		initializers.		

	 	The following program:

		struct A { int a[3], b; } w[] = { { 1 }, 2 };
		main() {}

		When compiled, it produces the following error:

		% CC test.cc
		"test.cc", line 1: too many array initializers
		Compilation failed

		The reason for that is cfront generates the following 
		wrong C code:

		struct A w [1]= { { 1 } , 2 } ;


__________________________________________________________________________

1083627		Sometimes, C++ generates incorrect line numbers in 
		the .d file if the -a option is used along with -sb.
__________________________________________________________________________
1047451		In C++, if a name can be reached by several paths through a 
		multiple inheritance graph, the access is that of the path 
		that gives most access. 

		Cfront rejects the following program by issuing an error 
		message on the access of X::f. The access should be granted 
		because class XYZ has a public base class X in one path.


		#include <stdio.h> 
		 class X{
		         public:
		         virtual void f();
		 };
 
		 class Y : virtual private X{ };
 
		 class Z : virtual private X{ };
 
		 class XYZ : public Y, public Z,  virtual public X{ };
 
 
		 void X::f() { printf("\nX::f() "); }
 
		 int main() {
		       XYZ * xyzp = new XYZ;
		       xyzp->f();                 //LINE 31
		 }

		When compiled, the following error message is generated:

		#CC test.cc
		"test.cc", line 28: error:  main() cannot access f : X  is a 
		private


__________________________________________________________________________

1077967		Incorrect error messages may be generated under certain 
		conditions.  The following error message is obtained when 
		line 53 of the source code  shown below is commented out:

		"1077967.c", line 51: invalid cast expression

		The following error message is obtained when line 53 in
		the source code is uncommented:

		"1077967.c", line 53: error:  2 possible conversions for cast 

		These two error messages are misleading.  They should point 
		out that a conversion routine is needed to convert an object 
		from one class to another.

		Source:


		class data_class_1 {
		public:
		    int	a;
		};

		class data_class_2 {
		public:
		    int	b;
		};

		class data_class_3 {
		public:
		    int	c;
		};

		class derived_class_1: public data_class_1 {
		public:
		    derived_class_1() { a = 0; }
		    ~derived_class_1() { a = -1; }
		};

		class derived_class_2: public data_class_1, public data_class_2 {
		public:
		    derived_class_2() { a = b = 0; }
		    ~derived_class_2() { a = b = -1; }
		    derived_class_2( const derived_class_1 & d1 );
		    derived_class_2( const derived_class_2 & d2 );
		    operator derived_class_1( ) const;
		};

		class derived_class_3: public data_class_1, public data_class_2, 
		                       public data_class_3 {
		public:
		    derived_class_3() { a = b = c = 0; }
		    ~derived_class_3() { a = b = c = -1; }
		    derived_class_3( const derived_class_1 & d1 );
		    derived_class_3( const derived_class_2 & d2 );
		    derived_class_3( const derived_class_3 & d3 );
		    operator derived_class_1( ) const;
		    operator derived_class_2( ) const;
		};

		main() {
		    derived_class_1	d1;
		    derived_class_2	d2(d1);
		    derived_class_3	d3(d2);
    
		    data_class_1	da1;
		    data_class_2	da2;

		    da2 = (data_class_2)d3;

		    //da1 = (data_class_1)d3;  //Line 53

		    da2 = *((data_class_2 *)((derived_class_3 *)&d3));
		    da1 = *((data_class_1 *)((derived_class_3 *)&d3));
		}

		WORK AROUND:

		The conversion 'derived_class_3 -> -> data_class_1' is not 
		a legal conversion because there is not an appropriate 
		constructor or conversion operator.

		However, converting a pointer to derived_class_3 into a 
		pointer to data_class_1 is allowed because data_class_1 
		is a base class of derived_class_3.

		Therefore the workaround is to convert a pointer, or write 
		a conversion operator.

    
__________________________________________________________________________

1075964		C++ generates incorrect code when the +d (or -g) option is 
		used.  The program below compiles without errors if -g is 
		not used.


		#include <stdio.h>

		int x = 42;

		int f() {
		  static int x = 1066;
		  struct S { 
		  	int i;

		  	void setx() { x = 999; }
		  	// Does the x in setx refer to ::x or
		  	// to the f-local x?
		  } s;

		  s.setx();
		  return x;
		};


		main() {
		  int i = f();
		  printf( "::x is %d;  f-local x is %d\n",x,i);
		  if( ::x == 999 )
		    printf( "global x referenced from local struct member
 			function\n");
		  if( i == 999 )
		  	printf( "local x referenced from local struct member
			 function\n");
		}

		% $a/CC -g 1075964.c
		"1075964.c", line 13: warning:  s used but not set
		"1075964.c", line 10: undefined symbol: __1x

		WORK AROUND: Declare 'struct S' at global scope.

__________________________________________________________________________
1074181		C++ generates redundant calls to the destructor after the 
		break and return statements in the test example below. This
		causes warnings to be generated.  These warnings are harmless 
		and can be ignored because these extra calls to the destructor 
		will never be executed.

		#include <stdio.h>

		extern void foo();

		class myclass {
		  private:
		    int  i;
		  public:
		    get() { return i; }
		    myclass(int x) { i = x; }
		    ~myclass() { printf( "myclass::~myclass\n"); }
		};

		int main()
		{
		  int  i, j, k;
		  myclass instance(1);

		  i = 1;
		  j = 2;
		  k = 3;
		  switch (i) {
		    case 1:
		    {
		      myclass myinstance(2);
		      foo();
		      break;
		    }
		//->
		  }
		  if (j) {
		    foo();
		    return 1;
		  } 
		  else {
		    k = j + i;
		    foo();
		    return 2;
		  }
		//->
		}

		void foo()
		{
		}

		% $a/CC 1074181.c
		"1074181.c", line 27: warning: statement not reached
		"1074181.c", line 39: warning: statement not reached


__________________________________________________________________________

1099775		The test program below causes C++ to get confused - it thinks 
		that concrete::x() and abstract::x() are ambiguous.

		struct abstract {
		    virtual void x () = 0;
		    virtual void y () = 0;
		};

		struct concrete : virtual abstract {
		    void x ();
		};

		struct A : virtual abstract {
		};

		struct A_i : virtual A, virtual concrete {
		};

		struct B : virtual abstract {
		};

		struct B_i : virtual B, virtual concrete {
		};

		struct AB : virtual A, virtual B {
		};

		struct AB_i : virtual AB, virtual A_i, virtual B_i {
		};

		struct ABC1_i : 
			virtual AB_i,
			virtual A_i,
			virtual B_i,
			virtual C_i {
		    void y () {x();}
		};


 		WORK AROUND:  Use concrete::x() in ABC1_i::y() instead
                              of x().
__________________________________________________________________________
1101336 	Pure virtual functions should not be overloaded.
		The following program:

		class base 
		{
		public:
			virtual void fun(int i=0) = 0;
			virtual void fun(float i=2.3) = 0; // marked - 1
		};

		class der1: public virtual base 
		{
		};

		class der2: public virtual base 
		{
		public:
			void fun(int i) { }
			void fun(float i) { }	// marked - 2
		};

		class good : public virtual der2, public virtual der1 
		{
		};

		main()
		{
			good g;
		}

		When compiled, generates the following error message:

		% CC test.cc
                "test.cc", line 25: error:  declaration of object of abstract 
                class good - pure virtual function(s)  base::fun()  
                base::fun() have not been defined


 		WORK AROUND: Do not use pure virtual functions.
__________________________________________________________________________
1092587		C++ 3.0.1 does not support use of a template parameter of 
		a template class as a base class of the template class.

		Example:

		template<class Rep>
		class A: public Rep {
		  public:
		    int i;
		};

		class Foo {
		  public:
		    int j;
		};

		main() {
		    A<Foo> aa;
		    aa.j=2;
		    aa.i=1;
		    return 0;
		}

		% CC test.c
		"test.c", line 2: sorry, not implemented: formal type 
		parameter Rep used as base class of template "test.c", 
		line 14: error:  member j undefined

 		WORK AROUND: Use some other style.
__________________________________________________________________________

1092799		C++ permits access to members of anonymous unions in a 
		class as though each member of the union were a member of 
		the class, based on section 9.5 of the language definition.
		This feature does not work together with access declarations 
		in a derived class for the union members.  The error message 
		issued shows that the compiler is confused.


		class Link {
		  protected:
		  union {
		    Link* next;
		    Link* prev;
		  };
		};

		class List: private Link {
		  protected:
		    Link::next;
		};


		% CC -c test.c
		"test.c", line 11: error:  public member Link::next specified 
		protected
__________________________________________________________________________
1097234		C++ does not perform user defined type conversions in
		conditional expressions.


		void foo() 
		{
		  class X 
		  {
		    int i;
		  public:
		    X(int ii) : i(ii) { }
		    operator int() { return i; }
		  };

		  class Y
		  {
		    double d;
		  public:
		    Y(double dd) : d(dd) { }
		    operator double() { return d; }
		  };

		  X x = 1;
		  Y y = -1.0;
		  x > 0 ? x + 1 : x;
		  y > 0 ? y : y - 1;
		  int i = x;
		  while (x)
		  {
		    x == i--;
		    x = x - 1;
		  }
		}

		When compiled, the program generates the following error 
		messages:

		% CC -c test.c
		"test.c", line 21: error:  class X(local to foo()) operand 
		for  ?:
		"test.c", line 22: error:  class Y(local to foo()) operand 
		for  ?:


 		WORK AROUND: Use explicit casts in conditional expressions:
                  x > 0 ? x + 1 : (int)x;
                  y > 0 ? (double)y : y - 1;
__________________________________________________________________________
1100945		Using a nested enumeration within a template class causes 
		strange error messages and the program will not compile. The
		following example works if the line marked "BUG!!" is 
		commented out. With the line in place it causes errors:

		// sl.h:
		#ifndef _SL_H
		#define _SL_H

		template <class T> class SL_list;

		template <class T>
		class SL_link {
		private:
			friend class SL_list<T>;

			T f_elem;
			SL_link<T> *f_next;
		};

		template <class T>
		class SL_list {
		public:
			SL_list();
			void append(T elem);
       		 enum E_find {e_not_present_ok, e_must_be_present};
			void remove(T elem, E_find presence);        // BUG!!
		private:
			SL_link<T> *f_tail;
		};

		template <class T>
		SL_list<T>::SL_list() : f_tail(NULL)
		{
		}

		template <class T>
		void
		SL_list<T>::append(T elem)
		{
			f_tail->f_elem = elem;
			f_tail = f_tail->f_next;
		}

		#endif /* _SL_H */ 

		// test.c:
		#include <iostream.h>

		#include "sl.h"

		main()
		{
				SL_list<int> pig;
			cout << "Hi there";
		}

		When compiled, the program will generate the following error
		messages:		

		% CC -c test.c
		"./sl.h", line 35: error:  member f_elem undefined
		"./sl.h", line 35: error detected during the instantiation 
			of SL_list <int >
 		"test.c", line 11: is the site of the instantiation
		"./sl.h", line 36: error: member f_next undefined
		"./sl.h", line 36: error detected during the instantiation 
			of SL_list <int >
 		"test.c", line 11: is the site of the instantiation


		WORK AROUND: move the enumeration out of the template class
__________________________________________________________________________

1080360		All template parameters must be used in function templates.  
		C++ issues an error for the following program:

		template<class In, class Out> class Function 
		{
		public:
		  virtual Out compute(In arg) = 0;
		};
 
		template<class In, class Out> class SimpleFunction 
		{
		public:
	  	  SimpleFunction(Out f(In));
		  Out compute(In arg)  { return fun(arg); }
		private:
		  Out *fun(In);
		};
       
		template<class In, class Out> SimpleFunction<In,Out>&
		simple_function(Out (*f)(In))
		{
		  return *(new SimpleFunction<In,Out>(f)); 
		}

		When compiled, the following error messages will be generated:

		% CC -c test.c
		"test.c", line 20: error:  function template parameter In must 
			be used in signature of  simple_function()
		"test.c", line 20: error:  function template parameter Out must
 			be used in signature of  simple_function()

 		WORK AROUND: Use some dummy parameters:
		    template<class In, class Out> SimpleFunction<In,Out>&
		    simple_function(Out (*f)(In), In, Out)
		                                  ^^^^^^^

-----------------------------------------------------------------------------
1116740 (x86compilers c++)  cfront produces a dubious lineno directive
			    this bug only shows up when using -g , it generates 
		            a warning and does not seem to have any harmful side
			    effects.
		            This will not be fixed  for the PC2.0.1 (fcs) release .

--------------------------------------------------------------
 
		


E.  LANGUAGE CLARIFICATIONS
__________________________________________________________________________


1.  Anachronistic Features

	There are a number of anachronistic features of C++.  These
	features, which are documented in Section B.3 of the "C++ Language 
        System Product Reference Manual", still work so that existing
	code does not have to be changed.  However, these features
	may not be allowed in future versions of C++, so new code
	should be written without their use.
	
	Use of the +p option will disable these features so that
	only the pure language is accepted.
	
	Also see the section on `Anachronisms', under `Upgrading from
	Release 2.1 to Release 3.0' in the "C++ Language System Release Notes" 
        manual.




F.  FEATURE CLARIFICATION

TEMPLATE ISSUES
_________________________________________________________________________
1. Slow compilation speed for programs not using templates.

        Description: This problem may occur if a ./ptrepository directory
        exists in your current directory. If this directory does exist, then
        according to our method of automatic instantiation of templates,
        ptlink will be invoked to determine if there are any unresolved
        template symbols that require instantiation. If you are not using
        templates, then the ptlink step is unnecessry.
 
        Workaround: If you are not using templates, simply remove the
        ptrepository directory from your current directory.
 

2. Instantiated templates are not reolved from shared libraries.

        Description: If your application calls a template function that is
        available in a shared library, and if you link to the shared library
        using the -l flag, then this function will not get resolved by the
        linker.

        Workaround: Supply the full path name of the shared library on the
        command line instead of using the -l flag to link shared libraries.
 
        Example:
 
                Error occurs: CC test.c -lx
 
                Workaround: CC test.c /opt/mylibs/libx.so
 
3. Template functions not instantiated if called from library.
 
        Description: If you are linking a library that uses template functions
        which are not part of the library, then these functions will not
        instantiated at link time. This is already documented in the Selected
        Readings, Chapter 8, "Template Instantiation - User Guide".
 
        Workaround: Preinstantiate all funcitons needed by the library into
        object files, and add the object files to the library, i.e., form a
        "closure" of the library.
 
        Example:
 
                To form a closure for the library /usr/proj/lib.a, do the
                following:
 
                $ mkdir scr
 
                $ cd scr
 
                $ ar x /usr/proj/lib.a
 
                $ CC -pts -I/usr/proj/tincl -I/usr/proj/incl *.o
 
                $ rm -f /usr/proj/lib.a
 
                $ ar cr /usr/proj/lib.s *.o ./ptrepository/.o
 
                This process will cause a link error from CC (because there
                is no main() function) that can be ignored. -pts is specified
                so that the instantiation objects are split apart into separate
                files, which minimizes external symbol collisoins when objects
                are linked with an application or another library.



G. USL README for Cfront 3.0.2
__________________________________________________________________________
 
 
README for Cfront 3.0.2
December 1992
 
3.0.2 HIGHLIGHTS
 
1.  Template Nested Types
 
Previously sorried nested types (classes, typedefs, enums) have been
incorporated into templates.
 
2.  Many Bugs Fixed
 
DETAILS OF 3.0.2 CHANGES
 

========================= CFRONT +A1 =========================
 
1.  Fix bug with extraneous 'const' coming out in C output.
 
        template<class V, class S>
        class DAVC {
        public:
                inline const V& operator*=(const S& rhs);
                inline const V& operator*=(const V& rhs);
                inline V operator*(const S& rhs) const;
        };
        template<class V, class S>
        inline const V& DAVC<V, S>::operator*=(const V& rhs) {
                return rhs;
        }
        template<class V, class S>
        inline V DAVC<V, S>::operator*(const S& rhs) const {
                V temp = (const V&) *this;
                return temp *= rhs;
        }
        template<class V, class S>
        const V& DAVC<V, S>::operator*=(const S& rhs) {
                V& lhs = (V&) *this;
                ecl(lhs, rhs);
                return lhs;
        }
        template<class T> class D;
        template <class T>
        class D : public DAVC< D<T>, T >
        {
        public:
                D(const T& a_t):t(a_t){}
                friend void ecl(D<T>& v, const T& s);
        protected:
                T t;
        };
        main(){
                D<double> kr(5.);
        }

2.  Fix bug with >= 2 'const' coming out in a row.
 
        struct S {
                const S *pcS;
        };
        typedef const S*S::*T;
        void F3()
        {
                const T*const(*pacpcN)[6] = new (const T *const[3][6]);
        }
 
3.  Fix bad C bug with type of const temporaries.
 
        struct A {};
        A a;
        const char& f1()
        {
                return *(new const char(0));
        }
        const char f2()
        {
                return *(new const char(0));
        }
        const A f3()
        {
                return *(new const A(a));
        }
        const char* f4()
        {
                return *(new const char*(0));
        }
 
4.  Rework aggregate initialization:
 
        struct A { int a[3], b; } w[] = { { 1 }, 2 };
 
5.  Fix bad C bug with ?: and inline of only one arm.
 
        extern "C" void printf( char *, ...);
        int   i, j;
        inline void foo( int x) { i = x; }
        inline int  bar( int y) { return y; }
        main()
        {
                j = 2;
                (j > 2) ? foo ( bar(11)) : foo ( bar(22));
                printf( "i=%d\n", i);
        }
 
6.  Fix typedef const bug:
 
        const int *p;
        struct A {
                typedef const int *Z;
                static Z sp;
        };
        A::Z A::sp = p;         // good ANSI C
        struct X {
                typedef const int Z;
                static Z *sp;
        };
        X::Z *X::sp = p;        // bad ANSI C
 
 
7.  Fix bug with forward declarations not coming out soon enough.
 
        typedef void (*fp)(struct A*);
        int i = sizeof(struct A*);
        void f(struct A*) {}
        fp p = f;
        struct A {};
        A a;
        void g()
        {
                typedef void (*fp)(struct B*);
                int i = sizeof(struct B*);
                void h(struct B*);
                fp p = h;
                struct B {};
                B b;
        }
 
8.  Fix bug with initializer expansion:
 
        #include "tc.h"
        struct Str {
                static int nbrOfStrs;
                Str(int iv = nbrOfStrs++) {value = iv;}
                int value;
        };
        int Str::nbrOfStrs = 0;
        int pr_array[] = {0,1,2};
        main()
        {
                Str strArray[3];
                int cnt;
                for(cnt = 0; cnt < 3; cnt++){
                        if (strArray[cnt].value != cnt)
                                return 1;
                }
                return 0;
        }
9.  Fix bug with initialization order:
 
        #include "tc.h"
        struct A {
                int x;
                A() {x = 37;}
                ~A() {}
                A(const A& a) {x = a.x;}
        };
        A a1;
        const A a2 = a1;
        int glob = 47;
        int x = 53;
        const int y = x + glob;
        main()
        {
                A a1;
                const A a2 = a1;
                int x = 53;
                const int y = x + glob;
                if (::a2.x != 37)
                        return 1;
                if (a2.x != 37)
                        return 2;
                if (::y != 100)
                        return 3;
                if (y != 100)
                        return 4;
                return 0;
        }
 
10.  Fix union initialization bug.
 
        union U {
                int a;
                int b;
        };
        U u1 = {37, 47};                // should be rejected
        U u2[] = {1, 2, 3, 4, 5, 6};    // should have length 6
 
11.  Fix for:
 
        void f(...)
        {
                f(f());         // illegal
        }
 
12.  Fix bug with emission of 'char f;' with templates.
 
        template <class T> void f(T) ;//{}
        typedef void (*fp1)(int);
        fp1 p1[] = {f, f, f};
 
13.  Fix bug with 'auto' emission.
 
        class Class {
        public:
                mf();
        };
        int f(auto int (Class::*)());
        void g() {
                f( & Class::mf);
        }
        main()
        {
                return 0;
        }
 
14.  Fix bug with type of 'this' with +d +p.
 
        class A {
                int p;
        public:
                A() : p(100) {}
                ~A() {}
        };
        main()
        {
                A a;
        }
15.  Fix bug with pointer types passed to vec_new() and vec_delete().
 
        int dlop_flg;
        int dtor_flg;
        class C {
        public:
                int *pi;
                C *pC;
                void operator delete(void *pv)
                {
                        ++dlop_flg;
                        ::delete pv;
                }
                ~C() { ++dtor_flg; }
        };
        int main()
        {
                C *apC[1];
                delete [] apC[0]->pC;
                return 0;
        }
 
16.  Fix bug with not expanding typedefs:
 
        typedef char T[10];
        void f()
        {
                T buf = "";
        }
 
17.  Fix bug with const vectors.
 
        struct A {
                int x;
                A() {x = 37;}
                A(int i) {x = i;}
        };
        const A a[3] = {37, A(), a[0]};
 
18.  Fix regression with:
 
        struct Y {
                int j;
                Y() : j(0) {}
                Y(int i) : j(i) {}
        };
        class X {
                static const int i[3];
                static const Y y[3];
        };
        const int X::i[] = {10, 20, 30}; // gets declared and initialized
        const Y X::y[] = {Y(10), Y(20), Y(30)};   // only declared as extern
        void main()
        {
                return 0;
        }
 
19.  Fix for cfront internal state bug.
 
        typedef unsigned char T;
        void F2()
        {
                T *const*pcpN = new (T *const[7]);
                const T*const*pcpcN = new const T *const[7];
        }
 
20.  Disallow a non-inline function in an unnamed class.
 
        struct {
                void f();               // now illegal (must be inline)
        } x;
 

21.  Fix bug with if/then processing and inlines.

        extern "C" void printf(const char*, ...);
        class A {
                int cnt;
        public:
                void fct() { cnt++; }
        };
        A x1;
        extern int ID;
        void error(char* mess)
        {
                (void)printf("error: %s\n",mess);
        }
        static inline void match(int t)
        {
                if (t)
                        x1.fct();
                else
                        error(0);
        }
        static void classHead()
        {
                match(ID);
        }
 
22.  Disallow casts to vector types.
 
        typedef int T[29];
        void f()
        {
                T x;
                (T)x;           // illegal cast to vector
        }
23.  Fix bug with uncompilable C emitted.
 
        extern "C" void printf(const char*, ...);
        class xyz {
        public:
                xyz(const unsigned int a);
                void func();
                virtual ~xyz();
        };
        class sample: public xyz {
                int a;
        public:
                sample():xyz(sizeof(a)) {}
                ~sample();
        };
        void xyz::func()
        {
                static sample j;
                printf("hello world\n");
        }
        xyz::~xyz() { }
        main()
        {
                xyz a(9);
                a.func();
        }
        xyz::xyz(const unsigned int) {}
        sample::~sample() {}
 
========================= CFRONT TEMPLATE =========================
 
1.  Fix bug which caused cfront to hang on certain machine types.
 
        template <class T> class A {
        public:
                void f();
        };
        typedef A<int> T;
        class A<int> {
        public:
                int f();
        } a;
 
2.  Fix cfront crash:
 
        struct O {};
        struct P : O {} os;
        template<class T, class V> struct X
        {
                friend int operator<<(O& os, const X<T,V>& r);
        };
        template<class T, unsigned n> struct Y : X<T,T> {};
        int operator<<(O&, const Y<int,1u>&) { return 7; }
        Y<int,1u> y;
        int i = os << y;
3.  Fix failure to compile:
 
        template <class T> class B {};
        template <class T> void F(B<T>&) {}
        class D : public B<int> { } d;
        void f()
        {
                F(d);
        }
 
4.  Fix 3.0 regression with function templates.
 
        template <class T> void ftempl(T*) {}
        class Base {} b;
        class Derived : public Base {} d;
        void foo()
        {
                ftempl(&b);     // 'ftempl(B*)' called       [*]
                ftempl(&d);     // before fix: 'ftempl(B*)' called
                                // but 'ftempl(D*)' called if
                                // line [*] commented out
                                // after fix: ftempl(D*) called regardless
        }
 
5.  Fix for 3.0 regression with function templates.
 
        template <class T> void ftempl(T*) {}
        class Base {} b;
        class Derived : public Base {} d;
        void foo()
        {
                ftempl(&d);
                ftempl(&b);
                // got "error: no standard conversion of Base* to
                // struct Derived*"
                // now calls 'ftempl(B*)'
        }
6.  Fix cfront crash.
 
        template <class T> struct Block {
                Block() {}
                Block(const Block<T>& b) { ; }
                ~Block() {}
        };
        template <class T> class Cast{};
        struct Alf {
                Alf() {}
                virtual ~Alf() {}
        };
        struct Cast<Alf> : public Alf {
                Cast(const Alf& a) : Alf() {};
        };
        struct Bits {
                Block<int> b;
                Bits() {}
                Bits(int) {}
        };
        int const_matters(Bits cnst2) { return 0; }
        int type_check(Alf u2)
        {
                Bits cnst2 = 0;
                int level;
                if  ( level || type_check(Cast<Alf>(u2)))
                {
                        int return_value=const_matters(cnst2);
                        return return_value;
                } else
                        return 0;
        }
 
7.  Fix bug with comparison of template class names.
 
        class bar;
        template <class S> class foo {
                friend class bar;
        private:
                S priv;
        };
        class bar {
        public:
                bar(foo<int>& f) {f.priv = 10;}
        };
 
8.  Fix 3.0.1 regression with cfront crashing.
 
        class D {
        protected:
                int size;
        public:
                template <class T> friend class X;
        };
        class DL : public D {
        public:
                DL(int elems) { size = elems; }
        };
9.  Fix crash:
 
        Fix for crash that occurred on this example.
 
        class A {
        private:
                operator<<(float);
                template <class T> friend class M;
        };
 
        void foo()
        {
                A a;
                a << 3.0;       // now gets proper error
        }
 
10.  Improve wording of error messages, e.g.
 
old:
 
        error detected during the instantiation of C <L14 , L3'c' >
 
new:
 
        error detected during the instantiation of C <4 , 'c' >
 
11.  Improve same_class() function in cfront to better handle
templates.
 
        struct Z {};
        template<class T, int n, class V> class B {
        public :
                B ( ) : x ( 99 ) { }
                operator int ( ) ;
                int x ;
        } ;
        B<double*,66,Z> :: operator int ( ) { return x ; }
        template<class T, int n, class V> class L :
                virtual public B<double*,66,Z> { } ;
        template<class T, int n, class V> class R :
                virtual public B<double*,66,Z> { } ;
        template<class T, int n, class V> class J :
                public L<double*,66,Z> , public R<double*,66,Z> { } ;
        int main ( )
        {
                J<double*,66,Z> j ;
                int i = j ;
                if ( i != 99 )
                        return 1 ;
                return 0 ;
        }
12.  Fix bad C problem.
 
        template <class S, class T> class X { };
        template <class S, class T> class Y { X<S,T>* p; };
        class C {
        public:
                typedef int TD;
                Y<char, TD> y;
        } c;
 
13.  Fix problem with lone ';' emitted at global scope.
 
        template <class T> void f(void (T::*)()) {}
        struct A { void g(); };
        void foo() { f(A::g); }
 
14.  Fix crash with 'CC -c' of:
 
        struct A { int operator<() { return 10; } };
        template<class T> struct vector { int m(); };
        template<class T> int vector<T>::m() { return T::operator<(); }
        vector<A> a;
        int i = a.m();
 
15.  Fix bad encoding for 'X<4,iarr,carr>'.
 
        template<int I, int *IP, char *CP> class X { };
        int  iarr[10];
        char carr[] = "hello";
        X< 4, iarr, carr > x;
 
16.  Improve error messages for errant template functions.
 
        template <class T> void F(T o, T *p, T **pp) { *o; }
        void f(int i, int *pi, int **ppi)
        {
                F(i,pi,ppi);    // error
        }
 
old:
 
        error detected during the instantiation of F <int >
 
new:
 
        error detected during the instantiation of F (int , int *, int **)
 
17.  Fix function matching bug with templates.
 
        template <class T> class W {
        public:
                W( void (T::*pm)() );
        };
        struct S { void f(); };
        W<S> w(&S::f);
18.  Fix template bug with 'A<V,U>' incorrectly matching 'A<U,V>'.
 
        template <class U, class V> struct A { A<V,U> f(); };
        A<int,char> aic;
        A<char,int> aci;
        void foo() { aci = aic.f(); }
 
19.  Fix bug with static copy of template class member function laid
down before declaration of containing class.
 
        #include <stddef.h>
        #include <iostream.h>
        class SPNCPP_Err {
        public:
                virtual void message(ostream&) const = 0;
                virtual ~SPNCPP_Err() {}
                void user_message() const;
        };
        extern void fake_throw(const SPNCPP_Err&);
        typedef size_t UncheckedSubscript;
        typedef int Dimension;
        class SubscriptRangeErr : public SPNCPP_Err {
        public:
                SubscriptRangeErr(UncheckedSubscript i, UncheckedSubscript n) :
                        bad_sub(i), nelts(n) {}
                virtual void message(ostream&) const;
        private:
                const UncheckedSubscript bad_sub;
                const UncheckedSubscript nelts;
        };
        class Subscript {
        public:
                Subscript() {}
                Subscript(UncheckedSubscript i) : s(i) {}
                operator UncheckedSubscript&() { return s; }
                operator UncheckedSubscript() const { return s; }
                UncheckedSubscript check(UncheckedSubscript n) const {
                        if (s >= n) ::fake_throw(SubscriptRangeErr(s, n));
                        return s;
                }
        private:
                UncheckedSubscript s;
        };
	template<class T, UncheckedSubscript num>
        class RigidArray1d {
        public:
                RigidArray1d() {}
                virtual UncheckedSubscript num_elts() const { return num; }
                virtual UncheckedSubscript stride(Dimension) const
                        { return 1; }
                const T& operator[](UncheckedSubscript i) const
                        { return elts[i]; }
                T& operator[](UncheckedSubscript i) { return elts[i]; }
                const T& operator()(UncheckedSubscript i) const
                        { return elts[i]; }
                T& operator()(UncheckedSubscript i) { return elts[i]; }
                const T& operator[](Subscript i) const
                        { return (*this)[i.check(num)]; }
                const T& operator[](int i) const
                        { return (*this)[Subscript(i)]; }
                const T& operator[](long int i) const
                        { return (*this)[Subscript(i)]; }
                T& operator[](Subscript i)
                        { return (*this)[i.check(num)]; }
                T& operator[](int i) { return (*this)[Subscript(i)]; }
                T& operator[](long int i) { return (*this)[Subscript(i)]; }
                const T& operator()(Subscript i) const { return (*this)[i]; }
                const T& operator()(int i) const { return (*this)[i]; }
                const T& operator()(long int i) const { return (*this)[i]; }
                T& operator()(Subscript i) { return (*this)[i]; }
                T& operator()(int i) { return (*this)[i]; }
                T& operator()(long int i) { return (*this)[i]; }
                virtual const T* first_datum() const { return elts; }
                virtual T* first_datum() { return elts; }
        private:
                T elts[num];
        };
        void main() {
                RigidArray1d<int, (const UncheckedSubscript) 10> x;
        }
 
20.  Fix bad ANSI C:
 
        template <class T> void G(const T*) {}
        void foo()
        {
                const int ci=23;
                G(&ci);
        }
21.  Fix cfront malloc() bug with:
 
        template <class T> struct A {};
        struct A<long>;
        struct A<int> { A<long>* p; };
        struct A<long> { A<int>* p; };
 
22.  Fix bad C:
 
        template <class S, class T> class X { };
        template <class S, class T> class Y
        {
                X<T,S> *p;
        };
        struct S { int i; };
        typedef int TD1;
        X<char,TD1> x1;
        Y<int,TD1> y1;
        void f2()
        {
                typedef S TD2;
                X<char,TD2> x2;
                Y<int,TD2> y2;
        }
        class C3 {
        public:
                typedef S* TD3a;
                X<char,TD3a> x3;
                Y<int,TD3a> y3;
                typedef int* TD3b;
        };
        X<char,C3::TD3b> x3;
        Y<int,C3::TD3b> y3;
        C3 c3;
 
23.  Fix cfront crash with:
 
        template <int i> struct S { char ac[i+1]; };
        template <class T> S<sizeof(T)> *f(T t) { return new S<sizeof t>; }
 
24.  Fix access bug with:
 
        class A5 {
        private:
                int operator<<(float);
                template <class T> friend void foo5(T);
        };
        void foo5(int)
        {
                A5 a;
                a << 3.0;       // access to << denied
        }
 
25.  Fix 3.0 regression with:
 
        template <int n> struct B;
        template <int n> struct A { A(B<n>&); };
        template <int n> struct B { void f(); };
        B<8> b8;
        B<16> b16;
        template <int n> void B<n>::f() { A<n> a(*this); }
 
26.  Fix directed mode bug with:
 
        template <class S, class T> class Map;
        template <class S, class T> class Mapiter;
        class Mapnodebase {
        protected:
                Mapnodebase *L_, *R_, *U_;
                friend class Mapbase;
                Mapnodebase() { }
                virtual ~Mapnodebase();
        };
        class Mapbase {
        public:
        protected:
                Mapnodebase *head_;
                Mapbase() { head_ = 0; }
                ~Mapbase() { }
        };
        template <class S, class T>
        class Mapnode : public Mapnodebase {
                Mapnode(const S&, const T&){};
                ~Mapnode() { }
                friend class Map<S,T>;
                friend class Mapiter<S,T>;
        };
        template <class S, class T>
        class Mapiter {
                friend class Map<S,T>;
        public:
                Mapiter(const Map<S,T>&){}
                ~Mapiter(){}
                Mapiter<S,T>& operator=(const Mapiter<S,T>&);
        };
        template <class S, class T>
        class Map : public Mapbase {
                friend class Mapiter<S,T>;
        public:
                Map(){}
                Map(const Map<S,T>&);
                ~Map() {}
                Map<S,T>& operator= (const Map<S,T>&);
        };
        template <class S, class T>
        Map<S,T>::Map (const Map<S,T>& m)
        {
		operator= (m);
        }
        template <class S, class T>
        Mapiter<S,T>&
        Mapiter<S,T>::operator=(const Mapiter<S,T>& mi)
        {
                return *this;
        }
        Mapnodebase::~Mapnodebase() {
                delete L_;
                delete R_;
        }
        class Fldid {
        public:
                int fldid;                      // Field identifier
                Fldid(int id=0) { fldid = id;  }
                ~Fldid()                  { }
        };
        int
        main() {
                Map<Fldid,int>  msgbuf;
                return(0);
        }
 
27.  Fix problem with laying down template statics.
 
        struct A {
                static int FOO;
        };
        int A::FOO;
        int main()
        {
                A a;
                a.FOO = 1;
                return 0;
        }
 
28.  Fix crash on:
 
        struct N {
                class B {};
                enum {};
                B init;
                unsigned char m1, m2, m3, m4, m5;
        };
        template <class T> struct A { N::B b; };
        A<char> a;
 
========================= CFRONT MISCELLANEOUS =========================
 
1.  Fix failure to call destructors with new placement.
 
        #include <malloc.h>
        extern "C" int printf(const char *, ...);
        void *operator new(size_t s, char *h) { return (void*) malloc(s); }
        void operator delete(void* ptr) { free(ptr); }
        struct A {
                A() { printf("A::A called\n"); }
                ~A() { printf("A::~A called\n"); }
        };
        main()
        {
                char *c = 0;
                A *ap = new(c) A[3];
                delete [] ap;           // no destructor calls !
                return 0;
        }
 
2.  Accept a local class declaration in a member function, which was
rejected if the class name is the same as the enclosing class of the
member function.
 
        class A {
                int f() {
                        class A;
                }
        };
 
3.  Fix casts of float literals to integral types.
 
        enum { a = (char)0.1622e2 };
        int x = a;
        main() {
                if ((char)0.1622e2 == x)
                        exit(0);
                exit(1);
        }
 
4.  Fix 3.0 regression with bad C.
 
        struct Point {
                Point();
                Point(Point&);
        };
        struct Trans {
                Point trans(Point);
        };
        void f(Point p, Trans *t)
        {
                Point tp = (t) ? t->trans(p) : p;       // bad C
        }
 
5.  Fix function matching bug where two conversions were wrongly
detected.
 
        class base
        {
        public:
                base();
                base(const base&);
                base& operator=(const base&);
        };
        class derived2 : public base {};
        class derived1 : public base
        {
        public:
                derived1();
                derived1(const derived1&);
                operator derived2() const;
        };
 
        void f(derived1& b)
        {
                base f = b;  // gives error
        };
 
6.  Fix regression with vector access.
 
        class foo {
        protected:
                friend class bar;
                foo();
                ~foo();
        };
        class bar {
        public:
                bar();
                ~bar();
                foo x;                  // no error on this line
                foo d[1];               // error -- protected member
        };
 
7.  Change error into sorry for bit fields within unions.
 
8.  Fix performance regression with call through vtbl when object type
is known.
 
        struct A {
                virtual void f();
        };
        void A::f()
        {
        }
        main()
        {
                A a;
                a.f();
        }
 
9.  Fix +d bug with undefined symbol being emitted by cfront.
 
        extern int i;
        struct S {
                static int i;
                struct Embedded {
                        int f() { return i; }
                };
        };
        {
                struct S x;
        };
 
10.  Fix problem with calculating virtual table offsets for base
classes.
 
        #include <iostream.h>
        class A
        {
        private:
                int adata;
        public:
                A()     { adata = 1; cout << "A::A() called" << endl; }
                virtual ~A()    { cout << "A::~A() called" << endl; }
                void    f() {
                        cout << "A::f():  adata = " << adata << endl;
                        k();
                }
                virtual void k() {
                        cout << "A::k():  adata = " << adata << endl;
                }
        };
        class B : public virtual A
        {
        private:
                int     bdata;
        public:
                B()     { bdata = 3; cout << "B::B() called" << endl; }
                ~B()    { cout << "B::~B() called" << endl; }
                void    k() {
                        cout << "B::k():  bdata = " << bdata << endl;
                }
        };
        class C : public virtual A { };
        class D : public C, public B { };
        class E : public D { };
        main()
        {
                cout << "A::A() called" << endl;
                E *e = new E;
                cout << "B::B() called" << endl;
                cout << "A::f():  adata = 1" << endl;
                e->f();
                cout << "B::k():  bdata = 3" << endl;
                return 0;
        }
11.  Fix problem with enumerator overflow:
 
        #include <limits.h>
        enum E {a = INT_MAX, b};
 
This now gets a cfront error.
 
12.  Fix cfront crash when parsing function argument declarations with
more than one class name argument.
 
        void f(class A, class B);
 
13.  Fix bug with no error reported for a static class member
definition with incomplete type.
 
        class A {
        public:
                static class B b;
        };
        B A::b;
 
14.  Change an error to a warning in main() when if-then is the last
statement and there is no return.
 
        main() {
                int x;
                ...
                if (x) return 34;
        }
 
15.  Fix 3.0 regression with:
 
        struct entry { char *a; };
        struct st_t { int entry; } st;
        void func() { st.entry < 0; }
 
16.  Fix bug with bad C:
 
        struct String {
                String(int);
                String();
                String(const String&);
                String& operator=(const String&);
        };
        String s;
        void f(const String arg, int x)
        {
                s = x ? arg : (String)0;
        }
        String tmp = s;
 
17.  Add space after 'operator' for better error messages.
 
        // [1]
        typedef unsigned int size_t;
        void *operator new(size_t);
        void *operator new(size_t, char * = 0);
        void f1() { int *pi = new int; }
        // [2]
        class A {} a;
        int operator +(A,long);
        int operator +(A,short);
        void f2() { a + 1; }
        // [3]
        void operator delete(void*);
        void operator delete(void*, char* = 0);
        void f3(int *pi) { delete pi; }
        // [4]
        class B {} b;
        int operator ->*(B,long);
        int operator ->*(B,short);
        void f4() { b ->* 1; }
 
18.  Fix for new placement bug.
 
        typedef unsigned int size_t;
        void *operator new(size_t, char*);
        void operator delete(void*);
        struct A {
                void* operator new(size_t, char* = 0);
                void operator delete(void*);
                A();
                ~A();
        };
        char *c;
        A *ap = new(c) A[2];    // used to call 'A::operator new'
                                // will now call '::operator new'
 
19.  Avoid cfront crash during error recovery.
 
        class b;
        class foo { b * operator->(); };
        class c {};
        class a { public: c& model_ref(); };
        class b { public: a * model_entry(); };
        extern void scan_design(c& C);
        void bar(foo & f) { scan_design(f->model_ref()); }
 
20.  Warn (error in later release) on casts from pointer to member to
other than other pointer to member types or void type.
 
        struct A {};
        typedef void (A::*pmf)();
        void f()
        {
                int(pmf(0));    // illegal
        }
21.  Fix pointer to member bug where '{0,0,0}' was printed:
 
        struct A {
                void f();
        };
        typedef void (A::*pmf)();
        main()
        {
                int x;
                if (x)
                        pmf(A::f);
                while (x)
                        pmf(A::f);
                for (;;)
                        pmf(A::f);
                do
                        pmf(A::f);
                while (x);
        }
 
22.  Fix bad C bug with ?:.
 
        int x;
        extern void f();
        struct S {
                static S &smf();
                void mf() { x--; x--; x--; x--; }
        };
        void F5(int (**p)(const char *, ...))
        {
                x ? (void)S::smf() : (++x, delete [] p);
                x ? (++x, delete [] p) : (void)S::smf();
                x ? (void)S::smf() : (void)S::smf();
        }
 
23.  Fix +p bug with laying down tentative statics.
 
        template <class T> struct A {
                static int x;
        };
        template <class T> struct B {
                static int x;
        };
        template <class T> int A<T>::x = 37;
        template <class T> int B<T>::x = 47;
        A<int> a;
        B<int> b;
        typedef A<int> _dummy_;
24.  Fix pointer to member bug with:
 
        struct A {
                void f();
        };
        typedef void (A::*pmf)();
        struct B {
                int x;
                pmf p1;
                pmf p2;
        };
        B b[] = {37, A::f, A::f, 47, A::f, A::f};
 
25.  Fix pointer to member bug with:
 
        struct A {
                void f();
        };
        typedef void (A::*pmf)();
        struct B {
                pmf p;
                int x;
        };
        B b[] = {A::f, 37};
 
26.  Fix bug with stray cast being emitted:
 
        class A {
        public:
                A() {}
                ~A() {}
                virtual void V() = 0;
        };
        class B : public A {
        public:
                B() {}
                ~B() {}
                void V() {}
        };
        class C : public A {
        public:
                C() {}
                ~C() {}
                void V() {}
        };
        class X {
        public:
                X() {}
                ~X() {}
                static B get_b();
                static C get_c();
                int set_x();
        };
        B
	 X::get_b()
        {
                B vt;
                vt.V();
                return vt;
        }
        C
        X::get_c()
        {
                C vt;
                vt.V();
                return vt;
        }
        X::set_x()
        {
                B b = get_b();
                return 0;
        }
 
27.  Fix bit field size/alignment problem for 68K architectures.
 
        struct READ_DEF
        {
                unsigned long int y:32;
                unsigned long int z:32;
                unsigned long int x:16;
                unsigned long int r:8;
                unsigned long int s:8;
        } READ;
        enum LEN
        {
                LENGTH = (sizeof(struct READ_DEF)-2)
        };
 
LENGTH came back as 8 instead of 10 on the Sun-3.
 
28.  Fix cfront global state bug with:
 
        class   BaseNet {
        public:
                BaseNet(){}
        };
        class   Bus: public BaseNet
        {
                Bus(Bus& n):BaseNet(n) {}
        };
        class NIHCL { };
        class   SubBus: public virtual NIHCL
        {
                virtual NIHCL   *foo() {return this;}
        };
 
29.  Fix cfront crash:
 
        class Alf {
        public:
                Alf();
        };
        class Expr : public Alf {
        public:
                Expr(const Alf& );
                Expr();
        };
        void f(const Alf* alf)
        {
                Expr init_expr (alf ? *alf : Expr());
        }
 
30.  Fix 3.0 regression with name return value:
 
        class A {
        public:
                A(const A &src);
        };
        class B {
        public:
                static A s();
        };
        A int_s()
        {
                A s ( B::s() );         // gives bad operand error
                return s;
        }
 
31.  Fix bad C bug on use of "x." on function pointer.
 
        struct A {
                static void f();
        };
        main()
        {
                void* p;
                A a;
                p = a.f;
        }
 
32.  Fix failure to call base constructor.
 
        struct A {
                A(const A&, int);
        };
        struct B : public A {
                B(const A& a);
        };
        B::B(const A& a) : A(a, 47)
        {
        }
33.  Fix bug with virtual base class name mangling.
 
        class A1
        {
        public:
                class B1 { };
                class C1 : virtual public B1 { };
        };
        class A2
        {
        public:
                class B2 { };
                class C2 : virtual public A2::B2 { };
        };
        class A3
        {
        public:
                void f() {
                        class B3 { };
                        class C3 : virtual public B3 { };
                }
        };
 
34.  Disallow unions with members that have T::operator=() defined.
 
        struct A {
                void operator=(const A&);
        };
        union U {
                A a;
        };
 
35.  Give +w warning on non-virtual destructor in second or virtual base
class.
        typedef unsigned char uchar;
        struct A {
                int x[59];
        };
        class X {
        protected:
                int d;
        public:
                int i;
                ~X();
        };
        class Y: public virtual X {
        public:
                Y(int, int, uchar*, int, int);
        };
        class YY: public A, public X {
        public:
                YY(int, int, uchar*, int, int);
        };
        int main()
        {
                X *x = new Y(256,256,0,2,2);
                delete x;
                x = new YY(256,256,0,2,2);
                delete x;
                return 0;
        }
        X::~X() {}
        Y::Y(int, int, uchar*, int, int) {}
        YY::YY(int, int, uchar*, int, int) {}
 
36.  Fix +d bug with failing to lay down struct.
 
        struct A {
                A() {}
                A f() {return *(new A);}
        };
        template <class T>
        struct B : public A {
                B() {}
                void f() {B x;}
        };
        B<int> b;
 
37.  Fix cfront crash on {} initializer.
 
        class Foo {
                char *name;
        public:
                Foo(char*);
        };
 
        Foo bar[] =
        {
                {""}
        };
 
38.  Disallow illegal derived --> base conversions.
 
        class L { };
        class A : virtual public L { };
        class B : private virtual L { };
        class X : private A, public B { };
        L *f(X *pX) { return pX; }      // error
        L &g(X &rX) { return rX; }      // error
        void h(L*);
        void h2(X* p) {h(p);}
 
39.  Fix for bug where error was invalidly given on function call.
 
        struct X {
                void (*f)();
        };
        void g(){}
        const X x = {g};
        main()
        {
                x.f();          // error
                (*x.f)();       // OK
        }
 
40.  Fix bug with declaration parsing; 'int (e0)' is currently (3.0)
treated as a cast but with +p is a declaration.
 
        void main()
        {
                int (e0),  *const volatile f0 = &e0;
        }
 
41.  Fix crash on undefined nested type as base class:
 
        class Foo {
                class Bar;
        };
        class X : public Foo::Bar{};
 
 
42.  Propagate internal new() failure in _arr_map.c (in library) back
to caller of new().
 
        extern "C" {
                void* malloc(unsigned int);
                void free(void*);
        };
        void* operator new(unsigned int n)
        {
                void* p;
                static int x = 0;
                if (++x == 3)
                        return 0;
                p = malloc(n);
                return p;
        }
        void operator delete(void* p)
        {
                free(p);
        }
        struct A {
                A() {}
                ~A() {}
        };
        main()
        {
                A* p1;
                A* p2;
                p1 = new A[23];
                p2 = new A[47];
                delete [] p2;
                delete [] p1;
        }
 
43.  Fix failure to call static destructors.
 
        class Foo {
        public:
                int n;
                Foo(const int i = 0) {n = i; printf ("construct %d\n", i);}
                ~Foo(void) {printf("destruct %d\n", n);}
        };
        extern const Foo a;
        extern const Foo b;
        extern Foo c;
        const Foo a;
        const Foo b(1);
        Foo c(2);
        main()
        {
                return 0;
        }
 
 
44.  Change sorry to error on 'non trivial declaration in switch
statement' message.
 
        void f()
        {
                int x;
                switch (x) {
                        case 20:
                                if (x) {
                        default:
                                        const int y = 37;
                                }
                }
        }
 
45.  Fix bug that disallowed:
 
        void f()
        {
                int x=1;
                switch (x)
                        case 66: switch (1) {case 1: ;}
        }
 
46.  Fix bug with virtual base classes and temporaries.
 
        int ctor = 0;
        struct VB { };
        struct B1 : virtual public VB { };
        struct B2 : virtual public VB {
                virtual void Display() { }
        };
        struct D : public B1, public B2 {
                D() { ctor++; }
        };
        void f() {
                new D()->Display();
        }
        int main()
        {
                ctor = 0;
                f();
                if (ctor != 1)
                        return 1;
                return 0;
        }
47.  Fix bug with global scope operator used in inheritance list.
 
        class A
        {
        public:
                class B
                {
                };
        };
        class C
        {
        public:
                class B : public A::B
                {
                };
        };
 
48.  Fix cfront crash:
 
        void f()
        {
                "abc"/1;
        }
 
49.  Fix bug with :: qualification of reference member.
 
        struct foo {
                int &i;
                foo();
                inline int bar(void ) { return foo::i ; }
        };
 
50.  Fix parsing error on constructor calls.
 
        struct A {
                A();
        };
        void f()
        {
                A(), 37;                        // OK
                (A(), 37);                      // syntax error
        }
 
51.  Fix incorrect error message on derived to base conversion.
 
        class A {};
        class B {};
        class C : private A, public B {};
        class D: public C {};
        D obj;
        void func(B x) {x=x;}
        main ()
        {
                func(obj);
                B* b = &obj;
        }
52.  Fix bug where a class was deemed to be abstract.
 
        class W {
                virtual int f() = 0;
                virtual int g() = 0;
        };
        class A : public virtual W {
                int f();
        };
        class B : public virtual W {
                int g();
        };
        class C : public A, public B { };
 
        C c;    // C is not an abstract class since f(), g() are defined
                // in the hierarchy of class C.
 
53.  Fix bad C bug with failure to emit declaration of the global
delete() operator.
 
        class X
        {
        public:
                void operator delete (void *);
                static void f(X *x);
        };
        class Y
        {
        public:
                static void f(Y *y);
        };
        void X::operator delete(void *obj) {}
        void X::f(X *x) { ::delete x; }
        void Y::f(Y *y) { ::delete y; }
 
54.  Eliminate warning about illegal pointer combinations.
 
        void f()
        {
                typedef int iar[4];
                iar localitem;
                iar *iap = &localitem;
                iap = &localitem;
        }
 
55.  Fix bug where invalid reference to vector was allowed as an
argument.
 
        void f2(int (&x)[10]);
        int x[10], *y;
        void g2() {
                f2(x);
                f2(y);
        }
 
56.  Tighten checking of void* arithmetic.
 
        typedef void* addr;
        void write( void * value);
        class xx { } p;
        const addr operator* ( xx );
        extern long *q ;
        void foo()
        {
                write( *p + *q);        // now gives error
        }
 
57.  Fix bad C bug with passing a derived class object (with virtual
derivation) to a base class formal.
 
        extern "C" void exit(int);
        class Foo {
        public:
                int foostuff;
                Foo () {
                        foostuff = 1 ;
                };
        };
        class Bar: public virtual Foo {};
        void my (const Foo& x)  {
                if (x.foostuff != 1)
                        exit(1);
        };
        void testing (Bar arg) {
                Bar local;
                my(local);                //correct
                my (arg);                 //bad code
        }
        main ()
        {
                Bar pass_arg;
                testing(pass_arg);
                exit(0);
        }
 
58.  Fix bug with destructor called on temporary that was never
constructed.
 
        #include <assert.h>
        class thing {
                int store;
        public:
                operator int() const;
                thing();
                ~thing();
                thing another_thing();
        };
        thing::operator int() const {
                return 0;
        };
        thing thing::another_thing() {
                thing *x;
                x = new thing;
                return *x;
        };
        thing::thing() {
                store = 1099;
        };
        thing::~thing() {
                assert (store == 1099);
        };
        main () {
                thing t;
                if (t && t.another_thing())  // <--bad code here
                { }
        };
 
59.  Fix bug with nested class name mangling (test case too large to
include).
 
60.  Fix bug with ?: and temporary cleanup (test case too large to
include).
 
61.  Fix failure to call 'vec_new':
 
        struct Instruction {
                Instruction();
                union {
                        unsigned index;
                } operand;
        };
        void f() { Instruction* a = new Instruction[1]; }
 
62.  Fix crash on:
 
        struct F {
                F(int);
                friend int operator>=(F,F);
                friend int operator<(F,F);
        };
        inline void foo(F &prev, F next) {
                if (prev<0)
                        prev = next;
                else if (next<prev)
                        prev = next;
        }
 
63.  Fix bug with incorrect rejection of:
 
        class base
        {
        public:
                virtual void fun(int) = 0;
                virtual void fun(float) = 0;
        };
        class der1: public virtual base {
        public:
        };
        class der2: public virtual base
        {
        public:
                void fun(int);
                void fun(float);
        };
        class good : public virtual der1, public virtual der2 {};
        main()
        {
                good g;
        }
 
64.  Fix bad C bug with:
 
        class String {
        public:
                String() { length = 8; }
                int length;
        };
        main()
        {
                String s8[1] = { String() };
                return s8[0].length + 10;
        }
 

============================================================================== 
NOTE:These  are some  intel specific problems
1.yacc
.y files that pass thru yacc and are then compiled with -g may produce
	debug information where scopes are not nested properly. In such cases,
	only limited debugging in this file is possible. The debugger will
	also emit (many) warnings about out-of-scope and "unexpected
	start of scope" stabs for such code. This will, however, not hinder
	debugging of code from other files.

2.dbx 

some test cases have the strange behaviour that when using dbx if you try
to stop in main it stops in stdio.h etc. This is only seen in certain sepcific
test cases.Adding a comment line at the top of the file helps get around
this problem.The first test case fails, the second passes

D107.cc
::::::::::::::
#include <stdio.h>

typedef int grandaddy_t;

class grandaddy {
    public: 
    grandaddy_t m_grandaddy;
    grandaddy_t m_male;
};

main (int, char **)
{
}
::::::::::::::
D1.cc
::::::::::::::
/* Add some bogus comment line here */
#include <stdio.h>

typedef int grandaddy_t;

class grandaddy {
    public: 
    grandaddy_t m_grandaddy;
    grandaddy_t m_male;
};

main (int, char **)
{
}

==============================================================================

Licensing
---------

This release uses network licensing.  Refer to the installation
instructions for information on installing the license manager
and getting a license.

Note: the license file <install-dir>/SC2.0.1/SC_LICENSE_FILE
      (where <install-dir> is /opt/SUNWspro or the alternate
      directory into which you installed the compiler) is overwritten
      by the installation of the C, C++ and FORTRAN compilers.  If
      you have modified this file for licensing, you will need to
      save a copy of the file before installing additional compiler
      products.


