Commit Graph

2618 Commits

Author SHA1 Message Date
vdonaldson 65791b2d0b [flang] Relax the implementation of constraint C1302. (flang-compiler/f18#805)
* Relax the implementation of constraint C1302.

When a list of format items can be unambiguously partitioned into individual items even though one or more otherwise required comma separators are omitted, generate a warning rather than an error.

Fixes flang-compiler/f18#703

Original-commit: flang-compiler/f18@79c0731137
Reviewed-on: https://github.com/flang-compiler/f18/pull/805
2019-11-05 10:11:36 -08:00
jeanPerier 9392f2a329 [flang] Merge pull request flang-compiler/f18#803 from flang-compiler/jpr-extremums
Implement MIN and MAX folding

Original-commit: flang-compiler/f18@b91bb50410
Reviewed-on: https://github.com/flang-compiler/f18/pull/803
2019-11-05 03:49:25 -08:00
Jean Perier 572de7c7b0 [flang] Implement MIN and MAX folding
* Use Extremum<T> FoldOperation to fold MIN and MAX
* Fix Extremum<T> FolOperation
    * For character, the length is the one of the longest argument.
      Define and use `CharacterUtils<Kind>::Resize` helper to do this.
    * For array of all types, Extremum<T> with Ordering::Less was
      behaving like Ordering::Greater. This is because the default
      `ApplyElementwise` for `Operation` was selected and it then
       called the Extremum<T> constructor without the ordering
       argument (which was an optional defaulted to Greater).
      Define a specific handler for Extremum<T> and make the ordering
      argument mandatory to prevent this kind of bug to pass
      f18 compilation in the futur.
* Fix intrinsic.cc for MIN and MAX
    * When provided with two arguments, `Match` was adding an empty
      3rd optional actual argument. Later code working on min and
      max was not expecting this and failing. The fix prevent this
      empty argument to be created by changing the initial size of
      `actualForDummy` to actually be the number of dummies that do
      not have `Optionality::Repeats`

This commit fixes issue flang-compiler/f18#677.

Original-commit: flang-compiler/f18@acb62f240b
Reviewed-on: https://github.com/flang-compiler/f18/pull/803
2019-11-05 02:54:12 -08:00
Peter Klausler f991c76521 [flang] Merge pull request flang-compiler/f18#812 from flang-compiler/pmk-call08
Enable and pass call08.f90

Original-commit: flang-compiler/f18@997f59f4a3
Reviewed-on: https://github.com/flang-compiler/f18/pull/812
2019-11-04 14:36:10 -08:00
peter klausler 2c89c31a59 [flang] Enable and pass call08.f90
Refine a check

Original-commit: flang-compiler/f18@bb96c195d4
Reviewed-on: https://github.com/flang-compiler/f18/pull/812
2019-11-04 14:35:36 -08:00
Tim Keith 5d76a55b01 [flang] Merge pull request flang-compiler/f18#810 from flang-compiler/tsk-defined-ops
Fix build error using clang

Original-commit: flang-compiler/f18@0879810f8b
Reviewed-on: https://github.com/flang-compiler/f18/pull/810
2019-11-04 12:58:48 -08:00
Tim Keith cf9059ae98 [flang] Fix build error using clang
Change `AllFortranNames()` to return a `std::vector` rather than a
`std::initialization_list`. The latter doesn't own its underlying
storage and so can't be returned as a value. clang detects this and
issues a warning.

Two tests in `resolve63.f90` behave differently with clang and require
further investigation.

Original-commit: flang-compiler/f18@1ed3a3cfee
Reviewed-on: https://github.com/flang-compiler/f18/pull/810
2019-11-04 12:05:51 -08:00
Tim Keith eaa0a45587 [flang] Merge pull request flang-compiler/f18#807 from flang-compiler/tsk-defined-ops
Resolve extended intrinsic operators

Original-commit: flang-compiler/f18@bcdf3fc6e5
Reviewed-on: https://github.com/flang-compiler/f18/pull/807
2019-11-04 10:56:12 -08:00
Tim Keith dce7f0aca0 [flang] Resolve extended intrinsic operators
Enhance `ArgumentAnalyzer` to do most of the work for this.
For each kind of operator that might have a user-defined form we follow
this process:
- analyze the arguments
- if the types and shapes match the intrinsic operator do the usual
  processing
- otherwise attempt to interpret it as a user-defined operator with
  `TryDefinedOp`

When we fail to resolve an operator, produce different errors depending
on whether there is a user-defined operator available or not.
If there is, report that neither user-defined nor intrinsic operator
worked. If there is not, describe the rules for the intrinsic operator.
In either case, include the type(s) of the operand(s).

Most of the uses of `ArgumentAnalyzer` are in helper functions that
apply to classes of operators.
For consistency, rename `BinaryOperationHelper` to `NumericBinaryOperator`
and `LogicalHelper` to `LogicalBinaryHelper` and introduce `NumericUnaryHelper`
for unary `+` and `-`.  `.NOT.` and `//` are not implemented in helpers.

Replace `success_` with `fatalErrors_` in `ArgumentAnalyzer` for
consistency with `ExpressionAnalyzer`.

Add `NumericOperator` and `LogicalOperator` enums to `Fortran.h` to go
with `RelationalOperator`. Add `AddFortran` functions to each to convert
to a Fortran source string. `RelationalOperator` also has `AllFortranNames`
because there are multiple names for each operator. This replaces
`LogicalOperator` in `expression.h` and the string representation of
the operators in `formatting.cc`.

Original-commit: flang-compiler/f18@3bb9d664e8
Reviewed-on: https://github.com/flang-compiler/f18/pull/807
2019-11-04 10:47:43 -08:00
Peter Klausler 41aa3bf7a4 [flang] Merge pull request flang-compiler/f18#806 from flang-compiler/pmk-calls
Enable and pass test call07.f90

Original-commit: flang-compiler/f18@ac3c69f29c
Reviewed-on: https://github.com/flang-compiler/f18/pull/806
2019-11-02 10:56:47 -07:00
peter klausler c14c2b9573 [flang] Enable and pass test call07.f90
Remove a std::move()

Final tweaks after testing and review

Original-commit: flang-compiler/f18@b3fe97b1a0
Reviewed-on: https://github.com/flang-compiler/f18/pull/806
2019-11-02 10:20:39 -07:00
Peter Klausler e91e7e4d95 [flang] Merge pull request flang-compiler/f18#804 from flang-compiler/pmk-c_str
Use c_str() rather than data() where NUL termination is assumed

Original-commit: flang-compiler/f18@97a0a0f78f
Reviewed-on: https://github.com/flang-compiler/f18/pull/804
2019-10-31 14:01:14 -07:00
peter klausler 7a681f46f8 [flang] Use c_str() rather than data() where NUL termination is assumed
Original-commit: flang-compiler/f18@5baed3c856
Reviewed-on: https://github.com/flang-compiler/f18/pull/804
2019-10-31 13:25:28 -07:00
Peter Klausler 0e74840ac2 [flang] Merge pull request flang-compiler/f18#801 from flang-compiler/pmk-call06
More semantic checks for calls & declarations

Original-commit: flang-compiler/f18@d29f634c35
Reviewed-on: https://github.com/flang-compiler/f18/pull/801
2019-10-30 15:51:17 -07:00
peter klausler 926da903f2 [flang] enable call06.f90 test
Relax checking when irrelevant due to INTENT(IN)

Add and pass call14.f90 test on VALUE

Allow ASYNCHRONOUS/VOLATILE to apply to host/USE associated entities, add tests

Pass call06

Check C827 & C828, fix tests

Original-commit: flang-compiler/f18@df6cb83794
Reviewed-on: https://github.com/flang-compiler/f18/pull/801
2019-10-30 15:50:28 -07:00
Peter Klausler e46a5a4c10 [flang] Merge pull request flang-compiler/f18#788 from flang-compiler/pmk-ref-wrap
Create `common::Reference<>`, use it to replace non-nullable pointers

Original-commit: flang-compiler/f18@0857755e59
Reviewed-on: https://github.com/flang-compiler/f18/pull/788
2019-10-29 12:45:13 -07:00
peter klausler afd39cd49c [flang] Use reference_wrapper in vectors and sets
Convert some CharBlock references to values

Replace more pointers with reference wrappers

Restore object references that were converted to value semantics in an earlier commit

Use Reference<> in Scope

Fix new component iterator

Document pitfall that bit me

final tweaks before rebasing and merging

Rebasing

Original-commit: flang-compiler/f18@87874af934
Reviewed-on: https://github.com/flang-compiler/f18/pull/788
2019-10-29 12:32:28 -07:00
Jinxin Yang 2839cb3835 [flang] Throw error in case of missing listed test
Original-commit: flang-compiler/f18@dabc0ba0e0
2019-10-28 12:58:52 -07:00
Jinxin Yang 004a4c577b [flang] [OpenMP] Test Infra update to support OpenMP symbol tests
During the symbol tests, OpenMP directives (start with "!$omp")
line needs to be saved for 1.f90 and 2.f90. Also moved "OPTIONS:"
detection to common.sh as "$USER_OPTIONS"

Original-commit: flang-compiler/f18@7d4e8e8ad5
2019-10-28 12:58:15 -07:00
Jinxin Yang eeda304160 [flang] [OpenMP] address more comments
The major changes are:
  1) changed the non-nullptr type to reference
  2) changed ResolveOmpObject to use std::visit
  3) the rest of the changes are about positions and naming

