diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1369,6 +1369,9 @@ "missing map type modifier">; def err_omp_declare_simd_inbranch_notinbranch : Error< "unexpected '%0' clause, '%1' is specified already">; +def err_omp_expected_clause_argument + : Error<"expected '%0' clause with an argument on '#pragma omp %1' " + "construct">; def err_expected_end_declare_target_or_variant : Error< "expected '#pragma omp end declare %select{target|variant}0'">; def err_expected_begin_declare_variant diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -17662,6 +17662,13 @@ SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc) { + if (!InteropVar && LangOpts.OpenMP >= 52 && + DSAStack->getCurrentDirective() == OMPD_depobj) { + Diag(StartLoc, diag::err_omp_expected_clause_argument) + << getOpenMPClauseName(OMPC_destroy) + << getOpenMPDirectiveName(OMPD_depobj); + return nullptr; + } if (InteropVar && !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) return nullptr; diff --git a/clang/test/OpenMP/depobj_messages.cpp b/clang/test/OpenMP/depobj_messages.cpp --- a/clang/test/OpenMP/depobj_messages.cpp +++ b/clang/test/OpenMP/depobj_messages.cpp @@ -2,11 +2,15 @@ // RUN: -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp51 -fopenmp -fopenmp-version=51 \ // RUN: -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp -fopenmp-version=52 \ +// RUN: -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 \ // RUN: -ferror-limit 100 %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp51 -fopenmp-simd -fopenmp-version=51 \ // RUN: -ferror-limit 100 %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp52 -fopenmp-simd -fopenmp-version=52 \ +// RUN: -ferror-limit 100 %s -Wuninitialized struct S1 { // expected-note 2 {{declared here}} int a; @@ -27,7 +31,7 @@ #pragma omp depobj(x) untied // expected-error {{unexpected OpenMP clause 'untied' in directive '#pragma omp depobj'}} #pragma omp depobj(x) unknown // expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} if (argc) -#pragma omp depobj(x) destroy // expected-error {{'#pragma omp depobj' cannot be an immediate substatement}} +#pragma omp depobj(x) destroy // omp52-error {{expected 'destroy' clause with an argument on '#pragma omp depobj' construct}} expected-error {{'#pragma omp depobj' cannot be an immediate substatement}} if (argc) { #pragma omp depobj(x) depend(in:s) } @@ -148,16 +152,16 @@ #pragma omp parallel depobj(argc) // expected-warning {{extra tokens at the end of '#pragma omp parallel' are ignored}} ; #pragma omp depobj(x) seq_cst // expected-error {{unexpected OpenMP clause 'seq_cst' in directive '#pragma omp depobj'}} -#pragma omp depobj(x) depend(source: x) // omp51-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'depend'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} +#pragma omp depobj(x) depend(source: x) // omp52-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'depend'}} omp51-error {{expected depend modifier(iterator) or 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'depend'}} omp50-error {{expected depend modifier(iterator) or 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'depend'}} #pragma omp depobj(x) update // expected-error {{expected '(' after 'update'}} -#pragma omp depobj(x) update( // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'update'}} omp50-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} -#pragma omp depobj(x) update(sink // expected-error {{expected ')'}} expected-note {{to match this '('}} omp51-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'update'}} omp50-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} -#pragma omp depobj(x) destroy destroy // expected-error {{directive '#pragma omp depobj' cannot contain more than one 'destroy' clause}} +#pragma omp depobj(x) update( // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'update'}} omp51-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'update'}} omp50-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} +#pragma omp depobj(x) update(sink // expected-error {{expected ')'}} expected-note {{to match this '('}} omp52-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'update'}} omp51-error {{expected 'in', 'out', 'inout', 'mutexinoutset' or 'inoutset' in OpenMP clause 'update'}} omp50-error {{expected 'in', 'out', 'inout' or 'mutexinoutset' in OpenMP clause 'update'}} +#pragma omp depobj(x) destroy destroy //omp52-error {{expected 'destroy' clause with an argument on '#pragma omp depobj' construct}} omp50-error {{directive '#pragma omp depobj' cannot contain more than one 'destroy' clause}} // omp52-error {{directive '#pragma omp depobj' cannot contain more than one 'destroy' clause}} omp52-error {{expected 'destroy' clause with an argument on '#pragma omp depobj' construct}} omp51-error {{directive '#pragma omp depobj' cannot contain more than one 'destroy' clause}} #pragma omp depobj(x) update(in) update(in) // expected-error {{directive '#pragma omp depobj' cannot contain more than one 'update' clause}} -#pragma omp depobj(x) depend(in: argc) destroy // expected-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} -#pragma omp depobj(x) destroy depend(in: argc) // expected-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} +#pragma omp depobj(x) depend(in: argc) destroy // omp52-error {{expected 'destroy' clause with an argument on '#pragma omp depobj' construct}} omp51-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} omp50-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} +#pragma omp depobj(x) destroy depend(in: argc) // omp52-error {{expected 'destroy' clause with an argument on '#pragma omp depobj' construct}} omp51-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} omp50-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} #pragma omp depobj(x) depend(in: argc) update(mutexinoutset) // expected-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} -#pragma omp depobj(x) update(inout) destroy // expected-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} +#pragma omp depobj(x) update(inout) destroy // omp52-error {{expected 'destroy' clause with an argument on '#pragma omp depobj' construct}} omp51-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} omp50-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} #pragma omp depobj(x) (x) depend(in: x) // expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} #pragma omp depobj(x) (x) update(in) // expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} #pragma omp depobj(x) depend(in: argc) depend(out:argc) // expected-error {{exactly one of 'depend', 'destroy', or 'update' clauses is expected}} @@ -165,7 +169,7 @@ #pragma omp destroy depobj(x) // expected-error {{expected an OpenMP directive}} #pragma omp update(out) depobj(x) // expected-error {{expected an OpenMP directive}} #pragma omp depobj depend(in:x) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} expected-error {{expected addressable lvalue expression, array element, array section or array shaping expression of non 'omp_depend_t' type}} -#pragma omp depobj destroy (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} +#pragma omp depobj destroy (x) // omp52-error {{expected 'destroy' clause with an argument on '#pragma omp depobj' construct}} expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} #pragma omp depobj update(in) (x) // expected-error {{expected depobj expression}} expected-warning {{extra tokens at the end of '#pragma omp depobj' are ignored}} return tmain(argc); // expected-note {{in instantiation of function template specialization 'tmain' requested here}} }