From: johnston@cs.utexas.edu (Mark Stuart Johnstone)
Subject: bug report
Organization: GNUs Not Usenet
Distribution: gnu
Date: Fri, 8 Jan 1993 05:14:20 GMT

Hello,

In the process of trying to put together a short program to see if a
problem I am having is a compiler bug, I came across an error
message:

foo.c:118: Internal compiler error.
foo.c:118: Please report this to `bug-g++@prep.ai.mit.edu'.

So, here is the report, and what follows is the file that generates the
error when compiled as follows:

oporto:~/garbage> g++ -V 2.3.3-930101 foo.c

I hope it helps.

--Mark Johnstone

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

class BRefBase {
 protected:
  void* Ptr(const BRefAny& bra ) { return bra.ptr; }
};

class BRefAny {
 private:
  // These are all used to figure out RCMap's.
  static RCMap* curMap;
  static void* containerStart;
  static void CtorInit(void* ptrStart, void*&);
  static void CtorNorm(void*, void*& ptr);
  static void (*Ctor)(void*, void*&);
  static void SetCtorInit() {
    Ctor = CtorInit;
    curMap = new RCMap;
  }
  static void SetCtorNorm() {Ctor = CtorNorm; }
  friend class RCMapperBase;

 protected:
  // This is the pointer to the heap-allocated object.
  void* ptr;
#ifdef ULTRASAFE
  volatile void* ptr2;
#endif

  BRefAny() { Ctor(this, ptr); }

  // This adds ptr, which must be a RefTargetBase*, to the ZCL.
  void Delete(void* ptr);
  
 public:

  int operator==(const BRefAny& ra) const;
  int operator!=(const BRefAny& ra) const;

  // Returns TRUE iff the RefAny is NULL.
  int IsNull() const;
  operator int() const;

  int TypeCode() const;

  // This is the heap from which the reference objects are allocated.
  static Heap heap;

  // These are for statistics-gathering.
  static int nStackAssigns;
  static int nStackCCs;
  static int nHeapAssigns;
  static int nHeapCCs;


  friend class RefAny;
  friend class SRefAny;

  friend class BRefBase;
};

// BRef means "Base Ref."  Both Ref and SRef are derived from BRef, which
// provides some shared implementations and also provides type-checking.

template<class T> class BRef: public BRefAny, public BRefBase {
  static RCMapperIndirect<T>* rcmti;

 protected:
  // Protected constructor makes an "abstract class."
  BRef() {};			// Initialize to NIL

  // This allows a "widen" to set the 'ptr' of a Ref<T> or SRef<T>.
  void SetPtr(BRef<T>& brt, void* ptr) {
    brt.ptr = ptr;
  }

 public:
  void New();

  // overloaded pointer operations.
  int operator==(const BRefAny& ra) const {
    return (*((BRefAny*)this)) == ra;
  }
  int operator!=(const BRefAny& ra) const {
    return (*((BRefAny*)this)) != ra;
  }

  // dereference operators.  These can't be inline at present because
  // that precludes linked-list-style types.
  T& operator*() const;
  T* operator->() const;

  // Typecode.
  static int StatTypeCode();
  int TypeCode() const { return StatTypeCode(); }

 friend class Ref<T>;
 friend class SRef<T>;
 friend class WidenBase<T>;
};

// An SRef (Stack Ref) does no reference counting.
template<class T> class SRef: public BRef<T> {
 public:
  SRef() {};			// Does nothing.
  
  void New();			// Allocate a new T on the heap.

  // Copy constructors.
  SRef(const SRef<T>& rt) {
#ifdef DEBUG
    nStackCCs++;
#endif
    ptr = rt.ptr;
#ifdef ULTRASAFE
    ptr2 = ptr;
#endif
  }
  SRef(const Ref<T>& rt) {
#ifdef DEBUG
    nStackCCs++;
#endif
    ptr = ((BRef<T>&)rt).ptr;
#ifdef ULTRASAFE
    ptr2 = ptr;
#endif
  }
  // Throws NarrowFault if bra is not a Ref<T>.
  SRef(const BRefAny& bra) {exit (NarrowFault);}
  
  
  // Assignment operators.
  SRef<T>& operator=(const Ref<T>& rt) {
#ifdef DEBUG
    nStackAssigns++;
#endif
    ptr = ((BRef<T>&)rt).ptr;
#ifdef ULTRASAFE
    ptr2 = ptr;
#endif
  }
  // I don't completely understand if this one is necessary, and not
  // taken care of by the const BRef<T>& version.  But, to be consistent
  // with Ref<T>...
  SRef<T>& operator=(const SRef<T>& srt) {
#ifdef DEBUG
    nStackAssigns++;
#endif
    ptr = srt.ptr;
#ifdef ULTRASAFE
    ptr2 = ptr;
#endif
  }
  // Throws NarrowFault if bra is not a Ref<T>.
  SRef<T>& operator=(const BRefAny& bra) {exit (NarrowFault);}

 private:
  // This is for use in the debugger.
  T* v();
  
};

struct GorpA {
  int i;
  GorpA() { i = 7; }
};

struct GorpB: public GorpA {
  int j;
  GorpB() { j = 77; }
};

void fooGorpA(SRef<GorpA> srga) {
  cout << "In fooGorpA!\n";
}

void fooGorpB(SRef<GorpB> srgb) {
  cout << "In fooGorpB!\n";
}

void test_Narrow() {
  Ref<GorpA> rga1;
  rga1.New();
  RefAny ra;
  ra = rga1;
//  try {
    Ref<GorpB> rgb;
    rgb = ra;
//  } catch(NarrowFault) {
//    cout << "rgb = ra raised NarrowFault...\n";
//  }
  cout << "After rgb = ra; should have raised NarrowFault above...\n";

  Ref<GorpA> rga2 = ra;
  cout << "After Narrow<GorpA>(ra); didn't raise exception.\n";

//  try {
    SRef<GorpA> temporary(ra);
    fooGorpA(temporary);
    fooGorpB(ra);
//  } catch(NarrowFault) {
//    cout << "Someone (correctly) raised NarrowFault...\n";
//  }
}


Newsgroups: gnu.g++.bug