[flang] Catch misuse of a procedure designator as an output item
authorPeter Klausler <pklausler@nvidia.com>
Fri, 3 Feb 2023 00:50:09 +0000 (16:50 -0800)
committerPeter Klausler <pklausler@nvidia.com>
Mon, 13 Feb 2023 00:44:58 +0000 (16:44 -0800)
f18 was diagnosing the misuse of a procedure pointer as an output item,
but not the more general case of a procedure designator other than
a pointer.

Differential Revision: https://reviews.llvm.org/D143780

flang/lib/Semantics/check-io.cpp
flang/lib/Semantics/expression.cpp
flang/test/Semantics/io04.f90

index 349b34d..bbe76c4 100644 (file)
@@ -613,11 +613,9 @@ void IoChecker::Enter(const parser::OutputItem &item) {
       if (evaluate::IsBOZLiteral(*expr)) {
         context_.Say(parser::FindSourceLocation(*x), // C7109
             "Output item must not be a BOZ literal constant"_err_en_US);
-      }
-      const Symbol *last{GetLastSymbol(*expr)};
-      if (last && IsProcedurePointer(*last)) {
+      } else if (IsProcedure(*expr)) {
         context_.Say(parser::FindSourceLocation(*x),
-            "Output item must not be a procedure pointer"_err_en_US); // C1233
+            "Output item must not be a procedure"_err_en_US); // C1233
       }
       CheckForBadIoType(*expr,
           flags_.test(Flag::FmtOrNml)
index 116aa7f..6eb0889 100644 (file)
@@ -566,10 +566,10 @@ MaybeExpr ExpressionAnalyzer::Analyze(const parser::Designator &d) {
     std::optional<DataRef> dataRef{ExtractDataRef(std::move(result))};
     if (!dataRef) {
       dataRef = ExtractDataRef(std::move(result), /*intoSubstring=*/true);
-      if (!dataRef) {
-        dataRef = ExtractDataRef(std::move(result),
-            /*intoSubstring=*/false, /*intoComplexPart=*/true);
-      }
+    }
+    if (!dataRef) {
+      dataRef = ExtractDataRef(std::move(result),
+          /*intoSubstring=*/false, /*intoComplexPart=*/true);
     }
     if (dataRef && !CheckDataRef(*dataRef)) {
       result.reset();
index 9260119..685e43d 100644 (file)
@@ -12,6 +12,8 @@
   integer, pointer :: a(:)
   integer, parameter :: const_id = 66666
   procedure(), pointer :: procptr
+  external external
+  intrinsic acos
 
   namelist /nnn/ nn1, nn2
 
 
   write(*, '(X)')
 
-  !ERROR: Output item must not be a procedure pointer
-  print*, n1, procptr, n2
+  !ERROR: Output item must not be a procedure
+  print*, procptr
+  !ERROR: Output item must not be a procedure
+  print*, acos
+  !ERROR: Output item must not be a procedure
+  print*, external
 
 1 format (A)
 9 continue