From 7016a706c9fab0d7c1603e424c61abbff9077037 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 20 Aug 2007 22:37:10 +0000 Subject: [PATCH] Fix array->pointer decay. This unbreaks test/CodeGen/array.c git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41202 91177308-0d34-0410-b5e6-96231b3b80d8 --- CodeGen/CGExpr.cpp | 27 ++++++++++++++++++++++++++- CodeGen/CodeGenFunction.h | 2 ++ test/CodeGen/array.c | 6 ++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/array.c diff --git a/CodeGen/CGExpr.cpp b/CodeGen/CGExpr.cpp index 317a554800..9713cf8e1a 100644 --- a/CodeGen/CGExpr.cpp +++ b/CodeGen/CGExpr.cpp @@ -586,7 +586,7 @@ RValue CodeGenFunction::EmitExpr(const Expr *E) { E->getType(), cast(E)->isSizeOf()); case Expr::ImplicitCastExprClass: - return EmitCastExpr(cast(E)->getSubExpr(), E->getType()); + return EmitImplicitCastExpr(cast(E)); case Expr::CastExprClass: return EmitCastExpr(cast(E)->getSubExpr(), E->getType()); case Expr::CallExprClass: @@ -660,6 +660,31 @@ RValue CodeGenFunction::EmitCastExpr(const Expr *Op, QualType DestTy) { return EmitConversion(Src, Op->getType(), DestTy); } +/// EmitImplicitCastExpr - Implicit casts are the same as normal casts, but also +/// handle things like function to pointer-to-function decay, and array to +/// pointer decay. +RValue CodeGenFunction::EmitImplicitCastExpr(const ImplicitCastExpr *E) { + const Expr *Op = E->getSubExpr(); + QualType OpTy = Op->getType().getCanonicalType(); + + // If this is due to array->pointer conversion, emit the array expression as + // an l-value. + if (isa(OpTy)) { + // FIXME: For now we assume that all source arrays map to LLVM arrays. This + // will not true when we add support for VLAs. + llvm::Value *V = EmitLValue(Op).getAddress(); // Bitfields can't be arrays. + + assert(isa(V->getType()) && + isa(cast(V->getType()) + ->getElementType()) && + "Doesn't support VLAs yet!"); + llvm::Constant *Idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); + return RValue::get(Builder.CreateGEP(V, Idx0, Idx0, "arraydecay")); + } + + return EmitCastExpr(Op, E->getType()); +} + RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) { if (const ImplicitCastExpr *IcExpr = dyn_cast(E->getCallee())) diff --git a/CodeGen/CodeGenFunction.h b/CodeGen/CodeGenFunction.h index 5f78a33738..f233108dbd 100644 --- a/CodeGen/CodeGenFunction.h +++ b/CodeGen/CodeGenFunction.h @@ -50,6 +50,7 @@ namespace clang { class CharacterLiteral; class TypesCompatibleExpr; + class ImplicitCastExpr; class CastExpr; class CallExpr; class UnaryOperator; @@ -350,6 +351,7 @@ public: RValue EmitCharacterLiteral(const CharacterLiteral *E); RValue EmitTypesCompatibleExpr(const TypesCompatibleExpr *E); + RValue EmitImplicitCastExpr(const ImplicitCastExpr *Op); RValue EmitCastExpr(const Expr *Op, QualType DestTy); RValue EmitCallExpr(const CallExpr *E); RValue EmitBuiltinExpr(unsigned builtinID, const CallExpr *E); diff --git a/test/CodeGen/array.c b/test/CodeGen/array.c new file mode 100644 index 0000000000..dfbd10ddad --- /dev/null +++ b/test/CodeGen/array.c @@ -0,0 +1,6 @@ +// RUN: clang -emit-llvm %s + +int f() { + int a[2]; + a[0] = 0; +} -- 2.40.0