*: 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:
parent
71f0ed8b74
commit
788e3b31e1
1
NEWS
1
NEWS
|
@ -1,6 +1,7 @@
|
|||
ver 0.20.7 (not yet released)
|
||||
* database
|
||||
- simple: fix false positive directory loop detection with NFS
|
||||
* fix random crashes when compiled with clang
|
||||
|
||||
ver 0.20.6 (2017/03/10)
|
||||
* input
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -130,7 +130,6 @@ struct Config {
|
|||
ReplayGainConfig replay_gain;
|
||||
};
|
||||
|
||||
gcc_const
|
||||
static Config
|
||||
LoadConfig()
|
||||
{
|
||||
|
|
|
@ -200,7 +200,6 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
|
|||
*/
|
||||
const Database *GetDatabase() const;
|
||||
|
||||
gcc_pure
|
||||
const Database &GetDatabaseOrThrow() const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -49,7 +49,6 @@ static std::map<std::string, unsigned> permission_passwords;
|
|||
|
||||
static unsigned permission_default;
|
||||
|
||||
gcc_pure
|
||||
static unsigned
|
||||
ParsePermission(const char *p)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -191,7 +191,6 @@ public:
|
|||
/**
|
||||
* Wrapper for Instance::GetDatabaseOrThrow().
|
||||
*/
|
||||
gcc_pure
|
||||
const Database &GetDatabaseOrThrow() const;
|
||||
|
||||
gcc_pure
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -71,7 +71,6 @@ struct ConfigParam {
|
|||
*
|
||||
* Throws #std::runtime_error on error.
|
||||
*/
|
||||
gcc_pure
|
||||
AllocatedPath GetPath() const;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -86,7 +86,6 @@ public:
|
|||
|
||||
void Close();
|
||||
|
||||
gcc_pure
|
||||
FileInfo GetFileInfo() const;
|
||||
|
||||
gcc_pure
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@ private:
|
|||
AllocatedPath MapFSOrThrow(const char *uri_utf8) const;
|
||||
};
|
||||
|
||||
gcc_pure
|
||||
static StorageFileInfo
|
||||
Stat(Path path, bool follow)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
*/
|
||||
|
||||
#include "TimeParser.hxx"
|
||||
#include "Compiler.h"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue