r335559 - [analyzer] Track null and undef values through expressions with cleanups.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 25 16:55:07 PDT 2018


Author: dergachev
Date: Mon Jun 25 16:55:07 2018
New Revision: 335559

URL: http://llvm.org/viewvc/llvm-project?rev=335559&view=rev
Log:
[analyzer] Track null and undef values through expressions with cleanups.

ExprWithCleanups wraps full-expressions that require temporary destructors
and highlights the moment of time in which these destructors need to be called
(i.e., "at the end of the full-expression...").

Such expressions don't necessarily return an object; they may return anything,
including a null or undefined value.

When the analyzer tries to understand where the null or undefined value came
from in order to present better diagnostics to the user, it will now skip
any ExprWithCleanups it encounters and look into the expression itself.

Differential Revision: https://reviews.llvm.org/D48204

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
    cfe/trunk/test/Analysis/inlining/inline-defensive-checks.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=335559&r1=335558&r2=335559&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Mon Jun 25 16:55:07 2018
@@ -141,6 +141,8 @@ const Expr *bugreporter::getDerefExpr(co
       E = AE->getBase();
     } else if (const auto *PE = dyn_cast<ParenExpr>(E)) {
       E = PE->getSubExpr();
+    } else if (const auto *EWC = dyn_cast<ExprWithCleanups>(E)) {
+      E = EWC->getSubExpr();
     } else {
       // Other arbitrary stuff.
       break;

Modified: cfe/trunk/test/Analysis/inlining/inline-defensive-checks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inlining/inline-defensive-checks.cpp?rev=335559&r1=335558&r2=335559&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inlining/inline-defensive-checks.cpp (original)
+++ cfe/trunk/test/Analysis/inlining/inline-defensive-checks.cpp Mon Jun 25 16:55:07 2018
@@ -84,3 +84,20 @@ void testRefToField(Bar *b) {
   int &x = b->x; // no-warning
   x = 5;
 }
+
+namespace get_deref_expr_with_cleanups {
+struct S {
+~S();
+};
+S *conjure();
+// The argument won't be used, but it'll cause cleanups
+// to appear around the call site.
+S *get_conjured(S _) {
+  S *s = conjure();
+  if (s) {}
+  return s;
+}
+void test_conjured() {
+  S &s = *get_conjured(S()); // no-warning
+}
+} // namespace get_deref_expr_with_cleanups




More information about the cfe-commits mailing list