Original-commit: flang-compiler/f18@93debe59f3
2019-10-25 15:16:20 -07:00
Jinxin Yang 8143b8980d [flang] [OpenMP] adjust for PR#753 `OmpObject` parse tree change
PR#753 changed the `OmpObject` to be:

```
struct OmpObject {
  UNION_CLASS_BOILERPLATE(OmpObject);
  std::variant<Designator, /*common block*/ Name> u;
};
```

This commit adjust the logic flow for `ResolveOmpObject` based on
the above parse tree change.

For an `OmpObject`,
```
if (Designator) {
  if (DataRef.Name) {
    // Resolve Names
  } else {
    // ResolveDesignator
    // AnalyzeExpr
    if (Designator.Substring) {
      // Error
    }
    // other checks like StructureComponent, ArrayElement, etc.
  }
} else if (Name) {
  // Resolve COMMON block
}
```

Original-commit: flang-compiler/f18@e5c1b92c15
2019-10-25 15:16:20 -07:00
Jinxin Yang 0554d39d74 [flang] [OpenMP] Implement no-multiple-appearance rule for DSA Clauses
DSA stands for Data-Sharing Attribute. This work is part of the
Name Resolution for OpenMP framework (data-refs on clauses part)

Based on 2.15.3: A list item that specifies a given variable may
not appear in more than one clause on the same directive, except that
a variable may be specified in both firstprivate and lastprivate clauses.

