summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Bataev <a.bataev@hotmail.com>2018-10-25 15:35:27 +0000
committerAlexey Bataev <a.bataev@hotmail.com>2018-10-25 15:35:27 +0000
commit8fc7b5f92217bc28e911ca27e20d2880e412aa06 (patch)
treec693aa62309f078c5a3712d5683bdfacc3837a1d
parent8f11ddc397471379a71fa86345e13d35d1ea5fdc (diff)
downloadbcm5719-llvm-8fc7b5f92217bc28e911ca27e20d2880e412aa06.tar.gz
bcm5719-llvm-8fc7b5f92217bc28e911ca27e20d2880e412aa06.zip
[OPENMP]Fix PR39422: variables are not firstprivatized in task context.
According to the OpenMP standard, In a task generating construct, if no default clause is present, a variable for which the data-sharing attribute is not determined by the rules above is firstprivatized. Compiler tries to implement this, but if the variable is not directly used in the task context, this variable may not be firstprivatized. Patch fixes this problem. llvm-svn: 345277
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp27
-rw-r--r--clang/test/OpenMP/parallel_sections_default_messages.cpp2
-rw-r--r--clang/test/OpenMP/task_codegen.cpp1
3 files changed, 27 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 7b4cc9fd170..92d1514ee0c 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -2251,8 +2251,31 @@ public:
}
void VisitStmt(Stmt *S) {
for (Stmt *C : S->children()) {
- if (C && !isa<OMPExecutableDirective>(C))
- Visit(C);
+ if (C) {
+ if (auto *OED = dyn_cast<OMPExecutableDirective>(C)) {
+ // Check implicitly captured vriables in the task-based directives to
+ // check if they must be firstprivatized.
+ if (!OED->hasAssociatedStmt())
+ continue;
+ const Stmt *AS = OED->getAssociatedStmt();
+ if (!AS)
+ continue;
+ for (const CapturedStmt::Capture &Cap :
+ cast<CapturedStmt>(AS)->captures()) {
+ if (Cap.capturesVariable()) {
+ DeclRefExpr *DRE = buildDeclRefExpr(
+ SemaRef, Cap.getCapturedVar(),
+ Cap.getCapturedVar()->getType().getNonLValueExprType(
+ SemaRef.Context),
+ Cap.getLocation(),
+ /*RefersToCapture=*/true);
+ Visit(DRE);
+ }
+ }
+ } else {
+ Visit(C);
+ }
+ }
}
}
diff --git a/clang/test/OpenMP/parallel_sections_default_messages.cpp b/clang/test/OpenMP/parallel_sections_default_messages.cpp
index a62b86ff34a..b16e5f73695 100644
--- a/clang/test/OpenMP/parallel_sections_default_messages.cpp
+++ b/clang/test/OpenMP/parallel_sections_default_messages.cpp
@@ -34,7 +34,7 @@ int main(int argc, char **argv) {
{
#pragma omp parallel sections default(shared)
{
- ++argc;
+ ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}}
}
}
return 0;
diff --git a/clang/test/OpenMP/task_codegen.cpp b/clang/test/OpenMP/task_codegen.cpp
index 05767726f05..b034bb29c88 100644
--- a/clang/test/OpenMP/task_codegen.cpp
+++ b/clang/test/OpenMP/task_codegen.cpp
@@ -107,6 +107,7 @@ int main() {
// CHECK: call i32 @__kmpc_omp_task([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i8* [[ORIG_TASK_PTR]])
#pragma omp task untied
{
+#pragma omp critical
a = 1;
}
// CHECK: [[ORIG_TASK_PTR:%.+]] = call i8* @__kmpc_omp_task_alloc([[IDENT_T]]* @{{.+}}, i32 [[GTID]], i32 0, i64 40, i64 1,
OpenPOWER on IntegriCloud