Index: flang/include/flang/Semantics/symbol.h =================================================================== --- flang/include/flang/Semantics/symbol.h +++ flang/include/flang/Semantics/symbol.h @@ -351,6 +351,10 @@ MutableSymbolVector &objects() { return objects_; } const MutableSymbolVector &objects() const { return objects_; } void add_object(Symbol &object) { objects_.emplace_back(object); } + void replace_object(Symbol &object, unsigned index) { + if (index < (unsigned)objects_.size()) + objects_[index] = object; + } std::size_t alignment() const { return alignment_; } void set_alignment(std::size_t alignment) { alignment_ = alignment; } Index: flang/lib/Semantics/compute-offsets.cpp =================================================================== --- flang/lib/Semantics/compute-offsets.cpp +++ flang/lib/Semantics/compute-offsets.cpp @@ -294,7 +294,8 @@ } std::size_t ComputeOffsetsHelper::DoSymbol(Symbol &symbol) { - if (!symbol.has() && !symbol.has()) { + if (!symbol.has() && !symbol.has() && + !symbol.has()) { return 0; } SizeAndAlignment s{GetSizeAndAlignment(symbol, true)}; @@ -306,6 +307,10 @@ std::size_t padding{offset_ - previousOffset}; symbol.set_size(s.size); symbol.set_offset(offset_); + if (symbol.has()) { + symbol.GetUltimate().set_size(s.size); + symbol.GetUltimate().set_offset(offset_); + } offset_ += s.size; alignment_ = std::max(alignment_, s.alignment); return padding; Index: flang/lib/Semantics/resolve-directives.cpp =================================================================== --- flang/lib/Semantics/resolve-directives.cpp +++ flang/lib/Semantics/resolve-directives.cpp @@ -1629,7 +1629,9 @@ // 2.15.3 When a named common block appears in a list, it has the // same meaning as if every explicit member of the common block // appeared in the list - for (auto &object : symbol->get().objects()) { + auto &details{symbol->get()}; + unsigned index{0}; + for (auto &object : details.objects()) { if (auto *resolvedObject{ ResolveOmp(*object, ompFlag, currScope())}) { if (dataCopyingAttributeFlags.test(ompFlag)) { @@ -1637,7 +1639,9 @@ } else { AddToContextObjectWithDSA(*resolvedObject, ompFlag); } + details.replace_object(*resolvedObject, index); } + index++; } } else { context_.Say(name.source, // 2.15.3 Index: flang/test/Semantics/omp-symbol09.f90 =================================================================== --- /dev/null +++ flang/test/Semantics/omp-symbol09.f90 @@ -0,0 +1,28 @@ +! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s + +! 2.15.3 Data-Sharing Attribute Clauses +! When a named common block appears in a list, it has the same meaning as if +! every explicit member of the common block appeared in the list. + +! CHECK: a size=4 offset=0: ObjectEntity type: REAL(4) +! CHECK: b size=8 offset=4: ObjectEntity type: INTEGER(4) shape: 1_8:2_8 +! CHECK: c size=4 offset=12: ObjectEntity type: REAL(4) +! CHECK: x size=8 offset=0: ObjectEntity type: INTEGER(4) shape: 1_8:2_8 +! CHECK: blk size=16 offset=0: CommonBlockDetails alignment=4: a b c +! CHECK: Block scope: size=24 alignment=4 +! CHECK: a (OmpPrivate) size=4 offset=0: HostAssoc +! CHECK: b (OmpPrivate) size=8 offset=4: HostAssoc +! CHECK: c (OmpPrivate) size=4 offset=12: HostAssoc +! CHECK: x (OmpPrivate) size=8 offset=0: HostAssoc + +program main + integer :: x(2) + real :: a, c + integer :: b(2) + common /blk/ a, b, c + + !$omp parallel private(/blk/, x) num_threads(1) + call sub(a, b, c, x) + !$omp end parallel + +end program Index: flang/test/Semantics/omp-threadprivate04.f90 =================================================================== --- flang/test/Semantics/omp-threadprivate04.f90 +++ flang/test/Semantics/omp-threadprivate04.f90 @@ -5,44 +5,45 @@ program main integer :: i, N = 10 - integer, save :: x - common /blk/ y + integer, save :: x1, x2, x3, x4, x5, x6, x7, x8, x9 + common /blk1/ y1, /blk2/ y2, /blk3/ y3, /blk4/ y4, /blk5/ y5 - !$omp threadprivate(x, /blk/) + !$omp threadprivate(x1, x2, x3, x4, x5, x6, x7, x8, x9) + !$omp threadprivate(/blk1/, /blk2/, /blk3/, /blk4/, /blk5/) - !$omp parallel num_threads(x) + !$omp parallel num_threads(x1) !$omp end parallel - !$omp single copyprivate(x, /blk/) + !$omp single copyprivate(x2, /blk1/) !$omp end single - !$omp do schedule(static, x) + !$omp do schedule(static, x3) do i = 1, N - y = x + y1 = x3 end do !$omp end do - !$omp parallel copyin(x, /blk/) + !$omp parallel copyin(x4, /blk2/) !$omp end parallel - !$omp parallel if(x > 1) + !$omp parallel if(x5 > 1) !$omp end parallel - !$omp teams thread_limit(x) + !$omp teams thread_limit(x6) !$omp end teams !ERROR: A THREADPRIVATE variable cannot be in PRIVATE clause !ERROR: A THREADPRIVATE variable cannot be in PRIVATE clause - !$omp parallel private(x, /blk/) + !$omp parallel private(x7, /blk3/) !$omp end parallel !ERROR: A THREADPRIVATE variable cannot be in FIRSTPRIVATE clause !ERROR: A THREADPRIVATE variable cannot be in FIRSTPRIVATE clause - !$omp parallel firstprivate(x, /blk/) + !$omp parallel firstprivate(x8, /blk4/) !$omp end parallel !ERROR: A THREADPRIVATE variable cannot be in SHARED clause !ERROR: A THREADPRIVATE variable cannot be in SHARED clause - !$omp parallel shared(x, /blk/) + !$omp parallel shared(x9, /blk5/) !$omp end parallel end