[clang] c86dacd - [-Wcalled-once-parameter] Let escapes overwrite MaybeCalled states

Valeriy Savchenko via cfe-commits cfe-commits at lists.llvm.org
Wed Mar 17 01:13:09 PDT 2021


Author: Valeriy Savchenko
Date: 2021-03-17T11:12:55+03:00
New Revision: c86dacd1a4489572721dec3135506d31da96c679

URL: https://github.com/llvm/llvm-project/commit/c86dacd1a4489572721dec3135506d31da96c679
DIFF: https://github.com/llvm/llvm-project/commit/c86dacd1a4489572721dec3135506d31da96c679.diff

LOG: [-Wcalled-once-parameter] Let escapes overwrite MaybeCalled states

This commit makes escapes symmetrical, meaning that having escape
before and after the branching, where parameter is not called on
one of the paths, will have the same effect.

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

Added: 
    

Modified: 
    clang/lib/Analysis/CalledOnceCheck.cpp
    clang/test/SemaObjC/warn-called-once.m

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/CalledOnceCheck.cpp b/clang/lib/Analysis/CalledOnceCheck.cpp
index 2438c50d7e4e..d24e0b500564 100644
--- a/clang/lib/Analysis/CalledOnceCheck.cpp
+++ b/clang/lib/Analysis/CalledOnceCheck.cpp
@@ -867,16 +867,14 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
     // Let's check if any of the call arguments is a point of interest.
     for (const auto &Argument : llvm::enumerate(Arguments)) {
       if (auto Index = getIndexOfExpression(Argument.value())) {
-        ParameterStatus &CurrentParamStatus = CurrentState.getStatusFor(*Index);
-
         if (shouldBeCalledOnce(CallOrMessage, Argument.index())) {
           // If the corresponding parameter is marked as 'called_once' we should
           // consider it as a call.
           processCallFor(*Index, CallOrMessage);
-        } else if (CurrentParamStatus.getKind() == ParameterStatus::NotCalled) {
+        } else {
           // Otherwise, we mark this parameter as escaped, which can be
           // interpreted both as called or not called depending on the context.
-          CurrentParamStatus = ParameterStatus::Escaped;
+          processEscapeFor(*Index);
         }
         // Otherwise, let's keep the state as it is.
       }
@@ -910,6 +908,16 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
     }
   }
 
+  /// Process escape of the parameter with the given index
+  void processEscapeFor(unsigned Index) {
+    ParameterStatus &CurrentParamStatus = CurrentState.getStatusFor(Index);
+
+    // Escape overrides whatever error we think happened.
+    if (CurrentParamStatus.isErrorStatus()) {
+      CurrentParamStatus = ParameterStatus::Escaped;
+    }
+  }
+
   void findAndReportNotCalledBranches(const CFGBlock *Parent, unsigned Index,
                                       bool IsEscape = false) {
     for (const CFGBlock *Succ : Parent->succs()) {
@@ -1365,11 +1373,7 @@ class CalledOnceChecker : public ConstStmtVisitor<CalledOnceChecker> {
   /// Check given parameter that was discovered to escape.
   void checkEscapee(const ParmVarDecl &Parameter) {
     if (auto Index = getIndex(Parameter)) {
-      ParameterStatus &CurrentParamStatus = CurrentState.getStatusFor(*Index);
-
-      if (CurrentParamStatus.getKind() == ParameterStatus::NotCalled) {
-        CurrentParamStatus = ParameterStatus::Escaped;
-      }
+      processEscapeFor(*Index);
     }
   }
 

diff  --git a/clang/test/SemaObjC/warn-called-once.m b/clang/test/SemaObjC/warn-called-once.m
index 3d846deca921..7d0679035238 100644
--- a/clang/test/SemaObjC/warn-called-once.m
+++ b/clang/test/SemaObjC/warn-called-once.m
@@ -1130,4 +1130,32 @@ - (void)test_nil_suppression_3:(int)cond1
   }
 }
 
+- (void)test_escape_before_branch:(int)cond
+                   withCompletion:(void (^)(void))handler {
+  if (cond) {
+    filler();
+  }
+
+  void (^copiedHandler)(void) = ^{
+    handler();
+  };
+
+  if (cond) {
+    // no-warning
+    handler();
+  } else {
+    copiedHandler();
+  }
+}
+
+- (void)test_escape_after_branch:(int)cond
+                  withCompletion:(void (^)(void))handler {
+  if (cond) {
+    // no-warning
+    handler();
+  }
+
+  escape(handler);
+}
+
 @end


        


More information about the cfe-commits mailing list