[cfe-commits] r114737 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Type.h include/clang/Sema/Initialization.h lib/AST/ASTContext.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.cpp lib/CodeGen/CodeGenFunction.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaOverload.cpp test/CodeGen/vla.c

Fariborz Jahanian fjahanian at apple.com
Fri Sep 24 10:30:16 PDT 2010


Author: fjahanian
Date: Fri Sep 24 12:30:16 2010
New Revision: 114737

URL: http://llvm.org/viewvc/llvm-project?rev=114737&view=rev
Log:
Patch implements passing arrays to functions expecting
vla. Implements pr7827.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/include/clang/Sema/Initialization.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CodeGen/vla.c

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Sep 24 12:30:16 2010
@@ -568,6 +568,14 @@
   QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize,
                                 ArrayType::ArraySizeModifier ASM,
                                 unsigned EltTypeQuals);
+  
+  /// getUnknownSizeVariableArrayType - Return a variable array type with
+  /// all variable indices replaced with unknow [*] size.
+  QualType getUnknownSizeVariableArrayType(QualType Ty);
+  
+  /// getVariableArrayDecayedType - Returns a vla type where known sizes
+  /// are replaced with [*]
+  QualType getVariableArrayDecayedType(QualType Ty);
 
   /// getVectorType - Return the unique reference to a vector type of
   /// the specified element type and size. VectorType must be a built-in type.

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Fri Sep 24 12:30:16 2010
@@ -3281,7 +3281,17 @@
 
 inline bool QualType::isCanonicalAsParam() const {
   if (hasLocalQualifiers()) return false;
+  
   const Type *T = getTypePtr();
+  if ((*this)->isPointerType()) {
+    QualType BaseType = (*this)->getAs<PointerType>()->getPointeeType();
+    if (isa<VariableArrayType>(BaseType)) {
+      ArrayType *AT = dyn_cast<ArrayType>(BaseType);
+      VariableArrayType *VAT = cast<VariableArrayType>(AT);
+      if (VAT->getSizeExpr())
+        T = BaseType.getTypePtr();
+    }
+  }
   return T->isCanonicalUnqualified() &&
            !isa<FunctionType>(T) && !isa<ArrayType>(T);
 }

Modified: cfe/trunk/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Initialization.h?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Initialization.h (original)
+++ cfe/trunk/include/clang/Sema/Initialization.h Fri Sep 24 12:30:16 2010
@@ -152,16 +152,20 @@
   }
   
   /// \brief Create the initialization entity for a parameter.
