[OPENMP] Fix for PR32333: Crash in call of outlined Function.

If the type of the captured variable is a pointer(s) to variably
modified type, this type was not processed correctly. Need to drill into
the type, find the innermost variably modified array type and convert it
to canonical parameter type.

llvm-svn: 299868
This commit is contained in:
Alexey Bataev 2017-04-10 19:16:45 +00:00
parent ec4880905d
commit f7ce166220
2 changed files with 34 additions and 6 deletions

View File

@ -227,6 +227,17 @@ static Address castValueFromUintptr(CodeGenFunction &CGF, QualType DstType,
return TmpAddr;
}
static QualType getCanonicalParamType(ASTContext &C, QualType T) {
if (T->isLValueReferenceType()) {
return C.getLValueReferenceType(
getCanonicalParamType(C, T.getNonReferenceType()),
/*SpelledAsLValue=*/false);
}
if (T->isPointerType())
return C.getPointerType(getCanonicalParamType(C, T->getPointeeType()));
return C.getCanonicalParamType(T);
}
llvm::Function *
CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
assert(
@ -266,13 +277,8 @@ CodeGenFunction::GenerateOpenMPCapturedStmtFunction(const CapturedStmt &S) {
II = &getContext().Idents.get("vla");
}
if (ArgType->isVariablyModifiedType()) {
bool IsReference = ArgType->isLValueReferenceType();
ArgType =
getContext().getCanonicalParamType(ArgType.getNonReferenceType());
if (IsReference && !ArgType->isPointerType()) {
ArgType = getContext().getLValueReferenceType(
ArgType, /*SpelledAsLValue=*/false);
}
getCanonicalParamType(getContext(), ArgType.getNonReferenceType());
}
Args.push_back(ImplicitParamDecl::Create(getContext(), nullptr,
FD->getLocation(), II, ArgType));

View File

@ -0,0 +1,22 @@
// RUN: %clang_cc1 -verify -triple powerpc64le-unknown-linux-gnu -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
// expected-no-diagnostics
int a;
// CHECK-LABEL: foo
void foo() {
int(*b)[a];
int *(**c)[a];
// CHECK: [[B:%.+]] = alloca i32*,
// CHECK: [[C:%.+]] = alloca i32***,
// CHECK: @__kmpc_global_thread_num
// CHECK: call void @__kmpc_serialized_parallel
// CHECK: call void [[OUTLINED:@[^(]+]](i32* %{{[^,]+}}, i32* %{{[^,]+}}, i64 %{{[^,]+}}, i32** [[B]], i64 %{{[^,]+}}, i32**** [[C]])
// CHECK: call void @__kmpc_end_serialized_parallel
// CHECK: ret void
#pragma omp parallel if (0)
b[0][0] = c[0][a][0][a];
}
// CHECK: define internal void [[OUTLINED]](i32* {{[^,]+}}, i32* {{[^,]+}}, i64 {{[^,]+}}, i32** {{[^,]+}}, i64 {{[^,]+}}, i32**** {{[^,]+}})