Index: CodeGen/CGExprConstant.cpp =================================================================== --- CodeGen/CGExprConstant.cpp (revision 46389) +++ CodeGen/CGExprConstant.cpp (working copy) @@ -130,38 +181,36 @@ return llvm::ConstantArray::get(AType, Elts); } - + llvm::Constant *VisitImplicitCastExpr(ImplicitCastExpr *ICExpr) { - // If this is due to array->pointer conversion, emit the array expression as - // an l-value. - if (ICExpr->getSubExpr()->getType()->isArrayType()) { - // Note that VLAs can't exist for global variables. - // The only thing that can have array type like this is a - // DeclRefExpr(FileVarDecl)? - const DeclRefExpr *DRE = cast(ICExpr->getSubExpr()); - const VarDecl *VD = cast(DRE->getDecl()); - llvm::Constant *C = CGM.GetAddrOfGlobalVar(VD, false); - assert(isa(C->getType()) && - isa(cast(C->getType()) - ->getElementType())); + Expr* SExpr = ICExpr->getSubExpr(); + QualType SType = SExpr->getType(); + llvm::Constant *C; // the intermediate expression + QualType T; // the type of the intermediate expression + if (SType->isArrayType()) { + // Arrays decay to a pointer to the first element + C = EmitLValue(SExpr); llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); - llvm::Constant *Ops[] = {Idx0, Idx0}; C = llvm::ConstantExpr::getGetElementPtr(C, Ops, 2); - - // The resultant pointer type can be implicitly cast to other pointer - // types as well, for example void*. - const llvm::Type *DestPTy = ConvertType(ICExpr->getType()); - assert(isa(DestPTy) && - "Only expect implicit cast to pointer"); - return llvm::ConstantExpr::getBitCast(C, DestPTy); + + QualType ElemType = SType->getAsArrayType()->getElementType(); + T = CGM.getContext().getPointerType(ElemType); + } else if (SType->isFunctionType()) { + // Function types decay to a pointer to the function + C = EmitLValue(SExpr); + T = CGM.getContext().getPointerType(SType); + } else { + C = Visit(SExpr); + T = SType; } - - llvm::Constant *C = Visit(ICExpr->getSubExpr()); - - return EmitConversion(C, ICExpr->getSubExpr()->getType(),ICExpr->getType()); + + // Perform the conversion; note that we always have to go through + // this step because an implicit cast can both promote and convert + // an array/function + return EmitConversion(C, T, ICExpr->getType()); } - + llvm::Constant *VisitStringLiteral(StringLiteral *E) { const char *StrData = E->getStrData(); unsigned Len = E->getByteLength();