diff --git a/NEWS b/NEWS
index c57c9dca3..349010e53 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 ver 0.20.7 (not yet released)
 * database
   - simple: fix false positive directory loop detection with NFS
+* fix random crashes when compiled with clang
 
 ver 0.20.6 (2017/03/10)
 * input
diff --git a/src/AudioParser.hxx b/src/AudioParser.hxx
index 6923dbad5..36c36740a 100644
--- a/src/AudioParser.hxx
+++ b/src/AudioParser.hxx
@@ -25,8 +25,6 @@
 #ifndef MPD_AUDIO_PARSER_HXX
 #define MPD_AUDIO_PARSER_HXX
 
-#include "Compiler.h"
-
 struct AudioFormat;
 
 /**
@@ -38,7 +36,6 @@ struct AudioFormat;
  * @param src the input string
  * @param mask if true, then "*" is allowed for any number of items
  */
-gcc_pure
 AudioFormat
 ParseAudioFormat(const char *src, bool mask);
 
diff --git a/src/Instance.hxx b/src/Instance.hxx
index babc0b3e6..7084b6089 100644
--- a/src/Instance.hxx
+++ b/src/Instance.hxx
@@ -117,7 +117,6 @@ struct Instance final
 	 * DatabaseError if this MPD configuration has no database (no
 	 * music_directory was configured).
 	 */
-	gcc_pure
 	const Database &GetDatabaseOrThrow() const;
 #endif
 
diff --git a/src/Main.cxx b/src/Main.cxx
index 0ea263a87..4924fbb2a 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -130,7 +130,6 @@ struct Config {
 	ReplayGainConfig replay_gain;
 };
 
-gcc_const
 static Config
 LoadConfig()
 {
diff --git a/src/Partition.hxx b/src/Partition.hxx
index b3c0bad72..873f40c92 100644
--- a/src/Partition.hxx
+++ b/src/Partition.hxx
@@ -200,7 +200,6 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
 	 */
 	const Database *GetDatabase() const;
 
-	gcc_pure
 	const Database &GetDatabaseOrThrow() const;
 
 	/**
diff --git a/src/Permission.cxx b/src/Permission.cxx
index 39b33bf1d..e955c4ca5 100644
--- a/src/Permission.cxx
+++ b/src/Permission.cxx
@@ -49,7 +49,6 @@ static std::map<std::string, unsigned> permission_passwords;
 
 static unsigned permission_default;
 
-gcc_pure
 static unsigned
 ParsePermission(const char *p)
 {
diff --git a/src/ReplayGainMode.hxx b/src/ReplayGainMode.hxx
index 37b76f16f..885151704 100644
--- a/src/ReplayGainMode.hxx
+++ b/src/ReplayGainMode.hxx
@@ -42,7 +42,6 @@ ToString(ReplayGainMode mode) noexcept;
  * Parse a string to a #ReplayGainMode.  Throws std::runtime_error on
  * error.
  */
-gcc_pure
 ReplayGainMode
 FromString(const char *s);
 
diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx
index 96edfdea1..ed556ede0 100644
--- a/src/SongFilter.cxx
+++ b/src/SongFilter.cxx
@@ -57,7 +57,6 @@ locate_parse_type(const char *str) noexcept
 	return tag_name_parse_i(str);
 }
 
-gcc_pure
 static AllocatedString<>
 ImportString(const char *p, bool fold_case)
 {
diff --git a/src/client/Client.hxx b/src/client/Client.hxx
index 24461878e..c3a9a9cc0 100644
--- a/src/client/Client.hxx
+++ b/src/client/Client.hxx
@@ -191,7 +191,6 @@ public:
 	/**
 	 * Wrapper for Instance::GetDatabaseOrThrow().
 	 */
-	gcc_pure
 	const Database &GetDatabaseOrThrow() const;
 
 	gcc_pure
diff --git a/src/config/Block.cxx b/src/config/Block.cxx
index 2f26de368..723e5f6f0 100644
--- a/src/config/Block.cxx
+++ b/src/config/Block.cxx
@@ -129,7 +129,6 @@ ConfigBlock::GetBlockValue(const char *name, unsigned default_value) const
 	return bp->GetUnsignedValue();
 }
 
