<div dir="ltr">On Thu, Apr 4, 2013 at 6:45 AM, Rafael Espíndola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">> Add hasExternalLinkageUncached back with the test that Richard provided, but<br>

> keep the call at the current location.<br>
<br>
</div>I was trying to figure out what these hidden decl are. My<br>
understanding so far is:<br></blockquote><div><br></div><div style>Since you asked for comments on this bit...</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

* Modules are handle liked a unit, so loading a module semantically<br>
loads all sub modules, but they can be hidden.<br>
* An external variable/function in a hidden sub module still conflicts<br>
with an external variable/function in the TU importing the module. Is<br>
this is some form of ODR for modules?<br></blockquote><div><br></div><div style>Yes, the model which Doug and I discussed on IRC is this: when you import any part of a module, all of that module is included in your program, but only the part you actually imported is included in your translation unit [*]. So we can perform ODR checking against external-linkage hidden declarations, and we do so where possible.</div>
<div style><br></div><div style><div>My desire when discussing the model for submodules was that they be as much like #includes as we can reasonably get (with the proviso that importing any part of a module implies that the program as a whole contains all of the module).</div>
</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
* An internal variable/function in a hidden sub module doesn't<br>
interfere with the TU importing the module.<br></blockquote><div><br></div><div style>Right, by the above model, things in unimported submodules aren't part of the current translation unit, so internal linkage functions aren't relevant.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
* An external variable/function in a hidden sub module doesn't<br>
interfere with a hidden variable/function in the TU importing the<br>
module.<br></blockquote><div><br></div><div style>There are no hidden variables/functions in the importing TU. But an external-linkage hidden declaration doesn't interfere with internal linkage declarations in the TU, in the same way that an external-linkage declaration in a header which you haven't #included doesn't interfere with an internal linkage declaration (even if you know that header is included somewhere else in the program).</div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
This last item I find surprising if the objective is really some form<br>
of ODR. In particular, I would expect an error for f1 and v1 in<br>
Modules/linkage-merge.m. I would also expect an error in the peculiar<br>
case Richard mentioned last night:<br>
<br>
hidden sub module:<br>
-------------------------<br>
extern const int foo;<br>
------------------------<br>
TU importing the module:<br>
----------------------------<br>
const int foo = 32;<br>
-------------------------<br>
<br>
but currently they are not linked and we accept it.<br></blockquote><div><br></div><div style>These are separate entities (one is an external linkage entity, not part of the current TU, and the other is an internal linkage entity within the TU). Therefore the ODR does not apply. C++ core issue 426 tightens up the rules here (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#426">http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#426</a>), but even then it's still OK to have the same name and scope be used for an internal linkage entity and an external linkage entity if they're not declared in the same TU.</div>
<div><br></div><div><br></div><div style>[*] We need a more finessed way of saying this than just that unimported submodules are not part of the TU. Consider this:</div><div style><br></div><div style>module m.a:</div><div style>
  int f();</div><div style>  static int n = f();</div><div style>module m.b:</div><div style>  import m.a;</div><div style>  int *p = &n;</div><div style>x.cc:</div><div style>  import m.b; // do not import m.a</div><div style>
  int *x = p;</div><div style>y.cc:</div><div style>  import m.b;</div><div style>  int *y = p;</div><div style>main.cc:</div><div style>  extern int *x, *y;</div><div style>  int main() { return x == y; }<br></div><div style>
<br></div><div style>Presumably main() here should return 0, because x.cc and y.cc each get their own copy of ::n, but that requires the hidden declaration ::n to be part of the respective TUs. (We'd also presumably expect to see f() being run twice on startup.) And if we allow this, we can have two internal linkage symbols of the same name in the same scope which are not merged because they come from unimported submodules of different modules -- and yet we still have to emit code for both of them.</div>
</div></div></div>