[llvm-branch-commits] [flang] 3de92ca - [flang] Add tests for procedure arguments with implicit interfaces
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
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
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
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
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
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
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
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
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
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