*: remove "pure" and "const" attributes from throwing functions

The "pure" and "const" attributes are not so well-defined, and a
recent clang version implements an optimization which pushes the
definition's boundary beyond what I believed it was.  clang now
assumes that functions declared "pure" cannot throw exceptions, even
if they lack the "noexcept" specification.

When compiled with this new clang version, MPD will crash randomly if
an exception happens to get thrown by such as "pure" function
(https://github.com/MusicPlayerDaemon/MPD/issues/41).

This commit removes all such misplaced "pure" and "const" attributes,
closing #41.
This commit is contained in:
Max Kellermann 2017-05-08 14:48:58 +02:00
parent 71f0ed8b74
commit 788e3b31e1
27 changed files with 8 additions and 61 deletions

1
NEWS
View File

@ -1,6 +1,7 @@
ver 0.20.7 (not yet released)
* database
- simple: fix false positive directory loop detection with NFS
* fix random crashes when compiled with clang
ver 0.20.6 (2017/03/10)
* input

View File

@ -25,8 +25,6 @@
#ifndef MPD_AUDIO_PARSER_HXX
#define MPD_AUDIO_PARSER_HXX
#include "Compiler.h"
struct AudioFormat;
/**
@ -38,7 +36,6 @@ struct AudioFormat;
* @param src the input string
* @param mask if true, then "*" is allowed for any number of items
*/
gcc_pure
AudioFormat
ParseAudioFormat(const char *src, bool mask);

View File

@ -117,7 +117,6 @@ struct Instance final
* DatabaseError if this MPD configuration has no database (no
* music_directory was configured).
*/
gcc_pure
const Database &GetDatabaseOrThrow() const;
#endif

View File

@ -130,7 +130,6 @@ struct Config {
ReplayGainConfig replay_gain;
};
gcc_const
static Config
LoadConfig()
{

View File

@ -200,7 +200,6 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
*/
const Database *GetDatabase() const;
gcc_pure
const Database &GetDatabaseOrThrow() const;
/**

View File

@ -49,7 +49,6 @@ static std::map<std::string, unsigned> permission_passwords;
static unsigned permission_default;
gcc_pure
static unsigned
ParsePermission(const char *p)
{

View File

@ -42,7 +42,6 @@ ToString(ReplayGainMode mode) noexcept;
* Parse a string to a #ReplayGainMode. Throws std::runtime_error on
* error.
*/
gcc_pure
ReplayGainMode
FromString(const char *s);

View File

@ -57,7 +57,6 @@ locate_parse_type(const char *str) noexcept
return tag_name_parse_i(str);
}
gcc_pure
static AllocatedString<>
ImportString(const char *p, bool fold_case)
{

View File

@ -191,7 +191,6 @@ public:
/**
* Wrapper for Instance::GetDatabaseOrThrow().
*/
gcc_pure
const Database &GetDatabaseOrThrow() const;
gcc_pure

View File

@ -129,7 +129,6 @@ ConfigBlock::GetBlockValue(const char *name, unsigned default_value) const
return bp->GetUnsignedValue();
}
gcc_pure
bool
ConfigBlock::GetBlockValue(const char *name, bool default_value) const
{

View File

@ -44,13 +44,10 @@ struct BlockParam {
BlockParam(const char *_name, const char *_value, int _line=-1)
:name(_name), value(_value), line(_line), used(false) {}
gcc_pure
int GetIntValue() const;
gcc_pure
unsigned GetUnsignedValue() const;
gcc_pure
bool GetBoolValue() const;
};
@ -116,13 +113,10 @@ struct ConfigBlock {
AllocatedPath GetPath(const char *name,
const char *default_value=nullptr) const;
gcc_pure
int GetBlockValue(const char *name, int default_value) const;
gcc_pure
unsigned GetBlockValue(const char *name, unsigned default_value) const;
gcc_pure
bool GetBlockValue(const char *name, bool default_value) const;
};

View File

@ -61,18 +61,9 @@ config_get_block(enum ConfigBlockOption option) noexcept;
* @param key the attribute name
* @param value the expected attribute value
*/
gcc_pure
const ConfigBlock *
config_find_block(ConfigBlockOption option, const char *key, const char *value);
/* Note on gcc_pure: Some of the functions declared pure are not
really pure in strict sense. They have side effect such that they
validate parameter's value and signal an error if it's invalid.
However, if the argument was already validated or we don't care
about the argument at all, this may be ignored so in the end, we
should be fine with calling those functions pure. */
gcc_pure
const char *
config_get_string(enum ConfigOption option,
const char *default_value=nullptr) noexcept;
@ -87,11 +78,9 @@ config_get_string(enum ConfigOption option,
AllocatedPath
config_get_path(enum ConfigOption option);
gcc_pure
unsigned
config_get_unsigned(enum ConfigOption option, unsigned default_value);
gcc_pure
static inline std::chrono::steady_clock::duration
config_get_unsigned(ConfigOption option,
std::chrono::steady_clock::duration default_value)
@ -101,11 +90,9 @@ config_get_unsigned(ConfigOption option,
return std::chrono::steady_clock::duration(u);
}
gcc_pure
unsigned
config_get_positive(enum ConfigOption option, unsigned default_value);
gcc_pure
static inline std::chrono::steady_clock::duration
config_get_positive(ConfigOption option,
std::chrono::steady_clock::duration default_value)
@ -115,7 +102,6 @@ config_get_positive(ConfigOption option,
return std::chrono::steady_clock::duration(u);
}
gcc_pure
bool config_get_bool(enum ConfigOption option, bool default_value);
#endif

View File

@ -71,7 +71,6 @@ struct ConfigParam {
*
* Throws #std::runtime_error on error.
*/
gcc_pure
AllocatedPath GetPath() const;
};

View File

@ -31,7 +31,6 @@ class DetachedSong;
* "Detach" the #Song object, i.e. convert it to a #DetachedSong
* instance.
*/
gcc_pure
DetachedSong
DatabaseDetachSong(const Storage &storage, const LightSong &song);

View File

@ -159,7 +159,7 @@ public:
* Convert a UTF-8 C string to an #AllocatedPath instance.
* Throws a std::runtime_error on error.
*/
gcc_pure gcc_nonnull_all
gcc_nonnull_all
static AllocatedPath FromUTF8Throw(const char *path_utf8);
/**

View File

@ -49,7 +49,7 @@ DeinitFSCharset() noexcept;
*
* Throws std::runtime_error on error.
*/
gcc_pure gcc_nonnull_all
gcc_nonnull_all
PathTraitsUTF8::string
PathToUTF8(PathTraitsFS::const_pointer_type path_fs);
@ -58,7 +58,7 @@ PathToUTF8(PathTraitsFS::const_pointer_type path_fs);
*
* Throws std::runtime_error on error.
*/
gcc_pure gcc_nonnull_all
gcc_nonnull_all
PathTraitsFS::string
PathFromUTF8(PathTraitsUTF8::const_pointer_type path_utf8);

View File

@ -65,7 +65,6 @@ public:
* it). Throws std::runtime_error if not enough data is
* available.
*/
gcc_pure
void *ReadFull(size_t size);
void Consume(size_t n) {

View File

@ -86,7 +86,6 @@ public:
void Close();
gcc_pure
FileInfo GetFileInfo() const;
gcc_pure

View File

@ -38,7 +38,7 @@ gcc_pure gcc_nonnull_all
int
IcuCollate(const char *a, const char *b) noexcept;
gcc_pure gcc_nonnull_all
gcc_nonnull_all
AllocatedString<char>
IcuCaseFold(const char *src);

View File

@ -81,7 +81,7 @@ public:
*
* Throws std::runtime_error on error.
*/
gcc_pure gcc_nonnull_all
gcc_nonnull_all
AllocatedString<char> ToUTF8(const char *s) const;
/**
@ -89,7 +89,7 @@ public:
*
* Throws std::runtime_error on error.
*/
gcc_pure gcc_nonnull_all
gcc_nonnull_all
AllocatedString<char> FromUTF8(const char *s) const;
};

View File

@ -68,7 +68,6 @@ struct AudioOutputWrapper {
return t.Delay();
}
gcc_pure
static void SendTag(AudioOutput *ao, const Tag &tag) {
T &t = Cast(*ao);
t.SendTag(tag);
@ -89,7 +88,6 @@ struct AudioOutputWrapper {
t.Cancel();
}
gcc_pure
static bool Pause(AudioOutput *ao) {
T &t = Cast(*ao);
return t.Pause();

View File

@ -74,7 +74,6 @@ static int shout_init_count;
static constexpr Domain shout_output_domain("shout_output");
gcc_pure
static const char *
require_block_string(const ConfigBlock &block, const char *name)
{

View File

@ -21,7 +21,6 @@
#define MPD_PROTOCOL_ARGPARSER_HXX
#include "check.h"
#include "Compiler.h"
#include <limits>
@ -30,15 +29,12 @@
class SongTime;
class SignedSongTime;
gcc_pure
uint32_t
ParseCommandArgU32(const char *s);
gcc_pure
int
ParseCommandArgInt(const char *s, int min_value, int max_value);
gcc_pure
int
ParseCommandArgInt(const char *s);
@ -55,31 +51,24 @@ struct RangeArg {
}
};
gcc_pure
RangeArg
ParseCommandArgRange(const char *s);
gcc_pure
unsigned
ParseCommandArgUnsigned(const char *s, unsigned max_value);
gcc_pure
unsigned
ParseCommandArgUnsigned(const char *s);
gcc_pure
bool
ParseCommandArgBool(const char *s);
gcc_pure
float
ParseCommandArgFloat(const char *s);
gcc_pure
SongTime
ParseCommandArgSongTime(const char *s);
gcc_pure
SignedSongTime
ParseCommandArgSignedSongTime(const char *s);

View File

@ -21,7 +21,6 @@
#define MPD_SONG_STICKER_HXX
#include "Match.hxx"
#include "Compiler.h"
#include <string>
@ -34,7 +33,6 @@ class Database;
*
* Throws #SqliteError on error.
*/
gcc_pure
std::string
sticker_song_get_value(const LightSong &song, const char *name);

View File

@ -71,7 +71,6 @@ private:
AllocatedPath MapFSOrThrow(const char *uri_utf8) const;
};
gcc_pure
static StorageFileInfo
Stat(Path path, bool follow)
{

View File

@ -28,6 +28,7 @@
*/
#include "TimeParser.hxx"
#include "Compiler.h"
#include <stdexcept>

View File

@ -30,8 +30,6 @@
#ifndef TIME_PARSER_HXX
#define TIME_PARSER_HXX
#include "Compiler.h"
#include <chrono>
/**
@ -39,7 +37,6 @@
*
* Throws std::runtime_error on error.
*/
gcc_pure
std::chrono::system_clock::time_point
ParseTimePoint(const char *s, const char *format);