[flang] Use structureComponent.component.symbol directly instead of getting
authorSteve Scalpone <sscalpone@nvidia.com>
Mon, 8 Apr 2019 07:26:10 +0000 (00:26 -0700)
committerSteve Scalpone <sscalpone@nvidia.com>
Mon, 8 Apr 2019 07:26:10 +0000 (00:26 -0700)
the symbol from the result of expression analysis.  (This opens the
door to moving structure component semantic checking to expression
analysis.)

Also, improve error messages, remove unused include files, and add
copyright headers to test files.

Original-commit: flang-compiler/f18@17780c40d7380db9760e972dcc52724838cd89d8
Reviewed-on: https://github.com/flang-compiler/f18/pull/388

flang/lib/semantics/check-nullify.cc
flang/lib/semantics/expression.cc
flang/lib/semantics/expression.h
flang/test/semantics/nullify01.f90
flang/test/semantics/nullify02.f90

index ad63941..c30b813 100644 (file)
 #include "../parser/message.h"
 #include "../parser/parse-tree.h"
 
-#include "../parser/dump-parse-tree.h"
-#include <iostream>
-
 namespace Fortran::semantics {
 
 void NullifyChecker::Leave(const parser::NullifyStmt &nullifyStmt) {
-  // R938
   for (const parser::PointerObject &pointerObject : nullifyStmt.v) {
-    // R939
     std::visit(
         common::visitors{
             [&](const parser::Name &name) {
               auto const *symbol{name.symbol};
               if (!IsVariableName(*symbol) && !IsProcName(*symbol)) {
                 context_.messages().Say(name.source,
-                    "name must be a variable or procedure pointer name"_err_en_US);
+                    "name in NULLIFY statement must be a variable or procedure pointer name"_err_en_US);
               } else if (!IsPointer(*symbol)) {  // C951
                 context_.messages().Say(name.source,
-                    "name must have the POINTER attribute"_err_en_US);
+                    "name in NULLIFY statement must have the POINTER attribute"_err_en_US);
               }
             },
             [&](const parser::StructureComponent &structureComponent) {
               evaluate::ExpressionAnalyzer analyzer{context_};
               if (MaybeExpr checked{analyzer.Analyze(structureComponent)}) {
-                if (std::optional<evaluate::DataRef> dataRef{
-                        evaluate::ExtractDataRef(std::move(checked))}) {
-                  const Symbol &symbol{dataRef->GetLastSymbol()};
-                  if (!IsPointer(symbol)) {  // C951
-                    context_.messages().Say(structureComponent.component.source,
-                        "component must have the POINTER attribute"_err_en_US);
-                  }
+                if (!IsPointer(*structureComponent.component.symbol)) {  // C951
+                  context_.messages().Say(structureComponent.component.source,
+                      "component in NULLIFY statement must have the POINTER attribute"_err_en_US);
                 }
               }
             },
index 1b6b855..508d4ac 100644 (file)
@@ -111,11 +111,6 @@ std::optional<DataRef> ExtractDataRef(std::optional<A> &&x) {
   return std::nullopt;
 }
 
-// Explicit instantiation instead of moving all ExtractDataRef templates to the
-// header
-template std::optional<DataRef> ExtractDataRef<Expr<SomeType>>(
-    std::optional<Expr<SomeType>> &&);
-
 struct DynamicTypeWithLength : public DynamicType {
   std::optional<Expr<SubscriptInteger>> LEN() const;
   std::optional<Expr<SubscriptInteger>> length;
index 078c2cd..4aa68b6 100644 (file)
@@ -278,9 +278,6 @@ void ConformabilityCheck(
         left.Rank(), right.Rank());
   }
 }
-
-template<typename A>
-std::optional<evaluate::DataRef> ExtractDataRef(std::optional<A> &&x);
 }  // namespace Fortran::evaluate
 
 namespace Fortran::semantics {
index 399caa9..5424681 100644 (file)
@@ -1,3 +1,19 @@
+! Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
+!
+! Licensed under the Apache License, Version 2.0 (the "License");
+! you may not use this file except in compliance with the License.
+! You may obtain a copy of the License at
+!
+!     http://www.apache.org/licenses/LICENSE-2.0
+!
+! Unless required by applicable law or agreed to in writing, software
+! distributed under the License is distributed on an "AS IS" BASIS,
+! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+! See the License for the specific language governing permissions and
+! limitations under the License.
+
+! Test that NULLIFY works
+
 INTEGER, PARAMETER :: maxvalue=1024
 
 Type dt
index ac71ea4..4f05f12 100644 (file)
@@ -1,3 +1,19 @@
+! Copyright (c) 2019, NVIDIA CORPORATION.  All rights reserved.
+!
+! Licensed under the Apache License, Version 2.0 (the "License");
+! you may not use this file except in compliance with the License.
+! You may obtain a copy of the License at
+!
+!     http://www.apache.org/licenses/LICENSE-2.0
+!
+! Unless required by applicable law or agreed to in writing, software
+! distributed under the License is distributed on an "AS IS" BASIS,
+! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+! See the License for the specific language governing permissions and
+! limitations under the License.
+
+! Check for semantic errors in NULLIFY statements
+
 INTEGER, PARAMETER :: maxvalue=1024
 
 Type dt
@@ -13,16 +29,16 @@ Integer :: pi
 Procedure(Real) :: prp
 
 Allocate(x(3))
-!ERROR: component must have the POINTER attribute
+!ERROR: component in NULLIFY statement must have the POINTER attribute
 Nullify(x(2)%p)
 
-!ERROR: name must have the POINTER attribute
+!ERROR: name in NULLIFY statement must have the POINTER attribute
 Nullify(pi)
 
-!ERROR: name must have the POINTER attribute
+!ERROR: name in NULLIFY statement must have the POINTER attribute
 Nullify(prp)
 
-!ERROR: name must be a variable or procedure pointer name
+!ERROR: name in NULLIFY statement must be a variable or procedure pointer name
 Nullify(maxvalue)
 
 End Program