<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoListParagraph, li.MsoListParagraph, div.MsoListParagraph
        {mso-style-priority:34;
        margin-top:0in;
        margin-right:0in;
        margin-bottom:0in;
        margin-left:.5in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
/* List Definitions */
@list l0
        {mso-list-id:1098326949;
        mso-list-type:hybrid;
        mso-list-template-ids:-2113262396 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l0:level1
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level2
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level3
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level4
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level5
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level6
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l0:level7
        {mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level8
        {mso-level-number-format:alpha-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;}
@list l0:level9
        {mso-level-number-format:roman-lower;
        mso-level-tab-stop:none;
        mso-level-number-position:right;
        text-indent:-9.0pt;}
@list l1
        {mso-list-id:1320697427;
        mso-list-template-ids:-1950979842;}
@list l2
        {mso-list-id:1547333778;
        mso-list-type:hybrid;
        mso-list-template-ids:-1454322616 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l2:level1
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;}
@list l2:level2
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l2:level3
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l2:level4
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;}
@list l2:level5
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l2:level6
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l2:level7
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Symbol;}
@list l2:level8
        {mso-level-number-format:bullet;
        mso-level-text:o;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:"Courier New";}
@list l2:level9
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:none;
        mso-level-number-position:left;
        text-indent:-.25in;
        font-family:Wingdings;}
@list l3
        {mso-list-id:1809738889;
        mso-list-template-ids:339134536;}
@list l3:level1
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l3:level2
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:1.0in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l3:level3
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:1.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l3:level4
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:2.0in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l3:level5
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:2.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l3:level6
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:3.0in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l3:level7
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:3.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l3:level8
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:4.0in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
@list l3:level9
        {mso-level-number-format:bullet;
        mso-level-text:;
        mso-level-tab-stop:4.5in;
        mso-level-number-position:left;
        text-indent:-.25in;
        mso-ansi-font-size:10.0pt;
        font-family:Symbol;}
ol
        {margin-bottom:0in;}
