[OPENMP] Fix for PR32333: Crash in call of outlined Function.
authorAlexey Bataev <a.bataev@hotmail.com>
Mon, 10 Apr 2017 19:16:45 +0000 (19:16 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Mon, 10 Apr 2017 19:16:45 +0000 (19:16 +0000)
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

clang/lib/CodeGen/CGStmtOpenMP.cpp
clang/test/OpenMP/vla_crash.c [new file with mode: 0644]

index 71d8ea2..22269e4 100644 (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));
diff --git a/clang/test/OpenMP/vla_crash.c b/clang/test/OpenMP/vla_crash.c
new file mode 100644 (file)
index 0000000..50dcf06
--- /dev/null
@@ -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**** {{[^,]+}})
+