<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/146362>146362</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [Flang] Preprocessor
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            flang
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          marikurz-amd
      </td>
    </tr>
</table>

<pre>
    I encountered 3 problems with the Flang preprocessor that give unexpected results that do not match the output of the Intel, GNU or Cray Fortran compilers. The following gives a reproducer and details for each of them. Each code snippet is compiled with:
```bash
flang -cpp -o demonstrator demonstrator.f90 && ./demonstrator
```
using
```
flang version 21.0.0git (https://github.com/llvm/llvm-project 532facc78e075255afde69f2d86f26e4d4dd4c7f)
Target: x86_64-unknown-linux-gnu
```

### Bug 1:

Compiling the following code:
```fortran
#define UNITY(k) 1_ ## k
PROGRAM REPRODUCER
WRITE(*,*) UNITY(4)
END PROGRAM REPRODUCER
```
causes a core dump in the preprocessing stage.
The expected output would be to just print a `1` to standard out (intel, Cray compiler) or throw an compilation error (GNU) since `1_` is not a parsable token. In no case it should crash.

### Bug 2:

The following demonstrator reveals a problem in a composite truth evaluation:

```fortran
PROGRAM Demonstrator
#if 1
WRITE(*,*) '`1` evaluates to TRUE'
#else
WRITE(*,*) '`1` evaluates to FALSE'
#endif
#if 2
WRITE(*,*) '`2` evaluates to TRUE'
#else
WRITE(*,*) '`2` evaluates to FALSE'
#endif
#if (1 && 2)
WRITE(*,*) '`1 && 2` evaluates to TRUE'
#else
WRITE(*,*) '`1 && 2` evaluates to FALSE'
#endif
END PROGRAM Demonstrator
```
The program outputs:
```
 `1` evaluates to TRUE
 `2` evaluates to TRUE
 `1 && 2` evaluates to FALSE
```
even though both values individually evaluate to `TRUE`.
The generated preprocessed file looks like (empty lines removed):
```fortran
#line "./demonstrator.f90" 1
 PROGRAM Demonstrator
      WRITE(*,*) '`1` evaluates to TRUE'
 WRITE(*,*) '`2` evaluates to TRUE'
      WRITE(*,*) '`1 && 2` evaluates to FALSE'
      END PROGRAM Demonstrator
```
The expected output (and the one obtained with Intel, GNU, Cray) would be:
```
 `1` evaluates to TRUE
 `2` evaluates to TRUE
 `1 && 2` evaluates to TRUE
```

### Bug 3:

