Skip to content

[pull] swiftwasm from swift/main #1131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions clang/lib/Analysis/CalledOnceCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -330,6 +331,29 @@ class DeclRefFinder
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.
Expand Down
4 changes: 1 addition & 3 deletions clang/lib/Analysis/RetainSummaryManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,7 @@ static bool isSubclass(const Decl *D,
}

static bool isOSObjectSubclass(const Decl *D) {
// OSSymbols are particular OSObjects that are allocated globally
// and therefore aren't really refcounted, so we ignore them.
return D && isSubclass(D, "OSMetaClassBase") && !isSubclass(D, "OSSymbol");
return D && isSubclass(D, "OSMetaClassBase");
}

static bool isOSObjectDynamicCast(StringRef S) {
Expand Down
10 changes: 0 additions & 10 deletions clang/test/Analysis/osobject-retain-release.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ struct MyArray : public OSArray {
OSObject *generateObject(OSObject *input) override;
};

// These are never refcounted.
struct OSSymbol : OSObject {};

struct OtherStruct {
static void doNothingToArray(OSArray *array);
OtherStruct(OSArray *arr);
Expand Down Expand Up @@ -757,10 +754,3 @@ void test() {
b(0);
}
} // namespace inherited_constructor_crash

namespace ossymbol_suppression {
OSSymbol *createSymbol();
void test() {
OSSymbol *sym = createSymbol(); // no-warning
}
} // namespace ossymbol_suppression
71 changes: 70 additions & 1 deletion clang/test/SemaObjC/warn-called-once.m
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
// RUN: %clang_cc1 -verify -fsyntax-only -fblocks -fobjc-exceptions -Wcompletion-handler %s
// RUN: %clang_cc1 -verify -fsyntax-only -fblocks -fobjc-exceptions -Wcompletion-handler -Wno-pointer-to-int-cast %s

#define NULL (void *)0
#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
Expand Down Expand Up @@ -547,6 +552,70 @@ int call_with_check_7(int (^callback)(void) CALLED_ONCE) {
// 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) {

Expand Down