<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
  <meta charset="utf-8" />
  <meta name="generator" content="pandoc" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  <title>P1815R2: Translation-unit-local entities</title>
  <style>
    code{white-space: pre-wrap;}
    span.smallcaps{font-variant: small-caps;}
    span.underline{text-decoration: underline;}
    div.column{display: inline-block; vertical-align: top; width: 50%;}
    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
    ul.task-list{list-style: none;}
    pre > code.sourceCode { white-space: pre; position: relative; }
    pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
    pre > code.sourceCode > span:empty { height: 1.2em; }
    code.sourceCode > span { color: inherit; text-decoration: inherit; }
    div.sourceCode { margin: 1em 0; }
    pre.sourceCode { margin: 0; }
    @media screen {
    div.sourceCode { overflow: auto; }
    }
    @media print {
    pre > code.sourceCode { white-space: pre-wrap; }
    pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
    }
    pre.numberSource code
      { counter-reset: source-line 0; }
    pre.numberSource code > span
      { position: relative; left: -4em; counter-increment: source-line; }
    pre.numberSource code > span > a:first-child::before
      { content: counter(source-line);
        position: relative; left: -1em; text-align: right; vertical-align: baseline;
        border: none; display: inline-block;
        -webkit-touch-callout: none; -webkit-user-select: none;
        -khtml-user-select: none; -moz-user-select: none;
        -ms-user-select: none; user-select: none;
        padding: 0 4px; width: 4em;
        color: #aaaaaa;
      }
    pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
    div.sourceCode
      {   }
    @media screen {
    pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
    }
    code span.al { color: #ff0000; font-weight: bold; } /* Alert */
    code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
    code span.at { color: #7d9029; } /* Attribute */
    code span.bn { color: #40a070; } /* BaseN */
    code span.bu { } /* BuiltIn */
    code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
    code span.ch { color: #4070a0; } /* Char */
    code span.cn { color: #880000; } /* Constant */
    code span.co { color: #60a0b0; font-style: italic; } /* Comment */
    code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
    code span.do { color: #ba2121; font-style: italic; } /* Documentation */
    code span.dt { color: #902000; } /* DataType */
    code span.dv { color: #40a070; } /* DecVal */
    code span.er { color: #ff0000; font-weight: bold; } /* Error */
    code span.ex { } /* Extension */
    code span.fl { color: #40a070; } /* Float */
    code span.fu { color: #06287e; } /* Function */
    code span.im { } /* Import */
    code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
    code span.kw { color: #007020; font-weight: bold; } /* Keyword */
    code span.op { color: #666666; } /* Operator */
    code span.ot { color: #007020; } /* Other */
    code span.pp { color: #bc7a00; } /* Preprocessor */
    code span.sc { color: #4070a0; } /* SpecialChar */
    code span.ss { color: #bb6688; } /* SpecialString */
    code span.st { color: #4070a0; } /* String */
    code span.va { color: #19177c; } /* Variable */
    code span.vs { color: #4070a0; } /* VerbatimString */
    code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  </style>
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
  <style type="text/css">
  div.del, section.del { background: #fcd; }
  div.ins, section.ins { background: #bfa; }
  s, .del { background: #ff8888; }
  u, .ins { background: #88ff88; }
  /* from https://stackoverflow.com/a/32456613 */
  div > blockquote, body > blockquote {
      display: list-item;
      list-style-type: "- ";
  }
  pre {
  		margin-left: 1.2em;
  }
  .tony {
    border-collapse: collapse;
  }
  .tony > tbody > tr {
    vertical-align: top;
  }
  tr.hr, tr.hr {
    border-bottom: thin solid #60a0b0;  /* relies on collapse */
  }
  </style>
</head>
<body>
<header id="title-block-header">
<h1 class="title">P1815R2: Translation-unit-local entities<!-- -*- c++-md -*- --></h1>
</header>
<p><em>Audience</em>: CWG<br />
S. Davis Herring &lt;<a href="mailto:herring@lanl.gov" class="email">herring@lanl.gov</a>&gt;<br />
Los Alamos National Laboratory<br />
February 14, 2020</p>
<h1 id="history">History</h1>
<p>r2:</p>
<ul>
<li>Rebased onto N4849</li>
<li>Added changes specified by P2003R1
<ul>
<li>Allowed non-exposure references and local references to entities internal to header units</li>
<li>Allowed multiple realizations of a header unit</li>
<li>Prohibited in header units entities that cannot be defined in multiple translation units</li>
</ul></li>
<li>Added changes specified by P1884R0</li>
<li>Allowed exposures in private module fragments</li>
<li>Excluded use of constant-initialized references as an exposure</li>
<li>Prohibited redundant implicit instantiations of inline variables</li>
<li>Combined explicit instantiation wording and adjusted it for modules and member classes</li>
<li>Defined TU-local for values for exposures via constant expressions</li>
<li>Made unnamed types without an associated key be TU-local</li>
<li>Corrected requirements for definitions of inline functions/variables and templates</li>
<li>Covered missing kinds of “naming”</li>
<li>Simplified naming to be independent of translation units</li>
<li>Clarified (uninstantiated) inline function template case</li>
<li>Removed leftover deduction guide wording</li>
<li>Fixed overbroad [dcl.inline] note</li>
<li>Added motivation for TU-locality of classes without linkage</li>
<li>Fixed paragraph markers</li>
</ul>
<p>r1:</p>
<ul>
<li>Added example and fixed existing example</li>
<li>Added NB comment reference</li>
<li>Moved deduction guide wording to correct place</li>
<li>Restored basic permission for <code>static</code> in header units</li>
<li>Made more template specializations TU-local</li>
<li>Clarified type specifiers</li>
<li>Clarified TU-locality and usage of unnamed types</li>
</ul>
<h1 id="introduction">Introduction</h1>
<p>This paper is a replacement for <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1498r1.html">P1498R1</a> that includes the wording promised for it and thereby addresses <a href="https://github.com/cplusplus/nbballot/issues/34">US35</a>. While its general principle of forbidding exposure of internal-linkage constructs to other translation units is followed, this paper presents rules that differ for consistency, especially for templates. It also includes wording (which would conflict) for <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2020/p2003r1.html">P2003R1</a> and <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2020/p1884r0.pdf">P1884R0</a> and thereby addresses <a href="https://github.com/cplusplus/nbballot/issues/132">US133</a> and <a href="https://github.com/cplusplus/nbballot/issues/133">US134</a> (and, in a sense, <a href="https://github.com/cplusplus/nbballot/issues/35">US36</a>).</p>
<p>The function to which a dependent name refers cannot, of course, be determined merely from the template declaration that contains it. <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1347r1.pdf">P1347R1</a> proposed forbidding such a call that selects an internal-linkage function via overload resolution. Such overload resolution can in general require undesirably extensive analysis of otherwise-local declarations, so P1498R1 goes further and (with a single exception for certain constants) forbids any use of such a name in a context where code generation might occur for another translation unit. (This includes, for example, the return type of a non-template function with more than internal linkage; while it need not be mangled, it is accessible via <code>decltype</code> anywhere the function is.) We can consider such overload sets to be <em>poisoned</em> by their mere inclusion of an unusable candidate. The unusable candidate might be a template; templates whose declarations involve internal entities must themselves be internal to avoid needing to perform template argument deduction for them (even if the resulting specialization might not involve any internal types). (As a reminder, <code>export</code> is irrelevant here because the client translation unit might be in the same module.)</p>
<p>However, ADL considers a set of functions and function templates which itself cannot be known until instantiation. It is therefore impossible to reliably preclude poisoned overload sets by any reasonable restriction on (non-internal) templates.</p>
<p>This paper therefore merely proscribes the external use of internal entities and of poisoned overload sets, and does so for the definition of a template only during instantiation. Even a template that unambiguously calls an internal function can have non-internal linkage so long as the only specializations used in other translation units are those generated by an explicit specialization or instantiation. (Implicit instantiation of a template does not preclude other implicit instantiations and so does not allow usage from other translation units.) Local/anonymous classes (including closure types) are internal based on where they are defined, regardless of whether they (attempt to) use internal entities, partly to avoid any need to include in an invented name for the class an internal-linkage name introduced by the enclosing definition.</p>
<p>It would of course be possible to discard certain overload resolution candidates before deciding whether an overload set is poisoned. Most simply, any that do not support the number of arguments given in the call could be excluded. More sophisticated analysis might exclude functions or function templates with parameter types not convertible from a (non-dependent) argument type, as well as those whose constraints are known not to be met for any instantiation. Preferring future flexibility and compatibility over invention, this paper simply poisons overload sets unconditionally.</p>
<h1 id="wording">Wording</h1>
<p>Relative to N4849.</p>
<p>Change [basic.def.odr]/10:</p>
<blockquote>
<p>Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement ([stmt.if]); no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see [class.default.ctor], [class.copy.ctor], [class.dtor], and [class.copy.assign]). <s>A definition of an inline function or variable shall be reachable in every translation unit in which it is odr-used outside of a discarded statement.</s> [<em>Example</em>:</p>
<p>[…]</p>
<p>— <em>end example</em>]</p>
</blockquote>
<p>Insert before [basic.def.odr]/11:</p>
<div class="ins">
<blockquote>
<p>A <em>definition domain</em> is a <em>private-module-fragment</em> or the portion of a translation unit before its <em>private-module-fragment</em> (if any). A definition of an inline function or variable shall be reachable from the end of every definition domain in which it is odr-used outside of a discarded statement.</p>
</blockquote>
</div>
<p>Change [basic.lookup.argdep]/5:</p>
<blockquote>
<p>[<em>Example</em>:<br />
Translation unit #1:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb1-1"><a href="#cb1-1"></a><span class="kw">export</span> module M;</span>
<span id="cb1-2"><a href="#cb1-2"></a><span class="kw">namespace</span> R {</span>
<span id="cb1-3"><a href="#cb1-3"></a>  <span class="kw">export</span> <span class="kw">struct</span> X {};</span>
<span id="cb1-4"><a href="#cb1-4"></a>  <span class="kw">export</span> <span class="dt">void</span> f(X);</span>
<span id="cb1-5"><a href="#cb1-5"></a>}</span>
<span id="cb1-6"><a href="#cb1-6"></a><span class="kw">namespace</span> S {</span>
<span id="cb1-7"><a href="#cb1-7"></a>  <span class="kw">export</span> <span class="dt">void</span> f(R::X, R::X);</span>
<span id="cb1-8"><a href="#cb1-8"></a>}</span></code></pre></div>
<p>Translation unit #2:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">export</span> module N;</span>
<span id="cb2-2"><a href="#cb2-2"></a>import M;</span>
<span id="cb2-3"><a href="#cb2-3"></a><span class="kw">export</span> R::X make();</span>
<span id="cb2-4"><a href="#cb2-4"></a><span class="kw">namespace</span> R { <span class="at">static</span> <span class="dt">int</span> g(X); }</span>
<span id="cb2-5"><a href="#cb2-5"></a><span class="kw">export</span> <span class="kw">template</span>&lt;<span class="kw">typename</span> T, <span class="kw">typename</span> U&gt; <span class="dt">void</span> apply(T t, U u) {</span>
<span id="cb2-6"><a href="#cb2-6"></a>  f(t, u);</span>
<span id="cb2-7"><a href="#cb2-7"></a>  g(t);</span>
<span id="cb2-8"><a href="#cb2-8"></a>}</span></code></pre></div>
Translation unit #3:
<pre class="cpp">
module Q;
import N;
namespace S {
  struct Z { template<typename T> operator T(); };
}
void test() {
  auto x = make();              // OK, decltype(x) is R::X in module M
  R::f(x);                      // error: R and R::f are not visible here
  f(x);                         // OK, calls R::f from interface of M
  f(x, S::Z());                 // error: S::f in module M not considered
                                // even though S is an associated namespace
  apply(x, S::Z());             // <s>OK,</s><u>error:</u> S::f is visible in instantiation context, <s>and</s><u>but</u>
                                // R::g <s>is visible even though it </s>has internal linkage<u> and cannot be used outside TU #2</u>
}
</pre>
<p>— <em>end example</em>]</p>
</blockquote>
<p>Append paragraphs to [basic.link]:</p>
<div class="ins">
<blockquote>
<p>A declaration <em>D</em> <em>names</em> an entity <em>E</em> if</p>
<ol type="1">
<li><em>D</em> contains a <em>lambda-expression</em> whose closure type is <em>E</em>,</li>
<li><em>E</em> is not a function or function template and <em>D</em> contains an <em>id-expression</em>, <em>type-specifier</em>, <em>nested-name-specifier</em>, <em>template-name</em>, or <em>concept-name</em> denoting <em>E</em>, or</li>
<li><em>E</em> is a function or function template and <em>D</em> contains an expression that names <em>E</em> ([basic.def.odr]) or an <em>id-expression</em> that refers to a set of overloads that contains <em>E</em>. [<em>Note</em>: Non-dependent names in an instantiated declaration do not refer to a set of overloads ([temp.nondep]). — <em>end note</em>]</li>
</ol>
</blockquote>
<blockquote>
<p>A declaration is an <em>exposure</em> if it either names a TU-local entity (defined below), ignoring</p>
<ol type="1">
<li>the <em>function-body</em> for a non-inline function or function template (but not the deduced return type for a (possibly instantiated) definition of a function with a declared return type that uses a placeholder type ([dcl.spec.auto])),</li>
<li>the <em>initializer</em> for a variable or variable template (but not the variable’s type),</li>
<li>friend declarations in a class definition, and</li>
<li>any reference to a non-volatile const object or reference with internal or no linkage initialized with a constant expression that is not an odr-use ([basic.def.odr]),</li>
</ol>
<p>or defines a constexpr variable initialized to a TU-local value (defined below). [<em>Note</em>: An inline function template can be an exposure even though explicit specializations of it might be usable in other translation units. — <em>end note</em>]</p>
</blockquote>
<blockquote>
<p>An entity is <em>TU-local</em> if it is</p>
<ol type="1">
<li>a type, function, variable, or template that
<ol type="1">
<li>has a name with internal linkage, or</li>
<li>does not have a name with linkage and is declared, or introduced by a <em>lambda-expression</em>, within the definition of a TU-local entity,</li>
</ol></li>
<li>a type with no name that is defined outside a <em>class-specifier</em>, function body, or <em>initializer</em> or is introduced by a <em>defining-type-specifier</em> that is used to declare only TU-local entities,</li>
<li>a specialization of a TU-local template,</li>
<li>a specialization of a template with any TU-local template argument, or</li>
<li>a specialization of a template whose (possibly instantiated) declaration is an exposure. [<em>Note</em>: The specialization might have been implicitly or explicitly instantiated. — <em>end note</em>]</li>
</ol>
</blockquote>
<blockquote>
<p>A value or object is TU-local if either</p>
<ol type="1">
<li>it is, or is a pointer to, a TU-local function or the object associated with a TU-local variable,</li>
<li>it is an object of class or array type and any of its subobjects or any of the objects or functions to which its non-static data members of reference type refer is TU-local and is usable in constant expressions.</li>
</ol>
</blockquote>
<blockquote>
<p>If a (possibly instantiated) declaration of, or a deduction guide for, a non-TU-local entity in a module interface unit (outside the <em>private-module-fragment</em>, if any) or module partition ([module.unit]) is an exposure, the program is ill-formed. Such a declaration in any other context is deprecated ([depr.local]).</p>
</blockquote>
<blockquote>
<p>If a declaration that appears in one translation unit names a TU-local entity declared in another translation unit that is not a header unit, the program is ill-formed. A declaration instantiated for a template specialization ([temp.spec]) appears at the point of instantiation of the specialization ([temp.point]).</p>
</blockquote>
<blockquote>
<p>[<em>Example</em>:<br />
Translation unit #1:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">export</span> module A;</span>
<span id="cb3-2"><a href="#cb3-2"></a><span class="at">static</span> <span class="dt">void</span> f() {}</span>
<span id="cb3-3"><a href="#cb3-3"></a><span class="kw">inline</span> <span class="dt">void</span> it() {f();} <span class="co">// error: is an exposure of f</span></span>
<span id="cb3-4"><a href="#cb3-4"></a><span class="at">static</span> <span class="kw">inline</span> <span class="dt">void</span> its() {f();} <span class="co">// OK</span></span>
<span id="cb3-5"><a href="#cb3-5"></a><span class="kw">template</span>&lt;<span class="dt">int</span>&gt; <span class="dt">void</span> g() {its();} <span class="co">// OK</span></span>
<span id="cb3-6"><a href="#cb3-6"></a><span class="kw">template</span> <span class="dt">void</span> g&lt;<span class="dv">0</span>&gt;();</span>
<span id="cb3-7"><a href="#cb3-7"></a></span>
<span id="cb3-8"><a href="#cb3-8"></a><span class="kw">decltype</span>(f) *fp;  <span class="co">// error: f (though not its type) is TU-local</span></span>
<span id="cb3-9"><a href="#cb3-9"></a><span class="kw">auto</span> &amp;fr=f;                     <span class="co">// OK</span></span>
<span id="cb3-10"><a href="#cb3-10"></a><span class="kw">constexpr</span> <span class="kw">auto</span> &amp;fr2=fr;         <span class="co">// error: is an exposure of f</span></span>
<span id="cb3-11"><a href="#cb3-11"></a><span class="kw">constexpr</span> <span class="at">static</span> <span class="kw">auto</span> fp2=fr;   <span class="co">// OK</span></span>
<span id="cb3-12"><a href="#cb3-12"></a></span>
<span id="cb3-13"><a href="#cb3-13"></a><span class="kw">struct</span> S {<span class="dt">void</span> (&amp;ref)();} s{f};             <span class="co">// OK: value is TU-local</span></span>
<span id="cb3-14"><a href="#cb3-14"></a><span class="kw">constexpr</span> <span class="at">extern</span> <span class="kw">struct</span> W {S &amp;s;} wrap{s};  <span class="co">// OK: value is not TU-local</span></span>
<span id="cb3-15"><a href="#cb3-15"></a></span>
<span id="cb3-16"><a href="#cb3-16"></a><span class="at">static</span> <span class="kw">auto</span> x=[]{f();};  <span class="co">// OK</span></span>
<span id="cb3-17"><a href="#cb3-17"></a><span class="kw">auto</span> x2=x;               <span class="co">// error: the closure type is TU-local</span></span>
<span id="cb3-18"><a href="#cb3-18"></a><span class="dt">int</span> y=([]{f();}(),<span class="dv">0</span>);    <span class="co">// error: the closure type is not TU-local</span></span>
<span id="cb3-19"><a href="#cb3-19"></a><span class="dt">int</span> y2=(x,<span class="dv">0</span>);            <span class="co">// OK</span></span>
<span id="cb3-20"><a href="#cb3-20"></a></span>
<span id="cb3-21"><a href="#cb3-21"></a><span class="kw">namespace</span> N {</span>
<span id="cb3-22"><a href="#cb3-22"></a>  <span class="kw">struct</span> A {};</span>
<span id="cb3-23"><a href="#cb3-23"></a>  <span class="dt">void</span> adl(A);</span>
<span id="cb3-24"><a href="#cb3-24"></a>  <span class="at">static</span> <span class="dt">void</span> adl(<span class="dt">int</span>);</span>
<span id="cb3-25"><a href="#cb3-25"></a>}</span>
<span id="cb3-26"><a href="#cb3-26"></a><span class="dt">void</span> adl(<span class="dt">double</span>);</span>
<span id="cb3-27"><a href="#cb3-27"></a></span>
<span id="cb3-28"><a href="#cb3-28"></a><span class="kw">inline</span> <span class="dt">void</span> h(<span class="kw">auto</span> x) {adl(x);} <span class="co">// OK, but a specialization might be an exposure</span></span></code></pre></div>
<p>Translation unit #2:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb4-1"><a href="#cb4-1"></a>module A;</span>
<span id="cb4-2"><a href="#cb4-2"></a><span class="dt">void</span> other() {</span>
<span id="cb4-3"><a href="#cb4-3"></a>  g&lt;<span class="dv">0</span>&gt;();  <span class="co">// OK: specialization is explicitly instantiated</span></span>
<span id="cb4-4"><a href="#cb4-4"></a>  g&lt;<span class="dv">1</span>&gt;();  <span class="co">// error: instantiation uses TU-local its</span></span>
<span id="cb4-5"><a href="#cb4-5"></a>  h(N::A{});  <span class="co">// error: overload set contains TU-local N::adl(int)</span></span>
<span id="cb4-6"><a href="#cb4-6"></a>  h(<span class="dv">0</span>);  <span class="co">// OK: calls adl(double)</span></span>
<span id="cb4-7"><a href="#cb4-7"></a>  adl(N::A{});  <span class="co">// OK: N::adl(int) not found; calls N::adl(N::A)</span></span>
<span id="cb4-8"><a href="#cb4-8"></a>  fr();                   <span class="co">// OK: calls f</span></span>
<span id="cb4-9"><a href="#cb4-9"></a>  <span class="kw">constexpr</span> <span class="kw">auto</span> ptr=fr;  <span class="co">// error: fr is not usable in constant expressions here</span></span>
<span id="cb4-10"><a href="#cb4-10"></a>}</span></code></pre></div>
<p>— <em>end example</em>]</p>
</blockquote>
</div>
<p>Insert before [expr.const]/3:</p>
<div class="ins">
<blockquote>
<p>A variable is <em>potentially-constant</em> if it is constexpr or it has reference or const-qualified integral or enumeration type.</p>
</blockquote>
</div>
<p>Change [expr.const]/3:</p>
<blockquote>
<p>A <u>constant-initialized potentially-constant </u>variable is <em>usable in constant expressions</em> <s>after</s><u>at a point <em>P</em> if</u> its initializing declaration<u> <em>D</em></u> is <s>encountered if</s><u>reachable from <em>P</em> and</u></p>
<ol type="1">
<li>it is <s>a </s>constexpr<s> variable</s>,<s> or it is a constant-initialized variable of reference type or of const-qualified integral or enumeration type</s></li>
<li><u>it is not initialized to a TU-local value, or</u></li>
<li><u><em>P</em> is in the same translation unit as <em>D</em></u>.</li>
</ol>
<p>An object or reference is <em>usable in constant expressions</em> if it is</p>
<p>[…]</p>
</blockquote>
<p>Change [dcl.inline]/2:</p>
<blockquote>
<p>A function declaration ([dcl.fct], [class.mfct], [class.friend]) with an <code>inline</code> specifier declares an <em>inline function</em>. The inline specifier indicates to the implementation that inline substitution of the function body at the point of call is to be preferred to the usual function call mechanism. An implementation is not required to perform this inline substitution at the point of call; however, even if this inline substitution is omitted, the other rules for inline functions specified in this subclause shall still be respected. [<em>Note</em>: The <code>inline</code> keyword has no effect on the linkage of a function. <u>In certain cases, an inline function cannot use names with internal linkage; see [basic.link].</u> — <em>end note</em>]</p>
</blockquote>
<p>Change and split [dcl.inline]/6:</p>
<blockquote>
<p><s>If an inline function or variable is odr-used in a translation unit, a definition of it shall be reachable from the end of that translation unit, and it shall have exactly the same definition in every such translation unit ([basic.def.odr]). [<em>Note</em>: A call to the inline function or a use of the inline variable may be encountered before its definition appears in the translation unit. — <em>end note</em>]</s> If a definition of a function or variable is reachable at the point of its first declaration as inline, the program is ill-formed. If a function or variable with external or module linkage is declared inline in one <s>translation unit</s><u>definition domain</u>, <s>there shall be a reachable</s><u>an</u> inline declaration <s>in all translation units</s><u>of it shall be reachable from the end of every definition domain</u> in which it is declared; no diagnostic is required. <u>[<em>Note</em>: A call to an inline function or a use of an inline variable may be encountered before its definition becomes reachable in a translation unit. — <em>end note</em>]</u></p>
</blockquote>
<blockquote>
<p><u>[<em>Note</em>: </u>An inline function or variable with external or module linkage <s>shall have</s><u>has</u> the same address in all translation units. <s>[<em>Note</em>: </s>A <code>static</code> local variable in an inline function with external or module linkage always refers to the same object. A type defined within the body of an inline function with external or module linkage is the same type in every translation unit. — <em>end note</em>]</p>
</blockquote>
<p>Change [dcl.inline]/7:</p>
<blockquote>
<p><s>An exported</s><u>If an</u> inline function or variable<u> that is attached to a named module is declared in a definition domain, it</u> shall be defined in <s>the translation unit containing its exported declaration, outside the <em>private-module-fragment</em> (if any)</s><u>that domain</u>. [<em>Note</em>: <s>There is no restriction on the linkage (or absence thereof) of entities that the function body of an exported inline function can reference.</s> A constexpr function ([dcl.constexpr]) is implicitly inline. — <em>end note</em>]</p>
</blockquote>
<p>Change [dcl.spec.auto]/10:</p>
<blockquote>
<p>An exported function with a declared return type that uses a placeholder type shall be defined in the translation unit containing its exported declaration, outside the <em>private-module-fragment</em> (if any). [<em>Note</em>: <s>There is no restriction on the linkage of the</s><u>The</u> deduced return type<u> cannot have a name with internal linkage ([basic.link])</u>. — <em>end note</em>]</p>
</blockquote>
<p>Change and split [module.import]/5:</p>
<blockquote>
<p>A <em>module-import-declaration</em> that specifies a <em>header-name</em> <code>H</code> imports a synthesized <em>header unit</em>, which is a translation unit formed by applying phases 1 to 7 of translation ([lex.phases]) to the source file or header nominated by <code>H</code>, which shall not contain a <em>module-declaration</em>. [<em>Note</em>: All declarations within a header unit are implicitly exported ([module.interface]), and are attached to the global module ([module.unit]). — <em>end note</em>] An <em>importable header</em> is a member of an implementation-defined set of headers that includes all importable C++ library headers ([headers]). <code>H</code> shall identify an importable header. <s>Two</s><u>Given two such</u> <em>module-import-declaration</em>⁠s<u>:</u></p>
<ol type="1">
<li><s>import the same header unit if and only </s>if their <em>header-name</em>⁠s identify <s>the same</s><u>different</u> header<u>s</u> or source file<u>s</u> ([cpp.include])<u>, they import distinct header units;</u></li>
<li><u>otherwise, if they appear in the same translation unit, they import the same header unit;</u></li>
<li><u>otherwise, it is unspecified whether they import the same header unit</u>. <u>[<em>Note</em>: It is therefore possible that multiple copies exist of entities declared with internal linkage in an importable header. — <em>end note</em>]</u></li>
</ol>
<p>[<em>Note</em>: A <em>module-import-declaration</em> nominating a <em>header-name</em> is also recognized by the preprocessor, and results in macros defined at the end of phase 4 of translation of the header unit being made visible as described in [cpp.import]. — <em>end note</em>]</p>
</blockquote>
<blockquote>
<p>A declaration of a name with internal linkage is permitted within a header unit despite all declarations being implicitly exported ([module.interface]). <s>If such a declaration declares an entity that is odr-used outside the header unit, or by a template instantiation whose point of instantiation is outside the header unit, the program is ill-formed.</s> <u>[<em>Note</em>: A definition that appears in multiple translation units cannot in general refer to such names ([basic.def.odr]). — <em>end note</em>] A header unit shall not contain a definition of a non-inline function or variable whose name has external linkage.</u></p>
</blockquote>
<p>Change [module.private.frag]/2:</p>
<blockquote>
<p>[<em>Note</em>: A <em>private-module-fragment</em> ends the portion of the module interface unit that can affect the behavior of other translation units. A <em>private-module-fragment</em> allows a module to be represented as a single translation unit without making all of the contents of the module reachable to importers. The presence of a <em>private-module-fragment</em> affects:</p>
<ol type="1">
<li>the point by which the definition of an exported inline function is required ([dcl.inline]),</li>
<li>the point by which the definition of an exported function with a placeholder return type is required ([dcl.spec.auto]),</li>
<li><u>whether a declaration is required not to be an exposure ([basic.link]),</u></li>
<li><u>where definitions for inline functions and templates must appear ([basic.def.odr], [temp.pre]),</u></li>
<li>the instantiation contexts of templates instantiated before it ([module.context]), and</li>
<li>the reachability of declarations within it ([module.reach]). — <em>end note</em>]</li>
</ol>
</blockquote>
<p>Change [temp.pre]/10:</p>
<blockquote>
<p>A <u>definition of a </u>function template, member function of a class template, variable template, or static data member of a class template shall be <s>defined in</s><u>reachable from the end of</u> every <s>translation unit</s><u>definition domain ([basic.def.odr])</u> in which it is implicitly instantiated ([temp.inst]) unless the corresponding specialization is explicitly instantiated ([temp.explicit]) in some translation unit; no diagnostic is required.</p>
</blockquote>
<p>Change [temp.dep.constexpr]/2.5:</p>
<blockquote>
<p>it <s>is a constant with literal type and</s><u>names a potentially-constant variable ([expr.const]) that</u> is initialized with an expression that is value-dependent.</p>
</blockquote>
<p>Insert before [temp.inst]/1:</p>
<div class="ins">
<blockquote>
<p>A template specialization <em>E</em> is a <em>declared specialization</em> if there is a reachable explicit instantiation definition ([temp.explicit]) or explicit specialization declaration ([temp.expl.spec]) for <em>E</em>, or if there is a reachable explicit instantiation declaration for <em>E</em> and <em>E</em> is not</p>
<ol type="1">
<li>an inline function,</li>
<li>declared with a type deduced from its initializer or return value ([dcl.spec.auto]),</li>
<li>a potentially-constant variable ([expr.const]), or</li>
<li>a specialization of a templated class.</li>
</ol>
<p>[<em>Note</em>: An implicit instantiation in an importing translation unit cannot use names with internal linkage from an imported translation unit ([basic.link]). — <em>end note</em>]</p>
</blockquote>
</div>
<p>Change [temp.inst]/1:</p>
<blockquote>
<p>Unless a class template specialization <s>has been explicitly instantiated ([temp.explicit]) or explicitly specialized ([temp.expl.spec])</s><u>is a declared specialization</u>, the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program. […]</p>
</blockquote>
<p>Change [temp.inst]/3:</p>
<blockquote>
<p>Unless a member of a class template or a member template <s>has been explicitly instantiated or explicitly specialized</s><u>is a declared specialization</u>, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist or if the existence of the definition of the member affects the semantics of the program; in particular, the initialization (and any associated side effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.</p>
</blockquote>
<p>Change [temp.inst]/4:</p>
<blockquote>
<p>Unless a function template specialization <s>has been explicitly instantiated or explicitly specialized</s><u>is a declared specialization</u>, the function template specialization is implicitly instantiated when the specialization is referenced in a context that requires a function definition to exist or if the existence of the definition affects the semantics of the program. A function whose declaration was instantiated from a friend function definition is implicitly instantiated when it is referenced in a context that requires a function definition to exist or if the existence of the definition affects the semantics of the program. Unless a call is to a function template explicit specialization or to a member function of an explicitly specialized class template, a default argument for a function template or a member function of a class template is implicitly instantiated when the function is called in a context that requires the value of the default argument. <u>[<em>Note</em>: An inline function that is the subject of an explicit instantiation declaration is not a declared specialization; the intent is that it still be implicitly instantiated when odr-used ([basic.def.odr]) so that the body can be considered for inlining, but that no out-of-line copy of it be generated in the translation unit. — <em>end note</em>]</u></p>
</blockquote>
<p>Change [temp.inst]/6:</p>
<blockquote>
<p>Unless a variable template specialization <s>has been explicitly instantiated or explicitly specialized</s><u>is a declared specialization</u>, the variable template specialization is implicitly instantiated when it is referenced in a context that requires a variable definition to exist or if the existence of the definition affects the semantics of the program. A default template argument for a variable template is implicitly instantiated when the variable template is referenced in a context that requires the value of the default argument.</p>
</blockquote>
<p>Remove [temp.explicit]/14:</p>
<div class="del">
<blockquote>
<p>Except for inline functions […]</p>
</blockquote>
</div>
<p>Add a subclause before [depr.impldec]:</p>
<div class="ins">
<blockquote>
<h2 id="non-local-use-of-tu-local-entities-depr.local">Non-local use of TU-local entities [depr.local]</h2>
<p>A declaration of a non-TU-local entity that is an exposure ([basic.link]) is deprecated. [<em>Note</em>: Such a declaration in an importable module unit is ill-formed. — <em>end note</em>] [<em>Example</em>:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode cpp"><code class="sourceCode cpp"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">namespace</span> {</span>
<span id="cb5-2"><a href="#cb5-2"></a>  <span class="kw">struct</span> A {</span>
<span id="cb5-3"><a href="#cb5-3"></a>    <span class="dt">void</span> f() {}</span>
<span id="cb5-4"><a href="#cb5-4"></a>  };</span>
<span id="cb5-5"><a href="#cb5-5"></a>}</span>
<span id="cb5-6"><a href="#cb5-6"></a>A h();                      <span class="co">// deprecated: not internal linkage</span></span>
<span id="cb5-7"><a href="#cb5-7"></a><span class="kw">inline</span> <span class="dt">void</span> g() {A().f();}  <span class="co">// deprecated: inline and not internal linkage</span></span></code></pre></div>
<p>— <em>end example</em>]</p>
</blockquote>
</div>
</body>
</html>