Through a temporary `std::set` of `const Symbol *` to keep track of
all the symbols on a certain OpenMP directive, we can determine whether
a variable `Name` (or `Symbol`, more accurately) has already appeared on
another DSA clause already, with the exception of FIRSTPRIVATE clause
and LASTPRIVATE clause. This rule applies to `/COMMON block/` also and
the source provenance shows on error message points to the `Name` between
slashes.

Added two more tests and changed some existing tests to accommodate
this commit. I intend to keep the `omp-clause-validity01.f90` test to
do the validity checks only.

Original-commit: flang-compiler/f18@0d7828c21e
2019-10-25 15:16:20 -07:00
Jinxin Yang df51352d72 [flang] [OpenMP] avoid creating new symbol for common block
Original-commit: flang-compiler/f18@ba2cceb4a2
2019-10-25 15:16:20 -07:00
Jinxin Yang f3961579ac [flang] [OpenMP] add common block example
Original-commit: flang-compiler/f18@a4c923e848
2019-10-25 15:16:20 -07:00
Jinxin Yang 4ca8c5dc5c [flang] [OpenMP] OmpVisitor framework for Name Resolution
This is a preliminary framework to do the name resolution for
data references on the OpenMP clauses. Unlike data references
in the OpenMP region, clauses determining the data-sharing or
data-mapping attributes are straightforward and the resolution
process could be extended to do the name resolution in the OpenMP
region. It is hard to determine what kind of checks can be done
in this visitor and what checks should be done later after name
resolution. But the guide line is that `After the completion of
this phase, every Name corresponds to a Symbol with proper OpenMP
attribute(s) determined unless an error occurred.`

1. Take data-sharing clauses as example, create new symbol for
variable that require private access within the OpenMP region.
Declare the entity implicitly if necessary. The new symbol has
`HostAssocDetails`, which is mentioned in the `OpenMP-semantics.md`.

