ABataev created this revision.
ABataev added reviewers: NoQ, Szelethus, dcoughlin, xazax.hun, a.sidorin, 
george.karpenkov, szepet.
Herald added subscribers: jdoerfert, jfb, guansong, rnkovacs.
Herald added a project: clang.

Some OpenMP clauses rely on the values of the variables. If the variable
is not initialized and used in OpenMP clauses that depend on the
variables values, it should be reported that the uninitialized variable
is used in the OpenMP clause expression.
This patch adds initial processing for uninitialized variables in OpenMP
constructs. Currently, it checks for use of the uninitialized variables
in the structured blocks.


Repository:
  rC Clang

https://reviews.llvm.org/D64356

Files:
  include/clang/AST/StmtOpenMP.h
  lib/AST/StmtOpenMP.cpp
  lib/Analysis/CFG.cpp
  lib/Analysis/UninitializedValues.cpp
  test/OpenMP/atomic_messages.c
  test/OpenMP/critical_messages.cpp
  test/OpenMP/distribute_parallel_for_messages.cpp
  test/OpenMP/distribute_parallel_for_simd_misc_messages.c
  test/OpenMP/distribute_simd_misc_messages.c
  test/OpenMP/for_misc_messages.c
  test/OpenMP/for_simd_misc_messages.c
  test/OpenMP/master_messages.cpp
  test/OpenMP/ordered_messages.cpp
  test/OpenMP/parallel_for_messages.cpp
  test/OpenMP/parallel_for_simd_messages.cpp
  test/OpenMP/parallel_messages.cpp
  test/OpenMP/parallel_sections_messages.cpp
  test/OpenMP/sections_misc_messages.c
  test/OpenMP/simd_misc_messages.c
  test/OpenMP/single_misc_messages.c
  test/OpenMP/target_depend_messages.cpp
  test/OpenMP/target_parallel_for_messages.cpp
  test/OpenMP/target_parallel_for_simd_messages.cpp
  test/OpenMP/target_parallel_messages.cpp
  test/OpenMP/target_simd_messages.cpp
  test/OpenMP/target_teams_distribute_messages.cpp
  test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
  test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
  test/OpenMP/target_teams_distribute_simd_messages.cpp
  test/OpenMP/target_teams_messages.cpp
  test/OpenMP/target_update_messages.cpp
  test/OpenMP/task_messages.cpp
  test/OpenMP/taskgroup_messages.cpp
  test/OpenMP/taskloop_misc_messages.c
  test/OpenMP/taskloop_simd_misc_messages.c
  test/OpenMP/teams_distribute_parallel_for_messages.cpp
  test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
  test/OpenMP/teams_distribute_simd_messages.cpp
  test/OpenMP/teams_messages.cpp

Index: test/OpenMP/teams_messages.cpp
===================================================================
--- test/OpenMP/teams_messages.cpp
+++ test/OpenMP/teams_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target
+#pragma omp teams
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/teams_distribute_simd_messages.cpp
===================================================================
--- test/OpenMP/teams_distribute_simd_messages.cpp
+++ test/OpenMP/teams_distribute_simd_messages.cpp
@@ -2,6 +2,14 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
===================================================================
--- test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
+++ test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
@@ -2,6 +2,14 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/teams_distribute_parallel_for_messages.cpp
===================================================================
--- test/OpenMP/teams_distribute_parallel_for_messages.cpp
+++ test/OpenMP/teams_distribute_parallel_for_messages.cpp
@@ -2,6 +2,14 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/taskloop_simd_misc_messages.c
===================================================================
--- test/OpenMP/taskloop_simd_misc_messages.c
+++ test/OpenMP/taskloop_simd_misc_messages.c
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -triple x86_64-unknown-unknown -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp taskloop simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp taskloop simd'}}
 #pragma omp taskloop simd
 
Index: test/OpenMP/taskloop_misc_messages.c
===================================================================
--- test/OpenMP/taskloop_misc_messages.c
+++ test/OpenMP/taskloop_misc_messages.c
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -triple x86_64-unknown-unknown -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp taskloop'}}
 #pragma omp taskloop
 
