[OpenMP] Diagnose function name on the link clause

This patch is to add diagnose when a function name is
specified on the link clause. According to the  OpenMP
spec, only the list items that exclude the function 
name are allowed on the link clause.

Differential Revision: https://reviews.llvm.org/D40968

llvm-svn: 320521
This commit is contained in:
Kelvin Li 2017-12-12 20:08:12 +00:00
parent 1ce416c635
commit 1ce87c7051
5 changed files with 22 additions and 9 deletions

View File

@ -8710,6 +8710,8 @@ def err_omp_declare_target_to_and_link : Error<
def warn_omp_not_in_target_context : Warning< def warn_omp_not_in_target_context : Warning<
"declaration is not declared in any declare target region">, "declaration is not declared in any declare target region">,
InGroup<OpenMPTarget>; InGroup<OpenMPTarget>;
def err_omp_function_in_link_clause : Error<
"function name is not allowed in 'link' clause">;
def err_omp_aligned_expected_array_or_ptr : Error< def err_omp_aligned_expected_array_or_ptr : Error<
"argument of aligned clause should be array" "argument of aligned clause should be array"
"%select{ or pointer|, pointer, reference to array or reference to pointer}1" "%select{ or pointer|, pointer, reference to array or reference to pointer}1"

View File

@ -8656,7 +8656,8 @@ public:
OMPDeclareTargetDeclAttr::MapTypeTy MT, OMPDeclareTargetDeclAttr::MapTypeTy MT,
NamedDeclSetType &SameDirectiveDecls); NamedDeclSetType &SameDirectiveDecls);
/// Check declaration inside target region. /// Check declaration inside target region.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D); void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
SourceLocation IdLoc = SourceLocation());
/// Return true inside OpenMP declare target region. /// Return true inside OpenMP declare target region.
bool isInOpenMPDeclareTargetContext() const { bool isInOpenMPDeclareTargetContext() const {
return IsInOpenMPDeclareTargetContext; return IsInOpenMPDeclareTargetContext;

View File

@ -12600,7 +12600,7 @@ void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope,
ND->addAttr(A); ND->addAttr(A);
if (ASTMutationListener *ML = Context.getASTMutationListener()) if (ASTMutationListener *ML = Context.getASTMutationListener())
ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
checkDeclIsAllowedInOpenMPTarget(nullptr, ND); checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
} else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
<< Id.getName(); << Id.getName();
@ -12689,7 +12689,8 @@ static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
return true; return true;
} }
void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
SourceLocation IdLoc) {
if (!D || D->isInvalidDecl()) if (!D || D->isInvalidDecl())
return; return;
SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
@ -12718,6 +12719,16 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) {
return; return;
} }
} }
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
(FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
OMPDeclareTargetDeclAttr::MT_Link)) {
assert(IdLoc.isValid() && "Source location is expected");
Diag(IdLoc, diag::err_omp_function_in_link_clause);
Diag(FD->getLocation(), diag::note_defined_here) << FD;
return;
}
}
if (!E) { if (!E) {
// Checking declaration inside declare target region. // Checking declaration inside declare target region.
if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&

View File

@ -108,9 +108,7 @@ void f2() {
// CHECK: #pragma omp end declare target // CHECK: #pragma omp end declare target
int c1, c2, c3; int c1, c2, c3;
void f3() { #pragma omp declare target link(c1) link(c2), link(c3)
}
#pragma omp declare target link(c1) link(c2), link(c3, f3)
// CHECK: #pragma omp declare target link // CHECK: #pragma omp declare target link
// CHECK: int c1; // CHECK: int c1;
// CHECK: #pragma omp end declare target // CHECK: #pragma omp end declare target
@ -120,9 +118,6 @@ void f3() {
// CHECK: #pragma omp declare target link // CHECK: #pragma omp declare target link
// CHECK: int c3; // CHECK: int c3;
// CHECK: #pragma omp end declare target // CHECK: #pragma omp end declare target
// CHECK: #pragma omp declare target link
// CHECK: void f3()
// CHECK: #pragma omp end declare target
struct SSSt { struct SSSt {
#pragma omp declare target #pragma omp declare target

View File

@ -19,6 +19,10 @@ void f();
void c(); // expected-warning {{declaration is not declared in any declare target region}} void c(); // expected-warning {{declaration is not declared in any declare target region}}
void func() {} // expected-note {{'func' defined here}}
#pragma omp declare target link(func) // expected-error {{function name is not allowed in 'link' clause}}
extern int b; extern int b;
struct NonT { struct NonT {