This revision was automatically updated to reflect the committed changes. Closed by commit rL343902: Thread safety analysis: Handle conditional expression in getTrylockCallExpr (authored by aaronpuchert, committed by ). Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D52888?vs=168295&id=168557#toc Repository: rL LLVM https://reviews.llvm.org/D52888 Files: cfe/trunk/lib/Analysis/ThreadSafety.cpp cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp Index: cfe/trunk/lib/Analysis/ThreadSafety.cpp =================================================================== --- cfe/trunk/lib/Analysis/ThreadSafety.cpp +++ cfe/trunk/lib/Analysis/ThreadSafety.cpp @@ -1435,6 +1435,17 @@ if (BOP->getOpcode() == BO_LOr) return getTrylockCallExpr(BOP->getRHS(), C, Negate); return nullptr; + } else if (const auto *COP = dyn_cast<ConditionalOperator>(Cond)) { + bool TCond, FCond; + if (getStaticBooleanValue(COP->getTrueExpr(), TCond) && + getStaticBooleanValue(COP->getFalseExpr(), FCond)) { + if (TCond && !FCond) + return getTrylockCallExpr(COP->getCond(), C, Negate); + if (!TCond && FCond) { + Negate = !Negate; + return getTrylockCallExpr(COP->getCond(), C, Negate); + } + } } return nullptr; } @@ -1449,7 +1460,8 @@ Result = ExitSet; const Stmt *Cond = PredBlock->getTerminatorCondition(); - if (!Cond) + // We don't acquire try-locks on ?: branches, only when its result is used. + if (!Cond || isa<ConditionalOperator>(PredBlock->getTerminator())) return; bool Negate = false; Index: cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp =================================================================== --- cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp +++ cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1873,6 +1873,23 @@ int i = a; mu.Unlock(); } + + // Test with conditional operator + void foo13() { + if (mu.TryLock() ? 1 : 0) + mu.Unlock(); + } + + void foo14() { + if (mu.TryLock() ? 0 : 1) + return; + mu.Unlock(); + } + + void foo15() { + if (mu.TryLock() ? 0 : 1) // expected-note{{mutex acquired here}} + mu.Unlock(); // expected-warning{{releasing mutex 'mu' that was not held}} + } // expected-warning{{mutex 'mu' is not held on every path through here}} }; // end TestTrylock } // end namespace TrylockTest
Index: cfe/trunk/lib/Analysis/ThreadSafety.cpp =================================================================== --- cfe/trunk/lib/Analysis/ThreadSafety.cpp +++ cfe/trunk/lib/Analysis/ThreadSafety.cpp @@ -1435,6 +1435,17 @@ if (BOP->getOpcode() == BO_LOr) return getTrylockCallExpr(BOP->getRHS(), C, Negate); return nullptr; + } else if (const auto *COP = dyn_cast<ConditionalOperator>(Cond)) { + bool TCond, FCond; + if (getStaticBooleanValue(COP->getTrueExpr(), TCond) && + getStaticBooleanValue(COP->getFalseExpr(), FCond)) { + if (TCond && !FCond) + return getTrylockCallExpr(COP->getCond(), C, Negate); + if (!TCond && FCond) { + Negate = !Negate; + return getTrylockCallExpr(COP->getCond(), C, Negate); + } + } } return nullptr; } @@ -1449,7 +1460,8 @@ Result = ExitSet; const Stmt *Cond = PredBlock->getTerminatorCondition(); - if (!Cond) + // We don't acquire try-locks on ?: branches, only when its result is used. + if (!Cond || isa<ConditionalOperator>(PredBlock->getTerminator())) return; bool Negate = false; Index: cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp =================================================================== --- cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp +++ cfe/trunk/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1873,6 +1873,23 @@ int i = a; mu.Unlock(); } + + // Test with conditional operator + void foo13() { + if (mu.TryLock() ? 1 : 0) + mu.Unlock(); + } + + void foo14() { + if (mu.TryLock() ? 0 : 1) + return; + mu.Unlock(); + } + + void foo15() { + if (mu.TryLock() ? 0 : 1) // expected-note{{mutex acquired here}} + mu.Unlock(); // expected-warning{{releasing mutex 'mu' that was not held}} + } // expected-warning{{mutex 'mu' is not held on every path through here}} }; // end TestTrylock } // end namespace TrylockTest
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits