Issue 139297
Summary Preprocessor inconsistency of compiler directives in macros
Labels bug, flang
Assignees
Reporter Meinersbur
    Flang fails to parse its own preprocessor output:
```sh
$ flang -E -Xflang -fno-reformat ~/src/llvm-project/flang/module/ieee_arithmetic.f90 -o - | flang - -fsyntax-only
error: Could not parse -
standard input:105:3: error: expected declaration construct
  elemental logical function ieee_is_finite_a2(x); real(2), intent(in) :: x; !dir$ ignore_tkr(d) x; end function ieee_is_finite_a2; elemental logical function ieee_is_finite_a3(x); real(3), intent(in) :: x; !dir$ ignore_tkr(d) x; end function ieee_is_finite_a3; elemental logical function ieee_is_finite_a4(x); real(4), intent(in) :: x; !dir$ ignore_tkr(d) x; end function ieee_is_finite_a4; elemental logical function ieee_is_finite_a8(x); real(8), intent(in) :: x; !dir$ ignore_tkr(d) x; end function ieee_is_finite_a8;
    ^
standard input:2:1: in the context: specification part
  use __fortran_ieee_exceptions
  ^
standard input:1:1: in the context: module
 module ieee_arithmetic
  ^
standard input:106:5: error: expected end of statement
  end interface ieee_is_finite
      ^
[...]
```

The failing like comes from
https://github.com/llvm/llvm-project/blob/a6385a87a2e5537f0790494ebe8bb4c3cc9506b9/flang/module/ieee_arithmetic.f90#L342

which after preprocessing expands to
```f90
elemental logical function ieee_is_finite_a2(x); real(2), intent(in) :: x; !dir$ ignore_tkr(d) x; end function ieee_is_finite_a2;
```

Flang manages to parse this if the the `!dir$` is within a macro, but not if expanded. The error comes from interpreting `!` as a comment line, which removes everything following on the same line from the cooked character stream, including `end function ieee_is_finite_a2;`, which causes the error. My initial diagnosis was that `Prescanner::IsCompilerDirectiveSentinel` does not recognize `!` as a potential start of a compiler directive, but this does not fix the inconcistencies:

```f90
module m
 contains

! Directive inside macro on same line; works
#define MACRO(X)  subroutine func1(X);    real(2) :: X; !dir$ ignore_tkr(d) X; end subroutine func1;
MACRO(foo)

! Same subroutine, but after preprocessor expansion (-e -fno-reformat); syntax error
  ! subroutine func2(foo);  real(2) :: foo; !dir$ ignore_tkr(d) foo; end subroutine func2;

! Parses with line wrap before !dir$
  subroutine func3(foo);     real(2) :: foo;
  !dir$ ignore_tkr(d) foo; end subroutine func3;

! Parses with line wrap after !dir$, but swallows the directive
 subroutine func4(foo); real(2) :: foo; !dir$ ignore_tkr(d) foo;
  end subroutine func4;

end module
```
which results in the following parse tree (`-fdebug-unparse` without func2):
```f90
MODULE m
CONTAINS
 SUBROUTINE func1 (foo)
  REAL(KIND=2_4) foo
  !DIR$ IGNORE_TKR (d) foo
 END SUBROUTINE func1
 SUBROUTINE func3 (foo)
  REAL(KIND=2_4) foo
  !DIR$ IGNORE_TKR (d) foo
 END SUBROUTINE func3
 SUBROUTINE func4 (foo)
 REAL(KIND=2_4) foo
 END SUBROUTINE func4
END MODULE
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to