diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 686cef249f3a5..ec0d095e89950 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -11015,8 +11015,6 @@ class OpenMPAtomicCompareChecker { 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); @@ -11073,23 +11071,7 @@ bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, } 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())) { @@ -11102,7 +11084,10 @@ bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 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())) { @@ -11117,6 +11102,13 @@ bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 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; @@ -11167,23 +11159,7 @@ bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, } 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())) { @@ -11196,7 +11172,10 @@ bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 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())) { @@ -11211,6 +11190,13 @@ bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 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; @@ -11220,8 +11206,7 @@ bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { // '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(); @@ -11238,7 +11223,7 @@ bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 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(); @@ -11249,13 +11234,13 @@ bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 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 index d9e2b1a352ec6..22f7be91662b5 100644 --- a/clang/test/OpenMP/atomic_messages.c +++ b/clang/test/OpenMP/atomic_messages.c @@ -483,5 +483,12 @@ void compare(void) { 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