<div dir="ltr"><div>Hi Gábor,</div><div><br></div><div>I'm very excited about lifetime annotations! I have two comments/requests.</div><div><br></div><div>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.</div><div><br></div><div>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.</div><div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Dec 5, 2019 at 12:02 AM Gábor Horváth via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span id="gmail-m_2174022339785357515gmail-docs-internal-guid-90c1467e-7fff-7fc2-ace7-fc52df1d83fb"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><br></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:"Roboto Mono",monospace;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap">  const char *find(const string &haystack, const string &needle) </span><span style="font-size:11pt;font-family:"Roboto Mono",monospace;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap"><br></span><span style="font-size:11pt;font-family:"Roboto Mono",monospace;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap">       [[gsl::post(lifetime(find, {haystack, null})</span><span style="font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap">)]];</span></p></span></div></blockquote><div><br></div><div>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.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><span id="gmail-m_2174022339785357515gmail-docs-internal-guid-90c1467e-7fff-7fc2-ace7-fc52df1d83fb"><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><b style="font-weight:normal"></b></p><p dir="ltr" style="line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style="font-size:11pt;font-family:"Roboto Mono",monospace;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap">  struct Match { const char *pos; /* ... */ };</span><span style="font-size:11pt;font-family:"Roboto Mono",monospace;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap"><br></span><span style="font-size:11pt;font-family:"Roboto Mono",monospace;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap">  bool find(const string &hs, const string &n, Match *m)</span><span style="font-size:11pt;font-family:"Roboto Mono",monospace;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap"><br></span><span style="font-size:11pt;font-family:"Roboto Mono",monospace;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-style:normal;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre-wrap">    [[gsl::post(lifetime(deref(M).pos, {haystack}))]];</span></p></span></div></blockquote><div><br></div><div>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.</div><div><br></div><div>Dmitri</div><div><br></div></div>-- <br><div dir="ltr" class="gmail_signature">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>>*/</div></div>