ICE in LLVM GCC4 Front End

[Reposted from llvm-bugs mailing list. Also has an updated, hopefully better, patch associated with it.]

Hi,

The following program causes the LLVM GCC4 front end to ICE:

struct A {
   virtual ~A();
};

template <typename Ty>
struct B : public A {
   ~B () { delete val; }
private:
     Ty* val;
};

template <typename Ty>
struct C : public A {
   C ();
   ~C ();
};

template <typename Ty>
struct D : public A {
     D () {}
   private:
     B<C<Ty> > blocks;
};

template class D<double>;

I'm far from an expert on this area of the code base, so I'm submitting this as a proposed fix:

Index: gcc/llvm-convert.cpp

I'm far from an expert on this area of the code base, so I'm
submitting this as a proposed fix:

Patch looks great. I switched it to use "if (ElTy->isSized())" instead of checking to see if it's abstract. Types like "{ opaque* }" are considered abstract (because they contain an opaque type in the type graph) but they have a size (in this case, sizeof(pointer)).

Thanks for tracking this down! I've applied the fix.

-Chris

Index: gcc/llvm-convert.cpp

--- gcc/llvm-convert.cpp (revision 166)
+++ gcc/llvm-convert.cpp (working copy)
@@ -2202,18 +2202,23 @@

     // Figure out how large the element pointed to is.
     const Type *ElTy = cast<PointerType>(LHS->getType())-
>getElementType();
- int64_t EltSize = TD.getTypeSize(ElTy);
+
+ if (!ElTy->isAbstract()) {
+ // We can only get the type size (and thus convert to using a
GEP instr)
+ // if the type isn't abstract
+ int64_t EltSize = TD.getTypeSize(ElTy);

- // If EltSize exactly divides Offset, then we know that we can
turn this
- // into a getelementptr instruction.
- int64_t EltOffset = Offset/EltSize;
- if (EltOffset*EltSize == Offset) {
- // If this is a subtract, we want to step backwards.
- if (Opc == Instruction::Sub)
- EltOffset = -EltOffset;
- Constant *C = ConstantSInt::get(Type::LongTy, EltOffset);
- Value *V = new GetElementPtrInst(LHS, C, "tmp", CurBB);
- return CastToType(V, TREE_TYPE(exp));
+ // If EltSize exactly divides Offset, then we know that we can
turn
+ // this into a getelementptr instruction.
+ int64_t EltOffset = Offset/EltSize;
+ if (EltOffset*EltSize == Offset) {
+ // If this is a subtract, we want to step backwards.
+ if (Opc == Instruction::Sub)
+ EltOffset = -EltOffset;
+ Constant *C = ConstantSInt::get(Type::LongTy, EltOffset);
+ Value *V = new GetElementPtrInst(LHS, C, "tmp", CurBB);
+ return CastToType(V, TREE_TYPE(exp));
+ }
     }
   }

_______________________________________________
LLVM Developers mailing list
LLVMdev@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-Chris