@@ -3170,11 +3170,13 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &x) {
31703170void OmpStructureChecker::Enter (const parser::OmpClause::Lastprivate &x) {
31713171 CheckAllowedClause (llvm::omp::Clause::OMPC_lastprivate);
31723172
3173- CheckIsVarPartOfAnotherVar (GetContext ().clauseSource , x.v , " LASTPRIVATE" );
3173+ const auto &objectList{std::get<parser::OmpObjectList>(x.v .t )};
3174+ CheckIsVarPartOfAnotherVar (
3175+ GetContext ().clauseSource , objectList, " LASTPRIVATE" );
31743176
31753177 DirectivesClauseTriple dirClauseTriple;
31763178 SymbolSourceMap currSymbols;
3177- GetSymbolsInObjectList (x. v , currSymbols);
3179+ GetSymbolsInObjectList (objectList , currSymbols);
31783180 CheckDefinableObjects (currSymbols, GetClauseKindForParserClass (x));
31793181 CheckCopyingPolymorphicAllocatable (
31803182 currSymbols, llvm::omp::Clause::OMPC_lastprivate);
@@ -3189,6 +3191,21 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Lastprivate &x) {
31893191
31903192 CheckPrivateSymbolsInOuterCxt (
31913193 currSymbols, dirClauseTriple, GetClauseKindForParserClass (x));
3194+
3195+ using LastprivateModifier = parser::OmpLastprivateClause::LastprivateModifier;
3196+ const auto &maybeMod{std::get<std::optional<LastprivateModifier>>(x.v .t )};
3197+ if (maybeMod) {
3198+ unsigned version{context_.langOptions ().OpenMPVersion };
3199+ unsigned allowedInVersion = 50 ;
3200+ if (version < allowedInVersion) {
3201+ std::string thisVersion{
3202+ std::to_string (version / 10 ) + " ." + std::to_string (version % 10 )};
3203+ context_.Say (GetContext ().clauseSource ,
3204+ " LASTPRIVATE clause with CONDITIONAL modifier is not "
3205+ " allowed in OpenMP v%s, try -fopenmp-version=%d" _err_en_US,
3206+ thisVersion, allowedInVersion);
3207+ }
3208+ }
31923209}
31933210
31943211void OmpStructureChecker::Enter (const parser::OmpClause::Copyin &x) {
@@ -3608,18 +3625,17 @@ const parser::OmpObjectList *OmpStructureChecker::GetOmpObjectList(
36083625 const parser::OmpClause &clause) {
36093626
36103627 // Clauses with OmpObjectList as its data member
3611- using MemberObjectListClauses =
3612- std::tuple<parser::OmpClause::Copyprivate, parser::OmpClause::Copyin,
3613- parser::OmpClause::Firstprivate, parser::OmpClause::From,
3614- parser::OmpClause::Lastprivate, parser::OmpClause::Link,
3615- parser::OmpClause::Private, parser::OmpClause::Shared,
3616- parser::OmpClause::To, parser::OmpClause::Enter,
3617- parser::OmpClause::UseDevicePtr, parser::OmpClause::UseDeviceAddr>;
3628+ using MemberObjectListClauses = std::tuple<parser::OmpClause::Copyprivate,
3629+ parser::OmpClause::Copyin, parser::OmpClause::Firstprivate,
3630+ parser::OmpClause::From, parser::OmpClause::Link,
3631+ parser::OmpClause::Private, parser::OmpClause::Shared,
3632+ parser::OmpClause::To, parser::OmpClause::Enter,
3633+ parser::OmpClause::UseDevicePtr, parser::OmpClause::UseDeviceAddr>;
36183634
36193635 // Clauses with OmpObjectList in the tuple
3620- using TupleObjectListClauses =
3621- std::tuple< parser::OmpClause::Allocate , parser::OmpClause::Map,
3622- parser::OmpClause::Reduction, parser::OmpClause::Aligned>;
3636+ using TupleObjectListClauses = std::tuple<parser::OmpClause::Allocate,
3637+ parser::OmpClause::Lastprivate , parser::OmpClause::Map,
3638+ parser::OmpClause::Reduction, parser::OmpClause::Aligned>;
36233639
36243640 // TODO:: Generate the tuples using TableGen.
36253641 // Handle other constructs with OmpObjectList such as OpenMPThreadprivate.
0 commit comments