This revision was automatically updated to reflect the committed changes.
Closed by commit rL365786: [OPENMP]Initial fix PR42392: Improve -Wuninitialized 
warnings for OpenMP… (authored by ABataev, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D64356?vs=209042&id=209222#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D64356/new/

https://reviews.llvm.org/D64356

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

Index: cfe/trunk/include/clang/AST/StmtOpenMP.h
===================================================================
--- cfe/trunk/include/clang/AST/StmtOpenMP.h
+++ cfe/trunk/include/clang/AST/StmtOpenMP.h
@@ -87,6 +87,63 @@
   }
 
 public:
+  /// Iterates over expressions/statements used in the construct.
+  class used_clauses_child_iterator
+      : public llvm::iterator_adaptor_base<
+            used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
+            std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
+    ArrayRef<OMPClause *>::iterator End;
+    OMPClause::child_iterator ChildI, ChildEnd;
+
+    void MoveToNext() {
+      if (ChildI != ChildEnd)
+        return;
+      while (this->I != End) {
+        ++this->I;
+        if (this->I != End) {
+          ChildI = (*this->I)->used_children().begin();
+          ChildEnd = (*this->I)->used_children().end();
+          if (ChildI != ChildEnd)
+            return;
+        }
+      }
+    }
+
+  public:
+    explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses)
+        : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
+          End(Clauses.end()) {
+      if (this->I != End) {
+        ChildI = (*this->I)->used_children().begin();
+        ChildEnd = (*this->I)->used_children().end();
+        MoveToNext();
+      }
+    }
+    Stmt *operator*() const { return *ChildI; }
+    Stmt *operator->() const { return **this; }
+
+    used_clauses_child_iterator &operator++() {
+      ++ChildI;
+      if (ChildI != ChildEnd)
+        return *this;
+      if (this->I != End) {
+        ++this->I;
+        if (this->I != End) {
+          ChildI = (*this->I)->used_children().begin();
+          ChildEnd = (*this->I)->used_children().end();
+        }
+      }
+      MoveToNext();
+      return *this;
+    }
+  };
+
+  static llvm::iterator_range<used_clauses_child_iterator>
+  used_clauses_children(ArrayRef<OMPClause *> Clauses) {
+    return {used_clauses_child_iterator(Clauses),
+            used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))};
+  }
+
   /// Iterates over a filtered subrange of clauses applied to a
   /// directive.
   ///
Index: cfe/trunk/include/clang/AST/OpenMPClause.h
===================================================================
--- cfe/trunk/include/clang/AST/OpenMPClause.h
+++ cfe/trunk/include/clang/AST/OpenMPClause.h
@@ -90,6 +90,15 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  /// Get the iterator range for the expressions used in the clauses. Used
+  /// expressions include only the children that must be evaluated at the
+  /// runtime before entering the construct.
+  child_range used_children();
+  const_child_range used_children() const {
+    auto Children = const_cast<OMPClause *>(this)->children();
+    return const_child_range(Children.begin(), Children.end());
+  }
+
   static bool classof(const OMPClause *) { return true; }
 };
 
@@ -294,6 +303,13 @@
     return const_child_range(&Allocator, &Allocator + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_allocator;
   }
@@ -384,6 +400,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_allocate;
   }
@@ -478,6 +501,13 @@
     return const_child_range(&Condition, &Condition + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_if;
   }
@@ -533,6 +563,13 @@
     return const_child_range(&Condition, &Condition + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_final;
   }
@@ -598,6 +635,13 @@
     return const_child_range(&NumThreads, &NumThreads + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_num_threads;
   }
@@ -657,6 +701,13 @@
     return const_child_range(&Safelen, &Safelen + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_safelen;
   }
@@ -715,6 +766,13 @@
     return const_child_range(&Simdlen, &Simdlen + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_simdlen;
   }
@@ -774,6 +832,13 @@
     return const_child_range(&NumForLoops, &NumForLoops + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_collapse;
   }
@@ -846,6 +911,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_default;
   }
@@ -920,6 +992,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_proc_bind;
   }