-gcc_pure
 bool
 ConfigBlock::GetBlockValue(const char *name, bool default_value) const
 {
diff --git a/src/config/Block.hxx b/src/config/Block.hxx
index 8003a31b0..edfa5a7d2 100644
--- a/src/config/Block.hxx
+++ b/src/config/Block.hxx
@@ -44,13 +44,10 @@ struct BlockParam {
 	BlockParam(const char *_name, const char *_value, int _line=-1)
 		:name(_name), value(_value), line(_line), used(false) {}
 
-	gcc_pure
 	int GetIntValue() const;
 
-	gcc_pure
 	unsigned GetUnsignedValue() const;
 
-	gcc_pure
 	bool GetBoolValue() const;
 };
 
@@ -116,13 +113,10 @@ struct ConfigBlock {
 	AllocatedPath GetPath(const char *name,
 			      const char *default_value=nullptr) const;
 
-	gcc_pure
 	int GetBlockValue(const char *name, int default_value) const;
 
-	gcc_pure
 	unsigned GetBlockValue(const char *name, unsigned default_value) const;
 
-	gcc_pure
 	bool GetBlockValue(const char *name, bool default_value) const;
 };
 
diff --git a/src/config/ConfigGlobal.hxx b/src/config/ConfigGlobal.hxx
index b6c86b3c1..89a4b7cad 100644
--- a/src/config/ConfigGlobal.hxx
+++ b/src/config/ConfigGlobal.hxx
@@ -61,18 +61,9 @@ config_get_block(enum ConfigBlockOption option) noexcept;
  * @param key the attribute name
  * @param value the expected attribute value
  */
-gcc_pure
 const ConfigBlock *
 config_find_block(ConfigBlockOption option, const char *key, const char *value);
 
-/* Note on gcc_pure: Some of the functions declared pure are not
-   really pure in strict sense.  They have side effect such that they
-   validate parameter's value and signal an error if it's invalid.
-   However, if the argument was already validated or we don't care
-   about the argument at all, this may be ignored so in the end, we
-   should be fine with calling those functions pure.  */
-
-gcc_pure
 const char *
 config_get_string(enum ConfigOption option,
 		  const char *default_value=nullptr) noexcept;
@@ -87,11 +78,9 @@ config_get_string(enum ConfigOption option,
 AllocatedPath
 config_get_path(enum ConfigOption option);
 
-gcc_pure
 unsigned
 config_get_unsigned(enum ConfigOption option, unsigned default_value);
 
-gcc_pure
 static inline std::chrono::steady_clock::duration
 config_get_unsigned(ConfigOption option,
 		    std::chrono::steady_clock::duration default_value)
@@ -101,11 +90,9 @@ config_get_unsigned(ConfigOption option,
 	return std::chrono::steady_clock::duration(u);
 }
 
-gcc_pure
 unsigned
 config_get_positive(enum ConfigOption option, unsigned default_value);
 
-gcc_pure
 static inline std::chrono::steady_clock::duration
 config_get_positive(ConfigOption option,
 		    std::chrono::steady_clock::duration default_value)
@@ -115,7 +102,6 @@ config_get_positive(ConfigOption option,
 	return std::chrono::steady_clock::duration(u);
 }
 
-gcc_pure
 bool config_get_bool(enum ConfigOption option, bool default_value);
 
 #endif
diff --git a/src/config/Param.hxx b/src/config/Param.hxx
index e0a4b9a19..50c514a19 100644
--- a/src/config/Param.hxx
+++ b/src/config/Param.hxx
@@ -71,7 +71,6 @@ struct ConfigParam {
 	 *
 	 * Throws #std::runtime_error on error.
 	 */
-	gcc_pure
 	AllocatedPath GetPath() const;
 };
 
diff --git a/src/db/DatabaseSong.hxx b/src/db/DatabaseSong.hxx
index bafc1df89..9b3e36589 100644
--- a/src/db/DatabaseSong.hxx
+++ b/src/db/DatabaseSong.hxx
@@ -31,7 +31,6 @@ class DetachedSong;
  * "Detach" the #Song object, i.e. convert it to a #DetachedSong
  * instance.
  */
-gcc_pure
 DetachedSong
 DatabaseDetachSong(const Storage &storage, const LightSong &song);
 
diff --git a/src/fs/AllocatedPath.hxx b/src/fs/AllocatedPath.hxx
index 2ee55479e..513453ffd 100644
--- a/src/fs/AllocatedPath.hxx
+++ b/src/fs/AllocatedPath.hxx
@@ -159,7 +159,7 @@ public:
 	 * Convert a UTF-8 C string to an #AllocatedPath instance.
 	 * Throws a std::runtime_error on error.
 	 */
-	gcc_pure gcc_nonnull_all
+	gcc_nonnull_all
 	static AllocatedPath FromUTF8Throw(const char *path_utf8);
 
 	/**
diff --git a/src/fs/Charset.hxx b/src/fs/Charset.hxx
index 84cf64ec6..7f7097b95 100644
--- a/src/fs/Charset.hxx
+++ b/src/fs/Charset.hxx
@@ -49,7 +49,7 @@ DeinitFSCharset() noexcept;
  *
  * Throws std::runtime_error on error.
  */
-gcc_pure gcc_nonnull_all
+gcc_nonnull_all
 PathTraitsUTF8::string
 PathToUTF8(PathTraitsFS::const_pointer_type path_fs);
 
@@ -58,7 +58,7 @@ PathToUTF8(PathTraitsFS::const_pointer_type path_fs);
  *
  * Throws std::runtime_error on error.
  */
-gcc_pure gcc_nonnull_all
+gcc_nonnull_all
 PathTraitsFS::string
 PathFromUTF8(PathTraitsUTF8::const_pointer_type path_utf8);
 
diff --git a/src/fs/io/BufferedReader.hxx b/src/fs/io/BufferedReader.hxx
index 6495b71ef..0e1b4a5b7 100644
--- a/src/fs/io/BufferedReader.hxx
+++ b/src/fs/io/BufferedReader.hxx
@@ -65,7 +65,6 @@ public:
 	 * it).  Throws std::runtime_error if not enough data is
 	 * available.
 	 */
-	gcc_pure
 	void *ReadFull(size_t size);
 
 	void Consume(size_t n) {
diff --git a/src/fs/io/FileReader.hxx b/src/fs/io/FileReader.hxx
index 7ca981f7d..7dc122217 100644
--- a/src/fs/io/FileReader.hxx
+++ b/src/fs/io/FileReader.hxx
@@ -86,7 +86,6 @@ public:
 
 	void Close();
 
-	gcc_pure
 	FileInfo GetFileInfo() const;
 
 	gcc_pure
diff --git a/src/lib/icu/Collate.hxx b/src/lib/icu/Collate.hxx
index d6f999214..d6cfcb764 100644
--- a/src/lib/icu/Collate.hxx
+++ b/src/lib/icu/Collate.hxx
@@ -38,7 +38,7 @@ gcc_pure gcc_nonnull_all
 int
 IcuCollate(const char *a, const char *b) noexcept;
 
-gcc_pure gcc_nonnull_all
+gcc_nonnull_all
 AllocatedString<char>
 IcuCaseFold(const char *src);
 
diff --git a/src/lib/icu/Converter.hxx b/src/lib/icu/Converter.hxx
index 80eec20c0..7ce545cf6 100644
--- a/src/lib/icu/Converter.hxx
+++ b/src/lib/icu/Converter.hxx
@@ -81,7 +81,7 @@ public:
 	 *
 	 * Throws std::runtime_error on error.
 	 */
-	gcc_pure gcc_nonnull_all
+	gcc_nonnull_all
 	AllocatedString<char> ToUTF8(const char *s) const;
 
 	/**
@@ -89,7 +89,7 @@ public:
 	 *
 	 * Throws std::runtime_error on error.
 	 */
-	gcc_pure gcc_nonnull_all
+	gcc_nonnull_all
 	AllocatedString<char> FromUTF8(const char *s) const;
 };
 
diff --git a/src/output/Wrapper.hxx b/src/output/Wrapper.hxx
index 55ffc91f4..5eb3d599c 100644
--- a/src/output/Wrapper.hxx
+++ b/src/output/Wrapper.hxx
@@ -68,7 +68,6 @@ struct AudioOutputWrapper {
 		return t.Delay();
 	}
 
-	gcc_pure
 	static void SendTag(AudioOutput *ao, const Tag &tag) {
 		T &t = Cast(*ao);
 		t.SendTag(tag);
@@ -89,7 +88,6 @@ struct AudioOutputWrapper {
 		t.Cancel();
 	}
 
-	gcc_pure
 	static bool Pause(AudioOutput *ao) {
 		T &t = Cast(*ao);
 		return t.Pause();
diff --git a/src/output/plugins/ShoutOutputPlugin.cxx b/src/output/plugins/ShoutOutputPlugin.cxx
index 8e797d9bd..16607fd62 100644
--- a/src/output/plugins/ShoutOutputPlugin.cxx
+++ b/src/output/plugins/ShoutOutputPlugin.cxx
@@ -74,7 +74,6 @@ static int shout_init_count;
 
 static constexpr Domain shout_output_domain("shout_output");
 
-gcc_pure
 static const char *
 require_block_string(const ConfigBlock &block, const char *name)
 {
diff --git a/src/protocol/ArgParser.hxx b/src/protocol/ArgParser.hxx
index 135f9e74b..8a23f25a8 100644
--- a/src/protocol/ArgParser.hxx
+++ b/src/protocol/ArgParser.hxx
@@ -21,7 +21,6 @@
 #define MPD_PROTOCOL_ARGPARSER_HXX
 
 #include "check.h"
-#include "Compiler.h"
 
 #include <limits>
 
@@ -30,15 +29,12 @@
 class SongTime;
 class SignedSongTime;
 
-gcc_pure
 uint32_t
 ParseCommandArgU32(const char *s);
 
-gcc_pure
 int
 ParseCommandArgInt(const char *s, int min_value, int max_value);
 
-gcc_pure
 int
 ParseCommandArgInt(const char *s);
 
@@ -55,31 +51,24 @@ struct RangeArg {
 	}
 };
 
-gcc_pure
 RangeArg
 ParseCommandArgRange(const char *s);
 
-gcc_pure
 unsigned
 ParseCommandArgUnsigned(const char *s, unsigned max_value);
 
-gcc_pure
 unsigned
 ParseCommandArgUnsigned(const char *s);
 
-gcc_pure
 bool
 ParseCommandArgBool(const char *s);
 
-gcc_pure
 float
 ParseCommandArgFloat(const char *s);
 
-gcc_pure
 SongTime
 ParseCommandArgSongTime(const char *s);
 
-gcc_pure
 SignedSongTime
 ParseCommandArgSignedSongTime(const char *s);
 
diff --git a/src/sticker/SongSticker.hxx b/src/sticker/SongSticker.hxx
index f52175e97..ea78d4e47 100644
--- a/src/sticker/SongSticker.hxx
+++ b/src/sticker/SongSticker.hxx
@@ -21,7 +21,6 @@
 #define MPD_SONG_STICKER_HXX
 
 #include "Match.hxx"
-#include "Compiler.h"
 
 #include <string>
 
@@ -34,7 +33,6 @@ class Database;
  *
  * Throws #SqliteError on error.
  */
-gcc_pure
 std::string
 sticker_song_get_value(const LightSong &song, const char *name);
 
diff --git a/src/storage/plugins/LocalStorage.cxx b/src/storage/plugins/LocalStorage.cxx
index 389d52a26..816286b1b 100644
--- a/src/storage/plugins/LocalStorage.cxx
+++ b/src/storage/plugins/LocalStorage.cxx
@@ -71,7 +71,6 @@ private:
 	AllocatedPath MapFSOrThrow(const char *uri_utf8) const;
 };
 
-gcc_pure
 static StorageFileInfo
 Stat(Path path, bool follow)
 {
diff --git a/src/util/TimeParser.cxx b/src/util/TimeParser.cxx
index b99433a75..9ce915c7f 100644
--- a/src/util/TimeParser.cxx
+++ b/src/util/TimeParser.cxx
@@ -28,6 +28,7 @@
  */
 
 #include "TimeParser.hxx"
+#include "Compiler.h"
 
 #include <stdexcept>
 
diff --git a/src/util/TimeParser.hxx b/src/util/TimeParser.hxx
index 8b539b4a7..97aa0c016 100644
--- a/src/util/TimeParser.hxx
+++ b/src/util/TimeParser.hxx
@@ -30,8 +30,6 @@
 #ifndef TIME_PARSER_HXX
 #define TIME_PARSER_HXX
 
-#include "Compiler.h"
-
 #include <chrono>
 
 /**
@@ -39,7 +37,6 @@
  *
  * Throws std::runtime_error on error.
  */
-gcc_pure
 std::chrono::system_clock::time_point
 ParseTimePoint(const char *s, const char *format);