From 12182a0344c11970f307bc79eeb102633561b680 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 22 Mar 2010 22:16:26 +0000 Subject: [PATCH] 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 --- lib/Checker/UndefinedAssignmentChecker.cpp | 38 +++++++++++++++------- test/Analysis/uninit-vals-ps-region.m | 7 ++++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/lib/Checker/UndefinedAssignmentChecker.cpp b/lib/Checker/UndefinedAssignmentChecker.cpp index 7c33c1d392..9f17ef126d 100644 --- a/lib/Checker/UndefinedAssignmentChecker.cpp +++ b/lib/Checker/UndefinedAssignmentChecker.cpp @@ -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(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(AssignE)) ex = B->getRHS(); - else if (const DeclStmt *DS = dyn_cast(AssignE)) { + break; + } + + if (const DeclStmt *DS = dyn_cast(AssignE)) { const VarDecl* VD = dyn_cast(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); -} +} diff --git a/test/Analysis/uninit-vals-ps-region.m b/test/Analysis/uninit-vals-ps-region.m index 7e2fff9db5..69c1ecd1e3 100644 --- a/test/Analysis/uninit-vals-ps-region.m +++ b/test/Analysis/uninit-vals-ps-region.m @@ -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 . 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}} +} -- 2.40.0