[cfe-dev] Modules: redefinition errors from explicit submodules

Bruno Cardoso Lopes via cfe-dev cfe-dev at lists.llvm.org
Tue Mar 21 14:53:51 PDT 2017


(+cfe-dev & others for extra input)

Hi Richard,

Unlike C++/ObjC++, we don't currently merge struct (and others)
definitions in C/ObjC. This is fine since we are not even talking
about local submodules visibility. However, consider the following:

- Consider module F, and its submodule F.Private.
- The submodule is marked explicit and should only contain private
headers that won't be visible unless by explicit include or @import
Module.Private.
- A private header NS.h defines 'struct NS {...}'
- A TU x.c also defines 'struct NS {...}' but it never includes NS.h.
The private module is built though, since module.private.modulemap
builds any submodule of what has been previously defined in
module.modulemap
- BOOM -> error: redefinition of 'NS'

Turns out that this example does not error in C++ because we merge
this definition if one of the candidates is hidden, but only in C++.
Shouldn't we behave the same in C/ObjC for the case where: (a) the
definition comes from a module marked 'explicit' and (b) there's no
@import / direct include in the TU at the point of re-definition?

Am I missing something or is it just that we never really implemented
this? What's your general opinion on this?

Here's the reduced testcase:

== F.framework/Headers/F.h
// F.h
== F.framework/Modules/module.modulemap
framework module F [extern_c] [system] {
  umbrella header "F.h"
  module * {
      export *
  }
  export *
}
== F.framework/Modules/module.private.modulemap
explicit module F.Private [system] {
  explicit module NS {
      header "NS.h"
      export *
  }
  export *
}
== F.framework/PrivateHeaders/NS.h
struct NS {
  int a;
  int b;
};
== x.c
#include "F/F.h"
//@import F.Private;
struct NS {
  int a;
  int b;
};

$ clang x.c -c -fmodules -F`pwd`

-- 
Bruno Cardoso Lopes
http://www.brunocardoso.cc



More information about the cfe-dev mailing list