@@ -955,6 +1034,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_unified_address;
   }
@@ -990,6 +1076,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_unified_shared_memory;
   }
@@ -1025,6 +1118,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_reverse_offload;
   }
@@ -1061,6 +1161,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_dynamic_allocators;
   }
@@ -1144,6 +1251,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_atomic_default_mem_order;
   }
@@ -1330,6 +1444,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_schedule;
   }
@@ -1419,6 +1540,13 @@
     return const_child_range(&NumForLoops, &NumForLoops + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_ordered;
   }
@@ -1451,6 +1579,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_nowait;
   }
@@ -1483,6 +1618,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_untied;
   }
@@ -1516,6 +1658,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_mergeable;
   }
@@ -1547,6 +1696,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_read;
   }
@@ -1579,6 +1735,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_write;
   }
@@ -1612,6 +1775,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_update;
   }
@@ -1645,6 +1815,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_capture;
   }
@@ -1678,6 +1855,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_seq_cst;
   }
@@ -1776,6 +1960,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_private;
   }
@@ -1908,6 +2099,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_firstprivate;
   }
@@ -2112,6 +2310,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_lastprivate;
   }
@@ -2177,6 +2382,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_shared;
   }
@@ -2404,6 +2616,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_reduction;
   }
@@ -2629,6 +2848,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_task_reduction;
   }
@@ -2877,6 +3103,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_in_reduction;
   }
@@ -3121,6 +3354,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_linear;
   }
@@ -3213,6 +3453,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_aligned;
   }
@@ -3382,6 +3629,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_copyin;
   }
@@ -3538,6 +3792,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_copyprivate;
   }
@@ -3608,6 +3869,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_flush;
   }
@@ -3732,6 +4000,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_depend;
   }
@@ -3799,6 +4074,13 @@
     return const_child_range(&Device, &Device + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_device;
   }
@@ -3831,6 +4113,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_threads;
   }
@@ -3862,6 +4151,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_simd;
   }
@@ -4699,6 +4995,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_map;
   }
@@ -4767,6 +5070,13 @@
     return const_child_range(&NumTeams, &NumTeams + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_num_teams;
   }
@@ -4836,6 +5146,13 @@
     return const_child_range(&ThreadLimit, &ThreadLimit + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_thread_limit;
   }
@@ -4897,6 +5214,13 @@
     return const_child_range(&Priority, &Priority + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_priority;
   }
@@ -4952,6 +5276,13 @@
     return const_child_range(&Grainsize, &Grainsize + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_grainsize;
   }
@@ -4984,6 +5315,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_nogroup;
   }
@@ -5039,6 +5377,13 @@
     return const_child_range(&NumTasks, &NumTasks + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_num_tasks;
   }
@@ -5093,6 +5438,13 @@
     return const_child_range(&Hint, &Hint + 1);
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_hint;
   }
@@ -5205,6 +5557,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_dist_schedule;
   }
@@ -5310,6 +5669,13 @@
     return const_child_range(const_child_iterator(), const_child_iterator());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_defaultmap;
   }
@@ -5420,6 +5786,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_to;
   }
@@ -5531,6 +5904,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_from;
   }
@@ -5687,6 +6067,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_use_device_ptr;
   }
@@ -5783,6 +6170,13 @@
     return const_child_range(Children.begin(), Children.end());
   }
 
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
   static bool classof(const OMPClause *T) {
     return T->getClauseKind() == OMPC_is_device_ptr;
   }
