Fix for PR21915: assert on multidimensional VLA in function arguments.

Fixed assertion on type checking for arguments and parameters on function call if arguments are pointers to VLA
Differential Revision: http://reviews.llvm.org/D6655

llvm-svn: 224504
This commit is contained in:
Alexey Bataev 2014-12-18 06:54:53 +00:00
parent f5ba8288ad
commit 7cb1789011
3 changed files with 59 additions and 22 deletions

View File

@ -2746,28 +2746,13 @@ public:
E = CallArgTypeInfo->param_type_end();
I != E; ++I, ++Arg) {
assert(Arg != ArgEnd && "Running over edge of argument list!");
#ifndef NDEBUG
QualType ArgType = *I;
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())
assert(
((*I)->isVariablyModifiedType() ||
getContext()
.getCanonicalType((*I).getNonReferenceType())
.getTypePtr() ==
getContext().getCanonicalType(ActualArgType).getTypePtr() &&
getContext().getCanonicalType(Arg->getType()).getTypePtr()) &&
"type mismatch in call argument!");
#endif
ArgTypes.push_back(*I);
}
}

View File

@ -0,0 +1,30 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
int c[1][3*2];
// CHECK: @{{.+}} = {{.*}} global [1 x [6 x {{i[0-9]+}}]] zeroinitializer
// CHECK-LABEL: @f
int f(int * const m, int (**v)[*m * 2])
{
return &(c[0][*m]) == &((*v)[0][*m]);
// CHECK: icmp
// CHECK: ret i{{[0-9]+}}
}
// CHECK-LABEL: @test
int test(int n, int (*(*fn)(void))[n]) {
return (*fn())[0];
}
// CHECK-LABEL: @main
int main()
{
int m = 3;
int (*d)[3*2] = c;
int (*fn[m])(void);
return f(&m, &d) + test(m, &fn);
// CHECK: call {{.+}} @f(
// CHECK: ret i{{[0-9]+}}
}

View File

@ -0,0 +1,22 @@
// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s
// CHECK-LABEL: @main
struct dyn_array {
int size;
int data[];
};
int foo(dyn_array **&d) {
return (*d)->data[1];
}
int main()
{
dyn_array **d;
return foo(d);
// CHECK: call {{.+}} @{{.+}}foo{{.+}}(
// CHECK: ret i{{[0-9]+}}
}