Skip to content

Preprocessor inconsistency of compiler directives in macros #139297

Open
@Meinersbur

Description

@Meinersbur

Flang fails to parse its own preprocessor output:

$ 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

!dir$ ignore_tkr(d) x; \

which after preprocessing expands to

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:

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):

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions