From: Alexey Bataev Date: Fri, 4 Sep 2015 12:55:50 +0000 (+0000) Subject: [OPENMP] Fix false diagnostic on instantiation-dependent exprs for atomic constructs. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f08b591b3f1f0b94def63bf4bda3af6d071ac7b7;p=clang [OPENMP] Fix false diagnostic on instantiation-dependent exprs for atomic constructs. Some of instantiation-dependent expressions could cause false diagnostic to be emitted about unsupported atomic constructs. Relaxed rules for detection of incorrect expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@246853 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index b4a6768394..6abdd9d8cd 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -4294,7 +4294,7 @@ bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, NoteLoc = AtomicUnaryOp->getOperatorLoc(); NoteRange = SourceRange(NoteLoc, NoteLoc); } - } else { + } else if (!AtomicBody->isInstantiationDependent()) { ErrorFound = NotABinaryOrUnaryExpression; NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); NoteRange = ErrorRange = AtomicBody->getSourceRange(); @@ -4440,7 +4440,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, NoteLoc = NotScalarExpr->getExprLoc(); NoteRange = NotScalarExpr->getSourceRange(); } - } else { + } else if (!AtomicBody->isInstantiationDependent()) { ErrorFound = NotAnAssignmentOp; ErrorLoc = AtomicBody->getExprLoc(); ErrorRange = AtomicBody->getSourceRange(); @@ -4501,7 +4501,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, NoteLoc = NotScalarExpr->getExprLoc(); NoteRange = NotScalarExpr->getSourceRange(); } - } else { + } else if (!AtomicBody->isInstantiationDependent()) { ErrorFound = NotAnAssignmentOp; ErrorLoc = AtomicBody->getExprLoc(); ErrorRange = AtomicBody->getSourceRange(); @@ -4579,7 +4579,7 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, UE = Checker.getUpdateExpr(); IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); IsPostfixUpdate = Checker.isPostfixUpdate(); - } else { + } else if (!AtomicBody->isInstantiationDependent()) { ErrorLoc = AtomicBody->getExprLoc(); ErrorRange = AtomicBody->getSourceRange(); NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() @@ -4686,46 +4686,54 @@ StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef Clauses, } if (!IsUpdateExprFound) { // { v = x; x = expr; } - auto *FirstBinOp = dyn_cast(First); - if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { - ErrorFound = NotAnAssignmentOp; - NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() - : First->getLocStart(); - NoteRange = ErrorRange = FirstBinOp - ? FirstBinOp->getSourceRange() - : SourceRange(ErrorLoc, ErrorLoc); - } else { - auto *SecondBinOp = dyn_cast(Second); - if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { + auto *FirstExpr = dyn_cast(First); + auto *SecondExpr = dyn_cast(Second); + if (!FirstExpr || !SecondExpr || + !(FirstExpr->isInstantiationDependent() || + SecondExpr->isInstantiationDependent())) { + auto *FirstBinOp = dyn_cast(First); + if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { ErrorFound = NotAnAssignmentOp; - NoteLoc = ErrorLoc = SecondBinOp ? SecondBinOp->getOperatorLoc() - : Second->getLocStart(); - NoteRange = ErrorRange = SecondBinOp - ? SecondBinOp->getSourceRange() + NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() + : First->getLocStart(); + NoteRange = ErrorRange = FirstBinOp + ? FirstBinOp->getSourceRange() : SourceRange(ErrorLoc, ErrorLoc); } else { - auto *PossibleXRHSInFirst = - FirstBinOp->getRHS()->IgnoreParenImpCasts(); - auto *PossibleXLHSInSecond = - SecondBinOp->getLHS()->IgnoreParenImpCasts(); - llvm::FoldingSetNodeID X1Id, X2Id; - PossibleXRHSInFirst->Profile(X1Id, Context, /*Canonical=*/true); - PossibleXLHSInSecond->Profile(X2Id, Context, - /*Canonical=*/true); - IsUpdateExprFound = X1Id == X2Id; - if (IsUpdateExprFound) { - V = FirstBinOp->getLHS(); - X = SecondBinOp->getLHS(); - E = SecondBinOp->getRHS(); - UE = nullptr; - IsXLHSInRHSPart = false; - IsPostfixUpdate = true; + auto *SecondBinOp = dyn_cast(Second); + if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { + ErrorFound = NotAnAssignmentOp; + NoteLoc = ErrorLoc = SecondBinOp + ? SecondBinOp->getOperatorLoc() + : Second->getLocStart(); + NoteRange = ErrorRange = + SecondBinOp ? SecondBinOp->getSourceRange() + : SourceRange(ErrorLoc, ErrorLoc); } else { - ErrorFound = NotASpecificExpression; - ErrorLoc = FirstBinOp->getExprLoc(); - ErrorRange = FirstBinOp->getSourceRange(); - NoteLoc = SecondBinOp->getLHS()->getExprLoc(); - NoteRange = SecondBinOp->getRHS()->getSourceRange(); + auto *PossibleXRHSInFirst = + FirstBinOp->getRHS()->IgnoreParenImpCasts(); + auto *PossibleXLHSInSecond = + SecondBinOp->getLHS()->IgnoreParenImpCasts(); + llvm::FoldingSetNodeID X1Id, X2Id; + PossibleXRHSInFirst->Profile(X1Id, Context, + /*Canonical=*/true); + PossibleXLHSInSecond->Profile(X2Id, Context, + /*Canonical=*/true); + IsUpdateExprFound = X1Id == X2Id; + if (IsUpdateExprFound) { + V = FirstBinOp->getLHS(); + X = SecondBinOp->getLHS(); + E = SecondBinOp->getRHS(); + UE = nullptr; + IsXLHSInRHSPart = false; + IsPostfixUpdate = true; + } else { + ErrorFound = NotASpecificExpression; + ErrorLoc = FirstBinOp->getExprLoc(); + ErrorRange = FirstBinOp->getSourceRange(); + NoteLoc = SecondBinOp->getLHS()->getExprLoc(); + NoteRange = SecondBinOp->getRHS()->getSourceRange(); + } } } } diff --git a/test/OpenMP/atomic_codegen.cpp b/test/OpenMP/atomic_codegen.cpp index 2ce1f9450b..bcaa0e9576 100644 --- a/test/OpenMP/atomic_codegen.cpp +++ b/test/OpenMP/atomic_codegen.cpp @@ -6,6 +6,7 @@ int a; int b; struct St { + unsigned long field; St() {} ~St() {} int &get() { return a; } @@ -13,6 +14,7 @@ struct St { // CHECK-LABEL: parallel_atomic_ewc void parallel_atomic_ewc() { + St s; #pragma omp parallel { // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) @@ -47,6 +49,8 @@ void parallel_atomic_ewc() { // CHECK: invoke void @_ZN2StD1Ev(%struct.St* [[TEMP_ST_ADDR]]) #pragma omp atomic St().get() %= b; +#pragma omp atomic + s.field++; // CHECK: invoke void @_ZN2StC1Ev(%struct.St* [[TEMP_ST_ADDR:%.+]]) // CHECK: [[SCALAR_ADDR:%.+]] = invoke dereferenceable(4) i32* @_ZN2St3getEv(%struct.St* [[TEMP_ST_ADDR]]) // CHECK: [[B_VAL:%.+]] = load i32, i32* @b diff --git a/test/OpenMP/atomic_messages.cpp b/test/OpenMP/atomic_messages.cpp index c3e02bc96e..7f78ad443d 100644 --- a/test/OpenMP/atomic_messages.cpp +++ b/test/OpenMP/atomic_messages.cpp @@ -48,8 +48,8 @@ T read() { // expected-note@+1 {{expected built-in assignment operator}} foo(); #pragma omp atomic read - // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} - // expected-note@+1 {{expected built-in assignment operator}} + // expected-error@+2 2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} + // expected-note@+1 2 {{expected built-in assignment operator}} a += b; #pragma omp atomic read // expected-error@+2 {{the statement for 'atomic read' must be an expression statement of form 'v = x;', where v and x are both lvalue expressions with scalar type}} @@ -93,7 +93,8 @@ int read() { #pragma omp atomic read read a = b; - // expected-note@+1 {{in instantiation of function template specialization 'read' requested here}} + // expected-note@+2 {{in instantiation of function template specialization 'read' requested here}} + // expected-note@+1 {{in instantiation of function template specialization 'read' requested here}} return read() + read().a; } @@ -147,6 +148,7 @@ int write() { #pragma omp atomic write a = foo(); + // expected-note@+1 {{in instantiation of function template specialization 'write' requested here}} return write(); } @@ -672,6 +674,7 @@ int capture() { #pragma omp atomic capture capture b = a /= b; + // expected-note@+1 {{in instantiation of function template specialization 'capture' requested here}} return capture(); }