VIEW_CONVERT_EXPR is sometimes used as a way of specifying the size of an object when the size would otherwise be unknown. In the (Ada) testcase an array, the type of which involves placeholder expressions, is view converted to an array type with length 2 (the compiler knows it has length 2, but presumably considers it too hard to work out what value should be substituted in the placeholder in order to get length 2 out, so uses a VIEW_CONVERT_EXPR instead). I think this can only happen for lvalues, though I'm not completely sure. This patch special cases view conversion of aggregate lvalues, using the size of the target type rather than the source type in the call to EmitAggregateCopy.
Ciao, Duncan.
Index: gcc.llvm.master/gcc/llvm-convert.cpp =================================================================== --- gcc.llvm.master.orig/gcc/llvm-convert.cpp 2007-03-08 10:27:40.000000000 +0100 +++ gcc.llvm.master/gcc/llvm-convert.cpp 2007-03-08 13:14:11.000000000 +0100 @@ -2789,25 +2789,50 @@ Value *TreeToLLVM::EmitVIEW_CONVERT_EXPR(tree exp, Value *DestLoc) { tree Op = TREE_OPERAND(exp, 0); - const Type *OpTy = ConvertType(TREE_TYPE(Op)); if (isAggregateTreeType(TREE_TYPE(Op))) { - if (DestLoc) { + const Type *OpTy = ConvertType(TREE_TYPE(Op)); + Value *Target = DestLoc ? // This is an aggregate-to-agg VIEW_CONVERT_EXPR, just evaluate in place. - Value *OpVal = Emit(Op, CastToType(Instruction::BitCast, DestLoc, - PointerType::get(OpTy))); - assert(OpVal == 0 && "Expected an aggregate operand!"); - return 0; - } else { + CastToType(Instruction::BitCast, DestLoc, PointerType::get(OpTy)) : // This is an aggregate-to-scalar VIEW_CONVERT_EXPR, evaluate, then load. - Value *DestLoc = CreateTemporary(OpTy); - Value *OpVal = Emit(Op, DestLoc); + CreateTemporary(OpTy); + + switch (TREE_CODE(Op)) { + default: { + Value *OpVal = Emit(Op, Target); assert(OpVal == 0 && "Expected an aggregate operand!"); - - const Type *ExpTy = ConvertType(TREE_TYPE(exp)); - return new LoadInst(CastToType(Instruction::BitCast, DestLoc, - PointerType::get(ExpTy)), "tmp", CurBB); + break; } + + // Lvalues + case VAR_DECL: + case PARM_DECL: + case RESULT_DECL: + case INDIRECT_REF: + case ARRAY_REF: + case ARRAY_RANGE_REF: + case COMPONENT_REF: + case BIT_FIELD_REF: + case STRING_CST: + case REALPART_EXPR: + case IMAGPART_EXPR: + // Same as EmitLoadOfLValue but taking the size from TREE_TYPE(exp), since + // the size of TREE_TYPE(Op) may not be available. + LValue LV = EmitLV(Op); + assert(!LV.isBitfield() && "Expected an aggregate operand!"); + bool isVolatile = TREE_THIS_VOLATILE(Op); + + EmitAggregateCopy(Target, LV.Ptr, TREE_TYPE(exp), false, isVolatile); + break; + } + + if (DestLoc) + return 0; + + const Type *ExpTy = ConvertType(TREE_TYPE(exp)); + return new LoadInst(CastToType(Instruction::BitCast, Target, + PointerType::get(ExpTy)), "tmp", CurBB); } if (DestLoc) {
Index: llvm.master/test/AdaFrontend/vce.adb =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ llvm.master/test/AdaFrontend/vce.adb 2007-03-08 13:13:06.000000000 +0100 @@ -0,0 +1,7 @@ +-- RUN: %llvmgcc -c %s -o /dev/null +procedure VCE is + S : String (1 .. 2); + B : Character := 'B'; +begin + S := 'A' & B; +end;
_______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits