PR 17558 -- Question About Uninitialized Variables

Hey all,

I'm looking at this bug report here:
http://llvm.org/bugs/show_bug.cgi?id=17558

And I wanted to get some feedback/ask some questions before putting
the patch onto cfe-commits.

I've narrowed down the issue ClassifyRefs::VisitCastExpr. Once it sees
an expression like (void)&x, it'll proceed to classify the
UnaryOperator which is the immediate subexpression of the Cast
expression rather than the DeclRefExpr whose classification will be
queried later when checking for uninitialized variables.

So my idea was to pretty much make sure that when ClassifyRefs
encounters a Cast expression, it will classify the nested DeclRefExpr
instead. This way Clang will not think that (void)&x is initializing
x.

However, I think that a previous commit's test case (for PR 16054
-16054 – Missing "uninitialized" warning) seems to be relying on
this behavior. In test/Analysis/uninit-sometimes.cpp,we have

void PR16054() {
  int x; // expected-note {{variable}} expected-warning {{used uninitialized whenever function 'PR16054}}
  while (x != 0) { // expected-note {{use}}
    (void)&x;
  }
}

Changing (void)&x to (void)x results in the "sometimes-uninitialized"
warning becoming a regular "uninitialized" warning. I believe in this
case, this warning should be the regular uninitialized warning, am I
correct in assuming this?

Finally, I have this following piece of code which is of questionable
quality. The purpose of this hack is to make the code function the
same as before when it encounters one of these situations. More or
less, I don't want to dig into function calls (including typeid,
sizeof and uuid) and mark them as ignore because that would override
the mark on them as being used. I'm sure there's probably a better way
to do this though, thoughts?

  if (isa<CXXTypeidExpr>(S) || isa<CallExpr>(S) || isa<CXXUuidofExpr>(S)
      >> isa<SizeOfPackExpr>(S)) {
    classify(dyn_cast<Expr>(S), Ignore);
    return;
  }

Thanks!

uninitialized-warning.patch (3.61 KB)