2. For `Shared` or `ThreadPrivate`, no symbol needs to be created.
OpenMP attribute Flag `OmpThreadprivate` needs to be marked for
`Threadprivate` because the `threadprivate` attribute remains the
same whenever these variables are referenced in the program.
`Names` in `Shared` clause need to be resolved to associate the
symbols in the clause enclosing scope (contains the OpenMP directive)
but `OmpShared` does not need to be marked. Declare the entity
implicitly if necessary.

3. For `COMMON block`, when a named common block appears in a list,
it has the same meaning as if every explicit member of the common
block appeared in the list. Also, a common block name specified in
a data-sharing attribute clause must be declared to be a common
block in the same scoping unit in which the data-sharing attribute
clause appears. So, if a named common block appears on a `PRIVATE`
clause, all its members should have new symbols created within the
OpenMP region (scope). For later Semantic checks and CG, a new
symbol is also created for common block name with `HostAssocDetails`.

There are many things are still on the TODO list:
- Better error/warning messages with directive/clause source provenance

- Resolve variables referenced in the OpenMP region, for example,
  `private(tt%a)` is not allowed but `tt%a = 1` is allowed in the
  OpenMP region and a private version of `tt` maybe created for
  the region. The functions created in the `OmpVisitor` should be
  able to handle the name resolution on the statement too (more
  data structures may be introduced). This is a big portion and may
  require some interface changes to distinguish a reference is on
  `OpenMP directive/clause` or `statements within OpenMP region`.

- Same data reference appears on multiple data-sharing clauses.

- Take association into consideration for example Pointer association,
  `ASSOCIATE` construct, and etc.

- Handle `Array Sections` and `Array or Structure Element`.

- Handle all the name resolution for directives/clauses that have
  `parser::Name`.

- More tests

Original-commit: flang-compiler/f18@b2ea520885
2019-10-25 15:16:20 -07:00
psteinfeld f6a5a3f45e [flang] Merge pull request flang-compiler/f18#789 from flang-compiler/ps-issue781
Changes to check for calls to PURE procedure components

Original-commit: flang-compiler/f18@3a0457adee
Reviewed-on: https://github.com/flang-compiler/f18/pull/789
2019-10-25 10:26:58 -07:00
Pete Steinfeld 31cc851629 [flang] Changes to check for calls to PURE procedure components
This addresses issue flang-compiler/f18#781.  I changed my test to create a PURE procedure
component by using an interface as suggested by Peter and Jean.  I then
enhanced the function IsPureProcedure() in tools.cc to cover this case
and updated the code in check-do.cc to perform the test.

Original-commit: flang-compiler/f18@5df56a217d
Reviewed-on: https://github.com/flang-compiler/f18/pull/789
2019-10-25 09:48:20 -07:00
Peter Klausler a11446f6c3 [flang] Merge pull request flang-compiler/f18#792 from flang-compiler/pmk-call05-again
pmk-call05 again

Original-commit: flang-compiler/f18@2b88ae44db
Reviewed-on: https://github.com/flang-compiler/f18/pull/792
2019-10-25 09:01:51 -07:00
peter klausler 7c44a2011b [flang] Restore a review comment response
Original-commit: flang-compiler/f18@d9673df31c
Reviewed-on: https://github.com/flang-compiler/f18/pull/792
2019-10-25 09:01:27 -07:00
peter klausler 715f2c0d86 [flang] Fix duplicate messages
Original-commit: flang-compiler/f18@6528c5f31b
Reviewed-on: https://github.com/flang-compiler/f18/pull/792
Tree-same-pre-rewrite: false
2019-10-24 16:38:09 -07:00
peter klausler 5f270940ff [flang] Restored changes from pmk-call05
Original-commit: flang-compiler/f18@bb9c12eec3
Reviewed-on: https://github.com/flang-compiler/f18/pull/792
Tree-same-pre-rewrite: false
2019-10-24 16:08:06 -07:00
Peter Klausler bf102b76e4 [flang] Merge pull request flang-compiler/f18#790 from flang-compiler/pmk-expr-msgs
Add contextualizing interfaces to ExpressionAnalyzer and ContextualMe…

