mirror of
https://github.com/intel/llvm.git
synced 2026-02-05 22:17:23 +08:00
Change EmitVLASize to take a QualType that must be a variably modified type.
Emit the size even if the declared type is a variably modified type. This lets us handle
void f(int n) {
int (*a)[n];
printf("size: %d\n", sizeof(*a));
}
llvm-svn: 61285
This commit is contained in:
@@ -160,9 +160,10 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
|
||||
D.getStorageClass() == VarDecl::Register ? ".reg." : ".auto.";
|
||||
DeclPtr = GenerateStaticBlockVarDecl(D, true, Class);
|
||||
}
|
||||
|
||||
if (Ty->isVariablyModifiedType())
|
||||
EmitVLASize(Ty);
|
||||
} else {
|
||||
const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty);
|
||||
|
||||
if (!StackSaveValues.back()) {
|
||||
// Save the stack.
|
||||
const llvm::Type *LTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
|
||||
@@ -180,7 +181,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
|
||||
const llvm::Type *LElemPtrTy =
|
||||
llvm::PointerType::get(LElemTy, D.getType().getAddressSpace());
|
||||
|
||||
llvm::Value *VLASize = EmitVLASize(VAT);
|
||||
llvm::Value *VLASize = EmitVLASize(Ty);
|
||||
|
||||
// Allocate memory for the array.
|
||||
llvm::Value *VLA = Builder.CreateAlloca(llvm::Type::Int8Ty, VLASize, "vla");
|
||||
|
||||
@@ -410,29 +410,40 @@ llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT)
|
||||
return SizeEntry;
|
||||
}
|
||||
|
||||
llvm::Value *CodeGenFunction::EmitVLASize(const VariableArrayType *VAT)
|
||||
llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty)
|
||||
{
|
||||
llvm::Value *&SizeEntry = VLASizeMap[VAT];
|
||||
|
||||
assert(!SizeEntry && "Must not emit the same VLA size more than once!");
|
||||
// Get the element size;
|
||||
llvm::Value *ElemSize;
|
||||
assert(Ty->isVariablyModifiedType() &&
|
||||
"Must pass variably modified type to EmitVLASizes!");
|
||||
|
||||
QualType ElemTy = VAT->getElementType();
|
||||
|
||||
if (const VariableArrayType *ElemVAT =
|
||||
getContext().getAsVariableArrayType(ElemTy))
|
||||
ElemSize = EmitVLASize(ElemVAT);
|
||||
if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) {
|
||||
llvm::Value *&SizeEntry = VLASizeMap[VAT];
|
||||
|
||||
assert(!SizeEntry && "Must not emit the same VLA size more than once!");
|
||||
|
||||
// Get the element size;
|
||||
llvm::Value *ElemSize;
|
||||
|
||||
QualType ElemTy = VAT->getElementType();
|
||||
|
||||
if (ElemTy->isVariableArrayType())
|
||||
ElemSize = EmitVLASize(ElemTy);
|
||||
else {
|
||||
// FIXME: We use Int32Ty here because the alloca instruction takes a
|
||||
// 32-bit integer. What should we do about overflow?
|
||||
ElemSize = llvm::ConstantInt::get(llvm::Type::Int32Ty,
|
||||
getContext().getTypeSize(ElemTy) / 8);
|
||||
}
|
||||
|
||||
llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr());
|
||||
|
||||
SizeEntry = Builder.CreateMul(ElemSize, NumElements);
|
||||
|
||||
return SizeEntry;
|
||||
} else if (const PointerType *PT = Ty->getAsPointerType())
|
||||
EmitVLASize(PT->getPointeeType());
|
||||
else {
|
||||
// FIXME: We use Int32Ty here because the alloca instruction takes a
|
||||
// 32-bit integer. What should we do about overflow?
|
||||
ElemSize = llvm::ConstantInt::get(llvm::Type::Int32Ty,
|
||||
getContext().getTypeSize(ElemTy) / 8);
|
||||
assert(0 && "unknown VM type!");
|
||||
}
|
||||
|
||||
llvm::Value *NumElements = EmitScalarExpr(VAT->getSizeExpr());
|
||||
|
||||
SizeEntry = Builder.CreateMul(ElemSize, NumElements);
|
||||
|
||||
return SizeEntry;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -350,9 +350,10 @@ public:
|
||||
// instruction in LLVM instead once it works well enough.
|
||||
llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty);
|
||||
|
||||
// EmitVLASize - Generate code for the VLA type. Returns an
|
||||
// lLVM value that corresponds to the size in bytes of the
|
||||
llvm::Value *EmitVLASize(const VariableArrayType *);
|
||||
// EmitVLASize - Generate code for any VLA size expressions that might occur
|
||||
// in a variably modified type. If Ty is a VLA, will return the value that
|
||||
// corresponds to the size in bytes of the VLA type. Will return 0 otherwise.
|
||||
llvm::Value *EmitVLASize(QualType Ty);
|
||||
|
||||
// GetVLASize - Returns an LLVM value that corresponds to the size in bytes
|
||||
// of a variable length array type.
|
||||
|
||||
Reference in New Issue
Block a user