[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