From 71f0ed8b7499011b53f90998ebfbd3250fd80948 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Mon, 8 May 2017 14:44:49 +0200
Subject: [PATCH] *: add "noexcept" to many, many function prototypes

This eliminates some overhead, because the compiler doesn't need to
consider these functions throwing.
---
 src/AudioFormat.cxx                           |  4 +-
 src/AudioFormat.hxx                           |  4 +-
 src/DetachedSong.cxx                          |  8 ++--
 src/DetachedSong.hxx                          | 18 +++----
 src/IOThread.cxx                              |  4 +-
 src/IOThread.hxx                              |  4 +-
 src/IdleFlags.cxx                             |  4 +-
 src/IdleFlags.hxx                             |  5 +-
 src/Mapper.cxx                                | 10 ++--
 src/Mapper.hxx                                | 10 ++--
 src/MusicBuffer.cxx                           |  6 +--
 src/MusicBuffer.hxx                           |  6 +--
 src/MusicChunk.cxx                            |  6 +--
 src/MusicChunk.hxx                            |  6 +--
 src/MusicPipe.cxx                             |  2 +-
 src/MusicPipe.hxx                             |  2 +-
 src/ReplayGainInfo.cxx                        |  2 +-
 src/ReplayGainInfo.hxx                        |  8 ++--
 src/ReplayGainMode.cxx                        |  2 +-
 src/ReplayGainMode.hxx                        |  2 +-
 src/SongFilter.cxx                            | 22 ++++-----
 src/SongFilter.hxx                            | 28 +++++------
 src/StateFile.cxx                             |  4 +-
 src/StateFile.hxx                             |  4 +-
 src/TagStream.cxx                             |  2 +-
 src/archive/ArchiveLookup.cxx                 |  4 +-
 src/archive/plugins/Bzip2ArchivePlugin.cxx    |  4 +-
 src/archive/plugins/Iso9660ArchivePlugin.cxx  |  4 +-
 src/archive/plugins/ZzipArchivePlugin.cxx     |  4 +-
 src/client/Client.cxx                         |  4 +-
 src/client/Client.hxx                         |  6 +--
 src/client/ClientMessage.cxx                  |  4 +-
 src/client/ClientMessage.hxx                  |  2 +-
 src/command/CommandError.cxx                  |  6 +--
 src/command/FileCommands.cxx                  |  8 ++--
 src/command/NeighborCommands.cxx              |  2 +-
 src/command/NeighborCommands.hxx              |  2 +-
 src/command/PlaylistCommands.cxx              |  2 +-
 src/command/PlaylistCommands.hxx              |  2 +-
 src/command/StorageCommands.cxx               |  2 +-
 src/config/Block.cxx                          |  5 +-
 src/config/Block.hxx                          |  4 +-
 src/config/ConfigGlobal.cxx                   |  6 +--
 src/config/ConfigGlobal.hxx                   |  7 +--
 src/config/ConfigOption.hxx                   |  4 +-
 src/config/ConfigTemplates.cxx                |  6 +--
 src/db/DatabaseLock.hxx                       |  2 +-
 src/db/LightSong.cxx                          |  2 +-
 src/db/LightSong.hxx                          |  4 +-
 src/db/PlaylistVector.cxx                     |  2 +-
 src/db/PlaylistVector.hxx                     |  2 +-
 src/db/Registry.cxx                           |  2 +-
 src/db/Registry.hxx                           |  2 +-
 src/db/Selection.cxx                          |  6 +--
 src/db/Selection.hxx                          |  6 +--
 src/db/plugins/ProxyDatabasePlugin.cxx        |  6 +--
 src/db/plugins/simple/Directory.cxx           | 18 +++----
 src/db/plugins/simple/Directory.hxx           | 24 +++++-----
 src/db/plugins/simple/DirectorySave.cxx       |  4 +-
 src/db/plugins/simple/Song.cxx                |  4 +-
 src/db/plugins/simple/Song.hxx                |  4 +-
 src/db/plugins/simple/SongSort.cxx            | 13 +++--
 src/db/plugins/simple/SongSort.hxx            |  2 +-
 src/db/plugins/upnp/Directory.cxx             |  6 +--
 src/db/plugins/upnp/Directory.hxx             |  2 +-
 src/db/update/InotifyQueue.cxx                |  2 +-
 src/db/update/InotifyUpdate.cxx               | 10 ++--
 src/db/update/InotifyUpdate.hxx               |  2 +-
 src/db/update/UpdateIO.cxx                    | 10 ++--
 src/db/update/UpdateIO.hxx                    | 10 ++--
 src/db/update/Walk.cxx                        |  4 +-
 src/db/update/Walk.hxx                        |  2 +-
 src/decoder/Bridge.cxx                        | 12 ++---
 src/decoder/Bridge.hxx                        |  8 ++--
 src/decoder/DecoderControl.cxx                |  2 +-
 src/decoder/DecoderControl.hxx                |  4 +-
 src/decoder/DecoderList.cxx                   |  4 +-
 src/decoder/DecoderList.hxx                   |  4 +-
 src/decoder/DecoderPlugin.cxx                 |  4 +-
 src/decoder/DecoderPlugin.hxx                 |  4 +-
 src/decoder/DecoderThread.cxx                 |  8 ++--
 .../plugins/AudiofileDecoderPlugin.cxx        |  4 +-
 src/decoder/plugins/DsdLib.cxx                |  4 +-
 src/decoder/plugins/DsdLib.hxx                |  4 +-
 src/decoder/plugins/FfmpegDecoderPlugin.cxx   | 18 +++----
 src/decoder/plugins/FlacMetadata.cxx          |  4 +-
 src/decoder/plugins/GmeDecoderPlugin.cxx      |  2 +-
 src/decoder/plugins/MadDecoderPlugin.cxx      | 16 +++----
 src/decoder/plugins/OpusTags.cxx              |  2 +-
 src/decoder/plugins/SidplayDecoderPlugin.cxx  |  4 +-
 src/decoder/plugins/SndfileDecoderPlugin.cxx  |  2 +-
 src/decoder/plugins/WavpackDecoderPlugin.cxx  |  2 +-
 src/event/ServerSocket.cxx                    | 10 ++--
 src/filter/FilterRegistry.cxx                 |  2 +-
 src/filter/FilterRegistry.hxx                 |  2 +-
 src/fs/AllocatedPath.cxx                      |  8 ++--
 src/fs/AllocatedPath.hxx                      | 12 ++---
 src/fs/Charset.cxx                            |  4 +-
 src/fs/Charset.hxx                            |  4 +-
 src/fs/Path.cxx                               |  4 +-
 src/fs/Path.hxx                               | 14 +++---
 src/fs/Path2.cxx                              |  2 +-
 src/fs/StandardDirectory.cxx                  | 24 ++++++----
 src/fs/StandardDirectory.hxx                  | 20 +++++---
 src/fs/Traits.cxx                             | 17 +++----
 src/fs/Traits.hxx                             | 18 +++----
 src/fs/io/AutoGunzipReader.cxx                |  2 +-
 src/fs/io/FileOutputStream.cxx                |  4 +-
 src/fs/io/FileOutputStream.hxx                |  2 +-
 src/fs/io/FileReader.hxx                      |  4 +-
 src/input/AsyncInputStream.cxx                |  4 +-
 src/input/AsyncInputStream.hxx                |  4 +-
 src/input/InputStream.cxx                     |  8 ++--
 src/input/InputStream.hxx                     |  8 ++--
 src/input/ProxyInputStream.cxx                |  4 +-
 src/input/ProxyInputStream.hxx                |  4 +-
 src/input/ThreadInputStream.cxx               |  4 +-
 src/input/ThreadInputStream.hxx               |  4 +-
 src/input/plugins/CdioParanoiaInputPlugin.cxx |  4 +-
 src/input/plugins/FfmpegInputPlugin.cxx       |  4 +-
 src/input/plugins/FileInputPlugin.cxx         |  2 +-
 src/input/plugins/RewindInputPlugin.cxx       |  2 +-
 src/input/plugins/SmbclientInputPlugin.cxx    |  2 +-
 src/lib/curl/Request.cxx                      |  2 +-
 src/lib/curl/Version.cxx                      |  2 +-
 src/lib/curl/Version.hxx                      |  2 +-
 src/lib/expat/ExpatParser.cxx                 |  4 +-
 src/lib/expat/ExpatParser.hxx                 | 12 ++---
 src/lib/ffmpeg/LogCallback.cxx                |  2 +-
 src/lib/ffmpeg/Time.hxx                       |  8 ++--
 src/lib/icu/Collate.cxx                       |  4 +-
 src/lib/icu/Collate.hxx                       |  4 +-
 src/lib/nfs/Base.cxx                          |  2 +-
 src/lib/nfs/Base.hxx                          |  2 +-
 src/lib/nfs/Cancellable.hxx                   | 14 +++---
 src/lib/nfs/Connection.hxx                    |  2 +-
 src/lib/nfs/Glue.cxx                          |  2 +-
 src/lib/nfs/Glue.hxx                          |  2 +-
 src/lib/nfs/Manager.cxx                       |  8 ++--
 src/lib/nfs/Manager.hxx                       |  8 ++--
 src/lib/upnp/Discovery.cxx                    |  4 +-
 src/lib/upnp/Util.cxx                         | 12 ++---
 src/lib/upnp/Util.hxx                         |  8 ++--
 src/ls.cxx                                    |  3 +-
 src/ls.hxx                                    |  3 +-
 src/mixer/MixerAll.cxx                        | 15 +++---
 src/mixer/MixerType.cxx                       |  2 +-
 src/mixer/MixerType.hxx                       |  5 +-
 src/mixer/Volume.cxx                          |  6 +--
 src/mixer/Volume.hxx                          |  6 +--
 src/mixer/plugins/AlsaMixerPlugin.cxx         |  3 +-
 src/mixer/plugins/SoftwareMixerPlugin.cxx     |  2 +-
 src/neighbor/Glue.cxx                         |  2 +-
 src/neighbor/Glue.hxx                         |  2 +-
 src/neighbor/Registry.cxx                     |  2 +-
 src/neighbor/Registry.hxx                     |  2 +-
 .../plugins/SmbclientNeighborPlugin.cxx       |  4 +-
 src/net/AllocatedSocketAddress.cxx            |  4 +-
 src/net/AllocatedSocketAddress.hxx            |  4 +-
 src/net/SocketAddress.cxx                     |  2 +-
 src/net/SocketAddress.hxx                     |  4 +-
 src/net/SocketError.cxx                       |  4 +-
 src/net/SocketError.hxx                       | 18 +++----
 src/net/StaticSocketAddress.cxx               |  2 +-
 src/net/StaticSocketAddress.hxx               |  2 +-
 src/net/ToString.cxx                          | 10 ++--
 src/net/ToString.hxx                          |  4 +-
 src/output/Init.cxx                           |  2 +-
 src/output/Internal.cxx                       |  2 +-
 src/output/Internal.hxx                       |  4 +-
 src/output/MultipleOutputs.cxx                |  8 ++--
 src/output/MultipleOutputs.hxx                | 16 +++----
 src/output/OutputPlugin.cxx                   |  2 +-
 src/output/OutputPlugin.hxx                   |  4 +-
 src/output/SharedPipeConsumer.cxx             |  4 +-
 src/output/SharedPipeConsumer.hxx             |  6 +--
 src/output/Source.cxx                         |  6 +--
 src/output/Source.hxx                         | 10 ++--
 src/output/Wrapper.hxx                        |  2 +-
 src/output/plugins/AlsaOutputPlugin.cxx       |  4 +-
 src/output/plugins/FifoOutputPlugin.cxx       |  4 +-
 src/output/plugins/JackOutputPlugin.cxx       |  6 +--
 src/output/plugins/NullOutputPlugin.cxx       |  2 +-
 src/output/plugins/OpenALOutputPlugin.cxx     |  2 +-
 src/output/plugins/OssOutputPlugin.cxx        |  4 +-
 src/output/plugins/PulseOutputPlugin.cxx      |  1 -
 src/output/plugins/RoarOutputPlugin.cxx       |  2 +-
 src/output/plugins/ShoutOutputPlugin.cxx      |  4 +-
 src/output/plugins/httpd/HttpdClient.cxx      |  2 +-
 src/output/plugins/httpd/HttpdClient.hxx      |  2 +-
 src/output/plugins/httpd/HttpdInternal.hxx    |  2 +-
 .../plugins/httpd/HttpdOutputPlugin.cxx       |  4 +-
 src/pcm/ChannelsConverter.cxx                 |  2 +-
 src/pcm/ChannelsConverter.hxx                 |  2 +-
 src/pcm/FloatConvert.hxx                      |  4 +-
 src/pcm/FormatConverter.cxx                   |  4 +-
 src/pcm/FormatConverter.hxx                   |  6 +--
 src/pcm/PcmExport.cxx                         |  8 ++--
 src/pcm/PcmExport.hxx                         |  8 ++--
 src/pcm/PcmFormat.cxx                         |  8 ++--
 src/pcm/PcmFormat.hxx                         |  8 ++--
 src/pcm/PcmUtils.hxx                          |  2 +-
 src/pcm/SampleFormat.cxx                      |  2 +-
 src/pcm/SampleFormat.hxx                      |  2 +-
 src/pcm/SoxrResampler.cxx                     |  4 +-
 src/pcm/Volume.cxx                            |  2 +-
 src/pcm/Volume.hxx                            |  2 +-
 src/player/Control.cxx                        |  2 +-
 src/player/Control.hxx                        |  6 +--
 src/player/CrossFade.cxx                      |  4 +-
 src/player/CrossFade.hxx                      |  2 +-
 src/playlist/cue/CueParser.cxx                | 12 ++---
 src/playlist/cue/CueParser.hxx                | 12 ++---
 src/queue/Playlist.cxx                        |  6 +--
 src/queue/Playlist.hxx                        |  6 +--
 src/queue/Queue.cxx                           | 25 +++++-----
 src/queue/Queue.hxx                           | 22 ++++-----
 src/sticker/StickerDatabase.cxx               |  4 +-
 src/sticker/StickerDatabase.hxx               |  4 +-
 src/storage/CompositeStorage.cxx              | 16 +++----
 src/storage/CompositeStorage.hxx              | 16 +++----
 src/storage/Configured.cxx                    |  2 +-
 src/storage/Configured.hxx                    |  2 +-
 src/storage/Registry.cxx                      |  2 +-
 src/storage/Registry.hxx                      |  2 +-
 src/storage/StorageInterface.cxx              |  4 +-
 src/storage/StorageInterface.hxx              |  8 ++--
 src/storage/plugins/CurlStorage.cxx           | 10 ++--
 src/storage/plugins/LocalStorage.cxx          | 14 +++---
 src/storage/plugins/NfsStorage.cxx            | 10 ++--
 src/storage/plugins/SmbclientStorage.cxx      | 10 ++--
 src/system/Error.hxx                          |  6 +--
 src/system/FileDescriptor.cxx                 | 28 +++++------
 src/system/FileDescriptor.hxx                 | 48 +++++++++----------
 src/tag/Format.cxx                            |  8 ++--
 src/tag/Format.hxx                            |  2 +-
 src/tag/Id3Load.cxx                           |  2 +-
 src/tag/Settings.hxx                          |  4 +-
 src/tag/Tag.cxx                               |  8 ++--
 src/tag/Tag.hxx                               |  8 ++--
 src/tag/TagBuilder.cxx                        |  6 +--
 src/tag/TagBuilder.hxx                        |  6 +--
 src/tag/TagId3.cxx                            |  4 +-
 src/tag/TagString.cxx                         |  2 +-
 src/tag/TagTable.cxx                          |  6 +--
 src/tag/TagTable.hxx                          |  6 +--
 src/tag/VorbisComment.cxx                     |  2 +-
 src/tag/VorbisComment.hxx                     |  2 +-
 src/thread/Id.hxx                             |  4 +-
 src/unix/PidFile.hxx                          |  2 +-
 src/util/ASCII.hxx                            |  4 +-
 src/util/HugeAllocator.cxx                    |  2 +-
 src/util/PeakBuffer.cxx                       |  9 ++--
 src/util/PeakBuffer.hxx                       |  6 +--
 src/util/StringAPI.hxx                        | 26 +++++-----
 src/util/StringCompare.cxx                    |  6 +--
 src/util/StringCompare.hxx                    | 10 ++--
 src/util/StringUtil.cxx                       | 20 ++++----
 src/util/StringUtil.hxx                       | 23 ++++-----
 src/util/TimeParser.cxx                       |  2 +-
 src/util/UTF8.cxx                             | 21 ++++----
 src/util/UTF8.hxx                             | 12 ++---
 src/util/UriUtil.cxx                          | 29 +++++------
 src/util/UriUtil.hxx                          | 21 ++++----
 src/util/WStringAPI.hxx                       | 26 +++++-----
 src/util/WStringCompare.cxx                   |  8 ++--
 src/util/WStringCompare.hxx                   | 10 ++--
 test/dump_rva2.cxx                            |  2 +-
 test/read_mixer.cxx                           |  2 +-
 test/run_output.cxx                           |  2 +-
 test/test_rewind.cxx                          |  2 +-
 test/test_translate_song.cxx                  |  6 +--
 272 files changed, 873 insertions(+), 846 deletions(-)

diff --git a/src/AudioFormat.cxx b/src/AudioFormat.cxx
index 9a9f8ab5e..f317d8abe 100644
--- a/src/AudioFormat.cxx
+++ b/src/AudioFormat.cxx
@@ -24,7 +24,7 @@
 #include <stdio.h>
 
 void
-AudioFormat::ApplyMask(AudioFormat mask)
+AudioFormat::ApplyMask(AudioFormat mask) noexcept
 {
 	assert(IsValid());
 	assert(mask.IsMaskValid());
@@ -42,7 +42,7 @@ AudioFormat::ApplyMask(AudioFormat mask)
 }
 
 StringBuffer<24>
