RFC: Macro for 'analyzer_noreturn' attribute

Jordan Rose jordan_rose at apple.com
Thu Mar 28 09:43:31 PDT 2013


On Mar 28, 2013, at 6:32 , Sean Silva <silvas at purdue.edu> wrote:

> Could you explain in a bit more detail why the "regular" noreturn attributes are insufficient for providing this information?

Sure. As you know, "noreturn" affects compilation: the emitted function will not have an epilogue, and callers will consider code following a call to be unreachable. The analyzer couldn't care less about the former, but would like to model the latter to avoid infeasible paths, such as the one shown here:

int *p = getPointerIfExists();
if (!p)
  exit(1);
*p = 1; // no null dereference

Although the assignment to *p looks accessible from both branches of the 'if', we recognize that exit() and functions marked noreturn won't actually reach that assignment.

We get a problem, however, in cases like this (simplified from AsmParser):

void readRegister(int *x) {
  // try to read register
  if (failure)
    return Error("Could not read register.");
  *x = parsedRegister;
}

  int x;
  if (readRegister(&x))
    return true;
  use(x); // no use of uninitialized memory

Here, the 'Error' method is always going to return 'true', so we know execution won't actually reach the use of 'x'. Because 'Error' is defined in another translation unit, however, the analyzer does not know this. We can't mark 'Error' as 'noreturn' because in the real program it does return—an error in parsing assembly does not immediately exit the whole program, just the AsmParser.

The best thing would be to have some form of whole-program analysis, but that's a ways off right now.

The next best thing would be to have a general postcondition annotation language that could say "this function always returns true", but that's a sort of language extension even if we implement it with attributes or comments.

So the next best thing after that would be to tell the analyzer that it should stop analyzing this path, because it's "like" a noreturn path—that's what 'analyzer_noreturn' does. This does mean we might miss some warnings that would only occur on the error path, but it also cuts down on false positives that basically come from the interprocedural CFG not reflecting reality. There won't ever be a branch on which Error returns false and 'x' is actually uninitialized.

If/when we get either of the better two solutions, I'll take this back out.

Hope that's a solid enough explanation of the analyzer's limitations.
Jordan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130328/fe5ec414/attachment.html>


More information about the llvm-commits mailing list