[llvm-branch-commits] [flang][runtime] Added custom visitor for IoStatementState variants. (PR #85179)

2024-03-14 Thread Peter Klausler via llvm-branch-commits

https://github.com/klausler requested changes to this pull request.

It would be better to have the types that are available on the device declare 
themselves so in their declarations via a member or (better) inherited trait.

The big variant union in `IoStatementState` could omit the host-only options 
when compiled for the device.

https://github.com/llvm/llvm-project/pull/85179
___
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] [NFC][flang] Reorder const and RT_API_ATTRS. (PR #85180)

2024-03-14 Thread Peter Klausler via llvm-branch-commits

https://github.com/klausler approved this pull request.


https://github.com/llvm/llvm-project/pull/85180
___
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][runtime] Added self-printing for InternalUnit. (PR #85181)

2024-03-14 Thread Peter Klausler via llvm-branch-commits


@@ -48,6 +55,10 @@ template  class InternalDescriptorUnit : 
public ConnectionState {
   void BlankFillOutputRecord();
 
   StaticDescriptor staticDescriptor_;
+  RT_OFFLOAD_VAR_GROUP_BEGIN
+  static constexpr std::size_t ownBufferSizeInBytes{1024};
+  RT_OFFLOAD_VAR_GROUP_END

klausler wrote:

Should this be one line lower?

https://github.com/llvm/llvm-project/pull/85181
___
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][runtime] Added self-printing for InternalUnit. (PR #85181)

2024-03-14 Thread Peter Klausler via llvm-branch-commits

https://github.com/klausler edited 
https://github.com/llvm/llvm-project/pull/85181
___
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][runtime] Added self-printing for InternalUnit. (PR #85181)

2024-03-14 Thread Peter Klausler via llvm-branch-commits

https://github.com/klausler commented:

If you want to support child I/O (user-defined derived type I/O) on the device, 
this approach of adding special behavior to the internal units won't work -- 
child I/O is embedded in external units.  It might be clearer to support this 
device output path by extending the external unit class instead -- its 
`FileFrame` template in buffer.h can be instantiated on a `Store` that has no 
`Read` and only a rudimentary `Write`.

https://github.com/llvm/llvm-project/pull/85181
___
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][runtime] Added self-printing for InternalUnit. (PR #85181)

2024-03-14 Thread Peter Klausler via llvm-branch-commits


@@ -119,6 +120,9 @@ template  void 
InternalIoStatementState::BackspaceRecord() {
 }
 
 template  int InternalIoStatementState::EndIoStatement() {
+  if constexpr (DIR == Direction::Output) {

klausler wrote:

If it is possible for the buffer flush to raise an error that the program can 
catch via `ERR=` or `IOSTAT=`, do this in `CompleteOperation` instead.

https://github.com/llvm/llvm-project/pull/85181
___
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][runtime] Added self-printing for InternalUnit. (PR #85181)

2024-03-14 Thread Peter Klausler via llvm-branch-commits


@@ -41,6 +52,26 @@ InternalDescriptorUnit::InternalDescriptorUnit(
   endfileRecordNumber = d.Elements() + 1;
 }
 
+template  void InternalDescriptorUnit::EndIoStatement() {
+  if constexpr (DIR == Direction::Output) {
+if (usesOwnBuffer) {
+  // Null terminate the buffer that contains just a single record.
+  Terminator terminator{__FILE__, __LINE__};
+  RUNTIME_CHECK(terminator,
+  furthestPositionInRecord <
+  static_cast(ownBufferSizeInBytes));
+  *reinterpret_cast(CurrentRecord() + furthestPositionInRecord) =
+  '\0';
+
+  // Print the buffer and deallocate memory.
+  // FIXME: this output does not match the regular unit 5 output.

klausler wrote:

The default output unit is 6.

https://github.com/llvm/llvm-project/pull/85181
___
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][runtime] Added self-printing for InternalUnit. (PR #85181)

2024-03-14 Thread Peter Klausler via llvm-branch-commits


@@ -41,6 +52,26 @@ InternalDescriptorUnit::InternalDescriptorUnit(
   endfileRecordNumber = d.Elements() + 1;
 }
 
+template  void InternalDescriptorUnit::EndIoStatement() {
+  if constexpr (DIR == Direction::Output) {
+if (usesOwnBuffer) {
+  // Null terminate the buffer that contains just a single record.
+  Terminator terminator{__FILE__, __LINE__};
+  RUNTIME_CHECK(terminator,
+  furthestPositionInRecord <
+  static_cast(ownBufferSizeInBytes));
+  *reinterpret_cast(CurrentRecord() + furthestPositionInRecord) =
+  '\0';
+
+  // Print the buffer and deallocate memory.
+  // FIXME: this output does not match the regular unit 5 output.
+  std::printf("%s\n", descriptor().OffsetElement());
+  FreeMemory(descriptor().OffsetElement());

klausler wrote:

Why not `descriptor().Deallocate()` (and `descriptor().Allocate()`)?

https://github.com/llvm/llvm-project/pull/85181
___
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][runtime] Added self-printing for InternalUnit. (PR #85181)

2024-03-14 Thread Peter Klausler via llvm-branch-commits


@@ -48,6 +55,10 @@ template  class InternalDescriptorUnit : 
public ConnectionState {
   void BlankFillOutputRecord();
 
   StaticDescriptor staticDescriptor_;
+  RT_OFFLOAD_VAR_GROUP_BEGIN
+  static constexpr std::size_t ownBufferSizeInBytes{1024};
+  RT_OFFLOAD_VAR_GROUP_END
+  bool usesOwnBuffer{false};

klausler wrote:

The naming convention in the runtime (and front-end) has an underscore at the 
end of the name of a private `class` data member.

https://github.com/llvm/llvm-project/pull/85181
___
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][runtime] Enable PRINT of integer32 for device. (PR #85182)

2024-03-14 Thread Peter Klausler via llvm-branch-commits

https://github.com/klausler edited 
https://github.com/llvm/llvm-project/pull/85182
___
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][runtime] Enable PRINT of integer32 for device. (PR #85182)

2024-03-14 Thread Peter Klausler via llvm-branch-commits

https://github.com/klausler approved this pull request.


https://github.com/llvm/llvm-project/pull/85182
___
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][runtime] Enable PRINT of integer32 for device. (PR #85182)

2024-03-14 Thread Peter Klausler via llvm-branch-commits


@@ -368,7 +368,12 @@ static bool FormattedDerivedTypeIO(IoStatementState &io,
++j, descriptor.IncrementSubscripts(subscripts)) {
 Fortran::common::optional result;
 if (special) {
+#if !defined(RT_DEVICE_COMPILATION)
   result = DefinedFormattedIo(io, descriptor, *type, *special, subscripts);
+#else
+  io.GetIoErrorHandler().Crash("not implemented yet: defined formatted 
IO");

klausler wrote:

"... from the device"

https://github.com/llvm/llvm-project/pull/85182
___
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] [flang][openacc] Carry device dependent info for acc routine in the module file (PR #77804)

2024-01-11 Thread Peter Klausler via llvm-branch-commits
Valentin Clement =?utf-8?b?KOODkOODrOODsw==?=
Message-ID:
In-Reply-To: 


https://github.com/klausler approved this pull request.


https://github.com/llvm/llvm-project/pull/77804
___
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] a50bb84 - [flang] Fix classification of shape inquiries in specification exprs

2021-01-13 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-13T10:05:14-08:00
New Revision: a50bb84ec0c2d47a2a7403ad29842ca48cd6b828

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

LOG: [flang] Fix classification of shape inquiries in specification exprs

In some contexts, including the motivating case of determining whether
the expressions that define the shape of a variable are "constant expressions"
in the sense of the Fortran standard, expression rewriting via Fold()
is not necessary, and should not be required.  The inquiry intrinsics LBOUND,
UBOUND, and SIZE work correctly now in specification expressions and are
classified correctly as being constant expressions (or not).  Getting this right
led to a fair amount of API clean-up as a consequence, including the
folding of shapes and TypeAndShape objects, and new APIs for shapes
that do not fold for those cases where folding isn't needed.  Further,
the symbol-testing predicate APIs in Evaluate/tools.h now all resolve any
associations of their symbols and work transparently on use-, host-, and
construct-association symbols; the tools used to resolve those associations have
been defined and documented more precisely, and their clients adjusted as 
needed.

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

Added: 


Modified: 
flang/include/flang/Evaluate/characteristics.h
flang/include/flang/Evaluate/fold.h
flang/include/flang/Evaluate/shape.h
flang/include/flang/Evaluate/tools.h
flang/include/flang/Evaluate/type.h
flang/include/flang/Semantics/tools.h
flang/lib/Evaluate/characteristics.cpp
flang/lib/Evaluate/check-expression.cpp
flang/lib/Evaluate/fold.cpp
flang/lib/Evaluate/intrinsics.cpp
flang/lib/Evaluate/shape.cpp
flang/lib/Evaluate/tools.cpp
flang/lib/Semantics/check-call.cpp
flang/lib/Semantics/check-declarations.cpp
flang/lib/Semantics/check-do-forall.cpp
flang/lib/Semantics/resolve-names.cpp
flang/lib/Semantics/semantics.cpp
flang/lib/Semantics/tools.cpp
flang/test/Semantics/data04.f90
flang/test/Semantics/resolve44.f90
flang/test/Semantics/shape.f90

Removed: 




diff  --git a/flang/include/flang/Evaluate/characteristics.h 
b/flang/include/flang/Evaluate/characteristics.h
index c7ef66e800a9..6b7b2f5408e4 100644
--- a/flang/include/flang/Evaluate/characteristics.h
+++ b/flang/include/flang/Evaluate/characteristics.h
@@ -81,9 +81,9 @@ class TypeAndShape {
   static std::optional Characterize(
   const semantics::ObjectEntityDetails &, FoldingContext &);
   static std::optional Characterize(
-  const semantics::ProcInterface &);
+  const semantics::ProcInterface &, FoldingContext &);
   static std::optional Characterize(
-  const semantics::DeclTypeSpec &);
+  const semantics::DeclTypeSpec &, FoldingContext &);
   static std::optional Characterize(
   const ActualArgument &, FoldingContext &);
 
@@ -101,15 +101,16 @@ class TypeAndShape {
 if (type->category() == TypeCategory::Character) {
   if (const auto *chExpr{UnwrapExpr>(x)}) {
 if (auto length{chExpr->LEN()}) {
-  result.set_LEN(Fold(context, std::move(*length)));
+  result.set_LEN(std::move(*length));
 }
   }
 }
-return result;
+return std::move(result.Rewrite(context));
   }
 }
 return std::nullopt;
   }
+
   template 
   static std::optional Characterize(
   const std::optional &x, FoldingContext &context) {
@@ -121,9 +122,9 @@ class TypeAndShape {
   }
   template 
   static std::optional Characterize(
-  const A *x, FoldingContext &context) {
-if (x) {
-  return Characterize(*x, context);
+  const A *p, FoldingContext &context) {
+if (p) {
+  return Characterize(*p, context);
 } else {
   return std::nullopt;
 }
@@ -151,14 +152,17 @@ class TypeAndShape {
   std::optional> MeasureSizeInBytes(
   FoldingContext &) const;
 
+  // called by Fold() to rewrite in place
+  TypeAndShape &Rewrite(FoldingContext &);
+
   llvm::raw_ostream &Dump(llvm::raw_ostream &) const;
 
 private:
   static std::optional Characterize(
   const semantics::AssocEntityDetails &, FoldingContext &);
   static std::optional Characterize(
-  const semantics::ProcEntityDetails &);
-  void AcquireShape(const semantics::ObjectEntityDetails &, FoldingContext &);
+  const semantics::ProcEntityDetails &, FoldingContext &);
+  void AcquireShape(const semantics::ObjectEntityDetails &);
   void AcquireLEN();
 
 protected:
@@ -325,6 +329,5 @@ struct Procedure {
 private:
   Procedure() {}
 };
-
 } // namespace Fortran::evaluate::characteristics
 #endif // FORTRAN_EVALUATE_CHARACTERISTICS_H_

diff  --git a/flang/include/flang/Evaluate/fold.h 
b/flang

[llvm-branch-commits] [flang] 166e5c3 - [flang] Do not create HostAssoc symbols in derived type scopes

2021-01-13 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-13T11:01:27-08:00
New Revision: 166e5c335cbe9f8144a7822ca655dc3352ec9e56

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

LOG: [flang] Do not create HostAssoc symbols in derived type scopes

When needed due to a specification expression in a derived type,
the host association symbols should be created in the surrounding
subprogram's scope instead.

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

Added: 


Modified: 
flang/lib/Semantics/resolve-names.cpp

Removed: 




diff  --git a/flang/lib/Semantics/resolve-names.cpp 
b/flang/lib/Semantics/resolve-names.cpp
index cee49175d7f4..d66f561fc3c5 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2050,7 +2050,9 @@ Symbol &ScopeHandler::MakeSymbol(const parser::Name 
&name, Attrs attrs) {
 }
 Symbol &ScopeHandler::MakeHostAssocSymbol(
 const parser::Name &name, const Symbol &hostSymbol) {
-  Symbol &symbol{MakeSymbol(name, HostAssocDetails{hostSymbol})};
+  Symbol &symbol{*NonDerivedTypeScope()
+  .try_emplace(name.source, HostAssocDetails{hostSymbol})
+  .first->second};
   name.symbol = &symbol;
   symbol.attrs() = hostSymbol.attrs(); // TODO: except PRIVATE, PUBLIC?
   symbol.flags() = hostSymbol.flags();



___
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] 4864d9f - [flang] Fix some module file issues exposed by Whizard

2021-01-14 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-14T09:44:50-08:00
New Revision: 4864d9f7e91fdd58a84e4ae576f1ad16f71f9d91

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

LOG: [flang] Fix some module file issues exposed by Whizard

Generic type-bound interfaces for user-defined operators need to be formatted
as "OPERATOR(.op.)", not just ".op."

PRIVATE generics need to be marked as such.

Declaration ordering: when a generic interface shadows a
derived type of the same name, it needs to be emitted to the
module file at the point of definition of the derived type;
otherwise, the derived type's definition may appear after its
first use.

The module symbol for a module read from a module file needs
to be marked as coming from a module file before semantic
processing is performed on the contents of the module so that
any special handling for declarations in module files can be
properly activated.

IMPORT statements were sometimes missing for use-associated
symbols in surrounding scopes; fine-tune NeedImport().

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

Added: 
flang/test/Semantics/modfile37.f90
flang/test/Semantics/modfile38.f90

Modified: 
flang/lib/Semantics/mod-file.cpp
flang/test/Semantics/modfile35.f90

Removed: 




diff  --git a/flang/lib/Semantics/mod-file.cpp 
b/flang/lib/Semantics/mod-file.cpp
index 23733f944d8c..af3267a1c9a0 100644
--- a/flang/lib/Semantics/mod-file.cpp
+++ b/flang/lib/Semantics/mod-file.cpp
@@ -198,6 +198,15 @@ bool ModFileWriter::PutSymbols(const Scope &scope) {
   }
 }
 
+static llvm::raw_ostream &PutGenericName(
+llvm::raw_ostream &os, const Symbol &symbol) {
+  if (IsGenericDefinedOp(symbol)) {
+return os << "operator(" << symbol.name() << ')';
+  } else {
+return os << symbol.name();
+  }
+}
+
 // Emit a symbol to decls_, except for bindings in a derived type (type-bound
 // procedures, type-bound generics, final procedures) which go to typeBindings.
 void ModFileWriter::PutSymbol(
@@ -210,8 +219,8 @@ void ModFileWriter::PutSymbol(
if (symbol.owner().IsDerivedType()) {
  // generic binding
  for (const Symbol &proc : x.specificProcs()) {
-   typeBindings << "generic::" << symbol.name() << "=>"
-<< proc.name() << '\n';
+   PutGenericName(typeBindings << "generic::", symbol)
+   << "=>" << proc.name() << '\n';
  }
} else {
  PutGeneric(symbol);
@@ -392,15 +401,6 @@ static bool IsIntrinsicOp(const Symbol &symbol) {
   }
 }
 
-static llvm::raw_ostream &PutGenericName(
-llvm::raw_ostream &os, const Symbol &symbol) {
-  if (IsGenericDefinedOp(symbol)) {
-return os << "operator(" << symbol.name() << ')';
-  } else {
-return os << symbol.name();
-  }
-}
-
 void ModFileWriter::PutGeneric(const Symbol &symbol) {
   const auto &genericOwner{symbol.owner()};
   auto &details{symbol.get()};
@@ -427,9 +427,11 @@ void ModFileWriter::PutUse(const Symbol &symbol) {
 PutGenericName(uses_ << "=>", use);
   }
   uses_ << '\n';
-  PutUseExtraAttr(Attr::PRIVATE, symbol, use);
   PutUseExtraAttr(Attr::VOLATILE, symbol, use);
   PutUseExtraAttr(Attr::ASYNCHRONOUS, symbol, use);
+  if (symbol.attrs().test(Attr::PRIVATE)) {
+PutGenericName(useExtraAttrs_ << "private::", symbol) << '\n';
+  }
 }
 
 // We have "USE local => use" in this module. If attr was added locally
@@ -442,6 +444,31 @@ void ModFileWriter::PutUseExtraAttr(
   }
 }
 
+// When a generic interface has the same name as a derived type
+// in the same scope, the generic shadows the derived type.
+// If the derived type were declared first, emit the generic
+// interface at the position of derived type's declaration.
+// (ReplaceName() is not used for this purpose because doing so
+// would confusingly position error messages pertaining to the generic
+// interface upon the derived type's declaration.)
+static inline SourceName NameInModuleFile(const Symbol &symbol) {
+  if (const auto *generic{symbol.detailsIf()}) {
+if (const auto *derivedTypeOverload{generic->derivedType()}) {
+  if (derivedTypeOverload->name().begin() < symbol.name().begin()) {
+return derivedTypeOverload->name();
+  }
+}
+  } else if (const auto *use{symbol.detailsIf()}) {
+if (use->symbol().attrs().test(Attr::PRIVATE)) {
+  // Avoid the use in sorting of names created to access private
+  // specific procedures as a result of generic resolution;
+  // they're not in the cooked source.
+  return use->symbol().name();
+}
+  }
+  return symbol.name();
+}
+
 // Collect the symbols of this scope sorted by their original order, not name.
 

[llvm-branch-commits] [flang] 1bd083b - [flang] Create names to allow access to inaccessible specifics

2021-01-15 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-15T16:56:38-08:00
New Revision: 1bd083b5d6d0619f532a7310e72887ea6d2e87eb

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

LOG: [flang] Create names to allow access to inaccessible specifics

When a reference to a generic interface occurs in a specification
expression that must be emitted to a module file, we have a problem
when the generic resolves to a function whose name is inaccessible
due to being PRIVATE or due to a conflict with another use of the
same name in the scope.  In these cases, construct a new name for
the specific procedure and emit a renaming USE to the module file.
Also, relax enforcement of PRIVATE when analyzing module files.

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

Added: 
flang/test/Semantics/modfile39.f90

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

Removed: 




diff  --git a/flang/include/flang/Semantics/expression.h 
b/flang/include/flang/Semantics/expression.h
index e095928656a8..7b252baa6c7d 100644
--- a/flang/include/flang/Semantics/expression.h
+++ b/flang/include/flang/Semantics/expression.h
@@ -363,6 +363,8 @@ class ExpressionAnalyzer {
   const Symbol *ResolveGeneric(const Symbol &, const ActualArguments &,
   const AdjustActuals &, bool mightBeStructureConstructor = false);
   void EmitGenericResolutionError(const Symbol &);
+  const Symbol &AccessSpecific(
+  const Symbol &originalGeneric, const Symbol &specific);
   std::optional GetCalleeAndArguments(const parser::Name &,
   ActualArguments &&, bool isSubroutine = false,
   bool mightBeStructureConstructor = false);

diff  --git a/flang/include/flang/Semantics/semantics.h 
b/flang/include/flang/Semantics/semantics.h
index de3d9aeac144..4f4bfc7fea2d 100644
--- a/flang/include/flang/Semantics/semantics.h
+++ b/flang/include/flang/Semantics/semantics.h
@@ -16,6 +16,7 @@
 #include "flang/Evaluate/intrinsics.h"
 #include "flang/Parser/message.h"
 #include 
+#include 
 #include 
 #include 
 
@@ -170,6 +171,7 @@ class SemanticsContext {
   void ActivateIndexVar(const parser::Name &, IndexVarKind);
   void DeactivateIndexVar(const parser::Name &);
   SymbolVector GetIndexVars(IndexVarKind);
+  SourceName SaveTempName(std::string &&);
   SourceName GetTempName(const Scope &);
 
 private:
@@ -198,7 +200,7 @@ class SemanticsContext {
   };
   std::map activeIndexVars_;
   std::set errorSymbols_;
-  std::vector tempNames_;
+  std::set tempNames_;
 };
 
 class Semantics {

diff  --git a/flang/include/flang/Semantics/tools.h 
b/flang/include/flang/Semantics/tools.h
index 1a0e2845534b..e809b300b3ad 100644
--- a/flang/include/flang/Semantics/tools.h
+++ b/flang/include/flang/Semantics/tools.h
@@ -38,6 +38,7 @@ const Scope &GetProgramUnitContaining(const Scope &);
 const Scope &GetProgramUnitContaining(const Symbol &);
 
 const Scope *FindModuleContaining(const Scope &);
+const Scope *FindModuleFileContaining(const Scope &);
 const Scope *FindPureProcedureContaining(const Scope &);
 const Scope *FindPureProcedureContaining(const Symbol &);
 const Symbol *FindPointerComponent(const Scope &);

diff  --git a/flang/lib/Evaluate/check-expression.cpp 
b/flang/lib/Evaluate/check-expression.cpp
index 45bfde08dfb9..4bedbe8d1d8f 100644
--- a/flang/lib/Evaluate/check-expression.cpp
+++ b/flang/lib/Evaluate/check-expression.cpp
@@ -485,16 +485,17 @@ class CheckSpecificationExprHelper
 
   template  Result operator()(const FunctionRef &x) const {
 if (const auto *symbol{x.proc().GetSymbol()}) {
-  if (!semantics::IsPureProcedure(*symbol)) {
-return "reference to impure function '"s + symbol->name().ToString() +
+  const Symbol &ultimate{symbol->GetUltimate()};
+  if (!semantics::IsPureProcedure(ultimate)) {
+return "reference to impure function '"s + ultimate.name().ToString() +
 "'";
   }
-  if (semantics::IsStmtFunction(*symbol)) {
+  if (semantics::IsStmtFunction(ultimate)) {
 return "reference to statement function '"s +
-symbol->name().ToString() + "'";
+ultimate.name().ToString() + "'";
   }
   if (scope_.IsDerivedType()) { // C750, C754
-return "reference to function '"s + symbol->name().ToString() +
+return "reference to function '"s + ultimate.name().ToString() +
 "' not allowed for derived type components or type parameter"
 " values";
   }

diff  --git a/flang/lib/Semantics/expression.cpp 
b/flang/lib/Semantics/e

[llvm-branch-commits] [flang] 24e8e21 - [flang] Refine WhyNotModifiable()

2021-01-19 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-19T11:44:51-08:00
New Revision: 24e8e21f19f4380e8410a12f9135bfef3c046142

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

LOG: [flang] Refine WhyNotModifiable()

The utility routine WhyNotModifiable() needed to become more
aware of the use of pointers in data-refs; the targets of
pointer components are sometimes modifiable even when the
leftmost ("base") symbol of a data-ref is not.

Added a new unit test for WhyNotModifiable() that uses internal
READ statements (mostly), since I/O semantic checking uses
WhyNotModifiable() for all its definability checking.

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

Added: 
flang/test/Semantics/modifiable01.f90

Modified: 
flang/include/flang/Evaluate/tools.h
flang/lib/Evaluate/tools.cpp
flang/lib/Semantics/check-io.cpp
flang/lib/Semantics/tools.cpp

Removed: 




diff  --git a/flang/include/flang/Evaluate/tools.h 
b/flang/include/flang/Evaluate/tools.h
index 69eab61f25b2..3fe3dc1843ec 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -336,6 +336,9 @@ template  const Symbol *GetFirstSymbol(const A 
&x) {
   }
 }
 
+// GetLastPointerSymbol(A%PTR1%B%PTR2%C) -> PTR2
+const Symbol *GetLastPointerSymbol(const evaluate::DataRef &);
+
 // Creation of conversion expressions can be done to either a known
 // specific intrinsic type with ConvertToType(x) or by converting
 // one arbitrary expression to the type of another with ConvertTo(to, from).

diff  --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp
index b1c01d4f4711..2b04ed8a6550 100644
--- a/flang/lib/Evaluate/tools.cpp
+++ b/flang/lib/Evaluate/tools.cpp
@@ -896,6 +896,31 @@ std::optional 
CheckProcCompatibility(bool isCall,
   return msg;
 }
 
+// GetLastPointerSymbol()
+static const Symbol *GetLastPointerSymbol(const Symbol &symbol) {
+  return IsPointer(GetAssociationRoot(symbol)) ? &symbol : nullptr;
+}
+static const Symbol *GetLastPointerSymbol(const SymbolRef &symbol) {
+  return GetLastPointerSymbol(*symbol);
+}
+static const Symbol *GetLastPointerSymbol(const Component &x) {
+  const Symbol &c{x.GetLastSymbol()};
+  return IsPointer(c) ? &c : GetLastPointerSymbol(x.base());
+}
+static const Symbol *GetLastPointerSymbol(const NamedEntity &x) {
+  const auto *c{x.UnwrapComponent()};
+  return c ? GetLastPointerSymbol(*c) : 
GetLastPointerSymbol(x.GetLastSymbol());
+}
+static const Symbol *GetLastPointerSymbol(const ArrayRef &x) {
+  return GetLastPointerSymbol(x.base());
+}
+static const Symbol *GetLastPointerSymbol(const CoarrayRef &x) {
+  return nullptr;
+}
+const Symbol *GetLastPointerSymbol(const DataRef &x) {
+  return std::visit([](const auto &y) { return GetLastPointerSymbol(y); }, 
x.u);
+}
+
 } // namespace Fortran::evaluate
 
 namespace Fortran::semantics {

diff  --git a/flang/lib/Semantics/check-io.cpp 
b/flang/lib/Semantics/check-io.cpp
index 9095951389f2..de19ed4d6d40 100644
--- a/flang/lib/Semantics/check-io.cpp
+++ b/flang/lib/Semantics/check-io.cpp
@@ -928,9 +928,12 @@ void IoChecker::CheckForDefinableVariable(
 const A &var, const std::string &s) const {
   const Symbol *sym{
   GetFirstName(*parser::Unwrap(var)).symbol};
-  if (WhyNotModifiable(*sym, context_.FindScope(*context_.location( {
-context_.Say(parser::FindSourceLocation(var),
-"%s variable '%s' must be definable"_err_en_US, s, sym->name());
+  if (auto whyNot{
+  WhyNotModifiable(*sym, context_.FindScope(*context_.location()))}) {
+auto at{parser::FindSourceLocation(var)};
+context_
+.Say(at, "%s variable '%s' must be definable"_err_en_US, s, 
sym->name())
+.Attach(at, std::move(*whyNot), sym->name());
   }
 }
 

diff  --git a/flang/lib/Semantics/tools.cpp b/flang/lib/Semantics/tools.cpp
index 1bc008610bf0..f7d3c20de2a0 100644
--- a/flang/lib/Semantics/tools.cpp
+++ b/flang/lib/Semantics/tools.cpp
@@ -776,27 +776,62 @@ bool InProtectedContext(const Symbol &symbol, const Scope 
¤tScope) {
 }
 
 // C1101 and C1158
-std::optional WhyNotModifiable(
-const Symbol &original, const Scope &scope) {
-  const Symbol &symbol{GetAssociationRoot(original)};
+// Modifiability checks on the leftmost symbol ("base object")
+// of a data-ref
+std::optional WhyNotModifiableFirst(
+const Symbol &symbol, const Scope &scope) {
   if (symbol.has()) {
 return "'%s' is construct associated with an expression"_en_US;
-  } else if (InProtectedContext(symbol, scope)) {
-return "'%s' is protected in this scope"_en_US;
   } else if (IsExternalInPureContext(symbol, scope)) {
 return "'%s' is externally visible and referenced in a pure"
" procedure"_en_US;
-  } else if (IsOrContainsEventOrLockComponent(symbol)) {
+  } else if (!I

[llvm-branch-commits] [flang] ff3b51b - [flang] Fix ASSOCIATE statement name resolution

2021-01-20 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-20T11:18:27-08:00
New Revision: ff3b51b0549343b6ef7d718e036116d5b502458c

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

LOG: [flang] Fix ASSOCIATE statement name resolution

F18 Clause 19.4p9 says:

  The associate names of an ASSOCIATE construct have the scope of the
  block.

Clause 11.3.1p1 says the ASSOCIATE statement is not itself in the block:

  R1102 associate-construct is:  associate-stmt block end-associate-stmt

Associate statement associations are currently fully processed from left
to right, incorrectly interposing associating entities earlier in the
list on same-named entities in the host scope.

1  program p
2logical :: a = .false.
3real :: b = 9.73
4associate (b => a, a => b)
5  print*, a, b
6end associate
7print*, a, b
8  end

Associating names 'a' and 'b' at line 4 in this code are now both
aliased to logical host entity 'a' at line 2.  This happens because the
reference to 'b' in the second association incorrectly resolves 'b' to
the entity in line 4 (already associated to 'a' at line 2), rather than
the 'b' at line 3.  With bridge code to process these associations,
f18 output is:

 F F
 F 9.73

It should be:

 9.73 F
 F 9.73

To fix this, names in right-hand side selector variables/expressions
must all be resolved before any left-hand side entities are resolved.
This is done by maintaining a stack of lists of associations, rather
than a stack of associations.  Each ASSOCIATE statement's list of
assocations is then visited once for right-hand side processing, and
once for left-hand side processing.

Note that other construct associations do not have this problem.
SELECT RANK and SELECT TYPE each have a single assocation, not a list.
Constraint C1113 prohibits the right-hand side of a CHANGE TEAM
association from referencing any left-hand side entity.

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

Added: 
flang/test/Semantics/resolve100.f90

Modified: 
flang/lib/Semantics/resolve-names.cpp

Removed: 




diff  --git a/flang/lib/Semantics/resolve-names.cpp 
b/flang/lib/Semantics/resolve-names.cpp
index 5d9ee35b79b3..3bc9a85cbf41 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1010,9 +1010,9 @@ class ConstructVisitor : public virtual 
DeclarationVisitor {
   bool Pre(const parser::BlockStmt &);
   bool Pre(const parser::EndBlockStmt &);
   void Post(const parser::Selector &);
-  bool Pre(const parser::AssociateStmt &);
+  void Post(const parser::AssociateStmt &);
   void Post(const parser::EndAssociateStmt &);
-  void Post(const parser::Association &);
+  bool Pre(const parser::Association &);
   void Post(const parser::SelectTypeStmt &);
   void Post(const parser::SelectRankStmt &);
   bool Pre(const parser::SelectTypeConstruct &);
@@ -1081,6 +1081,7 @@ class ConstructVisitor : public virtual 
DeclarationVisitor {
 Selector selector;
   };
   std::vector associationStack_;
+  Association *currentAssociation_{nullptr};
 
   template  bool CheckDef(const T &t) {
 return CheckDef(std::get>(t));
@@ -1098,9 +1099,10 @@ class ConstructVisitor : public virtual 
DeclarationVisitor {
   void SetAttrsFromAssociation(Symbol &);
   Selector ResolveSelector(const parser::Selector &);
   void ResolveIndexName(const parser::ConcurrentControl &control);
+  void SetCurrentAssociation(std::size_t n);
   Association &GetCurrentAssociation();
   void PushAssociation();
-  void PopAssociation();
+  void PopAssociation(std::size_t count = 1);
 };
 
 // Create scopes for OpenACC constructs
@@ -5153,29 +5155,33 @@ void ConstructVisitor::Post(const parser::Selector &x) {
   GetCurrentAssociation().selector = ResolveSelector(x);
 }
 
-bool ConstructVisitor::Pre(const parser::AssociateStmt &x) {
+void ConstructVisitor::Post(const parser::AssociateStmt &x) {
   CheckDef(x.t);
   PushScope(Scope::Kind::Block, nullptr);
-  PushAssociation();
-  return true;
+  const auto assocCount{std::get>(x.t).size()};
+  for (auto nthLastAssoc{assocCount}; nthLastAssoc > 0; --nthLastAssoc) {
+SetCurrentAssociation(nthLastAssoc);
+if (auto *symbol{MakeAssocEntity()}) {
+  if (ExtractCoarrayRef(GetCurrentAssociation().selector.expr)) { // C1103
+Say("Selector must not be a coindexed object"_err_en_US);
+  }
+  SetTypeFromAssociation(*symbol);
+  SetAttrsFromAssociation(*symbol);
+}
+  }
+  PopAssociation(assocCount);
 }
+
 void ConstructVisitor::Post(const parser::EndAssociateStmt &x) {
-  PopAssociation();
   PopScope();
   CheckRef(x.v);
 }
 
-void ConstructVisitor::Post(const parser::Association &x) {
+bool ConstructVisitor::Pre(const parser::Association &x) {
+  PushAssociation();
   const auto &name{st

[llvm-branch-commits] [flang] 0996b59 - [flang] Infrastructure improvements in utility routines

2021-01-20 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-20T12:40:25-08:00
New Revision: 0996b590aaafe2de8378fd45a5094c13a4de3360

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

LOG: [flang] Infrastructure improvements in utility routines

* IsArrayElement() needs another option to control whether it
  should ignore trailing component references.
* Add IsObjectPointer().
* Add const Scope& variants of IsFunction() and IsProcedure().
* Make TypeAndShape::Characterize() work with procedure bindings.
* Handle CHARACTER length in MeasureSizeInBytes().
* Fine-tune FindExternallyVisibleObject()'s handling of dummy arguments
  to conform with Fortran 2018: only INTENT(IN) and dummy pointers
  in pure functions signify; update two tests accordingly.

Also: resolve some stylistic inconsistencies and add a missing
"const" in the expression traversal template framework.

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

Added: 


Modified: 
flang/include/flang/Evaluate/call.h
flang/include/flang/Evaluate/tools.h
flang/include/flang/Evaluate/traverse.h
flang/lib/Evaluate/characteristics.cpp
flang/lib/Evaluate/tools.cpp
flang/lib/Semantics/tools.cpp
flang/test/Semantics/structconst03.f90
flang/test/Semantics/structconst04.f90

Removed: 




diff  --git a/flang/include/flang/Evaluate/call.h 
b/flang/include/flang/Evaluate/call.h
index 0e78839b2ccc..e74e82d86f87 100644
--- a/flang/include/flang/Evaluate/call.h
+++ b/flang/include/flang/Evaluate/call.h
@@ -111,12 +111,18 @@ class ActualArgument {
   llvm::raw_ostream &AsFortran(llvm::raw_ostream &) const;
 
   std::optional keyword() const { return keyword_; }
-  void set_keyword(parser::CharBlock x) { keyword_ = x; }
+  ActualArgument &set_keyword(parser::CharBlock x) {
+keyword_ = x;
+return *this;
+  }
   bool isAlternateReturn() const {
 return std::holds_alternative(u_);
   }
   bool isPassedObject() const { return isPassedObject_; }
-  void set_isPassedObject(bool yes = true) { isPassedObject_ = yes; }
+  ActualArgument &set_isPassedObject(bool yes = true) {
+isPassedObject_ = yes;
+return *this;
+  }
 
   bool Matches(const characteristics::DummyArgument &) const;
   common::Intent dummyIntent() const { return dummyIntent_; }

diff  --git a/flang/include/flang/Evaluate/tools.h 
b/flang/include/flang/Evaluate/tools.h
index 3fe3dc1843ec..351dc8715cdd 100644
--- a/flang/include/flang/Evaluate/tools.h
+++ b/flang/include/flang/Evaluate/tools.h
@@ -235,11 +235,14 @@ std::optional ExtractSubstringBase(const 
Substring &);
 
 // Predicate: is an expression is an array element reference?
 template 
-bool IsArrayElement(const Expr &expr, bool intoSubstring = false) {
+bool IsArrayElement(const Expr &expr, bool intoSubstring = true,
+bool skipComponents = false) {
   if (auto dataRef{ExtractDataRef(expr, intoSubstring)}) {
 const DataRef *ref{&*dataRef};
-while (const Component * component{std::get_if(&ref->u)}) {
-  ref = &component->base();
+if (skipComponents) {
+  while (const Component * component{std::get_if(&ref->u)}) {
+ref = &component->base();
+  }
 }
 if (const auto *coarrayRef{std::get_if(&ref->u)}) {
   return !coarrayRef->subscript().empty();
@@ -789,6 +792,7 @@ bool IsProcedure(const Expr &);
 bool IsFunction(const Expr &);
 bool IsProcedurePointer(const Expr &);
 bool IsNullPointer(const Expr &);
+bool IsObjectPointer(const Expr &, FoldingContext &);
 
 // Extracts the chain of symbols from a designator, which has perhaps been
 // wrapped in an Expr<>, removing all of the (co)subscripts.  The
@@ -913,12 +917,13 @@ class Scope;
 // These functions are used in Evaluate so they are defined here rather than in
 // Semantics to avoid a link-time dependency on Semantics.
 // All of these apply GetUltimate() or ResolveAssociations() to their 
arguments.
-
 bool IsVariableName(const Symbol &);
 bool IsPureProcedure(const Symbol &);
 bool IsPureProcedure(const Scope &);
 bool IsFunction(const Symbol &);
+bool IsFunction(const Scope &);
 bool IsProcedure(const Symbol &);
+bool IsProcedure(const Scope &);
 bool IsProcedurePointer(const Symbol &);
 bool IsSaved(const Symbol &); // saved implicitly or explicitly
 bool IsDummy(const Symbol &);

diff  --git a/flang/include/flang/Evaluate/traverse.h 
b/flang/include/flang/Evaluate/traverse.h
index 9238e58a1fb3..c9455910aa41 100644
--- a/flang/include/flang/Evaluate/traverse.h
+++ b/flang/include/flang/Evaluate/traverse.h
@@ -50,7 +50,7 @@ template  class Traverse {
   Result operator()(const common::Indirection &x) const {
 return visitor_(x.value());
   }
-  template  Result operator()(SymbolRef x) const {
+  template  Result operator()(const SymbolRef x) const {
 return visitor_(*x);
   }
   template  Re

[llvm-branch-commits] [flang] a75840a - [flang] Better C_LOC and C_ASSOCIATED in flang/module

2021-01-21 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-21T09:41:05-08:00
New Revision: a75840a09c65582e3ec4eb1654bd17386b71397d

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

LOG: [flang] Better C_LOC and C_ASSOCIATED in flang/module

The place-holding implementation of C_LOC just didn't work
when used with our more complete semantic checking, specifically
in the case of a polymorphic argument; convert it to an external
function with an implicit interface.  C_ASSOCIATED needs to be
a generic interface with specific implementations for C_PTR and
C_FUNPTR.

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

Added: 


Modified: 
flang/module/__fortran_builtins.f90
flang/module/iso_c_binding.f90

Removed: 




diff  --git a/flang/module/__fortran_builtins.f90 
b/flang/module/__fortran_builtins.f90
index 167bd80d6ad9..852a7a973fac 100644
--- a/flang/module/__fortran_builtins.f90
+++ b/flang/module/__fortran_builtins.f90
@@ -29,4 +29,6 @@
   type :: __builtin_team_type
 integer(kind=int64) :: __id
   end type
+
+  procedure(type(__builtin_c_ptr)) :: __builtin_c_loc
 end module

diff  --git a/flang/module/iso_c_binding.f90 b/flang/module/iso_c_binding.f90
index eed264f531a4..3668daab46ee 100644
--- a/flang/module/iso_c_binding.f90
+++ b/flang/module/iso_c_binding.f90
@@ -14,7 +14,8 @@ module iso_c_binding
 c_f_pointer => __builtin_c_f_pointer, &
 c_ptr => __builtin_c_ptr, &
 c_funptr => __builtin_c_funptr, &
-c_sizeof => sizeof
+c_sizeof => sizeof, &
+c_loc => __builtin_c_loc
 
   type(c_ptr), parameter :: c_null_ptr = c_ptr(0)
   type(c_funptr), parameter :: c_null_funptr = c_funptr(0)
@@ -76,25 +77,42 @@ module iso_c_binding
   character(kind=c_char, len=1), parameter :: c_horizontal_tab = achar(9)
   character(kind=c_char, len=1), parameter :: c_vertical_tab =  achar(11)
 
+  interface c_associated
+module procedure c_associated_c_ptr
+module procedure c_associated_c_funptr
+  end interface
+  private :: c_associated_c_ptr, c_associated_c_funptr
+
+  ! gfortran extensions
+  integer, parameter :: &
+c_float128 = 16, &
+c_float128_complex = c_float128
+
  contains
 
-  logical function c_associated(c_ptr_1, c_ptr_2)
+  logical function c_associated_c_ptr(c_ptr_1, c_ptr_2)
 type(c_ptr), intent(in) :: c_ptr_1
 type(c_ptr), intent(in), optional :: c_ptr_2
 if (c_ptr_1%__address == c_null_ptr%__address) then
-  c_associated = .false.
+  c_associated_c_ptr = .false.
 else if (present(c_ptr_2)) then
-  c_associated = c_ptr_1%__address == c_ptr_2%__address
+  c_associated_c_ptr = c_ptr_1%__address == c_ptr_2%__address
 else
-  c_associated = .true.
+  c_associated_c_ptr = .true.
 end if
-  end function c_associated
+  end function c_associated_c_ptr
 
-  function c_loc(x)
-type(c_ptr) :: c_loc
-type(*), dimension(..), intent(in) :: x
-c_loc = c_ptr(loc(x))
-  end function c_loc
+  logical function c_associated_c_funptr(c_funptr_1, c_funptr_2)
+type(c_funptr), intent(in) :: c_funptr_1
+type(c_funptr), intent(in), optional :: c_funptr_2
+if (c_funptr_1%__address == c_null_ptr%__address) then
+  c_associated_c_funptr = .false.
+else if (present(c_funptr_2)) then
+  c_associated_c_funptr = c_funptr_1%__address == c_funptr_2%__address
+else
+  c_associated_c_funptr = .true.
+end if
+  end function c_associated_c_funptr
 
   function c_funloc(x)
 type(c_funptr) :: c_funloc



___
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] 3738447 - [flang] Address name resolution problems

2021-01-21 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-21T16:15:38-08:00
New Revision: 3738447c96c7400d0e9b9b00b583dca45fb0807f

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

LOG: [flang] Address name resolution problems

Don't emit a bogus error message about a bad forward reference
when it's an IMPORT of a USE-associated symbol; don't ignore
intrinsic functions when USE-associating the contents of a
module when the intrinsic has been explicitly USE'd; allow
PUBLIC or PRIVATE accessibility attribute to be specified
for an enumerator before the declaration of the enumerator.

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

Added: 


Modified: 
flang/lib/Semantics/resolve-names.cpp

Removed: 




diff  --git a/flang/lib/Semantics/resolve-names.cpp 
b/flang/lib/Semantics/resolve-names.cpp
index d76abbf68a08..2b7ee045bc8f 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2238,6 +2238,12 @@ std::optional ScopeHandler::HadForwardRef(
 bool ScopeHandler::CheckPossibleBadForwardRef(const Symbol &symbol) {
   if (!context().HasError(symbol)) {
 if (auto fwdRef{HadForwardRef(symbol)}) {
+  const Symbol *outer{symbol.owner().FindSymbol(symbol.name())};
+  if (outer && symbol.has() &&
+  &symbol.GetUltimate() == &outer->GetUltimate()) {
+// e.g. IMPORT of host's USE association
+return false;
+  }
   Say(*fwdRef,
   "Forward reference to '%s' is not allowed in the same specification 
part"_err_en_US,
   *fwdRef)
@@ -2332,7 +2338,8 @@ void ModuleVisitor::Post(const parser::UseStmt &x) {
 }
 for (const auto &[name, symbol] : *useModuleScope_) {
   if (symbol->attrs().test(Attr::PUBLIC) &&
-  !symbol->attrs().test(Attr::INTRINSIC) &&
+  (!symbol->attrs().test(Attr::INTRINSIC) ||
+  symbol->has()) &&
   !symbol->has() && useNames.count(name) == 0) {
 SourceName location{x.moduleName.source};
 if (auto *localSymbol{FindInScope(name)}) {
@@ -3310,10 +3317,11 @@ bool DeclarationVisitor::Pre(const 
parser::NamedConstant &x) {
 bool DeclarationVisitor::Pre(const parser::Enumerator &enumerator) {
   const parser::Name &name{std::get(enumerator.t).v};
   Symbol *symbol{FindSymbol(name)};
-  if (symbol) {
+  if (symbol && !symbol->has()) {
 // Contrary to named constants appearing in a PARAMETER statement,
 // enumerator names should not have their type, dimension or any other
-// attributes defined before they are declared in the enumerator statement.
+// attributes defined before they are declared in the enumerator statement,
+// with the exception of accessibility.
 // This is not explicitly forbidden by the standard, but they are scalars
 // which type is left for the compiler to chose, so do not let users try to
 // tamper with that.



___
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] 0cfadb3 - [flang] Allow NULL() actual argument for pointer dummy

2021-01-21 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-21T16:37:35-08:00
New Revision: 0cfadb37f4fef016998cb412270cfe87b0683090

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

LOG: [flang] Allow NULL() actual argument for pointer dummy

Fixes a bogus error message about an actual argument not being an
object.

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

Added: 


Modified: 
flang/lib/Semantics/check-call.cpp

Removed: 




diff  --git a/flang/lib/Semantics/check-call.cpp 
b/flang/lib/Semantics/check-call.cpp
index ffae3410a852..1bd0b0ab6f08 100644
--- a/flang/lib/Semantics/check-call.cpp
+++ b/flang/lib/Semantics/check-call.cpp
@@ -139,8 +139,8 @@ static bool DefersSameTypeParameters(
 static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
 const std::string &dummyName, evaluate::Expr &actual,
 characteristics::TypeAndShape &actualType, bool isElemental,
-bool actualIsArrayElement, evaluate::FoldingContext &context,
-const Scope *scope, const evaluate::SpecificIntrinsic *intrinsic) {
+evaluate::FoldingContext &context, const Scope *scope,
+const evaluate::SpecificIntrinsic *intrinsic) {
 
   // Basic type & rank checking
   parser::ContextualMessages &messages{context.messages()};
@@ -153,7 +153,7 @@ static void CheckExplicitDataArg(const 
characteristics::DummyDataObject &dummy,
characteristics::TypeAndShape::Attr::AssumedRank)) {
 } else if (!dummy.type.attrs().test(
characteristics::TypeAndShape::Attr::AssumedShape) &&
-(actualType.Rank() > 0 || actualIsArrayElement)) {
+(actualType.Rank() > 0 || IsArrayElement(actual))) {
   // Sequence association (15.5.2.11) applies -- rank need not match
   // if the actual argument is an array or array element designator.
 } else {
@@ -271,8 +271,7 @@ static void CheckExplicitDataArg(const 
characteristics::DummyDataObject &dummy,
   ? actualLastSymbol->detailsIf()
   : nullptr};
   int actualRank{evaluate::GetRank(actualType.shape())};
-  bool actualIsPointer{(actualLastSymbol && IsPointer(*actualLastSymbol)) ||
-  evaluate::IsNullPointer(actual)};
+  bool actualIsPointer{evaluate::IsObjectPointer(actual, context)};
   if (dummy.type.attrs().test(
   characteristics::TypeAndShape::Attr::AssumedShape)) {
 // 15.5.2.4(16)
@@ -293,7 +292,9 @@ static void CheckExplicitDataArg(const 
characteristics::DummyDataObject &dummy,
   "Coindexed scalar actual argument must be associated with a scalar 
%s"_err_en_US,
   dummyName);
 }
-if (actualLastSymbol && actualLastSymbol->Rank() == 0 &&
+if (!IsArrayElement(actual) &&
+!(actualType.type().category() == TypeCategory::Character &&
+actualType.type().kind() == 1) &&
 !(dummy.type.type().IsAssumedType() && dummyIsAssumedSize)) {
   messages.Say(
   "Whole scalar actual argument may not be associated with a %s 
array"_err_en_US,
@@ -624,15 +625,18 @@ static void 
CheckExplicitInterfaceArg(evaluate::ActualArgument &arg,
 arg.set_dummyIntent(object.intent);
 bool isElemental{object.type.Rank() == 0 && 
proc.IsElemental()};
 CheckExplicitDataArg(object, dummyName, *expr, *type,
-isElemental, IsArrayElement(*expr), context, scope,
-intrinsic);
+isElemental, context, scope, intrinsic);
   } else if (object.type.type().IsTypelessIntrinsicArgument() &&
   std::holds_alternative(
   expr->u)) {
 // ok
   } else if (object.type.type().IsTypelessIntrinsicArgument() &&
   evaluate::IsNullPointer(*expr)) {
-// ok, calling ASSOCIATED(NULL())
+// ok, ASSOCIATED(NULL())
+  } else if (object.attrs.test(
+ characteristics::DummyDataObject::Attr::Pointer) 
&&
+  evaluate::IsNullPointer(*expr)) {
+// ok, FOO(NULL())
   } else {
 messages.Say(
 "Actual argument '%s' associated with %s is not a variable 
or typed expression"_err_en_US,



___
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] 2de5ea3 - [flang] Fix bogus error message with binding

2021-01-21 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-21T16:59:51-08:00
New Revision: 2de5ea3b3ed9882026d9dc6c5d8ec462ebe5f8ec

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

LOG: [flang] Fix bogus error message with binding

ProcedureDesignator::GetInterfaceSymbol() needs to return
the procedure bound to a bindings.

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

Added: 
flang/test/Semantics/call17.f90

Modified: 
flang/lib/Evaluate/call.cpp
flang/lib/Semantics/check-declarations.cpp
flang/test/Semantics/resolve88.f90

Removed: 




diff  --git a/flang/lib/Evaluate/call.cpp b/flang/lib/Evaluate/call.cpp
index 3fe56ab4874b..395751acabda 100644
--- a/flang/lib/Evaluate/call.cpp
+++ b/flang/lib/Evaluate/call.cpp
@@ -117,9 +117,12 @@ int ProcedureDesignator::Rank() const {
 
 const Symbol *ProcedureDesignator::GetInterfaceSymbol() const {
   if (const Symbol * symbol{GetSymbol()}) {
-if (const auto *details{
-symbol->detailsIf()}) {
-  return details->interface().symbol();
+const Symbol &ultimate{symbol->GetUltimate()};
+if (const auto *proc{ultimate.detailsIf()}) {
+  return proc->interface().symbol();
+} else if (const auto *binding{
+   ultimate.detailsIf()}) {
+  return &binding->symbol();
 }
   }
   return nullptr;

diff  --git a/flang/lib/Semantics/check-declarations.cpp 
b/flang/lib/Semantics/check-declarations.cpp
index aca5392e507f..cd35047681e3 100644
--- a/flang/lib/Semantics/check-declarations.cpp
+++ b/flang/lib/Semantics/check-declarations.cpp
@@ -53,8 +53,7 @@ class CheckHelper {
 evaluate::CheckSpecificationExpr(x, DEREF(scope_), foldingContext_);
   }
   void CheckValue(const Symbol &, const DerivedTypeSpec *);
-  void CheckVolatile(
-  const Symbol &, bool isAssociated, const DerivedTypeSpec *);
+  void CheckVolatile(const Symbol &, const DerivedTypeSpec *);
   void CheckPointer(const Symbol &);
   void CheckPassArg(
   const Symbol &proc, const Symbol *interface, const WithPassArg &);
@@ -172,22 +171,18 @@ void CheckHelper::Check(const Symbol &symbol) {
   context_.set_location(symbol.name());
   const DeclTypeSpec *type{symbol.GetType()};
   const DerivedTypeSpec *derived{type ? type->AsDerived() : nullptr};
-  bool isAssociated{symbol.has() || 
symbol.has()};
-  if (symbol.attrs().test(Attr::VOLATILE)) {
-CheckVolatile(symbol, isAssociated, derived);
-  }
-  if (isAssociated) {
-if (const auto *details{symbol.detailsIf()}) {
-  CheckHostAssoc(symbol, *details);
-}
-return; // no other checks on associated symbols
-  }
-  if (IsPointer(symbol)) {
-CheckPointer(symbol);
-  }
+  bool isDone{false};
   std::visit(
   common::visitors{
-  [&](const ProcBindingDetails &x) { CheckProcBinding(symbol, x); },
+  [&](const UseDetails &x) { isDone = true; },
+  [&](const HostAssocDetails &x) {
+CheckHostAssoc(symbol, x);
+isDone = true;
+  },
+  [&](const ProcBindingDetails &x) {
+CheckProcBinding(symbol, x);
+isDone = true;
+  },
   [&](const ObjectEntityDetails &x) { CheckObjectEntity(symbol, x); },
   [&](const ProcEntityDetails &x) { CheckProcEntity(symbol, x); },
   [&](const SubprogramDetails &x) { CheckSubprogram(symbol, x); },
@@ -196,6 +191,15 @@ void CheckHelper::Check(const Symbol &symbol) {
   [](const auto &) {},
   },
   symbol.details());
+  if (symbol.attrs().test(Attr::VOLATILE)) {
+CheckVolatile(symbol, derived);
+  }
+  if (isDone) {
+return; // following checks do not apply
+  }
+  if (IsPointer(symbol)) {
+CheckPointer(symbol);
+  }
   if (InPure()) {
 if (IsSaved(symbol)) {
   messages_.Say(
@@ -1279,7 +1283,7 @@ const Procedure *CheckHelper::Characterize(const Symbol 
&symbol) {
   return common::GetPtrFromOptional(it->second);
 }
 
-void CheckHelper::CheckVolatile(const Symbol &symbol, bool isAssociated,
+void CheckHelper::CheckVolatile(const Symbol &symbol,
 const DerivedTypeSpec *derived) { // C866 - C868
   if (IsIntentIn(symbol)) {
 messages_.Say(
@@ -1288,7 +1292,7 @@ void CheckHelper::CheckVolatile(const Symbol &symbol, 
bool isAssociated,
   if (IsProcedure(symbol)) {
 messages_.Say("VOLATILE attribute may apply only to a variable"_err_en_US);
   }
-  if (isAssociated) {
+  if (symbol.has() || symbol.has()) {
 const Symbol &ultimate{symbol.GetUltimate()};
 if (IsCoarray(ultimate)) {
   messages_.Say(

diff  --git a/flang/test/Semantics/call17.f90 b/flang/test/Semantics/call17.f90
new file mode 100644
index ..1f4d2c4d9186
--- /dev/null
+++ b/flang/test/Semantics/call17.f90
@@ -0,0 +1,19 @@
+! RUN: %f18 -fparse-only $s 2>&1 | FileCheck %s
+
+! Regression 

[llvm-branch-commits] [flang] 59bf9a8 - [flang] Remove some needless operations in expr rewriting

2021-01-22 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-22T10:08:51-08:00
New Revision: 59bf9a89d825c1f23b249e0ce43d8bf7b486a203

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

LOG: [flang] Remove some needless operations in expr rewriting

Expressions emitted to module files and error messages
sometimes contain conversions of integer results of inquiry
intrinsics; these are usually not needed, and can conflict
with "int" in the user's namespace.  Improve folding so that
these conversions don't appear, and do some other clean-up
in adjacent code.

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

Added: 


Modified: 
flang/lib/Evaluate/fold-implementation.h
flang/test/Semantics/modfile17.f90
flang/test/Semantics/modfile30.f90

Removed: 




diff  --git a/flang/lib/Evaluate/fold-implementation.h 
b/flang/lib/Evaluate/fold-implementation.h
index 7232715600fd..37116bb6bca4 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -1105,12 +1105,13 @@ Expr FoldOperation(
 // This variable is a workaround for msvc which emits an error when
 // using the FROMCAT template parameter below.
 TypeCategory constexpr FromCat{FROMCAT};
+static_assert(FromCat == Operand::category);
 auto &convert{msvcWorkaround.convert};
 char buffer[64];
 if (auto value{GetScalarConstantValue(kindExpr)}) {
   FoldingContext &ctx{msvcWorkaround.context};
   if constexpr (TO::category == TypeCategory::Integer) {
-if constexpr (Operand::category == TypeCategory::Integer) {
+if constexpr (FromCat == TypeCategory::Integer) {
   auto converted{Scalar::ConvertSigned(*value)};
   if (converted.overflow) {
 ctx.messages().Say(
@@ -1118,7 +1119,7 @@ Expr FoldOperation(
 Operand::kind, TO::kind);
   }
   return ScalarConstantToExpr(std::move(converted.value));
-} else if constexpr (Operand::category == TypeCategory::Real) {
+} else if constexpr (FromCat == TypeCategory::Real) {
   auto converted{value->template ToInteger>()};
   if (converted.flags.test(RealFlag::InvalidArgument)) {
 ctx.messages().Say(
@@ -1132,7 +1133,7 @@ Expr FoldOperation(
   return ScalarConstantToExpr(std::move(converted.value));
 }
   } else if constexpr (TO::category == TypeCategory::Real) {
-if constexpr (Operand::category == TypeCategory::Integer) {
+if constexpr (FromCat == TypeCategory::Integer) {
   auto converted{Scalar::FromInteger(*value)};
   if (!converted.flags.empty()) {
 std::snprintf(buffer, sizeof buffer,
@@ -1141,7 +1142,7 @@ Expr FoldOperation(
 RealFlagWarnings(ctx, converted.flags, buffer);
   }
   return ScalarConstantToExpr(std::move(converted.value));
-} else if constexpr (Operand::category == TypeCategory::Real) {
+} else if constexpr (FromCat == TypeCategory::Real) {
   auto converted{Scalar::Convert(*value)};
   if (!converted.flags.empty()) {
 std::snprintf(buffer, sizeof buffer,
@@ -1154,7 +1155,7 @@ Expr FoldOperation(
   return ScalarConstantToExpr(std::move(converted.value));
 }
   } else if constexpr (TO::category == TypeCategory::Complex) {
-if constexpr (Operand::category == TypeCategory::Complex) {
+if constexpr (FromCat == TypeCategory::Complex) {
   return FoldOperation(ctx,
   ComplexConstructor{
   AsExpr(Convert{AsCategoryExpr(
@@ -1163,17 +1164,31 @@ Expr FoldOperation(
   Constant{value->AIMAG()})})});
 }
   } else if constexpr (TO::category == TypeCategory::Character &&
-  Operand::category == TypeCategory::Character) {
+  FromCat == TypeCategory::Character) {
 if (auto converted{ConvertString>(std::move(*value))}) {
   return ScalarConstantToExpr(std::move(*converted));
 }
   } else if constexpr (TO::category == TypeCategory::Logical &&
-  Operand::category == TypeCategory::Logical) {
+  FromCat == TypeCategory::Logical) {
 return Expr{value->IsTrue()};
   }
-} else if constexpr (std::is_same_v &&
+} else if constexpr (TO::category == FromCat &&
 FromCat != TypeCategory::Character) {
-  return std::move(kindExpr); // remove needless conversion
+  // Conversion of non-constant in same type category
+  if constexpr (st

[llvm-branch-commits] [flang] 07f1e1f - [flang] Correct shape analysis for transformational intrinsic functions

2021-01-22 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-22T10:48:58-08:00
New Revision: 07f1e1f44c87d1ee84caf13d6e5aa64eb7e1b068

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

LOG: [flang] Correct shape analysis for transformational intrinsic functions

Correct the analysis of references to transformational intrinsic
functions that have different semantics based on the presence or
absence of a DIM= argument; add shape analysis for UNPACK().

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

Added: 


Modified: 
flang/lib/Evaluate/intrinsics.cpp
flang/lib/Evaluate/shape.cpp

Removed: 




diff  --git a/flang/lib/Evaluate/intrinsics.cpp 
b/flang/lib/Evaluate/intrinsics.cpp
index 3de43fd88d7e..98fbe92e2815 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -181,12 +181,13 @@ ENUM_CLASS(Rank,
 conformable, // scalar, or array of same rank & shape as "array" argument
 reduceOperation, // a pure function with constraints for REDUCE
 dimReduced, // scalar if no DIM= argument, else rank(array)-1
-dimRemoved, // scalar, or rank(array)-1
+dimRemovedOrScalar, // rank(array)-1 (less DIM) or scalar
+locReduced, // vector(1:rank) if no DIM= argument, else rank(array)-1
 rankPlus1, // rank(known)+1
 shaped, // rank is length of SHAPE vector
 )
 
-ENUM_CLASS(Optionality, required, optional,
+ENUM_CLASS(Optionality, required, optional, missing,
 defaultsToSameKind, // for MatchingDefaultKIND
 defaultsToDefaultForResult, // for DefaultingKIND
 defaultsToSizeKind, // for SizeDefaultKIND
@@ -227,6 +228,9 @@ static constexpr IntrinsicDummyArgument RequiredDIM{"dim",
 static constexpr IntrinsicDummyArgument OptionalDIM{"dim",
 {IntType, KindCode::dimArg}, Rank::scalar, Optionality::optional,
 common::Intent::In};
+static constexpr IntrinsicDummyArgument MissingDIM{"dim",
+{IntType, KindCode::dimArg}, Rank::scalar, Optionality::missing,
+common::Intent::In};
 static constexpr IntrinsicDummyArgument OptionalMASK{"mask", AnyLogical,
 Rank::conformable, Optionality::optional, common::Intent::In};
 
@@ -346,8 +350,8 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
 {"count", {{"mask", AnyLogical, Rank::array}, OptionalDIM, DefaultingKIND},
 KINDInt, Rank::dimReduced, IntrinsicClass::transformationalFunction},
 {"cshift",
-{{"array", SameType, Rank::array}, {"shift", AnyInt, Rank::dimRemoved},
-OptionalDIM},
+{{"array", SameType, Rank::array},
+{"shift", AnyInt, Rank::dimRemovedOrScalar}, OptionalDIM},
 SameType, Rank::conformable, IntrinsicClass::transformationalFunction},
 {"dble", {{"a", AnyNumeric, Rank::elementalOrBOZ}}, DoublePrecision},
 {"digits", {{"x", AnyIntOrReal, Rank::anyOrAssumedRank}}, DefaultInt,
@@ -380,16 +384,16 @@ static const IntrinsicInterface 
genericIntrinsicFunction[]{
 {"dshiftr", {{"i", BOZ}, {"j", SameInt}, {"shift", AnyInt}}, SameInt},
 {"eoshift",
 {{"array", SameIntrinsic, Rank::array},
-{"shift", AnyInt, Rank::dimRemoved},
-{"boundary", SameIntrinsic, Rank::dimRemoved,
+{"shift", AnyInt, Rank::dimRemovedOrScalar},
+{"boundary", SameIntrinsic, Rank::dimReduced,
 Optionality::optional},
 OptionalDIM},
 SameIntrinsic, Rank::conformable,
 IntrinsicClass::transformationalFunction},
 {"eoshift",
 {{"array", SameDerivedType, Rank::array},
-{"shift", AnyInt, Rank::dimRemoved},
-{"boundary", SameDerivedType, Rank::dimRemoved}, OptionalDIM},
+{"shift", AnyInt, Rank::dimReduced},
+{"boundary", SameDerivedType, Rank::dimReduced}, OptionalDIM},
 SameDerivedType, Rank::conformable,
 IntrinsicClass::transformationalFunction},
 {"epsilon", {{"x", SameReal, Rank::anyOrAssumedRank}}, SameReal,
@@ -410,20 +414,21 @@ static const IntrinsicInterface 
genericIntrinsicFunction[]{
 {"value", AnyNumeric, Rank::scalar}, RequiredDIM, OptionalMASK,
 SizeDefaultKIND,
 {"back", AnyLogical, Rank::scalar, Optionality::optional}},
-KINDInt, Rank::dimRemoved, IntrinsicClass::transformationalFunction},
+KINDInt, Rank::locReduced, IntrinsicClass::transformationalFunction},
 {"findloc",
 {{"array", AnyNumeric, Rank::array},
-{"value", AnyNumeric, Rank::scalar}, OptionalMASK, SizeDefaultKIND,
+{"value", AnyNumeric, Rank::scalar}, MissingDIM, OptionalMASK,
+SizeDefaultKIND,
 {"back", AnyLogical, Rank::scalar, Optionality::optional}},
 KINDInt, Rank::vector, IntrinsicClass::transformationalFunction},
 {"findloc",
 {{"a

[llvm-branch-commits] [flang] f187d64 - [flang][nfc] Fix comments, remove needless API, tweak script

2021-01-22 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2021-01-22T10:55:53-08:00
New Revision: f187d64c80acd84f3f60799b80eba2485f8866df

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

LOG: [flang][nfc] Fix comments, remove needless API, tweak script

* Remove an unimplemented and unused member function declaration
* Remove a misleading comment about an unrelated constraint number
* Fix a comment
* Add f18 crash message to "flang" driver script

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

Added: 


Modified: 
flang/include/flang/Parser/provenance.h
flang/include/flang/Semantics/symbol.h
flang/lib/Semantics/assignment.cpp
flang/tools/f18/flang

Removed: 




diff  --git a/flang/include/flang/Parser/provenance.h 
b/flang/include/flang/Parser/provenance.h
index 1f0a0a90e7019..73661d954854a 100644
--- a/flang/include/flang/Parser/provenance.h
+++ b/flang/include/flang/Parser/provenance.h
@@ -173,7 +173,6 @@ class AllSources {
   std::string GetPath(Provenance) const; // __FILE__
   int GetLineNumber(Provenance) const; // __LINE__
   Provenance CompilerInsertionProvenance(char ch);
-  Provenance CompilerInsertionProvenance(const char *, std::size_t);
   ProvenanceRange IntersectionWithSourceFiles(ProvenanceRange) const;
   llvm::raw_ostream &Dump(llvm::raw_ostream &) const;
 

diff  --git a/flang/include/flang/Semantics/symbol.h 
b/flang/include/flang/Semantics/symbol.h
index dc7196cfd5eab..f04b05afd6e4b 100644
--- a/flang/include/flang/Semantics/symbol.h
+++ b/flang/include/flang/Semantics/symbol.h
@@ -356,7 +356,7 @@ class TypeParamDetails {
 };
 
 // Record the USE of a symbol: location is where (USE statement or renaming);
-// symbol is the USEd module.
+// symbol is in the USEd module.
 class UseDetails {
 public:
   UseDetails(const SourceName &location, const Symbol &symbol)

diff  --git a/flang/lib/Semantics/assignment.cpp 
b/flang/lib/Semantics/assignment.cpp
index 090aae0af8cb7..1fae92c61f3cb 100644
--- a/flang/lib/Semantics/assignment.cpp
+++ b/flang/lib/Semantics/assignment.cpp
@@ -70,7 +70,7 @@ void AssignmentContext::Analyze(const parser::AssignmentStmt 
&stmt) {
   const Scope &scope{context_.FindScope(lhsLoc)};
   if (auto whyNot{WhyNotModifiable(lhsLoc, lhs, scope, true)}) {
 if (auto *msg{Say(lhsLoc,
-"Left-hand side of assignment is not modifiable"_err_en_US)}) 
{ // C1158
+"Left-hand side of assignment is not modifiable"_err_en_US)}) {
   msg->Attach(*whyNot);
 }
   }

diff  --git a/flang/tools/f18/flang b/flang/tools/f18/flang
index 01bdffdd20c72..7109cd7f547a9 100644
--- a/flang/tools/f18/flang
+++ b/flang/tools/f18/flang
@@ -12,4 +12,9 @@ module_dir=$wd/include/flang
 if [[ ! -d $module_dir ]]; then
   module_dir=$wd/tools/flang/include/flang
 fi
-$wd/bin/f18 -module-suffix .f18.mod -intrinsic-module-directory $module_dir 
"$@"
+opts="-module-suffix .f18.mod -intrinsic-module-directory $module_dir"
+if ! $wd/bin/f18 $opts "$@"
+then status=$?
+ echo flang: in $PWD, f18 failed with exit status $status: $wd/bin/f18 
$opts "$@" >&2
+ exit $status
+fi



___
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] b1afbce - [flang] Minor fix to list-directed REAL output editing

2020-12-15 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2020-12-15T13:04:44-08:00
New Revision: b1afbceb9296a9ce14a0bd38f36e93b8c77fa18a

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

LOG: [flang] Minor fix to list-directed REAL output editing

Always emit the letter 'E' in list-directed REAL output;
the library was omitting it for exponents greater than 99,
as should be done for E and D formatting of large exponents
without an Ed exponent digit count.

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

Added: 


Modified: 
flang/runtime/edit-output.cpp

Removed: 




diff  --git a/flang/runtime/edit-output.cpp b/flang/runtime/edit-output.cpp
index 31ba9f152d74..76f24cb07437 100644
--- a/flang/runtime/edit-output.cpp
+++ b/flang/runtime/edit-output.cpp
@@ -116,7 +116,7 @@ const char *RealOutputEditingBase::FormatExponent(
 }
   }
   *--exponent = expo < 0 ? '-' : '+';
-  if (edit.expoDigits || exponent + 3 == eEnd) {
+  if (edit.expoDigits || edit.IsListDirected() || exponent + 3 == eEnd) {
 *--exponent = edit.descriptor == 'D' ? 'D' : 'E'; // not 'G'
   }
   length = eEnd - exponent;



___
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] 9a883bf - [flang] Clean up TODO comments and fix one (DATA constant ambiguity)

2020-12-15 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2020-12-15T13:36:07-08:00
New Revision: 9a883bfa11dd77cf2d45a25c5efc364e256e6d9a

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

LOG: [flang] Clean up TODO comments and fix one (DATA constant ambiguity)

Remove resolved & moot TODO comments in Common/, Parser/,
and Evaluate/.  Address a pending one relating to parsing
ambiguity in DATA statement constants, handling it with
symbol table information in Semantics and adding a test.

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

Added: 
flang/test/Semantics/data10.f90

Modified: 
flang/include/flang/Evaluate/real.h
flang/include/flang/Parser/dump-parse-tree.h
flang/include/flang/Parser/parse-state.h
flang/include/flang/Parser/parse-tree.h
flang/lib/Evaluate/check-expression.cpp
flang/lib/Evaluate/type.cpp
flang/lib/Parser/Fortran-parsers.cpp
flang/lib/Parser/program-parsers.cpp
flang/lib/Semantics/data-to-inits.cpp
flang/lib/Semantics/rewrite-parse-tree.cpp
flang/test/Semantics/data01.f90
flang/test/Semantics/data06.f90

Removed: 




diff  --git a/flang/include/flang/Evaluate/real.h 
b/flang/include/flang/Evaluate/real.h
index 8ceb4639aa93..5864bdd7bd3a 100644
--- a/flang/include/flang/Evaluate/real.h
+++ b/flang/include/flang/Evaluate/real.h
@@ -63,10 +63,6 @@ class Real : public common::RealDetails {
 return word_ == that.word_;
   }
 
-  // TODO: DIM, MAX, MIN, DPROD, FRACTION,
-  // INT/NINT, NEAREST, OUT_OF_RANGE,
-  // RRSPACING/SPACING, SCALE, SET_EXPONENT
-
   constexpr bool IsSignBitSet() const { return word_.BTEST(bits - 1); }
   constexpr bool IsNegative() const {
 return !IsNotANumber() && IsSignBitSet();
@@ -118,7 +114,7 @@ class Real : public common::RealDetails {
   const Real &, Rounding rounding = defaultRounding) const;
 
   // SQRT(x**2 + y**2) but computed so as to avoid spurious overflow
-  // TODO: needed for CABS
+  // TODO: not yet implemented; needed for CABS
   ValueWithRealFlags HYPOT(
   const Real &, Rounding rounding = defaultRounding) const;
 

diff  --git a/flang/include/flang/Parser/dump-parse-tree.h 
b/flang/include/flang/Parser/dump-parse-tree.h
index 0d819f861495..8a7d1d1302b2 100644
--- a/flang/include/flang/Parser/dump-parse-tree.h
+++ b/flang/include/flang/Parser/dump-parse-tree.h
@@ -200,7 +200,6 @@ class ParseTreeDumper {
   NODE_ENUM(ConnectSpec::CharExpr, Kind)
   NODE(ConnectSpec, Newunit)
   NODE(ConnectSpec, Recl)
-  NODE(parser, ConstantValue)
   NODE(parser, ContainsStmt)
   NODE(parser, Contiguous)
   NODE(parser, ContiguousStmt)

diff  --git a/flang/include/flang/Parser/parse-state.h 
b/flang/include/flang/Parser/parse-state.h
index 00291bac4dbb..76cbb3470dc0 100644
--- a/flang/include/flang/Parser/parse-state.h
+++ b/flang/include/flang/Parser/parse-state.h
@@ -34,7 +34,6 @@ using common::LanguageFeature;
 
 class ParseState {
 public:
-  // TODO: Add a constructor for parsing a normalized module file.
   ParseState(const CookedSource &cooked)
   : p_{cooked.AsCharBlock().begin()}, limit_{cooked.AsCharBlock().end()} {}
   ParseState(const ParseState &that)

diff  --git a/flang/include/flang/Parser/parse-tree.h 
b/flang/include/flang/Parser/parse-tree.h
index 27998c308cc0..a2beac4737f6 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -426,8 +426,9 @@ struct DeclarationConstruct {
 
 // R504 specification-part -> [use-stmt]... [import-stmt]... [implicit-part]
 //[declaration-construct]...
-// TODO: transfer any statements after the last IMPLICIT (if any)
-// from the implicit part to the declaration constructs
+// PARAMETER, FORMAT, and ENTRY statements that appear before any other
+// kind of declaration-construct will be parsed into the implicit-part,
+// even if there are no IMPLICIT statements.
 struct SpecificationPart {
   TUPLE_CLASS_BOILERPLATE(SpecificationPart);
   std::tuple,
@@ -861,13 +862,6 @@ struct LiteralConstant {
   u;
 };
 
-// R604 constant ->  literal-constant | named-constant
-// Renamed to dodge a clash with Constant<> template class.
-struct ConstantValue {
-  UNION_CLASS_BOILERPLATE(ConstantValue);
-  std::variant u;
-};
-
 // R807 access-spec -> PUBLIC | PRIVATE
 struct AccessSpec {
   ENUM_CLASS(Kind, Public, Private)
@@ -1412,14 +1406,15 @@ using TypedExpr = 
common::ForwardOwningPointer;
 //signed-int-literal-constant | signed-real-literal-constant |
 //null-init | initial-data-target |
 //structure-constructor
+// N.B. Parsing ambiguities abound here without recourse to symbols
+// (see comments on R845's parser).
 struct DataStmtConstant {
   UNION_CLASS_BOILERPLATE(DataStmtConstant);
   CharBlock source;
   mutable TypedExpr typedExpr;
-  s

[llvm-branch-commits] [flang] d6a74ec - [flang] Fix false error message for "ptr => func()" array conformance

2020-12-15 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2020-12-15T16:26:18-08:00
New Revision: d6a74ec826adac16f715c5700fc102c62d1a8bf0

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

LOG: [flang] Fix false error message for "ptr => func()" array conformance

Pointers must have deferred shapes, so CheckConformance must be
extended to allow for them.

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

Added: 


Modified: 
flang/include/flang/Evaluate/characteristics.h
flang/include/flang/Evaluate/shape.h
flang/lib/Evaluate/characteristics.cpp
flang/lib/Evaluate/shape.cpp
flang/lib/Semantics/pointer-assignment.cpp
flang/test/Semantics/null01.f90

Removed: 




diff  --git a/flang/include/flang/Evaluate/characteristics.h 
b/flang/include/flang/Evaluate/characteristics.h
index bd0e1bf8186e..5d140a642c86 100644
--- a/flang/include/flang/Evaluate/characteristics.h
+++ b/flang/include/flang/Evaluate/characteristics.h
@@ -145,8 +145,9 @@ class TypeAndShape {
 
   int Rank() const { return GetRank(shape_); }
   bool IsCompatibleWith(parser::ContextualMessages &, const TypeAndShape &that,
-  const char *thisIs = "POINTER", const char *thatIs = "TARGET",
-  bool isElemental = false) const;
+  const char *thisIs = "pointer", const char *thatIs = "target",
+  bool isElemental = false, bool thisIsDeferredShape = false,
+  bool thatIsDeferredShape = false) const;
   std::optional> MeasureSizeInBytes(
   FoldingContext * = nullptr) const;
 

diff  --git a/flang/include/flang/Evaluate/shape.h 
b/flang/include/flang/Evaluate/shape.h
index dc76afe57b40..da0b958a3beb 100644
--- a/flang/include/flang/Evaluate/shape.h
+++ b/flang/include/flang/Evaluate/shape.h
@@ -211,7 +211,8 @@ std::optional GetConstantExtents(
 bool CheckConformance(parser::ContextualMessages &, const Shape &left,
 const Shape &right, const char *leftIs = "left operand",
 const char *rightIs = "right operand", bool leftScalarExpandable = true,
-bool rightScalarExpandable = true);
+bool rightScalarExpandable = true, bool leftIsDeferredShape = false,
+bool rightIsDeferredShape = false);
 
 // Increments one-based subscripts in element order (first varies fastest)
 // and returns true when they remain in range; resets them all to one and

diff  --git a/flang/lib/Evaluate/characteristics.cpp 
b/flang/lib/Evaluate/characteristics.cpp
index f88e518b4891..7b7e62ee179e 100644
--- a/flang/lib/Evaluate/characteristics.cpp
+++ b/flang/lib/Evaluate/characteristics.cpp
@@ -150,7 +150,8 @@ std::optional TypeAndShape::Characterize(
 
 bool TypeAndShape::IsCompatibleWith(parser::ContextualMessages &messages,
 const TypeAndShape &that, const char *thisIs, const char *thatIs,
-bool isElemental) const {
+bool isElemental, bool thisIsDeferredShape,
+bool thatIsDeferredShape) const {
   if (!type_.IsTkCompatibleWith(that.type_)) {
 const auto &len{that.LEN()};
 messages.Say(
@@ -161,7 +162,8 @@ bool 
TypeAndShape::IsCompatibleWith(parser::ContextualMessages &messages,
   }
   return isElemental ||
   CheckConformance(messages, shape_, that.shape_, thisIs, thatIs, false,
-  false /* no scalar expansion */);
+  false /* no scalar expansion */, thisIsDeferredShape,
+  thatIsDeferredShape);
 }
 
 std::optional> TypeAndShape::MeasureSizeInBytes(

diff  --git a/flang/lib/Evaluate/shape.cpp b/flang/lib/Evaluate/shape.cpp
index 37373ae95692..b740c81e0796 100644
--- a/flang/lib/Evaluate/shape.cpp
+++ b/flang/lib/Evaluate/shape.cpp
@@ -683,7 +683,8 @@ auto GetShapeHelper::operator()(const ProcedureRef &call) 
const -> Result {
 // that they conform
 bool CheckConformance(parser::ContextualMessages &messages, const Shape &left,
 const Shape &right, const char *leftIs, const char *rightIs,
-bool leftScalarExpandable, bool rightScalarExpandable) {
+bool leftScalarExpandable, bool rightScalarExpandable,
+bool leftIsDeferredShape, bool rightIsDeferredShape) {
   int n{GetRank(left)};
   if (n == 0 && leftScalarExpandable) {
 return true;
@@ -698,15 +699,18 @@ bool CheckConformance(parser::ContextualMessages 
&messages, const Shape &left,
 return false;
   }
   for (int j{0}; j < n; ++j) {
-auto leftDim{ToInt64(left[j])};
-auto rightDim{ToInt64(right[j])};
-if (!leftDim || !rightDim) {
-  return false;
-}
-if (*leftDim != *rightDim) {
-  messages.Say("Dimension %1$d of %2$s has extent %3$jd, "
-   "but %4$s has extent %5$jd"_err_en_US,
-  j + 1, leftIs, *leftDim, rightIs, *rightDim);
+if (auto leftDim{ToInt64(left[j])}) {
+  if (auto rightDim{ToInt64(right[j])}) {
+if (*leftDim != *rightDim) {
+  messages.Say("Dimension %1$d of %2$s has extent %3$jd, "
+   

[llvm-branch-commits] [flang] 6aa3591 - [flang] Implement STORAGE_SIZE(), SIZEOF(), C_SIZEOF()

2020-12-15 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2020-12-15T17:26:20-08:00
New Revision: 6aa3591e98402418e110c506cdd488ed1e3021b6

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

LOG: [flang] Implement STORAGE_SIZE(), SIZEOF(), C_SIZEOF()

STORAGE_SIZE() is a standard inquiry intrinsic (size in bits
of an array element of the same type as the argument); SIZEOF()
is a common extension that returns the size in bytes of its
argument; C_SIZEOF() is a renaming of SIZEOF() in module ISO_C_BINDING.

STORAGE_SIZE() and SIZEOF() are implemented via rewrites to
expressions; these expressions will be constant when the necessary
type parameters and bounds are also constant.

Code to calculate the sizes of types (with and without alignment)
was isolated into Evaluate/type.* and /characteristics.*.
Code in Semantics/compute-offsets.* to calculate sizes and alignments
of derived types' scopes was exposed so that it can be called at type
instantiation time (earlier than before) so that these inquiry intrinsics
could be called from specification expressions.

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

Added: 
flang/test/Evaluate/folding17.f90

Modified: 
flang/docs/Extensions.md
flang/include/flang/Evaluate/characteristics.h
flang/include/flang/Evaluate/common.h
flang/include/flang/Evaluate/initial-image.h
flang/include/flang/Evaluate/type.h
flang/lib/Evaluate/characteristics.cpp
flang/lib/Evaluate/fold-designator.cpp
flang/lib/Evaluate/fold-integer.cpp
flang/lib/Evaluate/initial-image.cpp
flang/lib/Evaluate/intrinsics.cpp
flang/lib/Evaluate/shape.cpp
flang/lib/Evaluate/type.cpp
flang/lib/Semantics/compute-offsets.cpp
flang/lib/Semantics/compute-offsets.h
flang/lib/Semantics/data-to-inits.cpp
flang/lib/Semantics/semantics.cpp
flang/lib/Semantics/type.cpp
flang/module/__fortran_builtins.f90
flang/module/iso_c_binding.f90
flang/test/Semantics/resolve92.f90
flang/test/Semantics/typeinfo01.f90

Removed: 




diff  --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index d0b24969b41b..ea90db1aa77c 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -129,7 +129,7 @@ accepted if enabled by command-line options.
 * A `RETURN` statement may appear in a main program.
 * DATA statement initialization is allowed for procedure pointers outside
   structure constructors.
-* Nonstandard intrinsic functions: ISNAN
+* Nonstandard intrinsic functions: ISNAN, SIZEOF
 
 ### Extensions supported when enabled by options
 
@@ -144,10 +144,11 @@ accepted if enabled by command-line options.
   rule imposes an artificially small constraint in some cases
   where Fortran mandates that something have the default `INTEGER`
   type: specifically, the results of references to the intrinsic functions
-  `SIZE`, `LBOUND`, `UBOUND`, `SHAPE`, and the location reductions
+  `SIZE`, `STORAGE_SIZE`,`LBOUND`, `UBOUND`, `SHAPE`, and the location 
reductions
   `FINDLOC`, `MAXLOC`, and `MINLOC` in the absence of an explicit
   `KIND=` actual argument.  We return `INTEGER(KIND=8)` by default in
   these cases when the `-flarge-sizes` option is enabled.
+  `SIZEOF` and `C_SIZEOF` always return `INTEGER(KIND=8)`.
 * Treat each specification-part like is has `IMPLICIT NONE`
   [-fimplicit-none-type-always]
 * Ignore occurrences of `IMPLICIT NONE` and `IMPLICIT NONE(TYPE)`

diff  --git a/flang/include/flang/Evaluate/characteristics.h 
b/flang/include/flang/Evaluate/characteristics.h
index 5d140a642c86..c7ef66e800a9 100644
--- a/flang/include/flang/Evaluate/characteristics.h
+++ b/flang/include/flang/Evaluate/characteristics.h
@@ -149,7 +149,7 @@ class TypeAndShape {
   bool isElemental = false, bool thisIsDeferredShape = false,
   bool thatIsDeferredShape = false) const;
   std::optional> MeasureSizeInBytes(
-  FoldingContext * = nullptr) const;
+  FoldingContext &) const;
 
   llvm::raw_ostream &Dump(llvm::raw_ostream &) const;
 

diff  --git a/flang/include/flang/Evaluate/common.h 
b/flang/include/flang/Evaluate/common.h
index 5328f007bf40..284014fb5fb9 100644
--- a/flang/include/flang/Evaluate/common.h
+++ b/flang/include/flang/Evaluate/common.h
@@ -235,6 +235,7 @@ class FoldingContext {
   Rounding rounding() const { return rounding_; }
   bool flushSubnormalsToZero() const { return flushSubnormalsToZero_; }
   bool bigEndian() const { return bigEndian_; }
+  std::size_t maxAlignment() const { return maxAlignment_; }
   const semantics::DerivedTypeSpec *pdtInstance() const { return pdtInstance_; 
}
   const IntrinsicProcTable &intrinsics() const { return intrinsics_; }
 
@@ -257,7 +258,8 @@ class FoldingContext {
   const IntrinsicProcTable &intrinsics_;
   Rounding rounding_{defaultRounding};
   bool flushSubnormalsTo

[llvm-branch-commits] [flang] 0775131 - [flang] Fix crash in folding (#48437)

2020-12-16 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2020-12-16T07:55:44-08:00
New Revision: 07751310580fa5b7b94b6efa85d7964af0f699a6

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

LOG: [flang] Fix crash in folding (#48437)

Elemental intrinsic function folding was not taking the lower
bounds of constant array arguments into account; these lower bounds
can be distinct from 1 when named constants appear as arguments.

LLVM bugzilla #48437.

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

Added: 
flang/test/Evaluate/folding16.f90

Modified: 
flang/include/flang/Evaluate/constant.h
flang/lib/Evaluate/fold-implementation.h

Removed: 




diff  --git a/flang/include/flang/Evaluate/constant.h 
b/flang/include/flang/Evaluate/constant.h
index a9f6e87c9db0..89a5867722f7 100644
--- a/flang/include/flang/Evaluate/constant.h
+++ b/flang/include/flang/Evaluate/constant.h
@@ -140,7 +140,8 @@ template  class Constant : public 
ConstantBase {
 }
   }
 
-  // Apply subscripts.
+  // Apply subscripts.  An empty subscript list is allowed for
+  // a scalar constant.
   Element At(const ConstantSubscripts &) const;
 
   Constant Reshape(ConstantSubscripts &&) const;
@@ -177,7 +178,7 @@ class Constant> : 
public ConstantBounds {
 }
   }
 
-  // Apply subscripts
+  // Apply subscripts, if any.
   Scalar At(const ConstantSubscripts &) const;
 
   Constant Reshape(ConstantSubscripts &&) const;

diff  --git a/flang/lib/Evaluate/fold-implementation.h 
b/flang/lib/Evaluate/fold-implementation.h
index 4fa5f6a4c883..7232715600fd 100644
--- a/flang/lib/Evaluate/fold-implementation.h
+++ b/flang/lib/Evaluate/fold-implementation.h
@@ -443,9 +443,8 @@ Expr FoldElementalIntrinsicHelper(FoldingContext 
&context,
 // Compute the shape of the result based on shapes of arguments
 ConstantSubscripts shape;
 int rank{0};
-const ConstantSubscripts *shapes[sizeof...(TA)]{
-&std::get(*args)->shape()...};
-const int ranks[sizeof...(TA)]{std::get(*args)->Rank()...};
+const ConstantSubscripts *shapes[]{&std::get(*args)->shape()...};
+const int ranks[]{std::get(*args)->Rank()...};
 for (unsigned int i{0}; i < sizeof...(TA); ++i) {
   if (ranks[i] > 0) {
 if (rank == 0) {
@@ -470,20 +469,19 @@ Expr FoldElementalIntrinsicHelper(FoldingContext 
&context,
 std::vector> results;
 if (TotalElementCount(shape) > 0) {
   ConstantBounds bounds{shape};
-  ConstantSubscripts index(rank, 1);
+  ConstantSubscripts resultIndex(rank, 1);
+  ConstantSubscripts argIndex[]{std::get(*args)->lbounds()...};
   do {
 if constexpr (std::is_same_v,
   ScalarFuncWithContext>) {
-  results.emplace_back(func(context,
-  (ranks[I] ? std::get(*args)->At(index)
-: std::get(*args)->GetScalarValue().value())...));
+  results.emplace_back(
+  func(context, std::get(*args)->At(argIndex[I])...));
 } else if constexpr (std::is_same_v,
  ScalarFunc>) {
-  results.emplace_back(func(
-  (ranks[I] ? std::get(*args)->At(index)
-: std::get(*args)->GetScalarValue().value())...));
+  results.emplace_back(func(std::get(*args)->At(argIndex[I])...));
 }
-  } while (bounds.IncrementSubscripts(index));
+(std::get(*args)->IncrementSubscripts(argIndex[I]), ...);
+  } while (bounds.IncrementSubscripts(resultIndex));
 }
 // Build and return constant result
 if constexpr (TR::category == TypeCategory::Character) {
@@ -732,17 +730,11 @@ template  class ArrayConstructorFolder {
 Expr folded{Fold(context_, common::Clone(expr.value()))};
 if (const auto *c{UnwrapConstantValue(folded)}) {
   // Copy elements in Fortran array element order
-  ConstantSubscripts shape{c->shape()};
-  int rank{c->Rank()};
-  ConstantSubscripts index(GetRank(shape), 1);
-  for (std::size_t n{c->size()}; n-- > 0;) {
-elements_.emplace_back(c->At(index));
-for (int d{0}; d < rank; ++d) {
-  if (++index[d] <= shape[d]) {
-break;
-  }
-  index[d] = 1;
-}
+  if (c->size() > 0) {
+ConstantSubscripts index{c->lbounds()};
+do {
+  elements_.emplace_back(c->At(index));
+} while (c->IncrementSubscripts(index));
   }
   return true;
 } else {

diff  --git a/flang/test/Evaluate/folding16.f90 
b/flang/test/Evaluate/folding16.f90
new file mode 100644
index ..0918381040bf
--- /dev/null
+++ b/flang/test/Evaluate/folding16.f90
@@ -0,0 +1,8 @@
+! RUN: %S/test_folding.sh %s %t %f18
+! Ensure that lower bounds are accounted for in intrinsic folding;
+! this is a regression test f

[llvm-branch-commits] [flang] 4fede8b - [flang] Implement derived type description table encoding

2020-12-08 Thread peter klausler via llvm-branch-commits

Author: peter klausler
Date: 2020-12-08T10:26:58-08:00
New Revision: 4fede8bc8a015477f2a8feeb30a1d2a2e155106d

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

LOG: [flang] Implement derived type description table encoding

Define Fortran derived types that describe the characteristics
of derived types, and instantiations of parameterized derived
types, that are of relevance to the runtime language support
library.  Define a suite of corresponding C++ structure types
for the runtime library to use to interpret instances of the
descriptions.

Create instances of these description types in Semantics as
static initializers for compiler-created objects in the scopes
that define or instantiate user derived types.

Delete obsolete code from earlier attempts to package runtime
type information.

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

Added: 
flang/include/flang/Semantics/runtime-type-info.h
flang/lib/Semantics/runtime-type-info.cpp
flang/module/__fortran_type_info.f90
flang/runtime/derived.cpp
flang/runtime/derived.h
flang/runtime/type-info.h
flang/test/Semantics/typeinfo01.f90

Modified: 
flang/docs/RuntimeTypeInfo.md
flang/include/flang/Semantics/scope.h
flang/lib/Semantics/CMakeLists.txt
flang/lib/Semantics/compute-offsets.cpp
flang/lib/Semantics/semantics.cpp
flang/lib/Semantics/tools.cpp
flang/module/__fortran_builtins.f90
flang/module/iso_c_binding.f90
flang/runtime/CMakeLists.txt
flang/runtime/allocatable.cpp
flang/runtime/allocatable.h
flang/runtime/descriptor.cpp
flang/runtime/descriptor.h
flang/runtime/transformational.cpp
flang/tools/f18/CMakeLists.txt
flang/tools/f18/f18.cpp

Removed: 
flang/runtime/derived-type.cpp
flang/runtime/derived-type.h



diff  --git a/flang/docs/RuntimeTypeInfo.md b/flang/docs/RuntimeTypeInfo.md
index 2a511b208d0e..391b6ea5f88b 100644
--- a/flang/docs/RuntimeTypeInfo.md
+++ b/flang/docs/RuntimeTypeInfo.md
@@ -216,7 +216,7 @@ So the derived type information for a defined assignment 
needs to
 comprise:
 * address(es) of the subroutine
 * whether the first, second, or both arguments are descriptors
-* whether the subroutine is elemental
+* whether the subroutine is elemental (necessarily also impure)
 
 ### User defined derived type I/O
 

diff  --git a/flang/include/flang/Semantics/runtime-type-info.h 
b/flang/include/flang/Semantics/runtime-type-info.h
new file mode 100644
index ..71b5cac58eb5
--- /dev/null
+++ b/flang/include/flang/Semantics/runtime-type-info.h
@@ -0,0 +1,38 @@
+//===-- include/flang/Semantics/runtime-type-info.h -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+// BuildRuntimeDerivedTypeTables() translates the scopes of derived types
+// and parameterized derived type instantiations into the type descriptions
+// defined in module/__fortran_type_info.f90, packaging these descriptions
+// as static initializers for compiler-created objects.
+
+#ifndef FORTRAN_SEMANTICS_RUNTIME_TYPE_INFO_H_
+#define FORTRAN_SEMANTICS_RUNTIME_TYPE_INFO_H_
+
+#include 
+#include 
+
+namespace llvm {
+class raw_ostream;
+}
+
+namespace Fortran::semantics {
+class Scope;
+class SemanticsContext;
+class Symbol;
+
+struct RuntimeDerivedTypeTables {
+  Scope *schemata{nullptr};
+  std::set names;
+};
+
+RuntimeDerivedTypeTables BuildRuntimeDerivedTypeTables(SemanticsContext &);
+
+void Dump(llvm::raw_ostream &, const RuntimeDerivedTypeTables &);
+} // namespace Fortran::semantics
+#endif // FORTRAN_SEMANTICS_RUNTIME_TYPE_INFO_H_

diff  --git a/flang/include/flang/Semantics/scope.h 
b/flang/include/flang/Semantics/scope.h
index cae94dfac9e8..535e2bd50dce 100644
--- a/flang/include/flang/Semantics/scope.h
+++ b/flang/include/flang/Semantics/scope.h
@@ -197,8 +197,11 @@ class Scope {
 
   std::size_t size() const { return size_; }
   void set_size(std::size_t size) { size_ = size; }
-  std::size_t alignment() const { return alignment_; }
-  void set_alignment(std::size_t alignment) { alignment_ = alignment; }
+  std::optional alignment() const { return alignment_; }
+
+  void SetAlignment(std::size_t n) {
+alignment_ = std::max(alignment_.value_or(0), n);
+  }
 
   ImportKind GetImportKind() const;
   // Names appearing in IMPORT statements in this scope
@@ -242,11 +245,18 @@ class Scope {
 
   void InstantiateDerivedTypes(SemanticsContext &);
 
+  const Symbol *runtimeDerivedTypeDescription() const {
+return runtimeDerivedTypeDescription_;
+  }
+  void set_run

[llvm-branch-commits] [flang] [llvm] [Flang] Move runtime library files to FortranRuntime. NFC (PR #110298)

2024-10-09 Thread Peter Klausler via llvm-branch-commits

klausler wrote:

> While it would be possible to only have a `FortranRuntime/CMakeLists.txt` and 
> leave all the other files in `flang/`, I strongly believe this is a bad idea. 
> It is the norm for LLVM runtimes to have separate sources.

A Fortran compiler and its runtime are tightly coupled; the compiler can only 
work with this runtime, this runtime can only be used by this compiler, and 
they share common API definitions and data structures.

I don't mind if you move the sources and headers that are used *only* by the 
runtime into a new top-level directory, if you must.  But moving common headers 
and sources used by *both* the compiler and the runtime builds out of the 
compiler tree makes no sense to me.


https://github.com/llvm/llvm-project/pull/110298
___
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] [llvm] [Flang] Move runtime library files to FortranRuntime. NFC (PR #110298)

2024-10-08 Thread Peter Klausler via llvm-branch-commits

https://github.com/klausler commented:

This is a gigantic change and I don't understand why it's being made.  Why is 
so much code moving out of flang/ ?

https://github.com/llvm/llvm-project/pull/110298
___
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] [Flang] Split runtime headers in preparation for cross-compilation. NFC. (PR #112188)

2024-10-16 Thread Peter Klausler via llvm-branch-commits

klausler wrote:

On what targets would the size or member byte offsets in a descriptor differ?

https://github.com/llvm/llvm-project/pull/112188
___
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] [clang] [flang] [lld] [llvm] [Flang] LLVM_ENABLE_RUNTIMES=FortranRuntime (PR #110217)

2024-10-16 Thread Peter Klausler via llvm-branch-commits


@@ -11,8 +11,11 @@
 
 using namespace Fortran::parser::literals;
 
+

klausler wrote:

why are these new blank lines necessary?

https://github.com/llvm/llvm-project/pull/110217
___
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] [llvm] [Flang] Move runtime library files to clang-rt. NFC (PR #110298)

2024-10-16 Thread Peter Klausler via llvm-branch-commits


@@ -1,13 +1,13 @@
-//===-- include/flang/Runtime/CUDA/allocator.h --*- C++ 
-*-===//
+//===-- include/flang-rt/CufRuntime/allocator.h -*- C++ 
-*-===//

klausler wrote:

CUDA Fortran is the name of the language.  "cuf" is a filename extension.

https://github.com/llvm/llvm-project/pull/110298
___
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] [llvm] [Flang] Move runtime library files to FortranRuntime. NFC (PR #110298)

2024-10-10 Thread Peter Klausler via llvm-branch-commits

klausler wrote:

> > A Fortran compiler and its runtime are tightly coupled; the compiler can 
> > only work with this runtime, this runtime can only be used by this 
> > compiler, and they share common API definitions and data structures.
> 
> So is c C/C++ compiler and its runtime(s). There is still a need to support 
> cross-compilation and other build modes like 
> `FLANG_EXPERIMENTAL_CUDA_RUNTIME`.
> 
> > I don't mind if you move the sources and headers that are used _only_ by 
> > the runtime into a new top-level directory, if you must. But moving common 
> > headers and sources used by _both_ the compiler and the runtime builds out 
> > of the compiler tree makes no sense to me.
> 
> As said, this was the result of the RFC. I can update the PR and leave them 
> in `flang/`.

I am not in disagreement with your objectives.  But I think that you will be 
able to achieve them without scrambling the source locations so much that I 
won't be able to continue maintaining them upstream.

https://github.com/llvm/llvm-project/pull/110298
___
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] [flang] handle fir.call in AliasAnalysis::getModRef (PR #117164)

2024-11-21 Thread Peter Klausler via llvm-branch-commits

https://github.com/klausler approved this pull request.


https://github.com/llvm/llvm-project/pull/117164
___
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] [flang] handle fir.call in AliasAnalysis::getModRef (PR #117164)

2024-11-21 Thread Peter Klausler via llvm-branch-commits


@@ -0,0 +1,135 @@
+! RUN: bbc -emit-hlfir %s -o - | %python %S/gen_mod_ref_test.py | \
+! RUN:  fir-opt 
-pass-pipeline='builtin.module(func.func(test-fir-alias-analysis-modref))' \
+! RUN:  --mlir-disable-threading -o /dev/null 2>&1 | FileCheck %s
+
+! Test fir.call modref with internal procedures
+
+subroutine simple_modref_test(test_var_x)
+  implicit none
+  real :: test_var_x
+  call test_effect_internal()
+contains
+  subroutine test_effect_internal()
+test_var_x = 0.
+  end subroutine
+end subroutine
+! CHECK-LABEL: Testing : "_QPsimple_modref_test"
+! CHECK: test_effect_internal -> test_var_x#0: ModRef
+
+subroutine simple_nomodref_test(test_var_x)
+  implicit none
+  real :: test_var_x
+  call test_effect_internal()
+contains
+  subroutine test_effect_internal()
+call some_external()
+  end subroutine
+end subroutine
+! CHECK-LABEL: Testing : "_QPsimple_nomodref_test"
+! CHECK: test_effect_internal -> test_var_x#0: NoModRef
+
+! Test that effects on captured variable are propagated to associated variables
+! in associate construct.
+
+subroutine test_associate()
+  implicit none
+  real :: test_var_x(10)
+  associate (test_var_y=>test_var_x)
+test_var_y = test_effect_internal()

klausler wrote:

Is it necessary for this test that `test_var_y` be the LHS of the assignment 
statement?  You would expect ModRef even if it were not modified by/after the 
call.  Might be more clear if the result were stored elsewhere.

https://github.com/llvm/llvm-project/pull/117164
___
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] [flang] handle fir.call in AliasAnalysis::getModRef (PR #117164)

2024-11-21 Thread Peter Klausler via llvm-branch-commits


@@ -0,0 +1,68 @@
+! RUN: bbc -emit-hlfir %s -o - | %python %S/gen_mod_ref_test.py | \
+! RUN:  fir-opt 
-pass-pipeline='builtin.module(func.func(test-fir-alias-analysis-modref))' \
+! RUN:  --mlir-disable-threading -o /dev/null 2>&1 | FileCheck %s
+
+! Test fir.call modref for global variables (module, saved, common).
+
+
+module somemod
+  implicit none
+  real :: test_var_xmod
+  interface
+subroutine may_capture(x)
+  real, target :: x
+end subroutine
+  end interface
+end module
+
+subroutine test_module
+  use somemod, only : test_var_xmod
+  implicit none
+  call test_effect_external()
+end subroutine
+! CHECK-LABEL: Testing : "_QPtest_module"
+! CHECK: test_effect_external -> test_var_xmod#0: ModRef
+
+subroutine test_saved_local
+  use somemod, only : may_capture
+  implicit none
+  real, save :: test_var_xsaved
+  ! Capture is invalid after the call because test_var_xsaved does not have the
+  ! target attribute.
+  call may_capture(test_var_xsaved)
+  call test_effect_external()
+end subroutine
+! CHECK-LABEL: Testing : "_QPtest_saved_local"
+! CHECK: test_effect_external -> test_var_xsaved#0: NoModRef
+
+subroutine test_saved_target
+  use somemod, only : may_capture
+  implicit none
+  real, save, target :: test_var_target_xsaved

klausler wrote:

The 'save' attribute shouldn't matter; the result would be ModRef with and 
without `save`, yes?

https://github.com/llvm/llvm-project/pull/117164
___
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] [Flang] Introduce FortranSupport (PR #122069)

2025-01-10 Thread Peter Klausler via llvm-branch-commits

klausler wrote:

There's an implicit assumption here that either future runtime work won't 
occur, or won't need anything from Common that you're moving away into the new 
compiler-only directory.

Is this change required for your work that restructures the runtime builds?

https://github.com/llvm/llvm-project/pull/122069
___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits