This revision was automatically updated to reflect the committed changes. Closed by commit rL283302: [analyzer] Improve "Assuming..." diagnostic pieces for logical operators. (authored by dergachev).
Changed prior to commit: https://reviews.llvm.org/D25092?vs=73472&id=73601#toc Repository: rL LLVM https://reviews.llvm.org/D25092 Files: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp cfe/trunk/test/Analysis/conditional-path-notes.c cfe/trunk/test/Analysis/edges-new.mm
Index: cfe/trunk/test/Analysis/conditional-path-notes.c =================================================================== --- cfe/trunk/test/Analysis/conditional-path-notes.c +++ cfe/trunk/test/Analysis/conditional-path-notes.c @@ -64,11 +64,12 @@ } } -void testNonDiagnosableBranchLogical(int a, int b) { +void testDiagnosableBranchLogical(int a, int b) { if (a && b) { - // expected-note@-1 {{Assuming the condition is true}} + // expected-note@-1 {{Assuming 'a' is not equal to 0}} // expected-note@-2 {{Left side of '&&' is true}} - // expected-note@-3 {{Taking true branch}} + // expected-note@-3 {{Assuming 'b' is not equal to 0}} + // expected-note@-4 {{Taking true branch}} *(volatile int *)0 = 1; // expected-warning{{Dereference of null pointer}} // expected-note@-1 {{Dereference of null pointer}} } @@ -1343,6 +1344,35 @@ // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>68</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>68</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>68</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Assuming 'a' is not equal to 0</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Assuming 'a' is not equal to 0</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> // CHECK-NEXT: <key>edges</key> // CHECK-NEXT: <array> @@ -1377,53 +1407,19 @@ // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>12</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> @@ -1435,9 +1431,9 @@ // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Assuming the condition is true</string> +// CHECK-NEXT: <string>Assuming 'b' is not equal to 0</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Assuming the condition is true</string> +// CHECK-NEXT: <string>Assuming 'b' is not equal to 0</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -1448,24 +1444,24 @@ // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>68</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>12</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1481,25 +1477,25 @@ // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1511,20 +1507,20 @@ // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>26</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1542,13 +1538,13 @@ // CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> // CHECK-NEXT: <key>check_name</key><string>core.NullDereference</string> // CHECK-NEXT: <!-- This hash is experimental and going to change! --> -// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>ebd0bb32bbdcaa2a806ff1984974c07a</string> +// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>a2b345c9681d9dd3aa15d12810759cb9</string> // CHECK-NEXT: <key>issue_context_kind</key><string>function</string> -// CHECK-NEXT: <key>issue_context</key><string>testNonDiagnosableBranchLogical</string> -// CHECK-NEXT: <key>issue_hash_function_offset</key><string>5</string> +// CHECK-NEXT: <key>issue_context</key><string>testDiagnosableBranchLogical</string> +// CHECK-NEXT: <key>issue_hash_function_offset</key><string>6</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>72</integer> +// CHECK-NEXT: <key>line</key><integer>73</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1564,25 +1560,25 @@ // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>78</integer> +// CHECK-NEXT: <key>line</key><integer>79</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>78</integer> +// CHECK-NEXT: <key>line</key><integer>79</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1598,25 +1594,25 @@ // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1628,20 +1624,20 @@ // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>26</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1665,7 +1661,7 @@ // CHECK-NEXT: <key>issue_hash_function_offset</key><string>3</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>80</integer> +// CHECK-NEXT: <key>line</key><integer>81</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> Index: cfe/trunk/test/Analysis/edges-new.mm =================================================================== --- cfe/trunk/test/Analysis/edges-new.mm +++ cfe/trunk/test/Analysis/edges-new.mm @@ -7655,53 +7655,19 @@ // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>22</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>19</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>19</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> @@ -7713,9 +7679,9 @@ // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Assuming the condition is true</string> +// CHECK-NEXT: <string>Assuming 'coin' is not equal to 0</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Assuming the condition is true</string> +// CHECK-NEXT: <string>Assuming 'coin' is not equal to 0</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -7726,12 +7692,12 @@ // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>19</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -8000,53 +7966,19 @@ // CHECK-NEXT: </array> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>kind</key><string>control</string> -// CHECK-NEXT: <key>edges</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>start</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>19</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>22</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: <key>end</key> -// CHECK-NEXT: <array> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> -// CHECK-NEXT: <key>file</key><integer>0</integer> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> -// CHECK-NEXT: </dict> -// CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>19</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>ranges</key> // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>19</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> @@ -8058,9 +7990,9 @@ // CHECK-NEXT: </array> // CHECK-NEXT: <key>depth</key><integer>0</integer> // CHECK-NEXT: <key>extended_message</key> -// CHECK-NEXT: <string>Assuming the condition is false</string> +// CHECK-NEXT: <string>Assuming 'coin' is 0</string> // CHECK-NEXT: <key>message</key> -// CHECK-NEXT: <string>Assuming the condition is false</string> +// CHECK-NEXT: <string>Assuming 'coin' is 0</string> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>kind</key><string>control</string> @@ -8071,12 +8003,12 @@ // CHECK-NEXT: <array> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>19</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>line</key><integer>263</integer> -// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </array> Index: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1271,15 +1271,48 @@ BugReporterContext &BRC) { const Expr *Cond = nullptr; + // In the code below, Term is a CFG terminator and Cond is a branch condition + // expression upon which the decision is made on this terminator. + // + // For example, in "if (x == 0)", the "if (x == 0)" statement is a terminator, + // and "x == 0" is the respective condition. + // + // Another example: in "if (x && y)", we've got two terminators and two + // conditions due to short-circuit nature of operator "&&": + // 1. The "if (x && y)" statement is a terminator, + // and "y" is the respective condition. + // 2. Also "x && ..." is another terminator, + // and "x" is its condition. + switch (Term->getStmtClass()) { + // FIXME: Stmt::SwitchStmtClass is worth handling, however it is a bit + // more tricky because there are more than two branches to account for. default: return nullptr; case Stmt::IfStmtClass: Cond = cast<IfStmt>(Term)->getCond(); break; case Stmt::ConditionalOperatorClass: Cond = cast<ConditionalOperator>(Term)->getCond(); break; + case Stmt::BinaryOperatorClass: + // When we encounter a logical operator (&& or ||) as a CFG terminator, + // then the condition is actually its LHS; otheriwse, we'd encounter + // the parent, such as if-statement, as a terminator. + const auto *BO = cast<BinaryOperator>(Term); + assert(BO->isLogicalOp() && + "CFG terminator is not a short-circuit operator!"); + Cond = BO->getLHS(); + break; + } + + // However, when we encounter a logical operator as a branch condition, + // then the condition is actually its RHS, because LHS would be + // the condition for the logical operator terminator. + while (const auto *InnerBO = dyn_cast<BinaryOperator>(Cond)) { + if (!InnerBO->isLogicalOp()) + break; + Cond = InnerBO->getRHS()->IgnoreParens(); } assert(Cond);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits