r246853 - [OPENMP] Fix false diagnostic on instantiation-dependent exprs for atomic constructs.

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 4 05:55:51 PDT 2015


Author: abataev
Date: Fri Sep  4 07:55:50 2015
New Revision: 246853

URL: http://llvm.org/viewvc/llvm-project?rev=246853&view=rev
Log:
[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.

Modified:
    cfe/trunk/lib/Sema/SemaOpenMP.cpp
    cfe/trunk/test/OpenMP/atomic_codegen.cpp
    cfe/trunk/test/OpenMP/atomic_messages.cpp

Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=246853&r1=246852&r2=246853&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Sep  4 07:55:50 2015
@@ -4294,7 +4294,7 @@ bool OpenMPAtomicUpdateChecker::checkSta
           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::ActOnOpenMPAtomicDirect
           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::ActOnOpenMPAtomicDirect
           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::ActOnOpenMPAtomicDirect
         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::ActOnOpenMPAtomicDirect
           }
           if (!IsUpdateExprFound) {
             //  { v = x; x = expr; }
-            auto *FirstBinOp = dyn_cast<BinaryOperator>(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<BinaryOperator>(Second);
-              if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
+            auto *FirstExpr = dyn_cast<Expr>(First);
+            auto *SecondExpr = dyn_cast<Expr>(Second);
+            if (!FirstExpr || !SecondExpr ||
+                !(FirstExpr->isInstantiationDependent() ||
+                  SecondExpr->isInstantiationDependent())) {
+              auto *FirstBinOp = dyn_cast<BinaryOperator>(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<BinaryOperator>(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();
+                  }
                 }
               }
             }

Modified: cfe/trunk/test/OpenMP/atomic_codegen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_codegen.cpp?rev=246853&r1=246852&r2=246853&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/atomic_codegen.cpp (original)
+++ cfe/trunk/test/OpenMP/atomic_codegen.cpp Fri Sep  4 07:55:50 2015
@@ -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

Modified: cfe/trunk/test/OpenMP/atomic_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/atomic_messages.cpp?rev=246853&r1=246852&r2=246853&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/atomic_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/atomic_messages.cpp Fri Sep  4 07:55:50 2015
@@ -48,8 +48,8 @@ T read() {
   // expected-note at +1 {{expected built-in assignment operator}}
   foo();
 #pragma omp atomic read
-  // expected-error at +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 at +1 {{expected built-in assignment operator}}
+  // expected-error at +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 at +1 2 {{expected built-in assignment operator}}
   a += b;
 #pragma omp atomic read
   // expected-error at +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 at +1 {{in instantiation of function template specialization 'read<S>' requested here}}
+  // expected-note at +2 {{in instantiation of function template specialization 'read<S>' requested here}}
+  // expected-note at +1 {{in instantiation of function template specialization 'read<int>' requested here}}
   return read<int>() + read<S>().a;
 }
 
@@ -147,6 +148,7 @@ int write() {
 #pragma omp atomic write
   a = foo();
 
+  // expected-note at +1 {{in instantiation of function template specialization 'write<int>' requested here}}
   return write<int>();
 }
 
@@ -672,6 +674,7 @@ int capture() {
 #pragma omp atomic capture capture
   b = a /= b;
 
+  // expected-note at +1 {{in instantiation of function template specialization 'capture<int>' requested here}}
   return capture<int>();
 }
 




More information about the cfe-commits mailing list