-ToString(const AudioFormat af)
+ToString(const AudioFormat af) noexcept
 {
 	StringBuffer<24> buffer;
 
diff --git a/src/AudioFormat.hxx b/src/AudioFormat.hxx
index e48d2c8cf..04c682b54 100644
--- a/src/AudioFormat.hxx
+++ b/src/AudioFormat.hxx
@@ -124,7 +124,7 @@ struct AudioFormat {
 		return !(*this == other);
 	}
 
-	void ApplyMask(AudioFormat mask);
+	void ApplyMask(AudioFormat mask) noexcept;
 
 	gcc_pure
 	AudioFormat WithMask(AudioFormat mask) const {
@@ -223,6 +223,6 @@ AudioFormat::GetTimeToSize() const
  */
 gcc_const
 StringBuffer<24>
-ToString(AudioFormat af);
+ToString(AudioFormat af) noexcept;
 
 #endif
diff --git a/src/DetachedSong.cxx b/src/DetachedSong.cxx
index 8bef0f6ff..e4a292814 100644
--- a/src/DetachedSong.cxx
+++ b/src/DetachedSong.cxx
@@ -37,19 +37,19 @@ DetachedSong::~DetachedSong()
 }
 
 bool
-DetachedSong::IsRemote() const
+DetachedSong::IsRemote() const noexcept
 {
 	return uri_has_scheme(GetRealURI());
 }
 
 bool
-DetachedSong::IsAbsoluteFile() const
+DetachedSong::IsAbsoluteFile() const noexcept
 {
 	return PathTraitsUTF8::IsAbsolute(GetRealURI());
 }
 
 bool
-DetachedSong::IsInDatabase() const
+DetachedSong::IsInDatabase() const noexcept
 {
 	/* here, we use GetURI() and not GetRealURI() because
 	   GetRealURI() is never relative */
@@ -59,7 +59,7 @@ DetachedSong::IsInDatabase() const
 }
 
 SignedSongTime
-DetachedSong::GetDuration() const
+DetachedSong::GetDuration() const noexcept
 {
 	SongTime a = start_time, b = end_time;
 	if (!b.IsPositive()) {
diff --git a/src/DetachedSong.hxx b/src/DetachedSong.hxx
index 083cad610..9d1f1edd9 100644
--- a/src/DetachedSong.hxx
+++ b/src/DetachedSong.hxx
@@ -100,7 +100,7 @@ public:
 	~DetachedSong();
 
 	gcc_pure
-	const char *GetURI() const {
+	const char *GetURI() const noexcept {
 		return uri.c_str();
 	}
 
@@ -114,7 +114,7 @@ public:
 	 * displayed URI?
 	 */
 	gcc_pure
-	bool HasRealURI() const {
+	bool HasRealURI() const noexcept {
 		return !real_uri.empty();
 	}
 
@@ -123,7 +123,7 @@ public:
 	 * GetURI().
 	 */
 	gcc_pure
-	const char *GetRealURI() const {
+	const char *GetRealURI() const noexcept {
 		return (HasRealURI() ? real_uri : uri).c_str();
 	}
 
@@ -137,19 +137,19 @@ public:
 	 * song.
 	 */
 	gcc_pure
-	bool IsSame(const DetachedSong &other) const {
+	bool IsSame(const DetachedSong &other) const noexcept {
 		return uri == other.uri &&
 			start_time == other.start_time &&
 			end_time == other.end_time;
 	}
 
 	gcc_pure gcc_nonnull_all
-	bool IsURI(const char *other_uri) const {
+	bool IsURI(const char *other_uri) const noexcept {
 		return uri == other_uri;
 	}
 
 	gcc_pure
-	bool IsRemote() const;
+	bool IsRemote() const noexcept;
 
 	gcc_pure
 	bool IsFile() const {
@@ -157,10 +157,10 @@ public:
 	}
 
 	gcc_pure
-	bool IsAbsoluteFile() const;
+	bool IsAbsoluteFile() const noexcept;
 
 	gcc_pure
-	bool IsInDatabase() const;
+	bool IsInDatabase() const noexcept;
 
 	const Tag &GetTag() const {
 		return tag;
@@ -215,7 +215,7 @@ public:
 	}
 
 	gcc_pure
-	SignedSongTime GetDuration() const;
+	SignedSongTime GetDuration() const noexcept;
 
 	/**
 	 * Update the #tag and #mtime.
diff --git a/src/IOThread.cxx b/src/IOThread.cxx
index 252540501..a83c125a7 100644
--- a/src/IOThread.cxx
+++ b/src/IOThread.cxx
@@ -96,7 +96,7 @@ io_thread_deinit(void)
 }
 
 EventLoop &
-io_thread_get()
+io_thread_get() noexcept
 {
 	assert(io.loop != nullptr);
 
@@ -104,7 +104,7 @@ io_thread_get()
 }
 
 bool
-io_thread_inside(void)
+io_thread_inside() noexcept
 {
 	return io.thread.IsInside();
 }
diff --git a/src/IOThread.hxx b/src/IOThread.hxx
index f769f8ad4..63cbbee6e 100644
--- a/src/IOThread.hxx
+++ b/src/IOThread.hxx
@@ -51,13 +51,13 @@ io_thread_deinit();
 
 gcc_const
 EventLoop &
-io_thread_get();
+io_thread_get() noexcept;
 
 /**
  * Is the current thread the I/O thread?
  */
 gcc_pure
 bool
-io_thread_inside();
+io_thread_inside() noexcept;
 
 #endif
diff --git a/src/IdleFlags.cxx b/src/IdleFlags.cxx
index 84b49add3..823dde823 100644
--- a/src/IdleFlags.cxx
+++ b/src/IdleFlags.cxx
@@ -46,13 +46,13 @@ static const char *const idle_names[] = {
 };
 
 const char*const*
-idle_get_names(void)
+idle_get_names() noexcept
 {
         return idle_names;
 }
 
 unsigned
-idle_parse_name(const char *name)
+idle_parse_name(const char *name) noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
diff --git a/src/IdleFlags.hxx b/src/IdleFlags.hxx
index 423ad272d..ce991d92c 100644
--- a/src/IdleFlags.hxx
+++ b/src/IdleFlags.hxx
@@ -70,8 +70,9 @@ static constexpr unsigned IDLE_MOUNT = 0x1000;
 /**
  * Get idle names
  */
+gcc_const
 const char*const*
-idle_get_names();
+idle_get_names() noexcept;
 
 /**
  * Parse an idle name and return its mask.  Returns 0 if the given
@@ -79,6 +80,6 @@ idle_get_names();
  */
 gcc_nonnull_all gcc_pure
 unsigned
-idle_parse_name(const char *name);
+idle_parse_name(const char *name) noexcept;
 
 #endif
diff --git a/src/Mapper.cxx b/src/Mapper.cxx
index 5df4a962e..959e6836e 100644
--- a/src/Mapper.cxx
+++ b/src/Mapper.cxx
@@ -59,14 +59,14 @@ mapper_init(AllocatedPath &&_playlist_dir)
 }
 
 void
-mapper_finish()
+mapper_finish() noexcept
 {
 }
 
 #ifdef ENABLE_DATABASE
 
 AllocatedPath
-map_uri_fs(const char *uri)
+map_uri_fs(const char *uri) noexcept
 {
 	assert(uri != nullptr);
 	assert(*uri != '/');
@@ -86,7 +86,7 @@ map_uri_fs(const char *uri)
 }
 
 std::string
-map_fs_to_utf8(Path path_fs)
+map_fs_to_utf8(Path path_fs) noexcept
 {
 	if (path_fs.IsAbsolute()) {
 		if (instance->storage == nullptr)
@@ -109,13 +109,13 @@ map_fs_to_utf8(Path path_fs)
 #endif
 
 const AllocatedPath &
-map_spl_path()
+map_spl_path() noexcept
 {
 	return playlist_dir_fs;
 }
 
 AllocatedPath
-map_spl_utf8_to_fs(const char *name)
+map_spl_utf8_to_fs(const char *name) noexcept
 {
 	if (playlist_dir_fs.IsNull())
 		return AllocatedPath::Null();
diff --git a/src/Mapper.hxx b/src/Mapper.hxx
index befab774e..55731a6d8 100644
--- a/src/Mapper.hxx
+++ b/src/Mapper.hxx
@@ -37,7 +37,7 @@ void
 mapper_init(AllocatedPath &&playlist_dir);
 
 void
-mapper_finish();
+mapper_finish() noexcept;
 
 #ifdef ENABLE_DATABASE
 
@@ -48,7 +48,7 @@ mapper_finish();
  */
 gcc_pure
 AllocatedPath
-map_uri_fs(const char *uri);
+map_uri_fs(const char *uri) noexcept;
 
 /**
  * Maps a file system path (relative to the music directory or
@@ -60,7 +60,7 @@ map_uri_fs(const char *uri);
  */
 gcc_pure
 std::string
-map_fs_to_utf8(Path path_fs);
+map_fs_to_utf8(Path path_fs) noexcept;
 
 #endif
 
@@ -69,7 +69,7 @@ map_fs_to_utf8(Path path_fs);
  */
 gcc_const
 const AllocatedPath &
-map_spl_path();
+map_spl_path() noexcept;
 
 /**
  * Maps a playlist name (without the ".m3u" suffix) to a file system
@@ -79,6 +79,6 @@ map_spl_path();
  */
 gcc_pure
 AllocatedPath
-map_spl_utf8_to_fs(const char *name);
+map_spl_utf8_to_fs(const char *name) noexcept;
 
 #endif
diff --git a/src/MusicBuffer.cxx b/src/MusicBuffer.cxx
index defd0d2fc..2d08f42f1 100644
--- a/src/MusicBuffer.cxx
+++ b/src/MusicBuffer.cxx
@@ -23,19 +23,19 @@
 
 #include <assert.h>
 
-MusicBuffer::MusicBuffer(unsigned num_chunks)
+MusicBuffer::MusicBuffer(unsigned num_chunks) noexcept
 	:buffer(num_chunks) {
 }
 
 MusicChunk *
-MusicBuffer::Allocate()
+MusicBuffer::Allocate() noexcept
 {
 	const std::lock_guard<Mutex> protect(mutex);
 	return buffer.Allocate();
 }
 
 void
-MusicBuffer::Return(MusicChunk *chunk)
+MusicBuffer::Return(MusicChunk *chunk) noexcept
 {
 	assert(chunk != nullptr);
 
diff --git a/src/MusicBuffer.hxx b/src/MusicBuffer.hxx
index 108e2522c..1c51839e2 100644
--- a/src/MusicBuffer.hxx
+++ b/src/MusicBuffer.hxx
@@ -41,7 +41,7 @@ public:
 	 * @param num_chunks the number of #MusicChunk reserved in
 	 * this buffer
 	 */
-	MusicBuffer(unsigned num_chunks);
+	MusicBuffer(unsigned num_chunks) noexcept;
 
 #ifndef NDEBUG
 	/**
@@ -71,13 +71,13 @@ public:
 	 * @return an empty chunk or nullptr if there are no chunks
 	 * available
 	 */
-	MusicChunk *Allocate();
+	MusicChunk *Allocate() noexcept;
 
 	/**
 	 * Returns a chunk to the buffer.  It can be reused by
 	 * Allocate() then.
 	 */
-	void Return(MusicChunk *chunk);
+	void Return(MusicChunk *chunk) noexcept;
 };
 
 #endif
diff --git a/src/MusicChunk.cxx b/src/MusicChunk.cxx
index 55a9f98b1..581974ae4 100644
--- a/src/MusicChunk.cxx
+++ b/src/MusicChunk.cxx
@@ -31,7 +31,7 @@ MusicChunk::~MusicChunk()
 
 #ifndef NDEBUG
 bool
-MusicChunk::CheckFormat(const AudioFormat other_format) const
+MusicChunk::CheckFormat(const AudioFormat other_format) const noexcept
 {
 	assert(other_format.IsValid());
 
@@ -41,7 +41,7 @@ MusicChunk::CheckFormat(const AudioFormat other_format) const
 
 WritableBuffer<void>
 MusicChunk::Write(const AudioFormat af,
-		  SongTime data_time, uint16_t _bit_rate)
+		  SongTime data_time, uint16_t _bit_rate) noexcept
 {
 	assert(CheckFormat(af));
 	assert(length == 0 || audio_format.IsValid());
@@ -64,7 +64,7 @@ MusicChunk::Write(const AudioFormat af,
 }
 
 bool
-MusicChunk::Expand(const AudioFormat af, size_t _length)
+MusicChunk::Expand(const AudioFormat af, size_t _length) noexcept
 {
 	const size_t frame_size = af.GetFrameSize();
 
diff --git a/src/MusicChunk.hxx b/src/MusicChunk.hxx
index d572152cd..c5be179a9 100644
--- a/src/MusicChunk.hxx
+++ b/src/MusicChunk.hxx
@@ -111,7 +111,7 @@ struct MusicChunk {
 	 * specified audio_format.
 	 */
 	gcc_pure
-	bool CheckFormat(AudioFormat audio_format) const;
+	bool CheckFormat(AudioFormat audio_format) const noexcept;
 #endif
 
 	/**
@@ -127,7 +127,7 @@ struct MusicChunk {
 	 */
 	WritableBuffer<void> Write(AudioFormat af,
 				   SongTime data_time,
-				   uint16_t bit_rate);
+				   uint16_t bit_rate) noexcept;
 
 	/**
 	 * Increases the length of the chunk after the caller has written to
@@ -138,7 +138,7 @@ struct MusicChunk {
 	 * @param length the number of bytes which were appended
 	 * @return true if the chunk is full
 	 */
-	bool Expand(AudioFormat af, size_t length);
+	bool Expand(AudioFormat af, size_t length) noexcept;
 };
 
 #endif
diff --git a/src/MusicPipe.cxx b/src/MusicPipe.cxx
index c6128ce74..c82faa648 100644
--- a/src/MusicPipe.cxx
+++ b/src/MusicPipe.cxx
@@ -25,7 +25,7 @@
 #ifndef NDEBUG
 
 bool
-MusicPipe::Contains(const MusicChunk *chunk) const
+MusicPipe::Contains(const MusicChunk *chunk) const noexcept
 {
 	const std::lock_guard<Mutex> protect(mutex);
 
diff --git a/src/MusicPipe.hxx b/src/MusicPipe.hxx
index 65890580c..e9bebed6e 100644
--- a/src/MusicPipe.hxx
+++ b/src/MusicPipe.hxx
@@ -86,7 +86,7 @@ public:
 	 * Checks if the specified chunk is enqueued in the music pipe.
 	 */
 	gcc_pure
-	bool Contains(const MusicChunk *chunk) const;
+	bool Contains(const MusicChunk *chunk) const noexcept;
 #endif
 
 	/**
diff --git a/src/ReplayGainInfo.cxx b/src/ReplayGainInfo.cxx
index 1f9f863ce..c7742d056 100644
--- a/src/ReplayGainInfo.cxx
+++ b/src/ReplayGainInfo.cxx
@@ -24,7 +24,7 @@
 #include <math.h>
 
 float
-ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const
+ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const noexcept
 {
 	float scale;
 
diff --git a/src/ReplayGainInfo.hxx b/src/ReplayGainInfo.hxx
index 413e2fb1d..4cdbbc0c6 100644
--- a/src/ReplayGainInfo.hxx
+++ b/src/ReplayGainInfo.hxx
@@ -40,23 +40,23 @@ struct ReplayGainTuple {
 	}
 
 	gcc_pure
-	float CalculateScale(const ReplayGainConfig &config) const;
+	float CalculateScale(const ReplayGainConfig &config) const noexcept;
 };
 
 struct ReplayGainInfo {
 	ReplayGainTuple track, album;
 
-	constexpr bool IsDefined() const {
+	constexpr bool IsDefined() const noexcept {
 		return track.IsDefined() || album.IsDefined();
 	}
 
-	const ReplayGainTuple &Get(ReplayGainMode mode) const {
+	const ReplayGainTuple &Get(ReplayGainMode mode) const noexcept {
 		return mode == ReplayGainMode::ALBUM
 			? (album.IsDefined() ? album : track)
 			: (track.IsDefined() ? track : album);
 	}
 
-	void Clear() {
+	void Clear() noexcept {
 		track.Clear();
 		album.Clear();
 	}
diff --git a/src/ReplayGainMode.cxx b/src/ReplayGainMode.cxx
index 0db40cc40..ddcec0450 100644
--- a/src/ReplayGainMode.cxx
+++ b/src/ReplayGainMode.cxx
@@ -25,7 +25,7 @@
 #include <string.h>
 
 const char *
-ToString(ReplayGainMode mode)
+ToString(ReplayGainMode mode) noexcept
 {
 	switch (mode) {
 	case ReplayGainMode::AUTO:
diff --git a/src/ReplayGainMode.hxx b/src/ReplayGainMode.hxx
index 37cbb2ab7..37b76f16f 100644
--- a/src/ReplayGainMode.hxx
+++ b/src/ReplayGainMode.hxx
@@ -36,7 +36,7 @@ enum class ReplayGainMode : uint8_t {
  */
 gcc_pure
 const char *
-ToString(ReplayGainMode mode);
+ToString(ReplayGainMode mode) noexcept;
 
 /**
  * Parse a string to a #ReplayGainMode.  Throws std::runtime_error on
diff --git a/src/SongFilter.cxx b/src/SongFilter.cxx
index d2bbc9b32..96edfdea1 100644
--- a/src/SongFilter.cxx
+++ b/src/SongFilter.cxx
@@ -39,7 +39,7 @@
 #define LOCATE_TAG_ANY_KEY      "any"
 
 unsigned
-locate_parse_type(const char *str)
+locate_parse_type(const char *str) noexcept
 {
 	if (StringEqualsCaseASCII(str, LOCATE_TAG_FILE_KEY) ||
 	    StringEqualsCaseASCII(str, LOCATE_TAG_FILE_KEY_OLD))
@@ -78,7 +78,7 @@ SongFilter::Item::Item(unsigned _tag, time_t _time)
 }
 
 bool
-SongFilter::Item::StringMatch(const char *s) const
+SongFilter::Item::StringMatch(const char *s) const noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
@@ -97,14 +97,14 @@ SongFilter::Item::StringMatch(const char *s) const
 }
 
 bool
-SongFilter::Item::Match(const TagItem &item) const
+SongFilter::Item::Match(const TagItem &item) const noexcept
 {
 	return (tag == LOCATE_TAG_ANY_TYPE || (unsigned)item.type == tag) &&
 		StringMatch(item.value);
 }
 
 bool
-SongFilter::Item::Match(const Tag &_tag) const
+SongFilter::Item::Match(const Tag &_tag) const noexcept
 {
 	bool visited_types[TAG_NUM_OF_ITEM_TYPES];
 	std::fill_n(visited_types, size_t(TAG_NUM_OF_ITEM_TYPES), false);
@@ -140,7 +140,7 @@ SongFilter::Item::Match(const Tag &_tag) const
 }
 
 bool
-SongFilter::Item::Match(const DetachedSong &song) const
+SongFilter::Item::Match(const DetachedSong &song) const noexcept
 {
 	if (tag == LOCATE_TAG_BASE_TYPE)
 		return uri_is_child_or_same(value.c_str(), song.GetURI());
@@ -155,7 +155,7 @@ SongFilter::Item::Match(const DetachedSong &song) const
 }
 
 bool
-SongFilter::Item::Match(const LightSong &song) const
+SongFilter::Item::Match(const LightSong &song) const noexcept
 {
 	if (tag == LOCATE_TAG_BASE_TYPE) {
 		const auto uri = song.GetURI();
@@ -185,7 +185,7 @@ SongFilter::~SongFilter()
 
 gcc_pure
 static time_t
-ParseTimeStamp(const char *s)
+ParseTimeStamp(const char *s) noexcept
 {
 	assert(s != nullptr);
 
@@ -246,7 +246,7 @@ SongFilter::Parse(ConstBuffer<const char *> args, bool fold_case)
 }
 
 bool
-SongFilter::Match(const DetachedSong &song) const
+SongFilter::Match(const DetachedSong &song) const noexcept
 {
 	for (const auto &i : items)
 		if (!i.Match(song))
@@ -256,7 +256,7 @@ SongFilter::Match(const DetachedSong &song) const
 }
 
 bool
-SongFilter::Match(const LightSong &song) const
+SongFilter::Match(const LightSong &song) const noexcept
 {
 	for (const auto &i : items)
 		if (!i.Match(song))
@@ -266,7 +266,7 @@ SongFilter::Match(const LightSong &song) const
 }
 
 bool
-SongFilter::HasOtherThanBase() const
+SongFilter::HasOtherThanBase() const noexcept
 {
 	for (const auto &i : items)
 		if (i.GetTag() != LOCATE_TAG_BASE_TYPE)
@@ -276,7 +276,7 @@ SongFilter::HasOtherThanBase() const
 }
 
 const char *
-SongFilter::GetBase() const
+SongFilter::GetBase() const noexcept
 {
 	for (const auto &i : items)
 		if (i.GetTag() == LOCATE_TAG_BASE_TYPE)
diff --git a/src/SongFilter.hxx b/src/SongFilter.hxx
index e8ffa7075..a0bb25d41 100644
--- a/src/SongFilter.hxx
+++ b/src/SongFilter.hxx
@@ -80,19 +80,19 @@ public:
 		}
 
 		gcc_pure gcc_nonnull(2)
-		bool StringMatch(const char *s) const;
+		bool StringMatch(const char *s) const noexcept;
 
 		gcc_pure
-		bool Match(const TagItem &tag_item) const;
+		bool Match(const TagItem &tag_item) const noexcept;
 
 		gcc_pure
-		bool Match(const Tag &tag) const;
+		bool Match(const Tag &tag) const noexcept;
 
 		gcc_pure
-		bool Match(const DetachedSong &song) const;
+		bool Match(const DetachedSong &song) const noexcept;
 
 		gcc_pure
-		bool Match(const LightSong &song) const;
+		bool Match(const LightSong &song) const noexcept;
 	};
 
 private:
@@ -112,20 +112,20 @@ public:
 	bool Parse(ConstBuffer<const char *> args, bool fold_case=false);
 
 	gcc_pure
-	bool Match(const Tag &tag) const;
+	bool Match(const Tag &tag) const noexcept;
 
 	gcc_pure
-	bool Match(const DetachedSong &song) const;
+	bool Match(const DetachedSong &song) const noexcept;
 
 	gcc_pure
-	bool Match(const LightSong &song) const;
+	bool Match(const LightSong &song) const noexcept;
 
-	const std::list<Item> &GetItems() const {
+	const std::list<Item> &GetItems() const noexcept {
 		return items;
 	}
 
 	gcc_pure
-	bool IsEmpty() const {
+	bool IsEmpty() const noexcept {
 		return items.empty();
 	}
 
@@ -133,7 +133,7 @@ public:
 	 * Is there at least one item with "fold case" enabled?
 	 */
 	gcc_pure
-	bool HasFoldCase() const {
+	bool HasFoldCase() const noexcept {
 		for (const auto &i : items)
 			if (i.GetFoldCase())
 				return true;
@@ -145,14 +145,14 @@ public:
 	 * Does this filter contain constraints other than "base"?
 	 */
 	gcc_pure
-	bool HasOtherThanBase() const;
+	bool HasOtherThanBase() const noexcept;
 
 	/**
 	 * Returns the "base" specification (if there is one) or
 	 * nullptr.
 	 */
 	gcc_pure
-	const char *GetBase() const;
+	const char *GetBase() const noexcept;
 };
 
 /**
@@ -160,6 +160,6 @@ public:
  */
 gcc_pure
 unsigned
-locate_parse_type(const char *str);
+locate_parse_type(const char *str) noexcept;
 
 #endif
diff --git a/src/StateFile.cxx b/src/StateFile.cxx
index 7035e0e12..cc02d0ff7 100644
--- a/src/StateFile.cxx
+++ b/src/StateFile.cxx
@@ -50,7 +50,7 @@ StateFile::StateFile(AllocatedPath &&_path,
 }
 
 void
-StateFile::RememberVersions()
+StateFile::RememberVersions() noexcept
 {
 	prev_volume_version = sw_volume_state_get_hash();
 	prev_output_version = audio_output_state_get_version();
@@ -59,7 +59,7 @@ StateFile::RememberVersions()
 }
 
 bool
-StateFile::IsModified() const
+StateFile::IsModified() const noexcept
 {
 	return prev_volume_version != sw_volume_state_get_hash() ||
 		prev_output_version != audio_output_state_get_version() ||
diff --git a/src/StateFile.hxx b/src/StateFile.hxx
index c4ceb2abb..342a20c22 100644
--- a/src/StateFile.hxx
+++ b/src/StateFile.hxx
@@ -67,14 +67,14 @@ private:
 	/**
 	 * Save the current state versions for use with IsModified().
 	 */
-	void RememberVersions();
+	void RememberVersions() noexcept;
 
 	/**
 	 * Check if MPD's state was modified since the last
 	 * RememberVersions() call.
 	 */
 	gcc_pure
-	bool IsModified() const;
+	bool IsModified() const noexcept;
 
 	/* virtual methods from TimeoutMonitor */
 	void OnTimeout() override;
diff --git a/src/TagStream.cxx b/src/TagStream.cxx
index 595a456ac..b5ece93bb 100644
--- a/src/TagStream.cxx
+++ b/src/TagStream.cxx
@@ -40,7 +40,7 @@
 gcc_pure
 static bool
 CheckDecoderPlugin(const DecoderPlugin &plugin,
-		   const char *suffix, const char *mime)
+		   const char *suffix, const char *mime) noexcept
 {
 	return (mime != nullptr && plugin.SupportsMimeType(mime)) ||
 		(suffix != nullptr && plugin.SupportsSuffix(suffix));
diff --git a/src/archive/ArchiveLookup.cxx b/src/archive/ArchiveLookup.cxx
index 07b73e147..f84d97f23 100644
--- a/src/archive/ArchiveLookup.cxx
+++ b/src/archive/ArchiveLookup.cxx
@@ -28,7 +28,7 @@
 
 gcc_pure
 static char *
-FindSlash(char *p, size_t i)
+FindSlash(char *p, size_t i) noexcept
 {
 	for (; i > 0; --i)
 		if (p[i] == '/')
@@ -39,7 +39,7 @@ FindSlash(char *p, size_t i)
 
 gcc_pure
 static const char *
-FindSuffix(const char *p, const char *i)
+FindSuffix(const char *p, const char *i) noexcept
 {
 	for (; i > p; --i) {
 		if (*i == '.')
diff --git a/src/archive/plugins/Bzip2ArchivePlugin.cxx b/src/archive/plugins/Bzip2ArchivePlugin.cxx
index ee22290c2..3dc0b51c3 100644
--- a/src/archive/plugins/Bzip2ArchivePlugin.cxx
+++ b/src/archive/plugins/Bzip2ArchivePlugin.cxx
@@ -93,7 +93,7 @@ public:
 	~Bzip2InputStream();
 
 	/* virtual methods from InputStream */
-	bool IsEOF() override;
+	bool IsEOF() noexcept override;
 	size_t Read(void *ptr, size_t size) override;
 
 private:
@@ -205,7 +205,7 @@ Bzip2InputStream::Read(void *ptr, size_t length)
 }
 
 bool
-Bzip2InputStream::IsEOF()
+Bzip2InputStream::IsEOF() noexcept
 {
 	return eof;
 }
diff --git a/src/archive/plugins/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx
index 7139da32d..9e4c4f16a 100644
--- a/src/archive/plugins/Iso9660ArchivePlugin.cxx
+++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx
@@ -162,7 +162,7 @@ public:
 	}
 
 	/* virtual methods from InputStream */
-	bool IsEOF() override;
+	bool IsEOF() noexcept override;
 	size_t Read(void *ptr, size_t size) override;
 };
 
@@ -213,7 +213,7 @@ Iso9660InputStream::Read(void *ptr, size_t read_size)
 }
 
 bool
-Iso9660InputStream::IsEOF()
+Iso9660InputStream::IsEOF() noexcept
 {
 	return offset == size;
 }
diff --git a/src/archive/plugins/ZzipArchivePlugin.cxx b/src/archive/plugins/ZzipArchivePlugin.cxx
index f9b2b3010..5ba087f48 100644
--- a/src/archive/plugins/ZzipArchivePlugin.cxx
+++ b/src/archive/plugins/ZzipArchivePlugin.cxx
@@ -116,7 +116,7 @@ struct ZzipInputStream final : public InputStream {
 	}
 
 	/* virtual methods from InputStream */
-	bool IsEOF() override;
+	bool IsEOF() noexcept override;
 	size_t Read(void *ptr, size_t size) override;
 	void Seek(offset_type offset) override;
 };
@@ -147,7 +147,7 @@ ZzipInputStream::Read(void *ptr, size_t read_size)
 }
 
 bool
-ZzipInputStream::IsEOF()
+ZzipInputStream::IsEOF() noexcept
 {
 	return offset_type(zzip_tell(file)) == size;
 }
diff --git a/src/client/Client.cxx b/src/client/Client.cxx
index f6defedf9..c52ca77a1 100644
--- a/src/client/Client.cxx
+++ b/src/client/Client.cxx
@@ -28,7 +28,7 @@ const Domain client_domain("client");
 #ifdef ENABLE_DATABASE
 
 const Database *
-Client::GetDatabase() const
+Client::GetDatabase() const noexcept
 {
 	return partition.instance.GetDatabase();
 }
@@ -40,7 +40,7 @@ Client::GetDatabaseOrThrow() const
 }
 
 const Storage *
-Client::GetStorage() const
+Client::GetStorage() const noexcept
 {
 	return partition.instance.storage;
 }
diff --git a/src/client/Client.hxx b/src/client/Client.hxx
index 69492b4ee..24461878e 100644
--- a/src/client/Client.hxx
+++ b/src/client/Client.hxx
@@ -160,7 +160,7 @@ public:
 	};
 
 	gcc_pure
-	bool IsSubscribed(const char *channel_name) const {
+	bool IsSubscribed(const char *channel_name) const noexcept {
 		return subscriptions.find(channel_name) != subscriptions.end();
 	}
 
@@ -186,7 +186,7 @@ public:
 	 * Wrapper for Instance::GetDatabase().
 	 */
 	gcc_pure
-	const Database *GetDatabase() const;
+	const Database *GetDatabase() const noexcept;
 
 	/**
 	 * Wrapper for Instance::GetDatabaseOrThrow().
@@ -195,7 +195,7 @@ public:
 	const Database &GetDatabaseOrThrow() const;
 
 	gcc_pure
-	const Storage *GetStorage() const;
+	const Storage *GetStorage() const noexcept;
 
 private:
 	/* virtual methods from class BufferedSocket */
diff --git a/src/client/ClientMessage.cxx b/src/client/ClientMessage.cxx
index 145f706dd..da45fe643 100644
--- a/src/client/ClientMessage.cxx
+++ b/src/client/ClientMessage.cxx
@@ -23,14 +23,14 @@
 
 gcc_const
 static bool
-valid_channel_char(const char ch)
+valid_channel_char(const char ch) noexcept
 {
 	return IsAlphaNumericASCII(ch) ||
 		ch == '_' || ch == '-' || ch == '.' || ch == ':';
 }
 
 bool
-client_message_valid_channel_name(const char *name)
+client_message_valid_channel_name(const char *name) noexcept
 {
 	do {
 		if (!valid_channel_char(*name))
diff --git a/src/client/ClientMessage.hxx b/src/client/ClientMessage.hxx
index aef914dd7..b665cd65e 100644
--- a/src/client/ClientMessage.hxx
+++ b/src/client/ClientMessage.hxx
@@ -53,6 +53,6 @@ public:
 
 gcc_pure
 bool
-client_message_valid_channel_name(const char *name);
+client_message_valid_channel_name(const char *name) noexcept;
 
 #endif
diff --git a/src/command/CommandError.cxx b/src/command/CommandError.cxx
index c52eb86ca..8f5badb4d 100644
--- a/src/command/CommandError.cxx
+++ b/src/command/CommandError.cxx
@@ -54,7 +54,7 @@
 
 gcc_const
 static enum ack
-ToAck(PlaylistResult result)
+ToAck(PlaylistResult result) noexcept
 {
 	switch (result) {
 	case PlaylistResult::SUCCESS:
@@ -90,7 +90,7 @@ ToAck(PlaylistResult result)
 #ifdef ENABLE_DATABASE
 gcc_const
 static enum ack
-ToAck(DatabaseErrorCode code)
+ToAck(DatabaseErrorCode code) noexcept
 {
 	switch (code) {
 	case DatabaseErrorCode::DISABLED:
@@ -107,7 +107,7 @@ ToAck(DatabaseErrorCode code)
 
 gcc_pure
 static enum ack
-ToAck(std::exception_ptr ep)
+ToAck(std::exception_ptr ep) noexcept
 {
 	try {
 		std::rethrow_exception(ep);
diff --git a/src/command/FileCommands.cxx b/src/command/FileCommands.cxx
index 51bde6eb6..19c9bad58 100644
--- a/src/command/FileCommands.cxx
+++ b/src/command/FileCommands.cxx
@@ -44,7 +44,7 @@
 
 gcc_pure
 static bool
-SkipNameFS(PathTraitsFS::const_pointer_type name_fs)
+SkipNameFS(PathTraitsFS::const_pointer_type name_fs) noexcept
 {
 	return name_fs[0] == '.' &&
 		(name_fs[1] == 0 ||
@@ -53,7 +53,7 @@ SkipNameFS(PathTraitsFS::const_pointer_type name_fs)
 
 gcc_pure
 static bool
-skip_path(Path name_fs)
+skip_path(Path name_fs) noexcept
 {
 	return name_fs.HasNewline();
 }
@@ -107,7 +107,7 @@ handle_listfiles_local(Response &r, Path path_fs)
 
 gcc_pure
 static bool
-IsValidName(const char *p)
+IsValidName(const char *p) noexcept
 {
 	if (!IsAlphaASCII(*p))
 		return false;
@@ -123,7 +123,7 @@ IsValidName(const char *p)
 
 gcc_pure
 static bool
-IsValidValue(const char *p)
+IsValidValue(const char *p) noexcept
 {
 	while (*p) {
 		const char ch = *p++;
diff --git a/src/command/NeighborCommands.cxx b/src/command/NeighborCommands.cxx
index 5a46417bf..e7ed34bc8 100644
--- a/src/command/NeighborCommands.cxx
+++ b/src/command/NeighborCommands.cxx
@@ -30,7 +30,7 @@
 #include <string>
 
 bool
-neighbor_commands_available(const Instance &instance)
+neighbor_commands_available(const Instance &instance) noexcept
 {
 	return instance.neighbors != nullptr;
 }
diff --git a/src/command/NeighborCommands.hxx b/src/command/NeighborCommands.hxx
index fa021f313..9c383c599 100644
--- a/src/command/NeighborCommands.hxx
+++ b/src/command/NeighborCommands.hxx
@@ -30,7 +30,7 @@ class Response;
 
 gcc_pure
 bool
-neighbor_commands_available(const Instance &instance);
+neighbor_commands_available(const Instance &instance) noexcept;
 
 CommandResult
 handle_listneighbors(Client &client, Request request, Response &response);
diff --git a/src/command/PlaylistCommands.cxx b/src/command/PlaylistCommands.cxx
index da380bcc5..b59610419 100644
--- a/src/command/PlaylistCommands.cxx
+++ b/src/command/PlaylistCommands.cxx
@@ -39,7 +39,7 @@
 #include "util/ConstBuffer.hxx"
 
 bool
-playlist_commands_available()
+playlist_commands_available() noexcept
 {
 	return !map_spl_path().IsNull();
 }
diff --git a/src/command/PlaylistCommands.hxx b/src/command/PlaylistCommands.hxx
index ef72cce61..9a787a7d2 100644
--- a/src/command/PlaylistCommands.hxx
+++ b/src/command/PlaylistCommands.hxx
@@ -29,7 +29,7 @@ class Response;
 
 gcc_const
 bool
-playlist_commands_available();
+playlist_commands_available() noexcept;
 
 CommandResult
 handle_save(Client &client, Request request, Response &response);
diff --git a/src/command/StorageCommands.cxx b/src/command/StorageCommands.cxx
index 7b5445e23..1ecd96c46 100644
--- a/src/command/StorageCommands.cxx
+++ b/src/command/StorageCommands.cxx
@@ -45,7 +45,7 @@
 
 gcc_pure
 static bool
-skip_path(const char *name_utf8)
+skip_path(const char *name_utf8) noexcept
 {
 	return strchr(name_utf8, '\n') != nullptr;
 }
diff --git a/src/config/Block.cxx b/src/config/Block.cxx
index b3da7ed88..2f26de368 100644
--- a/src/config/Block.cxx
+++ b/src/config/Block.cxx
@@ -68,7 +68,7 @@ ConfigBlock::~ConfigBlock()
 }
 
 const BlockParam *
-ConfigBlock::GetBlockParam(const char *name) const
+ConfigBlock::GetBlockParam(const char *name) const noexcept
 {
 	for (const auto &i : block_params) {
 		if (i.name == name) {
@@ -81,7 +81,8 @@ ConfigBlock::GetBlockParam(const char *name) const
 }
 
 const char *
-ConfigBlock::GetBlockValue(const char *name, const char *default_value) const
+ConfigBlock::GetBlockValue(const char *name,
+			   const char *default_value) const noexcept
 {
 	const BlockParam *bp = GetBlockParam(name);
 	if (bp == nullptr)
diff --git a/src/config/Block.hxx b/src/config/Block.hxx
index 96399e59f..8003a31b0 100644
--- a/src/config/Block.hxx
+++ b/src/config/Block.hxx
@@ -101,11 +101,11 @@ struct ConfigBlock {
 	}
 
 	gcc_nonnull_all gcc_pure
-	const BlockParam *GetBlockParam(const char *_name) const;
+	const BlockParam *GetBlockParam(const char *_name) const noexcept;
 
 	gcc_pure
 	const char *GetBlockValue(const char *name,
-				  const char *default_value=nullptr) const;
+				  const char *default_value=nullptr) const noexcept;
 
 	/**
 	 * Same as config_get_path(), but looks up the setting in the
diff --git a/src/config/ConfigGlobal.cxx b/src/config/ConfigGlobal.cxx
index ebb04039c..8425a2e6e 100644
--- a/src/config/ConfigGlobal.cxx
+++ b/src/config/ConfigGlobal.cxx
@@ -75,7 +75,7 @@ void config_global_check(void)
 }
 
 const ConfigParam *
-config_get_param(ConfigOption option)
+config_get_param(ConfigOption option) noexcept
 {
 	auto *param = config_data.params[unsigned(option)];
 	if (param != nullptr)
@@ -84,7 +84,7 @@ config_get_param(ConfigOption option)
 }
 
 const ConfigBlock *
-config_get_block(ConfigBlockOption option)
+config_get_block(ConfigBlockOption option) noexcept
 {
 	ConfigBlock *block = config_data.blocks[unsigned(option)];
 	if (block != nullptr)
@@ -110,7 +110,7 @@ config_find_block(ConfigBlockOption option, const char *key, const char *value)
 }
 
 const char *
-config_get_string(ConfigOption option, const char *default_value)
+config_get_string(ConfigOption option, const char *default_value) noexcept
 {
 	const auto *param = config_get_param(option);
 
diff --git a/src/config/ConfigGlobal.hxx b/src/config/ConfigGlobal.hxx
index 735649eae..b6c86b3c1 100644
--- a/src/config/ConfigGlobal.hxx
+++ b/src/config/ConfigGlobal.hxx
@@ -48,11 +48,11 @@ ReadConfigFile(Path path);
 
 gcc_pure
 const ConfigParam *
-config_get_param(enum ConfigOption option);
+config_get_param(enum ConfigOption option) noexcept;
 
 gcc_pure
 const ConfigBlock *
-config_get_block(enum ConfigBlockOption option);
+config_get_block(enum ConfigBlockOption option) noexcept;
 
 /**
  * Find a block with a matching attribute.
@@ -74,7 +74,8 @@ config_find_block(ConfigBlockOption option, const char *key, const char *value);
 
 gcc_pure
 const char *
-config_get_string(enum ConfigOption option, const char *default_value=nullptr);
+config_get_string(enum ConfigOption option,
+		  const char *default_value=nullptr) noexcept;
 
 /**
  * Returns an optional configuration variable which contains an
diff --git a/src/config/ConfigOption.hxx b/src/config/ConfigOption.hxx
index efbf613d5..b29bf526b 100644
--- a/src/config/ConfigOption.hxx
+++ b/src/config/ConfigOption.hxx
@@ -102,13 +102,13 @@ enum class ConfigBlockOption {
  */
 gcc_pure
 enum ConfigOption
-ParseConfigOptionName(const char *name);
+ParseConfigOptionName(const char *name) noexcept;
 
 /**
  * @return #ConfigOption::MAX if not found
  */
 gcc_pure
 enum ConfigBlockOption
-ParseConfigBlockOptionName(const char *name);
+ParseConfigBlockOptionName(const char *name) noexcept;
 
 #endif
diff --git a/src/config/ConfigTemplates.cxx b/src/config/ConfigTemplates.cxx
index 54ceb5e04..683e30ccd 100644
--- a/src/config/ConfigTemplates.cxx
+++ b/src/config/ConfigTemplates.cxx
@@ -101,7 +101,7 @@ static_assert(n_config_block_templates == unsigned(ConfigBlockOption::MAX),
 gcc_pure
 static inline unsigned
 ParseConfigTemplateName(const ConfigTemplate templates[], unsigned count,
-			const char *name)
+			const char *name) noexcept
 {
 	unsigned i = 0;
 	for (; i < count; ++i)
@@ -112,7 +112,7 @@ ParseConfigTemplateName(const ConfigTemplate templates[], unsigned count,
 }
 
 ConfigOption
-ParseConfigOptionName(const char *name)
+ParseConfigOptionName(const char *name) noexcept
 {
 	return ConfigOption(ParseConfigTemplateName(config_param_templates,
 						    n_config_param_templates,
@@ -120,7 +120,7 @@ ParseConfigOptionName(const char *name)
 }
 
 ConfigBlockOption
-ParseConfigBlockOptionName(const char *name)
+ParseConfigBlockOptionName(const char *name) noexcept
 {
 	return ConfigBlockOption(ParseConfigTemplateName(config_block_templates,
 							 n_config_block_templates,
diff --git a/src/db/DatabaseLock.hxx b/src/db/DatabaseLock.hxx
index cf551b7ac..4bcb17bc0 100644
--- a/src/db/DatabaseLock.hxx
+++ b/src/db/DatabaseLock.hxx
@@ -45,7 +45,7 @@ extern ThreadId db_mutex_holder;
  */
 gcc_pure
 static inline bool
-holding_db_lock(void)
+holding_db_lock() noexcept
 {
 	return db_mutex_holder.IsInside();
 }
diff --git a/src/db/LightSong.cxx b/src/db/LightSong.cxx
index 5f78f101d..98e8a1001 100644
--- a/src/db/LightSong.cxx
+++ b/src/db/LightSong.cxx
@@ -21,7 +21,7 @@
 #include "tag/Tag.hxx"
 
 SignedSongTime
-LightSong::GetDuration() const
+LightSong::GetDuration() const noexcept
 {
 	SongTime a = start_time, b = end_time;
 	if (!b.IsPositive()) {
diff --git a/src/db/LightSong.hxx b/src/db/LightSong.hxx
index 737992703..599acba54 100644
--- a/src/db/LightSong.hxx
+++ b/src/db/LightSong.hxx
@@ -76,7 +76,7 @@ struct LightSong {
 	SongTime end_time;
 
 	gcc_pure
-	std::string GetURI() const {
+	std::string GetURI() const noexcept {
 		if (directory == nullptr)
 			return std::string(uri);
 
@@ -87,7 +87,7 @@ struct LightSong {
 	}
 
 	gcc_pure
-	SignedSongTime GetDuration() const;
+	SignedSongTime GetDuration() const noexcept;
 };
 
 #endif
diff --git a/src/db/PlaylistVector.cxx b/src/db/PlaylistVector.cxx
index 08a294cfb..26269b88b 100644
--- a/src/db/PlaylistVector.cxx
+++ b/src/db/PlaylistVector.cxx
@@ -26,7 +26,7 @@
 #include <assert.h>
 
 PlaylistVector::iterator
-PlaylistVector::find(const char *name)
+PlaylistVector::find(const char *name) noexcept
 {
 	assert(holding_db_lock());
 	assert(name != nullptr);
diff --git a/src/db/PlaylistVector.hxx b/src/db/PlaylistVector.hxx
index 20e943a59..5a7f9f973 100644
--- a/src/db/PlaylistVector.hxx
+++ b/src/db/PlaylistVector.hxx
@@ -31,7 +31,7 @@ protected:
 	 * Caller must lock the #db_mutex.
 	 */
 	gcc_pure
-	iterator find(const char *name);
+	iterator find(const char *name) noexcept;
 
 public:
 	using std::list<PlaylistInfo>::empty;
diff --git a/src/db/Registry.cxx b/src/db/Registry.cxx
index 27e3dd69d..71598c777 100644
--- a/src/db/Registry.cxx
+++ b/src/db/Registry.cxx
@@ -38,7 +38,7 @@ const DatabasePlugin *const database_plugins[] = {
 };
 
 const DatabasePlugin *
-GetDatabasePluginByName(const char *name)
+GetDatabasePluginByName(const char *name) noexcept
 {
 	for (auto i = database_plugins; *i != nullptr; ++i)
 		if (strcmp((*i)->name, name) == 0)
diff --git a/src/db/Registry.hxx b/src/db/Registry.hxx
index 1fca03dcc..71f107c42 100644
--- a/src/db/Registry.hxx
+++ b/src/db/Registry.hxx
@@ -32,6 +32,6 @@ extern const DatabasePlugin *const database_plugins[];
 
 gcc_pure
 const DatabasePlugin *
-GetDatabasePluginByName(const char *name);
+GetDatabasePluginByName(const char *name) noexcept;
 
 #endif
diff --git a/src/db/Selection.cxx b/src/db/Selection.cxx
index b15a3a587..bab9c9de8 100644
--- a/src/db/Selection.cxx
+++ b/src/db/Selection.cxx
@@ -34,19 +34,19 @@ DatabaseSelection::DatabaseSelection(const char *_uri, bool _recursive,
 }
 
 bool
-DatabaseSelection::IsEmpty() const
+DatabaseSelection::IsEmpty() const noexcept
 {
 	return uri.empty() && (filter == nullptr || filter->IsEmpty());
 }
 
 bool
-DatabaseSelection::HasOtherThanBase() const
+DatabaseSelection::HasOtherThanBase() const noexcept
 {
 	return filter != nullptr && filter->HasOtherThanBase();
 }
 
 bool
-DatabaseSelection::Match(const LightSong &song) const
+DatabaseSelection::Match(const LightSong &song) const noexcept
 {
 	return filter == nullptr || filter->Match(song);
 }
diff --git a/src/db/Selection.hxx b/src/db/Selection.hxx
index 1ace52c8d..633f858c5 100644
--- a/src/db/Selection.hxx
+++ b/src/db/Selection.hxx
@@ -45,16 +45,16 @@ struct DatabaseSelection {
 			  const SongFilter *_filter=nullptr);
 
 	gcc_pure
-	bool IsEmpty() const;
+	bool IsEmpty() const noexcept;
 
 	/**
 	 * Does this selection contain constraints other than "base"?
 	 */
 	gcc_pure
-	bool HasOtherThanBase() const;
+	bool HasOtherThanBase() const noexcept;
 
 	gcc_pure
-	bool Match(const LightSong &song) const;
+	bool Match(const LightSong &song) const noexcept;
 };
 
 #endif
diff --git a/src/db/plugins/ProxyDatabasePlugin.cxx b/src/db/plugins/ProxyDatabasePlugin.cxx
index b3df1d28e..0145c4b4f 100644
--- a/src/db/plugins/ProxyDatabasePlugin.cxx
+++ b/src/db/plugins/ProxyDatabasePlugin.cxx
@@ -216,7 +216,7 @@ ProxySong::ProxySong(const mpd_song *song)
 
 gcc_const
 static enum mpd_tag_type
-Convert(TagType tag_type)
+Convert(TagType tag_type) noexcept
 {
 	for (auto i = &tag_table[0]; i->d != TAG_NUM_OF_ITEM_TYPES; ++i)
 		if (i->d == tag_type)
@@ -574,7 +574,7 @@ Visit(struct mpd_connection *connection,
 
 gcc_pure
 static bool
-Match(const SongFilter *filter, const LightSong &song)
+Match(const SongFilter *filter, const LightSong &song) noexcept
 {
 	return filter == nullptr || filter->Match(song);
 }
@@ -717,7 +717,7 @@ SearchSongs(struct mpd_connection *connection,
  */
 gcc_pure
 static bool
-ServerSupportsSearchBase(const struct mpd_connection *connection)
+ServerSupportsSearchBase(const struct mpd_connection *connection) noexcept
 {
 #if LIBMPDCLIENT_CHECK_VERSION(2,9,0)
 	return mpd_connection_cmp_server_version(connection, 0, 18, 0) >= 0;
diff --git a/src/db/plugins/simple/Directory.cxx b/src/db/plugins/simple/Directory.cxx
index 8fb0f709e..655778b99 100644
--- a/src/db/plugins/simple/Directory.cxx
+++ b/src/db/plugins/simple/Directory.cxx
@@ -65,7 +65,7 @@ Directory::Delete()
 }
 
 const char *
-Directory::GetName() const
+Directory::GetName() const noexcept
 {
 	assert(!IsRoot());
 
@@ -89,7 +89,7 @@ Directory::CreateChild(const char *name_utf8)
 }
 
 const Directory *
-Directory::FindChild(const char *name) const
+Directory::FindChild(const char *name) const noexcept
 {
 	assert(holding_db_lock());
 
@@ -101,7 +101,7 @@ Directory::FindChild(const char *name) const
 }
 
 void
-Directory::PruneEmpty()
+Directory::PruneEmpty() noexcept
 {
 	assert(holding_db_lock());
 
@@ -118,7 +118,7 @@ Directory::PruneEmpty()
 }
 
 Directory::LookupResult
-Directory::LookupDirectory(const char *uri)
+Directory::LookupDirectory(const char *uri) noexcept
 {
 	assert(holding_db_lock());
 	assert(uri != nullptr);
@@ -173,7 +173,7 @@ Directory::AddSong(Song *song)
 }
 
 void
-Directory::RemoveSong(Song *song)
+Directory::RemoveSong(Song *song) noexcept
 {
 	assert(holding_db_lock());
 	assert(song != nullptr);
@@ -183,7 +183,7 @@ Directory::RemoveSong(Song *song)
 }
 
 const Song *
-Directory::FindSong(const char *name_utf8) const
+Directory::FindSong(const char *name_utf8) const noexcept
 {
 	assert(holding_db_lock());
 	assert(name_utf8 != nullptr);
@@ -200,13 +200,13 @@ Directory::FindSong(const char *name_utf8) const
 
 gcc_pure
 static bool
-directory_cmp(const Directory &a, const Directory &b)
+directory_cmp(const Directory &a, const Directory &b) noexcept
 {
 	return IcuCollate(a.path.c_str(), b.path.c_str()) < 0;
 }
 
 void
-Directory::Sort()
+Directory::Sort() noexcept
 {
 	assert(holding_db_lock());
 
@@ -261,7 +261,7 @@ Directory::Walk(bool recursive, const SongFilter *filter,
 }
 
 LightDirectory
-Directory::Export() const
+Directory::Export() const noexcept
 {
 	return LightDirectory(GetPath(), mtime);
 }
diff --git a/src/db/plugins/simple/Directory.hxx b/src/db/plugins/simple/Directory.hxx
index 15631a091..cb8ebd530 100644
--- a/src/db/plugins/simple/Directory.hxx
+++ b/src/db/plugins/simple/Directory.hxx
@@ -134,10 +134,10 @@ public:
 	 * Caller must lock the #db_mutex.
 	 */
 	gcc_pure
-	const Directory *FindChild(const char *name) const;
+	const Directory *FindChild(const char *name) const noexcept;
 
 	gcc_pure
-	Directory *FindChild(const char *name) {
+	Directory *FindChild(const char *name) noexcept {
 		const Directory *cthis = this;
 		return const_cast<Directory *>(cthis->FindChild(name));
 	}
@@ -177,10 +177,10 @@ public:
 	 * @return the Directory, or nullptr if none was found
 	 */
 	gcc_pure
-	LookupResult LookupDirectory(const char *uri);
+	LookupResult LookupDirectory(const char *uri) noexcept;
 
 	gcc_pure
-	bool IsEmpty() const {
+	bool IsEmpty() const noexcept {
 		return children.empty() &&
 			songs.empty() &&
 			playlists.empty();
@@ -195,13 +195,13 @@ public:
 	 * Returns the base name of the directory.
 	 */
 	gcc_pure
-	const char *GetName() const;
+	const char *GetName() const noexcept;
 
 	/**
 	 * Is this the root directory of the music database?
 	 */
 	gcc_pure
-	bool IsRoot() const {
+	bool IsRoot() const noexcept {
 		return parent == nullptr;
 	}
 
@@ -229,10 +229,10 @@ public:
 	 * Caller must lock the #db_mutex.
 	 */
 	gcc_pure
-	const Song *FindSong(const char *name_utf8) const;
+	const Song *FindSong(const char *name_utf8) const noexcept;
 
 	gcc_pure
-	Song *FindSong(const char *name_utf8) {
+	Song *FindSong(const char *name_utf8) noexcept {
 		const Directory *cthis = this;
 		return const_cast<Song *>(cthis->FindSong(name_utf8));
 	}
@@ -248,19 +248,19 @@ public:
 	 * invalidates the song object, because the "parent" attribute becomes
 	 * stale), but does not free it.
 	 */
-	void RemoveSong(Song *song);
+	void RemoveSong(Song *song) noexcept;
 
 	/**
 	 * Caller must lock the #db_mutex.
 	 */
-	void PruneEmpty();
+	void PruneEmpty() noexcept;
 
 	/**
 	 * Sort all directory entries recursively.
 	 *
 	 * Caller must lock the #db_mutex.
 	 */
-	void Sort();
+	void Sort() noexcept;
 
 	/**
 	 * Caller must lock #db_mutex.
@@ -270,7 +270,7 @@ public:
 		  VisitPlaylist visit_playlist) const;
 
 	gcc_pure
-	LightDirectory Export() const;
+	LightDirectory Export() const noexcept;
 };
 
 #endif
diff --git a/src/db/plugins/simple/DirectorySave.cxx b/src/db/plugins/simple/DirectorySave.cxx
index 8272985e7..e1f83bf5b 100644
--- a/src/db/plugins/simple/DirectorySave.cxx
+++ b/src/db/plugins/simple/DirectorySave.cxx
@@ -40,7 +40,7 @@
 
 gcc_const
 static const char *
-DeviceToTypeString(unsigned device)
+DeviceToTypeString(unsigned device) noexcept
 {
 	switch (device) {
 	case DEVICE_INARCHIVE:
@@ -56,7 +56,7 @@ DeviceToTypeString(unsigned device)
 
 gcc_pure
 static unsigned
-ParseTypeString(const char *type)
+ParseTypeString(const char *type) noexcept
 {
 	if (strcmp(type, "archive") == 0)
 		return DEVICE_INARCHIVE;
diff --git a/src/db/plugins/simple/Song.cxx b/src/db/plugins/simple/Song.cxx
index 45c8c67fe..54a9c95ff 100644
--- a/src/db/plugins/simple/Song.cxx
+++ b/src/db/plugins/simple/Song.cxx
@@ -77,7 +77,7 @@ Song::Free()
 }
 
 std::string
-Song::GetURI() const
+Song::GetURI() const noexcept
 {
 	assert(*uri);
 
@@ -96,7 +96,7 @@ Song::GetURI() const
 }
 
 LightSong
-Song::Export() const
+Song::Export() const noexcept
 {
 	LightSong dest;
 	dest.directory = parent->IsRoot()
diff --git a/src/db/plugins/simple/Song.hxx b/src/db/plugins/simple/Song.hxx
index 85f9f2867..2fa952a35 100644
--- a/src/db/plugins/simple/Song.hxx
+++ b/src/db/plugins/simple/Song.hxx
@@ -123,10 +123,10 @@ struct Song {
 	 * location within the music directory.
 	 */
 	gcc_pure
-	std::string GetURI() const;
+	std::string GetURI() const noexcept;
 
 	gcc_pure
-	LightSong Export() const;
+	LightSong Export() const noexcept;
 };
 
 typedef boost::intrusive::list<Song,
diff --git a/src/db/plugins/simple/SongSort.cxx b/src/db/plugins/simple/SongSort.cxx
index e383f44ab..57fe9430b 100644
--- a/src/db/plugins/simple/SongSort.cxx
+++ b/src/db/plugins/simple/SongSort.cxx
@@ -26,7 +26,7 @@
 #include <stdlib.h>
 
 static int
-compare_utf8_string(const char *a, const char *b)
+compare_utf8_string(const char *a, const char *b) noexcept
 {
 	if (a == nullptr)
 		return b == nullptr ? 0 : -1;
@@ -42,8 +42,7 @@ compare_utf8_string(const char *a, const char *b)
  * nullptr.
  */
 static int
-compare_string_tag_item(const Tag &a, const Tag &b,
-			TagType type)
+compare_string_tag_item(const Tag &a, const Tag &b, TagType type) noexcept
 {
 	return compare_utf8_string(a.GetValue(type),
 				   b.GetValue(type));
@@ -54,7 +53,7 @@ compare_string_tag_item(const Tag &a, const Tag &b,
  * (e.g. disc or track number).  Either one may be nullptr.
  */
 static int
-compare_number_string(const char *a, const char *b)
+compare_number_string(const char *a, const char *b) noexcept
 {
 	long ai = a == nullptr ? 0 : strtol(a, nullptr, 10);
 	long bi = b == nullptr ? 0 : strtol(b, nullptr, 10);
@@ -69,7 +68,7 @@ compare_number_string(const char *a, const char *b)
 }
 
 static int
-compare_tag_item(const Tag &a, const Tag &b, TagType type)
+compare_tag_item(const Tag &a, const Tag &b, TagType type) noexcept
 {
 	return compare_number_string(a.GetValue(type),
 				     b.GetValue(type));
@@ -78,7 +77,7 @@ compare_tag_item(const Tag &a, const Tag &b, TagType type)
 /* Only used for sorting/searchin a songvec, not general purpose compares */
 gcc_pure
 static bool
-song_cmp(const Song &a, const Song &b)
+song_cmp(const Song &a, const Song &b) noexcept
 {
 	int ret;
 
@@ -102,7 +101,7 @@ song_cmp(const Song &a, const Song &b)
 }
 
 void
-song_list_sort(SongList &songs)
+song_list_sort(SongList &songs) noexcept
 {
 	songs.sort(song_cmp);
 }
diff --git a/src/db/plugins/simple/SongSort.hxx b/src/db/plugins/simple/SongSort.hxx
index 23acb7506..e1c1ae1fa 100644
--- a/src/db/plugins/simple/SongSort.hxx
+++ b/src/db/plugins/simple/SongSort.hxx
@@ -23,6 +23,6 @@
 #include "Song.hxx"
 
 void
-song_list_sort(SongList &songs);
+song_list_sort(SongList &songs) noexcept;
 
 #endif
diff --git a/src/db/plugins/upnp/Directory.cxx b/src/db/plugins/upnp/Directory.cxx
index 444cf1a73..ac518d9be 100644
--- a/src/db/plugins/upnp/Directory.cxx
+++ b/src/db/plugins/upnp/Directory.cxx
@@ -39,7 +39,7 @@ UPnPDirContent::~UPnPDirContent()
 
 gcc_pure
 static UPnPDirObject::ItemClass
-ParseItemClass(StringView name)
+ParseItemClass(StringView name) noexcept
 {
 	if (name.EqualsLiteral("object.item.audioItem.musicTrack"))
 		return UPnPDirObject::ItemClass::MUSIC;
@@ -51,7 +51,7 @@ ParseItemClass(StringView name)
 
 gcc_pure
 static SignedSongTime
-ParseDuration(const char *duration)
+ParseDuration(const char *duration) noexcept
 {
 	char *endptr;
 
@@ -81,7 +81,7 @@ ParseDuration(const char *duration)
  */
 gcc_pure
 static std::string &&
-TitleToPathSegment(std::string &&s)
+TitleToPathSegment(std::string &&s) noexcept
 {
 	std::replace(s.begin(), s.end(), '/', '_');
 	return std::move(s);
diff --git a/src/db/plugins/upnp/Directory.hxx b/src/db/plugins/upnp/Directory.hxx
index f8427d513..23d01039c 100644
--- a/src/db/plugins/upnp/Directory.hxx
+++ b/src/db/plugins/upnp/Directory.hxx
@@ -40,7 +40,7 @@ public:
 	~UPnPDirContent();
 
 	gcc_pure
-	UPnPDirObject *FindObject(const char *name) {
+	UPnPDirObject *FindObject(const char *name) noexcept {
 		for (auto &o : objects)
 			if (o.name == name)
 				return &o;
diff --git a/src/db/update/InotifyQueue.cxx b/src/db/update/InotifyQueue.cxx
index e097dda0b..d83d26612 100644
--- a/src/db/update/InotifyQueue.cxx
+++ b/src/db/update/InotifyQueue.cxx
@@ -56,7 +56,7 @@ InotifyQueue::OnTimeout()
 
 gcc_pure
 static bool
-path_in(const char *path, const char *possible_parent)
+path_in(const char *path, const char *possible_parent) noexcept
 {
 	if (StringIsEmpty(path))
 		return true;
diff --git a/src/db/update/InotifyUpdate.cxx b/src/db/update/InotifyUpdate.cxx
index 245a7bcb9..562315fa3 100644
--- a/src/db/update/InotifyUpdate.cxx
+++ b/src/db/update/InotifyUpdate.cxx
@@ -62,10 +62,10 @@ struct WatchDirectory {
 	WatchDirectory &operator=(const WatchDirectory &) = delete;
 
 	gcc_pure
-	unsigned GetDepth() const;
+	unsigned GetDepth() const noexcept;
 
 	gcc_pure
-	AllocatedPath GetUriFS() const;
+	AllocatedPath GetUriFS() const noexcept;
 };
 
 static InotifySource *inotify_source;
@@ -132,7 +132,7 @@ remove_watch_directory(WatchDirectory *directory)
 }
 
 AllocatedPath
-WatchDirectory::GetUriFS() const
+WatchDirectory::GetUriFS() const noexcept
 {
 	if (parent == nullptr)
 		return AllocatedPath::Null();
@@ -225,7 +225,7 @@ recursive_watch_subdirectories(WatchDirectory *directory,
 
 gcc_pure
 unsigned
-WatchDirectory::GetDepth() const
+WatchDirectory::GetDepth() const noexcept
 {
 	const WatchDirectory *d = this;
 	unsigned depth = 0;
@@ -331,7 +331,7 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update,
 }
 
 void
-mpd_inotify_finish(void)
+mpd_inotify_finish(void) noexcept
 {
 	if (inotify_source == nullptr)
 		return;
diff --git a/src/db/update/InotifyUpdate.hxx b/src/db/update/InotifyUpdate.hxx
index 8bef9016d..a58a38dcd 100644
--- a/src/db/update/InotifyUpdate.hxx
+++ b/src/db/update/InotifyUpdate.hxx
@@ -32,6 +32,6 @@ mpd_inotify_init(EventLoop &loop, Storage &storage, UpdateService &update,
 		 unsigned max_depth);
 
 void
-mpd_inotify_finish();
+mpd_inotify_finish() noexcept;
 
 #endif
diff --git a/src/db/update/UpdateIO.cxx b/src/db/update/UpdateIO.cxx
index 617a4f2f7..9680c06a0 100644
--- a/src/db/update/UpdateIO.cxx
+++ b/src/db/update/UpdateIO.cxx
@@ -32,7 +32,7 @@
 #include <errno.h>
 
 bool
-GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info)
+GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info) noexcept
 try {
 	info = storage.GetInfo(uri_utf8, true);
 	return true;
@@ -42,7 +42,7 @@ try {
 }
 
 bool
-GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info)
+GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info) noexcept
 try {
 	info = reader.GetInfo(true);
 	return true;
@@ -52,7 +52,7 @@ try {
 }
 
 bool
-DirectoryExists(Storage &storage, const Directory &directory)
+DirectoryExists(Storage &storage, const Directory &directory) noexcept
 {
 	StorageFileInfo info;
 
@@ -79,7 +79,7 @@ GetDirectoryChildInfo(Storage &storage, const Directory &directory,
 
 bool
 directory_child_is_regular(Storage &storage, const Directory &directory,
-			   const char *name_utf8)
+			   const char *name_utf8) noexcept
 try {
 	return GetDirectoryChildInfo(storage, directory, name_utf8)
 		.IsRegular();
@@ -89,7 +89,7 @@ try {
 
 bool
 directory_child_access(Storage &storage, const Directory &directory,
-		       const char *name, int mode)
+		       const char *name, int mode) noexcept
 {
 #ifdef WIN32
 	/* CheckAccess() is useless on WIN32 */
diff --git a/src/db/update/UpdateIO.hxx b/src/db/update/UpdateIO.hxx
index bf5e87c67..b9f43105a 100644
--- a/src/db/update/UpdateIO.hxx
+++ b/src/db/update/UpdateIO.hxx
@@ -33,23 +33,23 @@ class StorageDirectoryReader;
  * returning them.
  */
 bool
-GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info);
+GetInfo(Storage &storage, const char *uri_utf8, StorageFileInfo &info) noexcept;
 
 /**
  * Wrapper for LocalDirectoryReader::GetInfo() that logs errors
  * instead of returning them.
  */
 bool
-GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info);
+GetInfo(StorageDirectoryReader &reader, StorageFileInfo &info) noexcept;
 
 gcc_pure
 bool
-DirectoryExists(Storage &storage, const Directory &directory);
+DirectoryExists(Storage &storage, const Directory &directory) noexcept;
 
 gcc_pure
 bool
 directory_child_is_regular(Storage &storage, const Directory &directory,
-			   const char *name_utf8);
+			   const char *name_utf8) noexcept;
 
 /**
  * Checks if the given permissions on the mapped file are given.
@@ -57,6 +57,6 @@ directory_child_is_regular(Storage &storage, const Directory &directory,
 gcc_pure
 bool
 directory_child_access(Storage &storage, const Directory &directory,
-		       const char *name, int mode);
+		       const char *name, int mode) noexcept;
 
 #endif
diff --git a/src/db/update/Walk.cxx b/src/db/update/Walk.cxx
index 2e917037d..c3af3f789 100644
--- a/src/db/update/Walk.cxx
+++ b/src/db/update/Walk.cxx
@@ -248,7 +248,7 @@ try {
 /* we don't look at "." / ".." nor files with newlines in their name */
 gcc_pure
 static bool
-skip_path(const char *name_utf8)
+skip_path(const char *name_utf8) noexcept
 {
 	return strchr(name_utf8, '\n') != nullptr;
 }
@@ -256,7 +256,7 @@ skip_path(const char *name_utf8)
 gcc_pure
 bool
 UpdateWalk::SkipSymlink(const Directory *directory,
-			const char *utf8_name) const
+			const char *utf8_name) const noexcept
 {
 #ifndef WIN32
 	const auto path_fs = storage.MapChildFS(directory->GetPath(),
diff --git a/src/db/update/Walk.hxx b/src/db/update/Walk.hxx
index e32b906d0..7d7a03db5 100644
--- a/src/db/update/Walk.hxx
+++ b/src/db/update/Walk.hxx
@@ -78,7 +78,7 @@ public:
 private:
 	gcc_pure
 	bool SkipSymlink(const Directory *directory,
-			 const char *utf8_name) const;
+			 const char *utf8_name) const noexcept;
 
 	void RemoveExcludedFromDirectory(Directory &directory,
 					 const ExcludeList &exclude_list);
diff --git a/src/decoder/Bridge.cxx b/src/decoder/Bridge.cxx
index 201e6a1aa..c24c80768 100644
--- a/src/decoder/Bridge.cxx
+++ b/src/decoder/Bridge.cxx
@@ -54,7 +54,7 @@ DecoderBridge::~DecoderBridge()
 }
 
 bool
-DecoderBridge::CheckCancelRead() const
+DecoderBridge::CheckCancelRead() const noexcept
 {
 	if (error)
 		/* this translates to DecoderCommand::STOP */
@@ -78,7 +78,7 @@ DecoderBridge::CheckCancelRead() const
  * one.
  */
 static DecoderCommand
-need_chunks(DecoderControl &dc)
+need_chunks(DecoderControl &dc) noexcept
 {
 	if (dc.command == DecoderCommand::NONE)
 		dc.Wait();
@@ -87,14 +87,14 @@ need_chunks(DecoderControl &dc)
 }
 
 static DecoderCommand
-LockNeedChunks(DecoderControl &dc)
+LockNeedChunks(DecoderControl &dc) noexcept
 {
 	const std::lock_guard<Mutex> protect(dc.mutex);
 	return need_chunks(dc);
 }
 
 MusicChunk *
-DecoderBridge::GetChunk()
+DecoderBridge::GetChunk() noexcept
 {
 	DecoderCommand cmd;
 
@@ -177,7 +177,7 @@ DecoderBridge::PrepareInitialSeek()
 }
 
 DecoderCommand
-DecoderBridge::GetVirtualCommand()
+DecoderBridge::GetVirtualCommand() noexcept
 {
 	if (error)
 		/* an error has occurred: stop the decoder plugin */
@@ -192,7 +192,7 @@ DecoderBridge::GetVirtualCommand()
 }
 
 DecoderCommand
-DecoderBridge::LockGetVirtualCommand()
+DecoderBridge::LockGetVirtualCommand() noexcept
 {
 	const std::lock_guard<Mutex> protect(dc.mutex);
 	return GetVirtualCommand();
diff --git a/src/decoder/Bridge.hxx b/src/decoder/Bridge.hxx
index 977f56083..8573d6a7f 100644
--- a/src/decoder/Bridge.hxx
+++ b/src/decoder/Bridge.hxx
@@ -114,7 +114,7 @@ public:
 	 * Caller must lock the #DecoderControl object.
 	 */
 	gcc_pure
-	bool CheckCancelRead() const;
+	bool CheckCancelRead() const noexcept;
 
 	/**
 	 * Returns the current chunk the decoder writes to, or allocates a new
@@ -122,7 +122,7 @@ public:
 	 *
 	 * @return the chunk, or NULL if we have received a decoder command
 	 */
-	MusicChunk *GetChunk();
+	MusicChunk *GetChunk() noexcept;
 
 	/**
 	 * Flushes the current chunk.
@@ -161,8 +161,8 @@ private:
 	 * "virtual" synthesized command, e.g. to seek to the
 	 * beginning of the CUE track.
 	 */
-	DecoderCommand GetVirtualCommand();
-	DecoderCommand LockGetVirtualCommand();
+	DecoderCommand GetVirtualCommand() noexcept;
+	DecoderCommand LockGetVirtualCommand() noexcept;
 
 	/**
 	 * Sends a #Tag as-is to the #MusicPipe.  Flushes the current
diff --git a/src/decoder/DecoderControl.cxx b/src/decoder/DecoderControl.cxx
index 71c1c8cd1..7a271b281 100644
--- a/src/decoder/DecoderControl.cxx
+++ b/src/decoder/DecoderControl.cxx
@@ -74,7 +74,7 @@ DecoderControl::SetReady(const AudioFormat audio_format,
 }
 
 bool
-DecoderControl::IsCurrentSong(const DetachedSong &_song) const
+DecoderControl::IsCurrentSong(const DetachedSong &_song) const noexcept
 {
 	switch (state) {
 	case DecoderState::STOP:
diff --git a/src/decoder/DecoderControl.hxx b/src/decoder/DecoderControl.hxx
index ae405896d..fa8fdfd2b 100644
--- a/src/decoder/DecoderControl.hxx
+++ b/src/decoder/DecoderControl.hxx
@@ -305,10 +305,10 @@ struct DecoderControl {
 	 * Caller must lock the object.
 	 */
 	gcc_pure
-	bool IsCurrentSong(const DetachedSong &_song) const;
+	bool IsCurrentSong(const DetachedSong &_song) const noexcept;
 
 	gcc_pure
-	bool LockIsCurrentSong(const DetachedSong &_song) const {
+	bool LockIsCurrentSong(const DetachedSong &_song) const noexcept {
 		const std::lock_guard<Mutex> protect(mutex);
 		return IsCurrentSong(_song);
 	}
diff --git a/src/decoder/DecoderList.cxx b/src/decoder/DecoderList.cxx
index 4f420db05..58c0f0973 100644
--- a/src/decoder/DecoderList.cxx
+++ b/src/decoder/DecoderList.cxx
@@ -118,7 +118,7 @@ static constexpr unsigned num_decoder_plugins =
 bool decoder_plugins_enabled[num_decoder_plugins];
 
 const struct DecoderPlugin *
-decoder_plugin_from_name(const char *name)
+decoder_plugin_from_name(const char *name) noexcept
 {
 	return decoder_plugins_find([=](const DecoderPlugin &plugin){
 			return strcmp(plugin.name, name) == 0;
@@ -154,7 +154,7 @@ void decoder_plugin_deinit_all(void)
 }
 
 bool
-decoder_plugins_supports_suffix(const char *suffix)
+decoder_plugins_supports_suffix(const char *suffix) noexcept
 {
 	return decoder_plugins_try([suffix](const DecoderPlugin &plugin){
 			return plugin.SupportsSuffix(suffix);
diff --git a/src/decoder/DecoderList.hxx b/src/decoder/DecoderList.hxx
index 6dce02338..2eb9aa231 100644
--- a/src/decoder/DecoderList.hxx
+++ b/src/decoder/DecoderList.hxx
@@ -31,7 +31,7 @@ extern bool decoder_plugins_enabled[];
 
 gcc_pure
 const struct DecoderPlugin *
-decoder_plugin_from_name(const char *name);
+decoder_plugin_from_name(const char *name) noexcept;
 
 /* this is where we "load" all the "plugins" ;-) */
 void
@@ -86,6 +86,6 @@ decoder_plugins_for_each_enabled(F f)
  */
 gcc_pure gcc_nonnull_all
 bool
-decoder_plugins_supports_suffix(const char *suffix);
+decoder_plugins_supports_suffix(const char *suffix) noexcept;
 
 #endif
diff --git a/src/decoder/DecoderPlugin.cxx b/src/decoder/DecoderPlugin.cxx
index 1372e2504..0c2a3bbe9 100644
--- a/src/decoder/DecoderPlugin.cxx
+++ b/src/decoder/DecoderPlugin.cxx
@@ -24,7 +24,7 @@
 #include <assert.h>
 
 bool
-DecoderPlugin::SupportsSuffix(const char *suffix) const
+DecoderPlugin::SupportsSuffix(const char *suffix) const noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
@@ -36,7 +36,7 @@ DecoderPlugin::SupportsSuffix(const char *suffix) const
 }
 
 bool
-DecoderPlugin::SupportsMimeType(const char *mime_type) const
+DecoderPlugin::SupportsMimeType(const char *mime_type) const noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
diff --git a/src/decoder/DecoderPlugin.hxx b/src/decoder/DecoderPlugin.hxx
index 2d2631c24..5c7c81c8e 100644
--- a/src/decoder/DecoderPlugin.hxx
+++ b/src/decoder/DecoderPlugin.hxx
@@ -168,13 +168,13 @@ struct DecoderPlugin {
 	 * Does the plugin announce the specified file name suffix?
 	 */
 	gcc_pure gcc_nonnull_all
-	bool SupportsSuffix(const char *suffix) const;
+	bool SupportsSuffix(const char *suffix) const noexcept;
 
 	/**
 	 * Does the plugin announce the specified MIME type?
 	 */
 	gcc_pure gcc_nonnull_all
-	bool SupportsMimeType(const char *mime_type) const;
+	bool SupportsMimeType(const char *mime_type) const noexcept;
 };
 
 #endif
diff --git a/src/decoder/DecoderThread.cxx b/src/decoder/DecoderThread.cxx
index 551b1c641..e74ee0f84 100644
--- a/src/decoder/DecoderThread.cxx
+++ b/src/decoder/DecoderThread.cxx
@@ -170,7 +170,8 @@ decoder_file_decode(const DecoderPlugin &plugin,
 
 gcc_pure
 static bool
-decoder_check_plugin_mime(const DecoderPlugin &plugin, const InputStream &is)
+decoder_check_plugin_mime(const DecoderPlugin &plugin,
+			  const InputStream &is) noexcept
 {
 	assert(plugin.stream_decode != nullptr);
 
@@ -181,7 +182,8 @@ decoder_check_plugin_mime(const DecoderPlugin &plugin, const InputStream &is)
 
 gcc_pure
 static bool
-decoder_check_plugin_suffix(const DecoderPlugin &plugin, const char *suffix)
+decoder_check_plugin_suffix(const DecoderPlugin &plugin,
+			    const char *suffix) noexcept
 {
 	assert(plugin.stream_decode != nullptr);
 
@@ -191,7 +193,7 @@ decoder_check_plugin_suffix(const DecoderPlugin &plugin, const char *suffix)
 gcc_pure
 static bool
 decoder_check_plugin(const DecoderPlugin &plugin, const InputStream &is,
-		     const char *suffix)
+		     const char *suffix) noexcept
 {
 	return plugin.stream_decode != nullptr &&
 		(decoder_check_plugin_mime(plugin, is) ||
diff --git a/src/decoder/plugins/AudiofileDecoderPlugin.cxx b/src/decoder/plugins/AudiofileDecoderPlugin.cxx
index e58676d01..d4098da35 100644
--- a/src/decoder/plugins/AudiofileDecoderPlugin.cxx
+++ b/src/decoder/plugins/AudiofileDecoderPlugin.cxx
@@ -66,7 +66,7 @@ struct AudioFileInputStream {
 
 gcc_pure
 static SongTime
-audiofile_get_duration(AFfilehandle fh)
+audiofile_get_duration(AFfilehandle fh) noexcept
 {
 	return SongTime::FromScale<uint64_t>(afGetFrameCount(fh, AF_DEFAULT_TRACK),
 					     afGetRate(fh, AF_DEFAULT_TRACK));
@@ -239,7 +239,7 @@ audiofile_stream_decode(DecoderClient &client, InputStream &is)
 
 gcc_pure
 static SignedSongTime
-audiofile_get_duration(InputStream &is)
+audiofile_get_duration(InputStream &is) noexcept
 {
 	if (!is.IsSeekable() || !is.KnownSize())
 		return SignedSongTime::Negative();
diff --git a/src/decoder/plugins/DsdLib.cxx b/src/decoder/plugins/DsdLib.cxx
index 1fae21fd3..000af531a 100644
--- a/src/decoder/plugins/DsdLib.cxx
+++ b/src/decoder/plugins/DsdLib.cxx
@@ -39,7 +39,7 @@
 #include <stdlib.h>
 
 bool
-DsdId::Equals(const char *s) const
+DsdId::Equals(const char *s) const noexcept
 {
 	assert(s != nullptr);
 	assert(strlen(s) == sizeof(value));
@@ -95,7 +95,7 @@ dsdlib_skip(DecoderClient *client, InputStream &is,
 }
 
 bool
-dsdlib_valid_freq(uint32_t samplefreq)
+dsdlib_valid_freq(uint32_t samplefreq) noexcept
 {
 	switch (samplefreq) {
 	case 2822400: /* DSD64, 64xFs, Fs = 44.100kHz */
diff --git a/src/decoder/plugins/DsdLib.hxx b/src/decoder/plugins/DsdLib.hxx
index 311afb6e2..c1a059c55 100644
--- a/src/decoder/plugins/DsdLib.hxx
+++ b/src/decoder/plugins/DsdLib.hxx
@@ -34,7 +34,7 @@ struct DsdId {
 	char value[4];
 
 	gcc_pure
-	bool Equals(const char *s) const;
+	bool Equals(const char *s) const noexcept;
 };
 
 class DsdUint64 {
@@ -72,7 +72,7 @@ dsdlib_skip(DecoderClient *client, InputStream &is,
  **/
 gcc_const
 bool
-dsdlib_valid_freq(uint32_t samplefreq);
+dsdlib_valid_freq(uint32_t samplefreq) noexcept;
 
 /**
  * Add tags from ID3 tag. All tags commonly found in the ID3 tags of
diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
index 698645380..2c9d3a8fa 100644
--- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx
+++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx
@@ -112,14 +112,14 @@ ffmpeg_finish()
 
 gcc_pure
 static const AVCodecParameters &
-GetCodecParameters(const AVStream &stream)
+GetCodecParameters(const AVStream &stream) noexcept
 {
 	return *stream.codecpar;
 }
 
 gcc_pure
 static AVSampleFormat
-GetSampleFormat(const AVCodecParameters &codec_params)
+GetSampleFormat(const AVCodecParameters &codec_params) noexcept
 {
 	return AVSampleFormat(codec_params.format);
 }
@@ -128,14 +128,14 @@ GetSampleFormat(const AVCodecParameters &codec_params)
 
 gcc_pure
 static const AVCodecContext &
-GetCodecParameters(const AVStream &stream)
+GetCodecParameters(const AVStream &stream) noexcept
 {
 	return *stream.codec;
 }
 
 gcc_pure
 static AVSampleFormat
-GetSampleFormat(const AVCodecContext &codec_context)
+GetSampleFormat(const AVCodecContext &codec_context) noexcept
 {
 	return codec_context.sample_fmt;
 }
@@ -144,14 +144,14 @@ GetSampleFormat(const AVCodecContext &codec_context)
 
 gcc_pure
 static bool
-IsAudio(const AVStream &stream)
+IsAudio(const AVStream &stream) noexcept
 {
 	return GetCodecParameters(stream).codec_type == AVMEDIA_TYPE_AUDIO;
 }
 
 gcc_pure
 static int
-ffmpeg_find_audio_stream(const AVFormatContext &format_context)
+ffmpeg_find_audio_stream(const AVFormatContext &format_context) noexcept
 {
 	for (unsigned i = 0; i < format_context.nb_streams; ++i)
 		if (IsAudio(*format_context.streams[i]))
@@ -220,7 +220,7 @@ copy_interleave_frame(const AVCodecContext &codec_context,
  */
 gcc_pure
 static int64_t
-StreamRelativePts(const AVPacket &packet, const AVStream &stream)
+StreamRelativePts(const AVPacket &packet, const AVStream &stream) noexcept
 {
 	auto pts = packet.pts;
 	if (pts < 0 || pts == int64_t(AV_NOPTS_VALUE))
@@ -237,7 +237,7 @@ StreamRelativePts(const AVPacket &packet, const AVStream &stream)
 gcc_pure
 static uint64_t
 PtsToPcmFrame(uint64_t pts, const AVStream &stream,
-	      const AVCodecContext &codec_context)
+	      const AVCodecContext &codec_context) noexcept
 {
 	return av_rescale_q(pts, stream.time_base, codec_context.time_base);
 }
@@ -437,7 +437,7 @@ ffmpeg_send_packet(DecoderClient &client, InputStream &is,
 
 gcc_const
 static SampleFormat
-ffmpeg_sample_format(enum AVSampleFormat sample_fmt)
+ffmpeg_sample_format(enum AVSampleFormat sample_fmt) noexcept
 {
 	switch (sample_fmt) {
 	case AV_SAMPLE_FMT_S16:
diff --git a/src/decoder/plugins/FlacMetadata.cxx b/src/decoder/plugins/FlacMetadata.cxx
index 0d70a8e57..0a1e5af36 100644
--- a/src/decoder/plugins/FlacMetadata.cxx
+++ b/src/decoder/plugins/FlacMetadata.cxx
@@ -67,7 +67,7 @@ flac_parse_mixramp(const FLAC__StreamMetadata_VorbisComment &vc)
  */
 static const char *
 flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
-		   const char *name)
+		   const char *name) noexcept
 {
 	return vorbis_comment_value((const char *)entry->entry, name);
 }
@@ -126,7 +126,7 @@ flac_scan_comments(const FLAC__StreamMetadata_VorbisComment *comment,
 
 gcc_pure
 static inline SongTime
-flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info)
+flac_duration(const FLAC__StreamMetadata_StreamInfo *stream_info) noexcept
 {
 	assert(stream_info->sample_rate > 0);
 
diff --git a/src/decoder/plugins/GmeDecoderPlugin.cxx b/src/decoder/plugins/GmeDecoderPlugin.cxx
index 53d4cfea2..403e62346 100644
--- a/src/decoder/plugins/GmeDecoderPlugin.cxx
+++ b/src/decoder/plugins/GmeDecoderPlugin.cxx
@@ -74,7 +74,7 @@ gme_plugin_init(gcc_unused const ConfigBlock &block)
 
 gcc_pure
 static unsigned
-ParseSubtuneName(const char *base)
+ParseSubtuneName(const char *base) noexcept
 {
 	if (memcmp(base, SUBTUNE_PREFIX, sizeof(SUBTUNE_PREFIX) - 1) != 0)
 		return 0;
diff --git a/src/decoder/plugins/MadDecoderPlugin.cxx b/src/decoder/plugins/MadDecoderPlugin.cxx
index 3134f2569..49e9ae9e3 100644
--- a/src/decoder/plugins/MadDecoderPlugin.cxx
+++ b/src/decoder/plugins/MadDecoderPlugin.cxx
@@ -71,7 +71,7 @@ static bool gapless_playback;
 
 gcc_const
 static SongTime
-ToSongTime(mad_timer_t t)
+ToSongTime(mad_timer_t t) noexcept
 {
 	return SongTime::FromMS(mad_timer_count(t, MAD_UNITS_MILLISECONDS));
 }
@@ -155,10 +155,10 @@ struct MadDecoder {
 	enum mp3_action DecodeNextFrame();
 
 	gcc_pure
-	offset_type ThisFrameOffset() const;
+	offset_type ThisFrameOffset() const noexcept;
 
 	gcc_pure
-	offset_type RestIncludingThisFrame() const;
+	offset_type RestIncludingThisFrame() const noexcept;
 
 	/**
 	 * Attempt to calulcate the length of the song from filesize
@@ -177,7 +177,7 @@ struct MadDecoder {
 	}
 
 	gcc_pure
-	long TimeToFrame(SongTime t) const;
+	long TimeToFrame(SongTime t) const noexcept;
 
 	void UpdateTimerNextFrame();
 
@@ -291,7 +291,7 @@ parse_id3_replay_gain_info(ReplayGainInfo &rgi,
 #ifdef ENABLE_ID3TAG
 gcc_pure
 static MixRampInfo
-parse_id3_mixramp(struct id3_tag *tag)
+parse_id3_mixramp(struct id3_tag *tag) noexcept
 {
 	MixRampInfo result;
 
@@ -710,7 +710,7 @@ mp3_frame_duration(const struct mad_frame *frame)
 }
 
 inline offset_type
-MadDecoder::ThisFrameOffset() const
+MadDecoder::ThisFrameOffset() const noexcept
 {
 	auto offset = input_stream.GetOffset();
 
@@ -723,7 +723,7 @@ MadDecoder::ThisFrameOffset() const
 }
 
 inline offset_type
-MadDecoder::RestIncludingThisFrame() const
+MadDecoder::RestIncludingThisFrame() const noexcept
 {
 	return input_stream.GetSize() - ThisFrameOffset();
 }
@@ -846,7 +846,7 @@ mad_decoder_total_file_time(InputStream &is)
 }
 
 long
-MadDecoder::TimeToFrame(SongTime t) const
+MadDecoder::TimeToFrame(SongTime t) const noexcept
 {
 	unsigned long i;
 
diff --git a/src/decoder/plugins/OpusTags.cxx b/src/decoder/plugins/OpusTags.cxx
index 37419ed80..8baeccd2f 100644
--- a/src/decoder/plugins/OpusTags.cxx
+++ b/src/decoder/plugins/OpusTags.cxx
@@ -31,7 +31,7 @@
 
 gcc_pure
 static TagType
-ParseOpusTagName(const char *name)
+ParseOpusTagName(const char *name) noexcept
 {
 	TagType type = tag_name_parse_i(name);
 	if (type != TAG_NUM_OF_ITEM_TYPES)
diff --git a/src/decoder/plugins/SidplayDecoderPlugin.cxx b/src/decoder/plugins/SidplayDecoderPlugin.cxx
index 6674462eb..3a3c712ef 100644
--- a/src/decoder/plugins/SidplayDecoderPlugin.cxx
+++ b/src/decoder/plugins/SidplayDecoderPlugin.cxx
@@ -116,7 +116,7 @@ struct SidplayContainerPath {
 
 gcc_pure
 static unsigned
-ParseSubtuneName(const char *base)
+ParseSubtuneName(const char *base) noexcept
 {
 	if (memcmp(base, SUBTUNE_PREFIX, sizeof(SUBTUNE_PREFIX) - 1) != 0)
 		return 0;
@@ -390,7 +390,7 @@ sidplay_file_decode(DecoderClient &client, Path path_fs)
 
 gcc_pure
 static const char *
-GetInfoString(const SidTuneInfo &info, unsigned i)
+GetInfoString(const SidTuneInfo &info, unsigned i) noexcept
 {
 #ifdef HAVE_SIDPLAYFP
 	return info.numberOfInfoStrings() > i
diff --git a/src/decoder/plugins/SndfileDecoderPlugin.cxx b/src/decoder/plugins/SndfileDecoderPlugin.cxx
index 85ede0ec9..a662522d1 100644
--- a/src/decoder/plugins/SndfileDecoderPlugin.cxx
+++ b/src/decoder/plugins/SndfileDecoderPlugin.cxx
@@ -148,7 +148,7 @@ sndfile_duration(const SF_INFO &info)
 
 gcc_pure
 static SampleFormat
-sndfile_sample_format(const SF_INFO &info)
+sndfile_sample_format(const SF_INFO &info) noexcept
 {
 	switch (info.format & SF_FORMAT_SUBMASK) {
 	case SF_FORMAT_PCM_S8:
diff --git a/src/decoder/plugins/WavpackDecoderPlugin.cxx b/src/decoder/plugins/WavpackDecoderPlugin.cxx
index 7a30dbe23..d726ca2df 100644
--- a/src/decoder/plugins/WavpackDecoderPlugin.cxx
+++ b/src/decoder/plugins/WavpackDecoderPlugin.cxx
@@ -101,7 +101,7 @@ WavpackOpenInput(WavpackStreamReader *reader, void *wv_id, void *wvc_id,
 
 gcc_pure
 static SignedSongTime
-GetDuration(WavpackContext *wpc)
+GetDuration(WavpackContext *wpc) noexcept
 {
 #ifdef OPEN_DSD_AS_PCM
 	/* libWavPack 5 */
diff --git a/src/event/ServerSocket.cxx b/src/event/ServerSocket.cxx
index 6b36ed815..556648cc4 100644
--- a/src/event/ServerSocket.cxx
+++ b/src/event/ServerSocket.cxx
@@ -103,16 +103,16 @@ public:
 	using SocketMonitor::Close;
 
 	gcc_pure
-	std::string ToString() const {
+	std::string ToString() const noexcept {
 		return ::ToString(address);
 	}
 
-	void SetFD(int _fd) {
+	void SetFD(int _fd) noexcept {
 		SocketMonitor::Open(_fd);
 		SocketMonitor::ScheduleRead();
 	}
 
-	void Accept();
+	void Accept() noexcept;
 
 private:
 	virtual bool OnSocketReady(unsigned flags) override;
@@ -146,7 +146,7 @@ get_remote_uid(int fd)
 }
 
 inline void
-OneServerSocket::Accept()
+OneServerSocket::Accept() noexcept
 {
 	StaticSocketAddress peer_address;
 	size_t peer_address_length = sizeof(peer_address);
@@ -343,7 +343,7 @@ ServerSocket::AddPortIPv6(unsigned port)
  */
 gcc_pure
 static bool
-SupportsIPv6()
+SupportsIPv6() noexcept
 {
 	int fd = socket(AF_INET6, SOCK_STREAM, 0);
 	if (fd < 0)
diff --git a/src/filter/FilterRegistry.cxx b/src/filter/FilterRegistry.cxx
index 3a319da59..ffbbb9c3d 100644
--- a/src/filter/FilterRegistry.cxx
+++ b/src/filter/FilterRegistry.cxx
@@ -32,7 +32,7 @@ static const FilterPlugin *const filter_plugins[] = {
 };
 
 const FilterPlugin *
-filter_plugin_by_name(const char *name)
+filter_plugin_by_name(const char *name) noexcept
 {
 	for (unsigned i = 0; filter_plugins[i] != nullptr; ++i)
 		if (strcmp(filter_plugins[i]->name, name) == 0)
diff --git a/src/filter/FilterRegistry.hxx b/src/filter/FilterRegistry.hxx
index 20d3662d3..e014ed322 100644
--- a/src/filter/FilterRegistry.hxx
+++ b/src/filter/FilterRegistry.hxx
@@ -39,6 +39,6 @@ extern const FilterPlugin volume_filter_plugin;
 
 gcc_pure
 const FilterPlugin *
-filter_plugin_by_name(const char *name);
+filter_plugin_by_name(const char *name) noexcept;
 
 #endif
diff --git a/src/fs/AllocatedPath.cxx b/src/fs/AllocatedPath.cxx
index 0a1c26b42..fd5e54bf4 100644
--- a/src/fs/AllocatedPath.cxx
+++ b/src/fs/AllocatedPath.cxx
@@ -29,7 +29,7 @@
 AllocatedPath::~AllocatedPath() {}
 
 AllocatedPath
-AllocatedPath::FromUTF8(const char *path_utf8)
+AllocatedPath::FromUTF8(const char *path_utf8) noexcept
 {
 #if defined(HAVE_FS_CHARSET) || defined(WIN32)
 	try {
@@ -53,13 +53,13 @@ AllocatedPath::FromUTF8Throw(const char *path_utf8)
 }
 
 AllocatedPath
-AllocatedPath::GetDirectoryName() const
+AllocatedPath::GetDirectoryName() const noexcept
 {
 	return FromFS(PathTraitsFS::GetParent(c_str()));
 }
 
 std::string
-AllocatedPath::ToUTF8() const
+AllocatedPath::ToUTF8() const noexcept
 {
 	try {
 		return ::PathToUTF8(c_str());
@@ -69,7 +69,7 @@ AllocatedPath::ToUTF8() const
 }
 
 void
-AllocatedPath::ChopSeparators()
+AllocatedPath::ChopSeparators() noexcept
 {
 	size_t l = length();
 	const auto *p = data();
diff --git a/src/fs/AllocatedPath.hxx b/src/fs/AllocatedPath.hxx
index cb5192542..2ee55479e 100644
--- a/src/fs/AllocatedPath.hxx
+++ b/src/fs/AllocatedPath.hxx
@@ -153,7 +153,7 @@ public:
 	 * Returns return a "nulled" instance on error.
 	 */
 	gcc_pure gcc_nonnull_all
-	static AllocatedPath FromUTF8(const char *path_utf8);
+	static AllocatedPath FromUTF8(const char *path_utf8) noexcept;
 
 	/**
 	 * Convert a UTF-8 C string to an #AllocatedPath instance.
@@ -244,14 +244,14 @@ public:
 	 * (#IsNull returns true).
 	 */
 	gcc_pure
-	std::string ToUTF8() const;
+	std::string ToUTF8() const noexcept;
 
 	/**
 	 * Gets directory name of this path.
 	 * Returns a "nulled" instance on error.
 	 */
 	gcc_pure
-	AllocatedPath GetDirectoryName() const;
+	AllocatedPath GetDirectoryName() const noexcept;
 
 	/**
 	 * Determine the relative part of the given path to this
@@ -260,17 +260,17 @@ public:
 	 * nullptr on mismatch.
 	 */
 	gcc_pure
-	const_pointer_type Relative(Path other_fs) const {
+	const_pointer_type Relative(Path other_fs) const noexcept {
 		return PathTraitsFS::Relative(c_str(), other_fs.c_str());
 	}
 
 	/**
 	 * Chop trailing directory separators.
 	 */
-	void ChopSeparators();
+	void ChopSeparators() noexcept;
 
 	gcc_pure
-	bool IsAbsolute() const {
+	bool IsAbsolute() const noexcept {
 		return PathTraitsFS::IsAbsolute(c_str());
 	}
 };
diff --git a/src/fs/Charset.cxx b/src/fs/Charset.cxx
index 333c4afac..1b84063fa 100644
--- a/src/fs/Charset.cxx
+++ b/src/fs/Charset.cxx
@@ -57,7 +57,7 @@ SetFSCharset(const char *charset)
 #endif
 
 void
-DeinitFSCharset()
+DeinitFSCharset() noexcept
 {
 #ifdef HAVE_ICU_CONVERTER
 	delete fs_converter;
@@ -66,7 +66,7 @@ DeinitFSCharset()
 }
 
 const char *
-GetFSCharset()
+GetFSCharset() noexcept
 {
 #ifdef HAVE_FS_CHARSET
 	return fs_charset.empty() ? "UTF-8" : fs_charset.c_str();
diff --git a/src/fs/Charset.hxx b/src/fs/Charset.hxx
index 8f20cb565..84cf64ec6 100644
--- a/src/fs/Charset.hxx
+++ b/src/fs/Charset.hxx
@@ -33,7 +33,7 @@
  */
 gcc_const
 const char *
-GetFSCharset();
+GetFSCharset() noexcept;
 
 /**
  * Throws std::runtime_error on error.
@@ -42,7 +42,7 @@ void
 SetFSCharset(const char *charset);
 
 void
-DeinitFSCharset();
+DeinitFSCharset() noexcept;
 
 /**
  * Convert the path to UTF-8.
diff --git a/src/fs/Path.cxx b/src/fs/Path.cxx
index d8eadfcec..b8745915f 100644
--- a/src/fs/Path.cxx
+++ b/src/fs/Path.cxx
@@ -24,7 +24,7 @@
 #include <stdexcept>
 
 std::string
-Path::ToUTF8() const
+Path::ToUTF8() const noexcept
 {
 	try {
 		return ::PathToUTF8(c_str());
@@ -34,7 +34,7 @@ Path::ToUTF8() const
 }
 
 Path::const_pointer_type
-Path::GetSuffix() const
+Path::GetSuffix() const noexcept
 {
 	const auto base = GetBase().c_str();
 	const auto *dot = StringFindLast(base, '.');
diff --git a/src/fs/Path.hxx b/src/fs/Path.hxx
index ea2a6bb7c..5053162ef 100644
--- a/src/fs/Path.hxx
+++ b/src/fs/Path.hxx
@@ -123,7 +123,7 @@ public:
 	 * transfer newline characters).
 	 */
 	gcc_pure
-	bool HasNewline() const {
+	bool HasNewline() const noexcept {
 		return PathTraitsFS::Find(c_str(), '\n') != nullptr;
 	}
 
@@ -133,14 +133,14 @@ public:
 	 * (#IsNull returns true).
 	 */
 	gcc_pure
-	std::string ToUTF8() const;
+	std::string ToUTF8() const noexcept;
 
 	/**
 	 * Determine the "base" file name.
 	 * The return value points inside this object.
 	 */
 	gcc_pure
-	Path GetBase() const {
+	Path GetBase() const noexcept {
 		return FromFS(PathTraitsFS::GetBase(c_str()));
 	}
 
@@ -149,7 +149,7 @@ public:
 	 * Returns a "nulled" instance on error.
 	 */
 	gcc_pure
-	AllocatedPath GetDirectoryName() const;
+	AllocatedPath GetDirectoryName() const noexcept;
 
 	/**
 	 * Determine the relative part of the given path to this
@@ -158,17 +158,17 @@ public:
 	 * nullptr on mismatch.
 	 */
 	gcc_pure
-	const_pointer_type Relative(Path other_fs) const {
+	const_pointer_type Relative(Path other_fs) const noexcept {
 		return PathTraitsFS::Relative(c_str(), other_fs.c_str());
 	}
 
 	gcc_pure
-	bool IsAbsolute() const {
+	bool IsAbsolute() const noexcept {
 		return PathTraitsFS::IsAbsolute(c_str());
 	}
 
 	gcc_pure
-	const_pointer_type GetSuffix() const;
+	const_pointer_type GetSuffix() const noexcept;
 };
 
 #endif
diff --git a/src/fs/Path2.cxx b/src/fs/Path2.cxx
index ac2fb5a31..44410f9a2 100644
--- a/src/fs/Path2.cxx
+++ b/src/fs/Path2.cxx
@@ -22,7 +22,7 @@
 #include "AllocatedPath.hxx"
 
 AllocatedPath
-Path::GetDirectoryName() const
+Path::GetDirectoryName() const noexcept
 {
 	return AllocatedPath::FromFS(PathTraitsFS::GetParent(c_str()));
 }
diff --git a/src/fs/StandardDirectory.cxx b/src/fs/StandardDirectory.cxx
index 583962b12..1ea92cf2c 100644
--- a/src/fs/StandardDirectory.cxx
+++ b/src/fs/StandardDirectory.cxx
@@ -202,7 +202,8 @@ ParseConfigLine(char *line, const char *dir_name, AllocatedPath &result_dir)
 	return true;
 }
 
-static AllocatedPath GetUserDir(const char *name)
+static AllocatedPath
+GetUserDir(const char *name) noexcept
 try {
 	auto result = AllocatedPath::Null();
 	auto config_dir = GetUserConfigDir();
@@ -222,7 +223,8 @@ try {
 
 #endif
 
-AllocatedPath GetUserConfigDir()
+AllocatedPath
+GetUserConfigDir() noexcept
 {
 #if defined(WIN32)
 	return GetStandardDir(CSIDL_LOCAL_APPDATA);
@@ -246,7 +248,8 @@ AllocatedPath GetUserConfigDir()
 #endif
 }
 
-AllocatedPath GetUserMusicDir()
+AllocatedPath
+GetUserMusicDir() noexcept
 {
 #if defined(WIN32)
 	return GetStandardDir(CSIDL_MYMUSIC);	
@@ -259,7 +262,8 @@ AllocatedPath GetUserMusicDir()
 #endif
 }
 
-AllocatedPath GetUserCacheDir()
+AllocatedPath
+GetUserCacheDir() noexcept
 {
 #ifdef USE_XDG
 	// Check for $XDG_CACHE_HOME
@@ -285,12 +289,14 @@ AllocatedPath GetUserCacheDir()
 
 #ifdef WIN32
 
-AllocatedPath GetSystemConfigDir()
+AllocatedPath
+GetSystemConfigDir() noexcept
 {
 	return GetStandardDir(CSIDL_COMMON_APPDATA);
 }
 
-AllocatedPath GetAppBaseDir()
+AllocatedPath
+GetAppBaseDir() noexcept
 {
 	std::array<PathTraitsFS::value_type, MAX_PATH> app;
 	auto ret = GetModuleFileName(nullptr, app.data(), app.size());
@@ -309,7 +315,8 @@ AllocatedPath GetAppBaseDir()
 
 #else
 
-AllocatedPath GetHomeDir()
+AllocatedPath
+GetHomeDir() noexcept
 {
 #ifndef ANDROID
 	auto home = getenv("HOME");
@@ -322,7 +329,8 @@ AllocatedPath GetHomeDir()
 	return AllocatedPath::Null();
 }
 
-AllocatedPath GetHomeDir(const char *user_name)
+AllocatedPath
+GetHomeDir(const char *user_name) noexcept
 {
 #ifdef ANDROID
 	(void)user_name;
diff --git a/src/fs/StandardDirectory.hxx b/src/fs/StandardDirectory.hxx
index 26d6fe4e8..13d324c92 100644
--- a/src/fs/StandardDirectory.hxx
+++ b/src/fs/StandardDirectory.hxx
@@ -26,45 +26,51 @@
 /**
  * Obtains configuration directory for the current user.
  */
-AllocatedPath GetUserConfigDir();
+AllocatedPath
+GetUserConfigDir() noexcept;
 
 /**
  * Obtains music directory for the current user.
  */
-AllocatedPath GetUserMusicDir();
+AllocatedPath
+GetUserMusicDir() noexcept;
 
 /**
  * Obtains cache directory for the current user.
  */
 gcc_pure
 AllocatedPath
-GetUserCacheDir();
+GetUserCacheDir() noexcept;
 
 #ifdef WIN32
 
 /**
  * Obtains system configuration directory.
  */
-AllocatedPath GetSystemConfigDir();
+AllocatedPath
+GetSystemConfigDir() noexcept;
 
 /**
  * Obtains application application base directory.
  * Application base directory is a directory that contains 'bin' folder
  * for current executable.
  */
-AllocatedPath GetAppBaseDir();
+AllocatedPath
+GetAppBaseDir() noexcept;
 
 #else
 
 /**
  * Obtains home directory for the current user.
  */
-AllocatedPath GetHomeDir();
+AllocatedPath
+GetHomeDir() noexcept;
 
 /**
  * Obtains home directory for the specified user.
  */
-AllocatedPath GetHomeDir(const char *user_name);
+AllocatedPath
+GetHomeDir(const char *user_name) noexcept;
 
 #endif
 
diff --git a/src/fs/Traits.cxx b/src/fs/Traits.cxx
index c3f10a51a..ac0700bfb 100644
--- a/src/fs/Traits.cxx
+++ b/src/fs/Traits.cxx
@@ -114,50 +114,51 @@ RelativePathImpl(typename Traits::const_pointer_type base,
 
 PathTraitsFS::string
 PathTraitsFS::Build(const_pointer_type a, size_t a_size,
-		    const_pointer_type b, size_t b_size)
+		    const_pointer_type b, size_t b_size) noexcept
 {
 	return BuildPathImpl<PathTraitsFS>(a, a_size, b, b_size);
 }
 
 PathTraitsFS::const_pointer_type
-PathTraitsFS::GetBase(PathTraitsFS::const_pointer_type p)
+PathTraitsFS::GetBase(PathTraitsFS::const_pointer_type p) noexcept
 {
 	return GetBasePathImpl<PathTraitsFS>(p);
 }
 
 PathTraitsFS::string
-PathTraitsFS::GetParent(PathTraitsFS::const_pointer_type p)
+PathTraitsFS::GetParent(PathTraitsFS::const_pointer_type p) noexcept
 {
 	return GetParentPathImpl<PathTraitsFS>(p);
 }
 
 PathTraitsFS::const_pointer_type
-PathTraitsFS::Relative(const_pointer_type base, const_pointer_type other)
+PathTraitsFS::Relative(const_pointer_type base, const_pointer_type other) noexcept
 {
 	return RelativePathImpl<PathTraitsFS>(base, other);
 }
 
 PathTraitsUTF8::string
 PathTraitsUTF8::Build(const_pointer_type a, size_t a_size,
-		      const_pointer_type b, size_t b_size)
+		      const_pointer_type b, size_t b_size) noexcept
 {
 	return BuildPathImpl<PathTraitsUTF8>(a, a_size, b, b_size);
 }
 
 PathTraitsUTF8::const_pointer_type
-PathTraitsUTF8::GetBase(const_pointer_type p)
+PathTraitsUTF8::GetBase(const_pointer_type p) noexcept
 {
 	return GetBasePathImpl<PathTraitsUTF8>(p);
 }
 
 PathTraitsUTF8::string
-PathTraitsUTF8::GetParent(const_pointer_type p)
+PathTraitsUTF8::GetParent(const_pointer_type p) noexcept
 {
 	return GetParentPathImpl<PathTraitsUTF8>(p);
 }
 
 PathTraitsUTF8::const_pointer_type
-PathTraitsUTF8::Relative(const_pointer_type base, const_pointer_type other)
+PathTraitsUTF8::Relative(const_pointer_type base,
+			 const_pointer_type other) noexcept
 {
 	return RelativePathImpl<PathTraitsUTF8>(base, other);
 }
diff --git a/src/fs/Traits.hxx b/src/fs/Traits.hxx
index 388c41195..699ab73e8 100644
--- a/src/fs/Traits.hxx
+++ b/src/fs/Traits.hxx
@@ -124,7 +124,7 @@ struct PathTraitsFS {
 	 * The return value points inside the given string.
 	 */
 	gcc_pure gcc_nonnull_all
-	static const_pointer_type GetBase(const_pointer_type p);
+	static const_pointer_type GetBase(const_pointer_type p) noexcept;
 
 	/**
 	 * Determine the "parent" file name of the given native path.
@@ -132,7 +132,7 @@ struct PathTraitsFS {
 	 * separator in the given input string.
 	 */
 	gcc_pure gcc_nonnull_all
-	static string GetParent(const_pointer_type p);
+	static string GetParent(const_pointer_type p) noexcept;
 
 	/**
 	 * Determine the relative part of the given path to this
@@ -142,7 +142,7 @@ struct PathTraitsFS {
 	 */
 	gcc_pure gcc_nonnull_all
 	static const_pointer_type Relative(const_pointer_type base,
-					   const_pointer_type other);
+					   const_pointer_type other) noexcept;
 
 	/**
 	 * Constructs the path from the given components.
@@ -152,10 +152,10 @@ struct PathTraitsFS {
 	 */
 	gcc_pure gcc_nonnull_all
 	static string Build(const_pointer_type a, size_t a_size,
-			    const_pointer_type b, size_t b_size);
+			    const_pointer_type b, size_t b_size) noexcept;
 
 	gcc_pure gcc_nonnull_all
-	static string Build(const_pointer_type a, const_pointer_type b) {
+	static string Build(const_pointer_type a, const_pointer_type b) noexcept {
 		return Build(a, GetLength(a), b, GetLength(b));
 	}
 };
@@ -224,7 +224,7 @@ struct PathTraitsUTF8 {
 	 * The return value points inside the given string.
 	 */
 	gcc_pure gcc_nonnull_all
-	static const_pointer_type GetBase(const_pointer_type p);
+	static const_pointer_type GetBase(const_pointer_type p) noexcept;
 
 	/**
 	 * Determine the "parent" file name of the given UTF-8 path.
@@ -232,7 +232,7 @@ struct PathTraitsUTF8 {
 	 * separator in the given input string.
 	 */
 	gcc_pure gcc_nonnull_all
-	static string GetParent(const_pointer_type p);
+	static string GetParent(const_pointer_type p) noexcept;
 
 	/**
 	 * Determine the relative part of the given path to this
@@ -242,7 +242,7 @@ struct PathTraitsUTF8 {
 	 */
 	gcc_pure gcc_nonnull_all
 	static const_pointer_type Relative(const_pointer_type base,
-					   const_pointer_type other);
+					   const_pointer_type other) noexcept;
 
 	/**
 	 * Constructs the path from the given components.
@@ -252,7 +252,7 @@ struct PathTraitsUTF8 {
 	 */
 	gcc_pure gcc_nonnull_all
 	static string Build(const_pointer_type a, size_t a_size,
-			    const_pointer_type b, size_t b_size);
+			    const_pointer_type b, size_t b_size) noexcept;
 
 	gcc_pure gcc_nonnull_all
 	static string Build(const_pointer_type a, const_pointer_type b) {
diff --git a/src/fs/io/AutoGunzipReader.cxx b/src/fs/io/AutoGunzipReader.cxx
index c4a4dab61..bfbab240f 100644
--- a/src/fs/io/AutoGunzipReader.cxx
+++ b/src/fs/io/AutoGunzipReader.cxx
@@ -28,7 +28,7 @@ AutoGunzipReader::~AutoGunzipReader()
 
 gcc_pure
 static bool
-IsGzip(const uint8_t data[4])
+IsGzip(const uint8_t data[4]) noexcept
 {
 	return data[0] == 0x1f && data[1] == 0x8b && data[2] == 0x08 &&
 		(data[3] & 0xe0) == 0;
diff --git a/src/fs/io/FileOutputStream.cxx b/src/fs/io/FileOutputStream.cxx
index 6675cb431..b72bee643 100644
--- a/src/fs/io/FileOutputStream.cxx
+++ b/src/fs/io/FileOutputStream.cxx
@@ -78,7 +78,7 @@ FileOutputStream::OpenAppend(bool create)
 }
 
 uint64_t
-FileOutputStream::Tell() const
+FileOutputStream::Tell() const noexcept
 {
 	LONG high = 0;
 	DWORD low = SetFilePointer(handle, 0, &high, FILE_CURRENT);
@@ -184,7 +184,7 @@ FileOutputStream::OpenAppend(bool create)
 }
 
 uint64_t
-FileOutputStream::Tell() const
+FileOutputStream::Tell() const noexcept
 {
 	return fd.Tell();
 }
diff --git a/src/fs/io/FileOutputStream.hxx b/src/fs/io/FileOutputStream.hxx
index 8b1b30bd7..0d195909c 100644
--- a/src/fs/io/FileOutputStream.hxx
+++ b/src/fs/io/FileOutputStream.hxx
@@ -101,7 +101,7 @@ public:
 	}
 
 	gcc_pure
-	uint64_t Tell() const;
+	uint64_t Tell() const noexcept;
 
 	/* virtual methods from class OutputStream */
 	void Write(const void *data, size_t size) override;
diff --git a/src/fs/io/FileReader.hxx b/src/fs/io/FileReader.hxx
index 27a5e451b..7ca981f7d 100644
--- a/src/fs/io/FileReader.hxx
+++ b/src/fs/io/FileReader.hxx
@@ -90,7 +90,7 @@ public:
 	FileInfo GetFileInfo() const;
 
 	gcc_pure
-	uint64_t GetSize() const {
+	uint64_t GetSize() const noexcept {
 #ifdef WIN32
 		LARGE_INTEGER size;
 		return GetFileSizeEx(handle, &size)
@@ -102,7 +102,7 @@ public:
 	}
 
 	gcc_pure
-	uint64_t GetPosition() const {
+	uint64_t GetPosition() const noexcept {
 #ifdef WIN32
 		LARGE_INTEGER zero;
 		zero.QuadPart = 0;
diff --git a/src/input/AsyncInputStream.cxx b/src/input/AsyncInputStream.cxx
index 4f18782fe..52621019c 100644
--- a/src/input/AsyncInputStream.cxx
+++ b/src/input/AsyncInputStream.cxx
@@ -89,7 +89,7 @@ AsyncInputStream::Check()
 }
 
 bool
-AsyncInputStream::IsEOF()
+AsyncInputStream::IsEOF() noexcept
 {
 	return (KnownSize() && offset >= size) ||
 		(!open && buffer.IsEmpty());
@@ -164,7 +164,7 @@ AsyncInputStream::ReadTag()
 }
 
 bool
-AsyncInputStream::IsAvailable()
+AsyncInputStream::IsAvailable() noexcept
 {
 	return postponed_exception ||
 		IsEOF() ||
diff --git a/src/input/AsyncInputStream.hxx b/src/input/AsyncInputStream.hxx
index 32072d219..3a0b00580 100644
--- a/src/input/AsyncInputStream.hxx
+++ b/src/input/AsyncInputStream.hxx
@@ -82,10 +82,10 @@ public:
 
 	/* virtual methods from InputStream */
 	void Check() final;
-	bool IsEOF() final;
+	bool IsEOF() noexcept final;
 	void Seek(offset_type new_offset) final;
 	Tag *ReadTag() final;
-	bool IsAvailable() final;
+	bool IsAvailable() noexcept final;
 	size_t Read(void *ptr, size_t read_size) final;
 
 protected:
diff --git a/src/input/InputStream.cxx b/src/input/InputStream.cxx
index 592c6ebe1..d17a95f1e 100644
--- a/src/input/InputStream.cxx
+++ b/src/input/InputStream.cxx
@@ -75,14 +75,14 @@ InputStream::LockWaitReady()
  */
 gcc_pure
 static bool
-ExpensiveSeeking(const char *uri)
+ExpensiveSeeking(const char *uri) noexcept
 {
 	return StringStartsWith(uri, "http://") ||
 		StringStartsWith(uri, "https://");
 }
 
 bool
-InputStream::CheapSeeking() const
+InputStream::CheapSeeking() const noexcept
 {
 	return IsSeekable() && !ExpensiveSeeking(uri.c_str());
 }
@@ -121,7 +121,7 @@ InputStream::LockReadTag()
 }
 
 bool
-InputStream::IsAvailable()
+InputStream::IsAvailable() noexcept
 {
 	return true;
 }
@@ -169,7 +169,7 @@ InputStream::LockReadFull(void *ptr, size_t _size)
 }
 
 bool
-InputStream::LockIsEOF()
+InputStream::LockIsEOF() noexcept
 {
 	const std::lock_guard<Mutex> protect(mutex);
 	return IsEOF();
diff --git a/src/input/InputStream.hxx b/src/input/InputStream.hxx
index 095b498fc..86f19f094 100644
--- a/src/input/InputStream.hxx
+++ b/src/input/InputStream.hxx
@@ -261,7 +261,7 @@ public:
 	 * Determines whether seeking is cheap.  This is true for local files.
 	 */
 	gcc_pure
-	bool CheapSeeking() const;
+	bool CheapSeeking() const noexcept;
 
 	/**
 	 * Seeks to the specified position in the stream.  This will most
@@ -308,14 +308,14 @@ public:
 	 * The caller must lock the mutex.
 	 */
 	gcc_pure
-	virtual bool IsEOF() = 0;
+	virtual bool IsEOF() noexcept = 0;
 
 	/**
 	 * Wrapper for IsEOF() which locks and unlocks the mutex; the
 	 * caller must not be holding it already.
 	 */
 	gcc_pure
-	bool LockIsEOF();
+	bool LockIsEOF() noexcept;
 
 	/**
 	 * Reads the tag from the stream.
@@ -343,7 +343,7 @@ public:
 	 * The caller must lock the mutex.
 	 */
 	gcc_pure
-	virtual bool IsAvailable();
+	virtual bool IsAvailable() noexcept;
 
 	/**
 	 * Reads data from the stream into the caller-supplied buffer.
diff --git a/src/input/ProxyInputStream.cxx b/src/input/ProxyInputStream.cxx
index 481edd547..c8e66fecf 100644
--- a/src/input/ProxyInputStream.cxx
+++ b/src/input/ProxyInputStream.cxx
@@ -70,7 +70,7 @@ ProxyInputStream::Seek(offset_type new_offset)
 }
 
 bool
-ProxyInputStream::IsEOF()
+ProxyInputStream::IsEOF() noexcept
 {
 	return input.IsEOF();
 }
@@ -82,7 +82,7 @@ ProxyInputStream::ReadTag()
 }
 
 bool
-ProxyInputStream::IsAvailable()
+ProxyInputStream::IsAvailable() noexcept
 {
 	return input.IsAvailable();
 }
diff --git a/src/input/ProxyInputStream.hxx b/src/input/ProxyInputStream.hxx
index 27257b169..bce35c224 100644
--- a/src/input/ProxyInputStream.hxx
+++ b/src/input/ProxyInputStream.hxx
@@ -46,9 +46,9 @@ public:
 	void Check() override;
 	void Update() override;
 	void Seek(offset_type new_offset) override;
-	bool IsEOF() override;
+	bool IsEOF() noexcept override;
 	Tag *ReadTag() override;
-	bool IsAvailable() override;
+	bool IsAvailable() noexcept override;
 	size_t Read(void *ptr, size_t read_size) override;
 
 protected:
diff --git a/src/input/ThreadInputStream.cxx b/src/input/ThreadInputStream.cxx
index 77faf4b5b..2463c7df4 100644
--- a/src/input/ThreadInputStream.cxx
+++ b/src/input/ThreadInputStream.cxx
@@ -124,7 +124,7 @@ ThreadInputStream::Check()
 }
 
 bool
-ThreadInputStream::IsAvailable()
+ThreadInputStream::IsAvailable() noexcept
 {
 	assert(!thread.IsInside());
 
@@ -158,7 +158,7 @@ ThreadInputStream::Read(void *ptr, size_t read_size)
 }
 
 bool
-ThreadInputStream::IsEOF()
+ThreadInputStream::IsEOF() noexcept
 {
 	assert(!thread.IsInside());
 
diff --git a/src/input/ThreadInputStream.hxx b/src/input/ThreadInputStream.hxx
index 7bc168926..021bf6e03 100644
--- a/src/input/ThreadInputStream.hxx
+++ b/src/input/ThreadInputStream.hxx
@@ -84,8 +84,8 @@ public:
 
 	/* virtual methods from InputStream */
 	void Check() override final;
-	bool IsEOF() override final;
-	bool IsAvailable() override final;
+	bool IsEOF() noexcept final;
+	bool IsAvailable() noexcept final;
 	size_t Read(void *ptr, size_t size) override final;
 
 protected:
diff --git a/src/input/plugins/CdioParanoiaInputPlugin.cxx b/src/input/plugins/CdioParanoiaInputPlugin.cxx
index e87749c4d..39f90dcc0 100644
--- a/src/input/plugins/CdioParanoiaInputPlugin.cxx
+++ b/src/input/plugins/CdioParanoiaInputPlugin.cxx
@@ -96,7 +96,7 @@ class CdioParanoiaInputStream final : public InputStream {
 	}
 
 	/* virtual methods from InputStream */
-	bool IsEOF() override;
+	bool IsEOF() noexcept override;
 	size_t Read(void *ptr, size_t size) override;
 	void Seek(offset_type offset) override;
 };
@@ -340,7 +340,7 @@ CdioParanoiaInputStream::Read(void *ptr, size_t length)
 }
 
 bool
-CdioParanoiaInputStream::IsEOF()
+CdioParanoiaInputStream::IsEOF() noexcept
 {
 	return lsn_from + lsn_relofs > lsn_to;
 }
diff --git a/src/input/plugins/FfmpegInputPlugin.cxx b/src/input/plugins/FfmpegInputPlugin.cxx
index 0a7aa0cdc..4ba9b470a 100644
--- a/src/input/plugins/FfmpegInputPlugin.cxx
+++ b/src/input/plugins/FfmpegInputPlugin.cxx
@@ -59,7 +59,7 @@ struct FfmpegInputStream final : public InputStream {
 	}
 
 	/* virtual methods from InputStream */
-	bool IsEOF() override;
+	bool IsEOF() noexcept override;
 	size_t Read(void *ptr, size_t size) override;
 	void Seek(offset_type offset) override;
 };
@@ -118,7 +118,7 @@ FfmpegInputStream::Read(void *ptr, size_t read_size)
 }
 
 bool
-FfmpegInputStream::IsEOF()
+FfmpegInputStream::IsEOF() noexcept
 {
 	return eof;
 }
diff --git a/src/input/plugins/FileInputPlugin.cxx b/src/input/plugins/FileInputPlugin.cxx
index 0642b7233..fc51715ad 100644
--- a/src/input/plugins/FileInputPlugin.cxx
+++ b/src/input/plugins/FileInputPlugin.cxx
@@ -45,7 +45,7 @@ public:
 
 	/* virtual methods from InputStream */
 
-	bool IsEOF() override {
+	bool IsEOF() noexcept override {
 		return GetOffset() >= GetSize();
 	}
 
diff --git a/src/input/plugins/RewindInputPlugin.cxx b/src/input/plugins/RewindInputPlugin.cxx
index 5a4f91d9b..7ece4ad50 100644
--- a/src/input/plugins/RewindInputPlugin.cxx
+++ b/src/input/plugins/RewindInputPlugin.cxx
@@ -59,7 +59,7 @@ public:
 			ProxyInputStream::Update();
 	}
 
-	bool IsEOF() override {
+	bool IsEOF() noexcept override {
 		return !ReadingFromBuffer() && ProxyInputStream::IsEOF();
 	}
 
diff --git a/src/input/plugins/SmbclientInputPlugin.cxx b/src/input/plugins/SmbclientInputPlugin.cxx
index 326a25fbc..8e802a8e1 100644
--- a/src/input/plugins/SmbclientInputPlugin.cxx
+++ b/src/input/plugins/SmbclientInputPlugin.cxx
@@ -55,7 +55,7 @@ public:
 
 	/* virtual methods from InputStream */
 
-	bool IsEOF() override {
+	bool IsEOF() noexcept override {
 		return offset >= size;
 	}
 
diff --git a/src/lib/curl/Request.cxx b/src/lib/curl/Request.cxx
index 14d626b34..d8301cbba 100644
--- a/src/lib/curl/Request.cxx
+++ b/src/lib/curl/Request.cxx
@@ -170,7 +170,7 @@ CurlRequest::Done(CURLcode result)
 
 gcc_pure
 static bool
-IsResponseBoundaryHeader(StringView s)
+IsResponseBoundaryHeader(StringView s) noexcept
 {
 	return s.size > 5 && (memcmp(s.data, "HTTP/", 5) == 0 ||
 			      /* the proprietary "ICY 200 OK" is
diff --git a/src/lib/curl/Version.cxx b/src/lib/curl/Version.cxx
index 94a248b61..2a00d669b 100644
--- a/src/lib/curl/Version.cxx
+++ b/src/lib/curl/Version.cxx
@@ -32,7 +32,7 @@
 #include <curl/curl.h>
 
 bool
-IsCurlOlderThan(unsigned version_num)
+IsCurlOlderThan(unsigned version_num) noexcept
 {
 	const auto *const info = curl_version_info(CURLVERSION_FIRST);
 	return info == nullptr || info->version_num < version_num;
diff --git a/src/lib/curl/Version.hxx b/src/lib/curl/Version.hxx
index 21b5164e5..c854a0d58 100644
--- a/src/lib/curl/Version.hxx
+++ b/src/lib/curl/Version.hxx
@@ -34,6 +34,6 @@
 
 gcc_const
 bool
-IsCurlOlderThan(unsigned version_num);
+IsCurlOlderThan(unsigned version_num) noexcept;
 
 #endif
diff --git a/src/lib/expat/ExpatParser.cxx b/src/lib/expat/ExpatParser.cxx
index 75e4291a3..28e68e11a 100644
--- a/src/lib/expat/ExpatParser.cxx
+++ b/src/lib/expat/ExpatParser.cxx
@@ -32,7 +32,7 @@ ExpatParser::Parse(const char *data, size_t length, bool is_final)
 
 const char *
 ExpatParser::GetAttribute(const XML_Char **atts,
-			  const char *name)
+			  const char *name) noexcept
 {
 	for (unsigned i = 0; atts[i] != nullptr; i += 2)
 		if (strcmp(atts[i], name) == 0)
@@ -43,7 +43,7 @@ ExpatParser::GetAttribute(const XML_Char **atts,
 
 const char *
 ExpatParser::GetAttributeCase(const XML_Char **atts,
-			      const char *name)
+			      const char *name) noexcept
 {
 	for (unsigned i = 0; atts[i] != nullptr; i += 2)
 		if (StringEqualsCaseASCII(atts[i], name))
diff --git a/src/lib/expat/ExpatParser.hxx b/src/lib/expat/ExpatParser.hxx
index 1215b8bc4..99feb03fa 100644
--- a/src/lib/expat/ExpatParser.hxx
+++ b/src/lib/expat/ExpatParser.hxx
@@ -64,11 +64,11 @@ public:
 	ExpatParser &operator=(const ExpatParser &) = delete;
 
 	void SetElementHandler(XML_StartElementHandler start,
-			       XML_EndElementHandler end) {
+			       XML_EndElementHandler end) noexcept {
 		XML_SetElementHandler(parser, start, end);
 	}
 
-	void SetCharacterDataHandler(XML_CharacterDataHandler charhndl) {
+	void SetCharacterDataHandler(XML_CharacterDataHandler charhndl) noexcept {
 		XML_SetCharacterDataHandler(parser, charhndl);
 	}
 
@@ -78,11 +78,11 @@ public:
 
 	gcc_pure
 	static const char *GetAttribute(const XML_Char **atts,
-					const char *name);
+					const char *name) noexcept;
 
 	gcc_pure
 	static const char *GetAttributeCase(const XML_Char **atts,
-					    const char *name);
+					    const char *name) noexcept;
 };
 
 /**
@@ -114,13 +114,13 @@ public:
 
 	gcc_pure
 	static const char *GetAttribute(const XML_Char **atts,
-					const char *name) {
+					const char *name) noexcept {
 		return ExpatParser::GetAttribute(atts, name);
 	}
 
 	gcc_pure
 	static const char *GetAttributeCase(const XML_Char **atts,
-					    const char *name) {
+					    const char *name) noexcept {
 		return ExpatParser::GetAttributeCase(atts, name);
 	}
 
diff --git a/src/lib/ffmpeg/LogCallback.cxx b/src/lib/ffmpeg/LogCallback.cxx
index ee0389947..c682da63d 100644
--- a/src/lib/ffmpeg/LogCallback.cxx
+++ b/src/lib/ffmpeg/LogCallback.cxx
@@ -34,7 +34,7 @@ extern "C" {
 
 gcc_const
 static LogLevel
-FfmpegImportLogLevel(int level)
+FfmpegImportLogLevel(int level) noexcept
 {
 	if (level <= AV_LOG_FATAL)
 		return LogLevel::ERROR;
diff --git a/src/lib/ffmpeg/Time.hxx b/src/lib/ffmpeg/Time.hxx
index 39805b85f..71f7edd22 100644
--- a/src/lib/ffmpeg/Time.hxx
+++ b/src/lib/ffmpeg/Time.hxx
@@ -41,7 +41,7 @@ extern "C" {
  */
 gcc_const
 static inline double
-FfmpegTimeToDouble(int64_t t, const AVRational time_base)
+FfmpegTimeToDouble(int64_t t, const AVRational time_base) noexcept
 {
 	assert(t != (int64_t)AV_NOPTS_VALUE);
 
@@ -64,7 +64,7 @@ RatioToAVRational()
  */
 gcc_const
 static inline SongTime
-FromFfmpegTime(int64_t t, const AVRational time_base)
+FromFfmpegTime(int64_t t, const AVRational time_base) noexcept
 {
 	assert(t != (int64_t)AV_NOPTS_VALUE);
 
@@ -77,7 +77,7 @@ FromFfmpegTime(int64_t t, const AVRational time_base)
  */
 gcc_const
 static inline SignedSongTime
-FromFfmpegTimeChecked(int64_t t, const AVRational time_base)
+FromFfmpegTimeChecked(int64_t t, const AVRational time_base) noexcept
 {
 	return t != (int64_t)AV_NOPTS_VALUE
 		? SignedSongTime(FromFfmpegTime(t, time_base))
@@ -89,7 +89,7 @@ FromFfmpegTimeChecked(int64_t t, const AVRational time_base)
  */
 gcc_const
 static inline int64_t
-ToFfmpegTime(SongTime t, const AVRational time_base)
+ToFfmpegTime(SongTime t, const AVRational time_base) noexcept
 {
 	return av_rescale_q(t.count(),
 			    RatioToAVRational<SongTime::period>(),
diff --git a/src/lib/icu/Collate.cxx b/src/lib/icu/Collate.cxx
index 10452cc26..abb4b709c 100644
--- a/src/lib/icu/Collate.cxx
+++ b/src/lib/icu/Collate.cxx
@@ -65,7 +65,7 @@ IcuCollateInit()
 }
 
 void
-IcuCollateFinish()
+IcuCollateFinish() noexcept
 {
 	assert(collator != nullptr);
 
@@ -76,7 +76,7 @@ IcuCollateFinish()
 
 gcc_pure
 int
-IcuCollate(const char *a, const char *b)
+IcuCollate(const char *a, const char *b) noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
diff --git a/src/lib/icu/Collate.hxx b/src/lib/icu/Collate.hxx
index f96f32423..d6f999214 100644
--- a/src/lib/icu/Collate.hxx
+++ b/src/lib/icu/Collate.hxx
@@ -32,11 +32,11 @@ void
 IcuCollateInit();
 
 void
-IcuCollateFinish();
+IcuCollateFinish() noexcept;
 
 gcc_pure gcc_nonnull_all
 int
-IcuCollate(const char *a, const char *b);
+IcuCollate(const char *a, const char *b) noexcept;
 
 gcc_pure gcc_nonnull_all
 AllocatedString<char>
diff --git a/src/lib/nfs/Base.cxx b/src/lib/nfs/Base.cxx
index 0a9f4335c..5e67cb5f4 100644
--- a/src/lib/nfs/Base.cxx
+++ b/src/lib/nfs/Base.cxx
@@ -46,7 +46,7 @@ nfs_set_base(const char *server, const char *export_name)
 }
 
 const char *
-nfs_check_base(const char *server, const char *path)
+nfs_check_base(const char *server, const char *path) noexcept
 {
 	assert(server != nullptr);
 	assert(path != nullptr);
diff --git a/src/lib/nfs/Base.hxx b/src/lib/nfs/Base.hxx
index 2ca15929d..78d25da72 100644
--- a/src/lib/nfs/Base.hxx
+++ b/src/lib/nfs/Base.hxx
@@ -41,6 +41,6 @@ nfs_set_base(const char *server, const char *export_name);
  */
 gcc_pure
 const char *
-nfs_check_base(const char *server, const char *path);
+nfs_check_base(const char *server, const char *path) noexcept;
 
 #endif
diff --git a/src/lib/nfs/Cancellable.hxx b/src/lib/nfs/Cancellable.hxx
index 7c2ccd71a..89635bec7 100644
--- a/src/lib/nfs/Cancellable.hxx
+++ b/src/lib/nfs/Cancellable.hxx
@@ -91,29 +91,29 @@ private:
 	};
 
 	gcc_pure
-	iterator Find(reference_type p) {
+	iterator Find(reference_type p) noexcept {
 		return std::find_if(list.begin(), list.end(), MatchPointer(p));
 	}
 
 	gcc_pure
-	const_iterator Find(const_reference_type p) const {
+	const_iterator Find(const_reference_type p) const noexcept {
 		return std::find_if(list.begin(), list.end(), MatchPointer(p));
 	}
 
 	gcc_pure
-	iterator Find(CT &c) {
+	iterator Find(CT &c) noexcept {
 		return list.iterator_to(c);
 	}
 
 	gcc_pure
-	const_iterator Find(const CT &c) const {
+	const_iterator Find(const CT &c) const noexcept {
 		return list.iterator_to(c);
 	}
 
 public:
 #ifndef NDEBUG
 	gcc_pure
-	bool IsEmpty() const {
+	bool IsEmpty() const noexcept {
 		for (const auto &c : list)
 			if (!c.IsCancelled())
 				return false;
@@ -123,7 +123,7 @@ public:
 #endif
 
 	gcc_pure
-	bool Contains(const_reference_type p) const {
+	bool Contains(const_reference_type p) const noexcept {
 		return Find(p) != list.end();
 	}
 
@@ -151,7 +151,7 @@ public:
 		i->Cancel();
 	}
 
-	CT &Get(reference_type p) {
+	CT &Get(reference_type p) noexcept {
 		auto i = Find(p);
 		assert(i != list.end());
 
diff --git a/src/lib/nfs/Connection.hxx b/src/lib/nfs/Connection.hxx
index ec858e177..a752535e0 100644
--- a/src/lib/nfs/Connection.hxx
+++ b/src/lib/nfs/Connection.hxx
@@ -135,7 +135,7 @@ class NfsConnection : SocketMonitor, TimeoutMonitor, DeferredMonitor {
 public:
 	gcc_nonnull_all
 	NfsConnection(EventLoop &_loop,
-		      const char *_server, const char *_export_name)
+		      const char *_server, const char *_export_name) noexcept
 		:SocketMonitor(_loop), TimeoutMonitor(_loop),
 		 DeferredMonitor(_loop),
 		 server(_server), export_name(_export_name),
diff --git a/src/lib/nfs/Glue.cxx b/src/lib/nfs/Glue.cxx
index 173f4b333..abcb06f1c 100644
--- a/src/lib/nfs/Glue.cxx
+++ b/src/lib/nfs/Glue.cxx
@@ -50,7 +50,7 @@ nfs_finish()
 }
 
 NfsConnection &
-nfs_get_connection(const char *server, const char *export_name)
+nfs_get_connection(const char *server, const char *export_name) noexcept
 {
 	assert(in_use > 0);
 	assert(io_thread_inside());
diff --git a/src/lib/nfs/Glue.hxx b/src/lib/nfs/Glue.hxx
index 81b56ba64..3fc795866 100644
--- a/src/lib/nfs/Glue.hxx
+++ b/src/lib/nfs/Glue.hxx
@@ -33,6 +33,6 @@ nfs_finish();
 
 gcc_pure
 NfsConnection &
-nfs_get_connection(const char *server, const char *export_name);
+nfs_get_connection(const char *server, const char *export_name) noexcept;
 
 #endif
diff --git a/src/lib/nfs/Manager.cxx b/src/lib/nfs/Manager.cxx
index d9385782b..89999e44f 100644
--- a/src/lib/nfs/Manager.cxx
+++ b/src/lib/nfs/Manager.cxx
@@ -38,7 +38,7 @@ NfsManager::ManagedConnection::OnNfsConnectionError(std::exception_ptr &&e)
 
 inline bool
 NfsManager::Compare::operator()(const LookupKey a,
-				const ManagedConnection &b) const
+				const ManagedConnection &b) const noexcept
 {
 	int result = strcmp(a.server, b.GetServer());
 	if (result != 0)
@@ -50,7 +50,7 @@ NfsManager::Compare::operator()(const LookupKey a,
 
 inline bool
 NfsManager::Compare::operator()(const ManagedConnection &a,
-				const LookupKey b) const
+				const LookupKey b) const noexcept
 {
 	int result = strcmp(a.GetServer(), b.server);
 	if (result != 0)
@@ -62,7 +62,7 @@ NfsManager::Compare::operator()(const ManagedConnection &a,
 
 inline bool
 NfsManager::Compare::operator()(const ManagedConnection &a,
-				const ManagedConnection &b) const
+				const ManagedConnection &b) const noexcept
 {
 	int result = strcmp(a.GetServer(), b.GetServer());
 	if (result != 0)
@@ -82,7 +82,7 @@ NfsManager::~NfsManager()
 }
 
 NfsConnection &
-NfsManager::GetConnection(const char *server, const char *export_name)
+NfsManager::GetConnection(const char *server, const char *export_name) noexcept
 {
 	assert(server != nullptr);
 	assert(export_name != nullptr);
diff --git a/src/lib/nfs/Manager.hxx b/src/lib/nfs/Manager.hxx
index 6e9099e8f..ade256003 100644
--- a/src/lib/nfs/Manager.hxx
+++ b/src/lib/nfs/Manager.hxx
@@ -59,15 +59,15 @@ class NfsManager final : IdleMonitor {
 	struct Compare {
 		gcc_pure
 		bool operator()(const LookupKey a,
-				const ManagedConnection &b) const;
+				const ManagedConnection &b) const noexcept;
 
 		gcc_pure
 		bool operator()(const ManagedConnection &a,
-				const LookupKey b) const;
+				const LookupKey b) const noexcept;
 
 		gcc_pure
 		bool operator()(const ManagedConnection &a,
-				const ManagedConnection &b) const;
+				const ManagedConnection &b) const noexcept;
 	};
 
 	/**
@@ -99,7 +99,7 @@ public:
 
 	gcc_pure
 	NfsConnection &GetConnection(const char *server,
-				     const char *export_name);
+				     const char *export_name) noexcept;
 
 private:
 	void ScheduleDelete(ManagedConnection &c) {
diff --git a/src/lib/upnp/Discovery.cxx b/src/lib/upnp/Discovery.cxx
index 024658683..121c01c57 100644
--- a/src/lib/upnp/Discovery.cxx
+++ b/src/lib/upnp/Discovery.cxx
@@ -36,7 +36,7 @@ static constexpr char ContentDirectorySType[] = "urn:schemas-upnp-org:service:Co
 // version 1
 gcc_pure
 static bool
-isCDService(const char *st)
+isCDService(const char *st) noexcept
 {
 	constexpr size_t sz = sizeof(ContentDirectorySType) - 3;
 	return memcmp(ContentDirectorySType, st, sz) == 0;
@@ -47,7 +47,7 @@ static constexpr char MediaServerDType[] = "urn:schemas-upnp-org:device:MediaSer
 
 gcc_pure
 static bool
-isMSDevice(const char *st)
+isMSDevice(const char *st) noexcept
 {
 	constexpr size_t sz = sizeof(MediaServerDType) - 3;
 	return memcmp(MediaServerDType, st, sz) == 0;
diff --git a/src/lib/upnp/Util.cxx b/src/lib/upnp/Util.cxx
index 61c11719d..b6cd4189e 100644
--- a/src/lib/upnp/Util.cxx
+++ b/src/lib/upnp/Util.cxx
@@ -23,7 +23,7 @@
 
 /** Get rid of white space at both ends */
 void
-trimstring(std::string &s, const char *ws)
+trimstring(std::string &s, const char *ws) noexcept
 {
 	auto pos = s.find_first_not_of(ws);
 	if (pos == std::string::npos) {
@@ -38,14 +38,14 @@ trimstring(std::string &s, const char *ws)
 }
 
 static void
-path_catslash(std::string &s)
+path_catslash(std::string &s) noexcept
 {
 	if (s.empty() || s.back() != '/')
 		s += '/';
 }
 
 std::string
-path_getfather(const std::string &s)
+path_getfather(const std::string &s) noexcept
 {
 	std::string father = s;
 
@@ -71,7 +71,7 @@ path_getfather(const std::string &s)
 
 std::list<std::string>
 stringToTokens(const std::string &str,
-	       const char delim)
+	       const char delim) noexcept
 {
 	std::list<std::string> tokens;
 
@@ -105,7 +105,7 @@ stringToTokens(const std::string &str,
 
 template <class T>
 bool
-csvToStrings(const char *s, T &tokens)
+csvToStrings(const char *s, T &tokens) noexcept
 {
 	assert(tokens.empty());
 
@@ -132,4 +132,4 @@ csvToStrings(const char *s, T &tokens)
 	}
 }
 
-template bool csvToStrings<std::list<std::string>>(const char *, std::list<std::string> &);
+template bool csvToStrings<std::list<std::string>>(const char *, std::list<std::string> &) noexcept;
diff --git a/src/lib/upnp/Util.hxx b/src/lib/upnp/Util.hxx
index b935611ec..5ff2710a6 100644
--- a/src/lib/upnp/Util.hxx
+++ b/src/lib/upnp/Util.hxx
@@ -26,17 +26,17 @@
 #include <list>
 
 void
-trimstring(std::string &s, const char *ws = " \t\n");
+trimstring(std::string &s, const char *ws = " \t\n") noexcept;
 
 std::string
-path_getfather(const std::string &s);
+path_getfather(const std::string &s) noexcept;
 
 gcc_pure
 std::list<std::string>
-stringToTokens(const std::string &str, char delim);
+stringToTokens(const std::string &str, char delim) noexcept;
 
 template <class T>
 bool
-csvToStrings(const char *s, T &tokens);
+csvToStrings(const char *s, T &tokens) noexcept;
 
 #endif /* _UPNPP_H_X_INCLUDED_ */
diff --git a/src/ls.cxx b/src/ls.cxx
index 2ba735b4d..72754dd7f 100644
--- a/src/ls.cxx
+++ b/src/ls.cxx
@@ -89,7 +89,8 @@ print_supported_uri_schemes(Response &r)
 	}
 }
 
-bool uri_supported_scheme(const char *uri)
+bool
+uri_supported_scheme(const char *uri) noexcept
 {
 	const char *const*urlPrefixes = remoteUrlPrefixes;
 
diff --git a/src/ls.hxx b/src/ls.hxx
index d4c1d296b..b8c8f249a 100644
--- a/src/ls.hxx
+++ b/src/ls.hxx
@@ -32,7 +32,8 @@ class Response;
  * uri_has_scheme() first.
  */
 gcc_pure
-bool uri_supported_scheme(const char *url);
+bool
+uri_supported_scheme(const char *url) noexcept;
 
 /**
  * Send a list of supported URI schemes to the client.  This is the
diff --git a/src/mixer/MixerAll.cxx b/src/mixer/MixerAll.cxx
index e9bcde93a..d45e51ae4 100644
--- a/src/mixer/MixerAll.cxx
+++ b/src/mixer/MixerAll.cxx
@@ -30,8 +30,9 @@
 
 #include <assert.h>
 
+gcc_pure
 static int
-output_mixer_get_volume(const AudioOutput &ao)
+output_mixer_get_volume(const AudioOutput &ao) noexcept
 {
 	if (!ao.enabled)
 		return -1;
@@ -51,7 +52,7 @@ output_mixer_get_volume(const AudioOutput &ao)
 }
 
 int
-MultipleOutputs::GetVolume() const
+MultipleOutputs::GetVolume() const noexcept
 {
 	unsigned ok = 0;
 	int total = 0;
@@ -71,7 +72,7 @@ MultipleOutputs::GetVolume() const
 }
 
 static bool
-output_mixer_set_volume(AudioOutput &ao, unsigned volume)
+output_mixer_set_volume(AudioOutput &ao, unsigned volume) noexcept
 {
 	assert(volume <= 100);
 
@@ -94,7 +95,7 @@ output_mixer_set_volume(AudioOutput &ao, unsigned volume)
 }
 
 bool
-MultipleOutputs::SetVolume(unsigned volume)
+MultipleOutputs::SetVolume(unsigned volume) noexcept
 {
 	assert(volume <= 100);
 
@@ -107,7 +108,7 @@ MultipleOutputs::SetVolume(unsigned volume)
 }
 
 static int
-output_mixer_get_software_volume(const AudioOutput &ao)
+output_mixer_get_software_volume(const AudioOutput &ao) noexcept
 {
 	if (!ao.enabled)
 		return -1;
@@ -120,7 +121,7 @@ output_mixer_get_software_volume(const AudioOutput &ao)
 }
 
 int
-MultipleOutputs::GetSoftwareVolume() const
+MultipleOutputs::GetSoftwareVolume() const noexcept
 {
 	unsigned ok = 0;
 	int total = 0;
@@ -140,7 +141,7 @@ MultipleOutputs::GetSoftwareVolume() const
 }
 
 void
-MultipleOutputs::SetSoftwareVolume(unsigned volume)
+MultipleOutputs::SetSoftwareVolume(unsigned volume) noexcept
 {
 	assert(volume <= PCM_VOLUME_1);
 
diff --git a/src/mixer/MixerType.cxx b/src/mixer/MixerType.cxx
index cfc0edab9..e792123df 100644
--- a/src/mixer/MixerType.cxx
+++ b/src/mixer/MixerType.cxx
@@ -24,7 +24,7 @@
 #include <string.h>
 
 MixerType
-mixer_type_parse(const char *input)
+mixer_type_parse(const char *input) noexcept
 {
 	assert(input != NULL);
 
diff --git a/src/mixer/MixerType.hxx b/src/mixer/MixerType.hxx
index 0c5b55031..6c6d4cb47 100644
--- a/src/mixer/MixerType.hxx
+++ b/src/mixer/MixerType.hxx
@@ -20,6 +20,8 @@
 #ifndef MPD_MIXER_TYPE_HXX
 #define MPD_MIXER_TYPE_HXX
 
+#include "Compiler.h"
+
 enum class MixerType {
 	/** parser error */
 	UNKNOWN,
@@ -44,7 +46,8 @@ enum class MixerType {
  * a #MixerType value; #MixerType::UNKNOWN means #input could not be
  * parsed
  */
+gcc_pure
 MixerType
-mixer_type_parse(const char *input);
+mixer_type_parse(const char *input) noexcept;
 
 #endif
diff --git a/src/mixer/Volume.cxx b/src/mixer/Volume.cxx
index 365136240..c85dc8b8f 100644
--- a/src/mixer/Volume.cxx
+++ b/src/mixer/Volume.cxx
@@ -42,14 +42,14 @@ static int last_hardware_volume = -1;
 static PeriodClock hardware_volume_clock;
 
 void
-InvalidateHardwareVolume()
+InvalidateHardwareVolume() noexcept
 {
 	/* flush the hardware volume cache */
 	last_hardware_volume = -1;
 }
 
 int
-volume_level_get(const MultipleOutputs &outputs)
+volume_level_get(const MultipleOutputs &outputs) noexcept
 {
 	if (last_hardware_volume >= 0 &&
 	    !hardware_volume_clock.CheckUpdate(std::chrono::seconds(1)))
@@ -118,7 +118,7 @@ save_sw_volume_state(BufferedOutputStream &os)
 }
 
 unsigned
-sw_volume_state_get_hash(void)
+sw_volume_state_get_hash() noexcept
 {
 	return volume_software_set;
 }
diff --git a/src/mixer/Volume.hxx b/src/mixer/Volume.hxx
index c74786469..5ca467d77 100644
--- a/src/mixer/Volume.hxx
+++ b/src/mixer/Volume.hxx
@@ -26,11 +26,11 @@ class MultipleOutputs;
 class BufferedOutputStream;
 
 void
-InvalidateHardwareVolume();
+InvalidateHardwareVolume() noexcept;
 
 gcc_pure
 int
-volume_level_get(const MultipleOutputs &outputs);
+volume_level_get(const MultipleOutputs &outputs) noexcept;
 
 bool
 volume_level_change(MultipleOutputs &outputs, unsigned volume);
@@ -49,6 +49,6 @@ save_sw_volume_state(BufferedOutputStream &os);
  */
 gcc_pure
 unsigned
-sw_volume_state_get_hash();
+sw_volume_state_get_hash() noexcept;
 
 #endif
diff --git a/src/mixer/plugins/AlsaMixerPlugin.cxx b/src/mixer/plugins/AlsaMixerPlugin.cxx
index 85ccdf8dd..8012ca2fb 100644
--- a/src/mixer/plugins/AlsaMixerPlugin.cxx
+++ b/src/mixer/plugins/AlsaMixerPlugin.cxx
@@ -201,7 +201,8 @@ AlsaMixer::~AlsaMixer()
 
 gcc_pure
 static snd_mixer_elem_t *
-alsa_mixer_lookup_elem(snd_mixer_t *handle, const char *name, unsigned idx)
+alsa_mixer_lookup_elem(snd_mixer_t *handle,
+		       const char *name, unsigned idx) noexcept
 {
 	for (snd_mixer_elem_t *elem = snd_mixer_first_elem(handle);
 	     elem != nullptr; elem = snd_mixer_elem_next(elem)) {
diff --git a/src/mixer/plugins/SoftwareMixerPlugin.cxx b/src/mixer/plugins/SoftwareMixerPlugin.cxx
index 69491390d..14c35e7f1 100644
--- a/src/mixer/plugins/SoftwareMixerPlugin.cxx
+++ b/src/mixer/plugins/SoftwareMixerPlugin.cxx
@@ -71,7 +71,7 @@ software_mixer_init(gcc_unused EventLoop &event_loop,
 
 gcc_const
 static unsigned
-PercentVolumeToSoftwareVolume(unsigned volume)
+PercentVolumeToSoftwareVolume(unsigned volume) noexcept
 {
 	assert(volume <= 100);
 
diff --git a/src/neighbor/Glue.cxx b/src/neighbor/Glue.cxx
index f82abe899..f82e47fb8 100644
--- a/src/neighbor/Glue.cxx
+++ b/src/neighbor/Glue.cxx
@@ -93,7 +93,7 @@ NeighborGlue::Close()
 }
 
 NeighborGlue::List
-NeighborGlue::GetList() const
+NeighborGlue::GetList() const noexcept
 {
 	List result;
 
diff --git a/src/neighbor/Glue.hxx b/src/neighbor/Glue.hxx
index 68e219910..a0d749a3b 100644
--- a/src/neighbor/Glue.hxx
+++ b/src/neighbor/Glue.hxx
@@ -71,7 +71,7 @@ public:
 	 * plugins.
 	 */
 	gcc_pure
-	List GetList() const;
+	List GetList() const noexcept;
 };
 
 #endif
diff --git a/src/neighbor/Registry.cxx b/src/neighbor/Registry.cxx
index ea1c50cd6..fad045f27 100644
--- a/src/neighbor/Registry.cxx
+++ b/src/neighbor/Registry.cxx
@@ -36,7 +36,7 @@ const NeighborPlugin *const neighbor_plugins[] = {
 };
 
 const NeighborPlugin *
-GetNeighborPluginByName(const char *name)
+GetNeighborPluginByName(const char *name) noexcept
 {
 	for (auto i = neighbor_plugins; *i != nullptr; ++i)
 		if (strcmp((*i)->name, name) == 0)
diff --git a/src/neighbor/Registry.hxx b/src/neighbor/Registry.hxx
index f18c41d74..5e9ddfb62 100644
--- a/src/neighbor/Registry.hxx
+++ b/src/neighbor/Registry.hxx
@@ -32,6 +32,6 @@ extern const NeighborPlugin *const neighbor_plugins[];
 
 gcc_pure
 const NeighborPlugin *
-GetNeighborPluginByName(const char *name);
+GetNeighborPluginByName(const char *name) noexcept;
 
 #endif
diff --git a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
index 2ccfcc1e2..3b5bcba50 100644
--- a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
+++ b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
@@ -169,7 +169,7 @@ ReadServers(NeighborExplorer::List &list, const char *uri)
 
 gcc_pure
 static NeighborExplorer::List
-DetectServers()
+DetectServers() noexcept
 {
 	NeighborExplorer::List list;
 	const std::lock_guard<Mutex> protect(smbclient_mutex);
@@ -181,7 +181,7 @@ gcc_pure
 static NeighborExplorer::List::const_iterator
 FindBeforeServerByURI(NeighborExplorer::List::const_iterator prev,
 		      NeighborExplorer::List::const_iterator end,
-		      const std::string &uri)
+		      const std::string &uri) noexcept
 {
 	for (auto i = std::next(prev); i != end; prev = i, i = std::next(prev))
 		if (i->uri == uri)
diff --git a/src/net/AllocatedSocketAddress.cxx b/src/net/AllocatedSocketAddress.cxx
index d109eac8d..92781a29b 100644
--- a/src/net/AllocatedSocketAddress.cxx
+++ b/src/net/AllocatedSocketAddress.cxx
@@ -50,7 +50,7 @@ AllocatedSocketAddress::operator=(SocketAddress src)
 }
 
 void
-AllocatedSocketAddress::SetSize(size_type new_size)
+AllocatedSocketAddress::SetSize(size_type new_size) noexcept
 {
 	if (size == new_size)
 		return;
@@ -63,7 +63,7 @@ AllocatedSocketAddress::SetSize(size_type new_size)
 #ifdef HAVE_UN
 
 void
-AllocatedSocketAddress::SetLocal(const char *path)
+AllocatedSocketAddress::SetLocal(const char *path) noexcept
 {
 	const bool is_abstract = *path == '@';
 
diff --git a/src/net/AllocatedSocketAddress.hxx b/src/net/AllocatedSocketAddress.hxx
index af015a387..15aafd7d1 100644
--- a/src/net/AllocatedSocketAddress.hxx
+++ b/src/net/AllocatedSocketAddress.hxx
@@ -140,11 +140,11 @@ public:
 	 * begins with a '@', then the rest specifies an "abstract" local
 	 * address.
 	 */
-	void SetLocal(const char *path);
+	void SetLocal(const char *path) noexcept;
 #endif
 
 private:
-	void SetSize(size_type new_size);
+	void SetSize(size_type new_size) noexcept;
 };
 
 #endif
diff --git a/src/net/SocketAddress.cxx b/src/net/SocketAddress.cxx
index 10609269c..3bbb3ac1f 100644
--- a/src/net/SocketAddress.cxx
+++ b/src/net/SocketAddress.cxx
@@ -32,7 +32,7 @@
 #include <string.h>
 
 bool
-SocketAddress::operator==(SocketAddress other) const
+SocketAddress::operator==(SocketAddress other) const noexcept
 {
 	return size == other.size && memcmp(address, other.address, size) == 0;
 }
diff --git a/src/net/SocketAddress.hxx b/src/net/SocketAddress.hxx
index 31d513609..5db6d55f9 100644
--- a/src/net/SocketAddress.hxx
+++ b/src/net/SocketAddress.hxx
@@ -93,9 +93,9 @@ public:
 	}
 
 	gcc_pure
-	bool operator==(const SocketAddress other) const;
+	bool operator==(const SocketAddress other) const noexcept;
 
-	bool operator!=(const SocketAddress other) const {
+	bool operator!=(const SocketAddress other) const noexcept {
 		return !(*this == other);
 	}
 };
diff --git a/src/net/SocketError.cxx b/src/net/SocketError.cxx
index e670a3d47..082dec187 100644
--- a/src/net/SocketError.cxx
+++ b/src/net/SocketError.cxx
@@ -25,7 +25,7 @@
 
 #ifdef WIN32
 
-SocketErrorMessage::SocketErrorMessage(socket_error_t code)
+SocketErrorMessage::SocketErrorMessage(socket_error_t code) noexcept
 {
 #ifdef _UNICODE
 	wchar_t buffer[ARRAY_SIZE(msg)];
@@ -56,7 +56,7 @@ SocketErrorMessage::SocketErrorMessage(socket_error_t code)
 
 #else
 
-SocketErrorMessage::SocketErrorMessage(socket_error_t code)
+SocketErrorMessage::SocketErrorMessage(socket_error_t code) noexcept
 	:msg(strerror(code)) {}
 
 #endif
diff --git a/src/net/SocketError.hxx b/src/net/SocketError.hxx
index a86ceb86c..6e3a7799c 100644
--- a/src/net/SocketError.hxx
+++ b/src/net/SocketError.hxx
@@ -33,7 +33,7 @@ typedef int socket_error_t;
 
 gcc_pure
 static inline socket_error_t
-GetSocketError()
+GetSocketError() noexcept
 {
 #ifdef WIN32
 	return WSAGetLastError();
@@ -44,7 +44,7 @@ GetSocketError()
 
 gcc_const
 static inline bool
-IsSocketErrorAgain(socket_error_t code)
+IsSocketErrorAgain(socket_error_t code) noexcept
 {
 #ifdef WIN32
 	return code == WSAEINPROGRESS;
@@ -55,7 +55,7 @@ IsSocketErrorAgain(socket_error_t code)
 
 gcc_const
 static inline bool
-IsSocketErrorInterruped(socket_error_t code)
+IsSocketErrorInterruped(socket_error_t code) noexcept
 {
 #ifdef WIN32
 	return code == WSAEINTR;
@@ -66,7 +66,7 @@ IsSocketErrorInterruped(socket_error_t code)
 
 gcc_const
 static inline bool
-IsSocketErrorClosed(socket_error_t code)
+IsSocketErrorClosed(socket_error_t code) noexcept
 {
 #ifdef WIN32
 	return code == WSAECONNRESET;
@@ -88,11 +88,7 @@ class SocketErrorMessage {
 #endif
 
 public:
-#ifdef WIN32
-	explicit SocketErrorMessage(socket_error_t code=GetSocketError());
-#else
-	explicit SocketErrorMessage(socket_error_t code=GetSocketError());
-#endif
+	explicit SocketErrorMessage(socket_error_t code=GetSocketError()) noexcept;
 
 	operator const char *() const {
 		return msg;
@@ -101,7 +97,7 @@ public:
 
 gcc_const
 static inline std::system_error
-MakeSocketError(socket_error_t code, const char *msg)
+MakeSocketError(socket_error_t code, const char *msg) noexcept
 {
 #ifdef WIN32
 	return MakeLastError(code, msg);
@@ -112,7 +108,7 @@ MakeSocketError(socket_error_t code, const char *msg)
 
 gcc_pure
 static inline std::system_error
-MakeSocketError(const char *msg)
+MakeSocketError(const char *msg) noexcept
 {
 	return MakeSocketError(GetSocketError(), msg);
 }
diff --git a/src/net/StaticSocketAddress.cxx b/src/net/StaticSocketAddress.cxx
index 70237fd48..35a8cd804 100644
--- a/src/net/StaticSocketAddress.cxx
+++ b/src/net/StaticSocketAddress.cxx
@@ -35,7 +35,7 @@
 #include <string.h>
 
 StaticSocketAddress &
-StaticSocketAddress::operator=(SocketAddress other)
+StaticSocketAddress::operator=(SocketAddress other) noexcept
 {
 	size = std::min(other.GetSize(), GetCapacity());
 	memcpy(&address, other.GetAddress(), size);
diff --git a/src/net/StaticSocketAddress.hxx b/src/net/StaticSocketAddress.hxx
index 620b74e1d..d2da90d2f 100644
--- a/src/net/StaticSocketAddress.hxx
+++ b/src/net/StaticSocketAddress.hxx
@@ -49,7 +49,7 @@ private:
 public:
 	StaticSocketAddress() = default;
 
-	StaticSocketAddress &operator=(SocketAddress other);
+	StaticSocketAddress &operator=(SocketAddress other) noexcept;
 
 	operator SocketAddress() const {
 		return SocketAddress(reinterpret_cast<const struct sockaddr *>(&address),
diff --git a/src/net/ToString.cxx b/src/net/ToString.cxx
index 7df2cb07a..f185a5e2e 100644
--- a/src/net/ToString.cxx
+++ b/src/net/ToString.cxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright (C) 2011-2017 Max Kellermann <max.kellermann@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -53,7 +53,7 @@
 #ifdef HAVE_UN
 
 static std::string
-LocalAddressToString(const struct sockaddr_un &s_un, size_t size)
+LocalAddressToString(const struct sockaddr_un &s_un, size_t size) noexcept
 {
 	const size_t prefix_size = (size_t)
 		((struct sockaddr_un *)nullptr)->sun_path;
@@ -83,7 +83,7 @@ LocalAddressToString(const struct sockaddr_un &s_un, size_t size)
 
 gcc_pure
 static bool
-IsV4Mapped(SocketAddress address)
+IsV4Mapped(SocketAddress address) noexcept
 {
 	if (address.GetFamily() != AF_INET6)
 		return false;
@@ -96,7 +96,7 @@ IsV4Mapped(SocketAddress address)
  * Convert "::ffff:127.0.0.1" to "127.0.0.1".
  */
 static SocketAddress
-UnmapV4(SocketAddress src, struct sockaddr_in &buffer)
+UnmapV4(SocketAddress src, struct sockaddr_in &buffer) noexcept
 {
 	assert(IsV4Mapped(src));
 
@@ -113,7 +113,7 @@ UnmapV4(SocketAddress src, struct sockaddr_in &buffer)
 #endif
 
 std::string
-ToString(SocketAddress address)
+ToString(SocketAddress address) noexcept
 {
 #ifdef HAVE_UN
 	if (address.GetFamily() == AF_UNIX)
diff --git a/src/net/ToString.hxx b/src/net/ToString.hxx
index a221c6c06..4eef8656d 100644
--- a/src/net/ToString.hxx
+++ b/src/net/ToString.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2015 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright (C) 2011-2017 Max Kellermann <max.kellermann@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,6 +43,6 @@ class SocketAddress;
  */
 gcc_pure
 std::string
-ToString(SocketAddress address);
+ToString(SocketAddress address) noexcept;
 
 #endif
diff --git a/src/output/Init.cxx b/src/output/Init.cxx
index 42af034e9..453200dc9 100644
--- a/src/output/Init.cxx
+++ b/src/output/Init.cxx
@@ -89,7 +89,7 @@ audio_output_detect()
  */
 gcc_pure
 static MixerType
-audio_output_mixer_type(const ConfigBlock &block)
+audio_output_mixer_type(const ConfigBlock &block) noexcept
 {
 	/* read the local "mixer_type" setting */
 	const char *p = block.GetBlockValue("mixer_type");
diff --git a/src/output/Internal.cxx b/src/output/Internal.cxx
index 34d963232..875de1867 100644
--- a/src/output/Internal.cxx
+++ b/src/output/Internal.cxx
@@ -21,7 +21,7 @@
 #include "Internal.hxx"
 
 bool
-AudioOutput::IsChunkConsumed(const MusicChunk &chunk) const
+AudioOutput::IsChunkConsumed(const MusicChunk &chunk) const noexcept
 {
 	if (!open)
 		return true;
diff --git a/src/output/Internal.hxx b/src/output/Internal.hxx
index 023ee1e23..75355e8b9 100644
--- a/src/output/Internal.hxx
+++ b/src/output/Internal.hxx
@@ -436,10 +436,10 @@ public:
 	 * Caller must lock the mutex.
 	 */
 	gcc_pure
-	bool IsChunkConsumed(const MusicChunk &chunk) const;
+	bool IsChunkConsumed(const MusicChunk &chunk) const noexcept;
 
 	gcc_pure
-	bool LockIsChunkConsumed(const MusicChunk &chunk) {
+	bool LockIsChunkConsumed(const MusicChunk &chunk) noexcept {
 		const std::lock_guard<Mutex> protect(mutex);
 		return IsChunkConsumed(chunk);
 	}
diff --git a/src/output/MultipleOutputs.cxx b/src/output/MultipleOutputs.cxx
index 9b1f8169c..c55c447bd 100644
--- a/src/output/MultipleOutputs.cxx
+++ b/src/output/MultipleOutputs.cxx
@@ -94,7 +94,7 @@ MultipleOutputs::Configure(EventLoop &event_loop,
 }
 
 AudioOutput *
-MultipleOutputs::FindByName(const char *name) const
+MultipleOutputs::FindByName(const char *name) const noexcept
 {
 	for (auto i : outputs)
 		if (strcmp(i->GetName(), name) == 0)
@@ -120,7 +120,7 @@ MultipleOutputs::EnableDisable()
 }
 
 bool
-MultipleOutputs::AllFinished() const
+MultipleOutputs::AllFinished() const noexcept
 {
 	for (auto ao : outputs) {
 		const std::lock_guard<Mutex> protect(ao->mutex);
@@ -132,7 +132,7 @@ MultipleOutputs::AllFinished() const
 }
 
 void
-MultipleOutputs::WaitAll()
+MultipleOutputs::WaitAll() noexcept
 {
 	while (!AllFinished())
 		audio_output_client_notify.Wait();
@@ -243,7 +243,7 @@ MultipleOutputs::Open(const AudioFormat audio_format,
 }
 
 bool
-MultipleOutputs::IsChunkConsumed(const MusicChunk *chunk) const
+MultipleOutputs::IsChunkConsumed(const MusicChunk *chunk) const noexcept
 {
 	for (auto ao : outputs)
 		if (!ao->LockIsChunkConsumed(*chunk))
diff --git a/src/output/MultipleOutputs.hxx b/src/output/MultipleOutputs.hxx
index a6366cf89..014978882 100644
--- a/src/output/MultipleOutputs.hxx
+++ b/src/output/MultipleOutputs.hxx
@@ -109,7 +109,7 @@ public:
 	 * Returns nullptr if the name does not exist.
 	 */
 	gcc_pure
-	AudioOutput *FindByName(const char *name) const;
+	AudioOutput *FindByName(const char *name) const noexcept;
 
 	/**
 	 * Checks the "enabled" flag of all audio outputs, and if one has
@@ -195,7 +195,7 @@ public:
 	 * 0..100).  Returns -1 if no mixer can be queried.
 	 */
 	gcc_pure
-	int GetVolume() const;
+	int GetVolume() const noexcept;
 
 	/**
 	 * Sets the volume on all available mixers.
@@ -203,7 +203,7 @@ public:
 	 * @param volume the volume (range 0..100)
 	 * @return true on success, false on failure
 	 */
-	bool SetVolume(unsigned volume);
+	bool SetVolume(unsigned volume) noexcept;
 
 	/**
 	 * Similar to GetVolume(), but gets the volume only for
@@ -211,7 +211,7 @@ public:
 	 * function fails if no software mixer is configured.
 	 */
 	gcc_pure
-	int GetSoftwareVolume() const;
+	int GetSoftwareVolume() const noexcept;
 
 	/**
 	 * Similar to SetVolume(), but sets the volume only for
@@ -219,7 +219,7 @@ public:
 	 * function cannot fail, because the underlying software
 	 * mixers cannot fail either.
 	 */
-	void SetSoftwareVolume(unsigned volume);
+	void SetSoftwareVolume(unsigned volume) noexcept;
 
 private:
 	/**
@@ -227,9 +227,9 @@ private:
 	 * command.
 	 */
 	gcc_pure
-	bool AllFinished() const;
+	bool AllFinished() const noexcept;
 
-	void WaitAll();
+	void WaitAll() noexcept;
 
 	/**
 	 * Signals all audio outputs which are open.
@@ -247,7 +247,7 @@ private:
 	/**
 	 * Has this chunk been consumed by all audio outputs?
 	 */
-	bool IsChunkConsumed(const MusicChunk *chunk) const;
+	bool IsChunkConsumed(const MusicChunk *chunk) const noexcept;
 
 	/**
 	 * There's only one chunk left in the pipe (#pipe), and all
diff --git a/src/output/OutputPlugin.cxx b/src/output/OutputPlugin.cxx
index 7c8d5b1f3..d0323ebaf 100644
--- a/src/output/OutputPlugin.cxx
+++ b/src/output/OutputPlugin.cxx
@@ -64,7 +64,7 @@ ao_plugin_close(AudioOutput *ao)
 }
 
 std::chrono::steady_clock::duration
-ao_plugin_delay(AudioOutput *ao)
+ao_plugin_delay(AudioOutput *ao) noexcept
 {
 	return ao->plugin.delay != nullptr
 		? ao->plugin.delay(ao)
diff --git a/src/output/OutputPlugin.hxx b/src/output/OutputPlugin.hxx
index 22c520b59..b9c003376 100644
--- a/src/output/OutputPlugin.hxx
+++ b/src/output/OutputPlugin.hxx
@@ -101,7 +101,7 @@ struct AudioOutputPlugin {
 	 *
 	 * @return the duration to wait
 	 */
-	std::chrono::steady_clock::duration (*delay)(AudioOutput *data);
+	std::chrono::steady_clock::duration (*delay)(AudioOutput *data) noexcept;
 
 	/**
 	 * Display metadata for the next chunk.  Optional method,
@@ -182,7 +182,7 @@ ao_plugin_close(AudioOutput *ao);
 
 gcc_pure
 std::chrono::steady_clock::duration
-ao_plugin_delay(AudioOutput *ao);
+ao_plugin_delay(AudioOutput *ao) noexcept;
 
 void
 ao_plugin_send_tag(AudioOutput *ao, const Tag &tag);
diff --git a/src/output/SharedPipeConsumer.cxx b/src/output/SharedPipeConsumer.cxx
index ea3944fb4..f88e242a5 100644
--- a/src/output/SharedPipeConsumer.cxx
+++ b/src/output/SharedPipeConsumer.cxx
@@ -23,7 +23,7 @@
 #include "MusicPipe.hxx"
 
 const MusicChunk *
-SharedPipeConsumer::Get()
+SharedPipeConsumer::Get() noexcept
 {
 	if (chunk != nullptr) {
 		if (!consumed)
@@ -42,7 +42,7 @@ SharedPipeConsumer::Get()
 }
 
 bool
-SharedPipeConsumer::IsConsumed(const MusicChunk &_chunk) const
+SharedPipeConsumer::IsConsumed(const MusicChunk &_chunk) const noexcept
 {
 	if (chunk == nullptr)
 		return false;
diff --git a/src/output/SharedPipeConsumer.hxx b/src/output/SharedPipeConsumer.hxx
index 84bda4513..4b9efd48f 100644
--- a/src/output/SharedPipeConsumer.hxx
+++ b/src/output/SharedPipeConsumer.hxx
@@ -75,7 +75,7 @@ public:
 		chunk = nullptr;
 	}
 
-	const MusicChunk *Get();
+	const MusicChunk *Get() noexcept;
 
 	void Consume(gcc_unused const MusicChunk &_chunk) {
 		assert(chunk != nullptr);
@@ -85,9 +85,9 @@ public:
 	}
 
 	gcc_pure
-	bool IsConsumed(const MusicChunk &_chunk) const;
+	bool IsConsumed(const MusicChunk &_chunk) const noexcept;
 
-	void ClearTail(gcc_unused const MusicChunk &_chunk) {
+	void ClearTail(gcc_unused const MusicChunk &_chunk) noexcept {
 		assert(chunk == &_chunk);
 		assert(consumed);
 		chunk = nullptr;
diff --git a/src/output/Source.cxx b/src/output/Source.cxx
index e5a67f1bd..de11595f5 100644
--- a/src/output/Source.cxx
+++ b/src/output/Source.cxx
@@ -60,7 +60,7 @@ AudioOutputSource::Open(AudioFormat audio_format, const MusicPipe &_pipe,
 }
 
 void
-AudioOutputSource::Close()
+AudioOutputSource::Close() noexcept
 {
 	assert(in_audio_format.IsValid());
 	in_audio_format.Clear();
@@ -71,7 +71,7 @@ AudioOutputSource::Close()
 }
 
 void
-AudioOutputSource::Cancel()
+AudioOutputSource::Cancel() noexcept
 {
 	current_chunk = nullptr;
 	pipe.Cancel();
@@ -114,7 +114,7 @@ try {
 }
 
 void
-AudioOutputSource::CloseFilter()
+AudioOutputSource::CloseFilter() noexcept
 {
 	delete replay_gain_filter_instance;
 	replay_gain_filter_instance = nullptr;
diff --git a/src/output/Source.hxx b/src/output/Source.hxx
index c9bbd45f6..01b44521a 100644
--- a/src/output/Source.hxx
+++ b/src/output/Source.hxx
@@ -138,8 +138,8 @@ public:
 			 PreparedFilter *prepared_other_replay_gain_filter,
 			 PreparedFilter *prepared_filter);
 
-	void Close();
-	void Cancel();
+	void Close() noexcept;
+	void Cancel() noexcept;
 
 	/**
 	 * Ensure that ReadTag() or PeekData() return any input.
@@ -181,13 +181,13 @@ public:
 	 */
 	void ConsumeData(size_t nbytes) noexcept;
 
-	bool IsChunkConsumed(const MusicChunk &chunk) const {
+	bool IsChunkConsumed(const MusicChunk &chunk) const  noexcept {
 		assert(IsOpen());
 
 		return pipe.IsConsumed(chunk);
 	}
 
-	void ClearTailChunk(const MusicChunk &chunk) {
+	void ClearTailChunk(const MusicChunk &chunk) noexcept {
 		pipe.ClearTail(chunk);
 	}
 
@@ -197,7 +197,7 @@ private:
 			PreparedFilter *prepared_other_replay_gain_filter,
 			PreparedFilter *prepared_filter);
 
-	void CloseFilter();
+	void CloseFilter() noexcept;
 
 	ConstBuffer<void> GetChunkData(const MusicChunk &chunk,
 				       Filter *replay_gain_filter,
diff --git a/src/output/Wrapper.hxx b/src/output/Wrapper.hxx
index f2d212257..55ffc91f4 100644
--- a/src/output/Wrapper.hxx
+++ b/src/output/Wrapper.hxx
@@ -63,7 +63,7 @@ struct AudioOutputWrapper {
 	}
 
 	gcc_pure
-	static std::chrono::steady_clock::duration Delay(AudioOutput *ao) {
+	static std::chrono::steady_clock::duration Delay(AudioOutput *ao) noexcept {
 		T &t = Cast(*ao);
 		return t.Delay();
 	}
diff --git a/src/output/plugins/AlsaOutputPlugin.cxx b/src/output/plugins/AlsaOutputPlugin.cxx
index b9878bfed..5361f6431 100644
--- a/src/output/plugins/AlsaOutputPlugin.cxx
+++ b/src/output/plugins/AlsaOutputPlugin.cxx
@@ -249,7 +249,7 @@ alsa_test_default_device()
  */
 gcc_const
 static snd_pcm_format_t
-ToAlsaPcmFormat(SampleFormat sample_format)
+ToAlsaPcmFormat(SampleFormat sample_format) noexcept
 {
 	switch (sample_format) {
 	case SampleFormat::UNDEFINED:
@@ -287,7 +287,7 @@ ToAlsaPcmFormat(SampleFormat sample_format)
  * SND_PCM_FORMAT_UNKNOWN if the format cannot be byte-swapped.
  */
 static snd_pcm_format_t
-ByteSwapAlsaPcmFormat(snd_pcm_format_t fmt)
+ByteSwapAlsaPcmFormat(snd_pcm_format_t fmt) noexcept
 {
 	switch (fmt) {
 	case SND_PCM_FORMAT_S16_LE: return SND_PCM_FORMAT_S16_BE;
diff --git a/src/output/plugins/FifoOutputPlugin.cxx b/src/output/plugins/FifoOutputPlugin.cxx
index 57779fa15..3942658cc 100644
--- a/src/output/plugins/FifoOutputPlugin.cxx
+++ b/src/output/plugins/FifoOutputPlugin.cxx
@@ -66,7 +66,7 @@ public:
 	void Open(AudioFormat &audio_format);
 	void Close();
 
-	std::chrono::steady_clock::duration Delay() const;
+	std::chrono::steady_clock::duration Delay() const noexcept;
 	size_t Play(const void *chunk, size_t size);
 	void Cancel();
 };
@@ -205,7 +205,7 @@ FifoOutput::Cancel()
 }
 
 inline std::chrono::steady_clock::duration
-FifoOutput::Delay() const
+FifoOutput::Delay() const noexcept
 {
 	return timer->IsStarted()
 		? timer->GetDelay()
diff --git a/src/output/plugins/JackOutputPlugin.cxx b/src/output/plugins/JackOutputPlugin.cxx
index 0ad5768d3..11a186fb7 100644
--- a/src/output/plugins/JackOutputPlugin.cxx
+++ b/src/output/plugins/JackOutputPlugin.cxx
@@ -119,7 +119,7 @@ struct JackOutput {
 	 * on all channels.
 	 */
 	gcc_pure
-	jack_nframes_t GetAvailable() const;
+	jack_nframes_t GetAvailable() const noexcept;
 
 	void Process(jack_nframes_t nframes);
 
@@ -128,7 +128,7 @@ struct JackOutput {
 	 */
 	size_t WriteSamples(const float *src, size_t n_frames);
 
-	std::chrono::steady_clock::duration Delay() const {
+	std::chrono::steady_clock::duration Delay() const noexcept {
 		return base.pause && pause && !shutdown
 			? std::chrono::seconds(1)
 			: std::chrono::steady_clock::duration::zero();
@@ -215,7 +215,7 @@ JackOutput::JackOutput(const ConfigBlock &block)
 }
 
 inline jack_nframes_t
-JackOutput::GetAvailable() const
+JackOutput::GetAvailable() const noexcept
 {
 	size_t min = jack_ringbuffer_read_space(ringbuffer[0]);
 
diff --git a/src/output/plugins/NullOutputPlugin.cxx b/src/output/plugins/NullOutputPlugin.cxx
index 5b063386d..1f2f7d1fc 100644
--- a/src/output/plugins/NullOutputPlugin.cxx
+++ b/src/output/plugins/NullOutputPlugin.cxx
@@ -49,7 +49,7 @@ public:
 			delete timer;
 	}
 
-	std::chrono::steady_clock::duration Delay() const {
+	std::chrono::steady_clock::duration Delay() const noexcept {
 		return sync && timer->IsStarted()
 			? timer->GetDelay()
 			: std::chrono::steady_clock::duration::zero();
diff --git a/src/output/plugins/OpenALOutputPlugin.cxx b/src/output/plugins/OpenALOutputPlugin.cxx
index 6b0d1bfb9..508643112 100644
--- a/src/output/plugins/OpenALOutputPlugin.cxx
+++ b/src/output/plugins/OpenALOutputPlugin.cxx
@@ -58,7 +58,7 @@ class OpenALOutput {
 	void Close();
 
 	gcc_pure
-	std::chrono::steady_clock::duration Delay() const {
+	std::chrono::steady_clock::duration Delay() const noexcept {
 		return filled < NUM_BUFFERS || HasProcessed()
 			? std::chrono::steady_clock::duration::zero()
 			/* we don't know exactly how long we must wait
diff --git a/src/output/plugins/OssOutputPlugin.cxx b/src/output/plugins/OssOutputPlugin.cxx
index d02a8263b..2401afe9d 100644
--- a/src/output/plugins/OssOutputPlugin.cxx
+++ b/src/output/plugins/OssOutputPlugin.cxx
@@ -391,7 +391,7 @@ oss_setup_sample_rate(int fd, AudioFormat &audio_format)
  */
 gcc_const
 static int
-sample_format_to_oss(SampleFormat format)
+sample_format_to_oss(SampleFormat format) noexcept
 {
 	switch (format) {
 	case SampleFormat::UNDEFINED:
@@ -430,7 +430,7 @@ sample_format_to_oss(SampleFormat format)
  */
 gcc_const
 static SampleFormat
-sample_format_from_oss(int format)
+sample_format_from_oss(int format) noexcept
 {
 	switch (format) {
 	case AFMT_S8:
diff --git a/src/output/plugins/PulseOutputPlugin.cxx b/src/output/plugins/PulseOutputPlugin.cxx
index ec3ad6f5d..6e9bc7344 100644
--- a/src/output/plugins/PulseOutputPlugin.cxx
+++ b/src/output/plugins/PulseOutputPlugin.cxx
@@ -90,7 +90,6 @@ public:
 		Signal();
 	}
 
-	gcc_const
 	static bool TestDefaultDevice();
 
 	static PulseOutput *Create(const ConfigBlock &block);
diff --git a/src/output/plugins/RoarOutputPlugin.cxx b/src/output/plugins/RoarOutputPlugin.cxx
index e774bbfe8..7a201b2ca 100644
--- a/src/output/plugins/RoarOutputPlugin.cxx
+++ b/src/output/plugins/RoarOutputPlugin.cxx
@@ -73,7 +73,7 @@ static constexpr Domain roar_output_domain("roar_output");
 
 gcc_pure
 static int
-GetConfiguredRole(const ConfigBlock &block)
+GetConfiguredRole(const ConfigBlock &block) noexcept
 {
 	const char *role = block.GetBlockValue("role");
 	return role != nullptr
diff --git a/src/output/plugins/ShoutOutputPlugin.cxx b/src/output/plugins/ShoutOutputPlugin.cxx
index 97bab04da..8e797d9bd 100644
--- a/src/output/plugins/ShoutOutputPlugin.cxx
+++ b/src/output/plugins/ShoutOutputPlugin.cxx
@@ -63,7 +63,7 @@ struct ShoutOutput final {
 	void Open(AudioFormat &audio_format);
 	void Close();
 
-	std::chrono::steady_clock::duration Delay() const;
+	std::chrono::steady_clock::duration Delay() const noexcept;
 	void SendTag(const Tag &tag);
 	size_t Play(const void *chunk, size_t size);
 	void Cancel();
@@ -361,7 +361,7 @@ ShoutOutput::Open(AudioFormat &audio_format)
 }
 
 std::chrono::steady_clock::duration
-ShoutOutput::Delay() const
+ShoutOutput::Delay() const noexcept
 {
 	int delay = shout_delay(shout_conn);
 	if (delay < 0)
diff --git a/src/output/plugins/httpd/HttpdClient.cxx b/src/output/plugins/httpd/HttpdClient.cxx
index 386944eb3..d5a423d7d 100644
--- a/src/output/plugins/httpd/HttpdClient.cxx
+++ b/src/output/plugins/httpd/HttpdClient.cxx
@@ -260,7 +260,7 @@ HttpdClient::TryWritePageN(const Page &page, size_t position, ssize_t n)
 }
 
 ssize_t
-HttpdClient::GetBytesTillMetaData() const
+HttpdClient::GetBytesTillMetaData() const noexcept
 {
 	if (metadata_requested &&
 	    current_page->size - current_position > metaint - metadata_fill)
diff --git a/src/output/plugins/httpd/HttpdClient.hxx b/src/output/plugins/httpd/HttpdClient.hxx
index 8e822184f..3cc337e94 100644
--- a/src/output/plugins/httpd/HttpdClient.hxx
+++ b/src/output/plugins/httpd/HttpdClient.hxx
@@ -168,7 +168,7 @@ public:
 	bool SendResponse();
 
 	gcc_pure
-	ssize_t GetBytesTillMetaData() const;
+	ssize_t GetBytesTillMetaData() const noexcept;
 
 	ssize_t TryWritePage(const Page &page, size_t position);
 	ssize_t TryWritePageN(const Page &page, size_t position, ssize_t n);
diff --git a/src/output/plugins/httpd/HttpdInternal.hxx b/src/output/plugins/httpd/HttpdInternal.hxx
index f42ebb8af..331e83fc1 100644
--- a/src/output/plugins/httpd/HttpdInternal.hxx
+++ b/src/output/plugins/httpd/HttpdInternal.hxx
@@ -218,7 +218,7 @@ public:
 	void SendHeader(HttpdClient &client) const;
 
 	gcc_pure
-	std::chrono::steady_clock::duration Delay() const;
+	std::chrono::steady_clock::duration Delay() const noexcept;
 
 	/**
 	 * Reads data from the encoder (as much as available) and
diff --git a/src/output/plugins/httpd/HttpdOutputPlugin.cxx b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
index d8ca25d5e..966669b1e 100644
--- a/src/output/plugins/httpd/HttpdOutputPlugin.cxx
+++ b/src/output/plugins/httpd/HttpdOutputPlugin.cxx
@@ -345,7 +345,7 @@ HttpdOutput::SendHeader(HttpdClient &client) const
 }
 
 inline std::chrono::steady_clock::duration
-HttpdOutput::Delay() const
+HttpdOutput::Delay() const noexcept
 {
 	if (!LockHasClients() && base.pause) {
 		/* if there's no client and this output is paused,
@@ -366,7 +366,7 @@ HttpdOutput::Delay() const
 }
 
 static std::chrono::steady_clock::duration
-httpd_output_delay(AudioOutput *ao)
+httpd_output_delay(AudioOutput *ao) noexcept
 {
 	HttpdOutput *httpd = HttpdOutput::Cast(ao);
 
diff --git a/src/pcm/ChannelsConverter.cxx b/src/pcm/ChannelsConverter.cxx
index 0d446ffcb..c03c3e7ed 100644
--- a/src/pcm/ChannelsConverter.cxx
+++ b/src/pcm/ChannelsConverter.cxx
@@ -57,7 +57,7 @@ PcmChannelsConverter::Close()
 }
 
 ConstBuffer<void>
-PcmChannelsConverter::Convert(ConstBuffer<void> src)
+PcmChannelsConverter::Convert(ConstBuffer<void> src) noexcept
 {
 	switch (format) {
 	case SampleFormat::UNDEFINED:
diff --git a/src/pcm/ChannelsConverter.hxx b/src/pcm/ChannelsConverter.hxx
index 4cba279af..b14958ea1 100644
--- a/src/pcm/ChannelsConverter.hxx
+++ b/src/pcm/ChannelsConverter.hxx
@@ -75,7 +75,7 @@ public:
 	 * @return the destination buffer
 	 */
 	gcc_pure
-	ConstBuffer<void> Convert(ConstBuffer<void> src);
+	ConstBuffer<void> Convert(ConstBuffer<void> src) noexcept;
 };
 
 #endif
diff --git a/src/pcm/FloatConvert.hxx b/src/pcm/FloatConvert.hxx
index c32d2b32d..8022fd378 100644
--- a/src/pcm/FloatConvert.hxx
+++ b/src/pcm/FloatConvert.hxx
@@ -37,7 +37,7 @@ struct FloatToIntegerSampleConvert {
 	static constexpr SV factor = 1 << (DstTraits::BITS - 1);
 
 	gcc_const
-	static DV Convert(SV src) {
+	static DV Convert(SV src) noexcept {
 		return PcmClamp<F, Traits>(SL(src * factor));
 	}
 };
@@ -56,7 +56,7 @@ struct IntegerToFloatSampleConvert {
 	static constexpr DV factor = 0.5 / (1 << (SrcTraits::BITS - 2));
 
 	gcc_const
-	static DV Convert(SV src) {
+	static DV Convert(SV src) noexcept {
 		return DV(src) * factor;
 	}
 };
diff --git a/src/pcm/FormatConverter.cxx b/src/pcm/FormatConverter.cxx
index 21fe0b16a..89367e71a 100644
--- a/src/pcm/FormatConverter.cxx
+++ b/src/pcm/FormatConverter.cxx
@@ -54,7 +54,7 @@ PcmFormatConverter::Open(SampleFormat _src_format, SampleFormat _dest_format)
 }
 
 void
-PcmFormatConverter::Close()
+PcmFormatConverter::Close() noexcept
 {
 #ifndef NDEBUG
 	src_format = SampleFormat::UNDEFINED;
@@ -63,7 +63,7 @@ PcmFormatConverter::Close()
 }
 
 ConstBuffer<void>
-PcmFormatConverter::Convert(ConstBuffer<void> src)
+PcmFormatConverter::Convert(ConstBuffer<void> src) noexcept
 {
 	switch (dest_format) {
 	case SampleFormat::UNDEFINED:
diff --git a/src/pcm/FormatConverter.hxx b/src/pcm/FormatConverter.hxx
index e0381bf39..082dd4f1c 100644
--- a/src/pcm/FormatConverter.hxx
+++ b/src/pcm/FormatConverter.hxx
@@ -65,18 +65,16 @@ public:
 	/**
 	 * Closes the object.  After that, you may call Open() again.
 	 */
-	void Close();
+	void Close() noexcept;
 
 	/**
 	 * Convert a block of PCM data.
 	 *
-	 * Throws std::runtime_error on error.
-	 *
 	 * @param src the input buffer
 	 * @return the destination buffer
 	 */
 	gcc_pure
-	ConstBuffer<void> Convert(ConstBuffer<void> src);
+	ConstBuffer<void> Convert(ConstBuffer<void> src) noexcept;
 };
 
 #endif
diff --git a/src/pcm/PcmExport.cxx b/src/pcm/PcmExport.cxx
index fce50a4f3..1054dba4c 100644
--- a/src/pcm/PcmExport.cxx
+++ b/src/pcm/PcmExport.cxx
@@ -84,7 +84,7 @@ PcmExport::Open(SampleFormat sample_format, unsigned _channels,
 }
 
 size_t
-PcmExport::GetFrameSize(const AudioFormat &audio_format) const
+PcmExport::GetFrameSize(const AudioFormat &audio_format) const noexcept
 {
 	if (pack24)
 		/* packed 24 bit samples (3 bytes per sample) */
@@ -109,7 +109,7 @@ PcmExport::GetFrameSize(const AudioFormat &audio_format) const
 }
 
 unsigned
-PcmExport::Params::CalcOutputSampleRate(unsigned sample_rate) const
+PcmExport::Params::CalcOutputSampleRate(unsigned sample_rate) const noexcept
 {
 #ifdef ENABLE_DSD
 	if (dsd_u16)
@@ -132,7 +132,7 @@ PcmExport::Params::CalcOutputSampleRate(unsigned sample_rate) const
 }
 
 unsigned
-PcmExport::Params::CalcInputSampleRate(unsigned sample_rate) const
+PcmExport::Params::CalcInputSampleRate(unsigned sample_rate) const noexcept
 {
 #ifdef ENABLE_DSD
 	if (dsd_u16)
@@ -209,7 +209,7 @@ PcmExport::Export(ConstBuffer<void> data)
 }
 
 size_t
-PcmExport::CalcSourceSize(size_t size) const
+PcmExport::CalcSourceSize(size_t size) const noexcept
 {
 	if (pack24)
 		/* 32 bit to 24 bit conversion (4 to 3 bytes) */
diff --git a/src/pcm/PcmExport.hxx b/src/pcm/PcmExport.hxx
index 1639520d8..706a1131a 100644
--- a/src/pcm/PcmExport.hxx
+++ b/src/pcm/PcmExport.hxx
@@ -135,13 +135,13 @@ public:
 		 * one output word (32 bits), dividing the sample rate by 4.
 		 */
 		gcc_pure
-		unsigned CalcOutputSampleRate(unsigned input_sample_rate) const;
+		unsigned CalcOutputSampleRate(unsigned input_sample_rate) const noexcept;
 
 		/**
 		 * The inverse of CalcOutputSampleRate().
 		 */
 		gcc_pure
-		unsigned CalcInputSampleRate(unsigned output_sample_rate) const;
+		unsigned CalcInputSampleRate(unsigned output_sample_rate) const noexcept;
 	};
 
 	/**
@@ -167,7 +167,7 @@ public:
 	 * Calculate the size of one output frame.
 	 */
 	gcc_pure
-	size_t GetFrameSize(const AudioFormat &audio_format) const;
+	size_t GetFrameSize(const AudioFormat &audio_format) const noexcept;
 
 	/**
 	 * Export a PCM buffer.
@@ -183,7 +183,7 @@ public:
 	 * pcm_export() source buffer.
 	 */
 	gcc_pure
-	size_t CalcSourceSize(size_t dest_size) const;
+	size_t CalcSourceSize(size_t dest_size) const noexcept;
 };
 
 #endif
diff --git a/src/pcm/PcmFormat.cxx b/src/pcm/PcmFormat.cxx
index 76a639cd4..54608d917 100644
--- a/src/pcm/PcmFormat.cxx
+++ b/src/pcm/PcmFormat.cxx
@@ -161,7 +161,7 @@ pcm_allocate_float_to_16(PcmBuffer &buffer, ConstBuffer<float> src)
 
 ConstBuffer<int16_t>
 pcm_convert_to_16(PcmBuffer &buffer, PcmDither &dither,
-		  SampleFormat src_format, ConstBuffer<void> src)
+		  SampleFormat src_format, ConstBuffer<void> src) noexcept
 {
 	switch (src_format) {
 	case SampleFormat::UNDEFINED:
@@ -229,7 +229,7 @@ pcm_allocate_float_to_24(PcmBuffer &buffer, ConstBuffer<float> src)
 
 ConstBuffer<int32_t>
 pcm_convert_to_24(PcmBuffer &buffer,
-		  SampleFormat src_format, ConstBuffer<void> src)
+		  SampleFormat src_format, ConstBuffer<void> src) noexcept
 {
 	switch (src_format) {
 	case SampleFormat::UNDEFINED:
@@ -297,7 +297,7 @@ pcm_allocate_float_to_32(PcmBuffer &buffer, ConstBuffer<float> src)
 
 ConstBuffer<int32_t>
 pcm_convert_to_32(PcmBuffer &buffer,
-		  SampleFormat src_format, ConstBuffer<void> src)
+		  SampleFormat src_format, ConstBuffer<void> src) noexcept
 {
 	switch (src_format) {
 	case SampleFormat::UNDEFINED:
@@ -365,7 +365,7 @@ pcm_allocate_32_to_float(PcmBuffer &buffer, ConstBuffer<int32_t> src)
 
 ConstBuffer<float>
 pcm_convert_to_float(PcmBuffer &buffer,
-		     SampleFormat src_format, ConstBuffer<void> src)
+		     SampleFormat src_format, ConstBuffer<void> src) noexcept
 {
 	switch (src_format) {
 	case SampleFormat::UNDEFINED:
diff --git a/src/pcm/PcmFormat.hxx b/src/pcm/PcmFormat.hxx
index 9faa1a003..2c33a829a 100644
--- a/src/pcm/PcmFormat.hxx
+++ b/src/pcm/PcmFormat.hxx
@@ -40,7 +40,7 @@ class PcmDither;
 gcc_pure
 ConstBuffer<int16_t>
 pcm_convert_to_16(PcmBuffer &buffer, PcmDither &dither,
-		  SampleFormat src_format, ConstBuffer<void> src);
+		  SampleFormat src_format, ConstBuffer<void> src) noexcept;
 
 /**
  * Converts PCM samples to 24 bit (32 bit alignment).
@@ -52,7 +52,7 @@ pcm_convert_to_16(PcmBuffer &buffer, PcmDither &dither,
 gcc_pure
 ConstBuffer<int32_t>
 pcm_convert_to_24(PcmBuffer &buffer,
-		  SampleFormat src_format, ConstBuffer<void> src);
+		  SampleFormat src_format, ConstBuffer<void> src) noexcept;
 
 /**
  * Converts PCM samples to 32 bit.
@@ -64,7 +64,7 @@ pcm_convert_to_24(PcmBuffer &buffer,
 gcc_pure
 ConstBuffer<int32_t>
 pcm_convert_to_32(PcmBuffer &buffer,
-		  SampleFormat src_format, ConstBuffer<void> src);
+		  SampleFormat src_format, ConstBuffer<void> src) noexcept;
 
 /**
  * Converts PCM samples to 32 bit floating point.
@@ -76,6 +76,6 @@ pcm_convert_to_32(PcmBuffer &buffer,
 gcc_pure
 ConstBuffer<float>
 pcm_convert_to_float(PcmBuffer &buffer,
-		     SampleFormat src_format, ConstBuffer<void> src);
+		     SampleFormat src_format, ConstBuffer<void> src) noexcept;
 
 #endif
diff --git a/src/pcm/PcmUtils.hxx b/src/pcm/PcmUtils.hxx
index 556762748..b3bc058fa 100644
--- a/src/pcm/PcmUtils.hxx
+++ b/src/pcm/PcmUtils.hxx
@@ -36,7 +36,7 @@ template<SampleFormat F> struct SampleTraits;
 template<SampleFormat F, class Traits=SampleTraits<F>>
 gcc_const
 static inline typename Traits::value_type
-PcmClamp(typename Traits::long_type x)
+PcmClamp(typename Traits::long_type x) noexcept
 {
 	typedef typename Traits::value_type T;
 
diff --git a/src/pcm/SampleFormat.cxx b/src/pcm/SampleFormat.cxx
index 5d477115a..20a7c8c4a 100644
--- a/src/pcm/SampleFormat.cxx
+++ b/src/pcm/SampleFormat.cxx
@@ -22,7 +22,7 @@
 #include <assert.h>
 
 const char *
-sample_format_to_string(SampleFormat format)
+sample_format_to_string(SampleFormat format) noexcept
 {
 	switch (format) {
 	case SampleFormat::UNDEFINED:
diff --git a/src/pcm/SampleFormat.hxx b/src/pcm/SampleFormat.hxx
index 9ac2c8dab..febb89ff5 100644
--- a/src/pcm/SampleFormat.hxx
+++ b/src/pcm/SampleFormat.hxx
@@ -124,6 +124,6 @@ sample_format_size(SampleFormat format)
  */
 gcc_pure gcc_malloc
 const char *
-sample_format_to_string(SampleFormat format);
+sample_format_to_string(SampleFormat format) noexcept;
 
 #endif
diff --git a/src/pcm/SoxrResampler.cxx b/src/pcm/SoxrResampler.cxx
index 67d9f9950..621d3f970 100644
--- a/src/pcm/SoxrResampler.cxx
+++ b/src/pcm/SoxrResampler.cxx
@@ -56,7 +56,7 @@ static constexpr struct {
 
 gcc_const
 static const char *
-soxr_quality_name(unsigned long recipe)
+soxr_quality_name(unsigned long recipe) noexcept
 {
 	for (const auto *i = soxr_quality_table;; ++i) {
 		assert(i->name != nullptr);
@@ -68,7 +68,7 @@ soxr_quality_name(unsigned long recipe)
 
 gcc_pure
 static unsigned long
-soxr_parse_quality(const char *quality)
+soxr_parse_quality(const char *quality) noexcept
 {
 	if (quality == nullptr)
 		return SOXR_DEFAULT_RECIPE;
diff --git a/src/pcm/Volume.cxx b/src/pcm/Volume.cxx
index 761fd048d..97356e4d1 100644
--- a/src/pcm/Volume.cxx
+++ b/src/pcm/Volume.cxx
@@ -123,7 +123,7 @@ PcmVolume::Open(SampleFormat _format)
 }
 
 ConstBuffer<void>
-PcmVolume::Apply(ConstBuffer<void> src)
+PcmVolume::Apply(ConstBuffer<void> src) noexcept
 {
 	if (volume == PCM_VOLUME_1)
 		return src;
diff --git a/src/pcm/Volume.hxx b/src/pcm/Volume.hxx
index fde00b0f4..6a1ffde83 100644
--- a/src/pcm/Volume.hxx
+++ b/src/pcm/Volume.hxx
@@ -112,7 +112,7 @@ public:
 	 * Apply the volume level.
 	 */
 	gcc_pure
-	ConstBuffer<void> Apply(ConstBuffer<void> src);
+	ConstBuffer<void> Apply(ConstBuffer<void> src) noexcept;
 };
 
 #endif
diff --git a/src/player/Control.cxx b/src/player/Control.cxx
index 2b70b2a41..b6c3688f4 100644
--- a/src/player/Control.cxx
+++ b/src/player/Control.cxx
@@ -151,7 +151,7 @@ PlayerControl::LockSetBorderPause(bool _border_pause)
 }
 
 player_status
-PlayerControl::LockGetStatus()
+PlayerControl::LockGetStatus() noexcept
 {
 	player_status status;
 
diff --git a/src/player/Control.hxx b/src/player/Control.hxx
index 7bb8b7c79..e5023f0a9 100644
--- a/src/player/Control.hxx
+++ b/src/player/Control.hxx
@@ -317,7 +317,7 @@ private:
 	 * To be called from the main thread.  Caller must lock the
 	 * object.
 	 */
-	void SynchronousCommand(PlayerCommand cmd) {
+	void SynchronousCommand(PlayerCommand cmd) noexcept {
 		assert(command == PlayerCommand::NONE);
 
 		command = cmd;
@@ -332,7 +332,7 @@ private:
 	 * To be called from the main thread.  This method locks the
 	 * object.
 	 */
-	void LockSynchronousCommand(PlayerCommand cmd) {
+	void LockSynchronousCommand(PlayerCommand cmd) noexcept {
 		const std::lock_guard<Mutex> protect(mutex);
 		SynchronousCommand(cmd);
 	}
@@ -383,7 +383,7 @@ public:
 	void Kill();
 
 	gcc_pure
-	player_status LockGetStatus();
+	player_status LockGetStatus() noexcept;
 
 	PlayerState GetState() const {
 		return state;
diff --git a/src/player/CrossFade.cxx b/src/player/CrossFade.cxx
index 872fd3ab0..3db5932c0 100644
--- a/src/player/CrossFade.cxx
+++ b/src/player/CrossFade.cxx
@@ -32,7 +32,7 @@ static constexpr Domain cross_fade_domain("cross_fade");
 
 gcc_pure
 static float
-mixramp_interpolate(const char *ramp_list, float required_db)
+mixramp_interpolate(const char *ramp_list, float required_db) noexcept
 {
 	float last_db = 0, last_secs = 0;
 	bool have_last = false;
@@ -91,7 +91,7 @@ CrossFadeSettings::Calculate(SignedSongTime total_time,
 			     const char *mixramp_start, const char *mixramp_prev_end,
 			     const AudioFormat af,
 			     const AudioFormat old_format,
-			     unsigned max_chunks) const
+			     unsigned max_chunks) const noexcept
 {
 	unsigned int chunks = 0;
 	float chunks_f;
diff --git a/src/player/CrossFade.hxx b/src/player/CrossFade.hxx
index a1949c9f1..9241006d8 100644
--- a/src/player/CrossFade.hxx
+++ b/src/player/CrossFade.hxx
@@ -66,7 +66,7 @@ struct CrossFadeSettings {
 			   const char *mixramp_start,
 			   const char *mixramp_prev_end,
 			   AudioFormat af, AudioFormat old_format,
-			   unsigned max_chunks) const;
+			   unsigned max_chunks) const noexcept;
 };
 
 #endif
diff --git a/src/playlist/cue/CueParser.cxx b/src/playlist/cue/CueParser.cxx
index 4e511be85..acdd55483 100644
--- a/src/playlist/cue/CueParser.cxx
+++ b/src/playlist/cue/CueParser.cxx
@@ -107,7 +107,7 @@ cue_parse_rem(char *p, TagBuilder &tag)
 }
 
 TagBuilder *
-CueParser::GetCurrentTag()
+CueParser::GetCurrentTag() noexcept
 {
 	if (state == HEADER)
 		return &header_tag;
@@ -139,7 +139,7 @@ cue_parse_position(const char *p)
 }
 
 void
-CueParser::Commit()
+CueParser::Commit() noexcept
 {
 	/* the caller of this library must call cue_parser_get() often
 	   enough */
@@ -158,7 +158,7 @@ CueParser::Commit()
 }
 
 void
-CueParser::Feed2(char *p)
+CueParser::Feed2(char *p) noexcept
 {
 	assert(!end);
 	assert(p != nullptr);
@@ -260,7 +260,7 @@ CueParser::Feed2(char *p)
 }
 
 void
-CueParser::Feed(const char *line)
+CueParser::Feed(const char *line) noexcept
 {
 	assert(!end);
 	assert(line != nullptr);
@@ -271,7 +271,7 @@ CueParser::Feed(const char *line)
 }
 
 void
-CueParser::Finish()
+CueParser::Finish() noexcept
 {
 	if (end)
 		/* has already been called, ignore */
@@ -282,7 +282,7 @@ CueParser::Finish()
 }
 
 std::unique_ptr<DetachedSong>
-CueParser::Get()
+CueParser::Get() noexcept
 {
 	if (finished == nullptr && end) {
 		/* cue_parser_finish() has been called already:
diff --git a/src/playlist/cue/CueParser.hxx b/src/playlist/cue/CueParser.hxx
index 6f6061a59..6c84ddd4f 100644
--- a/src/playlist/cue/CueParser.hxx
+++ b/src/playlist/cue/CueParser.hxx
@@ -98,14 +98,14 @@ public:
 	 * Feed a text line from the CUE file into the parser.  Call
 	 * Get() after this to see if a song has been finished.
 	 */
-	void Feed(const char *line);
+	void Feed(const char *line) noexcept;
 
 	/**
 	 * Tell the parser that the end of the file has been reached.  Call
 	 * Get() after this to see if a song has been finished.
 	 * This procedure must be done twice!
 	 */
-	void Finish();
+	void Finish() noexcept;
 
 	/**
 	 * Check if a song was finished by the last Feed() or Finish()
@@ -114,20 +114,20 @@ public:
 	 * @return a song object that must be freed by the caller, or NULL if
 	 * no song was finished at this time
 	 */
-	std::unique_ptr<DetachedSong> Get();
+	std::unique_ptr<DetachedSong> Get() noexcept;
 
 private:
 	gcc_pure
-	TagBuilder *GetCurrentTag();
+	TagBuilder *GetCurrentTag() noexcept;
 
 	/**
 	 * Commit the current song.  It will be moved to "previous",
 	 * so the next song may soon edit its end time (using the next
 	 * song's start time).
 	 */
-	void Commit();
+	void Commit() noexcept;
 
-	void Feed2(char *p);
+	void Feed2(char *p) noexcept;
 };
 
 #endif
diff --git a/src/queue/Playlist.cxx b/src/queue/Playlist.cxx
index 2249dc8f3..667e3457f 100644
--- a/src/queue/Playlist.cxx
+++ b/src/queue/Playlist.cxx
@@ -92,7 +92,7 @@ playlist::QueuedSongStarted(PlayerControl &pc)
 }
 
 const DetachedSong *
-playlist::GetQueuedSong() const
+playlist::GetQueuedSong() const noexcept
 {
 	return playing && queued >= 0
 		? &queue.GetOrder(queued)
@@ -323,7 +323,7 @@ playlist::SetRandom(PlayerControl &pc, bool status)
 }
 
 int
-playlist::GetCurrentPosition() const
+playlist::GetCurrentPosition() const noexcept
 {
 	return current >= 0
 		? queue.OrderToPosition(current)
@@ -331,7 +331,7 @@ playlist::GetCurrentPosition() const
 }
 
 int
-playlist::GetNextPosition() const
+playlist::GetNextPosition() const noexcept
 {
 	if (current < 0)
 		return -1;
diff --git a/src/queue/Playlist.hxx b/src/queue/Playlist.hxx
index f66b1f2e7..32489e354 100644
--- a/src/queue/Playlist.hxx
+++ b/src/queue/Playlist.hxx
@@ -113,17 +113,17 @@ struct playlist {
 	}
 
 	gcc_pure
-	int GetCurrentPosition() const;
+	int GetCurrentPosition() const noexcept;
 
 	gcc_pure
-	int GetNextPosition() const;
+	int GetNextPosition() const noexcept;
 
 	/**
 	 * Returns the song object which is currently queued.  Returns
 	 * none if there is none (yet?) or if MPD isn't playing.
 	 */
 	gcc_pure
-	const DetachedSong *GetQueuedSong() const;
+	const DetachedSong *GetQueuedSong() const noexcept;
 
 	/**
 	 * This is the "PLAYLIST" event handler.  It is invoked by the
diff --git a/src/queue/Queue.cxx b/src/queue/Queue.cxx
index 6f6a9c8f7..d248f306b 100644
--- a/src/queue/Queue.cxx
+++ b/src/queue/Queue.cxx
@@ -43,7 +43,7 @@ Queue::~Queue()
 }
 
 int
-Queue::GetNextOrder(unsigned _order) const
+Queue::GetNextOrder(unsigned _order) const noexcept
 {
 	assert(_order < length);
 
@@ -60,7 +60,7 @@ Queue::GetNextOrder(unsigned _order) const
 }
 
 void
-Queue::IncrementVersion()
+Queue::IncrementVersion() noexcept
 {
 	static unsigned long max = ((uint32_t) 1 << 31) - 1;
 
@@ -75,7 +75,7 @@ Queue::IncrementVersion()
 }
 
 void
-Queue::ModifyAtOrder(unsigned _order)
+Queue::ModifyAtOrder(unsigned _order) noexcept
 {
 	assert(_order < length);
 
@@ -103,7 +103,7 @@ Queue::Append(DetachedSong &&song, uint8_t priority)
 }
 
 void
-Queue::SwapPositions(unsigned position1, unsigned position2)
+Queue::SwapPositions(unsigned position1, unsigned position2) noexcept
 {
 	unsigned id1 = items[position1].id;
 	unsigned id2 = items[position2].id;
@@ -118,7 +118,7 @@ Queue::SwapPositions(unsigned position1, unsigned position2)
 }
 
 void
-Queue::MovePostion(unsigned from, unsigned to)
+Queue::MovePostion(unsigned from, unsigned to) noexcept
 {
 	const Item tmp = items[from];
 
@@ -154,7 +154,7 @@ Queue::MovePostion(unsigned from, unsigned to)
 }
 
 void
-Queue::MoveRange(unsigned start, unsigned end, unsigned to)
+Queue::MoveRange(unsigned start, unsigned end, unsigned to) noexcept
 {
 	Item tmp[end - start];
 	// Copy the original block [start,end-1]
@@ -196,7 +196,7 @@ Queue::MoveRange(unsigned start, unsigned end, unsigned to)
 }
 
 void
-Queue::MoveOrder(unsigned from_order, unsigned to_order)
+Queue::MoveOrder(unsigned from_order, unsigned to_order) noexcept
 {
 	assert(from_order < length);
 	assert(to_order <= length);
@@ -215,7 +215,7 @@ Queue::MoveOrder(unsigned from_order, unsigned to_order)
 }
 
 void
-Queue::DeletePosition(unsigned position)
+Queue::DeletePosition(unsigned position) noexcept
 {
 	assert(position < length);
 
@@ -248,7 +248,7 @@ Queue::DeletePosition(unsigned position)
 }
 
 void
-Queue::Clear()
+Queue::Clear() noexcept
 {
 	for (unsigned i = 0; i < length; i++) {
 		Item *item = &items[i];
@@ -262,7 +262,8 @@ Queue::Clear()
 }
 
 static void
-queue_sort_order_by_priority(Queue *queue, unsigned start, unsigned end)
+queue_sort_order_by_priority(Queue *queue,
+			     unsigned start, unsigned end) noexcept
 {
 	assert(queue != nullptr);
 	assert(queue->random);
@@ -370,7 +371,7 @@ Queue::ShuffleRange(unsigned start, unsigned end)
 
 unsigned
 Queue::FindPriorityOrder(unsigned start_order, uint8_t priority,
-			 unsigned exclude_order) const
+			 unsigned exclude_order) const noexcept
 {
 	assert(random);
 	assert(start_order <= length);
@@ -386,7 +387,7 @@ Queue::FindPriorityOrder(unsigned start_order, uint8_t priority,
 }
 
 unsigned
-Queue::CountSamePriority(unsigned start_order, uint8_t priority) const
+Queue::CountSamePriority(unsigned start_order, uint8_t priority) const noexcept
 {
 	assert(random);
 	assert(start_order <= length);
diff --git a/src/queue/Queue.hxx b/src/queue/Queue.hxx
index 7ca29bfca..805c2f4de 100644
--- a/src/queue/Queue.hxx
+++ b/src/queue/Queue.hxx
@@ -232,13 +232,13 @@ struct Queue {
 	 * @return the next order number, or -1 to stop playback
 	 */
 	gcc_pure
-	int GetNextOrder(unsigned order) const;
+	int GetNextOrder(unsigned order) const noexcept;
 
 	/**
 	 * Increments the queue's version number.  This handles integer
 	 * overflow well.
 	 */
-	void IncrementVersion();
+	void IncrementVersion() noexcept;
 
 	/**
 	 * Marks the specified song as "modified".  Call
@@ -256,7 +256,7 @@ struct Queue {
 	 * IncrementVersion() after all modifications have been made.
 	 * number.
 	 */
-	void ModifyAtOrder(unsigned order);
+	void ModifyAtOrder(unsigned order) noexcept;
 
 	/**
 	 * Appends a song to the queue and returns its position.  Prior to
@@ -273,7 +273,7 @@ struct Queue {
 	/**
 	 * Swaps two songs, addressed by their position.
 	 */
-	void SwapPositions(unsigned position1, unsigned position2);
+	void SwapPositions(unsigned position1, unsigned position2) noexcept;
 
 	/**
 	 * Swaps two songs, addressed by their order number.
@@ -285,27 +285,27 @@ struct Queue {
 	/**
 	 * Moves a song to a new position in the "order" list.
 	 */
-	void MoveOrder(unsigned from_order, unsigned to_order);
+	void MoveOrder(unsigned from_order, unsigned to_order) noexcept;
 
 	/**
 	 * Moves a song to a new position.
 	 */
-	void MovePostion(unsigned from, unsigned to);
+	void MovePostion(unsigned from, unsigned to) noexcept;
 
 	/**
 	 * Moves a range of songs to a new position.
 	 */
-	void MoveRange(unsigned start, unsigned end, unsigned to);
+	void MoveRange(unsigned start, unsigned end, unsigned to) noexcept;
 
 	/**
 	 * Removes a song from the playlist.
 	 */
-	void DeletePosition(unsigned position);
+	void DeletePosition(unsigned position) noexcept;
 
 	/**
 	 * Removes all songs from the playlist.
 	 */
-	void Clear();
+	void Clear() noexcept;
 
 	/**
 	 * Initializes the "order" array, and restores "normal" order.
@@ -369,11 +369,11 @@ private:
 	 */
 	gcc_pure
 	unsigned FindPriorityOrder(unsigned start_order, uint8_t priority,
-				   unsigned exclude_order) const;
+				   unsigned exclude_order) const noexcept;
 
 	gcc_pure
 	unsigned CountSamePriority(unsigned start_order,
-				   uint8_t priority) const;
+				   uint8_t priority) const noexcept;
 };
 
 #endif
diff --git a/src/sticker/StickerDatabase.cxx b/src/sticker/StickerDatabase.cxx
index b8ec42ead..d51b6bf96 100644
--- a/src/sticker/StickerDatabase.cxx
+++ b/src/sticker/StickerDatabase.cxx
@@ -151,7 +151,7 @@ sticker_global_finish()
 }
 
 bool
-sticker_enabled()
+sticker_enabled() noexcept
 {
 	return sticker_db != nullptr;
 }
@@ -328,7 +328,7 @@ sticker_free(Sticker *sticker)
 }
 
 const char *
-sticker_get_value(const Sticker &sticker, const char *name)
+sticker_get_value(const Sticker &sticker, const char *name) noexcept
 {
 	auto i = sticker.table.find(name);
 	if (i == sticker.table.end())
diff --git a/src/sticker/StickerDatabase.hxx b/src/sticker/StickerDatabase.hxx
index ec929af11..e533fbfbe 100644
--- a/src/sticker/StickerDatabase.hxx
+++ b/src/sticker/StickerDatabase.hxx
@@ -69,7 +69,7 @@ sticker_global_finish();
  */
 gcc_const
 bool
-sticker_enabled();
+sticker_enabled() noexcept;
 
 /**
  * Returns one value from an object's sticker record.  Returns an
@@ -125,7 +125,7 @@ sticker_free(Sticker *sticker);
  */
 gcc_pure
 const char *
-sticker_get_value(const Sticker &sticker, const char *name);
+sticker_get_value(const Sticker &sticker, const char *name) noexcept;
 
 /**
  * Iterates over all sticker items in a sticker.
diff --git a/src/storage/CompositeStorage.cxx b/src/storage/CompositeStorage.cxx
index fce464db9..cd3a702bf 100644
--- a/src/storage/CompositeStorage.cxx
+++ b/src/storage/CompositeStorage.cxx
@@ -114,7 +114,7 @@ CompositeStorage::Directory::~Directory()
 }
 
 const CompositeStorage::Directory *
-CompositeStorage::Directory::Find(const char *uri) const
+CompositeStorage::Directory::Find(const char *uri) const noexcept
 {
 	const Directory *directory = this;
 	while (*uri != 0) {
@@ -180,7 +180,7 @@ CompositeStorage::Directory::Unmount(const char *uri)
 
 bool
 CompositeStorage::Directory::MapToRelativeUTF8(std::string &buffer,
-					       const char *uri) const
+					       const char *uri) const noexcept
 {
 	if (storage != nullptr) {
 		const char *result = storage->MapToRelativeUTF8(uri);
@@ -202,7 +202,7 @@ CompositeStorage::Directory::MapToRelativeUTF8(std::string &buffer,
 	return false;
 }
 
-CompositeStorage::CompositeStorage()
+CompositeStorage::CompositeStorage() noexcept
 {
 }
 
@@ -211,7 +211,7 @@ CompositeStorage::~CompositeStorage()
 }
 
 Storage *
-CompositeStorage::GetMount(const char *uri)
+CompositeStorage::GetMount(const char *uri) noexcept
 {
 	const std::lock_guard<Mutex> protect(mutex);
 
@@ -243,7 +243,7 @@ CompositeStorage::Unmount(const char *uri)
 }
 
 CompositeStorage::FindResult
-CompositeStorage::FindStorage(const char *uri) const
+CompositeStorage::FindStorage(const char *uri) const noexcept
 {
 	FindResult result{&root, uri};
 
@@ -322,7 +322,7 @@ CompositeStorage::OpenDirectory(const char *uri)
 }
 
 std::string
-CompositeStorage::MapUTF8(const char *uri) const
+CompositeStorage::MapUTF8(const char *uri) const noexcept
 {
 	const std::lock_guard<Mutex> protect(mutex);
 
@@ -334,7 +334,7 @@ CompositeStorage::MapUTF8(const char *uri) const
 }
 
 AllocatedPath
-CompositeStorage::MapFS(const char *uri) const
+CompositeStorage::MapFS(const char *uri) const noexcept
 {
 	const std::lock_guard<Mutex> protect(mutex);
 
@@ -346,7 +346,7 @@ CompositeStorage::MapFS(const char *uri) const
 }
 
 const char *
-CompositeStorage::MapToRelativeUTF8(const char *uri) const
+CompositeStorage::MapToRelativeUTF8(const char *uri) const noexcept
 {
 	const std::lock_guard<Mutex> protect(mutex);
 
diff --git a/src/storage/CompositeStorage.hxx b/src/storage/CompositeStorage.hxx
index 96909c559..db71fad8f 100644
--- a/src/storage/CompositeStorage.hxx
+++ b/src/storage/CompositeStorage.hxx
@@ -60,7 +60,7 @@ class CompositeStorage final : public Storage {
 		}
 
 		gcc_pure
-		const Directory *Find(const char *uri) const;
+		const Directory *Find(const char *uri) const noexcept;
 
 		Directory &Make(const char *uri);
 
@@ -69,7 +69,7 @@ class CompositeStorage final : public Storage {
 
 		gcc_pure
 		bool MapToRelativeUTF8(std::string &buffer,
-				       const char *uri) const;
+				       const char *uri) const noexcept;
 	};
 
 	struct FindResult {
@@ -89,7 +89,7 @@ class CompositeStorage final : public Storage {
 	mutable std::string relative_buffer;
 
 public:
-	CompositeStorage();
+	CompositeStorage() noexcept;
 	virtual ~CompositeStorage();
 
 	/**
@@ -101,7 +101,7 @@ public:
 	 * value is being used.
 	 */
 	gcc_pure gcc_nonnull_all
-	Storage *GetMount(const char *uri);
+	Storage *GetMount(const char *uri) noexcept;
 
 	/**
 	 * Call the given function for each mounted storage, including
@@ -123,11 +123,11 @@ public:
 
 	StorageDirectoryReader *OpenDirectory(const char *uri) override;
 
-	std::string MapUTF8(const char *uri) const override;
+	std::string MapUTF8(const char *uri) const noexcept override;
 
-	AllocatedPath MapFS(const char *uri) const override;
+	AllocatedPath MapFS(const char *uri) const noexcept override;
 
-	const char *MapToRelativeUTF8(const char *uri) const override;
+	const char *MapToRelativeUTF8(const char *uri) const noexcept override;
 
 private:
 	template<typename T>
@@ -159,7 +159,7 @@ private:
 	 * the URI was used).
 	 */
 	gcc_pure
-	FindResult FindStorage(const char *uri) const;
+	FindResult FindStorage(const char *uri) const noexcept;
 
 	const char *MapToRelativeUTF8(const Directory &directory,
 				      const char *uri) const;
diff --git a/src/storage/Configured.cxx b/src/storage/Configured.cxx
index f0e7598c0..4b2cc1b5c 100644
--- a/src/storage/Configured.cxx
+++ b/src/storage/Configured.cxx
@@ -73,7 +73,7 @@ CreateConfiguredStorage(EventLoop &event_loop)
 }
 
 bool
-IsStorageConfigured()
+IsStorageConfigured() noexcept
 {
 	return config_get_string(ConfigOption::MUSIC_DIR) != nullptr;
 }
diff --git a/src/storage/Configured.hxx b/src/storage/Configured.hxx
index ec813f313..4b630af04 100644
--- a/src/storage/Configured.hxx
+++ b/src/storage/Configured.hxx
@@ -40,6 +40,6 @@ CreateConfiguredStorage(EventLoop &event_loop);
  */
 gcc_const
 bool
-IsStorageConfigured();
+IsStorageConfigured() noexcept;
 
 #endif
diff --git a/src/storage/Registry.cxx b/src/storage/Registry.cxx
index d0104359c..a919bd9da 100644
--- a/src/storage/Registry.cxx
+++ b/src/storage/Registry.cxx
@@ -43,7 +43,7 @@ const StoragePlugin *const storage_plugins[] = {
 };
 
 const StoragePlugin *
-GetStoragePluginByName(const char *name)
+GetStoragePluginByName(const char *name) noexcept
 {
 	for (auto i = storage_plugins; *i != nullptr; ++i) {
 		const StoragePlugin &plugin = **i;
diff --git a/src/storage/Registry.hxx b/src/storage/Registry.hxx
index e0930fd29..998756da7 100644
--- a/src/storage/Registry.hxx
+++ b/src/storage/Registry.hxx
@@ -35,7 +35,7 @@ extern const StoragePlugin *const storage_plugins[];
 
 gcc_nonnull_all gcc_pure
 const StoragePlugin *
-GetStoragePluginByName(const char *name);
+GetStoragePluginByName(const char *name) noexcept;
 
 gcc_nonnull_all gcc_malloc
 Storage *
diff --git a/src/storage/StorageInterface.cxx b/src/storage/StorageInterface.cxx
index a8d1597cf..a0e8ab460 100644
--- a/src/storage/StorageInterface.cxx
+++ b/src/storage/StorageInterface.cxx
@@ -23,14 +23,14 @@
 #include "fs/Traits.hxx"
 
 AllocatedPath
-Storage::MapFS(gcc_unused const char *uri_utf8) const
+Storage::MapFS(gcc_unused const char *uri_utf8) const noexcept
 {
 	return AllocatedPath::Null();
 }
 
 AllocatedPath
 Storage::MapChildFS(const char *uri_utf8,
-		    const char *child_utf8) const
+		    const char *child_utf8) const noexcept
 {
 	const auto uri2 = PathTraitsUTF8::Build(uri_utf8, child_utf8);
 	return MapFS(uri2.c_str());
diff --git a/src/storage/StorageInterface.hxx b/src/storage/StorageInterface.hxx
index 86f21b0ea..57d15ab15 100644
--- a/src/storage/StorageInterface.hxx
+++ b/src/storage/StorageInterface.hxx
@@ -64,7 +64,7 @@ public:
 	 * Map the given relative URI to an absolute URI.
 	 */
 	gcc_pure
-	virtual std::string MapUTF8(const char *uri_utf8) const = 0;
+	virtual std::string MapUTF8(const char *uri_utf8) const noexcept = 0;
 
 	/**
 	 * Map the given relative URI to a local file path.  Returns
@@ -72,11 +72,11 @@ public:
 	 * support local files.
 	 */
 	gcc_pure
-	virtual AllocatedPath MapFS(const char *uri_utf8) const;
+	virtual AllocatedPath MapFS(const char *uri_utf8) const noexcept;
 
 	gcc_pure
 	AllocatedPath MapChildFS(const char *uri_utf8,
-				 const char *child_utf8) const;
+				 const char *child_utf8) const noexcept;
 
 	/**
 	 * Check if the given URI points inside this storage.  If yes,
@@ -84,7 +84,7 @@ public:
 	 * string); if not, returns nullptr.
 	 */
 	gcc_pure
-	virtual const char *MapToRelativeUTF8(const char *uri_utf8) const = 0;
+	virtual const char *MapToRelativeUTF8(const char *uri_utf8) const noexcept = 0;
 };
 
 #endif
diff --git a/src/storage/plugins/CurlStorage.cxx b/src/storage/plugins/CurlStorage.cxx
index cc65badfd..8dd736dad 100644
--- a/src/storage/plugins/CurlStorage.cxx
+++ b/src/storage/plugins/CurlStorage.cxx
@@ -64,13 +64,13 @@ public:
 
 	StorageDirectoryReader *OpenDirectory(const char *uri_utf8) override;
 
-	std::string MapUTF8(const char *uri_utf8) const override;
+	std::string MapUTF8(const char *uri_utf8) const noexcept override;
 
-	const char *MapToRelativeUTF8(const char *uri_utf8) const override;
+	const char *MapToRelativeUTF8(const char *uri_utf8) const noexcept override;
 };
 
 std::string
-CurlStorage::MapUTF8(const char *uri_utf8) const
+CurlStorage::MapUTF8(const char *uri_utf8) const noexcept
 {
 	assert(uri_utf8 != nullptr);
 
@@ -83,7 +83,7 @@ CurlStorage::MapUTF8(const char *uri_utf8) const
 }
 
 const char *
-CurlStorage::MapToRelativeUTF8(const char *uri_utf8) const
+CurlStorage::MapToRelativeUTF8(const char *uri_utf8) const noexcept
 {
 	// TODO: escape/unescape?
 
@@ -475,7 +475,7 @@ CurlStorage::GetInfo(const char *uri_utf8, gcc_unused bool follow)
 
 gcc_pure
 static const char *
-UriPathOrSlash(const char *uri)
+UriPathOrSlash(const char *uri) noexcept
 {
 	const char *path = uri_get_path(uri);
 	if (path == nullptr)
diff --git a/src/storage/plugins/LocalStorage.cxx b/src/storage/plugins/LocalStorage.cxx
index 59e0c34f3..389d52a26 100644
--- a/src/storage/plugins/LocalStorage.cxx
+++ b/src/storage/plugins/LocalStorage.cxx
@@ -61,11 +61,11 @@ public:
 
 	StorageDirectoryReader *OpenDirectory(const char *uri_utf8) override;
 
-	std::string MapUTF8(const char *uri_utf8) const override;
+	std::string MapUTF8(const char *uri_utf8) const noexcept override;
 
-	AllocatedPath MapFS(const char *uri_utf8) const override;
+	AllocatedPath MapFS(const char *uri_utf8) const noexcept override;
 
-	const char *MapToRelativeUTF8(const char *uri_utf8) const override;
+	const char *MapToRelativeUTF8(const char *uri_utf8) const noexcept override;
 
 private:
 	AllocatedPath MapFSOrThrow(const char *uri_utf8) const;
@@ -97,7 +97,7 @@ Stat(Path path, bool follow)
 }
 
 std::string
-LocalStorage::MapUTF8(const char *uri_utf8) const
+LocalStorage::MapUTF8(const char *uri_utf8) const noexcept
 {
 	assert(uri_utf8 != nullptr);
 
@@ -120,7 +120,7 @@ LocalStorage::MapFSOrThrow(const char *uri_utf8) const
 }
 
 AllocatedPath
-LocalStorage::MapFS(const char *uri_utf8) const
+LocalStorage::MapFS(const char *uri_utf8) const noexcept
 {
 	try {
 		return MapFSOrThrow(uri_utf8);
@@ -130,7 +130,7 @@ LocalStorage::MapFS(const char *uri_utf8) const
 }
 
 const char *
-LocalStorage::MapToRelativeUTF8(const char *uri_utf8) const
+LocalStorage::MapToRelativeUTF8(const char *uri_utf8) const noexcept
 {
 	return PathTraitsUTF8::Relative(base_utf8.c_str(), uri_utf8);
 }
@@ -149,7 +149,7 @@ LocalStorage::OpenDirectory(const char *uri_utf8)
 
 gcc_pure
 static bool
-SkipNameFS(PathTraitsFS::const_pointer_type name_fs)
+SkipNameFS(PathTraitsFS::const_pointer_type name_fs) noexcept
 {
 	return name_fs[0] == '.' &&
 		(name_fs[1] == 0 ||
diff --git a/src/storage/plugins/NfsStorage.cxx b/src/storage/plugins/NfsStorage.cxx
index acb83fc17..53549bead 100644
--- a/src/storage/plugins/NfsStorage.cxx
+++ b/src/storage/plugins/NfsStorage.cxx
@@ -87,9 +87,9 @@ public:
 
 	StorageDirectoryReader *OpenDirectory(const char *uri_utf8) override;
 
-	std::string MapUTF8(const char *uri_utf8) const override;
+	std::string MapUTF8(const char *uri_utf8) const noexcept override;
 
-	const char *MapToRelativeUTF8(const char *uri_utf8) const override;
+	const char *MapToRelativeUTF8(const char *uri_utf8) const noexcept override;
 
 	/* virtual methods from NfsLease */
 	void OnNfsConnectionReady() final {
@@ -223,7 +223,7 @@ UriToNfsPath(const char *_uri_utf8)
 }
 
 std::string
-NfsStorage::MapUTF8(const char *uri_utf8) const
+NfsStorage::MapUTF8(const char *uri_utf8) const noexcept
 {
 	assert(uri_utf8 != nullptr);
 
@@ -234,7 +234,7 @@ NfsStorage::MapUTF8(const char *uri_utf8) const
 }
 
 const char *
-NfsStorage::MapToRelativeUTF8(const char *uri_utf8) const
+NfsStorage::MapToRelativeUTF8(const char *uri_utf8) const noexcept
 {
 	return PathTraitsUTF8::Relative(base.c_str(), uri_utf8);
 }
@@ -291,7 +291,7 @@ NfsStorage::GetInfo(const char *uri_utf8, gcc_unused bool follow)
 
 gcc_pure
 static bool
-SkipNameFS(const char *name)
+SkipNameFS(const char *name) noexcept
 {
 	return name[0] == '.' &&
 		(name[1] == 0 ||
diff --git a/src/storage/plugins/SmbclientStorage.cxx b/src/storage/plugins/SmbclientStorage.cxx
index 54bd4df8c..67d8c3bca 100644
--- a/src/storage/plugins/SmbclientStorage.cxx
+++ b/src/storage/plugins/SmbclientStorage.cxx
@@ -69,13 +69,13 @@ public:
 
 	StorageDirectoryReader *OpenDirectory(const char *uri_utf8) override;
 
-	std::string MapUTF8(const char *uri_utf8) const override;
+	std::string MapUTF8(const char *uri_utf8) const noexcept override;
 
-	const char *MapToRelativeUTF8(const char *uri_utf8) const override;
+	const char *MapToRelativeUTF8(const char *uri_utf8) const noexcept override;
 };
 
 std::string
-SmbclientStorage::MapUTF8(const char *uri_utf8) const
+SmbclientStorage::MapUTF8(const char *uri_utf8) const noexcept
 {
 	assert(uri_utf8 != nullptr);
 
@@ -86,7 +86,7 @@ SmbclientStorage::MapUTF8(const char *uri_utf8) const
 }
 
 const char *
-SmbclientStorage::MapToRelativeUTF8(const char *uri_utf8) const
+SmbclientStorage::MapToRelativeUTF8(const char *uri_utf8) const noexcept
 {
 	return PathTraitsUTF8::Relative(base.c_str(), uri_utf8);
 }
@@ -143,7 +143,7 @@ SmbclientStorage::OpenDirectory(const char *uri_utf8)
 
 gcc_pure
 static bool
-SkipNameFS(const char *name)
+SkipNameFS(const char *name) noexcept
 {
 	return name[0] == '.' &&
 		(name[1] == 0 ||
diff --git a/src/system/Error.hxx b/src/system/Error.hxx
index 32887ec25..4d89e12c8 100644
--- a/src/system/Error.hxx
+++ b/src/system/Error.hxx
@@ -149,7 +149,7 @@ FormatErrno(const char *fmt, Args&&... args)
 
 gcc_pure
 static inline bool
-IsFileNotFound(const std::system_error &e)
+IsFileNotFound(const std::system_error &e) noexcept
 {
 #ifdef WIN32
 	return e.code().category() == std::system_category() &&
@@ -162,7 +162,7 @@ IsFileNotFound(const std::system_error &e)
 
 gcc_pure
 static inline bool
-IsPathNotFound(const std::system_error &e)
+IsPathNotFound(const std::system_error &e) noexcept
 {
 #ifdef WIN32
 	return e.code().category() == std::system_category() &&
@@ -175,7 +175,7 @@ IsPathNotFound(const std::system_error &e)
 
 gcc_pure
 static inline bool
-IsAccessDenied(const std::system_error &e)
+IsAccessDenied(const std::system_error &e) noexcept
 {
 #ifdef WIN32
 	return e.code().category() == std::system_category() &&
diff --git a/src/system/FileDescriptor.cxx b/src/system/FileDescriptor.cxx
index 68bb3c022..e570090c4 100644
--- a/src/system/FileDescriptor.cxx
+++ b/src/system/FileDescriptor.cxx
@@ -58,14 +58,14 @@
 #endif
 
 bool
-FileDescriptor::Open(const char *pathname, int flags, mode_t mode)
+FileDescriptor::Open(const char *pathname, int flags, mode_t mode) noexcept
 {
 	fd = ::open(pathname, flags | O_NOCTTY | O_CLOEXEC, mode);
 	return IsDefined();
 }
 
 bool
-FileDescriptor::OpenReadOnly(const char *pathname)
+FileDescriptor::OpenReadOnly(const char *pathname) noexcept
 {
 	return Open(pathname, O_RDONLY);
 }
@@ -73,13 +73,13 @@ FileDescriptor::OpenReadOnly(const char *pathname)
 #ifndef WIN32
 
 bool
-FileDescriptor::OpenNonBlocking(const char *pathname)
+FileDescriptor::OpenNonBlocking(const char *pathname) noexcept
 {
 	return Open(pathname, O_RDWR | O_NONBLOCK);
 }
 
 bool
-FileDescriptor::CreatePipe(FileDescriptor &r, FileDescriptor &w)
+FileDescriptor::CreatePipe(FileDescriptor &r, FileDescriptor &w) noexcept
 {
 	int fds[2];
 
@@ -99,7 +99,7 @@ FileDescriptor::CreatePipe(FileDescriptor &r, FileDescriptor &w)
 }
 
 void
-FileDescriptor::SetNonBlocking()
+FileDescriptor::SetNonBlocking() noexcept
 {
 	assert(IsDefined());
 
@@ -108,7 +108,7 @@ FileDescriptor::SetNonBlocking()
 }
 
 void
-FileDescriptor::SetBlocking()
+FileDescriptor::SetBlocking() noexcept
 {
 	assert(IsDefined());
 
@@ -121,7 +121,7 @@ FileDescriptor::SetBlocking()
 #ifdef USE_EVENTFD
 
 bool
-FileDescriptor::CreateEventFD(unsigned initval)
+FileDescriptor::CreateEventFD(unsigned initval) noexcept
 {
 	fd = ::eventfd(initval, EFD_NONBLOCK|EFD_CLOEXEC);
 	return fd >= 0;
@@ -132,7 +132,7 @@ FileDescriptor::CreateEventFD(unsigned initval)
 #ifdef USE_SIGNALFD
 
 bool
-FileDescriptor::CreateSignalFD(const sigset_t *mask)
+FileDescriptor::CreateSignalFD(const sigset_t *mask) noexcept
 {
 	int new_fd = ::signalfd(fd, mask, SFD_NONBLOCK|SFD_CLOEXEC);
 	if (new_fd < 0)
@@ -147,7 +147,7 @@ FileDescriptor::CreateSignalFD(const sigset_t *mask)
 #ifdef HAVE_INOTIFY_INIT
 
 bool
-FileDescriptor::CreateInotify()
+FileDescriptor::CreateInotify() noexcept
 {
 #ifdef HAVE_INOTIFY_INIT1
 	int new_fd = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
@@ -168,7 +168,7 @@ FileDescriptor::CreateInotify()
 #endif
 
 bool
-FileDescriptor::Rewind()
+FileDescriptor::Rewind() noexcept
 {
 	assert(IsDefined());
 
@@ -176,7 +176,7 @@ FileDescriptor::Rewind()
 }
 
 off_t
-FileDescriptor::GetSize() const
+FileDescriptor::GetSize() const noexcept
 {
 	struct stat st;
 	return ::fstat(fd, &st) >= 0
@@ -187,7 +187,7 @@ FileDescriptor::GetSize() const
 #ifndef WIN32
 
 int
-FileDescriptor::Poll(short events, int timeout) const
+FileDescriptor::Poll(short events, int timeout) const noexcept
 {
 	assert(IsDefined());
 
@@ -201,13 +201,13 @@ FileDescriptor::Poll(short events, int timeout) const
 }
 
 int
-FileDescriptor::WaitReadable(int timeout) const
+FileDescriptor::WaitReadable(int timeout) const noexcept
 {
 	return Poll(POLLIN, timeout);
 }
 
 int
-FileDescriptor::WaitWritable(int timeout) const
+FileDescriptor::WaitWritable(int timeout) const noexcept
 {
 	return Poll(POLLOUT, timeout);
 }
diff --git a/src/system/FileDescriptor.hxx b/src/system/FileDescriptor.hxx
index 89e2cab20..163418c42 100644
--- a/src/system/FileDescriptor.hxx
+++ b/src/system/FileDescriptor.hxx
@@ -70,11 +70,11 @@ public:
 		return fd;
 	}
 
-	void Set(int _fd) {
+	void Set(int _fd) noexcept {
 		fd = _fd;
 	}
 
-	int Steal() {
+	int Steal() noexcept {
 		assert(IsDefined());
 
 		int _fd = fd;
@@ -82,7 +82,7 @@ public:
 		return _fd;
 	}
 
-	void SetUndefined() {
+	void SetUndefined() noexcept {
 		fd = -1;
 	}
 
@@ -90,42 +90,42 @@ public:
 		return FileDescriptor(-1);
 	}
 
-	bool Open(const char *pathname, int flags, mode_t mode=0666);
-	bool OpenReadOnly(const char *pathname);
+	bool Open(const char *pathname, int flags, mode_t mode=0666) noexcept;
+	bool OpenReadOnly(const char *pathname) noexcept;
 
 #ifndef WIN32
-	bool OpenNonBlocking(const char *pathname);
+	bool OpenNonBlocking(const char *pathname) noexcept;
 
-	static bool CreatePipe(FileDescriptor &r, FileDescriptor &w);
+	static bool CreatePipe(FileDescriptor &r, FileDescriptor &w) noexcept;
 
 	/**
 	 * Enable non-blocking mode on this file descriptor.
 	 */
-	void SetNonBlocking();
+	void SetNonBlocking() noexcept;
 
 	/**
 	 * Enable blocking mode on this file descriptor.
 	 */
-	void SetBlocking();
+	void SetBlocking() noexcept;
 
 	/**
 	 * Duplicate the file descriptor onto the given file descriptor.
 	 */
-	bool Duplicate(int new_fd) const {
+	bool Duplicate(int new_fd) const noexcept {
 		return ::dup2(Get(), new_fd) == 0;
 	}
 #endif
 
 #ifdef USE_EVENTFD
-	bool CreateEventFD(unsigned initval=0);
+	bool CreateEventFD(unsigned initval=0) noexcept;
 #endif
 
 #ifdef USE_SIGNALFD
-	bool CreateSignalFD(const sigset_t *mask);
+	bool CreateSignalFD(const sigset_t *mask) noexcept;
 #endif
 
 #ifdef HAVE_INOTIFY_INIT
-	bool CreateInotify();
+	bool CreateInotify() noexcept;
 #endif
 
 	/**
@@ -133,25 +133,25 @@ public:
 	 * "undefined" object.  After this call, IsDefined() is guaranteed
 	 * to return false, and this object may be reused.
 	 */
-	bool Close() {
+	bool Close() noexcept {
 		return ::close(Steal()) == 0;
 	}
 
 	/**
 	 * Rewind the pointer to the beginning of the file.
 	 */
-	bool Rewind();
+	bool Rewind() noexcept;
 
-	off_t Seek(off_t offset) {
+	off_t Seek(off_t offset) noexcept {
 		return lseek(Get(), offset, SEEK_SET);
 	}
 
-	off_t Skip(off_t offset) {
+	off_t Skip(off_t offset) noexcept {
 		return lseek(Get(), offset, SEEK_CUR);
 	}
 
 	gcc_pure
-	off_t Tell() const {
+	off_t Tell() const noexcept {
 		return lseek(Get(), 0, SEEK_CUR);
 	}
 
@@ -159,21 +159,21 @@ public:
 	 * Returns the size of the file in bytes, or -1 on error.
 	 */
 	gcc_pure
-	off_t GetSize() const;
+	off_t GetSize() const noexcept;
 
-	ssize_t Read(void *buffer, size_t length) {
+	ssize_t Read(void *buffer, size_t length) noexcept {
 		return ::read(fd, buffer, length);
 	}
 
-	ssize_t Write(const void *buffer, size_t length) {
+	ssize_t Write(const void *buffer, size_t length) noexcept {
 		return ::write(fd, buffer, length);
 	}
 
 #ifndef WIN32
-	int Poll(short events, int timeout) const;
+	int Poll(short events, int timeout) const noexcept;
 
-	int WaitReadable(int timeout) const;
-	int WaitWritable(int timeout) const;
+	int WaitReadable(int timeout) const noexcept;
+	int WaitWritable(int timeout) const noexcept;
 #endif
 };
 
diff --git a/src/tag/Format.cxx b/src/tag/Format.cxx
index 1164d961c..d70a9c084 100644
--- a/src/tag/Format.cxx
+++ b/src/tag/Format.cxx
@@ -53,7 +53,7 @@ IsUnsafeChar(char ch)
 
 gcc_pure
 static bool
-HasUnsafeChar(const char *s)
+HasUnsafeChar(const char *s) noexcept
 {
 	for (; *s; ++s)
 		if (IsUnsafeChar(*s))
@@ -63,7 +63,7 @@ HasUnsafeChar(const char *s)
 }
 
 static const char *
-SanitizeString(const char *s, char *buffer, size_t buffer_size)
+SanitizeString(const char *s, char *buffer, size_t buffer_size) noexcept
 {
 	/* skip leading dots to avoid generating "../" sequences */
 	while (*s == '.')
@@ -79,7 +79,7 @@ SanitizeString(const char *s, char *buffer, size_t buffer_size)
 
 gcc_pure gcc_nonnull_all
 static const char *
-TagGetter(const void *object, const char *name)
+TagGetter(const void *object, const char *name) noexcept
 {
 	const auto &_ctx = *(const FormatTagContext *)object;
 	auto &ctx = const_cast<FormatTagContext &>(_ctx);
@@ -126,7 +126,7 @@ TagGetter(const void *object, const char *name)
 }
 
 char *
-FormatTag(const Tag &tag, const char *format)
+FormatTag(const Tag &tag, const char *format) noexcept
 {
 	FormatTagContext ctx(tag);
 	return format_object(format, &ctx, TagGetter);
diff --git a/src/tag/Format.hxx b/src/tag/Format.hxx
index cf211e010..3cda2e4f9 100644
--- a/src/tag/Format.hxx
+++ b/src/tag/Format.hxx
@@ -27,6 +27,6 @@ struct Tag;
 
 gcc_malloc gcc_nonnull_all
 char *
-FormatTag(const Tag &tag, const char *format);
+FormatTag(const Tag &tag, const char *format) noexcept;
 
 #endif
diff --git a/src/tag/Id3Load.cxx b/src/tag/Id3Load.cxx
index 50be9b76b..fe9ba0b0f 100644
--- a/src/tag/Id3Load.cxx
+++ b/src/tag/Id3Load.cxx
@@ -33,7 +33,7 @@ static constexpr size_t ID3V1_SIZE = 128;
 
 gcc_pure
 static inline bool
-tag_is_id3v1(struct id3_tag *tag)
+tag_is_id3v1(struct id3_tag *tag) noexcept
 {
 	return (id3_tag_options(tag, 0, 0) & ID3_TAG_OPTION_ID3V1) != 0;
 }
diff --git a/src/tag/Settings.hxx b/src/tag/Settings.hxx
index a6e573cee..be4e9e981 100644
--- a/src/tag/Settings.hxx
+++ b/src/tag/Settings.hxx
@@ -28,14 +28,14 @@ extern tag_mask_t global_tag_mask;
 
 gcc_const
 static inline bool
-IsTagEnabled(unsigned tag)
+IsTagEnabled(unsigned tag) noexcept
 {
 	return global_tag_mask & (1u << tag);
 }
 
 gcc_const
 static inline bool
-IsTagEnabled(TagType tag)
+IsTagEnabled(TagType tag) noexcept
 {
 	return IsTagEnabled(unsigned(tag));
 }
diff --git a/src/tag/Tag.cxx b/src/tag/Tag.cxx
index d2623793b..8efb8df39 100644
--- a/src/tag/Tag.cxx
+++ b/src/tag/Tag.cxx
@@ -27,7 +27,7 @@
 #include <string.h>
 
 TagType
-tag_name_parse(const char *name)
+tag_name_parse(const char *name) noexcept
 {
 	assert(name != nullptr);
 
@@ -42,7 +42,7 @@ tag_name_parse(const char *name)
 }
 
 TagType
-tag_name_parse_i(const char *name)
+tag_name_parse_i(const char *name) noexcept
 {
 	assert(name != nullptr);
 
@@ -112,7 +112,7 @@ Tag::MergeReplace(Tag *base, Tag *add)
 }
 
 const char *
-Tag::GetValue(TagType type) const
+Tag::GetValue(TagType type) const noexcept
 {
 	assert(type < TAG_NUM_OF_ITEM_TYPES);
 
@@ -124,7 +124,7 @@ Tag::GetValue(TagType type) const
 }
 
 bool
-Tag::HasType(TagType type) const
+Tag::HasType(TagType type) const noexcept
 {
 	return GetValue(type) != nullptr;
 }
diff --git a/src/tag/Tag.hxx b/src/tag/Tag.hxx
index 236793649..33320cf5c 100644
--- a/src/tag/Tag.hxx
+++ b/src/tag/Tag.hxx
@@ -133,14 +133,14 @@ struct Tag {
 	 * nullptr if none is present in this tag object.
 	 */
 	gcc_pure
-	const char *GetValue(TagType type) const;
+	const char *GetValue(TagType type) const noexcept;
 
 	/**
 	 * Checks whether the tag contains one or more items with
 	 * the specified type.
 	 */
 	gcc_pure
-	bool HasType(TagType type) const;
+	bool HasType(TagType type) const noexcept;
 
 	class const_iterator {
 		friend struct Tag;
@@ -202,7 +202,7 @@ struct Tag {
  */
 gcc_pure
 TagType
-tag_name_parse(const char *name);
+tag_name_parse(const char *name) noexcept;
 
 /**
  * Parse the string, and convert it into a #TagType.  Returns
@@ -212,6 +212,6 @@ tag_name_parse(const char *name);
  */
 gcc_pure
 TagType
-tag_name_parse_i(const char *name);
+tag_name_parse_i(const char *name) noexcept;
 
 #endif
diff --git a/src/tag/TagBuilder.cxx b/src/tag/TagBuilder.cxx
index 6d259dc54..43cf3cc6f 100644
--- a/src/tag/TagBuilder.cxx
+++ b/src/tag/TagBuilder.cxx
@@ -153,7 +153,7 @@ TagBuilder::CommitNew()
 }
 
 bool
-TagBuilder::HasType(TagType type) const
+TagBuilder::HasType(TagType type) const noexcept
 {
 	for (auto i : items)
 		if (i->type == type)
@@ -237,7 +237,7 @@ TagBuilder::AddEmptyItem(TagType type)
 }
 
 void
-TagBuilder::RemoveAll()
+TagBuilder::RemoveAll() noexcept
 {
 	tag_pool_lock.lock();
 	for (auto i : items)
@@ -248,7 +248,7 @@ TagBuilder::RemoveAll()
 }
 
 void
-TagBuilder::RemoveType(TagType type)
+TagBuilder::RemoveType(TagType type) noexcept
 {
 	const auto begin = items.begin(), end = items.end();
 
diff --git a/src/tag/TagBuilder.hxx b/src/tag/TagBuilder.hxx
index 43b4d71e7..2ec1ae876 100644
--- a/src/tag/TagBuilder.hxx
+++ b/src/tag/TagBuilder.hxx
@@ -124,7 +124,7 @@ public:
 	 * the specified type.
 	 */
 	gcc_pure
-	bool HasType(TagType type) const;
+	bool HasType(TagType type) const noexcept;
 
 	/**
 	 * Copy attributes and items from the other object that do not
@@ -161,12 +161,12 @@ public:
 	/**
 	 * Removes all tag items.
 	 */
-	void RemoveAll();
+	void RemoveAll() noexcept;
 
 	/**
 	 * Removes all tag items of the specified type.
 	 */
-	void RemoveType(TagType type);
+	void RemoveType(TagType type) noexcept;
 
 private:
 	gcc_nonnull_all
diff --git a/src/tag/TagId3.cxx b/src/tag/TagId3.cxx
index f9bf7e9b2..14ce2c392 100644
--- a/src/tag/TagId3.cxx
+++ b/src/tag/TagId3.cxx
@@ -57,7 +57,7 @@
 
 gcc_pure
 static id3_utf8_t *
-tag_id3_getstring(const struct id3_frame *frame, unsigned i)
+tag_id3_getstring(const struct id3_frame *frame, unsigned i) noexcept
 {
 	id3_field *field = id3_frame_field(frame, i);
 	if (field == nullptr)
@@ -203,7 +203,7 @@ tag_id3_import_comment(struct id3_tag *tag, const char *id, TagType type,
  */
 gcc_pure
 static TagType
-tag_id3_parse_txxx_name(const char *name)
+tag_id3_parse_txxx_name(const char *name) noexcept
 {
 	static constexpr struct tag_table txxx_tags[] = {
 		{ "ALBUMARTISTSORT", TAG_ALBUM_ARTIST_SORT },
diff --git a/src/tag/TagString.cxx b/src/tag/TagString.cxx
index 8462c1fa1..1c37bf422 100644
--- a/src/tag/TagString.cxx
+++ b/src/tag/TagString.cxx
@@ -29,7 +29,7 @@
 
 gcc_pure
 static const char *
-FindInvalidUTF8(const char *p, const char *const end)
+FindInvalidUTF8(const char *p, const char *const end) noexcept
 {
 	while (p < end) {
 		const size_t s = SequenceLengthUTF8(*p);
diff --git a/src/tag/TagTable.cxx b/src/tag/TagTable.cxx
index 74ef03521..9953c011a 100644
--- a/src/tag/TagTable.cxx
+++ b/src/tag/TagTable.cxx
@@ -28,7 +28,7 @@
  * in the table.
  */
 TagType
-tag_table_lookup(const struct tag_table *table, const char *name)
+tag_table_lookup(const struct tag_table *table, const char *name) noexcept
 {
 	for (; table->name != nullptr; ++table)
 		if (strcmp(name, table->name) == 0)
@@ -43,7 +43,7 @@ tag_table_lookup(const struct tag_table *table, const char *name)
  * in the table.
  */
 TagType
-tag_table_lookup_i(const struct tag_table *table, const char *name)
+tag_table_lookup_i(const struct tag_table *table, const char *name) noexcept
 {
 	for (; table->name != nullptr; ++table)
 		if (StringEqualsCaseASCII(name, table->name))
@@ -53,7 +53,7 @@ tag_table_lookup_i(const struct tag_table *table, const char *name)
 }
 
 const char *
-tag_table_lookup(const tag_table *table, TagType type)
+tag_table_lookup(const tag_table *table, TagType type) noexcept
 {
 	for (; table->name != nullptr; ++table)
 		if (table->type == type)
diff --git a/src/tag/TagTable.hxx b/src/tag/TagTable.hxx
index 3591fbb1d..c3357df5e 100644
--- a/src/tag/TagTable.hxx
+++ b/src/tag/TagTable.hxx
@@ -36,7 +36,7 @@ struct tag_table {
  */
 gcc_pure
 TagType
-tag_table_lookup(const tag_table *table, const char *name);
+tag_table_lookup(const tag_table *table, const char *name) noexcept;
 
 /**
  * Looks up a string in a tag translation table (case insensitive).
@@ -45,7 +45,7 @@ tag_table_lookup(const tag_table *table, const char *name);
  */
 gcc_pure
 TagType
-tag_table_lookup_i(const tag_table *table, const char *name);
+tag_table_lookup_i(const tag_table *table, const char *name) noexcept;
 
 /**
  * Looks up a #TagType in a tag translation table and returns its
@@ -54,6 +54,6 @@ tag_table_lookup_i(const tag_table *table, const char *name);
  */
 gcc_pure
 const char *
-tag_table_lookup(const tag_table *table, TagType type);
+tag_table_lookup(const tag_table *table, TagType type) noexcept;
 
 #endif
diff --git a/src/tag/VorbisComment.cxx b/src/tag/VorbisComment.cxx
index f29cb80ae..c312c9f18 100644
--- a/src/tag/VorbisComment.cxx
+++ b/src/tag/VorbisComment.cxx
@@ -25,7 +25,7 @@
 #include <string.h>
 
 const char *
-vorbis_comment_value(const char *entry, const char *name)
+vorbis_comment_value(const char *entry, const char *name) noexcept
 {
 	assert(entry != nullptr);
 	assert(name != nullptr);
diff --git a/src/tag/VorbisComment.hxx b/src/tag/VorbisComment.hxx
index f8635c8e1..d2ea86338 100644
--- a/src/tag/VorbisComment.hxx
+++ b/src/tag/VorbisComment.hxx
@@ -29,6 +29,6 @@
  */
 gcc_pure
 const char *
-vorbis_comment_value(const char *entry, const char *name);
+vorbis_comment_value(const char *entry, const char *name) noexcept;
 
 #endif
diff --git a/src/thread/Id.hxx b/src/thread/Id.hxx
index 3063d0098..169cb1af8 100644
--- a/src/thread/Id.hxx
+++ b/src/thread/Id.hxx
@@ -71,7 +71,7 @@ public:
 	 * Return the current thread's id .
 	 */
 	gcc_pure
-	static const ThreadId GetCurrent() {
+	static const ThreadId GetCurrent() noexcept {
 #ifdef WIN32
 		return ::GetCurrentThreadId();
 #else
@@ -91,7 +91,7 @@ public:
 	/**
 	 * Check if this thread is the current thread.
 	 */
-	bool IsInside() const {
+	bool IsInside() const noexcept {
 		return *this == GetCurrent();
 	}
 };
diff --git a/src/unix/PidFile.hxx b/src/unix/PidFile.hxx
index dbb94d8ff..0cb476755 100644
--- a/src/unix/PidFile.hxx
+++ b/src/unix/PidFile.hxx
@@ -88,7 +88,7 @@ public:
 
 gcc_pure
 static inline pid_t
-ReadPidFile(Path path)
+ReadPidFile(Path path) noexcept
 {
 	int fd = OpenFile(path, O_RDONLY, 0);
 	if (fd < 0)
diff --git a/src/util/ASCII.hxx b/src/util/ASCII.hxx
index 38cd9b765..6d31d836a 100644
--- a/src/util/ASCII.hxx
+++ b/src/util/ASCII.hxx
@@ -41,7 +41,7 @@
  */
 gcc_pure gcc_nonnull_all
 static inline bool
-StringEqualsCaseASCII(const char *a, const char *b)
+StringEqualsCaseASCII(const char *a, const char *b) noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
@@ -56,7 +56,7 @@ StringEqualsCaseASCII(const char *a, const char *b)
 
 gcc_pure gcc_nonnull_all
 static inline bool
-StringEqualsCaseASCII(const char *a, const char *b, size_t n)
+StringEqualsCaseASCII(const char *a, const char *b, size_t n) noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
diff --git a/src/util/HugeAllocator.cxx b/src/util/HugeAllocator.cxx
index 67fba1c6d..5116a5923 100644
--- a/src/util/HugeAllocator.cxx
+++ b/src/util/HugeAllocator.cxx
@@ -45,7 +45,7 @@
  */
 gcc_const
 static size_t
-AlignToPageSize(size_t size)
+AlignToPageSize(size_t size) noexcept
 {
 	static const long page_size = sysconf(_SC_PAGESIZE);
 	if (page_size <= 0)
diff --git a/src/util/PeakBuffer.cxx b/src/util/PeakBuffer.cxx
index 05d2f9e89..ea7ad94f3 100644
--- a/src/util/PeakBuffer.cxx
+++ b/src/util/PeakBuffer.cxx
@@ -32,14 +32,14 @@ PeakBuffer::~PeakBuffer()
 }
 
 bool
-PeakBuffer::IsEmpty() const
+PeakBuffer::IsEmpty() const noexcept
 {
 	return (normal_buffer == nullptr || normal_buffer->IsEmpty()) &&
 		(peak_buffer == nullptr || peak_buffer->IsEmpty());
 }
 
 WritableBuffer<void>
-PeakBuffer::Read() const
+PeakBuffer::Read() const noexcept
 {
 	if (normal_buffer != nullptr) {
 		const auto p = normal_buffer->Read();
@@ -57,7 +57,7 @@ PeakBuffer::Read() const
 }
 
 void
-PeakBuffer::Consume(size_t length)
+PeakBuffer::Consume(size_t length) noexcept
 {
 	if (normal_buffer != nullptr && !normal_buffer->IsEmpty()) {
 		normal_buffer->Consume(length);
@@ -76,7 +76,8 @@ PeakBuffer::Consume(size_t length)
 }
 
 static size_t
-AppendTo(DynamicFifoBuffer<uint8_t> &buffer, const void *data, size_t length)
+AppendTo(DynamicFifoBuffer<uint8_t> &buffer,
+	 const void *data, size_t length) noexcept
 {
 	assert(data != nullptr);
 	assert(length > 0);
diff --git a/src/util/PeakBuffer.hxx b/src/util/PeakBuffer.hxx
index a508062dc..294cba380 100644
--- a/src/util/PeakBuffer.hxx
+++ b/src/util/PeakBuffer.hxx
@@ -57,12 +57,12 @@ public:
 	PeakBuffer &operator=(const PeakBuffer &) = delete;
 
 	gcc_pure
-	bool IsEmpty() const;
+	bool IsEmpty() const noexcept;
 
 	gcc_pure
-	WritableBuffer<void> Read() const;
+	WritableBuffer<void> Read() const noexcept;
 
-	void Consume(size_t length);
+	void Consume(size_t length) noexcept;
 
 	bool Append(const void *data, size_t length);
 };
diff --git a/src/util/StringAPI.hxx b/src/util/StringAPI.hxx
index d9e89c628..85456fb8f 100644
--- a/src/util/StringAPI.hxx
+++ b/src/util/StringAPI.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2015 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright (C) 2010-2017 Max Kellermann <max.kellermann@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -40,70 +40,70 @@
 
 gcc_pure gcc_nonnull_all
 static inline size_t
-StringLength(const char *p)
+StringLength(const char *p) noexcept
 {
 	return strlen(p);
 }
 
 gcc_pure gcc_nonnull_all
 static inline const char *
-StringFind(const char *haystack, const char *needle)
+StringFind(const char *haystack, const char *needle) noexcept
 {
 	return strstr(haystack, needle);
 }
 
 gcc_pure gcc_nonnull_all
 static inline char *
-StringFind(char *haystack, char needle, size_t size)
+StringFind(char *haystack, char needle, size_t size) noexcept
 {
 	return (char *)memchr(haystack, needle, size);
 }
 
 gcc_pure gcc_nonnull_all
 static inline const char *
-StringFind(const char *haystack, char needle, size_t size)
+StringFind(const char *haystack, char needle, size_t size) noexcept
 {
 	return (const char *)memchr(haystack, needle, size);
 }
 
 gcc_pure gcc_nonnull_all
 static inline const char *
-StringFind(const char *haystack, char needle)
+StringFind(const char *haystack, char needle) noexcept
 {
 	return strchr(haystack, needle);
 }
 
 gcc_pure gcc_nonnull_all
 static inline char *
-StringFind(char *haystack, char needle)
+StringFind(char *haystack, char needle) noexcept
 {
 	return strchr(haystack, needle);
 }
 
 gcc_pure gcc_nonnull_all
 static inline const char *
-StringFindLast(const char *haystack, char needle)
+StringFindLast(const char *haystack, char needle) noexcept
 {
 	return strrchr(haystack, needle);
 }
 
 gcc_pure gcc_nonnull_all
 static inline char *
-StringFindLast(char *haystack, char needle)
+StringFindLast(char *haystack, char needle) noexcept
 {
 	return strrchr(haystack, needle);
 }
 
 gcc_nonnull_all
 static inline void
-UnsafeCopyString(char *dest, const char *src)
+UnsafeCopyString(char *dest, const char *src) noexcept
 {
 	strcpy(dest, src);
 }
 
 gcc_nonnull_all
 static inline char *
-UnsafeCopyStringP(char *dest, const char *src)
+UnsafeCopyStringP(char *dest, const char *src) noexcept
 {
 #if defined(WIN32) || defined(__BIONIC__)
   /* emulate stpcpy() */
@@ -119,7 +119,7 @@ UnsafeCopyStringP(char *dest, const char *src)
  */
 gcc_pure gcc_nonnull_all
 static inline bool
-StringIsEqual(const char *a, const char *b)
+StringIsEqual(const char *a, const char *b) noexcept
 {
 	return strcmp(a, b) == 0;
 }
@@ -129,7 +129,7 @@ StringIsEqual(const char *a, const char *b)
  */
 gcc_pure gcc_nonnull_all
 static inline bool
-StringIsEqual(const char *a, const char *b, size_t length)
+StringIsEqual(const char *a, const char *b, size_t length) noexcept
 {
 	return strncmp(a, b, length) == 0;
 }
diff --git a/src/util/StringCompare.cxx b/src/util/StringCompare.cxx
index 0eb99034d..58ac5a2c1 100644
--- a/src/util/StringCompare.cxx
+++ b/src/util/StringCompare.cxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2015 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright (C) 2013-2017 Max Kellermann <max.kellermann@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,7 +30,7 @@
 #include "StringCompare.hxx"
 
 bool
-StringEndsWith(const char *haystack, const char *needle)
+StringEndsWith(const char *haystack, const char *needle) noexcept
 {
 	const size_t haystack_length = strlen(haystack);
 	const size_t needle_length = strlen(needle);
@@ -41,7 +41,7 @@ StringEndsWith(const char *haystack, const char *needle)
 }
 
 const char *
-FindStringSuffix(const char *p, const char *suffix)
+FindStringSuffix(const char *p, const char *suffix) noexcept
 {
 	const size_t p_length = strlen(p);
 	const size_t suffix_length = strlen(suffix);
diff --git a/src/util/StringCompare.hxx b/src/util/StringCompare.hxx
index 39df6c519..b8c69031a 100644
--- a/src/util/StringCompare.hxx
+++ b/src/util/StringCompare.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2015 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright (C) 2013-2017 Max Kellermann <max.kellermann@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,14 +45,14 @@ StringIsEmpty(const char *string)
 
 gcc_pure gcc_nonnull_all
 static inline bool
-StringStartsWith(const char *haystack, StringView needle)
+StringStartsWith(const char *haystack, StringView needle) noexcept
 {
 	return strncmp(haystack, needle.data, needle.size) == 0;
 }
 
 gcc_pure
 bool
-StringEndsWith(const char *haystack, const char *needle);
+StringEndsWith(const char *haystack, const char *needle) noexcept;
 
 /**
  * Returns the portion of the string after a prefix.  If the string
@@ -61,7 +61,7 @@ StringEndsWith(const char *haystack, const char *needle);
  */
 gcc_pure gcc_nonnull_all
 static inline const char *
-StringAfterPrefix(const char *haystack, StringView needle)
+StringAfterPrefix(const char *haystack, StringView needle) noexcept
 {
 	return StringStartsWith(haystack, needle)
 		? haystack + needle.size
@@ -74,6 +74,6 @@ StringAfterPrefix(const char *haystack, StringView needle)
  */
 gcc_pure
 const char *
-FindStringSuffix(const char *p, const char *suffix);
+FindStringSuffix(const char *p, const char *suffix) noexcept;
 
 #endif
diff --git a/src/util/StringUtil.cxx b/src/util/StringUtil.cxx
index 9f9d16c41..b8851edb6 100644
--- a/src/util/StringUtil.cxx
+++ b/src/util/StringUtil.cxx
@@ -27,7 +27,8 @@
 #include <string.h>
 
 char *
-CopyString(char *gcc_restrict dest, const char *gcc_restrict src, size_t size)
+CopyString(char *gcc_restrict dest, const char *gcc_restrict src,
+	   size_t size) noexcept
 {
 	size_t length = strlen(src);
 	if (length >= size)
@@ -39,7 +40,7 @@ CopyString(char *gcc_restrict dest, const char *gcc_restrict src, size_t size)
 }
 
 const char *
-StripLeft(const char *p)
+StripLeft(const char *p) noexcept
 {
 	while (IsWhitespaceNotNull(*p))
 		++p;
@@ -48,7 +49,7 @@ StripLeft(const char *p)
 }
 
 const char *
-StripLeft(const char *p, const char *end)
+StripLeft(const char *p, const char *end) noexcept
 {
 	while (p < end && IsWhitespaceOrNull(*p))
 		++p;
@@ -57,7 +58,7 @@ StripLeft(const char *p, const char *end)
 }
 
 const char *
-StripRight(const char *p, const char *end)
+StripRight(const char *p, const char *end) noexcept
 {
 	while (end > p && IsWhitespaceOrNull(end[-1]))
 		--end;
@@ -66,7 +67,7 @@ StripRight(const char *p, const char *end)
 }
 
 size_t
-StripRight(const char *p, size_t length)
+StripRight(const char *p, size_t length) noexcept
 {
 	while (length > 0 && IsWhitespaceOrNull(p[length - 1]))
 		--length;
@@ -75,7 +76,7 @@ StripRight(const char *p, size_t length)
 }
 
 void
-StripRight(char *p)
+StripRight(char *p) noexcept
 {
 	size_t old_length = strlen(p);
 	size_t new_length = StripRight(p, old_length);
@@ -83,7 +84,7 @@ StripRight(char *p)
 }
 
 char *
-Strip(char *p)
+Strip(char *p) noexcept
 {
 	p = StripLeft(p);
 	StripRight(p);
@@ -91,7 +92,8 @@ Strip(char *p)
 }
 
 bool
-StringArrayContainsCase(const char *const*haystack, const char *needle)
+StringArrayContainsCase(const char *const*haystack,
+			const char *needle) noexcept
 {
 	assert(haystack != nullptr);
 	assert(needle != nullptr);
@@ -104,7 +106,7 @@ StringArrayContainsCase(const char *const*haystack, const char *needle)
 }
 
 void
-ToUpperASCII(char *dest, const char *src, size_t size)
+ToUpperASCII(char *dest, const char *src, size_t size) noexcept
 {
 	assert(dest != nullptr);
 	assert(src != nullptr);
diff --git a/src/util/StringUtil.hxx b/src/util/StringUtil.hxx
index c2fc5dcbc..0fe131f25 100644
--- a/src/util/StringUtil.hxx
+++ b/src/util/StringUtil.hxx
@@ -34,7 +34,7 @@
  */
 gcc_nonnull_all
 char *
-CopyString(char *dest, const char *src, size_t size);
+CopyString(char *dest, const char *src, size_t size) noexcept;
 
 /**
  * Returns a pointer to the first non-whitespace character in the
@@ -42,32 +42,32 @@ CopyString(char *dest, const char *src, size_t size);
  */
 gcc_pure
 const char *
-StripLeft(const char *p);
+StripLeft(const char *p) noexcept;
 
 gcc_pure
 static inline char *
-StripLeft(char *p)
+StripLeft(char *p) noexcept
 {
 	return const_cast<char *>(StripLeft((const char *)p));
 }
 
 gcc_pure
 const char *
-StripLeft(const char *p, const char *end);
+StripLeft(const char *p, const char *end) noexcept;
 
 /**
  * Determine the string's end as if it was stripped on the right side.
  */
 gcc_pure
 const char *
-StripRight(const char *p, const char *end);
+StripRight(const char *p, const char *end) noexcept;
 
 /**
  * Determine the string's end as if it was stripped on the right side.
  */
 gcc_pure
 static inline char *
-StripRight(char *p, char *end)
+StripRight(char *p, char *end) noexcept
 {
 	return const_cast<char *>(StripRight((const char *)p,
 					     (const char *)end));
@@ -79,20 +79,20 @@ StripRight(char *p, char *end)
  */
 gcc_pure
 size_t
-StripRight(const char *p, size_t length);
+StripRight(const char *p, size_t length) noexcept;
 
 /**
  * Strip trailing whitespace by null-terminating the string.
  */
 void
-StripRight(char *p);
+StripRight(char *p) noexcept;
 
 /**
  * Skip whitespace at the beginning and terminate the string after the
  * last non-whitespace character.
  */
 char *
-Strip(char *p);
+Strip(char *p) noexcept;
 
 /**
  * Checks whether a string array contains the specified string.
@@ -104,7 +104,8 @@ Strip(char *p);
  */
 gcc_pure
 bool
-StringArrayContainsCase(const char *const*haystack, const char *needle);
+StringArrayContainsCase(const char *const*haystack,
+			const char *needle) noexcept;
 
 /**
  * Convert the specified ASCII string (0x00..0x7f) to upper case.
@@ -112,6 +113,6 @@ StringArrayContainsCase(const char *const*haystack, const char *needle);
  * @param size the destination buffer size
  */
 void
-ToUpperASCII(char *dest, const char *src, size_t size);
+ToUpperASCII(char *dest, const char *src, size_t size) noexcept;
 
 #endif
diff --git a/src/util/TimeParser.cxx b/src/util/TimeParser.cxx
index 1a3417928..b99433a75 100644
--- a/src/util/TimeParser.cxx
+++ b/src/util/TimeParser.cxx
@@ -41,7 +41,7 @@
  */
 gcc_const
 static time_t
-GetTimeZoneOffset()
+GetTimeZoneOffset() noexcept
 {
 	time_t t = 1234567890;
 	struct tm tm;
diff --git a/src/util/UTF8.cxx b/src/util/UTF8.cxx
index e0d0a4fd7..21ce6e1a8 100644
--- a/src/util/UTF8.cxx
+++ b/src/util/UTF8.cxx
@@ -124,7 +124,7 @@ MakeContinuation(unsigned char value)
 }
 
 bool
-ValidateUTF8(const char *p)
+ValidateUTF8(const char *p) noexcept
 {
 	for (; *p != 0; ++p) {
 		unsigned char ch = *p;
@@ -167,7 +167,7 @@ ValidateUTF8(const char *p)
 }
 
 size_t
-SequenceLengthUTF8(char ch)
+SequenceLengthUTF8(char ch) noexcept
 {
 	if (IsASCII(ch))
 		return 1;
@@ -196,14 +196,14 @@ SequenceLengthUTF8(char ch)
 template<size_t L>
 struct CheckSequenceUTF8 {
 	gcc_pure
-	bool operator()(const char *p) const {
+	bool operator()(const char *p) const noexcept {
 		return IsContinuation(*p) && CheckSequenceUTF8<L-1>()(p + 1);
 	}
 };
 
 template<>
 struct CheckSequenceUTF8<0u> {
-	constexpr bool operator()(gcc_unused const char *p) const {
+	constexpr bool operator()(gcc_unused const char *p) const noexcept {
 		return true;
 	}
 };
@@ -211,7 +211,7 @@ struct CheckSequenceUTF8<0u> {
 template<size_t L>
 gcc_pure
 static size_t
-InnerSequenceLengthUTF8(const char *p)
+InnerSequenceLengthUTF8(const char *p) noexcept
 {
 	return CheckSequenceUTF8<L>()(p)
 		? L + 1
@@ -219,7 +219,7 @@ InnerSequenceLengthUTF8(const char *p)
 }
 
 size_t
-SequenceLengthUTF8(const char *p)
+SequenceLengthUTF8(const char *p) noexcept
 {
 	const unsigned char ch = *p++;
 
@@ -246,8 +246,9 @@ SequenceLengthUTF8(const char *p)
 		return 0;
 }
 
+gcc_pure
 static const char *
-FindNonASCIIOrZero(const char *p)
+FindNonASCIIOrZero(const char *p) noexcept
 {
   while (*p != 0 && IsASCII(*p))
     ++p;
@@ -256,7 +257,7 @@ FindNonASCIIOrZero(const char *p)
 
 const char *
 Latin1ToUTF8(const char *gcc_restrict src, char *gcc_restrict buffer,
-	     size_t buffer_size)
+	     size_t buffer_size) noexcept
 {
 	const char *p = FindNonASCIIOrZero(src);
 	if (*p == 0)
@@ -294,7 +295,7 @@ Latin1ToUTF8(const char *gcc_restrict src, char *gcc_restrict buffer,
 }
 
 char *
-UnicodeToUTF8(unsigned ch, char *q)
+UnicodeToUTF8(unsigned ch, char *q) noexcept
 {
   if (gcc_likely(ch < 0x80)) {
     *q++ = (char)ch;
@@ -331,7 +332,7 @@ UnicodeToUTF8(unsigned ch, char *q)
 }
 
 size_t
-LengthUTF8(const char *p)
+LengthUTF8(const char *p) noexcept
 {
 	/* this is a very naive implementation: it does not do any
 	   verification, it just counts the bytes that are not a UTF-8
diff --git a/src/util/UTF8.hxx b/src/util/UTF8.hxx
index e829407bb..62decb4f5 100644
--- a/src/util/UTF8.hxx
+++ b/src/util/UTF8.hxx
@@ -40,7 +40,7 @@
  */
 gcc_pure gcc_nonnull_all
 bool
-ValidateUTF8(const char *p);
+ValidateUTF8(const char *p) noexcept;
 
 /**
  * @return the number of the sequence beginning with the given
@@ -48,7 +48,7 @@ ValidateUTF8(const char *p);
  */
 gcc_const
 size_t
-SequenceLengthUTF8(char ch);
+SequenceLengthUTF8(char ch) noexcept;
 
 /**
  * @return the number of the first sequence in the given string, or 0
@@ -56,7 +56,7 @@ SequenceLengthUTF8(char ch);
  */
 gcc_pure
 size_t
-SequenceLengthUTF8(const char *p);
+SequenceLengthUTF8(const char *p) noexcept;
 
 /**
  * Convert the specified string from ISO-8859-1 to UTF-8.
@@ -67,7 +67,7 @@ SequenceLengthUTF8(const char *p);
  */
 gcc_pure  gcc_nonnull_all
 const char *
-Latin1ToUTF8(const char *src, char *buffer, size_t buffer_size);
+Latin1ToUTF8(const char *src, char *buffer, size_t buffer_size) noexcept;
 
 /**
  * Convert the specified Unicode character to UTF-8 and write it to
@@ -77,7 +77,7 @@ Latin1ToUTF8(const char *src, char *buffer, size_t buffer_size);
  */
 gcc_nonnull_all
 char *
-UnicodeToUTF8(unsigned ch, char *buffer);
+UnicodeToUTF8(unsigned ch, char *buffer) noexcept;
 
 /**
  * Returns the number of characters in the string.  This is different
@@ -85,6 +85,6 @@ UnicodeToUTF8(unsigned ch, char *buffer);
  */
 gcc_pure gcc_nonnull_all
 size_t
-LengthUTF8(const char *p);
+LengthUTF8(const char *p) noexcept;
 
 #endif
diff --git a/src/util/UriUtil.cxx b/src/util/UriUtil.cxx
index 74f831513..61b90da29 100644
--- a/src/util/UriUtil.cxx
+++ b/src/util/UriUtil.cxx
@@ -39,7 +39,7 @@ IsValidSchemeChar(char ch)
 
 gcc_pure
 static bool
-IsValidScheme(StringView p)
+IsValidScheme(StringView p) noexcept
 {
 	if (p.IsEmpty() || !IsValidSchemeStart(p.front()))
 		return false;
@@ -57,7 +57,7 @@ IsValidScheme(StringView p)
  */
 gcc_pure
 static const char *
-uri_after_scheme(const char *uri)
+uri_after_scheme(const char *uri) noexcept
 {
 	if (uri[0] == '/' && uri[1] == '/' && uri[2] != '/')
 		return uri + 2;
@@ -70,13 +70,14 @@ uri_after_scheme(const char *uri)
 		: nullptr;
 }
 
-bool uri_has_scheme(const char *uri)
+bool
+uri_has_scheme(const char *uri) noexcept
 {
 	return strstr(uri, "://") != nullptr;
 }
 
 std::string
-uri_get_scheme(const char *uri)
+uri_get_scheme(const char *uri) noexcept
 {
 	const char *end = strstr(uri, "://");
 	if (end == nullptr)
@@ -86,7 +87,7 @@ uri_get_scheme(const char *uri)
 }
 
 const char *
-uri_get_path(const char *uri)
+uri_get_path(const char *uri) noexcept
 {
 	const char *ap = uri_after_scheme(uri);
 	if (ap != nullptr)
@@ -97,7 +98,7 @@ uri_get_path(const char *uri)
 
 /* suffixes should be ascii only characters */
 const char *
-uri_get_suffix(const char *uri)
+uri_get_suffix(const char *uri) noexcept
 {
 	const char *suffix = strrchr(uri, '.');
 	if (suffix == nullptr || suffix == uri ||
@@ -113,7 +114,7 @@ uri_get_suffix(const char *uri)
 }
 
 const char *
-uri_get_suffix(const char *uri, UriSuffixBuffer &buffer)
+uri_get_suffix(const char *uri, UriSuffixBuffer &buffer) noexcept
 {
 	const char *suffix = uri_get_suffix(uri);
 	if (suffix == nullptr)
@@ -130,7 +131,7 @@ uri_get_suffix(const char *uri, UriSuffixBuffer &buffer)
 }
 
 static const char *
-verify_uri_segment(const char *p)
+verify_uri_segment(const char *p) noexcept
 {
 	unsigned dots = 0;
 	while (*p == '.') {
@@ -146,7 +147,7 @@ verify_uri_segment(const char *p)
 }
 
 bool
-uri_safe_local(const char *uri)
+uri_safe_local(const char *uri) noexcept
 {
 	while (true) {
 		uri = verify_uri_segment(uri);
@@ -164,7 +165,7 @@ uri_safe_local(const char *uri)
 
 gcc_pure
 static const char *
-SkipUriScheme(const char *uri)
+SkipUriScheme(const char *uri) noexcept
 {
 	const char *const schemes[] = { "http://", "https://", "ftp://" };
 	for (auto scheme : schemes) {
@@ -177,7 +178,7 @@ SkipUriScheme(const char *uri)
 }
 
 std::string
-uri_remove_auth(const char *uri)
+uri_remove_auth(const char *uri) noexcept
 {
 	const char *auth = SkipUriScheme(uri);
 	if (auth == nullptr)
@@ -201,7 +202,7 @@ uri_remove_auth(const char *uri)
 }
 
 bool
-uri_is_child(const char *parent, const char *child)
+uri_is_child(const char *parent, const char *child) noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
@@ -216,13 +217,13 @@ uri_is_child(const char *parent, const char *child)
 
 
 bool
-uri_is_child_or_same(const char *parent, const char *child)
+uri_is_child_or_same(const char *parent, const char *child) noexcept
 {
 	return strcmp(parent, child) == 0 || uri_is_child(parent, child);
 }
 
 std::string
-uri_apply_base(const std::string &uri, const std::string &base)
+uri_apply_base(const std::string &uri, const std::string &base) noexcept
 {
 	if (uri.front() == '/') {
 		/* absolute path: replace the whole URI path in base */
diff --git a/src/util/UriUtil.hxx b/src/util/UriUtil.hxx
index 3f673ca7b..10ed67cc0 100644
--- a/src/util/UriUtil.hxx
+++ b/src/util/UriUtil.hxx
@@ -29,14 +29,15 @@
  * "scheme://".
  */
 gcc_pure
-bool uri_has_scheme(const char *uri);
+bool
+uri_has_scheme(const char *uri) noexcept;
 
 /**
  * Returns the scheme name of the specified URI, or an empty string.
  */
 gcc_pure
 std::string
-uri_get_scheme(const char *uri);
+uri_get_scheme(const char *uri) noexcept;
 
 /**
  * Returns the URI path (including the query string) or nullptr if the
@@ -44,11 +45,11 @@ uri_get_scheme(const char *uri);
  */
 gcc_pure gcc_nonnull_all
 const char *
-uri_get_path(const char *uri);
+uri_get_path(const char *uri) noexcept;
 
 gcc_pure
 const char *
-uri_get_suffix(const char *uri);
+uri_get_suffix(const char *uri) noexcept;
 
 struct UriSuffixBuffer {
 	char data[8];
@@ -59,7 +60,7 @@ struct UriSuffixBuffer {
  */
 gcc_pure
 const char *
-uri_get_suffix(const char *uri, UriSuffixBuffer &buffer);
+uri_get_suffix(const char *uri, UriSuffixBuffer &buffer) noexcept;
 
 /**
  * Returns true if this is a safe "local" URI:
@@ -71,7 +72,7 @@ uri_get_suffix(const char *uri, UriSuffixBuffer &buffer);
  */
 gcc_pure
 bool
-uri_safe_local(const char *uri);
+uri_safe_local(const char *uri) noexcept;
 
 /**
  * Removes HTTP username and password from the URI.  This may be
@@ -81,7 +82,7 @@ uri_safe_local(const char *uri);
  */
 gcc_pure
 std::string
-uri_remove_auth(const char *uri);
+uri_remove_auth(const char *uri) noexcept;
 
 /**
  * Check whether #child specifies a resource "inside" the directory
@@ -90,11 +91,11 @@ uri_remove_auth(const char *uri);
  */
 gcc_pure gcc_nonnull_all
 bool
-uri_is_child(const char *parent, const char *child);
+uri_is_child(const char *parent, const char *child) noexcept;
 
 gcc_pure gcc_nonnull_all
 bool
-uri_is_child_or_same(const char *parent, const char *child);
+uri_is_child_or_same(const char *parent, const char *child) noexcept;
 
 /**
  * Translate the given URI in the context of #base.  For example,
@@ -102,6 +103,6 @@ uri_is_child_or_same(const char *parent, const char *child);
  */
 gcc_pure
 std::string
-uri_apply_base(const std::string &uri, const std::string &base);
+uri_apply_base(const std::string &uri, const std::string &base) noexcept;
 
 #endif
diff --git a/src/util/WStringAPI.hxx b/src/util/WStringAPI.hxx
index 1feaf78c6..f69aaf6d1 100644
--- a/src/util/WStringAPI.hxx
+++ b/src/util/WStringAPI.hxx
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2015 Max Kellermann <max.kellermann@gmail.com>
+ * Copyright (C) 2010-2017 Max Kellermann <max.kellermann@gmail.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,70 +36,70 @@
 
 gcc_pure gcc_nonnull_all
 static inline size_t
-StringLength(const wchar_t *p)
+StringLength(const wchar_t *p) noexcept
 {
 	return wcslen(p);
 }
 
 gcc_pure gcc_nonnull_all
 static inline const wchar_t *
-StringFind(const wchar_t *haystack, const wchar_t *needle)
+StringFind(const wchar_t *haystack, const wchar_t *needle) noexcept
 {
 	return wcsstr(haystack, needle);
 }
 
 gcc_pure gcc_nonnull_all
 static inline const wchar_t *
-StringFind(const wchar_t *haystack, wchar_t needle, size_t size)
+StringFind(const wchar_t *haystack, wchar_t needle, size_t size) noexcept
 {
 	return wmemchr(haystack, needle, size);
 }
 
 gcc_pure gcc_nonnull_all
 static inline wchar_t *
-StringFind(wchar_t *haystack, wchar_t needle, size_t size)
+StringFind(wchar_t *haystack, wchar_t needle, size_t size) noexcept
 {
 	return wmemchr(haystack, needle, size);
 }
 
 gcc_pure gcc_nonnull_all
 static inline const wchar_t *
-StringFind(const wchar_t *haystack, wchar_t needle)
+StringFind(const wchar_t *haystack, wchar_t needle) noexcept
 {
 	return wcschr(haystack, needle);
 }
 
 gcc_pure gcc_nonnull_all
 static inline wchar_t *
-StringFind(wchar_t *haystack, wchar_t needle)
+StringFind(wchar_t *haystack, wchar_t needle) noexcept
 {
 	return wcschr(haystack, needle);
 }
 
 gcc_pure gcc_nonnull_all
 static inline const wchar_t *
-StringFindLast(const wchar_t *haystack, wchar_t needle)
+StringFindLast(const wchar_t *haystack, wchar_t needle) noexcept
 {
 	return wcsrchr(haystack, needle);
 }
 
 gcc_pure gcc_nonnull_all
 static inline wchar_t *
-StringFindLast(wchar_t *haystack, wchar_t needle)
+StringFindLast(wchar_t *haystack, wchar_t needle) noexcept
 {
 	return wcsrchr(haystack, needle);
 }
 
 gcc_nonnull_all
 static inline void
-UnsafeCopyString(wchar_t *dest, const wchar_t *src)
+UnsafeCopyString(wchar_t *dest, const wchar_t *src) noexcept
 {
 	wcscpy(dest, src);
 }
 
 gcc_nonnull_all
 static inline wchar_t *
-UnsafeCopyStringP(wchar_t *dest, const wchar_t *src)
+UnsafeCopyStringP(wchar_t *dest, const wchar_t *src) noexcept
 {
 #if defined(WIN32) || defined(__BIONIC__) || defined(__OpenBSD__) || \
 	defined(__NetBSD__)
@@ -119,7 +119,7 @@ UnsafeCopyStringP(wchar_t *dest, const wchar_t *src)
  */
 gcc_pure gcc_nonnull_all
 static inline bool
-StringIsEqual(const wchar_t *str1, const wchar_t *str2)
+StringIsEqual(const wchar_t *str1, const wchar_t *str2) noexcept
 {
 	return wcscmp(str1, str2) == 0;
 }
@@ -129,7 +129,7 @@ StringIsEqual(const wchar_t *str1, const wchar_t *str2)
  */
 gcc_pure gcc_nonnull_all
 static inline bool
-StringIsEqual(const wchar_t *a, const wchar_t *b, size_t length)
+StringIsEqual(const wchar_t *a, const wchar_t *b, size_t length) noexcept
 {
 	return wcsncmp(a, b, length) == 0;
 }
diff --git a/src/util/WStringCompare.cxx b/src/util/WStringCompare.cxx
index 1ffdb82c3..c030d84ac 100644
--- a/src/util/WStringCompare.cxx
+++ b/src/util/WStringCompare.cxx
@@ -24,14 +24,14 @@
 #include <string.h>
 
 bool
-StringStartsWith(const wchar_t *haystack, const wchar_t *needle)
+StringStartsWith(const wchar_t *haystack, const wchar_t *needle) noexcept
 {
 	const size_t length = StringLength(needle);
 	return StringIsEqual(haystack, needle, length);
 }
 
 bool
-StringEndsWith(const wchar_t *haystack, const wchar_t *needle)
+StringEndsWith(const wchar_t *haystack, const wchar_t *needle) noexcept
 {
 	const size_t haystack_length = StringLength(haystack);
 	const size_t needle_length = StringLength(needle);
@@ -41,7 +41,7 @@ StringEndsWith(const wchar_t *haystack, const wchar_t *needle)
 }
 
 const wchar_t *
-StringAfterPrefix(const wchar_t *string, const wchar_t *prefix)
+StringAfterPrefix(const wchar_t *string, const wchar_t *prefix) noexcept
 {
 #if !CLANG_CHECK_VERSION(3,6)
 	/* disabled on clang due to -Wtautological-pointer-compare */
@@ -56,7 +56,7 @@ StringAfterPrefix(const wchar_t *string, const wchar_t *prefix)
 }
 
 const wchar_t *
-FindStringSuffix(const wchar_t *p, const wchar_t *suffix)
+FindStringSuffix(const wchar_t *p, const wchar_t *suffix) noexcept
 {
 	const size_t p_length = StringLength(p);
 	const size_t suffix_length = StringLength(suffix);
diff --git a/src/util/WStringCompare.hxx b/src/util/WStringCompare.hxx
index ce5d3163d..03bb19794 100644
--- a/src/util/WStringCompare.hxx
+++ b/src/util/WStringCompare.hxx
@@ -42,20 +42,20 @@ StringIsEmpty(const wchar_t *string)
 
 gcc_pure
 bool
-StringStartsWith(const wchar_t *haystack, const wchar_t *needle);
+StringStartsWith(const wchar_t *haystack, const wchar_t *needle) noexcept;
 
 gcc_pure
 bool
-StringEndsWith(const wchar_t *haystack, const wchar_t *needle);
+StringEndsWith(const wchar_t *haystack, const wchar_t *needle) noexcept;
 
 /**
  * Returns the portion of the string after a prefix.  If the string
  * does not begin with the specified prefix, this function returns
  * nullptr.
  */
-gcc_nonnull_all
+gcc_pure gcc_nonnull_all
 const wchar_t *
-StringAfterPrefix(const wchar_t *string, const wchar_t *prefix);
+StringAfterPrefix(const wchar_t *string, const wchar_t *prefix) noexcept;
 
 /**
  * Check if the given string ends with the specified suffix.  If yes,
@@ -63,6 +63,6 @@ StringAfterPrefix(const wchar_t *string, const wchar_t *prefix);
  */
 gcc_pure
 const wchar_t *
-FindStringSuffix(const wchar_t *p, const wchar_t *suffix);
+FindStringSuffix(const wchar_t *p, const wchar_t *suffix) noexcept;
 
 #endif
diff --git a/test/dump_rva2.cxx b/test/dump_rva2.cxx
index 3765ebfdf..6a90e5b41 100644
--- a/test/dump_rva2.cxx
+++ b/test/dump_rva2.cxx
@@ -40,7 +40,7 @@
 
 const char *
 config_get_string(gcc_unused enum ConfigOption option,
-		  const char *default_value)
+		  const char *default_value) noexcept
 {
 	return default_value;
 }
diff --git a/test/read_mixer.cxx b/test/read_mixer.cxx
index 575894cee..4c7efabe3 100644
--- a/test/read_mixer.cxx
+++ b/test/read_mixer.cxx
@@ -33,7 +33,7 @@
 #include <stdlib.h>
 
 const FilterPlugin *
-filter_plugin_by_name(gcc_unused const char *name)
+filter_plugin_by_name(gcc_unused const char *name) noexcept
 {
 	assert(false);
 	return NULL;
diff --git a/test/run_output.cxx b/test/run_output.cxx
index bf3c31205..8af46211b 100644
--- a/test/run_output.cxx
+++ b/test/run_output.cxx
@@ -55,7 +55,7 @@ public:
 };
 
 const FilterPlugin *
-filter_plugin_by_name(gcc_unused const char *name)
+filter_plugin_by_name(gcc_unused const char *name) noexcept
 {
 	assert(false);
 	return NULL;
diff --git a/test/test_rewind.cxx b/test/test_rewind.cxx
index ef417de34..ac23d598a 100644
--- a/test/test_rewind.cxx
+++ b/test/test_rewind.cxx
@@ -32,7 +32,7 @@ public:
 	}
 
 	/* virtual methods from InputStream */
-	bool IsEOF() override {
+	bool IsEOF() noexcept override {
 		return remaining == 0;
 	}
 
diff --git a/test/test_translate_song.cxx b/test/test_translate_song.cxx
index 698218029..3bba65afa 100644
--- a/test/test_translate_song.cxx
+++ b/test/test_translate_song.cxx
@@ -32,7 +32,7 @@ Log(const Domain &domain, gcc_unused LogLevel level, const char *msg)
 }
 
 bool
-uri_supported_scheme(const char *uri)
+uri_supported_scheme(const char *uri) noexcept
 {
 	return strncmp(uri, "http://", 7) == 0;
 }
@@ -130,13 +130,13 @@ DetachedSong::LoadFile(Path path)
 }
 
 const Database *
-Client::GetDatabase() const
+Client::GetDatabase() const noexcept
 {
 	return reinterpret_cast<const Database *>(this);
 }
 
 const Storage *
-Client::GetStorage() const
+Client::GetStorage() const noexcept
 {
 	return ::storage;
 }