From d7d01c2b94311893407956ebe9024fa878f2a645 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Thu, 20 Aug 2015 12:15:57 +0000 Subject: [PATCH] [OPENMP 4.1] Allow to use 'uval' and 'ref' modifiers for reference types only. Standard allows to use 'uval' and 'ref' modifiers in 'linear' clause for variables with reference types only. Added check for it and modified test. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@245556 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Parse/ParseOpenMP.cpp | 3 +-- lib/Sema/SemaOpenMP.cpp | 6 ++++++ test/OpenMP/simd_linear_messages.cpp | 14 ++++++++------ 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 1debbc5b62..43a51f4335 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -7669,6 +7669,8 @@ def err_omp_parent_cancel_region_ordered : Error< "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be ordered">; def err_omp_wrong_linear_modifier : Error< "expected %select{'val' modifier|one of 'ref', val' or 'uval' modifiers}0">; +def err_omp_wrong_linear_modifier_non_reference : Error< + "variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index e7966d42a5..beb38e10f2 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -785,9 +785,8 @@ OMPClause *Parser::ParseOpenMPVarListClause(OpenMPClauseKind Kind) { } else if (Kind == OMPC_linear) { // Try to parse modifier if any. if (Tok.is(tok::identifier) && PP.LookAhead(0).is(tok::l_paren)) { - StringRef TokSpelling = PP.getSpelling(Tok); LinearModifier = static_cast( - getOpenMPSimpleClauseType(Kind, TokSpelling)); + getOpenMPSimpleClauseType(Kind, PP.getSpelling(Tok))); DepLinLoc = ConsumeToken(); LinearT.consumeOpen(); NeedRParenForLinear = true; diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 33bc621afa..d2653b7cb9 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -6383,6 +6383,12 @@ OMPClause *Sema::ActOnOpenMPLinearClause( diag::err_omp_linear_incomplete_type)) { continue; } + if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && + !QType->isReferenceType()) { + Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) + << QType << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); + continue; + } QType = QType.getNonReferenceType(); // A list item must not be const-qualified. diff --git a/test/OpenMP/simd_linear_messages.cpp b/test/OpenMP/simd_linear_messages.cpp index 1c6d854978..792f78aa3d 100644 --- a/test/OpenMP/simd_linear_messages.cpp +++ b/test/OpenMP/simd_linear_messages.cpp @@ -135,11 +135,11 @@ template int foomain(I argc, C **argv) { for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear (argv[1]) // expected-error {{expected variable name}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(ref(e, g)) + #pragma omp simd linear(ref(e, g)) // expected-error 2 {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'ref'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear(h) // expected-error {{threadprivate or thread local variable cannot be linear}} for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(uval(i)) + #pragma omp simd linear(uval(i)) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}} for (int k = 0; k < argc; ++k) ++k; #pragma omp parallel { @@ -148,7 +148,9 @@ template int foomain(I argc, C **argv) { #pragma omp simd linear(v:i) for (int k = 0; k < argc; ++k) { i = k; v += i; } } - #pragma omp simd linear(j) + #pragma omp simd linear(ref(j)) + for (int k = 0; k < argc; ++k) ++k; + #pragma omp simd linear(uval(j)) for (int k = 0; k < argc; ++k) ++k; int v = 0; #pragma omp simd linear(v:j) @@ -167,7 +169,7 @@ using A::x; } void linear_modifiers(int argc) { - int f; + int &f = argc; #pragma omp simd linear(f) for (int k = 0; k < argc; ++k) ++k; #pragma omp simd linear(val(f)) @@ -233,7 +235,7 @@ int main(int argc, char **argv) { int i; #pragma omp simd linear(val(i)) for (int k = 0; k < argc; ++k) ++k; - #pragma omp simd linear(uval(i) : 4) + #pragma omp simd linear(uval(i) : 4) // expected-error {{variable of non-reference type 'int' can be used only with 'val' modifier, but used with 'uval'}} for (int k = 0; k < argc; ++k) { ++k; i += 4; } } #pragma omp simd linear(ref(j)) @@ -241,7 +243,7 @@ int main(int argc, char **argv) { #pragma omp simd linear(i) for (int k = 0; k < argc; ++k) ++k; - foomain(argc,argv); + foomain(argc,argv); // expected-note {{in instantiation of function template specialization 'foomain' requested here}} return 0; } -- 2.40.0