diff --git a/Makefile.docker b/Makefile.docker
index 1ee2657a9728cf6c9c44e3c1601bd7655a7b2997..464e1dff2f4a9ff1b546cde78c47c3a563f53501 100644
--- a/Makefile.docker
+++ b/Makefile.docker
@@ -5,44 +5,57 @@ export DOCKER_FLAGS ?= --rm
 export DOCKER_MAKECMDGOALS_POSSIBLE = \
   all \
   buildtest \
+  scan-build \
+  scan-build-analyze \
   #
 export DOCKER_MAKECMDGOALS = $(filter $(MAKECMDGOALS),$(DOCKER_MAKECMDGOALS_POSSIBLE))
 
+# Docker creates the files .dockerinit and .dockerenv in the root directory of
+# the container, we check for the files to determine if we are inside a container.
+ifneq (,$(wildcard /.dockerinit /.dockerenv))
+  export INSIDE_DOCKER := 1
+else
+  export INSIDE_DOCKER := 0
+endif
+
 # Default target for building inside a Docker container if nothing was given
 export DOCKER_MAKECMDGOALS ?= all
 # List of all exported environment variables that shall be passed on to the
 # Docker container, they will only be passed if they are set from the
 # environment, not if they are only default Makefile values.
 export DOCKER_ENV_VARS = \
-  BINDIRBASE \
-  BOARD \
-  QUIET \
-  RIOT_VERSION \
   APPDIR \
+  AR \
+  ARFLAGS \
+  AS \
+  ASFLAGS \
   BINDIR \
+  BINDIRBASE \
+  BOARD \
   BUILDRELPATH \
-  ELFFILE \
-  HEXFILE \
-  LINKFLAGPREFIX \
-  CPPMIX \
-  PREFIX \
+  BUILDTEST_MCU_GROUP \
+  BUILDTEST_VERBOSE \
   CC \
-  CXX \
   CFLAGS \
-  CXXUWFLAGS \
+  CPPMIX \
+  CXX \
   CXXEXFLAGS \
-  AR \
-  ARFLAGS \
-  AS \
-  ASFLAGS \
+  CXXUWFLAGS \
+  ELFFILE \
+  HEXFILE \
   LINK \
+  LINKFLAGPREFIX \
   LINKFLAGS \
   OBJCOPY \
   OFLAGS \
+  PREFIX \
+  QUIET \
+  RIOT_VERSION \
+  SCANBUILD_ARGS \
+  SCANBUILD_OUTPUTDIR \
   SIZE \
+  TOOLCHAIN \
   UNDEF \
-  BUILDTEST_MCU_GROUP \
-  BUILDTEST_VERBOSE \
   #
 
 # Find which variables were set using the command line or the environment and
@@ -51,9 +64,9 @@ export DOCKER_ENV_VARS = \
 # of the environment variables will be overwritten by Makefile.include and their
 # origin is changed to "file"
 DOCKER_ENVIRONMENT_CMDLINE := $(foreach varname,$(DOCKER_ENV_VARS), \
-    $(if $(filter environment command,$(origin $(varname))), \
-    -e '$(varname)=$($(varname))', \
-    ))
+  $(if $(filter environment command,$(origin $(varname))), \
+  -e '$(varname)=$(subst ','\'',$($(varname)))', \
+  ))
 DOCKER_ENVIRONMENT_CMDLINE := $(strip $(DOCKER_ENVIRONMENT_CMDLINE))
 
 # This will execute `make $(DOCKER_MAKECMDGOALS)` inside a Docker container.
@@ -70,6 +83,7 @@ DOCKER_ENVIRONMENT_CMDLINE := $(strip $(DOCKER_ENVIRONMENT_CMDLINE))
 	    -v '$(RIOTCPU):$(DOCKER_BUILD_ROOT)/riotcpu' \
 	    -v '$(RIOTBOARD):$(DOCKER_BUILD_ROOT)/riotboard' \
 	    -v '$(RIOTPROJECT):$(DOCKER_BUILD_ROOT)/riotproject' \
+	    -v /etc/localtime:/etc/localtime:ro \
 	    -e 'RIOTBASE=$(DOCKER_BUILD_ROOT)/riotbase' \
 	    -e 'RIOTCPU=$(DOCKER_BUILD_ROOT)/riotcpu' \
 	    -e 'RIOTBOARD=$(DOCKER_BUILD_ROOT)/riotboard' \
diff --git a/Makefile.include b/Makefile.include
index 8b253f64c811ef26822681ed702778240b352259..dcf05902b9ca36a060b8d6d9da26db80b808f66b 100644
--- a/Makefile.include
+++ b/Makefile.include
@@ -18,6 +18,9 @@ RIOTPROJECT := $(abspath $(RIOTPROJECT))
 # using abspath, strip etc.
 include $(RIOTBASE)/Makefile.docker
 