-  static InitializedEntity InitializeParameter(ParmVarDecl *Parm) {
-    return InitializedEntity(Parm);
+  static InitializedEntity InitializeParameter(ASTContext &Context,
+                                               ParmVarDecl *Parm) {
+    InitializedEntity Res(Parm);
+    Res.Type = Context.getVariableArrayDecayedType(Res.Type);
+    return Res;
   }
 
   /// \brief Create the initialization entity for a parameter that is
   /// only known by its type.
-  static InitializedEntity InitializeParameter(QualType Type) {
+  static InitializedEntity InitializeParameter(ASTContext &Context,
+                                               QualType Type) {
     InitializedEntity Entity;
     Entity.Kind = EK_Parameter;
-    Entity.Type = Type;
+    Entity.Type = Context.getVariableArrayDecayedType(Type);
     Entity.Parent = 0;
     Entity.VariableOrMember = 0;
     return Entity;

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Sep 24 12:30:16 2010
@@ -1413,6 +1413,54 @@
   return QualType(New, 0);
 }
 
+/// getIncompleteArrayType - Returns a unique reference to the type for a
+/// incomplete array of the specified element type.
+QualType ASTContext::getUnknownSizeVariableArrayType(QualType Ty) {
+  QualType ElemTy = getBaseElementType(Ty);
+  DeclarationName Name;
+  llvm::SmallVector<QualType, 8> ATypes;
+  QualType ATy = Ty;
+  while (const ArrayType *AT = getAsArrayType(ATy)) {
+    ATypes.push_back(ATy);
+    ATy = AT->getElementType();
+  }
+  for (int i = ATypes.size() - 1; i >= 0; i--) {
+    if (const VariableArrayType *VAT = getAsVariableArrayType(ATypes[i])) {
+      ElemTy = getVariableArrayType(ElemTy, /*ArraySize*/0, ArrayType::Star,
+                                    0, VAT->getBracketsRange());
+    }
+    else if (const ConstantArrayType *CAT = getAsConstantArrayType(ATypes[i])) {
+      llvm::APSInt ConstVal(CAT->getSize());
+      ElemTy = getConstantArrayType(ElemTy, ConstVal, ArrayType::Normal, 0);
+    }
+    else if (getAsIncompleteArrayType(ATypes[i])) {
+      ElemTy = getVariableArrayType(ElemTy, /*ArraySize*/0, ArrayType::Normal,
+                                    0, SourceRange());
+    }
+    else
+      assert(false && "DependentArrayType is seen");
+  }
+  return ElemTy;
+}
+
+/// getVariableArrayDecayedType - Returns a vla type where known sizes
+/// are replaced with [*]
+QualType ASTContext::getVariableArrayDecayedType(QualType Ty) {
+  if (Ty->isPointerType()) {
+    QualType BaseType = Ty->getAs<PointerType>()->getPointeeType();
+    if (isa<VariableArrayType>(BaseType)) {
+      ArrayType *AT = dyn_cast<ArrayType>(BaseType);
+      VariableArrayType *VAT = cast<VariableArrayType>(AT);
+      if (VAT->getSizeExpr()) {
+        Ty = getUnknownSizeVariableArrayType(BaseType);
+        Ty = getPointerType(Ty);
+      }
+    }
+  }
+  return Ty;
+}
+
+
 /// getVariableArrayType - Returns a non-unique reference to the type for a
 /// variable array of the specified element type.
 QualType ASTContext::getVariableArrayType(QualType EltTy,
@@ -2396,8 +2444,8 @@
   // Push qualifiers into arrays, and then discard any remaining
   // qualifiers.
   T = getCanonicalType(T);
+  T = getVariableArrayDecayedType(T);
   const Type *Ty = T.getTypePtr();
-
   QualType Result;
   if (isa<ArrayType>(Ty)) {
     Result = getArrayDecayedType(QualType(Ty,0));
@@ -2737,7 +2785,6 @@
                                               VAT->getBracketsRange()));
 }
 
-
 /// getArrayDecayedType - Return the properly qualified result of decaying the
 /// specified array type to a pointer.  This operation is non-trivial when
 /// handling typedefs etc.  The canonical type of "T" must be an array type,

Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Fri Sep 24 12:30:16 2010
@@ -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);
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Fri Sep 24 12:30:16 2010
@@ -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) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Sep 24 12:30:16 2010
@@ -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));
       }

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Sep 24 12:30:16 2010
@@ -125,7 +125,8 @@
   //   the same semantic constraints as the initializer expression in
   //   a declaration of a variable of the parameter type, using the
   //   copy-initialization semantics (8.5).
-  InitializedEntity Entity = InitializedEntity::InitializeParameter(Param);
+  InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
+                                                                    Param);
   InitializationKind Kind = InitializationKind::CreateCopy(Param->getLocation(),
                                                            EqualLoc);
   InitializationSequence InitSeq(*this, Entity, Kind, &Arg, 1);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Sep 24 12:30:16 2010
@@ -3435,7 +3435,7 @@
 
     // Check the expression as an initializer for the parameter.
     InitializedEntity Entity
-      = InitializedEntity::InitializeParameter(Param);
+      = InitializedEntity::InitializeParameter(Context, Param);
     InitializationKind Kind
       = InitializationKind::CreateCopy(Param->getLocation(),
              /*FIXME:EqualLoc*/UninstExpr->getSourceRange().getBegin());
@@ -3564,10 +3564,9 @@
       if (FDecl && i < FDecl->getNumParams())
         Param = FDecl->getParamDecl(i);
 
-
       InitializedEntity Entity =
-        Param? InitializedEntity::InitializeParameter(Param)
-             : InitializedEntity::InitializeParameter(ProtoArgType);
+        Param? InitializedEntity::InitializeParameter(Context, Param)
+             : InitializedEntity::InitializeParameter(Context, ProtoArgType);
       ExprResult ArgE = PerformCopyInitialization(Entity,
                                                         SourceLocation(),
                                                         Owned(Arg));
