aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-08-20 22:37:10 +0000
committerChris Lattner <sabre@nondot.org>2007-08-20 22:37:10 +0000
commit7016a706c9fab0d7c1603e424c61abbff9077037 (patch)
treeb15513d09afa883cd6da6f36be7e0778643e20df
parent28a7ca80da5dd2d0fca75d9a3b7a5f4851712592 (diff)
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
-rw-r--r--CodeGen/CGExpr.cpp27
-rw-r--r--CodeGen/CodeGenFunction.h2
-rw-r--r--test/CodeGen/array.c6
3 files changed, 34 insertions, 1 deletions
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<SizeOfAlignOfTypeExpr>(E)->isSizeOf());
case Expr::ImplicitCastExprClass:
- return EmitCastExpr(cast<ImplicitCastExpr>(E)->getSubExpr(), E->getType());
+ return EmitImplicitCastExpr(cast<ImplicitCastExpr>(E));
case Expr::CastExprClass:
return EmitCastExpr(cast<CastExpr>(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<ArrayType>(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<llvm::PointerType>(V->getType()) &&
+ isa<llvm::ArrayType>(cast<llvm::PointerType>(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<const ImplicitCastExpr>(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;
+}