Improve the diagnostics for the UndefinedAssignmentChecker when an

uninitialized value is used in the LHS of a compound assignment.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99221 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ted Kremenek 2010-03-22 22:16:26 +00:00
Родитель f6728fcbec
Коммит 12182a0344
2 изменённых файлов: 34 добавлений и 11 удалений

Просмотреть файл

@ -53,27 +53,43 @@ void UndefinedAssignmentChecker::PreVisitBind(CheckerContext &C,
if (!N)
return;
const char *str = "Assigned value is garbage or undefined";
if (!BT)
BT = new BuiltinBug("Assigned value is garbage or undefined");
BT = new BuiltinBug(str);
// Generate a report for this bug.
EnhancedBugReport *R = new EnhancedBugReport(*BT, BT->getName(), N);
const Expr *ex = 0;
if (AssignE) {
const Expr *ex = 0;
while (AssignE) {
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(AssignE)) {
if (B->isCompoundAssignmentOp()) {
const GRState *state = C.getState();
if (state->getSVal(B->getLHS()).isUndef()) {
str = "The left expression of the compound assignment is an "
"uninitialized value. The computed value will also be garbage";
ex = B->getLHS();
break;
}
}
if (const BinaryOperator *B = dyn_cast<BinaryOperator>(AssignE))
ex = B->getRHS();
else if (const DeclStmt *DS = dyn_cast<DeclStmt>(AssignE)) {
break;
}
if (const DeclStmt *DS = dyn_cast<DeclStmt>(AssignE)) {
const VarDecl* VD = dyn_cast<VarDecl>(DS->getSingleDecl());
ex = VD->getInit();
}
if (ex) {
R->addRange(ex->getSourceRange());
R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
}
break;
}
EnhancedBugReport *R = new EnhancedBugReport(*BT, str, N);
if (ex) {
R->addRange(ex->getSourceRange());
R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, ex);
}
C.EmitReport(R);
}
}

Просмотреть файл

@ -59,4 +59,11 @@ void testFoo(Foo *o) {
[o passVal:x]; // expected-warning{{Passed-by-value struct argument contains uninitialized data (e.g., field: 'x')}}
}
// Test case from <rdar://problem/7780304>. That shows an uninitialized value
// being used in the LHS of a compound assignment.
void rdar_7780304() {
typedef struct s_r7780304 { int x; } s_r7780304;
s_r7780304 b;
b.x |= 1; // expected-warning{{The left expression of the compound assignment is an uninitialized value. The computed value will also be garbage}}
}