From 299628e2cbcf1576deb8b451348ef87ef355d3d8 Mon Sep 17 00:00:00 2001 From: Tim Keith Date: Tue, 19 Mar 2019 13:38:54 -0700 Subject: [PATCH] [flang] Strip whitespace from parse tree source locations Parse tree nodes have `source` fields that map the node back to a range in the cooked input stream. These are used for names and to locate error messages. This change strips spaces from the beginning and end of those source ranges before they are saved. This fixes two problems: 1. For a statement like this: `generic :: operator(+) => ...`, the name of the symbol we want to create is "operator(+)" but the parser was including the following space in the CharBlock it captured. 2. Error messages referring to parts of expressions sometimes included extra spaces in the source locations. For example: ``` t.f90:9:29: error: subscripts may be applied only to an object or component integer, parameter :: b = a(1) + 1 ^^^^^ t.f90:4:8: error: operands to LOGICAL operation must be LOGICAL i = j .or. k ^^^^^^^ ``` Original-commit: flang-compiler/f18@fa14297967b7852fd130790eca4186f259f0a1f2 Reviewed-on: https://github.com/flang-compiler/f18/pull/343 Tree-same-pre-rewrite: false --- flang/lib/parser/basic-parsers.h | 9 ++++++++- flang/test/semantics/modfile07.f90 | 4 ++-- flang/test/semantics/resolve11.f90 | 2 +- flang/test/semantics/resolve13.f90 | 2 +- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/flang/lib/parser/basic-parsers.h b/flang/lib/parser/basic-parsers.h index 6a1167e..d70b8d6 100644 --- a/flang/lib/parser/basic-parsers.h +++ b/flang/lib/parser/basic-parsers.h @@ -1343,7 +1343,14 @@ public: const char *start{state.GetLocation()}; auto result{parser_.Parse(state)}; if (result.has_value()) { - result->source = CharBlock{start, state.GetLocation()}; + const char *end{state.GetLocation()}; + if (start < end && start[0] == ' ') { + ++start; + } + if (start < end && end[-1] == ' ') { + --end; + } + result->source = CharBlock{start, end}; } return result; } diff --git a/flang/test/semantics/modfile07.f90 b/flang/test/semantics/modfile07.f90 index 2560e28..23cf4e9 100644 --- a/flang/test/semantics/modfile07.f90 +++ b/flang/test/semantics/modfile07.f90 @@ -22,14 +22,14 @@ module m complex x,y end function end interface - generic :: operator(+)=> s1, s2 + generic :: operator ( + ) => s1, s2 interface bar procedure :: s1 procedure :: s2 procedure :: s3 procedure :: s4 end interface - interface operator(.bar.) + interface operator( .bar.) procedure :: s1 procedure :: s2 procedure :: s3 diff --git a/flang/test/semantics/resolve11.f90 b/flang/test/semantics/resolve11.f90 index 1f41368..a5e4985 100644 --- a/flang/test/semantics/resolve11.f90 +++ b/flang/test/semantics/resolve11.f90 @@ -33,7 +33,7 @@ module m2 end interface public :: operator(+) !ERROR: The accessibility of 'operator(+)' has already been specified as PUBLIC - private :: operator(+) + private :: operator(+) , ifoo contains integer function ifoo(x, y) integer, intent(in) :: x, y diff --git a/flang/test/semantics/resolve13.f90 b/flang/test/semantics/resolve13.f90 index 7e314bd..13f962c 100644 --- a/flang/test/semantics/resolve13.f90 +++ b/flang/test/semantics/resolve13.f90 @@ -56,7 +56,7 @@ use m1, only: my_x => z use m1, only: operator(.foo.) !ERROR: Operator '.bar.' not found in module 'm1' use m1, only: operator(.bar.) -use m1, only: operator(-) +use m1, only: operator(-) , ifoo !ERROR: 'operator(+)' not found in module 'm1' use m1, only: operator(+) -- 2.7.4