From 5d154c3e7d9dcd8f651ac6b34ee21aa553c82c74 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 8 Oct 2019 15:56:43 +0000 Subject: [PATCH] [OPENMP50]Prohibit multiple context selector sets in context selectors. According to OpenMP 5.0, 2.3.2 Context Selectors, Restrictions, each trait-set-selector-name can only be specified once. Added check to implement this restriction. llvm-svn: 374072 --- clang/include/clang/Basic/DiagnosticParseKinds.td | 4 +++ clang/lib/Parse/ParseOpenMP.cpp | 11 +++++++++ clang/test/OpenMP/declare_variant_ast_print.c | 3 +-- clang/test/OpenMP/declare_variant_ast_print.cpp | 30 ++++++++--------------- clang/test/OpenMP/declare_variant_messages.c | 2 +- clang/test/OpenMP/declare_variant_messages.cpp | 4 +-- 6 files changed, 29 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index ac1c525..c0b488d 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1211,6 +1211,10 @@ def warn_omp_declare_variant_cs_name_expected : Warning< InGroup; def err_omp_declare_variant_item_expected : Error< "expected %0 in '%1' context selector of '%2' selector set of 'omp declare variant' directive">; +def err_omp_declare_variant_ctx_set_mutiple_use : Error< + "context selector set '%0' is used already in the same 'omp declare variant' directive">; +def note_omp_declare_variant_ctx_set_used_here : Note< + "previously context selector set '%0' used here">; def warn_omp_more_one_device_type_clause : Warning< "more than one 'device_type' clause is specified">, InGroup; diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index 998fae6..e487e0a 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -892,6 +892,7 @@ bool Parser::parseOpenMPContextSelectors( llvm::function_ref Callback) { + llvm::StringMap UsedCtxSets; do { // Parse inner context selector set name. if (!Tok.is(tok::identifier)) { @@ -901,6 +902,16 @@ bool Parser::parseOpenMPContextSelectors( } SmallString<16> Buffer; StringRef CtxSelectorSetName = PP.getSpelling(Tok, Buffer); + auto Res = UsedCtxSets.try_emplace(CtxSelectorSetName, Tok.getLocation()); + if (!Res.second) { + // OpenMP 5.0, 2.3.2 Context Selectors, Restrictions. + // Each trait-set-selector-name can only be specified once. + Diag(Tok.getLocation(), diag::err_omp_declare_variant_ctx_set_mutiple_use) + << CtxSelectorSetName; + Diag(Res.first->getValue(), + diag::note_omp_declare_variant_ctx_set_used_here) + << CtxSelectorSetName; + } // Parse '='. (void)ConsumeToken(); if (Tok.isNot(tok::equal)) { diff --git a/clang/test/OpenMP/declare_variant_ast_print.c b/clang/test/OpenMP/declare_variant_ast_print.c index 07e55a9..0174c07 100644 --- a/clang/test/OpenMP/declare_variant_ast_print.c +++ b/clang/test/OpenMP/declare_variant_ast_print.c @@ -8,7 +8,7 @@ int foo(void); #pragma omp declare variant(foo) match(xxx={}, yyy={ccc}) #pragma omp declare variant(foo) match(xxx={vvv}) -#pragma omp declare variant(foo) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(foo) match(implementation={vendor(llvm)}) #pragma omp declare variant(foo) match(implementation={vendor(unknown)}) #pragma omp declare variant(foo) match(implementation={vendor(score(5): ibm, xxx)}) int bar(void); @@ -17,6 +17,5 @@ int bar(void); // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):ibm)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(score(5):xxx)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(foo) match(implementation={vendor(llvm)}) // CHECK-NEXT: int bar(); diff --git a/clang/test/OpenMP/declare_variant_ast_print.cpp b/clang/test/OpenMP/declare_variant_ast_print.cpp index 984aafa..879014b 100644 --- a/clang/test/OpenMP/declare_variant_ast_print.cpp +++ b/clang/test/OpenMP/declare_variant_ast_print.cpp @@ -19,12 +19,11 @@ T foofoo() { return T(); } // CHECK: #pragma omp declare variant(foofoo) match(implementation={vendor(score(5):ibm)}) // CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(llvm)}) // CHECK-NEXT: int bar(); #pragma omp declare variant(foofoo ) match(xxx = {}) #pragma omp declare variant(foofoo ) match(xxx = {vvv}) -#pragma omp declare variant(foofoo ) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(foofoo ) match(implementation={vendor(llvm)}) #pragma omp declare variant(foofoo ) match(implementation={vendor(unknown)}) #pragma omp declare variant(foofoo ) match(implementation={vendor(score(5): ibm)}) int bar(); @@ -32,16 +31,15 @@ int bar(); // CHECK: #pragma omp declare variant(foofoo) match(implementation={vendor(score(C + 5):ibm)}) // CHECK: #pragma omp declare variant(foofoo) match(implementation={vendor(score(C + 5):xxx)}) // CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(llvm)}) // CHECK-NEXT: template T barbar(); #pragma omp declare variant(foofoo ) match(xxx = {}) #pragma omp declare variant(foofoo ) match(xxx = {vvv}) #pragma omp declare variant(foofoo ) match(user = {score() : condition()}) -#pragma omp declare variant(foofoo ) match(user = {score() : condition()}, user = {condition()}) +#pragma omp declare variant(foofoo ) match(user = {score() : condition()}) #pragma omp declare variant(foofoo ) match(user = {condition()}) #pragma omp declare variant(foofoo ) match(user = {condition()}) -#pragma omp declare variant(foofoo ) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(foofoo ) match(implementation={vendor(llvm)}) #pragma omp declare variant(foofoo ) match(implementation={vendor(unknown)}) #pragma omp declare variant(foofoo ) match(implementation={vendor(score(C+5): ibm, xxx)}) template @@ -50,7 +48,6 @@ T barbar(); // CHECK: #pragma omp declare variant(foofoo) match(implementation={vendor(score(3 + 5):ibm)}) // CHECK: #pragma omp declare variant(foofoo) match(implementation={vendor(score(3 + 5):xxx)}) // CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(foofoo) match(implementation={vendor(llvm)}) // CHECK-NEXT: template<> int barbar(); @@ -72,19 +69,17 @@ void h_ref(C *hp, C *hp2, C *hq, C *lin) { } // CHECK: #pragma omp declare variant(h_ref) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(h_ref) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(h_ref) match(implementation={vendor(llvm)}) // CHECK-NEXT: template void h(C *hp, C *hp2, C *hq, C *lin) { // CHECK-NEXT: } #pragma omp declare variant(h_ref ) match(xxx = {}) -#pragma omp declare variant(h_ref ) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(h_ref ) match(implementation={vendor(llvm)}) #pragma omp declare variant(h_ref ) match(implementation={vendor(unknown)}) template void h(C *hp, C *hp2, C *hq, C *lin) { } // CHECK: #pragma omp declare variant(h_ref) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(h_ref) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(h_ref) match(implementation={vendor(llvm)}) // CHECK-NEXT: template<> void h(float *hp, float *hp2, float *hq, float *lin) { // CHECK-NEXT: } @@ -93,7 +88,7 @@ void h(C *hp, C *hp2, C *hq, C *lin) { // CHECK-NEXT: h((float *)hp, (float *)hp2, (float *)hq, (float *)lin); // CHECK-NEXT: } #pragma omp declare variant(h_ref ) match(xxx = {}) -#pragma omp declare variant(h_ref ) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(h_ref ) match(implementation={vendor(ibm)}) #pragma omp declare variant(h_ref ) match(implementation={vendor(unknown)}) template <> void h(double *hp, double *hp2, double *hq, double *lin) { @@ -105,11 +100,10 @@ int fn(); // CHECK: int fn(int); int fn(int); // CHECK: #pragma omp declare variant(fn) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(fn) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(fn) match(implementation={vendor(llvm)}) // CHECK-NEXT: int overload(); #pragma omp declare variant(fn) match(xxx = {}) -#pragma omp declare variant(fn) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(fn) match(implementation={vendor(llvm)}) #pragma omp declare variant(fn) match(implementation={vendor(unknown)}) int overload(void); @@ -118,11 +112,10 @@ int overload(void); // CHECK-NEXT: } auto fn_deduced_variant() { return 0; } // CHECK: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(llvm)}) // CHECK-NEXT: int fn_deduced(); #pragma omp declare variant(fn_deduced_variant) match(xxx = {}) -#pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(llvm)}) #pragma omp declare variant(fn_deduced_variant) match(implementation={vendor(unknown)}) int fn_deduced(); @@ -130,12 +123,11 @@ int fn_deduced(); int fn_deduced_variant1(); // CHECK: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(unknown)}) // CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)}) -// CHECK-NEXT: #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(llvm)}) // CHECK-NEXT: int fn_deduced1() { // CHECK-NEXT: return 0; // CHECK-NEXT: } #pragma omp declare variant(fn_deduced_variant1) match(xxx = {}) -#pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(ibm)}) #pragma omp declare variant(fn_deduced_variant1) match(implementation={vendor(unknown)}) auto fn_deduced1() { return 0; } @@ -152,7 +144,6 @@ auto fn_deduced1() { return 0; } // CHECK-NEXT: } // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}) // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)}) -// CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(llvm)}) // CHECK-NEXT: void foo1() { // CHECK-NEXT: } // CHECK-NEXT: #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}) @@ -168,7 +159,7 @@ struct SpecialFuncs { void bar(int) {} #pragma omp declare variant(SpecialFuncs::baz) match(xxx = {}) #pragma omp declare variant(SpecialFuncs::bar) match(xxx = {}) -#pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(SpecialFuncs::bar) match(implementation={vendor(ibm)}) #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}) void foo1() {} #pragma omp declare variant(SpecialFuncs::baz) match(implementation={vendor(unknown)}) @@ -184,12 +175,11 @@ void SpecialFuncs::xxx() {} // CHECK-NEXT: } static void static_f_variant() {} // CHECK: #pragma omp declare variant(static_f_variant) match(implementation={vendor(unknown)}) -// CHECK-NEXT: #pragma omp declare variant(static_f_variant) match(implementation={vendor(ibm)}) // CHECK-NEXT: #pragma omp declare variant(static_f_variant) match(implementation={vendor(llvm)}) // CHECK-NEXT: static void static_f() { // CHECK-NEXT: } #pragma omp declare variant(static_f_variant) match(xxx = {}) -#pragma omp declare variant(static_f_variant) match(implementation={vendor(ibm)}, implementation={vendor(llvm)}) +#pragma omp declare variant(static_f_variant) match(implementation={vendor(llvm)}) #pragma omp declare variant(static_f_variant) match(implementation={vendor(unknown)}) static void static_f() {} diff --git a/clang/test/OpenMP/declare_variant_messages.c b/clang/test/OpenMP/declare_variant_messages.c index e8fed31..c6737f5 100644 --- a/clang/test/OpenMP/declare_variant_messages.c +++ b/clang/test/OpenMP/declare_variant_messages.c @@ -24,7 +24,7 @@ int foo(void); #pragma omp declare variant(foo) match(xxx={) // expected-error {{expected '}'}} expected-note {{to match this '{'}} #pragma omp declare variant(foo) match(xxx={}) #pragma omp declare variant(foo) match(xxx={vvv}) -#pragma omp declare variant(foo) match(xxx={vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} +#pragma omp declare variant(foo) match(xxx={vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-error {{context selector set 'xxx' is used already in the same 'omp declare variant' directive}} expected-note {{previously context selector set 'xxx' used here}} #pragma omp declare variant(foo) match(xxx={vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}} #pragma omp declare variant(foo) match(implementation={xxx}) // expected-warning {{unknown context selector in 'implementation' context selector set of 'omp declare variant' directive, ignored}} #pragma omp declare variant(foo) match(implementation={vendor}) // expected-error {{expected '(' after 'vendor'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')' or ',' after 'vendor name'}} expected-error {{expected ')'}} expected-note {{to match this '('}} diff --git a/clang/test/OpenMP/declare_variant_messages.cpp b/clang/test/OpenMP/declare_variant_messages.cpp index f80c93c..e986cd6 100644 --- a/clang/test/OpenMP/declare_variant_messages.cpp +++ b/clang/test/OpenMP/declare_variant_messages.cpp @@ -27,7 +27,7 @@ T foofoo(); // expected-note 2 {{declared here}} #pragma omp declare variant(foofoo ) match(xxx = {) // expected-error {{expected '}'}} expected-note {{to match this '{'}} #pragma omp declare variant(foofoo ) match(xxx = {}) #pragma omp declare variant(foofoo ) match(xxx = {vvv}) -#pragma omp declare variant(foofoo ) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} +#pragma omp declare variant(foofoo ) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-error {{context selector set 'xxx' is used already in the same 'omp declare variant' directive}} expected-note {{previously context selector set 'xxx' used here}} #pragma omp declare variant(foofoo ) match(xxx = {vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}} #pragma omp declare variant(foofoo ) match(implementation={xxx}) // expected-warning {{unknown context selector in 'implementation' context selector set of 'omp declare variant' directive, ignored}} #pragma omp declare variant(foofoo ) match(implementation={vendor}) // expected-error {{expected '(' after 'vendor'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-error {{expected ')' or ',' after 'vendor name'}} expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -60,7 +60,7 @@ int bar(); #pragma omp declare variant(foofoo ) match(user = {score() : condition()}) #pragma omp declare variant(foofoo ) match(user = {condition()}) #pragma omp declare variant(foofoo ) match(user = {condition()}) -#pragma omp declare variant(foofoo ) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} +#pragma omp declare variant(foofoo ) match(xxx = {vvv} xxx) // expected-error {{expected ','}} expected-error {{expected '=' after 'xxx' context selector set name on 'omp declare variant' directive}} expected-error {{context selector set 'xxx' is used already in the same 'omp declare variant' directive}} expected-note {{previously context selector set 'xxx' used here}} #pragma omp declare variant(foofoo ) match(xxx = {vvv}) xxx // expected-warning {{extra tokens at the end of '#pragma omp declare variant' are ignored}} #pragma omp declare variant(foofoo ) match(implementation={vendor(score ibm)}) // expected-error {{expected '(' after 'score'}} expected-warning {{missing ':' after context selector score clause - ignoring}} #pragma omp declare variant(foofoo ) match(implementation={vendor(score( ibm)}) // expected-error {{expected ')' or ',' after 'vendor name'}} expected-error {{expected ')'}} expected-error {{use of undeclared identifier 'ibm'}} expected-error {{expected vendor identifier in 'vendor' context selector of 'implementation' selector set of 'omp declare variant' directive}} expected-warning {{missing ':' after context selector score clause - ignoring}} expected-note {{to match this '('}} -- 2.7.4