Index: cfe/trunk/test/OpenMP/target_depend_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_depend_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/distribute_parallel_for_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/distribute_parallel_for_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/parallel_for_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/parallel_for_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/teams_distribute_simd_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/teams_distribute_simd_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/teams_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/teams_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_teams_distribute_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_teams_distribute_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/parallel_for_simd_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/parallel_for_simd_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/for_simd_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/for_simd_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/critical_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/critical_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/taskloop_simd_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/taskloop_simd_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_parallel_for_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_parallel_for_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/ordered_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/ordered_messages.cpp
+++ cfe/trunk/test/OpenMP/ordered_messages.cpp
@@ -6,6 +6,15 @@
 // 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: cfe/trunk/test/OpenMP/taskloop_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/taskloop_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_simd_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_simd_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/for_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/for_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/distribute_parallel_for_simd_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/distribute_parallel_for_simd_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/task_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/task_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/master_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/master_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_update_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_update_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_parallel_for_simd_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_parallel_for_simd_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/atomic_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/atomic_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/taskgroup_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/taskgroup_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/distribute_simd_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/distribute_simd_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_teams_distribute_simd_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_teams_distribute_simd_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_teams_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_teams_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_parallel_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_parallel_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/parallel_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/parallel_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/teams_distribute_parallel_for_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/teams_distribute_parallel_for_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/simd_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/simd_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/parallel_sections_messages.cpp
