Patch implements passing arrays to functions expecting
vla. Implements pr7827.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114737 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 055e3f7..73e94d1 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -209,17 +209,8 @@
   }
   Value *VisitCastExpr(CastExpr *E) {
     // Make sure to evaluate VLA bounds now so that we have them for later.
-    if (E->getType()->isVariablyModifiedType()) {
-      // Implicit cast of a null pointer to a vla type need not result in vla
-      // size computation which is not always possible in any case (see pr7827).
-      bool NeedSize = true;
-      if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E))
-        NeedSize = 
-          !ICE->getSubExpr()->isNullPointerConstant(CGF.getContext(),
-                                                Expr::NPC_ValueDependentIsNull);
-      if (NeedSize)
-        CGF.EmitVLASize(E->getType());
-    }
+    if (E->getType()->isVariablyModifiedType())
+      CGF.EmitVLASize(E->getType());
 
     return EmitCastExpr(E);
   }
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index c2016e8..5e301b5 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -625,6 +625,9 @@
   EnsureInsertPoint();
 
   if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) {
+    // unknown size indication requires no size computation.
+    if (!VAT->getSizeExpr())
+      return 0;
     llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()];
 
     if (!SizeEntry) {
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 7403711..8dc8ac1 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -1714,12 +1714,26 @@
            E = CallArgTypeInfo->arg_type_end(); I != E; ++I, ++Arg) {
         assert(Arg != ArgEnd && "Running over edge of argument list!");
         QualType ArgType = *I;
-
+#ifndef NDEBUG
+        QualType ActualArgType = Arg->getType();
+        if (ArgType->isPointerType() && ActualArgType->isPointerType()) {
+          QualType ActualBaseType = 
+            ActualArgType->getAs<PointerType>()->getPointeeType();
+          QualType ArgBaseType = 
+            ArgType->getAs<PointerType>()->getPointeeType();
+          if (ArgBaseType->isVariableArrayType()) {
+            if (const VariableArrayType *VAT =
+                getContext().getAsVariableArrayType(ActualBaseType)) {
+              if (!VAT->getSizeExpr())
+                ActualArgType = ArgType;
+            }
+          }
+        }
         assert(getContext().getCanonicalType(ArgType.getNonReferenceType()).
                getTypePtr() ==
-               getContext().getCanonicalType(Arg->getType()).getTypePtr() &&
+               getContext().getCanonicalType(ActualArgType).getTypePtr() &&
                "type mismatch in call argument!");
-
+#endif
         Args.push_back(std::make_pair(EmitCallArg(*Arg, ArgType),
                                       ArgType));
       }