+# Static code analysis tools provided by LLVM
+include $(RIOTBASE)/Makefile.scan-build
+
 # Path to the current directory relative to the git root
 BUILDRELPATH ?= $(shell git rev-parse --show-prefix)
 
@@ -54,6 +57,12 @@ ifeq (, ${JENKINS_URL})
   endif
 endif
 
+ifeq ($(OS),Darwin)
+  OPEN   := open
+else
+  OPEN   := xdg-open
+endif
+
 ifeq ($(QUIET),1)
 	AD=@
 	MAKEFLAGS += --no-print-directory
diff --git a/Makefile.scan-build b/Makefile.scan-build
new file mode 100644
index 0000000000000000000000000000000000000000..5137d05a2ca90c672537e9243d69d93901ea9803
--- /dev/null
+++ b/Makefile.scan-build
@@ -0,0 +1,91 @@
+SCANBUILD_ENV_VARS := \
+  APPDIR \
+  AR \
+  ARFLAGS \
+  AS \
+  ASFLAGS \
+  BINDIR \
+  BINDIRBASE \
+  BOARD \
+  BUILDRELPATH \
+  CC \
+  CFLAGS \
+  CPPMIX \
+  CXX \
+  CXXEXFLAGS \
+  CXXUWFLAGS \
+  ELFFILE \
+  HEXFILE \
+  HOME \
+  LINK \
+  LINKFLAGPREFIX \
+  LINKFLAGS \
+  OBJCOPY \
+  OFLAGS \
+  PATH \
+  PREFIX \
+  QUIET \
+  RIOT_VERSION \
+  SIZE \
+  TOOLCHAIN \
+  UNDEF \
+  USER \
+  #
+
+SCANBUILD_ARGS ?= \
+  -analyze-headers \
+  --use-cc=$(CC) \
+  --use-c++=$(CXX) \
+  -analyzer-config stable-report-filename=true \
+  #
+
+export SCANBUILD_OUTPUTDIR = $(CURDIR)/scan-build/
+
+# Find all variables given on the command line and recreate the command.
+CMDVARS := $(strip $(foreach varname, $(SCANBUILD_ENV_VARS), \
+  $(if $(filter command, $(origin $(varname))), \
+  '$(varname)=$(subst ','\'',$($(varname)))', \
+  )))
+ENVVARS := $(strip $(foreach varname, $(SCANBUILD_ENV_VARS), \
+  $(if $(filter environment, $(origin $(varname))), \
+  '$(varname)=$(subst ','\'',$($(varname)))', \
+  )))
+
+.PHONY: scan-build scan-build-analyze scan-build-view
+scan-build: scan-build-view scan-build-analyze
+scan-build-view: scan-build-analyze
+ifeq ($(BUILD_IN_DOCKER),1)
+scan-build-analyze: ..in-docker-container
+else # BUILD_IN_DOCKER
+scan-build-analyze: clean
+	@$(COLOR_ECHO) '$(COLOR_GREEN)Performing Clang static code analysis using toolchain "$(TOOLCHAIN)".$(COLOR_RESET)'
+# ccc-analyzer needs to be told the proper -target setting for best results,
+# otherwise false error reports about unknown register names etc will be produced.
+# These kinds of errors can be safely ignored as long as they only come from LLVM
+	@if [ "$${TOOLCHAIN}" != "llvm" -a "$${BOARD}" != "native" ]; then \
+	  $(COLOR_ECHO) '$(COLOR_YELLOW)Recommend using TOOLCHAIN=llvm for best results.$(COLOR_RESET)'; \
+	  $(COLOR_ECHO) '$(COLOR_YELLOW)Ignore any "error: unknown register name '\''rX'\'' in asm" messages.$(COLOR_RESET)'; \
+	fi
+	$(AD)mkdir -p '$(SCANBUILD_OUTPUTDIR)'
+	$(AD)env -i $(ENVVARS) \
+	    scan-build -o '$(SCANBUILD_OUTPUTDIR)' $(SCANBUILD_ARGS) \
+	      make -C $(CURDIR) all $(strip $(CMDVARS));
+endif # BUILD_IN_DOCKER
+
+ifeq (1,$(INSIDE_DOCKER))
+scan-build-view:
+	@
+else
+	@echo "Showing most recent report in your web browser..."
+	@REPORT_FILE="$$(find '$(SCANBUILD_OUTPUTDIR)' -maxdepth 2 -mindepth 2 \
+	            -type f -name 'index.html' 2>/dev/null | sort | tail -n 1)"; \
+	  if [ -n "$${REPORT_FILE}" ]; then \
+	    echo "$(OPEN) $${REPORT_FILE}"; \
+	    $(OPEN) "$${REPORT_FILE}"; \
+	  else \
+	    echo "No report found"; \
+	  fi
+endif
+
+# Reset the default goal.
+.DEFAULT_GOAL :=