===================================================================
--- cfe/trunk/test/OpenMP/parallel_sections_messages.cpp
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/sections_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/sections_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/OpenMP/single_misc_messages.c
===================================================================
--- cfe/trunk/test/OpenMP/single_misc_messages.c
+++ cfe/trunk/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: cfe/trunk/test/Analysis/cfg-openmp.cpp
===================================================================
--- cfe/trunk/test/Analysis/cfg-openmp.cpp
+++ cfe/trunk/test/Analysis/cfg-openmp.cpp
@@ -0,0 +1,340 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 -fopenmp | FileCheck %s
+
+// CHECK-LABEL:  void xxx(int argc)
+void xxx(int argc) {
+// CHECK:        [B1]
+// CHECK-NEXT:   1: int x;
+  int x;
+// CHECK-NEXT:   2: x
+// CHECK-NEXT:   3: [B1.2] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   4: argc
+// CHECK-NEXT:   5: [B1.4] = [B1.3]
+// CHECK-NEXT:   6: #pragma omp atomic read
+// CHECK-NEXT:    [B1.5];
+#pragma omp atomic read
+  argc = x;
+// CHECK-NEXT:   7: x
+// CHECK-NEXT:   8: [B1.7] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   9: argc
+// CHECK-NEXT:  10: [B1.9] = [B1.8]
+// CHECK-NEXT:  11: #pragma omp critical
+// CHECK-NEXT:    [B1.10];
+#pragma omp critical
+  argc = x;
+// CHECK-NEXT:  12: x
+// CHECK-NEXT:  13: [B1.12] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  14: argc
+// CHECK-NEXT:  15: [B1.14] = [B1.13]
+// CHECK-NEXT:  16: #pragma omp distribute parallel for
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.15];
+#pragma omp distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  17: x
+// CHECK-NEXT:  18: [B1.17] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  19: argc
+// CHECK-NEXT:  20: [B1.19] = [B1.18]
+// CHECK-NEXT:  21: #pragma omp distribute parallel for simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.20];
+#pragma omp distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  22: x
+// CHECK-NEXT:  23: [B1.22] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  24: argc
+// CHECK-NEXT:  25: [B1.24] = [B1.23]
+// CHECK-NEXT:  26: #pragma omp distribute simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.25];
+#pragma omp distribute simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  27: x
+// CHECK-NEXT:  28: [B1.27] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  29: argc
+// CHECK-NEXT:  30: [B1.29] = [B1.28]
+// CHECK-NEXT:  31: #pragma omp for
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.30];
+#pragma omp for
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  32: x
+// CHECK-NEXT:  33: [B1.32] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  34: argc
+// CHECK-NEXT:  35: [B1.34] = [B1.33]
+// CHECK-NEXT:  36: #pragma omp for simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.35];
+#pragma omp for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  37: x
+// CHECK-NEXT:  38: [B1.37] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  39: argc
+// CHECK-NEXT:  40: [B1.39] = [B1.38]
+// CHECK-NEXT:  41: #pragma omp master
+// CHECK-NEXT:    [B1.40];
+#pragma omp master
+  argc = x;
+// CHECK-NEXT:  42: x
+// CHECK-NEXT:  43: [B1.42] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  44: argc
+// CHECK-NEXT:  45: [B1.44] = [B1.43]
+// CHECK-NEXT:  46: #pragma omp ordered
+// CHECK-NEXT:    [B1.45];
+// CHECK-NEXT:  47: #pragma omp for ordered
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i) {
+// CHECK-NEXT:[B1.46]    }
+#pragma omp for ordered
+  for (int i = 0; i < 10; ++i) {
+#pragma omp ordered
+    argc = x;
+  }
+// CHECK-NEXT:  48: x
+// CHECK-NEXT:  49: [B1.48] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  50: argc
+// CHECK-NEXT:  51: [B1.50] = [B1.49]
+// CHECK-NEXT:  52: #pragma omp parallel for
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.51];
+#pragma omp parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  53: x
+// CHECK-NEXT:  54: [B1.53] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  55: argc
+// CHECK-NEXT:  56: [B1.55] = [B1.54]
+// CHECK-NEXT:  57: #pragma omp parallel for simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.56];
+#pragma omp parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  58: x
+// CHECK-NEXT:  59: [B1.58] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  60: argc
+// CHECK-NEXT:  61: [B1.60] = [B1.59]
+// CHECK-NEXT:  62: #pragma omp parallel
+// CHECK-NEXT:    [B1.61];
+#pragma omp parallel
+  argc = x;
+// CHECK-NEXT:  63: x
+// CHECK-NEXT:  64: [B1.63] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  65: argc
+// CHECK-NEXT:  66: [B1.65] = [B1.64]
+// CHECK-NEXT:  67: #pragma omp parallel sections
+// CHECK-NEXT:    {
+// CHECK-NEXT:        [B1.66];
+// CHECK-NEXT:    }
+#pragma omp parallel sections
+  {
+    argc = x;
+  }
+// CHECK-NEXT:  68: x
+// CHECK-NEXT:  69: [B1.68] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  70: argc
+// CHECK-NEXT:  71: [B1.70] = [B1.69]
+// CHECK-NEXT:  72: #pragma omp simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.71];
+#pragma omp simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  73: x
+// CHECK-NEXT:  74: [B1.73] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  75: argc
+// CHECK-NEXT:  76: [B1.75] = [B1.74]
+// CHECK-NEXT:  77: #pragma omp single
+// CHECK-NEXT:    [B1.76];
+#pragma omp single
+  argc = x;
+// CHECK-NEXT:  78: x
+// CHECK-NEXT:  79: [B1.78] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  80: argc
+// CHECK-NEXT:  81: [B1.80] = [B1.79]
+// CHECK-NEXT:  82: #pragma omp target depend(in : argc)
+// CHECK-NEXT:    [B1.81];
+#pragma omp target depend(in \
+                          : argc)
+  argc = x;
+// CHECK-NEXT:  83: x
+// CHECK-NEXT:  84: [B1.83] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  85: argc
+// CHECK-NEXT:  86: [B1.85] = [B1.84]
+// CHECK-NEXT:  87: #pragma omp target parallel for
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.86];
+#pragma omp target parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  88: x
+// CHECK-NEXT:  89: [B1.88] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  90: argc
+// CHECK-NEXT:  91: [B1.90] = [B1.89]
+// CHECK-NEXT:  92: #pragma omp target parallel for simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.91];
+#pragma omp target parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:  93: x
+// CHECK-NEXT:  94: [B1.93] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:  95: argc
+// CHECK-NEXT:  96: [B1.95] = [B1.94]
+// CHECK-NEXT:  97: #pragma omp target parallel
+// CHECK-NEXT:    [B1.96];
+#pragma omp target parallel
+  argc = x;
+// CHECK-NEXT:  98: x
+// CHECK-NEXT:  99: [B1.98] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 100: argc
+// CHECK-NEXT: 101: [B1.100] = [B1.99]
+// CHECK-NEXT: 102: #pragma omp target simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.101];
+#pragma omp target simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT: 103: x
+// CHECK-NEXT: 104: [B1.103] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 105: argc
+// CHECK-NEXT: 106: [B1.105] = [B1.104]
+// CHECK-NEXT: 107: #pragma omp target teams distribute
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.106];
+#pragma omp target teams distribute
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT: 108: x
+// CHECK-NEXT: 109: [B1.108] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 110: argc
+// CHECK-NEXT: 111: [B1.110] = [B1.109]
+// CHECK-NEXT: 112: #pragma omp target teams distribute parallel for
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.111];
+#pragma omp target teams distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT: 113: x
+// CHECK-NEXT: 114: [B1.113] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 115: argc
+// CHECK-NEXT: 116: [B1.115] = [B1.114]
+// CHECK-NEXT: 117: #pragma omp target teams distribute parallel for simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.116];
+#pragma omp target teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT: 118: x
+// CHECK-NEXT: 119: [B1.118] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 120: argc
+// CHECK-NEXT: 121: [B1.120] = [B1.119]
+// CHECK-NEXT: 122: #pragma omp target teams distribute simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.121];
+#pragma omp target teams distribute simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT: 123: x
+// CHECK-NEXT: 124: [B1.123] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 125: argc
+// CHECK-NEXT: 126: [B1.125] = [B1.124]
+// CHECK-NEXT: 127: #pragma omp target teams
+// CHECK-NEXT:    [B1.126];
+#pragma omp target teams
+  argc = x;
+// CHECK-NEXT: 128: #pragma omp target update to(x)
+#pragma omp target update to(x)
+// CHECK-NEXT: 129: x
+// CHECK-NEXT: 130: [B1.129] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 131: argc
+// CHECK-NEXT: 132: [B1.131] = [B1.130]
+  argc = x;
+// CHECK-NEXT: 133: x
+// CHECK-NEXT: 134: [B1.133] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 135: argc
+// CHECK-NEXT: 136: [B1.135] = [B1.134]
+// CHECK-NEXT: 137: #pragma omp task
+// CHECK-NEXT:    [B1.136];
+#pragma omp task
+  argc = x;
+// CHECK-NEXT: 138: x
+// CHECK-NEXT: 139: [B1.138] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 140: argc
+// CHECK-NEXT: 141: [B1.140] = [B1.139]
+// CHECK-NEXT: 142: #pragma omp taskgroup
+// CHECK-NEXT:    [B1.141];
+#pragma omp taskgroup
+  argc = x;
+// CHECK-NEXT: 143: x
+// CHECK-NEXT: 144: [B1.143] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 145: argc
+// CHECK-NEXT: 146: [B1.145] = [B1.144]
+// CHECK-NEXT: 147: #pragma omp taskloop
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.146];
+#pragma omp taskloop
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT: 148: x
+// CHECK-NEXT: 149: [B1.148] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 150: argc
+// CHECK-NEXT: 151: [B1.150] = [B1.149]
+// CHECK-NEXT: 152: #pragma omp taskloop simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.151];
+#pragma omp taskloop simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT: 153: x
+// CHECK-NEXT: 154: [B1.153] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 155: argc
+// CHECK-NEXT: 156: [B1.155] = [B1.154]
+// CHECK-NEXT: 157: #pragma omp teams distribute parallel for
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.156];
+// CHECK-NEXT: 158: #pragma omp target
+#pragma omp target
+#pragma omp teams distribute parallel for
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:[B1.157] 159: x
+// CHECK-NEXT: 160: [B1.159] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 161: argc
+// CHECK-NEXT: 162: [B1.161] = [B1.160]
+// CHECK-NEXT: 163: #pragma omp teams distribute parallel for simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.162];
+// CHECK-NEXT: 164: #pragma omp target
+#pragma omp target
+#pragma omp teams distribute parallel for simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:[B1.163] 165: x
+// CHECK-NEXT: 166: [B1.165] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 167: argc
+// CHECK-NEXT: 168: [B1.167] = [B1.166]
+// CHECK-NEXT: 169: #pragma omp teams distribute simd
+// CHECK-NEXT:    for (int i = 0; i < 10; ++i)
+// CHECK-NEXT:        [B1.168];
+// CHECK-NEXT: 170: #pragma omp target
+#pragma omp target
+#pragma omp teams distribute simd
+  for (int i = 0; i < 10; ++i)
+    argc = x;
+// CHECK-NEXT:[B1.169] 171: x
+// CHECK-NEXT: 172: [B1.171] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT: 173: argc
+// CHECK-NEXT: 174: [B1.173] = [B1.172]
+// CHECK-NEXT: 175: #pragma omp teams
+// CHECK-NEXT:    [B1.174];
+// CHECK-NEXT: 176: #pragma omp target
+#pragma omp target
+#pragma omp teams
+  argc = x;
+// CHECK-NEXT:[B1.175]   Preds
+}
+
Index: cfe/trunk/lib/AST/OpenMPClause.cpp
===================================================================
--- cfe/trunk/lib/AST/OpenMPClause.cpp
+++ cfe/trunk/lib/AST/OpenMPClause.cpp
@@ -35,6 +35,20 @@
   llvm_unreachable("unknown OMPClause");
 }
 
