[llvm-branch-commits] [flang] 3de92ca - [flang] Add tests for procedure arguments with implicit interfaces

2021-01-13 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2021-01-13T16:43:09-08:00
New Revision: 3de92ca78cd4e180920acc077452f87c44c7d935

URL: 
https://github.com/llvm/llvm-project/commit/3de92ca78cd4e180920acc077452f87c44c7d935
DIFF: 
https://github.com/llvm/llvm-project/commit/3de92ca78cd4e180920acc077452f87c44c7d935.diff

LOG: [flang] Add tests for procedure arguments with implicit interfaces

It's possible to declare an external procedure and then pass it as an
actual argument to a subprogram expecting a procedure argument.  I added
tests for this and added an error message to distinguish passing an
actual argument with an implicit interface from passing an argument with
a mismatched explicit interface.

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

Added: 


Modified: 
flang/lib/Semantics/check-call.cpp
flang/test/Semantics/call09.f90

Removed: 




diff  --git a/flang/lib/Semantics/check-call.cpp 
b/flang/lib/Semantics/check-call.cpp
index c954dba58fbc..ffae3410a852 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -537,9 +537,20 @@ static void CheckProcedureArg(evaluate::ActualArgument 
&arg,
   }
   if (interface.HasExplicitInterface()) {
 if (interface != argInterface) {
-  messages.Say(
-  "Actual argument procedure has interface incompatible with 
%s"_err_en_US,
-  dummyName);
+  // 15.5.2.9(1): Explicit interfaces must match
+  if (argInterface.HasExplicitInterface()) {
+messages.Say(
+"Actual procedure argument has interface incompatible with 
%s"_err_en_US,
+dummyName);
+return;
+  } else {
+messages.Say(
+"Actual procedure argument has an implicit interface "
+"which is not known to be compatible with %s which has an "
+"explcit interface"_err_en_US,
+dummyName);
+return;
+  }
 }
   } else { // 15.5.2.9(2,3)
 if (interface.IsSubroutine() && argInterface.IsFunction()) {

diff  --git a/flang/test/Semantics/call09.f90 b/flang/test/Semantics/call09.f90
index 8c21d376fd60..e7f22e32ed44 100644
--- a/flang/test/Semantics/call09.f90
+++ b/flang/test/Semantics/call09.f90
@@ -19,6 +19,9 @@ subroutine s01(p)
   subroutine s02(p)
 procedure(realfunc), pointer :: p
   end subroutine
+  subroutine s03(p)
+procedure(realfunc) :: p
+  end subroutine
 
   subroutine selemental1(p)
 procedure(cos) :: p ! ok
@@ -47,28 +50,33 @@ subroutine test1 ! 15.5.2.9(5)
 procedure(realfunc), pointer :: p
 procedure(intfunc), pointer :: ip
 integer, pointer :: intPtr
+external :: extfunc
+external :: extfuncPtr
+pointer :: extfuncPtr
 p => realfunc
 ip => intfunc
 call s01(realfunc) ! ok
-!ERROR: Actual argument procedure has interface incompatible with dummy 
argument 'p='
+!ERROR: Actual procedure argument has interface incompatible with dummy 
argument 'p='
 call s01(intfunc)
 call s01(p) ! ok
 call s01(procptr()) ! ok
-!ERROR: Actual argument procedure has interface incompatible with dummy 
argument 'p='
+!ERROR: Actual procedure argument has interface incompatible with dummy 
argument 'p='
 call s01(intprocptr())
 call s01(null()) ! ok
 call s01(null(p)) ! ok
-!ERROR: Actual argument procedure has interface incompatible with dummy 
argument 'p='
+!ERROR: Actual procedure argument has interface incompatible with dummy 
argument 'p='
 call s01(null(ip))
 call s01(sin) ! ok
 !ERROR: Actual argument associated with procedure dummy argument 'p=' is 
not a procedure
 call s01(null(intPtr))
 !ERROR: Actual argument associated with procedure dummy argument 'p=' is 
not a procedure
 call s01(B"0101")
+!ERROR: Actual procedure argument has an implicit interface which is not 
known to be compatible with dummy argument 'p=' which has an explcit interface
+call s01(extfunc)
 !ERROR: Actual argument associated with procedure pointer dummy argument 
'p=' must be a POINTER unless INTENT(IN)
 call s02(realfunc)
 call s02(p) ! ok
-!ERROR: Actual argument procedure has interface incompatible with dummy 
argument 'p='
+!ERROR: Actual procedure argument has interface incompatible with dummy 
argument 'p='
 call s02(ip)
 !ERROR: Actual argument associated with procedure pointer dummy argument 
'p=' must be a POINTER unless INTENT(IN)
 call s02(procptr())
@@ -78,6 +86,10 @@ subroutine test1 ! 15.5.2.9(5)
 call s02(null(p))
 !ERROR: Actual argument associated with procedure pointer dummy argument 
'p=' must be a POINTER unless INTENT(IN)
 call s02(sin)
+!ERROR: Actual procedure argument has an implicit interface which 

[llvm-branch-commits] [flang] 1e1a011 - [flang] Disallow INTENT attribute on procedure dummy arguments

2021-01-15 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2021-01-15T08:53:43-08:00
New Revision: 1e1a011b09d0e6e9ff62b37721906485c386708c

URL: 
https://github.com/llvm/llvm-project/commit/1e1a011b09d0e6e9ff62b37721906485c386708c
DIFF: 
https://github.com/llvm/llvm-project/commit/1e1a011b09d0e6e9ff62b37721906485c386708c.diff

LOG: [flang] Disallow INTENT attribute on procedure dummy arguments

C843 states that "An entity with the INTENT attribute shall be a dummy
data object or a dummy procedure pointer."  This change enforces that
and fixes some tests that erroneously violated this rule.

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

Added: 


Modified: 
flang/lib/Semantics/check-declarations.cpp
flang/test/Semantics/assign03.f90
flang/test/Semantics/call09.f90
flang/test/Semantics/separate-mp02.f90

Removed: 




diff  --git a/flang/lib/Semantics/check-declarations.cpp 
b/flang/lib/Semantics/check-declarations.cpp
index 9bb82156e955..aca5392e507f 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -632,6 +632,14 @@ void CheckHelper::CheckArraySpec(
 void CheckHelper::CheckProcEntity(
 const Symbol &symbol, const ProcEntityDetails &details) {
   if (details.isDummy()) {
+if (!symbol.attrs().test(Attr::POINTER) && // C843
+(symbol.attrs().test(Attr::INTENT_IN) ||
+symbol.attrs().test(Attr::INTENT_OUT) ||
+symbol.attrs().test(Attr::INTENT_INOUT))) {
+  messages_.Say("A dummy procedure without the POINTER attribute"
+" may not have an INTENT attribute"_err_en_US);
+}
+
 const Symbol *interface{details.interface().symbol()};
 if (!symbol.attrs().test(Attr::INTRINSIC) &&
 (symbol.attrs().test(Attr::ELEMENTAL) ||

diff  --git a/flang/test/Semantics/assign03.f90 
b/flang/test/Semantics/assign03.f90
index 1435342b1ead..c53bb0ed291a 100644
--- a/flang/test/Semantics/assign03.f90
+++ b/flang/test/Semantics/assign03.f90
@@ -42,7 +42,7 @@ function f()
 
   ! C1030 and 10.2.2.4 - procedure names as target of procedure pointer
   subroutine s4(s_dummy)
-procedure(s), intent(in) :: s_dummy
+procedure(s) :: s_dummy
 procedure(s), pointer :: p, q
 procedure(), pointer :: r
 integer :: i

diff  --git a/flang/test/Semantics/call09.f90 b/flang/test/Semantics/call09.f90
index e7f22e32ed44..36aaa8f4ab46 100644
--- a/flang/test/Semantics/call09.f90
+++ b/flang/test/Semantics/call09.f90
@@ -1,5 +1,8 @@
 ! RUN: %S/test_errors.sh %s %t %f18
 ! Test 15.5.2.9(2,3,5) dummy procedure requirements
+! C843
+!   An entity with the INTENT attribute shall be a dummy data object or a 
+!   dummy procedure pointer.
 
 module m
  contains
@@ -22,6 +25,10 @@ subroutine s02(p)
   subroutine s03(p)
 procedure(realfunc) :: p
   end subroutine
+  subroutine s04(p)
+!ERROR: A dummy procedure without the POINTER attribute may not have an 
INTENT attribute
+procedure(realfunc), intent(in) :: p
+  end subroutine
 
   subroutine selemental1(p)
 procedure(cos) :: p ! ok

diff  --git a/flang/test/Semantics/separate-mp02.f90 
b/flang/test/Semantics/separate-mp02.f90
index 47abc83bff1e..6d620e71118b 100644
--- a/flang/test/Semantics/separate-mp02.f90
+++ b/flang/test/Semantics/separate-mp02.f90
@@ -157,9 +157,9 @@ module subroutine s3() bind(c, name="s3" // suffix)
 module m3
   interface
 module subroutine s1(x, y, z)
-  procedure(real), intent(in) :: x
-  procedure(real), intent(out) :: y
-  procedure(real), intent(out) :: z
+  procedure(real), pointer, intent(in) :: x
+  procedure(real), pointer, intent(out) :: y
+  procedure(real), pointer, intent(out) :: z
 end
 module subroutine s2(x, y)
   procedure(real), pointer :: x
@@ -171,11 +171,11 @@ module subroutine s2(x, y)
 submodule(m3) sm3
 contains
   module subroutine s1(x, y, z)
-procedure(real), intent(in) :: x
+procedure(real), pointer, intent(in) :: x
 !ERROR: The intent of dummy argument 'y' does not match the intent of the 
corresponding argument in the interface body
-procedure(real), intent(inout) :: y
+procedure(real), pointer, intent(inout) :: y
 !ERROR: The intent of dummy argument 'z' does not match the intent of the 
corresponding argument in the interface body
-procedure(real) :: z
+procedure(real), pointer :: z
   end
   module subroutine s2(x, y)
 !ERROR: Dummy argument 'x' has the OPTIONAL attribute; the corresponding 
argument in the interface body does not



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] bebbe64 - [flang] Fix creation of deferred shape arrays by POINTER statement

2021-01-20 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2021-01-20T13:08:11-08:00
New Revision: bebbe64075abf9d9887a8e1ee39c1ecefe970954

URL: 
https://github.com/llvm/llvm-project/commit/bebbe64075abf9d9887a8e1ee39c1ecefe970954
DIFF: 
https://github.com/llvm/llvm-project/commit/bebbe64075abf9d9887a8e1ee39c1ecefe970954.diff

LOG: [flang] Fix creation of deferred shape arrays by POINTER statement

It's possible to  declare deferred shape array using the POINTER
statement, for example:

  POINTER :: var(:)

When analyzing POINTER declarations, we were not capturing the array
specification information, if present.  I fixed this by changing the
"Post" function for "parser::PointerDecl" to check to see if the
declaration contained a "DeferredShapeSpecList".  In such cases, I
analyzed the shape and used to information to declare an "ObjectEntity"
that contains the shape information rather than an "UnknownEntity".

I also added a couple of small tests that fail to compile without these
changes.

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

Added: 


Modified: 
flang/lib/Semantics/resolve-names-utils.cpp
flang/lib/Semantics/resolve-names-utils.h
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/allocate12.f90

Removed: 




diff  --git a/flang/lib/Semantics/resolve-names-utils.cpp 
b/flang/lib/Semantics/resolve-names-utils.cpp
index 83bff78f426a..61cfba046022 100644
--- a/flang/lib/Semantics/resolve-names-utils.cpp
+++ b/flang/lib/Semantics/resolve-names-utils.cpp
@@ -219,6 +219,7 @@ class ArraySpecAnalyzer {
 public:
   ArraySpecAnalyzer(SemanticsContext &context) : context_{context} {}
   ArraySpec Analyze(const parser::ArraySpec &);
+  ArraySpec AnalyzeDeferredShapeSpecList(const parser::DeferredShapeSpecList 
&);
   ArraySpec Analyze(const parser::ComponentArraySpec &);
   ArraySpec Analyze(const parser::CoarraySpec &);
 
@@ -252,6 +253,11 @@ ArraySpec AnalyzeArraySpec(
 SemanticsContext &context, const parser::ComponentArraySpec &arraySpec) {
   return ArraySpecAnalyzer{context}.Analyze(arraySpec);
 }
+ArraySpec AnalyzeDeferredShapeSpecList(SemanticsContext &context,
+const parser::DeferredShapeSpecList &deferredShapeSpecs) {
+  return ArraySpecAnalyzer{context}.AnalyzeDeferredShapeSpecList(
+  deferredShapeSpecs);
+}
 ArraySpec AnalyzeCoarraySpec(
 SemanticsContext &context, const parser::CoarraySpec &coarraySpec) {
   return ArraySpecAnalyzer{context}.Analyze(coarraySpec);
@@ -275,6 +281,12 @@ ArraySpec ArraySpecAnalyzer::Analyze(const 
parser::ArraySpec &x) {
   CHECK(!arraySpec_.empty());
   return arraySpec_;
 }
+ArraySpec ArraySpecAnalyzer::AnalyzeDeferredShapeSpecList(
+const parser::DeferredShapeSpecList &x) {
+  Analyze(x);
+  CHECK(!arraySpec_.empty());
+  return arraySpec_;
+}
 ArraySpec ArraySpecAnalyzer::Analyze(const parser::CoarraySpec &x) {
   std::visit(
   common::visitors{

diff  --git a/flang/lib/Semantics/resolve-names-utils.h 
b/flang/lib/Semantics/resolve-names-utils.h
index 89011ff3b956..ce1673e681b4 100644
--- a/flang/lib/Semantics/resolve-names-utils.h
+++ b/flang/lib/Semantics/resolve-names-utils.h
@@ -100,6 +100,8 @@ class GenericSpecInfo {
 ArraySpec AnalyzeArraySpec(SemanticsContext &, const parser::ArraySpec &);
 ArraySpec AnalyzeArraySpec(
 SemanticsContext &, const parser::ComponentArraySpec &);
+ArraySpec AnalyzeDeferredShapeSpecList(
+SemanticsContext &, const parser::DeferredShapeSpecList &);
 ArraySpec AnalyzeCoarraySpec(
 SemanticsContext &context, const parser::CoarraySpec &);
 

diff  --git a/flang/lib/Semantics/resolve-names.cpp 
b/flang/lib/Semantics/resolve-names.cpp
index 3bc9a85cbf41..d76abbf68a08 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -429,6 +429,7 @@ class ArraySpecVisitor : public virtual BaseVisitor {
 
 protected:
   const ArraySpec &arraySpec();
+  void set_arraySpec(const ArraySpec arraySpec) { arraySpec_ = arraySpec; }
   const ArraySpec &coarraySpec();
   void BeginArraySpec();
   void EndArraySpec();
@@ -3250,8 +3251,18 @@ void DeclarationVisitor::Post(const parser::EntityDecl 
&x) {
 
 void DeclarationVisitor::Post(const parser::PointerDecl &x) {
   const auto &name{std::get(x.t)};
-  Symbol &symbol{DeclareUnknownEntity(name, Attrs{Attr::POINTER})};
-  symbol.ReplaceName(name.source);
+  if (const auto &deferredShapeSpecs{
+  std::get>(x.t)}) {
+CHECK(arraySpec().empty());
+BeginArraySpec();
+set_arraySpec(AnalyzeDeferredShapeSpecList(context(), 
*deferredShapeSpecs));
+Symbol &symbol{DeclareObjectEntity(name, Attrs{Attr::POINTER})};
+symbol.ReplaceName(name.source);
+EndArraySpec();
+  } else {
+Symbol &symbol{DeclareUnknownEntity(name, Attrs{Attr::POINTER})};
+symbol.ReplaceName(name.source);
+  }
 }
 
 bool DeclarationVisitor::Pre(const parser::BindEntity &x) {

diff  --git a/flang/test/Semantics/allocate12.f90 
b/flang/t

[llvm-branch-commits] [flang] 02e174e - [flang] Fix typo in error message

2021-01-22 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2021-01-22T07:28:37-08:00
New Revision: 02e174e8f77f8c03e32e5860492dd9c7dabc6906

URL: 
https://github.com/llvm/llvm-project/commit/02e174e8f77f8c03e32e5860492dd9c7dabc6906
DIFF: 
https://github.com/llvm/llvm-project/commit/02e174e8f77f8c03e32e5860492dd9c7dabc6906.diff

LOG: [flang] Fix typo in error message

The title says it all.

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

Added: 


Modified: 
flang/lib/Semantics/check-call.cpp
flang/test/Semantics/call09.f90

Removed: 




diff  --git a/flang/lib/Semantics/check-call.cpp 
b/flang/lib/Semantics/check-call.cpp
index 1bd0b0ab6f08..996cdf298d85 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -548,7 +548,7 @@ static void CheckProcedureArg(evaluate::ActualArgument &arg,
 messages.Say(
 "Actual procedure argument has an implicit interface "
 "which is not known to be compatible with %s which has an "
-"explcit interface"_err_en_US,
+"explicit interface"_err_en_US,
 dummyName);
 return;
   }

diff  --git a/flang/test/Semantics/call09.f90 b/flang/test/Semantics/call09.f90
index 36aaa8f4ab46..9db5887dc4e7 100644
--- a/flang/test/Semantics/call09.f90
+++ b/flang/test/Semantics/call09.f90
@@ -78,7 +78,7 @@ subroutine test1 ! 15.5.2.9(5)
 call s01(null(intPtr))
 !ERROR: Actual argument associated with procedure dummy argument 'p=' is 
not a procedure
 call s01(B"0101")
-!ERROR: Actual procedure argument has an implicit interface which is not 
known to be compatible with dummy argument 'p=' which has an explcit interface
+!ERROR: Actual procedure argument has an implicit interface which is not 
known to be compatible with dummy argument 'p=' which has an explicit interface
 call s01(extfunc)
 !ERROR: Actual argument associated with procedure pointer dummy argument 
'p=' must be a POINTER unless INTENT(IN)
 call s02(realfunc)
@@ -93,9 +93,9 @@ subroutine test1 ! 15.5.2.9(5)
 call s02(null(p))
 !ERROR: Actual argument associated with procedure pointer dummy argument 
'p=' must be a POINTER unless INTENT(IN)
 call s02(sin)
-!ERROR: Actual procedure argument has an implicit interface which is not 
known to be compatible with dummy argument 'p=' which has an explcit interface
+!ERROR: Actual procedure argument has an implicit interface which is not 
known to be compatible with dummy argument 'p=' which has an explicit interface
 call s02(extfunc)
-!ERROR: Actual procedure argument has an implicit interface which is not 
known to be compatible with dummy argument 'p=' which has an explcit interface
+!ERROR: Actual procedure argument has an implicit interface which is not 
known to be compatible with dummy argument 'p=' which has an explicit interface
 call s03(extfuncPtr)
   end subroutine
 



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] ae0d1d2 - [flang] Fix bogus message on internal subprogram with alternate return

2021-01-08 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2021-01-08T10:14:21-08:00
New Revision: ae0d1d2e5cd3a99da0b2eefc27c8f94b95f03cc6

URL: 
https://github.com/llvm/llvm-project/commit/ae0d1d2e5cd3a99da0b2eefc27c8f94b95f03cc6
DIFF: 
https://github.com/llvm/llvm-project/commit/ae0d1d2e5cd3a99da0b2eefc27c8f94b95f03cc6.diff

LOG: [flang] Fix bogus message on internal subprogram with alternate return

Internal subprograms have explicit interfaces.  If an internal subprogram has
an alternate return, we check its explicit interface.  But we were not
putting the label values of alternate returns into the actual argument.

I fixed this by changing the definition of actual arguments to be able
to contain a common::Label and putting the label for an alternate return
into the actual argument.

I also verified that we were already doing all of the semantic checking
required for alternate returns and removed a "TODO" for this.

I also added the test altreturn06.f90.

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

Added: 
flang/test/Semantics/altreturn06.f90

Modified: 
flang/include/flang/Common/Fortran.h
flang/include/flang/Evaluate/call.h
flang/include/flang/Parser/parse-tree.h
flang/lib/Evaluate/call.cpp
flang/lib/Evaluate/formatting.cpp
flang/lib/Semantics/check-call.cpp
flang/lib/Semantics/expression.cpp

Removed: 




diff  --git a/flang/include/flang/Common/Fortran.h 
b/flang/include/flang/Common/Fortran.h
index 5d5ab324e826..f0b111a3fec7 100644
--- a/flang/include/flang/Common/Fortran.h
+++ b/flang/include/flang/Common/Fortran.h
@@ -67,6 +67,9 @@ enum class RoundingMode : std::uint8_t {
   TiesAwayFromZero, // ROUND=COMPATIBLE, RC - ties round away from zero
 };
 
+// Fortran label. Must be in [1..9].
+using Label = std::uint64_t;
+
 // Fortran arrays may have up to 15 dimensions (See Fortran 2018 section 
5.4.6).
 static constexpr int maxRank{15};
 } // namespace Fortran::common

diff  --git a/flang/include/flang/Evaluate/call.h 
b/flang/include/flang/Evaluate/call.h
index 71e061054928..0e78839b2ccc 100644
--- a/flang/include/flang/Evaluate/call.h
+++ b/flang/include/flang/Evaluate/call.h
@@ -13,6 +13,7 @@
 #include "constant.h"
 #include "formatting.h"
 #include "type.h"
+#include "flang/Common/Fortran.h"
 #include "flang/Common/indirection.h"
 #include "flang/Common/reference.h"
 #include "flang/Parser/char-block.h"
@@ -73,6 +74,7 @@ class ActualArgument {
   explicit ActualArgument(Expr &&);
   explicit ActualArgument(common::CopyableIndirection> &&);
   explicit ActualArgument(AssumedType);
+  explicit ActualArgument(common::Label);
   ~ActualArgument();
   ActualArgument &operator=(Expr &&);
 
@@ -101,6 +103,8 @@ class ActualArgument {
 }
   }
 
+  common::Label GetLabel() const { return std::get(u_); }
+
   std::optional GetType() const;
   int Rank() const;
   bool operator==(const ActualArgument &) const;
@@ -108,8 +112,9 @@ class ActualArgument {
 
   std::optional keyword() const { return keyword_; }
   void set_keyword(parser::CharBlock x) { keyword_ = x; }
-  bool isAlternateReturn() const { return isAlternateReturn_; }
-  void set_isAlternateReturn() { isAlternateReturn_ = true; }
+  bool isAlternateReturn() const {
+return std::holds_alternative(u_);
+  }
   bool isPassedObject() const { return isPassedObject_; }
   void set_isPassedObject(bool yes = true) { isPassedObject_ = yes; }
 
@@ -131,9 +136,10 @@ class ActualArgument {
   // e.g. between X and (X).  The parser attempts to parse each argument
   // first as a variable, then as an expression, and the distinction appears
   // in the parse tree.
-  std::variant>, AssumedType> u_;
+  std::variant>, AssumedType,
+  common::Label>
+  u_;
   std::optional keyword_;
-  bool isAlternateReturn_{false}; // whether expr is a "*label" number
   bool isPassedObject_{false};
   common::Intent dummyIntent_{common::Intent::Default};
 };

diff  --git a/flang/include/flang/Parser/parse-tree.h 
b/flang/include/flang/Parser/parse-tree.h
index 119a92bee211..7a7b2a184004 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -333,7 +333,7 @@ using ScalarDefaultCharExpr = Scalar;
 using ScalarDefaultCharConstantExpr = Scalar>;
 
 // R611 label -> digit [digit]...
-using Label = std::uint64_t; // validated later, must be in [1..9]
+using Label = common::Label; // validated later, must be in [1..9]
 
 // A wrapper for xzy-stmt productions that are statements, so that
 // source provenances and labels have a uniform representation.

diff  --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp
index b4cf0dc3af3a..3fe56ab4874b 100644
--- a/flang/lib/Evaluate/call.cpp
+++ b/flang/lib/Evaluate/call.cpp
@@ -7,6 +7,7 @@
 
//===--===//
 
 #include "flang/Evaluate/call.h"
+#include "flang/Common/Fortran.h"
 #include "fl

[llvm-branch-commits] [flang] 70a0964 - [Docs] Update the public build documentation

2022-08-02 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2022-08-02T19:13:01-07:00
New Revision: 70a09642b3eea08b60d496480d198cd06c770f39

URL: 
https://github.com/llvm/llvm-project/commit/70a09642b3eea08b60d496480d198cd06c770f39
DIFF: 
https://github.com/llvm/llvm-project/commit/70a09642b3eea08b60d496480d198cd06c770f39.diff

LOG: [Docs] Update the public build documentation

Now it matches our internal documentation as much as possible.

Added: 


Modified: 
flang/README.md

Removed: 




diff  --git a/flang/README.md b/flang/README.md
index d593ac4371d3..831a373ba170 100644
--- a/flang/README.md
+++ b/flang/README.md
@@ -40,46 +40,75 @@ If you are interested in writing new documentation, follow
 There are two ways to build flang. The first method is to build it at the same
 time that you build all of the projects on which it depends. This is called
 building in tree. The second method is to first do an in tree build to create
-all of the projects on which flang depends, and then only build the flang code
-itself. This is called building standalone. Building standalone has the
-advantage of being smaller and faster. Once you create the base build and base
-install areas, you can create multiple standalone builds using them.
+all of the projects on which flang depends.  Then, after creating this base
+build, only build the flang code itself. This is called building standalone.
+Building standalone has the advantage of being smaller and faster. Once you
+create the base build and base install areas, you can create multiple
+standalone builds using them.
 
 Note that instructions for building LLVM can be found at
 https://llvm.org/docs/GettingStarted.html.
 
+All of the example below use GCC as the C/C++ compilers and ninja as the build
+tool.
+
 ### Building flang in tree
 Building flang in tree means building flang along with all of the projects on
-which it depends.  These projects include mlir, clang, flang, and compiler-rt.
-Note that compiler-rt is only needed to access libraries that support 16 bit
-floating point numbers.  It's not needed to run the automated tests.
+which it depends.  These projects include mlir, clang, flang, openmp, and
+compiler-rt.  Note that compiler-rt is only needed to access libraries that
+support 16 bit floating point numbers.  It's not needed to run the automated
+tests.  You can use several 
diff erent C++ compilers for most of the build,
+includig GNU and clang.  But building compiler-rt requres using the clang
+compiler built in the initial part of the build.
+
+I use the following directory structure.  I create a root directory for the
+cloned and built files.  Under that root directory, I clone the source code
+into a directory called llvm-project.  In the course of the build, I also
+create subdirectories under the root directory called build (holds most of
+the built files), install (holds the installed files, and compiler-rt (holds
+the result of building compiler-rt).
 
 Here's a complete set of commands to clone all of the necessary source and do
 the build.
 
-First clone the source:
+First, create the root directory and `cd` into it.
+```bash
+mkdir root
+cd root
+
+Now clone the source:
 ```bash
-git clone https://github.com/llvm/llvm-project.git my-project
+git clone https://github.com/llvm/llvm-project.git
 ```
 Once the clone is complete, execute the following commands:
 ```bash
-cd my-project
-
 rm -rf build
 mkdir -p build
+rm -rf install
+mkdir -p install
+ROOTDIR=`pwd`
+INSTALLDIR=ROOTDIR/install
 
 cd build
 
+CC=`which gcc` \
+CXX=`which g++` \
 cmake \
   -G Ninja \
-  ../llvm \
+  ../llvm-project/llvm \
   -DCMAKE_BUILD_TYPE=Release \
-  -DFLANG_ENABLE_WERROR=On \
+  -DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
+  -DCMAKE_CXX_STANDARD=17 \
+  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
+  -DCMAKE_CXX_LINK_FLAGS="-Wl,-rpath,$LD_LIBRARY_PATH" \
+  -DFLANG_ENABLE_WERROR=ON \
+  -DLLVM_ENABLE_ZLIB=OFF \
+  -DLLVM_INSTALL_UTILS=ON \
   -DLLVM_ENABLE_ASSERTIONS=ON \
+  -DLLVM_ENABLE_TERMINFO=OFF \
   -DLLVM_TARGETS_TO_BUILD=host \
-  -DCMAKE_INSTALL_PREFIX=$INSTALLDIR
   -DLLVM_LIT_ARGS=-v \
-  -DLLVM_ENABLE_PROJECTS="clang;mlir;flang" \
+  -DLLVM_ENABLE_PROJECTS="clang;mlir;flang;openmp" \
   -DLLVM_ENABLE_RUNTIMES="compiler-rt"
 
 ninja
@@ -91,6 +120,39 @@ directory:
 ninja check-flang
 ```
 
+To create the installed files:
+```bash
+ninja install
+```
+
+To build compiler-rt:
+```bash
+cd $ROOTDIR
+rm -rf compiler-rt
+mkdir compiler-rt
+cd compiler-rt
+CC=`which gcc` \
+CXX=`which g++` \
+cmake \
+  -G Ninja \
+  ../llvm-project/compiler-rt \
+  -DCMAKE_BUILD_TYPE=Release \
+  -DCMAKE_INSTALL_PREFIX=$INSTALLDIR \
+  -DCMAKE_CXX_STANDARD=11 \
+  -DCMAKE_C_CFLAGS=-mlong-double-128 \
+  -DCMAKE_CXX_CFLAGS=-mlong-double-128 \
+  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
+  -DCOMPILER_RT_BUILD_ORC=OFF \
+  -DCOMPILER_RT_BUILD_XRAY=OFF \
+  -DCOMPILER_RT_BUILD_MEMPROF=OFF \
+  -DCOMPILER_RT_BUILD_LIBFUZZER=OFF \

[llvm-branch-commits] [flang] 4e90cad - [flang] Handle undeclared names in EQUIVALENCE statements

2020-12-16 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2020-12-16T11:04:27-08:00
New Revision: 4e90cad6a6b5504f11b7876e26e80c2a079e04b0

URL: 
https://github.com/llvm/llvm-project/commit/4e90cad6a6b5504f11b7876e26e80c2a079e04b0
DIFF: 
https://github.com/llvm/llvm-project/commit/4e90cad6a6b5504f11b7876e26e80c2a079e04b0.diff

LOG: [flang] Handle undeclared names in EQUIVALENCE statements

Names in EQUIVALENCE statements are only allowed to indicate local
objects as per 19.5.1.4, paragraph 2, item (10).  Thus, a name appearing
in an EQUIVALENCE statement with no corresponding declaration in the
same scope is an implicit declaration of the name.  If that scope
contains an IMPLICIT NONE, it's an error.

I implemented this by adding a state variable to ScopeHandler to
indicate if we're resolving the names in an EQUIVALENCE statement and
then checked this state when resolving names.  I also added a test to
the existing tests for EQUIVALENCE statements.

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

Added: 


Modified: 
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/equivalence01.f90

Removed: 




diff  --git a/flang/lib/Semantics/resolve-names.cpp 
b/flang/lib/Semantics/resolve-names.cpp
index 1288b11a7727..495d7d0f8584 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -597,6 +597,7 @@ class ScopeHandler : public ImplicitRulesVisitor {
 
   bool inExecutionPart_{false};
   bool inSpecificationPart_{false};
+  bool inEquivalenceStmt_{false};
   std::set specPartForwardRefs_;
 
 private:
@@ -2021,7 +2022,11 @@ Symbol *ScopeHandler::FindSymbol(const Scope &scope, 
const parser::Name &name) {
 }
 return FindSymbol(scope.parent(), name);
   } else {
-return Resolve(name, scope.FindSymbol(name.source));
+// In EQUIVALENCE statements only resolve names in the local scope, see
+// 19.5.1.4, paragraph 2, item (10)
+return Resolve(name,
+inEquivalenceStmt_ ? FindInScope(scope, name)
+   : scope.FindSymbol(name.source));
   }
 }
 
@@ -4347,15 +4352,17 @@ void DeclarationVisitor::Post(const 
parser::CommonBlockObject &x) {
 
 bool DeclarationVisitor::Pre(const parser::EquivalenceStmt &x) {
   // save equivalence sets to be processed after specification part
-  CheckNotInBlock("EQUIVALENCE"); // C1107
-  for (const std::list &set : x.v) {
-equivalenceSets_.push_back(&set);
+  if (CheckNotInBlock("EQUIVALENCE")) { // C1107
+for (const std::list &set : x.v) {
+  equivalenceSets_.push_back(&set);
+}
   }
   return false; // don't implicitly declare names yet
 }
 
 void DeclarationVisitor::CheckEquivalenceSets() {
   EquivalenceSets equivSets{context()};
+  inEquivalenceStmt_ = true;
   for (const auto *set : equivalenceSets_) {
 const auto &source{set->front().v.value().source};
 if (set->size() <= 1) { // R871
@@ -4372,6 +4379,7 @@ void DeclarationVisitor::CheckEquivalenceSets() {
 }
 equivSets.FinishSet(source);
   }
+  inEquivalenceStmt_ = false;
   for (auto &set : equivSets.sets()) {
 if (!set.empty()) {
   currScope().add_equivalenceSet(std::move(set));

diff  --git a/flang/test/Semantics/equivalence01.f90 
b/flang/test/Semantics/equivalence01.f90
index 234c42744ee9..e75d954001d7 100644
--- a/flang/test/Semantics/equivalence01.f90
+++ b/flang/test/Semantics/equivalence01.f90
@@ -197,3 +197,20 @@ end subroutine interfaceSub
   end interface
 
 end subroutine s16
+
+module m17
+  real :: dupName
+contains
+  real function f17a()
+implicit none
+real :: y
+!ERROR: No explicit type declared for 'dupname'
+equivalence (dupName, y) 
+  end function f17a
+  real function f17b()
+real :: y
+! The following implicitly declares an object called "dupName" local to 
+! the function f17b().  OK since there's no "implicit none
+equivalence (dupName, y) 
+  end function f17b
+end module m17



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] f24c642 - [flang] Fix bogus message on interface procedure argument names

2020-12-03 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2020-12-03T12:08:55-08:00
New Revision: f24c642178a5a31aa1c44585537c08fdfc3fdfd5

URL: 
https://github.com/llvm/llvm-project/commit/f24c642178a5a31aa1c44585537c08fdfc3fdfd5
DIFF: 
https://github.com/llvm/llvm-project/commit/f24c642178a5a31aa1c44585537c08fdfc3fdfd5.diff

LOG: [flang] Fix bogus message on interface procedure argument names

We were keeping the state of parsed equivalence sets in the class
DeclarationVisitor.  A problem happened when  analyzing the the specification
part of a declaration that contained an EQUIVALENCE statement followed by an
interface block.  The same DeclarationVisitor object that was created for the
outer declaration was being used to analyze the specification part
of a procedure body in the interface block.  When analyzing the specification
part of the procedure in the interface block, the names in the outer
declaration's EQUIVALENCE statement were erroneously compared with the names in
the arguments of the interface procedure.  This resulted in a bogus error
message.

I fixed this by not checking equivalence sets when we're in an interface
block.  I also added a test that will produce an error message without
this change.

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

Added: 


Modified: 
flang/lib/Semantics/resolve-names.cpp
flang/test/Semantics/equivalence01.f90

Removed: 




diff  --git a/flang/lib/Semantics/resolve-names.cpp 
b/flang/lib/Semantics/resolve-names.cpp
index ad5fc734c776..78ce019ec4b8 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6194,7 +6194,11 @@ void ResolveNamesVisitor::FinishSpecificationPart(
   // TODO: what about instantiations in BLOCK?
   CheckSaveStmts();
   CheckCommonBlocks();
-  CheckEquivalenceSets();
+  if (!inInterfaceBlock()) {
+// TODO: warn for the case where the EQUIVALENCE statement is in a
+// procedure declaration in an interface block
+CheckEquivalenceSets();
+  }
 }
 
 // Analyze the bodies of statement functions now that the symbols in this

diff  --git a/flang/test/Semantics/equivalence01.f90 
b/flang/test/Semantics/equivalence01.f90
index 404be570d657..234c42744ee9 100644
--- a/flang/test/Semantics/equivalence01.f90
+++ b/flang/test/Semantics/equivalence01.f90
@@ -1,4 +1,4 @@
-! RUN: %S/test_errors.sh %s %t %f18
+!RUN: %S/test_errors.sh %s %t %f18
 subroutine s1
   integer i, j
   real r(2)
@@ -182,3 +182,18 @@ module s15
   !ERROR: 'a(3_8)' and 'a(1_8)' cannot have the same first storage unit
   equivalence(b(2),a(1))
 end module
+
+subroutine s16
+
+  integer var, dupName
+
+  ! There should be no error message for the following
+  equivalence (dupName, var)
+
+  interface
+subroutine interfaceSub (dupName)
+  integer dupName
+end subroutine interfaceSub
+  end interface
+
+end subroutine s16



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [flang] 9168a0f - [flang] Fix bogus message on index-names in the presence of associated entities

2020-12-10 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2020-12-10T07:36:41-08:00
New Revision: 9168a0f515c908dc3c3df822f17d489ec8a0caf2

URL: 
https://github.com/llvm/llvm-project/commit/9168a0f515c908dc3c3df822f17d489ec8a0caf2
DIFF: 
https://github.com/llvm/llvm-project/commit/9168a0f515c908dc3c3df822f17d489ec8a0caf2.diff

LOG: [flang] Fix bogus message on index-names in the presence of associated 
entities

The semantic analysis of index-names of FORALL statements looks up symbols with
the same name as the index-name.  This is needed to exclude symbols that are
not objects.  But if the symbol found is host-, use-, or construct-associated
with another entity, the check fails.

I fixed this by getting the root symbol of the symbol found and doing the check
on the root symbol.  This required creating a non-const version of
"GetAssociationRoot()".

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

Added: 
flang/test/Semantics/resolve99.f90

Modified: 
flang/include/flang/Evaluate/tools.h
flang/lib/Evaluate/tools.cpp
flang/lib/Semantics/resolve-names.cpp

Removed: 




diff  --git a/flang/include/flang/Evaluate/tools.h 
b/flang/include/flang/Evaluate/tools.h
index e7305d47ed10..0501023116d9 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -919,6 +919,7 @@ bool IsLenTypeParameter(const Symbol &);
 
 // Follow use, host, and construct assocations to a variable, if any.
 const Symbol *GetAssociationRoot(const Symbol &);
+Symbol *GetAssociationRoot(Symbol &);
 const Symbol *FindCommonBlockContaining(const Symbol &);
 int CountLenParameters(const DerivedTypeSpec &);
 int CountNonConstantLenParameters(const DerivedTypeSpec &);

diff  --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index 1ae0fce193b1..452ff0f35841 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -931,6 +931,11 @@ const Symbol *GetAssociationRoot(const Symbol &symbol) {
   return details ? GetAssociatedVariable(*details) : &ultimate;
 }
 
+Symbol *GetAssociationRoot(Symbol &symbol) {
+  return const_cast(
+  GetAssociationRoot(const_cast(symbol)));
+}
+
 bool IsVariableName(const Symbol &symbol) {
   const Symbol *root{GetAssociationRoot(symbol)};
   return root && root->has() && !IsNamedConstant(*root);

diff  --git a/flang/lib/Semantics/resolve-names.cpp 
b/flang/lib/Semantics/resolve-names.cpp
index 0d2b8813c7bb..b0e0b0b80ebf 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -4927,17 +4927,21 @@ void ConstructVisitor::ResolveIndexName(
 // type came from explicit type-spec
   } else if (!prev) {
 ApplyImplicitRules(symbol);
-  } else if (!prev->has() && !prev->has()) 
{
-Say2(name, "Index name '%s' conflicts with existing identifier"_err_en_US,
-*prev, "Previous declaration of '%s'"_en_US);
-return;
-  } else {
-if (const auto *type{prev->GetType()}) {
-  symbol.SetType(*type);
-}
-if (prev->IsObjectArray()) {
-  SayWithDecl(name, *prev, "Index variable '%s' is not scalar"_err_en_US);
+  } else if (const Symbol * prevRoot{GetAssociationRoot(*prev)}) {
+// prev could be host- use- or construct-associated with another symbol
+if (!prevRoot->has() &&
+!prevRoot->has()) {
+  Say2(name, "Index name '%s' conflicts with existing 
identifier"_err_en_US,
+  *prev, "Previous declaration of '%s'"_en_US);
   return;
+} else {
+  if (const auto *type{prevRoot->GetType()}) {
+symbol.SetType(*type);
+  }
+  if (prevRoot->IsObjectArray()) {
+SayWithDecl(name, *prev, "Index variable '%s' is not 
scalar"_err_en_US);
+return;
+  }
 }
   }
   EvaluateExpr(parser::Scalar{parser::Integer{common::Clone(name)}});

diff  --git a/flang/test/Semantics/resolve99.f90 
b/flang/test/Semantics/resolve99.f90
new file mode 100644
index ..a1c8c10af4ee
--- /dev/null
+++ b/flang/test/Semantics/resolve99.f90
@@ -0,0 +1,51 @@
+! RUN: %S/test_errors.sh %s %t %f18
+
+! Tests for the index-name of a FORALL statement
+
+module m1
+  integer modVar
+end module m1
+
+program indexName
+  common /iCommonName/ x
+  type ::  typeName
+  end type
+  iGlobalVar = 216
+
+contains
+  subroutine hostAssoc()
+integer, dimension(4) :: table
+
+  ! iGlobalVar is host associated with the global variable
+iGlobalVar = 1
+FORALL (iGlobalVar=1:4) table(iGlobalVar) = 343
+  end subroutine hostAssoc
+
+  subroutine useAssoc()
+use m1
+integer, dimension(4) :: tab
+  ! modVar is use associated with the module variable
+FORALL (modVar=1:4) tab(modVar) = 343
+  end subroutine useAssoc
+
+  subroutine constructAssoc()
+integer, dimension(4) :: table
+integer :: localVar
+associate (assocVar => localVar)
+  ! assocVar is construct associated with localVar
+  FORALL (assocVar=1:4) table(assocVar) = 343
+en

[llvm-branch-commits] [flang] 84c09ab - [flang] Removed an absolute path from the "flang" script

2020-12-11 Thread Peter Steinfeld via llvm-branch-commits

Author: Peter Steinfeld
Date: 2020-12-11T14:01:59-08:00
New Revision: 84c09ab44599ece409e4e19761288ddf796fceec

URL: 
https://github.com/llvm/llvm-project/commit/84c09ab44599ece409e4e19761288ddf796fceec
DIFF: 
https://github.com/llvm/llvm-project/commit/84c09ab44599ece409e4e19761288ddf796fceec.diff

LOG: [flang] Removed an absolute path from the "flang" script

The "flang" script that gets put into "install/bin" had an absolute path
in it.  This precuded moving the install directory to a new location.

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

Added: 


Modified: 
flang/tools/f18/flang.sh.in

Removed: 




diff  --git a/flang/tools/f18/flang.sh.in b/flang/tools/f18/flang.sh.in
index 7f0d1335aec4..295d93abbeb6 100644
--- a/flang/tools/f18/flang.sh.in
+++ b/flang/tools/f18/flang.sh.in
@@ -26,4 +26,4 @@ function abspath() {
 
 wd=`abspath $(dirname "$0")/..`
 
-${wd}/bin/f18 -module-suffix .f18.mod -intrinsic-module-directory 
@FLANG_INTRINSIC_MODULES_DIR@ $*
+${wd}/bin/f18 -module-suffix .f18.mod -intrinsic-module-directory 
${wd}/include/flang $*



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits