Skip to content

Commit

Permalink
[GCChecker] update to run on Darwin
Browse files Browse the repository at this point in the history
and simplify some of the code and makefile rules
  • Loading branch information
vtjnash committed Oct 30, 2019
1 parent 4e31741 commit 4c775e7
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 48 deletions.
28 changes: 15 additions & 13 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,10 @@ FLAGS += -DLLVM_SHLIB
endif # USE_LLVM_SHLIB == 1
endif

CLANGLINK :=
CLANGLINK += -lclangAnalysis -lclangStaticAnalyzerCore -lclangASTMatchers -lclangAST -lclangLex -lclangBasic
CLANGLINK += $(LLVMLINK)

COMMON_LIBS := -L$(build_shlibdir) -L$(build_libdir) $(LIBUV) $(LIBUTF8PROC) $(NO_WHOLE_ARCHIVE) $(LLVMLINK) $(OSLIBS) $(LIBUNWIND)
DEBUG_LIBS := $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp-debug.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport-debug.a $(COMMON_LIBS)
RELEASE_LIBS := $(WHOLE_ARCHIVE) $(BUILDDIR)/flisp/libflisp.a $(WHOLE_ARCHIVE) $(BUILDDIR)/support/libsupport.a $(COMMON_LIBS)
Expand Down Expand Up @@ -344,7 +348,7 @@ clean-support:
cleanall: clean clean-flisp clean-support clean-analyzegc

$(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT): $(SRCDIR)/clangsa/GCChecker.cpp
@$(call PRINT_CC, $(CXX) -g $(fPIC) -shared -o $@ -DCLANG_PLUGIN -I$(build_includedir) $(shell $(LLVM_CONFIG_HOST) --cxxflags) $(CPPFLAGS) $(CFLAGS) $< $(shell $(LLVM_CONFIG_HOST) --ldflags) $(LDFLAGS) -L$(build_libdir) -lclangAnalysis -lclangStaticAnalyzerCore -lclangASTMatchers -lclangAST -lclangLex -lclangBasic)
@$(call PRINT_CC, $(CXX) -g $(fPIC) -shared -o $@ -DCLANG_PLUGIN -I$(build_includedir) $(shell $(LLVM_CONFIG_HOST) --cxxflags) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CXXLDFLAGS) -L$(build_libdir) $< $(CLANGLINK))

# Throw an error if a proper version of `clang` is not available.
# Note that for a default install, you will need to have run the following
Expand All @@ -354,24 +358,22 @@ $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT): $(SRCDIR)/clangsa/GCChecker.c
analyzegc-deps-check: $(BUILDDIR)/julia_version.h $(BUILDDIR)/julia_flisp.boot.inc
ifeq ($(USE_BINARYBUILDER_LLVM),0)
ifneq ($(BUILD_LLVM_CLANG),1)
$(error Clang must be available to use the clang analyzer. Either build it (BUILD_LLVM_CLANG) or use BinaryBuilder)
$(error Clang must be available to use the clang analyzer. Either build it (BUILD_LLVM_CLANG=1) or use BinaryBuilder)
endif
endif


define CLANG_ANALYZE
clang-sa-$(1): $$(build_shlibdir)/libGCCheckerPlugin.$$(SHLIB_EXT) | analyzegc-deps-check
@$$(call PRINT_ANALYZE, $$(build_depsbindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $$(build_shlibdir)/libGCCheckerPlugin.$$(SHLIB_EXT) $$(CPPFLAGS) $$(CFLAGS) $$(DEBUGFLAGS) -Xclang -analyzer-checker=core$$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c $$(SRCDIR)/$(1).c)
.PHONY: clang-sa-$(1)

# Add this as a target of `analyzegc`
analyzegc: clang-sa-$(1)
endef
CLANGSA_FLAGS :=
ifeq ($(OS), Darwin) # on new XCode, the files are hidden
CLANGSA_FLAGS += -isysroot $(shell xcode-select -p)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
endif
clang-sa-%: $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) | analyzegc-deps-check
@$(call PRINT_ANALYZE, $(build_depsbindir)/clang --analyze -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-output=text -Xclang -load -Xclang $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT) $(CLANGSA_FLAGS) $(CPPFLAGS) $(CFLAGS) $(DEBUGFLAGS) -Xclang -analyzer-checker=core$(COMMA)julia.GCChecker --analyzer-no-default-checks -fcolor-diagnostics -Werror -x c $(SRCDIR)/$*.c)

# Build a Makefile target for each file we want to analyze
$(foreach S,$(RUNTIME_C_SRCS),$(eval $(call CLANG_ANALYZE,$(S))))
# Add C files as a target of `analyzegc`
analyzegc: $(addprefix clang-sa-,$(RUNTIME_C_SRCS))

clean-analyzegc:
rm -f $(build_shlibdir)/libGCCheckerPlugin.$(SHLIB_EXT)

.PHONY: default all debug release clean cleanall clean-* libccalltest libllvmcalltest julia_flisp.boot.inc.phony analyzegc
.PHONY: default all debug release clean cleanall clean-* libccalltest libllvmcalltest julia_flisp.boot.inc.phony analyzegc clang-sa-*
47 changes: 13 additions & 34 deletions src/clangsa/GCChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
#endif
#include <iostream>

#if defined(__GNUC__)
# define USED_FUNC __attribute__((used))
#elif defined(_COMPILER_MICROSOFT_)
// Does MSVC have this?
# define USED_FUNC
#else
# define USED_FUNC
#endif

namespace {
using namespace clang;
using namespace ento;
Expand Down Expand Up @@ -164,7 +173,6 @@ namespace {

static bool isGCTrackedType(QualType Type);
bool isGloballyRootedType(QualType Type) const;
bool isBundleOfGCValues(QualType QT) const;
static void dumpState(const ProgramStateRef &State);
static bool declHasAnnotation(const clang::Decl *D, const char *which);
static bool isFDAnnotatedNotSafepoint(const clang::FunctionDecl *FD);
Expand Down Expand Up @@ -287,12 +295,6 @@ SymbolRef GCChecker::walkToRoot(callback f, const ProgramStateRef &State, const


namespace Helpers {
static SymbolRef trySuperRegion(SValExplainer &Ex, ProgramStateRef State, SVal Val) {
const MemRegion *R = Val.getAsRegion();
const SubRegion *SR = R->getAs<SubRegion>();
return SR ? State->getSVal(SR->getSuperRegion()).getAsSymbol() : nullptr;
}

static const VarRegion *walk_back_to_global_VR(const MemRegion *Region) {
if (!Region)
return nullptr;
Expand Down Expand Up @@ -451,7 +453,7 @@ PDP GCChecker::GCValueBugVisitor::VisitNode(
if (NewValueState->FD) {
bool isFunctionSafepoint = !isFDAnnotatedNotSafepoint(NewValueState->FD);
bool maybeUnrooted = declHasAnnotation(NewValueState->PVD, "julia_maybe_unrooted");
assert(isFunctionSafepoint || maybeUnrooted);
assert(isFunctionSafepoint || maybeUnrooted); (void)maybeUnrooted;
Pos = PathDiagnosticLocation{NewValueState->PVD,
BRC.getSourceManager()};
if (!isFunctionSafepoint)
Expand Down Expand Up @@ -684,14 +686,6 @@ bool GCChecker::isFDAnnotatedNotSafepoint(const clang::FunctionDecl *FD) {
return declHasAnnotation(FD, "julia_not_safepoint");
}

bool GCChecker::isBundleOfGCValues(QualType QT) const {
return isJuliaType([](StringRef Name) {
if (Name.endswith_lower("typemap_intersection_env"))
return true;
return false;
}, QT);
}

bool GCChecker::isGCTrackedType(QualType QT) {
return isValueCollection(QT) || isJuliaType([](StringRef Name) {
if (Name.endswith_lower("jl_value_t") ||
Expand Down Expand Up @@ -749,23 +743,8 @@ bool GCChecker::isGloballyRootedType(QualType QT) const {
bool GCChecker::isSafepoint(const CallEvent &Call) const
{
bool isCalleeSafepoint = true;
if (Call.isGlobalCFunction("malloc") ||
Call.isGlobalCFunction("memcpy") ||
Call.isGlobalCFunction("memset") ||
Call.isGlobalCFunction("memcmp") ||
Call.isGlobalCFunction("mmap") ||
Call.isGlobalCFunction("munmap") ||
Call.isGlobalCFunction("mprotect") ||
Call.isGlobalCFunction("madvise") ||
Call.isGlobalCFunction("write") ||
Call.isGlobalCFunction("vasprintf") ||
Call.isGlobalCFunction("strrchr") ||
Call.isGlobalCFunction("free") ||
Call.isGlobalCFunction("__assert_fail") ||
Call.isGlobalCFunction("fflush") ||
Call.isGlobalCFunction("__isnan") ||
Call.isGlobalCFunction("__isnanf"))
{
if (Call.isInSystemHeader()) {
// defined by -isystem per https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-in-system-headers
isCalleeSafepoint = false;
} else {
auto *Decl = Call.getDecl();
Expand Down Expand Up @@ -1149,7 +1128,7 @@ void GCChecker::checkPostStmt(const UnaryOperator *UO, CheckerContext &C) const
}
}

void GCChecker::dumpState(const ProgramStateRef &State) {
USED_FUNC void GCChecker::dumpState(const ProgramStateRef &State) {
GCValueMapTy AMap = State->get<GCValueMap>();
llvm::raw_ostream &Out = llvm::outs();
Out << "State: " << "\n";
Expand Down
2 changes: 1 addition & 1 deletion src/threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ JL_DLLEXPORT JL_CONST_FUNC jl_ptls_t (jl_get_ptls_states)(void) JL_GLOBALLY_ROOT
}

// This is only used after the tls is already initialized on the thread
static JL_CONST_FUNC jl_ptls_t jl_get_ptls_states_fast(void)
static JL_CONST_FUNC jl_ptls_t jl_get_ptls_states_fast(void) JL_NOTSAFEPOINT
{
return (jl_ptls_t)pthread_getspecific(jl_tls_key);
}
Expand Down

0 comments on commit 4c775e7

Please sign in to comment.