Index: test/OpenMP/taskgroup_messages.cpp
===================================================================
--- test/OpenMP/taskgroup_messages.cpp
+++ test/OpenMP/taskgroup_messages.cpp
@@ -2,6 +2,12 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp taskgroup
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 int foo();
 
 int main() {
Index: test/OpenMP/task_messages.cpp
===================================================================
--- test/OpenMP/task_messages.cpp
+++ test/OpenMP/task_messages.cpp
@@ -2,6 +2,12 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp task
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_update_messages.cpp
===================================================================
--- test/OpenMP/target_update_messages.cpp
+++ test/OpenMP/target_update_messages.cpp
@@ -2,6 +2,12 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target update to(x)
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_teams_messages.cpp
===================================================================
--- test/OpenMP/target_teams_messages.cpp
+++ test/OpenMP/target_teams_messages.cpp
@@ -2,6 +2,12 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target teams
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_teams_distribute_simd_messages.cpp
===================================================================
--- test/OpenMP/target_teams_distribute_simd_messages.cpp
+++ test/OpenMP/target_teams_distribute_simd_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
===================================================================
--- test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
+++ test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
===================================================================
--- test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
+++ test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_teams_distribute_messages.cpp
===================================================================
--- test/OpenMP/target_teams_distribute_messages.cpp
+++ test/OpenMP/target_teams_distribute_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_simd_messages.cpp
===================================================================
--- test/OpenMP/target_simd_messages.cpp
+++ test/OpenMP/target_simd_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_parallel_messages.cpp
===================================================================
--- test/OpenMP/target_parallel_messages.cpp
+++ test/OpenMP/target_parallel_messages.cpp
@@ -1,9 +1,15 @@
 // RUN: %clang_cc1 -verify -fopenmp -std=c++11 -o - %s -Wuninitialized
 // RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=aaa-bbb-ccc-ddd -o - %s 2>&1 | FileCheck %s
 
-// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s -Wuninitialized
 // CHECK: error: OpenMP target is invalid: 'aaa-bbb-ccc-ddd'
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target parallel
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_parallel_for_simd_messages.cpp
===================================================================
--- test/OpenMP/target_parallel_for_simd_messages.cpp
+++ test/OpenMP/target_parallel_for_simd_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_parallel_for_messages.cpp
===================================================================
--- test/OpenMP/target_parallel_for_messages.cpp
+++ test/OpenMP/target_parallel_for_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/target_depend_messages.cpp
===================================================================
--- test/OpenMP/target_depend_messages.cpp
+++ test/OpenMP/target_depend_messages.cpp
@@ -2,6 +2,12 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - -std=c++11 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp target depend(in : argc)
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/single_misc_messages.c
===================================================================
--- test/OpenMP/single_misc_messages.c
+++ test/OpenMP/single_misc_messages.c
@@ -2,6 +2,12 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp single
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo();
 
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp single'}}
Index: test/OpenMP/simd_misc_messages.c
===================================================================
--- test/OpenMP/simd_misc_messages.c
+++ test/OpenMP/simd_misc_messages.c
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp simd'}}
 #pragma omp simd
 
Index: test/OpenMP/sections_misc_messages.c
===================================================================
--- test/OpenMP/sections_misc_messages.c
+++ test/OpenMP/sections_misc_messages.c
@@ -2,6 +2,14 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp sections
+{
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+}
+
 void foo();
 
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp sections'}}
Index: test/OpenMP/parallel_sections_messages.cpp
===================================================================
--- test/OpenMP/parallel_sections_messages.cpp
+++ test/OpenMP/parallel_sections_messages.cpp
@@ -2,6 +2,14 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp parallel sections
+{
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/parallel_messages.cpp
===================================================================
--- test/OpenMP/parallel_messages.cpp
+++ test/OpenMP/parallel_messages.cpp
@@ -5,6 +5,12 @@
 void foo() {
 }
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp parallel
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 #pragma omp parallel // expected-error {{unexpected OpenMP directive '#pragma omp parallel'}}
 
 int a;
Index: test/OpenMP/parallel_for_simd_messages.cpp
===================================================================
--- test/OpenMP/parallel_for_simd_messages.cpp
+++ test/OpenMP/parallel_for_simd_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/parallel_for_messages.cpp
===================================================================
--- test/OpenMP/parallel_for_messages.cpp
+++ test/OpenMP/parallel_for_messages.cpp
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp parallel for
+  for(int i = 0; i < 10; ++i)
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 void foo() {
 }
 
Index: test/OpenMP/ordered_messages.cpp
===================================================================
--- test/OpenMP/ordered_messages.cpp
+++ test/OpenMP/ordered_messages.cpp
@@ -6,6 +6,14 @@
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++98 -o - %s -Wuninitialized
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp for ordered
+  for(int i = 0; i < 10; ++i)
+#pragma omp ordered
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 int foo();
 
 template <class T>
Index: test/OpenMP/master_messages.cpp
===================================================================
--- test/OpenMP/master_messages.cpp
+++ test/OpenMP/master_messages.cpp
@@ -2,6 +2,12 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp master
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 int foo();
 
 int main() {
Index: test/OpenMP/for_simd_misc_messages.c
===================================================================
--- test/OpenMP/for_simd_misc_messages.c
+++ test/OpenMP/for_simd_misc_messages.c
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp for simd'}}
 #pragma omp for simd
 
Index: test/OpenMP/for_misc_messages.c
===================================================================
--- test/OpenMP/for_misc_messages.c
+++ test/OpenMP/for_misc_messages.c
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -triple x86_64-unknown-unknown -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp for
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp for'}}
 #pragma omp for
 
Index: test/OpenMP/distribute_simd_misc_messages.c
===================================================================
--- test/OpenMP/distribute_simd_misc_messages.c
+++ test/OpenMP/distribute_simd_misc_messages.c
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute simd'}}
 #pragma omp distribute simd
 
Index: test/OpenMP/distribute_parallel_for_simd_misc_messages.c
===================================================================
--- test/OpenMP/distribute_parallel_for_simd_misc_messages.c
+++ test/OpenMP/distribute_parallel_for_simd_misc_messages.c
@@ -2,6 +2,13 @@
 
 // RUN: %clang_cc1 -fsyntax-only -fopenmp-simd -verify %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 // expected-error@+1 {{unexpected OpenMP directive '#pragma omp distribute parallel for simd'}}
 #pragma omp distribute parallel for simd
 
Index: test/OpenMP/distribute_parallel_for_messages.cpp
===================================================================
--- test/OpenMP/distribute_parallel_for_messages.cpp
+++ test/OpenMP/distribute_parallel_for_messages.cpp
@@ -5,6 +5,13 @@
 void foo() {
 }
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 #pragma omp distribute parallel for // expected-error {{unexpected OpenMP directive '#pragma omp distribute parallel for'}}
 
 int main(int argc, char **argv) {
Index: test/OpenMP/critical_messages.cpp
===================================================================
--- test/OpenMP/critical_messages.cpp
+++ test/OpenMP/critical_messages.cpp
@@ -4,6 +4,12 @@
 
 int foo();
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp critical
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 template<typename T, int N>
 int tmain(int argc, char **argv) { // expected-note {{declared here}}
   #pragma omp critical
Index: test/OpenMP/atomic_messages.c
===================================================================
--- test/OpenMP/atomic_messages.c
+++ test/OpenMP/atomic_messages.c
@@ -2,6 +2,12 @@
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 %s -Wuninitialized
 
+void xxx(int argc) {
+  int x; // expected-note {{initialize the variable 'x' to silence this warning}}
+#pragma omp atomic read
+  argc = x; // expected-warning {{variable 'x' is uninitialized when used here}}
+}
+
 int foo() {
 L1:
   foo();
Index: lib/Analysis/UninitializedValues.cpp
===================================================================
--- lib/Analysis/UninitializedValues.cpp
+++ lib/Analysis/UninitializedValues.cpp
@@ -350,6 +350,7 @@
   void VisitBinaryOperator(BinaryOperator *BO);
   void VisitCallExpr(CallExpr *CE);
   void VisitCastExpr(CastExpr *CE);
+  void VisitOMPExecutableDirective(OMPExecutableDirective *ED);
 
   void operator()(Stmt *S) { Visit(S); }
 
@@ -455,6 +456,13 @@
     classify(UO->getSubExpr(), Use);
 }
 
+void ClassifyRefs::VisitOMPExecutableDirective(OMPExecutableDirective *ED) {
+  ED->for_each_used_expr([this](Expr *E) {
+    assert(E && "Expected non-null expression.");
+    classify(E, Use);
+  });
+}
+
 static bool isPointerToConst(const QualType &QT) {
   return QT->isAnyPointerType() && QT->getPointeeType().isConstQualified();
 }
@@ -532,6 +540,7 @@
   void VisitDeclStmt(DeclStmt *ds);
   void VisitObjCForCollectionStmt(ObjCForCollectionStmt *FS);
   void VisitObjCMessageExpr(ObjCMessageExpr *ME);
+  void VisitOMPExecutableDirective(OMPExecutableDirective *ED);
 
   bool isTrackedVar(const VarDecl *vd) {
     return ::isTrackedVar(vd, cast<DeclContext>(ac.getDecl()));
@@ -707,6 +716,16 @@
   }
 }
 
+void TransferFunctions::VisitOMPExecutableDirective(
+    OMPExecutableDirective *ED) {
+  ED->for_each_used_expr([this](Expr *E) {
+    assert(E && "Expected non-null expression.");
+    Visit(E);
+  });
+  if (!ED->isStandaloneDirective())
+    Visit(ED->getStructuredBlock());
+}
+
 void TransferFunctions::VisitBlockExpr(BlockExpr *be) {
   const BlockDecl *bd = be->getBlockDecl();
   for (const auto &I : bd->captures()) {
Index: lib/Analysis/CFG.cpp
===================================================================
--- lib/Analysis/CFG.cpp
+++ lib/Analysis/CFG.cpp
@@ -589,6 +589,8 @@
   CFGBlock *VisitStmt(Stmt *S, AddStmtChoice asc);
   CFGBlock *VisitChildren(Stmt *S);
   CFGBlock *VisitNoRecurse(Expr *E, AddStmtChoice asc);
+  CFGBlock *VisitOMPExecutableDirective(OMPExecutableDirective *D,
+                                        AddStmtChoice asc);
 
   void maybeAddScopeBeginForVarDecl(CFGBlock *B, const VarDecl *VD,
                                     const Stmt *S) {
@@ -2058,6 +2060,9 @@
   if (Expr *E = dyn_cast<Expr>(S))
     S = E->IgnoreParens();
 
+  if (Context->getLangOpts().OpenMP && isa<OMPExecutableDirective>(S))
+    return VisitOMPExecutableDirective(cast<OMPExecutableDirective>(S), asc);
+
   switch (S->getStmtClass()) {
     default:
       return VisitStmt(S, asc);
@@ -4728,6 +4733,33 @@
   return Block;
 }
 
+CFGBlock *CFGBuilder::VisitOMPExecutableDirective(OMPExecutableDirective *D,
+                                                  AddStmtChoice asc) {
+  if (asc.alwaysAdd(*this, D)) {
+    autoCreateBlock();
+    appendStmt(Block, D);
+  }
+
+  // Iterate over all used expression in clauses.
+  CFGBlock *B = Block;
+
+  D->for_each_used_expr([this, &B](Expr *E) {
+    assert(E && "Expected expression.");
+    if (CFGBlock *R = Visit(E))
+      B = R;
+  });
+  // Visit associated structured block if any.
+  if (!D->isStandaloneDirective())
+    if (Stmt *S = D->getStructuredBlock()) {
+      if (!isa<CompoundStmt>(S))
+        addLocalScopeAndDtors(S);
+      if (CFGBlock *R = addStmt(S))
+        B = R;
+    }
+
+  return B;
+}
+
 /// createBlock - Constructs and adds a new CFGBlock to the CFG.  The block has
 ///  no successors or predecessors.  If this is the first block created in the
 ///  CFG, it is automatically set to be the Entry and Exit of the CFG.
Index: lib/AST/StmtOpenMP.cpp
===================================================================
--- lib/AST/StmtOpenMP.cpp
+++ lib/AST/StmtOpenMP.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/AST/DeclOpenMP.h"
 #include "clang/AST/StmtOpenMP.h"
 
 #include "clang/AST/ASTContext.h"
@@ -33,6 +34,23 @@
   return !hasAssociatedStmt() || !getAssociatedStmt();
 }
 
+void OMPExecutableDirective::for_each_used_expr(
+    llvm::function_ref<void(Expr *)> Fn) const {
+  // Iterate through all the clauses and find those that use the expressions.
+  // Iterate in reverse order to process uninitialized declarations in the
+  // natural order.
+  for (OMPClause *C : llvm::reverse(clauses())) {
+    // All clauses with the preinits use the expresion captured by
+    // OMPCapturedExprDecl decls as inits.
+    if (const auto *PIC = OMPClauseWithPreInit::get(C)) {
+      if (auto *DS = cast_or_null<DeclStmt>(PIC->getPreInitStmt())) {
+        for (Decl *D : llvm::reverse(DS->decls()))
+          Fn(cast<OMPCapturedExprDecl>(D)->getInit());
+      }
+    }
+  }
+}
+
 const Stmt *OMPExecutableDirective::getStructuredBlock() const {
   assert(!isStandaloneDirective() &&
          "Standalone Executable Directives don't have Structured Blocks.");
Index: include/clang/AST/StmtOpenMP.h
===================================================================
--- include/clang/AST/StmtOpenMP.h
+++ include/clang/AST/StmtOpenMP.h
@@ -285,6 +285,11 @@
     return const_cast<Stmt *>(
         const_cast<const OMPExecutableDirective *>(this)->getStructuredBlock());
   }
+
+  /// Iterates over all expressions, which are used in the construct, and
+  /// require defined value, like the values in the clauses, variables in the
+  /// reduction, linear and firstprivate clauses, etc.
+  void for_each_used_expr(llvm::function_ref<void(Expr *)> Fn) const;
 };
 
 /// This represents '#pragma omp parallel' directive.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to