]> granicus.if.org Git - clang/commitdiff
Fix array->pointer decay. This unbreaks test/CodeGen/array.c
authorChris Lattner <sabre@nondot.org>
Mon, 20 Aug 2007 22:37:10 +0000 (22:37 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 20 Aug 2007 22:37:10 +0000 (22:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41202 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGExpr.cpp
CodeGen/CodeGenFunction.h
test/CodeGen/array.c [new file with mode: 0644]

index 317a5548006e1537f36d1bfde869691a08333e9e..9713cf8e1ae97e4bb9a348fb648dcb52b4673f1c 100644 (file)
@@ -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()))
index 5f78a3373875b002eb40b590f989dcbfb9d08de1..f233108dbd924d38044f3b4d5f4b46796909747c 100644 (file)
@@ -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 (file)
index 0000000..dfbd10d
--- /dev/null
@@ -0,0 +1,6 @@
+// RUN: clang -emit-llvm %s
+
+int f() {
+ int a[2];
+ a[0] = 0;
+}