The token `NUM` is not correctly replaced in the following example:
```fortran
#define NUM 1
PROGRAM Reproducer
IMPLICIT NONE
! This compiles
WRITE(*,*) &
NUM
! This does also compile
WRITE(*,*) (&
1,NUM )
! This does NOT compile
WRITE(*,*) (&
NUM )
END PROGRAM Reproducer
```
The preprocessed output yields (empty lines removed)
```fortran
#line "./demonstrator.f90" 2
      PROGRAM Reproducer
      IMPLICIT NONE
      WRITE(*,*) 1
      WRITE(*,*)( 1,1)
 WRITE(*,*)( NUM)
      END PROGRAM Reproducer
```
The final `NUM` does not get replaced due to the newline and the brackets, causing the compilation to fail, since `NUM` is not defined. Ifort, Gfortran and Cray-Fortran all compile this code and yield something like this in the output:
```
 1
 (1.,1.)
 1
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy8V19v4j4W_TTm5YoocSDAAw_82jJCmtKqS7Xap5GJbxIPxo5sh7b76Vd2CP-mMP-kHaGpwPb18b3nHF8za0WpEKdk-A8Z3vdY4yptpltmxKYx_-2zLe-tNf-YLgBVrhvl0CCHFGqj1xK3Ft6Eq8BVCHPJVAm1wdroHK3VBlzFHJRih9AofK8xd8jBoG2ks-0g16C0gy1zeRtFN65uHOgifFsoh5LQO_iyfAVt4M6wD5hr4wxTkOttLSQaG8GqQii0lPpNqDLsaIFBgMKbHA0wxYGjY0JaKLQBZHm132QbwYP_lmuOYJWoa3QgbBeehxOSdEbiGcni9rNmtiLxrAhH7ud1DX0NHLdaWWeY0-bsS1RMYiA0IzSDiND56dhpVBLPGitUefFbu8sOjRVaAU2iOIpL4YDQceVcbT02Oid0XgpXNeso11tC51Luuj_92ujvmDsYprRgeT4aYzwa0uGQFRyzSUH5OCtohgM-4HyQjwpCJySerZgp0ZF0Bu_j7Fs26Ddqo_Sb6kuhmvd-qZoLoP5D0_YD_zQlJPu0xbO7kExfHHdWKp_0i9wWbXnbYBwLoRBel4vVfwgdbwidQPIN9ntsSDx7fnn68jJ7hJeH55en-9e7hxcSz_79slg9EDomdEboXfh_cggyaI_3sLyHTxefHilnjQ1cyrVB4M22BqHCGY5E9-ewjpUY-aRVCAeq78n8phvJYY3gNHxvrIPaCOWAAcnihGSx_906pjgzYY2vrOiYHyjfUd0fI-jK6Dc4SIA5Tww0Rhu_9Mvy1c-zQuUYtvjm9xA2KI1BzYxla-nRbFBFsFCgNOTMIggHtgpgc8NsFX1WU3qo6bnozthvcIdM-rztfcJnjQW42gqH4EzjKsAdk01Afwj6CQ26It1fyIamooDkWrUJHXXp3W-D1id69fL64MdCAJQWfzfAfPb1XycRFBfFAQ29HYz-LZofA9xCQ-g46XyHtqS_ddLj1L_N2fVIn8M9leJllU_EuAqy06Vh27207IV3kHgG16veDl453n7lz6Cfb4Y79G6gm7KCtXYV-AVoQSgudoI3TMqPQxQfhGRx2C2LO7MoUaFh3i2OjoIcCiERpNYbC1Js0NcSt7X7ACkUWjC41Tvkvqg33NPPBULp5aXjLyRCaRDPtcRD-PeH0rq17ha9fr7pL1GrDfMbrLp0bELHvmMIDYlC0GvHhNq3AmdNSefQHmFn8_9HTu5n3byE0zPDDqbvoy5fH0-uhVwbg7mTH75pkixH3t1zR4fHd7at5a9c18vXx8Ctw_V6aMRIPFs8Pn9d3C1WsHxaBvA0gVV1bLjsdXPJSDzzuE8Wce2vZ2l1t_z66nEbICH0zgNsDfE80PJp9ctxjjHOOonTo_5oXicK31PtQ6Dk9oa-_1Tc9CCET7G1Q5fFuCHA5OYwoWPwmU1ayFfn-PK1M37Q6M3UFUIxecLbUC7P3BLdkbO8CS7reavwLWSo0_HasHyDznrF-q6u60VPWyinoWAiaPvQPZ3rpCU4j2DhaxFMYF-UsJG3gn73PmFSdmQC1xKct3hCzcHqLbrK4wgOH6bsRddy4xMjCUXw93rkcx3tU5mcTuvxacon6YT1cJqMhgmdDOM061XTfDJCOqR0nU6GoyEds2QSD4sEx2mcpkUx6okpjekwztI4Gfg1UZImeT4Z0VE-juMBG5FBjFsmZORfFZE2ZU9Y2-A0GWRpRnuSrVHa8JSkNLxaCKX-VWmm4RmybkpLBrEU1tljCCecDO_P8IAkw3t4PnlD9hojp7_3zCF0HmBZQud7ZLsp_V8AAAD__1wAZ_s">