diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index c33a74ee95..dad09babcc 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2105,14 +2105,16 @@ CanQualType ASTContext::getCanonicalType(QualType T) { if (DependentSizedArrayType *DSAT = dyn_cast(AT)) return CanQualType::CreateUnsafe( getDependentSizedArrayType(NewEltTy, - DSAT->getSizeExpr(), + DSAT->getSizeExpr() ? + DSAT->getSizeExpr()->Retain() : 0, DSAT->getSizeModifier(), DSAT->getIndexTypeQualifier(), DSAT->getBracketsRange())); VariableArrayType *VAT = cast(AT); return CanQualType::CreateUnsafe(getVariableArrayType(NewEltTy, - VAT->getSizeExpr(), + VAT->getSizeExpr() ? + VAT->getSizeExpr()->Retain() : 0, VAT->getSizeModifier(), VAT->getIndexTypeQualifier(), VAT->getBracketsRange())); @@ -2304,14 +2306,16 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) { = dyn_cast(ATy)) return cast( getDependentSizedArrayType(NewEltTy, - DSAT->getSizeExpr(), + DSAT->getSizeExpr() ? + DSAT->getSizeExpr()->Retain() : 0, DSAT->getSizeModifier(), DSAT->getIndexTypeQualifier(), DSAT->getBracketsRange())); const VariableArrayType *VAT = cast(ATy); return cast(getVariableArrayType(NewEltTy, - VAT->getSizeExpr(), + VAT->getSizeExpr() ? + VAT->getSizeExpr()->Retain() : 0, VAT->getSizeModifier(), VAT->getIndexTypeQualifier(), VAT->getBracketsRange())); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index e4a83bce02..1e8d05261d 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -477,7 +477,7 @@ void CodeGenFunction::EmitIndirectSwitches() { } llvm::Value *CodeGenFunction::GetVLASize(const VariableArrayType *VAT) { - llvm::Value *&SizeEntry = VLASizeMap[VAT]; + llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()]; assert(SizeEntry && "Did not emit size for type"); return SizeEntry; @@ -490,7 +490,7 @@ llvm::Value *CodeGenFunction::EmitVLASize(QualType Ty) { EnsureInsertPoint(); if (const VariableArrayType *VAT = getContext().getAsVariableArrayType(Ty)) { - llvm::Value *&SizeEntry = VLASizeMap[VAT]; + llvm::Value *&SizeEntry = VLASizeMap[VAT->getSizeExpr()]; if (!SizeEntry) { const llvm::Type *SizeTy = ConvertType(getContext().getSizeType()); diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index aa4bcceae2..b4469c503b 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -224,9 +224,12 @@ private: llvm::BasicBlock *InvokeDest; // VLASizeMap - This keeps track of the associated size for each VLA type. + // We track this by the size expression rather than the type itself because + // in certain situations, like a const qualifier applied to an VLA typedef, + // multiple VLA types can share the same size expression. // FIXME: Maybe this could be a stack of maps that is pushed/popped as we // enter/leave scopes. - llvm::DenseMap VLASizeMap; + llvm::DenseMap VLASizeMap; /// DidCallStackSave - Whether llvm.stacksave has been called. Used to avoid /// calling llvm.stacksave for multiple VLAs in the same scope. diff --git a/test/CodeGen/2009-08-14-vararray-crash.c b/test/CodeGen/2009-08-14-vararray-crash.c new file mode 100644 index 0000000000..40e071bd19 --- /dev/null +++ b/test/CodeGen/2009-08-14-vararray-crash.c @@ -0,0 +1,11 @@ +// RUN: clang-cc -emit-llvm < %s + +void sum1(int rb) { + typedef unsigned char imgrow[rb]; + typedef imgrow img[rb]; + + const img *br; + int y; + + (*br)[y]; +}