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

    <tr>
        <th>Summary</th>
        <td>
            Standard C++20 modules are carrying 'pragma once' state.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            clang,
            clang:modules,
            clang:PCH
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          mizvekov
      </td>
    </tr>
</table>

<pre>
    Reproducer:
```
// RUN: %clang_cc1 -std=c++20 %t/A.cppm -emit-module-interface -o %t/A.pcm -verify
// RUN: %clang_cc1 -std=c++20 %t/B.cpp -fprebuilt-module-path=%t -fsyntax-only -verify

//--- foo.hpp
#pragma once
#define FOO

//--- A.cppm
// expected-no-diagnostics
module;
#include "foo.hpp"
export module A;

//--- B.cpp
// expected-no-diagnostics
import A;
#include "foo.hpp"
#ifndef FOO
#error 'pragma once' state should not be exported on module interface
#endif
```

The inclusion of "foo.hpp" in `B.cpp` is skipped, due to pragma once considering the inclusion from the imported `A.cppm` module.

Conventional header guards work as expected.

This is due to the fact we export the HeaderSearch table in standard C++ modules. There are old workarounds for clang modules where, during search for header inclusion, we prefer a header which has been included in another module, over the normal search order. Though this causes us to merge their header infos, and that's where pragma once state lives.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycVV-P4jYQ_zTmZZTIOPw5HvIArNA99aq763M1sSeJu44d2Q4s_fSVk8DC9iqtKiGQx-P5_ZmxwRB0Y4lKtj4wITr995le3ZkJwdYvCxxi63x5iy4qp67ld-q9U4Mkz4o94y-M79mGz59pKU5MnOD7H7-xYg9MrKVB2_wp5RKyEBUrXiQTByYOgqfdyMRpn8u-7yCjTsesc2owlGkbydcoCTL3ntfLDrIzeV1f_zfaIaFBVveeqkGbO2KPsWXFS8qCrA5XG_Etc9ZcPyA-4GZZBrVzedv3t3DRe2w6BGcl3WOKam0JTt--_brGZMCTInrrSUZSmXWZ0thYF6KWYcqZGLPicEfQVppBETAhboSEmHbprXc-wnQG9u-nPpAYffk8B92NZfefZJF2a6uofnBBFOS988DE9tE1sYUQMRKE1g1GgXURKoJJBylw9ibmPiTvBa3S9a_ncvz-2aZT0gxBOwuufqYK2gLb8MmJDQcdILzqvifFxBHUQBAdPFAF6WzQiry2DcSn0rV33RTqZtpsw-c-b_gsIH-kdnT2TDZqZ9FAS6jIQzOgVwEuzr8ChntD8mdJOiSmM72EWaOMcLlZNoa-jgV_EHrZQsRqdC_5bBV6Bcfplsy8Qg4_W_IE6AmcUSMB9G6wKkDtPIy37JYMl5Q7OTQ6ESaUlDjruPuSsi4EvaeaPOBt_9Jq2UKLASoiC_McqUQRrYst-RksnXdn8qMm63yH5gbnvCKfiLuhaSEmVyQOgQIMIRnTkW8ondMPtGoXUkm0CmKLkYntLOepzdM4Gn2mkC9UWahdscMFlcstX68F3yz5oi2LSlSrVaFQqN1KfKEaqd5WqERVK7Xa4EKXgosVXy63y92qKHguCQXiEpGvkW9VxVacOtQmN-bc5c43Cx3CQOX2y2q3XhisyIT5rR4bkC6XON5XxfwuhH_Ffz9-nR91X6baWTU0ga240SGGd7Soo6Hyx4eZEPze6DQOEr2_pi7_x63NF4M3ZRtjH9JfxPiSNDq2Q5VL1zFxSnDzT9Z79xfJ9CqPSgMTp1HsPwEAAP__mTIXlw">