<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 3/23/2017 4:59 PM, David Blaikie via
      cfe-dev wrote:<br>
    </div>
    <blockquote
cite="mid:CAENS6Eup_Kmz2xgNktsm7NJ1T6Pwpao_HPYWxgNh7UZDmWEGYg@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div dir="ltr" class="gmail_msg">On Thu, Mar 23, 2017 at 4:47 PM
          Vedant Kumar <<a moz-do-not-send="true"
            href="mailto:vsk@apple.com" class="gmail_msg"
            target="_blank">vsk@apple.com</a>> wrote:<br>
        </div>
        <div class="gmail_quote gmail_msg">
          <blockquote class="gmail_quote gmail_msg" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">><br
              class="gmail_msg">
            >> On Mar 23, 2017, at 4:32 PM, David Blaikie <<a
              moz-do-not-send="true" href="mailto:dblaikie@gmail.com"
              class="gmail_msg" target="_blank">dblaikie@gmail.com</a>>
            wrote:<br class="gmail_msg">
            >><br class="gmail_msg">
            >><br class="gmail_msg">
            >><br class="gmail_msg">
            >> On Thu, Mar 23, 2017 at 4:23 PM Vedant Kumar via
            cfe-dev <<a moz-do-not-send="true"
              href="mailto:cfe-dev@lists.llvm.org" class="gmail_msg"
              target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> > On Mar 23, 2017, at 1:42 PM, Anna Zaks via
            cfe-dev <<a moz-do-not-send="true"
              href="mailto:cfe-dev@lists.llvm.org" class="gmail_msg"
              target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br
              class="gmail_msg">
            >> ><br class="gmail_msg">
            >> ><br class="gmail_msg">
            >> >> On Mar 23, 2017, at 11:48 AM, Reid
            Kleckner via cfe-dev <<a moz-do-not-send="true"
              href="mailto:cfe-dev@lists.llvm.org" class="gmail_msg"
              target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br
              class="gmail_msg">
            >> >><br class="gmail_msg">
            >> >> On Thu, Mar 23, 2017 at 10:55 AM, David
            Blaikie <<a moz-do-not-send="true"
              href="mailto:dblaikie@gmail.com" class="gmail_msg"
              target="_blank">dblaikie@gmail.com</a>> wrote:<br
              class="gmail_msg">
            >> >> On Thu, Mar 23, 2017 at 10:45 AM Reid
            Kleckner <<a moz-do-not-send="true"
              href="mailto:rnk@google.com" class="gmail_msg"
              target="_blank">rnk@google.com</a>> wrote:<br
              class="gmail_msg">
            >> >> I don't think it will be feasible to
            generalize UBSan's knowledge to the static analyzer.<br
              class="gmail_msg">
            >> >><br class="gmail_msg">
            >> >> Why not? The rough idea I meant would be
            to express the constraints UBSan is checking into the static
            analyzer - I realize the current layering (UBSan being in
            Clang's IRGen) doesn't make that trivial/obvious, but it
            seems to me that the constraints could be shared in some way
            - with some work.<br class="gmail_msg">
            >> >><br class="gmail_msg">
            >> >> Maybe I am not imaginative enough, but I
            cannot envision a clean way to express the conditions that
            trigger UB that is useful for both static analysis and
            dynamic instrumentation. The best I can come up with is
            AST-level instrumentation: synthesizing AST nodes that can
            be translated to IR or used for analysis. That doesn't seem
            reasonable, so I think getting ubsan into the static
            analyzer would end up duplicating the knowledge of what
            conditions trigger UB.<br class="gmail_msg">
            >> >><br class="gmail_msg">
            >> >> The static analyzer CFG is also at best an
            approximation of the real CFG, especially for C++.<br
              class="gmail_msg">
            >> >><br class="gmail_msg">
            >> ><br class="gmail_msg">
            >> > First, the CFG is not only used by the
            analyzer, but it is also used by Sema (ex: unreachable code
            warnings and uninitialized variables).<br class="gmail_msg">
            >> > Second, while there are corners of C++ that
            are not supported, it has high fidelity otherwise.<br
              class="gmail_msg">
            >> ><br class="gmail_msg">
            >> >> Sure enough - and I believe some of the
            people working/caring about it would like to fix that. I
            think Manuel & Chandler have expressed the notion that
            the best way to do that would be to move to a world where
            the CFG is used for CodeGen, so it's a single/consistent
            source of truth.<br class="gmail_msg">
            >> >><br class="gmail_msg">
            >> >> Yes, we could do all that work, but LLVM's
            CFG today is already precise for C++. If we allow ourselves
            to emit diagnostics from the middle-end, we can save all
            that work.<br class="gmail_msg">
            >> >><br class="gmail_msg">
            >> >> Going down the high-effort path of
            extending the CFG and abstracting or duplicating UBSan’s
            checks as static analyses on that CFG would definitely
            provide a better diagnostic experience, but it's worth
            re-examining conventional wisdom and exploring alternatives
            first.<br class="gmail_msg">
            >> ><br class="gmail_msg">
            >> > The idea of analysis based on top of LLVM IR
            is not new and have been discussed before. My personal
            belief is that having access to the AST (or just code as was
            written by the user) is very important.<br class="gmail_msg">
            >><br class="gmail_msg">
            >> UBSan diagnostics provide a filename, line #, and
            column #. There is enough information here for a clang-based
            tool to retrieve an AST node, and generate an appropriate
            diagnostic. In the non-LTO case, we'd have an ASTContext
            ready to go at the point where we get the diagnostics back
            from LLVM. In the LTO case, we could serialize the
            diagnostics and pass them to a clang tool for processing.<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >><br class="gmail_msg">
            >> > It ensures we can provide precise diagnostics.
            It also allows us to see when users want to suppress an
            issue report by changing the way the source code is uttered.
            For example, allows to tell the developer that they can
            suppress with a cast.<br class="gmail_msg">
            >><br class="gmail_msg">
            >> When users of a hypothetical "-Woptimizer" need to
            suppress diagnostics, they could use the no_sanitize
            function attribute, or sanitizer blacklists. These are big
            hammers: if it proves to be too clumsy, we could find a way
            to do more fine-grained sanitizer issue suppression.<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >><br class="gmail_msg">
            >> > Ensuring that clang CFG completely supports
            C++ is a bit challenging but not insurmountable task. In
            addition, fixing-up the unsupported corners in the CFG would
            benefit not only the clang static analyzer, but all the
            other “users” such as clang warnings, clang-tidy, possibly
            even refactoring in the future.<br class="gmail_msg">
            >> ><br class="gmail_msg">
            >> > Here is a thread where this has been discussed
            before:<br class="gmail_msg">
            >> > <a moz-do-not-send="true"
href="http://clang-developers.42468.n3.nabble.com/LLVM-Dev-meeting-Slides-amp-Minutes-from-the-Static-Analyzer-BoF-td4048418.html"
              rel="noreferrer" class="gmail_msg" target="_blank">http://clang-developers.42468.n3.nabble.com/LLVM-Dev-meeting-Slides-amp-Minutes-from-the-Static-Analyzer-BoF-td4048418.html</a><br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> I've tried to summarize this thread:<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> --- Slides & Minutes from the Static Analyzer
            BoF ---<br class="gmail_msg">
            >><br class="gmail_msg">
            >> * Cross Translation Unit Static Analysis: The
            proposed approach is to generate summaries for each TU, and
            to teach the analyses to emit diagnostics based on the
            summaries. I don't know the current status of this, or what
            using summaries does to false-positive rates.<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> * A Clang IR: Modeling things like temporaries is
            hard, so is dealing with language changes. One proposal is
            to create an alternate IR for C, then lower it to LLVM IR.
            The argument is that analyses would be easier to perform on
            the "C/C++" IR, because CodeGen/StaticAnalyzer would operate
            on the same structures. There are concerns raised about the
            complexity of this undertaking<br class="gmail_msg">
            >><br class="gmail_msg">
            >> * A Rich Type System in LLVM IR: An alternate
            proposal is to add a rich, language-agnostic type system to
            LLVM IR, with pointers back to frontend AST's. Under this
            proposal, I'm assuming LLVM would be responsible for
            generating diagnostics. There were concerns raised about
            having optimizations preserve the type information, about
            AST node lifetime issues, and about layering violations (i.e
            LLVM shouldn't be dealing with frontend stuff).<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> ---<br class="gmail_msg">
            >><br class="gmail_msg">
            >> ISTM that work on improving C++ support in the
            clang CFG can proceed in parallel to work on reporting
            sanitizer diagnostics from the middle-end. I'd like to know
            what others think about this.<br class="gmail_msg">
            >><br class="gmail_msg">
            >> Just to recap, the approach I have in mind is
            different from the options discussed in the thread Anna
            linked to. It's advantages are that;<br class="gmail_msg">
            >><br class="gmail_msg">
            >> * There is a clear path towards reporting issues
            that arise when LTO is enabled.<br class="gmail_msg">
            >><br class="gmail_msg">
            >> * We can design it s.t there aren't false
            positives, with the caveat that we will annoy users about
            bugs in dead code.<br class="gmail_msg">
            >><br class="gmail_msg">
            >> * It's extensible, in case we ever want to explore
            statically reporting diagnostics from other sanitizers.<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> * The classes of UB bugs we'd be able to diagnose
            statically would always be the same as the ones we diagnose
            at runtime, without writing much (or any) extra code.<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> * It's relatively simple to implement.<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> The main disadvantage are that;<br
              class="gmail_msg">
            >><br class="gmail_msg">
            >> * It constitutes a layering violation, because we'd
            need to teach LLVM about the names of some ubsan diagnostic
            handlers. IMO this isn't too onerous, we already do this
            with builtins.<br class="gmail_msg">
            >><br class="gmail_msg">
            >> * It's awkward to have llvm issue diagnostics,
            because this is usually done by Sema/clang-tidy/the static
            analyzer. I think this is something we could get used to.<br
              class="gmail_msg">
            ><br class="gmail_msg">
            > I'm not sure this last bulletpoint quite captures the
            difficulties of having diagnostics powered by optimizers.
            The concern is generally that this makes diagnostics
            unreliable and surprising to users because what would appear
            to be unrelated changes (especially to the degree of
            changing the optimization level/tweaks, or maybe changing
            architecture/target) cause diagnostics to appear/disappear.
            This is the sort of behavior that's been seen with some of
            GCC's diagnostics that are optimizer-powered, and something
            Clang's done a fair bit to avoid.<br class="gmail_msg">
            <br class="gmail_msg">
            That's fair, I should have examined that last point in more
            detail.<br class="gmail_msg">
            <br class="gmail_msg">
            I think we could minimize the confusion by making it clear
            that the warnings are dependent on optimizations. In part,
            this would mean writing good documentation. We'd also need
            to find the right language for the warnings. Something like:
            "warning: foo.cpp:N:M: At the -OX optimization level,
            undefined behavior due to <...> was detected
            [-Woptimizer]". We could teach clang to emit Fixits in some
            cases, or even notes which explain that the code could be
            removed by the optimizer.<br class="gmail_msg">
          </blockquote>
          <div><br>
            Fixits, notes, and other high precision source information
            (even in the case of a basic diagnostic - highlighting the
            expression range, etc) would be pretty challenging for a
            feature like this, btw. The source locations used by LLVM to
            report backend diagnostics (LLVM has some - for things like
            instruction selection/inline asm issues, etc - as well as
            the optimization report diagnostics) are from debug info,
            only line/col. Stitching that back to any part of the AST
            would be pretty ambiguous in most/many cases I'd imagine.</div>
        </div>
      </div>
    </blockquote>
    <br>
    The source locations clang uses for inline asm diagnostics are not
    from debug info; we serialize a clang::SourceLocation into the
    metadata.  See <a class="moz-txt-link-freetext" href="http://llvm.org/docs/LangRef.html#inline-asm-metadata">http://llvm.org/docs/LangRef.html#inline-asm-metadata</a>
    .  We could (and probably should) extend this to other diagnostics.<br>
    <br>
    Granted, that isn't really the problem here.  The static analyzer is
    very carefully designed to generate diagnostics which are useful; it
    shows the assumptions it makes, and a dynamic path through the
    function.  With diagnostics coming from the optimizer, we have no
    way to explain why a function has undefined behavior: we throw away
    the CFG in the process of optimizing the code.<br>
    <br>
    -Eli<br>
    <pre class="moz-signature" cols="72">-- 
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project</pre>
  </body>
</html>