This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rGd1522d349f4d: [-Wcompletion-handler] Support checks with builtins (authored by vsavchenko).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D96268/new/ https://reviews.llvm.org/D96268 Files: clang/lib/Analysis/CalledOnceCheck.cpp clang/test/SemaObjC/warn-called-once.m
Index: clang/test/SemaObjC/warn-called-once.m =================================================================== --- clang/test/SemaObjC/warn-called-once.m +++ clang/test/SemaObjC/warn-called-once.m @@ -4,6 +4,11 @@ #define nil (id)0 #define CALLED_ONCE __attribute__((called_once)) #define NORETURN __attribute__((noreturn)) +#define LIKELY(X) __builtin_expect(!!(X), 1) +#define UNLIKELY(X) __builtin_expect(!!(X), 0) +#define LIKELY_WITH_PROBA(X, P) __builtin_expect_with_probability(!!(X), 1, P) +#define UNLIKELY_WITH_PROBA(X, P) __builtin_expect_with_probability(!!(X), 0, P) +#define UNPRED(X) __builtin_unpredictable((long)(X)) @protocol NSObject @end @@ -547,6 +552,70 @@ // no-warning } +void call_with_builtin_check_1(int (^callback)(void) CALLED_ONCE) { + if (LIKELY(callback)) + callback(); + // no-warning +} + +void call_with_builtin_check_2(int (^callback)(void) CALLED_ONCE) { + if (!UNLIKELY(callback)) { + } else { + callback(); + } + // no-warning +} + +void call_with_builtin_check_3(int (^callback)(void) CALLED_ONCE) { + if (__builtin_expect((long)callback, 0L)) { + } else { + callback(); + } + // no-warning +} + +void call_with_builtin_check_4(int (^callback)(void) CALLED_ONCE) { + if (__builtin_expect(0L, (long)callback)) { + } else { + callback(); + } + // no-warning +} + +void call_with_builtin_check_5(int (^callback)(void) CALLED_ONCE) { + if (LIKELY_WITH_PROBA(callback, 0.9)) + callback(); + // no-warning +} + +void call_with_builtin_check_6(int (^callback)(void) CALLED_ONCE) { + if (!UNLIKELY_WITH_PROBA(callback, 0.9)) { + } else { + callback(); + } + // no-warning +} + +void call_with_builtin_check_7(int (^callback)(void) CALLED_ONCE) { + if (UNPRED(callback)) { + } else { + callback(); + } + // no-warning +} + +void call_with_builtin_check_8(int (^callback)(void) CALLED_ONCE) { + if (LIKELY(callback != nil)) + callback(); + // no-warning +} + +void call_with_builtin_check_9(int (^callback)(void) CALLED_ONCE) { + if (!UNLIKELY(callback == NULL)) + callback(); + // no-warning +} + void unreachable_true_branch(void (^callback)(void) CALLED_ONCE) { if (0) { Index: clang/lib/Analysis/CalledOnceCheck.cpp =================================================================== --- clang/lib/Analysis/CalledOnceCheck.cpp +++ clang/lib/Analysis/CalledOnceCheck.cpp @@ -22,6 +22,7 @@ #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/FlowSensitive/DataflowWorklist.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/BitVector.h" @@ -330,6 +331,29 @@ return Visit(OVE->getSourceExpr()); } + const DeclRefExpr *VisitCallExpr(const CallExpr *CE) { + if (!ShouldRetrieveFromComparisons) + return nullptr; + + // We want to see through some of the boolean builtin functions + // that we are likely to see in conditions. + switch (CE->getBuiltinCallee()) { + case Builtin::BI__builtin_expect: + case Builtin::BI__builtin_expect_with_probability: { + assert(CE->getNumArgs() >= 2); + + const DeclRefExpr *Candidate = Visit(CE->getArg(0)); + return Candidate != nullptr ? Candidate : Visit(CE->getArg(1)); + } + + case Builtin::BI__builtin_unpredictable: + return Visit(CE->getArg(0)); + + default: + return nullptr; + } + } + const DeclRefExpr *VisitExpr(const Expr *E) { // It is a fallback method that gets called whenever the actual type // of the given expression is not covered.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits