llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.07k stars 11.08k forks source link

clang module in deferred parse region gives very confusing diagnostics #56312

Open urnathan opened 2 years ago

urnathan commented 2 years ago

This is derived from boost's define_if_constexpr header. That (and its sibling undef_if_constexp) are non-idempotent headers that surround conditional use of if constexpr by defining an IF_CONSTEXPR macro. Sadly these #include <boost/config.hpp> to find information about whether if-constexpr is to be used. It's desirable to have config.hpp as a header module (and weirdly I couldn't just make it textual and its includes modules).

// hdr.hh
#include "config.hh"

// cc1 -triple x86_64-linux-gnu -emit-header-module -fmodule-name=testing -std=c++20 -fmodules -fimplicit-module-maps -fno-builtin-module-map -emit-module -fmodules-embed-all-files -fno-implicit-modules -x c++-header -I . -o x module.modulemap

struct F
{
  // OK
#include "on.hh"
#include "off.hh"
  void Fn () {
    // Not OK
#include "on.hh"
    if (true) {}
#include "off.hh"
  }
};
// config.hh
#ifndef _CONFIG_HH
#define _CONFIG_HH
#endif
// on.hh
#include "config.hh" // comment this to fix boost

#ifndef _ON_OFF
#define CONSTEXPR if constexpr
#else
#undef CONSTEXPR
#endif
// off.hh
#define _ON_OFF
#include "on.hh"
#undef _ON_OFF
// module.modulemap
module "testing" {
  explicit module bits {
    header "config.hh"
    header "hdr.hh"
    textual header "on.hh"
    textual header "off.hh"
    export *
  }
}

The redundant include warnings are clueful, but I didn't get them from our build -- I guess disabled? But look at that weird parse error about if (true)! that's really confusing. AFAICT it's because that's in a deferred parse region. The prior on/off includes inside the definition of F are fine.

A somewhat blunter diagnostic about trying to load an importable header not at namespace scope might be more helpful. Yes, I realize the in-struct case works, but seems still like code-smell to me, and of course won't work in C++20 modules land.

(130)devvm5975:47> ../llvm/trunk/build/bin/clang-15 -cc1 -triple x86_64-linux-gnu -emit-header-module -fmodule-name=testing -std=c++20 -fmodules -fimplicit-module-maps -fno-builtin-module-map -emit-module -fmodules-embed-all-files -fno-implicit-modules -x c++-header -I . -o x module.modulemap
While building module 'testing':
In file included from <module-includes>:2:
In file included from ./hdr.hh:8:
./on.hh:1:1: error: redundant #include of module 'testing.bits' appears within 'F' [-Wmodules-import-nested-redundant]
#include "config.hh"
^
./hdr.hh:5:1: note: 'F' begins here
struct F
^
While building module 'testing':
In file included from <module-includes>:2:
In file included from ./hdr.hh:9:
In file included from ./off.hh:2:
./on.hh:1:1: error: redundant #include of module 'testing.bits' appears within 'F' [-Wmodules-import-nested-redundant]
#include "config.hh"
^
./hdr.hh:5:1: note: 'F' begins here
struct F
^
While building module 'testing':
In file included from <module-includes>:2:
In file included from ./hdr.hh:12:
./on.hh:1:1: error: redundant #include of module 'testing.bits' appears within 'F' [-Wmodules-import-nested-redundant]
#include "config.hh"
^
./hdr.hh:5:1: note: 'F' begins here
struct F
^
./hdr.hh:13:5: error: expected member name or ';' after declaration specifiers
    if (true) {}
    ^
While building module 'testing':
In file included from <module-includes>:2:
In file included from ./hdr.hh:14:
In file included from ./off.hh:2:
./on.hh:1:1: error: redundant #include of module 'testing.bits' appears within 'F' [-Wmodules-import-nested-redundant]
#include "config.hh"
^
./hdr.hh:5:1: note: 'F' begins here
struct F
^
./hdr.hh:10:15: error: expected '}'
  void Fn () {
              ^
./hdr.hh:10:14: note: to match this '{'
  void Fn () {
             ^
./hdr.hh:15:4: error: expected ';' after struct
  }
   ^
   ;
./hdr.hh:16:1: error: extraneous closing brace ('}')
};
^
8 errors generated.
(1)devvm5975:47>
llvmbot commented 2 years ago

@llvm/issue-subscribers-clang-modules