ul
        {margin-bottom:0in;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal>Gábor wrote:<o:p></o:p></p><p class=MsoNormal>> I would love to see a simpler syntax. I think implementing this the most general<o:p></o:p></p><p class=MsoNormal>> way possible and adding some syntactic sugar later on after having some data<o:p></o:p></p><p class=MsoNormal>> about the most common patterns might make sense.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Yes. In particular, the nicest “nice syntax” of all is intended by design to be <b>whitespace</b> for the large majority of functions, via defaults that are equivalent to default annotations… the <a href="https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetime.pdf">Lifetime design paper</a> proposes such defaults (in sections 2.5.3 and 2.5.5), and the aim is that very few functions ever want explicit annotation.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>So far in our experience that has been working very well, including that the large majority of std:: standard library functions just work unchanged without annotation:<o:p></o:p></p><ul style='margin-top:0in' type=disc><li class=MsoListParagraph style='margin-left:0in;mso-list:l2 level1 lfo3'>To see basic examples, please look at <a href="https://godbolt.org/z/1C4t8m">https://godbolt.org/z/1C4t8m</a> (which involves std::min) and <a href="https://godbolt.org/z/4G-8H-">https://godbolt.org/z/4G-8H-</a> (which diagnoses a StackOverflow question involving unique_ptr). No annotation of the standard library was needed in either example, they use the stock unmodified std:: implementation.*<o:p></o:p></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l2 level1 lfo3'>For an (IMO pretty slick) example of zero-annotation of more complex code, see <a href="https://godbolt.org/z/eqCRLx">https://godbolt.org/z/eqCRLx</a> – the code it diagnoses is actually quite complex (vector push_back but also ranges with filtering views) and all unannotated, and it gives nice and accurate diagnostics (pretty much “hey, your ranges::view::filter is dangling here on line B, because your vector<int>.push_back() invalidated it here on line A”).<o:p></o:p></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l2 level1 lfo3'>See also section 2.6.2 in the design paper which shows that the string_view dangling problem examples given in WG21 paper P0936 are (I think all) diagnosed without any explicit annotation, because the proposed defaults do the right thing.<o:p></o:p></li></ul><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Those are examples, many of them drawn from real-world code, that needed no annotation at all with the proposed default annotations.<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>So I would propose this:<o:p></o:p></p><ol style='margin-top:0in' start=1 type=1><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level1 lfo6'>Implement the general form. We know that occasionally we’ll need that, and then we can express anything in #2 and #3 as equivalents/sugars for something expressible in #1.<o:p></o:p></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level1 lfo6'>Implement the proposed default rules (including tweak them as we gain experience in larger codebases) so that whitespace zero-annotation Just Works for (we hope) a very large number of functions.<o:p></o:p></li><li class=MsoListParagraph style='margin-left:0in;mso-list:l0 level1 lfo6'>Then see if we actually need any in-between syntactic sugars at all. If #2 covers a sufficiently high % of functions, we may not even be interested in other sugars. And if we discover there are patterns that #2 doesn’t cover well, then we can add sugars for those patterns.<o:p></o:p></li></ol><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>How does that sound?<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>Herb<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal>* As a temporary implementation detail, the prototype does currently hardwire knowledge that unique_ptr and vector are owners, but there also proposed default zero-annotation rules for automatically recognizing which types are Owners (see section 2.1) which recognize those types without annotation (e.g., it recognizes containers and smart pointers as implicitly Owners).<o:p></o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p><p class=MsoNormal><o:p> </o:p></p><div style='border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt'><div><div style='border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal><b>From:</b> Gábor Horváth <xazax@google.com> <br><b>Sent:</b> Thursday, December 12, 2019 8:43 AM<br><b>To:</b> Dmitri Gribenko <gribozavr@gmail.com><br><b>Cc:</b> cfe-dev <cfe-dev@lists.llvm.org>; gehre.matthias@gmail.com; Dmitri Gribenko <dmitrig@google.com>; Herb Sutter <hsutter@microsoft.com>; Kyle Reed <kylereed@microsoft.com>; Aaron Ballman <aaron.ballman@gmail.com>; Artem Dergachev <adergachev@apple.com>; xazax.hun <xazax.hun@gmail.com>; Petr Hosek <phosek@google.com>; Haowei Wu <haowei@google.com>; larsklein53@gmail.com; Richard Smith <richard@metafoo.co.uk><br><b>Subject:</b> Re: [cfe-dev] [RFC] Upstreaming Lifetime Function Annotations<o:p></o:p></p></div></div><p class=MsoNormal><o:p> </o:p></p><div><div><p class=MsoNormal>Hi Dmitri,<o:p></o:p></p></div><p class=MsoNormal><o:p> </o:p></p><div><div><p class=MsoNormal>On Thu, Dec 12, 2019 at 5:44 AM Dmitri Gribenko <<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>> wrote:<o:p></o:p></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt'><div><div><p class=MsoNormal>Hi Gábor,<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>I'm very excited about lifetime annotations! I have two comments/requests.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>The first one is about the implementation. There are quite a few warnings, ClangTidy checkers and other analyses in Clang that are dataflow-based or at least sort of dataflow-based. They all have to implement the interpretation of Clang's AST semantics, which is unfortunate, because it is very complicated logic that is refined and polished over time as we get to use those warnings and checkers, and yet, we can't reuse this logic for any new checker.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Therefore, my request is to try to structure the implementation in such a way that it is at least plausible to factor out the "dataflow engine" parts of the static analysis in future, and keep the abstract domain and lifetime specifics more or less separate.<o:p></o:p></p></div></div></blockquote><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Thanks, I totally agree. I think it should be relatively easy to separate the CFG traversal/fixed point iteration part. Anything bigger is likely to be more involved, but we definitely will strive for some reusability. <o:p></o:p></p></div><div><p class=MsoNormal> <o:p></o:p></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt'><div><p class=MsoNormal><o:p> </o:p></p><div><div><p class=MsoNormal>On Thu, Dec 5, 2019 at 12:02 AM Gábor Horváth via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<o:p></o:p></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt'><div><p style='margin:0in;margin-bottom:.0001pt'><o:p> </o:p></p><p style='margin:0in;margin-bottom:.0001pt'><span style='font-family:"Courier New";color:black'>  const char *find(const string &haystack, const string &needle) <br>      [[gsl::post(lifetime(find, {haystack, null})</span><span style='font-family:"Arial",sans-serif;color:black'>)]];</span><o:p></o:p></p></div></blockquote><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>I have a concern about the bulkiness of the syntax. I understand why it ended up this way (use standard attribute syntax, use the contracts syntax, ensure that names are referenced syntactically after they are declared, and we get the proposed syntax) -- that helps with rationalization, but that does not help me justify it.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt'><div><p style='margin:0in;margin-bottom:.0001pt'><span style='font-family:"Courier New";color:black'>  struct Match { const char *pos; /* ... */ };<br>  bool find(const string &hs, const string &n, Match *m)<br>    [[gsl::post(lifetime(deref(M).pos, {haystack}))]];</span><o:p></o:p></p></div></blockquote><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>I understand why the lifetime specification has to go at the end of the declaration in the general case -- to handle cases like this, where we want to specify a lifetime for some part of the data structure, but I'm not convinced that users should always use the most general syntax. I feel like it is going to be an adoption barrier and a readability issue.<o:p></o:p></p></div></div></div></blockquote><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>I would love to see a simpler syntax. I think implementing this the most general way possible and adding some syntactic sugar later on after having some data about the most common patterns might make sense. Is it problematic to evolve the syntax upstream? I know this would be bad for early adopters but we could make it clear what they are opting into. <o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-top:5.0pt;margin-right:0in;margin-bottom:5.0pt'><div><div><div><p class=MsoNormal>Dmitri<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div></div><p class=MsoNormal>-- <o:p></o:p></p><div><p class=MsoNormal>main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if<br>(j){printf("%d\n",i);}}} /*Dmitri Gribenko <<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</a>>*/<o:p></o:p></p></div></div></blockquote></div></div></div></div></body></html>