@@ -6232,12 +6231,12 @@
                   LHSTy->isRecordType());
   if (copyInit) {
     InitializedEntity Entity = 
-    InitializedEntity::InitializeParameter(LHSTy);
+    InitializedEntity::InitializeParameter(Context, LHSTy);
     Expr *Arg = RHS;
     ExprResult ArgE = PerformCopyInitialization(Entity, SourceLocation(),
                                                 Owned(Arg));
     if (!ArgE.isInvalid())
-      RHS = ArgE.takeAs<Expr>();
+      RHS = ArgE.takeAs<Expr>(); 
   }
 }
   

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Sep 24 12:30:16 2010
@@ -1194,6 +1194,7 @@
     for (unsigned i = 0; (i < NumArgs && i < NumArgsInFnDecl); ++i) {
       ExprResult Result
         = PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                       Context,
                                                        FnDecl->getParamDecl(i)),
                                     SourceLocation(),
                                     Owned(Args[i]->Retain()));

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Sep 24 12:30:16 2010
@@ -241,7 +241,8 @@
                               << argExpr->getSourceRange()))
       return true;
 
-    InitializedEntity Entity = InitializedEntity::InitializeParameter(Param);
+    InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
+                                                                      Param);
     ExprResult ArgE = PerformCopyInitialization(Entity,
                                                       SourceLocation(),
                                                       Owned(argExpr->Retain()));

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Sep 24 12:30:16 2010
@@ -6864,6 +6864,7 @@
         // Convert the arguments.
         ExprResult InputInit
           = PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                      Context,
                                                       FnDecl->getParamDecl(0)),
                                       SourceLocation(), 
                                       Input);
@@ -7045,6 +7046,7 @@
           ExprResult Arg1
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
+                                                        Context,
                                                         FnDecl->getParamDecl(0)),
                                         SourceLocation(),
                                         Owned(Args[1]));
@@ -7061,6 +7063,7 @@
           ExprResult Arg0
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
+                                                        Context,
                                                         FnDecl->getParamDecl(0)),
                                         SourceLocation(),
                                         Owned(Args[0]));
@@ -7070,6 +7073,7 @@
           ExprResult Arg1
             = PerformCopyInitialization(
                                         InitializedEntity::InitializeParameter(
+                                                        Context,
                                                         FnDecl->getParamDecl(1)),
                                         SourceLocation(),
                                         Owned(Args[1]));
@@ -7229,6 +7233,7 @@
         // Convert the arguments.
         ExprResult InputInit
           = PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                      Context,
                                                       FnDecl->getParamDecl(0)),
                                       SourceLocation(), 
                                       Owned(Args[1]));
@@ -7666,6 +7671,7 @@
 
       ExprResult InputInit
         = PerformCopyInitialization(InitializedEntity::InitializeParameter(
+                                                    Context,
                                                     Method->getParamDecl(i)),
                                     SourceLocation(), Arg);
       

Modified: cfe/trunk/test/CodeGen/vla.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/vla.c?rev=114737&r1=114736&r2=114737&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/vla.c (original)
+++ cfe/trunk/test/CodeGen/vla.c Fri Sep 24 12:30:16 2010
@@ -52,10 +52,24 @@
 }
 
 // pr7827
-void function(short width, int data[][width]) {}
+void function(short width, int data[][width]) {} // expected-note {{passing argument to parameter 'data' here}}
 
 void test() {
+     int bork[4][13];
      // CHECK: call void @function(i16 signext 1, i32* null)
      function(1, 0);
+     // CHECK: call void @function(i16 signext 1, i32* inttoptr
+     function(1, 0xbadbeef); // expected-warning {{incompatible integer to pointer conversion passing}}
+     // CHECK: call void @function(i16 signext 1, i32* {{.*}})
+     function(1, bork);
+}
+
+void function1(short width, int data[][width][width]) {}
+void test1() {
+     int bork[4][13][15];
+     // CHECK: call void @function1(i16 signext 1, i32* {{.*}})
+     function1(1, bork);
+     // CHECK: call void @function(i16 signext 1, i32* {{.*}}) 
+     function(1, bork[2]);
 }
 





More information about the cfe-commits mailing list