Original-commit: flang-compiler/f18@85136c45ef
Reviewed-on: https://github.com/flang-compiler/f18/pull/790
2019-10-24 15:03:26 -07:00
peter klausler b5eec67fc4 [flang] Add contextualizing interfaces to ExpressionAnalyzer and ContextualMessages
Original-commit: flang-compiler/f18@30a004d7b1
Reviewed-on: https://github.com/flang-compiler/f18/pull/790
2019-10-24 14:55:25 -07:00
psteinfeld f39e704606 [flang] Merge pull request flang-compiler/f18#780 from flang-compiler/ps-move_alloc
Changes to disallow image control statements in DO CONCURRENT

Original-commit: flang-compiler/f18@adc753c306
Reviewed-on: https://github.com/flang-compiler/f18/pull/780
2019-10-23 14:17:30 -07:00
Pete Steinfeld 196fec7d85 [flang] # This is a combination of 2 commits.
# This is the 1st commit message:

Changes to disallow image control statements in DO CONCURRENT

Most of these changes were already implemented.  The last remaining part was to check for calls to move_alloc with coarray arguments.  This set of changes implements that.  I also bundled other changes.  Specifically:

All of the code to detect image control statements was moved from check-do.cc to tools.cc so that it could be used by other semantic checking functions.

I added location information to the error messages for all DO semantics checks to highlight either the DO loop associated with the error or other relevant source locations.

I cleaned up the error messages associated with DO semantics so that they have more consistent grammar and punctuation.

I eliminated redundant checks for IEEE_GET_FLAG and IEEE_HALTING_MODE.

I removed the redundant test doconcurrent08.f90.

Responses to pull request comments

I changed the interface to determine whether a statement is an image control
statement to use an ExecutableConstruct as its input.  Since
ExecutableConstruct contains types that do not have source location information
(ChangeTeamConstruct and CriticalConstruct), I also created a function to get
the source location of an ExecutableConstruct.  Also, some ExecutableConstructs
are image control statements because they reference coarrays.  I wanted to tell
users that the reason that an ALLOCATE statement (for example) is an image
control statement because it references a coarray.  To make this happen, I
added another function to return a message for image control statements that
reference coarrays.

I also cleaned up the references to the standard in comments in check-do.cc to
briefly describe the contents of those constraints.

I also added messages that refer to the enclosing DO CONCURRENT statement for
error messages where appropriate.

Responses to pull request comments

The biggest change was to redo the implementation of "IsImageControlStmt()" to
use a custom visitor that strips off the "common::Indirection<...>" prefix of
most of the image control statement types and also takes advantage of
"common::HasMember<...>" to determine if a variant contains a specific type.

Spelling error.

# This is the commit message flang-compiler/f18#2:

More refactoring in response to comments on the pull request.

Original-commit: flang-compiler/f18@3f0a0155b3
Reviewed-on: https://github.com/flang-compiler/f18/pull/780
2019-10-23 14:06:16 -07:00
Tim Keith f0cef274b9 [flang] Merge pull request flang-compiler/f18#786 from flang-compiler/tsk-defined-ops
Resolve defined operators to specifics

Original-commit: flang-compiler/f18@b10a60d2d6
Reviewed-on: https://github.com/flang-compiler/f18/pull/786
2019-10-23 06:31:27 -07:00
Tim Keith 373f7489ef [flang] Resolve defined operators to specifics
Most of these changes involve moving code around so that it case be
used for `DefinedUnary` and `DefinedBinary`. The functional changes are
in the `Analyze` member functions for those cases where the arguments
are now analyzed, the generic is resolved, and a `FunctionRef` is
created.

Add `ArgumentAnalyzer` to handling building of the `ActualArguments`
of a call. This allows the code to be shared with the defined unary
and defined binary cases. Move `AnalyzeActualArgument` and
`AnalyzeActualArgument` into that class (renaming both to `Analyze`).

Create an overload of `GetCalleeAndArguments` for the `Name` case so it
can be used for defined ops where we don't have a `ProcedureDesignator`.

Move `IsGenericDefinedOp` to `tools.h` to make it available to the
new code.

We were using `semantics::CheckExplicitInterface` to resolve a generic
interface to a specific procedure based on actual arguments. The problem
with that is that it performs too many checks. We just want to get the
right specific; there may be errors reported later during call analysis.

