Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,31 @@ static std::string getOpenMPClauseNameForDiag(OpenMPClauseKind C) {
return getOpenMPClauseName(C).str();
}

static bool isAllocatableType(QualType QT) {
if (QT->isPointerType())
return true;

QT = QT.getCanonicalType().getUnqualifiedType();
if (const auto *RD = QT->getAsCXXRecordDecl())
if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(RD))
if (const auto *CTD = Spec->getSpecializedTemplate())
if (const auto *NS =
dyn_cast_or_null<NamespaceDecl>(CTD->getDeclContext())) {
StringRef Name = CTD->getIdentifier()->getName();

if (NS->isStdNamespace())
if (Name == "vector" || Name == "unique_ptr" ||
Name == "shared_ptr" || Name == "array")
return true;

if (NS->getIdentifier()->getName() == "llvm")
if (Name == "SmallVector")
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should not be anything like this. Please, remove!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A similar kind of code exists in file clang/lib/StaticAnalyzer/Checkers/SmartPtrModeling.cpp, function isStdSmartPtr( ). Without this I cannot check if the variable is of type Allocatable.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Analayser is the analysis tool, not a compiler, it may produce wrong results.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code related to allocatable variable category is now removed by checkin #167735 of David Pagan. These changes have been pulled into the current bug fix.

}

return false;
}

DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
ValueDecl *D) const {
D = getCanonicalDecl(D);
Expand Down Expand Up @@ -1370,20 +1395,19 @@ DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
DefaultDataSharingAttributes IterDA = Iter->DefaultAttr;
switch (Iter->DefaultVCAttr) {
case DSA_VC_aggregate:
if (!VD->getType()->isAggregateType())
if (!D->getType()->isAggregateType())
IterDA = DSA_none;
break;
case DSA_VC_allocatable:
if (!(VD->getType()->isPointerType() ||
VD->getType()->isVariableArrayType()))
if (!isAllocatableType(D->getType()))
IterDA = DSA_none;
break;
case DSA_VC_pointer:
if (!VD->getType()->isPointerType())
if (!D->getType()->isPointerType())
IterDA = DSA_none;
break;
case DSA_VC_scalar:
if (!VD->getType()->isScalarType())
if (!D->getType()->isScalarType())
IterDA = DSA_none;
break;
case DSA_VC_all:
Expand Down
113 changes: 113 additions & 0 deletions clang/test/OpenMP/parallel_default_variableCategory_codegen.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// RUN: %clangxx -Xclang -verify -Wno-vla -fopenmp -fopenmp-version=60 -x c++ -S -emit-llvm %s -o - | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER

#include <vector>

int global;
#define VECTOR_SIZE 4
int main (int argc, char **argv) {
int i,n;
int x;

n = VECTOR_SIZE;

#pragma omp parallel masked firstprivate(x) num_threads(2)
{
int *xPtr = nullptr;
// scalar
#pragma omp task default(shared:scalar)
{
xPtr = &x;
}
#pragma omp taskwait

// pointer
#pragma omp task default(shared:pointer) shared(x)
{
xPtr = &x;
}
#pragma omp taskwait
}

int *aggregate[VECTOR_SIZE] = {0,0,0,0};
std::vector<int *> arr(VECTOR_SIZE,0);

#pragma omp parallel masked num_threads(2)
{
// aggregate
#pragma omp task default(shared:aggregate)
for(i=0;i<n;i++) {
aggregate[i] = &x;
}
#pragma omp taskwait

#pragma omp task default(shared:aggregate) shared(x)
for(i=0;i<n;i++) {
aggregate[i] = &x;
}
#pragma omp taskwait

// allocatable
#pragma omp task default(shared:allocatable)
for(i=0;i<n;i++) {
arr[i] = &x;
}
#pragma omp taskwait

#pragma omp task default(shared:allocatable) shared(x)
for(i=0;i<n;i++) {
arr[i] = &x;
}
#pragma omp taskwait

// all
#pragma omp task default(shared:all)
for(i=0;i<n;i++) {
aggregate[i] = &x;
}
#pragma omp taskwait
}
}

#endif

// CHECK-LABEL: define {{.*}}main.omp_outlined{{.*}}
// CHECK-NEXT: entry:
// CHECK: %x.addr = alloca{{.*}}
// CHECK: %xPtr = alloca{{.*}}
// CHECK: store ptr null, ptr %xPtr{{.*}}
// CHECK: store ptr %xPtr{{.*}}
// CHECK: store ptr %x.addr{{.*}}
// CHECK-NEXT: {{.*}}call{{.*}}__kmpc_omp_task_alloc{{.*}}
// CHECK: ret void
//
// CHECK: define {{.*}}main.omp_outlined{{.*}}
// CHECK-NEXT: entry:
// CHECK-DAG: %i.addr = alloca{{.*}}
// CHECK-DAG: %n.addr = alloca{{.*}}
// CHECK-DAG: %aggregate.addr = alloca{{.*}}
// CHECK-DAG: %x.addr = alloca{{.*}}
// CHECK-DAG: %arr.addr = alloca{{.*}}
// CHECK: [[TMP0:%.*]] = load{{.*}}%i.addr{{.*}}
// CHECK-NEXT: [[TMP1:%.*]] = load{{.*}}%n.addr{{.*}}
// CHECK-NEXT: [[TMP2:%.*]] = load{{.*}}%aggregate.addr{{.*}}
// CHECK-NEXT: [[TMP3:%.*]] = load{{.*}}%x.addr{{.*}}
// CHECK-NEXT: [[TMP4:%.*]] = load{{.*}}%arr.addr{{.*}}
// CHECK: store ptr [[TMP2]]{{.*}}
// CHECK-NEXT: {{.*}}call{{.*}}__kmpc_omp_task_alloc{{.*}}
// CHECK: store ptr [[TMP2]]{{.*}}
// CHECK: store ptr [[TMP3]]{{.*}}
// CHECK-NEXT: {{.*}}call{{.*}}__kmpc_omp_task_alloc{{.*}}
// CHECK: store ptr [[TMP4]]{{.*}}
// CHECK-NEXT: {{.*}}call{{.*}}__kmpc_omp_task_alloc{{.*}}
// CHECK: store ptr [[TMP4]]{{.*}}
// CHECK: store ptr [[TMP3]]{{.*}}
// CHECK-NEXT: {{.*}}call{{.*}}__kmpc_omp_task_alloc{{.*}}
// CHECK: store ptr [[TMP0]]{{.*}}
// CHECK: store ptr [[TMP1]]{{.*}}
// CHECK: store ptr [[TMP2]]{{.*}}
// CHECK: store ptr [[TMP3]]{{.*}}
// CHECK-NEXT: {{.*}}call{{.*}}__kmpc_omp_task_alloc{{.*}}
// CHECK: ret void
Loading