+OMPClause::child_range OMPClause::used_children() {
+  switch (getClauseKind()) {
+#define OPENMP_CLAUSE(Name, Class)                                             \
+  case OMPC_##Name:                                                            \
+    return static_cast<Class *>(this)->used_children();
+#include "clang/Basic/OpenMPKinds.def"
+  case OMPC_threadprivate:
+  case OMPC_uniform:
+  case OMPC_unknown:
+    break;
+  }
+  llvm_unreachable("unknown OMPClause");
+}
+
 OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {
   auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
   return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
Index: cfe/trunk/lib/Analysis/CFG.cpp
===================================================================
--- cfe/trunk/lib/Analysis/CFG.cpp
+++ cfe/trunk/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,10 @@
   if (Expr *E = dyn_cast<Expr>(S))
     S = E->IgnoreParens();
 
+  if (Context->getLangOpts().OpenMP)
+    if (auto *D = dyn_cast<OMPExecutableDirective>(S))
+      return VisitOMPExecutableDirective(D, asc);
+
   switch (S->getStmtClass()) {
     default:
       return VisitStmt(S, asc);
@@ -4728,6 +4734,36 @@
   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;
+
+  // Reverse the elements to process them in natural order. Iterators are not
+  // bidirectional, so we need to create temp vector.
+  for (Stmt *S : llvm::reverse(llvm::to_vector<8>(
+           OMPExecutableDirective::used_clauses_children(D->clauses())))) {
+    assert(S && "Expected non-null used-in-clause child.");
+    if (CFGBlock *R = Visit(S))
+      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: cfe/trunk/lib/Analysis/UninitializedValues.cpp
===================================================================
--- cfe/trunk/lib/Analysis/UninitializedValues.cpp
+++ cfe/trunk/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,11 @@
     classify(UO->getSubExpr(), Use);
 }
 
+void ClassifyRefs::VisitOMPExecutableDirective(OMPExecutableDirective *ED) {
+  for (Stmt *S : OMPExecutableDirective::used_clauses_children(ED->clauses()))
+    classify(cast<Expr>(S), Use);
+}
+
 static bool isPointerToConst(const QualType &QT) {
   return QT->isAnyPointerType() && QT->getPointeeType().isConstQualified();
 }
@@ -532,6 +538,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 +714,16 @@
   }
 }
 
+void TransferFunctions::VisitOMPExecutableDirective(
+    OMPExecutableDirective *ED) {
+  for (Stmt *S : OMPExecutableDirective::used_clauses_children(ED->clauses())) {
+    assert(S && "Expected non-null used-in-clause child.");
+    Visit(S);
+  }
+  if (!ED->isStandaloneDirective())
+    Visit(ED->getStructuredBlock());
+}
+
 void TransferFunctions::VisitBlockExpr(BlockExpr *be) {
   const BlockDecl *bd = be->getBlockDecl();
   for (const auto &I : bd->captures()) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to