To fix this, add a new function, `CheckInterfaceForGeneric`, to perform
this check. It shares code with `CheckExplicitInterface`, but it passes
in a null scope to indicate that the full set of checks aren't
necessary in `CheckExplicitInterfaceArg`. Instead we lift the call to
`TypeAndShape::IsCompatibleWith` out of `CheckExplicitDataArg`, and skip
the latter when there is no scope.

Original-commit: flang-compiler/f18@fff2d1580f
Reviewed-on: https://github.com/flang-compiler/f18/pull/786
2019-10-23 06:25:51 -07:00
Peter Klausler 2a7af74b3e [flang] Merge pull request flang-compiler/f18#787 from flang-compiler/pmk-fix
Fix bad new test, and fix detection of test failures in that test too

Original-commit: flang-compiler/f18@7c32e67571
Reviewed-on: https://github.com/flang-compiler/f18/pull/787
2019-10-22 15:57:00 -07:00
peter klausler 7aea2f6cb9 [flang] Fix bad new test, and fix detection of test failures in that test too
Original-commit: flang-compiler/f18@38ec2a879b
Reviewed-on: https://github.com/flang-compiler/f18/pull/787
2019-10-22 15:28:26 -07:00
Peter Klausler 26334a9e1b [flang] Merge pull request flang-compiler/f18#785 from flang-compiler/pmk-int128
Implement uint128_t for impoverished build environments

Original-commit: flang-compiler/f18@6ea37f7cf5
Reviewed-on: https://github.com/flang-compiler/f18/pull/785
2019-10-22 13:18:59 -07:00
peter klausler f3ae44f645 [flang] Work around a gcc-7.2 specific build bug by recoding with a better approach
Original-commit: flang-compiler/f18@bc2b4015b0
Reviewed-on: https://github.com/flang-compiler/f18/pull/785
2019-10-22 10:34:05 -07:00
peter klausler 4f761d601e [flang] Fix clang performance problem with new code
Original-commit: flang-compiler/f18@b70cac3ba8
Reviewed-on: https://github.com/flang-compiler/f18/pull/785
Tree-same-pre-rewrite: false
2019-10-21 14:58:26 -07:00
peter klausler dc4fac5634 [flang] Testing and debugging
Original-commit: flang-compiler/f18@3fa2e55bef
Reviewed-on: https://github.com/flang-compiler/f18/pull/785
Tree-same-pre-rewrite: false
2019-10-21 14:58:25 -07:00
peter klausler 2348d593ae [flang] Add software uint128_t (debugging incomplete)
Original-commit: flang-compiler/f18@5be270e604
Reviewed-on: https://github.com/flang-compiler/f18/pull/785
Tree-same-pre-rewrite: false
2019-10-21 14:58:25 -07:00
Peter Klausler 416d9ced52 [flang] Merge pull request flang-compiler/f18#783 from flang-compiler/pmk-call04
Add call semantics checks, pass call04.f90 test

Original-commit: flang-compiler/f18@2555860e77
Reviewed-on: https://github.com/flang-compiler/f18/pull/783
2019-10-21 13:21:48 -07:00
peter klausler 9cf827d297 [flang] Pass call04
Original-commit: flang-compiler/f18@5a44837804
Reviewed-on: https://github.com/flang-compiler/f18/pull/783
2019-10-21 12:44:17 -07:00
peter klausler e6bf9526e1 [flang] most call04 checks
Original-commit: flang-compiler/f18@65289a66d1
Reviewed-on: https://github.com/flang-compiler/f18/pull/783
Tree-same-pre-rewrite: false
2019-10-21 12:44:17 -07:00
Peter Klausler a1839554bf [flang] Merge pull request flang-compiler/f18#782 from flang-compiler/pmk-calls
Further semantics checks for procedure references

Original-commit: flang-compiler/f18@fbdd919a14
Reviewed-on: https://github.com/flang-compiler/f18/pull/782
2019-10-21 12:43:13 -07:00
peter klausler 15f38e2d67 [flang] Use component iterators in check-call.cc
Original-commit: flang-compiler/f18@e78db8907f
Reviewed-on: https://github.com/flang-compiler/f18/pull/782
2019-10-17 15:29:26 -07:00
peter klausler 5f8817bdac [flang] Address remaining initial comments
Original-commit: flang-compiler/f18@acd307c91f
Reviewed-on: https://github.com/flang-compiler/f18/pull/782
Tree-same-pre-rewrite: false
2019-10-17 12:10:33 -07:00