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 @@ -11014,8 +11014,6 @@ Expr *C = nullptr; /// True if the cond expr is in the form of 'x ordop expr'. bool IsXBinopExpr = true; - /// The atomic compare operator. - OMPAtomicCompareOp Op; /// Check if it is a valid conditional update statement (cond-update-stmt). bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo); @@ -11072,23 +11070,7 @@ } switch (Cond->getOpcode()) { - case BO_EQ: - Op = OMPAtomicCompareOp::EQ; - break; - case BO_LT: - Op = OMPAtomicCompareOp::MIN; - break; - case BO_GT: - Op = OMPAtomicCompareOp::MAX; - break; - default: - ErrorInfo.Error = ErrorTy::InvalidBinaryOp; - ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); - ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); - return false; - } - - if (Cond->getOpcode() == BO_EQ) { + case BO_EQ: { C = Cond; D = BO->getRHS(); if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { @@ -11101,7 +11083,10 @@ ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); return false; } - } else { + break; + } + case BO_LT: + case BO_GT: { E = BO->getRHS(); if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { @@ -11116,6 +11101,13 @@ ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); return false; } + break; + } + default: + ErrorInfo.Error = ErrorTy::InvalidBinaryOp; + ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); + ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); + return false; } return true; @@ -11166,23 +11158,7 @@ } switch (Cond->getOpcode()) { - case BO_EQ: - Op = OMPAtomicCompareOp::EQ; - break; - case BO_LT: - Op = OMPAtomicCompareOp::MIN; - break; - case BO_GT: - Op = OMPAtomicCompareOp::MAX; - break; - default: - ErrorInfo.Error = ErrorTy::InvalidBinaryOp; - ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); - ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); - return false; - } - - if (Cond->getOpcode() == BO_EQ) { + case BO_EQ: { C = Cond; D = CO->getTrueExpr(); if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { @@ -11195,7 +11171,10 @@ ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); return false; } - } else { + break; + } + case BO_LT: + case BO_GT: { E = CO->getTrueExpr(); if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { @@ -11210,6 +11189,13 @@ ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); return false; } + break; + } + default: + ErrorInfo.Error = ErrorTy::InvalidBinaryOp; + ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); + ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); + return false; } return true; @@ -11219,8 +11205,7 @@ // 'x' and 'e' cannot be nullptr assert(X && E && "X and E cannot be nullptr"); - auto CheckValue = [&ErrorInfo](const Expr *E, OMPAtomicCompareOp Op, - bool ShouldBeLValue) { + auto CheckValue = [&ErrorInfo](const Expr *E, bool ShouldBeLValue) { if (ShouldBeLValue && !E->isLValue()) { ErrorInfo.Error = ErrorTy::XNotLValue; ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); @@ -11237,7 +11222,7 @@ return false; } - if (Op != OMPAtomicCompareOp::EQ && !QTy->isIntegerType()) { + if (!QTy->isIntegerType()) { ErrorInfo.Error = ErrorTy::NotInteger; ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); @@ -11248,13 +11233,13 @@ return true; }; - if (!CheckValue(X, Op, true)) + if (!CheckValue(X, true)) return false; - if (!CheckValue(E, Op, false)) + if (!CheckValue(E, false)) return false; - if (D && !CheckValue(D, Op, false)) + if (D && !CheckValue(D, false)) return false; return true; diff --git a/clang/test/OpenMP/atomic_messages.c b/clang/test/OpenMP/atomic_messages.c --- a/clang/test/OpenMP/atomic_messages.c +++ b/clang/test/OpenMP/atomic_messages.c @@ -483,5 +483,12 @@ if (fx > fe) fx = fe; } +// omp51-error@+5 {{the statement for 'atomic compare' must be a compound statement of form '{x = expr ordop x ? expr : x;}', '{x = x ordop expr? expr : x;}', '{x = x == e ? d : x;}', '{x = e == x ? d : x;}', or 'if(expr ordop x) {x = expr;}', 'if(x ordop expr) {x = expr;}', 'if(x == e) {x = d;}', 'if(e == x) {x = d;}' where 'x' is an lvalue expression with scalar type, 'expr', 'e', and 'd' are expressions with scalar type, and 'ordop' is one of '<' or '>'.}} +// omp51-note@+4 {{expect integer value}} +#pragma omp atomic compare + { + if (fx == fe) + fx = fe; + } } #endif