]> granicus.if.org Git - clang/commitdiff
Fix for PR4721: adjust CodeGen and ASTContext so that we have a
authorEli Friedman <eli.friedman@gmail.com>
Sat, 15 Aug 2009 02:50:32 +0000 (02:50 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sat, 15 Aug 2009 02:50:32 +0000 (02:50 +0000)
consistent model for handling size expressions for VLAs.

The model is essentially as follows: VLA types own their associated
expression.  In some cases, we need to create multiple VLA types to
represent a given VLA (for canonical types, or qualifiers on array types,
or type merging).  If we need to create multiple types based off of
the same VLA declaration, we use the new refcounting functionality so they can
all own the expression. The VLASizeMap in CodeGenFunction then uses the size
expression to identify the group of VLA types based off of the same original
declaration.

I'm not particularly attached to the VLA types owning the expression,
but we're stuck with at least until someone comes up with a way
to walk the VLA expressions for a declaration.

I did the parallel fix in ASTContext for DependentSizedArrayType, but I
haven't really looked closely at it, so there might still be issues
there.

I'll clean up the code duplication in ASTContext in a followup commit.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79071 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTContext.cpp
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGen/2009-08-14-vararray-crash.c [new file with mode: 0644]

index c33a74ee95ae52753d486527f740b0c81d1c83a9..dad09babccc271b7d3e5f3a9c84896294986c426 100644 (file)
@@ -2105,14 +2105,16 @@ CanQualType ASTContext::getCanonicalType(QualType T) {
   if (DependentSizedArrayType *DSAT = dyn_cast<DependentSizedArrayType>(AT))
     return CanQualType::CreateUnsafe(
              getDependentSizedArrayType(NewEltTy,
-                                        DSAT->getSizeExpr(),
+                                        DSAT->getSizeExpr() ?
+                                          DSAT->getSizeExpr()->Retain() : 0,
                                         DSAT->getSizeModifier(),
                                         DSAT->getIndexTypeQualifier(),
                                         DSAT->getBracketsRange()));
 
   VariableArrayType *VAT = cast<VariableArrayType>(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<DependentSizedArrayType>(ATy))
     return cast<ArrayType>(
                      getDependentSizedArrayType(NewEltTy, 
-                                                DSAT->getSizeExpr(),
+                                                DSAT->getSizeExpr() ?
+                                              DSAT->getSizeExpr()->Retain() : 0,
                                                 DSAT->getSizeModifier(),
                                                 DSAT->getIndexTypeQualifier(),
                                                 DSAT->getBracketsRange()));
   
   const VariableArrayType *VAT = cast<VariableArrayType>(ATy);
   return cast<ArrayType>(getVariableArrayType(NewEltTy,
-                                              VAT->getSizeExpr(),
+                                              VAT->getSizeExpr() ?
+                                               VAT->getSizeExpr()->Retain() : 0,
                                               VAT->getSizeModifier(),
                                               VAT->getIndexTypeQualifier(),
                                               VAT->getBracketsRange()));
index e4a83bce02960893cef6b01d02813b931b5b93a6..1e8d05261db2d861a4e740247b49c43b9138ce9b 100644 (file)
@@ -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());
index aa4bcceae2676132f0e1543a4372a5e5437cd724..b4469c503b3f53a7a89a2e19bb442062007a6d36 100644 (file)
@@ -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<const VariableArrayType*, llvm::Value*> VLASizeMap;
+  llvm::DenseMap<const Expr*, llvm::Value*> 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 (file)
index 0000000..40e071b
--- /dev/null
@@ -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];
+}