<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Mar 20, 2015, at 11:38 AM, Nico Weber <<a href="mailto:thakis@chromium.org" class="">thakis@chromium.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote">On Fri, Mar 20, 2015 at 11:28 AM, Ted Kremenek<span class="Apple-converted-space"> </span><span dir="ltr" class=""><<a href="mailto:kremenek@apple.com" target="_blank" class="">kremenek@apple.com</a>></span><span class="Apple-converted-space"> </span>wrote:<br class=""><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 style="word-wrap: break-word;" class=""><br class=""><div class=""><span class=""><blockquote type="cite" class=""><div class="">On Mar 20, 2015, at 11:07 AM, Nico Weber <<a href="mailto:thakis@chromium.org" target="_blank" class="">thakis@chromium.org</a>> wrote:</div><br class=""><div class=""><span style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">On Fri, Mar 20, 2015 at 10:42 AM, Ted Kremenek<span class=""> </span></span><span dir="ltr" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><<a href="mailto:kremenek@apple.com" target="_blank" class="">kremenek@apple.com</a>></span><span style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class=""> </span><span style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; float: none; display: inline !important;" class="">wrote:</span><br style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><blockquote class="gmail_quote" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; 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 style="word-wrap: break-word;" class=""><span class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Mar 20, 2015, at 8:35 AM, Nico Weber <<a href="mailto:thakis@chromium.org" target="_blank" class="">thakis@chromium.org</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote">On Fri, Mar 20, 2015 at 8:10 AM, Ted Kremenek<span class=""> </span><span dir="ltr" class=""><<a href="mailto:kremenek@apple.com" target="_blank" class="">kremenek@apple.com</a>></span><span class=""> </span>wrote:<br class=""><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 style="word-wrap: break-word;" class="">Hi Nico,<div class=""><br class=""></div><div class="">I'm really sorry, but this is the first time I saw this.  When you first proposed the patch I was away from work for several weeks and wasn't reading email.  I then missed most of this.</div><div class=""><br class=""></div><div class="">I honestly am very concerned about this approach.  The problem is certainly well-motivated, but it feels like a really partial solution to the problem that doesn't provide any real safety.  Looking back at the thread I see you and Doug discussed using dataflow analysis, which really seems like the right approach to me.  Even some basic lexical analysis to check if a guard existed before use probably would have provided some reasonable checking, and I disagree with Doug that the dataflow approach was "a heck of a lot more work".</div><div class=""><br class=""></div><div class="">The thing I don't like about this approach is that as soon as you provide the redeclaration you lose all checking for uses of a method.  Here are my concerns:</div><div class=""><br class=""></div><div class="">(1) You get a warning once for a method that is newer than your minimum deployment target regardless of whether or not you are using it safely.</div><div class=""><br class=""></div><div class="">(2) You silence that warning by adding the redeclaration.  Then all future uses of that method that you introduce won't get a warning.</div><div class=""><br class=""></div><div class="">I don't see how this provides any real checking at all.  Even if the first warning was valid in identify and unguarded case, you get no help from the compiler if you add the guard and do it incorrectly.</div><div class=""><br class=""></div><div class="">My concern here is not that this problem isn't important to solve.  It's a very big problem.  I am concerned that this approach causes users to clutter their code with redeclarations and it provides them no much safety checking at all.  I know part of this was motivated by real issues you were seeing in Chrome, a large codebase that needs to run on multiple OS versions.  Do you think this will be a practical, and useful approach, to solving that problem in practice on a codebase of that size?</div></div></blockquote><div class=""><br class=""></div><div class="">Hi Ted,</div><div class=""><br class=""></div><div class="">I agree that this is an imperfect solution. However, it's identical to our current approach of just building against an old SDK (10.6). This is what we currently do, and having to declare methods before using them does help in practice. However, the OS suppresses some bug fixes when linking against an old SDK, so we want to switch to a model where we use the newest SDK. This warning is supposed to give us the same level of safety as using an old SDK, without getting the drawbacks of an old SDK.</div><div class=""><br class=""></div><div class="">This isn't Chromium-specific either: I talked to the Firefox folks, and they currently build against an old SDK for the same reasons we do.</div><div class=""><br class=""></div><div class="">(Also note that this warning is off by default and not in -Wall.)</div><div class=""><br class=""></div><div class="">Nico</div><div class=""> </div></div></div></div></div></blockquote><br class=""></div></span><div class="">Hi Nico,</div><div class=""><br class=""></div><div class="">My main concern about this warning, as is, is that it creates a workflow that castrates itself immediately and adds lots of ancillary boilerplate to the code whose purpose is mostly indiscernible to a reader.  It also doesn't provide any real checking, and thus in my opinion creates a false sense of security.</div></div></blockquote><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">Again, this approach does help us in practice. I agree that it's not perfect, but it does work for us.</div></div></blockquote><div class=""><br class=""></div></span><div class="">I understand that it works for us, but it's not a great workflow in general.  It would be great if we had something that worked in general for OS X and iOS developers.  This feels, at least to me, very idiomatic to something that might be adopted in a particular codebase.</div><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""> </div><blockquote class="gmail_quote" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; 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 style="word-wrap: break-word;" class=""><div class=""> People often get the actual checking wrong, and they may also use an unavailable API multiple times.</div><div class=""><br class=""></div><div class="">I do think that we can take what you have and make something much better, and far more powerful, with not much effort.  Here's a counterproposal:</div><div class=""><br class=""></div><div class="">(a) Have the availability warning, as we have now, but delay issuing it until you can do a bit more analysis to validate if the use of the unavailable API is safe or not.</div><div class=""><br class=""></div><div class="">(b) For each use of an unavailable API, walk up the lexical structure and look for 'if' guards for 'respondsToSelector'.  If there is a 'respondsToSelector' check for the given potentially unavailable selector, then suppress the warning.</div><div class=""><br class=""></div><div class="">(c) As a refinement, you can possibly generalize the 'respondsToSelector' check to imply that other unavailable selectors that have the same API availability would also be guarded against.  This is potentially unsafe, however, as sometimes an API was internal Apple API in a previous OS, but this is an idiom that is widely followed.  Actually, 'respondsToSelector' for just checking on potentially unavailable selector is unsafe for this reason.  Regardless, I think the analysis would be pretty much the same.  You can just walk the lexical structure and look for availability guards that imply a minimum OS availability.  This seems very trivial to do; this is just an AST walk.  You can also batch it up and do it efficiently by only lazily doing it if a potentially unavailable API is encountered.</div><div class=""><br class=""></div><div class="">(d) As an escape hatch, provide a more localized way to suppress the warning other than suppressing all cases of the warning by adding a category.  The category approach is completely non-obvious anyway, and from a readability perspective doesn't provide any insight that the warning is being suppressed by this bit of what appears to be redundant code.</div></div></blockquote><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">The motivation is that it is the same mechanism one would use when building against an old SDK.</div><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">What do you think would be a better escape hatch syntax?</div></div></blockquote><div class=""><br class=""></div></span><div class="">I'm talking to process here, but we do have pragmas already for suppressing warnings.  Those can already be used to suppress warnings within blocks of code.  That idea could be extended to suppress the warning for specific selectors, or at least selectors with in an availability equivalence class (so to speak).</div><div class=""><br class=""></div><div class="">Note that this approach could extend to not just selectors, but any API.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Brainstorming a bit:</div><div class="">#pragma assume_availability(mac, 10.8)</div><div class="">…actually, that all I've got :-P</div></div></div></div></div></blockquote><div><br class=""></div><div>This seems reasonable, but to be clear I'd have it bracketed with two pragmas.  Everything within that bracket would follow that assumption.</div><div><br class=""></div><div>For example:</div><div><br class=""></div><div>  #pragma clang assume_availability(macosx, 10.8) begin</div><div>  ...</div><div>  #pragma clang assume_availability(macosx, 10.8) end</div><div class=""><br class=""></div><div class="">Some other considerations:</div><div class=""><br class=""></div><div class="">- the name should follow exactly what is spelled in the availability attribute for the platform name.</div><div class="">- what about code that runs on different platforms?  Straw man:</div><div class=""><br class=""></div><div class=""><div>  #pragma clang assume_availability(macosx, 10.8) begin</div><div><div>  #pragma clang assume_availability(ios, 8.0) begin</div><div class="">  ...</div></div><div><div>  #pragma clang assume_availability(ios, 8.0) end</div></div><div>  #pragma clang assume_availability(macosx, 10.8) end</div></div><div class=""><br class=""></div><div class="">or something more condense?</div><div class=""><br class=""></div><div class="">I assume if you are running with this idea that it appeals to you.</div><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </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;"><div style="word-wrap: break-word;" class=""><div class=""><span class=""><br class=""><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""> </div><blockquote class="gmail_quote" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; 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 style="word-wrap: break-word;" class=""><div class=""><br class=""></div><div class="">This counterproposal doesn't require dataflow analysis, and provides a strong model where actual checking is done.  It also doesn't create a workflow that castrates itself upon silencing the first warning for an unavailable selector.</div><div class=""><br class=""></div><div class="">Did you consider an approach like this?</div></div></blockquote><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px;" class="">Yes. It's not sufficient. Some of our classes do calls to partial methods unconditionally, and we only instantiate these classes after checking that the OS is new enough (else we build a dummy object) with the same interface.</div></div></blockquote><div class=""><br class=""></div></span><div class="">That's a very good point.</div><div class=""><br class=""></div><div class="">The suggestion I made above (with pragmas) could solve that problem, and would allow you to be more declarative about the actual availability you expect some code to be executed.  I think that would communicate far more intent than just adding categories that redeclare methods, and it gives you the flexibility to decide at what granularity you want to suppress the warning.</div></div></div></blockquote></div><br class=""></div><div class="gmail_extra">Ok, for next steps:</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">1.) I'll try to come up with a patch that suppresses the current warning in if (respondsToSelector) blocks for objc message sends, and in if (CFWeakFun) for C functions.</div></div></div></blockquote><div><br class=""></div><div>Sounds good.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" style="font-family: Helvetica; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><div class="gmail_extra">2.) I'll wait a bit for folks to brainstorm how exactly the pragma will look, and once that has settled use that as a signal instead of redeclarations.</div></div></div></blockquote><br class=""></div><div>Sounds great Nico.</div><br class=""></body></html>