Index: include/clang/AST/OpenMPClause.h =================================================================== --- include/clang/AST/OpenMPClause.h +++ 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(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: include/clang/AST/StmtOpenMP.h =================================================================== --- include/clang/AST/StmtOpenMP.h +++ 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::iterator, + std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { + ArrayRef::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 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_children(ArrayRef 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: lib/AST/OpenMPClause.cpp =================================================================== --- lib/AST/OpenMPClause.cpp +++ 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(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(C)); return Res ? const_cast(Res) : nullptr; 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,10 @@ if (Expr *E = dyn_cast(S)) S = E->IgnoreParens(); + if (Context->getLangOpts().OpenMP) + if (auto *D = dyn_cast(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(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/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,11 @@ classify(UO->getSubExpr(), Use); } +void ClassifyRefs::VisitOMPExecutableDirective(OMPExecutableDirective *ED) { + for (Stmt *S : OMPExecutableDirective::used_clauses_children(ED->clauses())) + classify(cast(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(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()) { Index: test/Analysis/cfg-openmp.cpp =================================================================== --- /dev/null +++ test/Analysis/cfg-openmp.cpp @@ -0,0 +1,341 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 -fopenmp | FileCheck %s + +// CHECK: void xxx(int argc) +// CHECK: [B1] +// CHECK-NEXT: 1: 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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] } +// 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]; +// 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]; +// 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]; +// 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: } +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// 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]; +// CHECK-NEXT: 128: #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] +// 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]; +// 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]; +// 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]; +// 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]; +// 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 +// 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 +// 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 +// 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 +// CHECK-NEXT:[B1.175] Preds + +void xxx(int argc) { + int x; +#pragma omp atomic read + argc = x; +#pragma omp critical + argc = x; +#pragma omp distribute parallel for + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp distribute parallel for simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp distribute simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp for + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp for simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp master + argc = x; +#pragma omp for ordered + for (int i = 0; i < 10; ++i) { +#pragma omp ordered + argc = x; + } +#pragma omp parallel for + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp parallel for simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp parallel + argc = x; +#pragma omp parallel sections + { + argc = x; + } +#pragma omp simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp single + argc = x; +#pragma omp target depend(in \ + : argc) + argc = x; +#pragma omp target parallel for + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target parallel for simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target parallel + argc = x; +#pragma omp target simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target teams distribute + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target teams distribute parallel for + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target teams distribute parallel for simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target teams distribute simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target teams + argc = x; +#pragma omp target update to(x) + argc = x; +#pragma omp task + argc = x; +#pragma omp taskgroup + argc = x; +#pragma omp taskloop + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp taskloop simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target +#pragma omp teams distribute parallel for + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target +#pragma omp teams distribute parallel for simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target +#pragma omp teams distribute simd + for (int i = 0; i < 10; ++i) + argc = x; +#pragma omp target +#pragma omp teams + argc = x; +} + 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: 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 int tmain(int argc, char **argv) { // expected-note {{declared here}} #pragma omp critical 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/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_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/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/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/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/ordered_messages.cpp =================================================================== --- test/OpenMP/ordered_messages.cpp +++ 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 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/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_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_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/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/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/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/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/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_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_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_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_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_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_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_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_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_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/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/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/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/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/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/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_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_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() { }