From f6dc7e78f052ff09e141f63ef8bd9b5c224cef1f Mon Sep 17 00:00:00 2001 From: John Bowler Date: Sat, 14 Sep 2024 19:13:13 -0700 Subject: [PATCH] Use standard C attributes ISO have recently standardized a way of defining attributes based on the ISO-C++ syntax standardised in 2011. This allows removal of the existing compiler-specific hacks as well as compatibility with C++. The latter is important for attributes used in the header files which declare the libpng API (png.h and descendants.) This also extends the attribute handling to any compliant C compiler, not just the three with compiler specific support in the prior code. The fix also enables removal of the highly idiosyncratic use of specific comments to indicate "fall through" in case statements; the concept is now supported by the [[fallthrough]] attribute. The changes include checks to ensure that the attribute syntax is supported by the compiler and that the specific attributes are also supported. The changes are detailed in these commits: commit 51b6189d3c21711bbd95538883c0aca3bb61dc67 commit 8942be90442e7a59260b01e49cdb4a3bc50c80b8 Signed-off-by: John Bowler --- contrib/libtests/pngstest.c | 26 +++- contrib/libtests/pngunknown.c | 15 ++- contrib/libtests/pngvalid.c | 15 ++- contrib/tools/pngfix.c | 14 +- pngconf.h | 240 +++++++++++++++++++--------------- pngerror.c | 13 +- pngpriv.h | 60 +++++---- pngread.c | 10 +- pngrtran.c | 4 +- pngrutil.c | 4 +- pngwrite.c | 6 +- 11 files changed, 242 insertions(+), 165 deletions(-) diff --git a/contrib/libtests/pngstest.c b/contrib/libtests/pngstest.c index 0f9b16cb53..56c5b4a196 100644 --- a/contrib/libtests/pngstest.c +++ b/contrib/libtests/pngstest.c @@ -1,7 +1,7 @@ /* pngstest.c * * Copyright (c) 2021-2024 Cosmin Truta - * Copyright (c) 2013-2017 John Cunningham Bowler + * Copyright (c) 2013-2017,2024 John Cunningham Bowler * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -46,6 +46,18 @@ #ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* Else nothing can be done */ #include "../tools/sRGB.h" +/* This is a sanity check on PNG_HAS_ATTRIBUTE. + */ +#if PNG_HAS_ATTRIBUTE(__unknown__::attribute) +# error PNG_HAS_ATTRIBUTE is not working correctly +#endif + +#if PNG_HAS_ATTRIBUTE(fallthrough) +# define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#else +# define FALLTRHOUGH /* FALLTHROUGH */ +#endif + /* KNOWN ISSUES * * These defines switch on alternate algorithms for format conversions to match @@ -2885,13 +2897,13 @@ compare_two_images(Image *a, Image *b, int via_linear, { case 4: if (pua[btoa[3]] != pub[3]) break; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ case 3: if (pua[btoa[2]] != pub[2]) break; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ case 2: if (pua[btoa[1]] != pub[1]) break; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ case 1: if (pua[btoa[0]] != pub[0]) break; if (alpha_added != 4 && pub[alpha_added] != 65535) break; @@ -2907,13 +2919,13 @@ compare_two_images(Image *a, Image *b, int via_linear, { case 4: if (psa[btoa[3]] != psb[3]) break; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ case 3: if (psa[btoa[2]] != psb[2]) break; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ case 2: if (psa[btoa[1]] != psb[1]) break; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ case 1: if (psa[btoa[0]] != psb[0]) break; if (alpha_added != 4 && psb[alpha_added] != 255) break; diff --git a/contrib/libtests/pngunknown.c b/contrib/libtests/pngunknown.c index 9528ab9f09..0f5105033a 100644 --- a/contrib/libtests/pngunknown.c +++ b/contrib/libtests/pngunknown.c @@ -2,6 +2,7 @@ * * Copyright (c) 2021-2024 Cosmin Truta * Copyright (c) 2015,2017 Glenn Randers-Pehrson + * Copyright (c) 2015-2016,2024 John Bowler * Written by John Cunningham Bowler * * This code is released under the libpng license. @@ -38,6 +39,12 @@ # define SKIP 0 #endif +#if PNG_HAS_ATTRIBUTE(fallthrough) +# define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#else +# define FALLTRHOUGH /* FALLTHROUGH */ +#endif + /* Since this program tests the ability to change the unknown chunk handling * these must be defined: @@ -433,7 +440,7 @@ clean_display(display *d) } } -PNG_FUNCTION(void, display_exit, (display *d), static PNG_NORETURN) +PNG_FUNCTION(void, display_exit, (display *d), PNG_NORETURN static) { ++(d->error_count); @@ -457,7 +464,7 @@ display_rc(const display *d, int strict) /* libpng error and warning callbacks */ PNG_FUNCTION(void, (PNGCBAPI error), (png_structp png_ptr, const char *message), - static PNG_NORETURN) + PNG_NORETURN static) { display *d = (display*)png_get_error_ptr(png_ptr); @@ -623,7 +630,7 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT) ++(d->error_count); break; } - /* FALLTHROUGH */ /* (safe) */ + FALLTHROUGH; /* (safe) */ /* FALLTHROUGH */ case PNG_HANDLE_CHUNK_ALWAYS: break; } @@ -1104,7 +1111,7 @@ static const char *standard_tests[] = NULL /*end*/ }; -static PNG_NORETURN void +PNG_NORETURN static void usage(const char *program, const char *reason) { fprintf(stderr, "pngunknown: %s: usage:\n %s [--strict] " diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c index d7d7a2ef77..2d607c4fc9 100644 --- a/contrib/libtests/pngvalid.c +++ b/contrib/libtests/pngvalid.c @@ -1,7 +1,7 @@ /* pngvalid.c - validate libpng by constructing then reading png files. * * Copyright (c) 2021-2024 Cosmin Truta - * Copyright (c) 2014-2017 John Cunningham Bowler + * Copyright (c) 2014-2017,2024 John Cunningham Bowler * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -156,6 +156,13 @@ typedef png_byte *png_const_bytep; # endif #endif +#if PNG_HAS_ATTRIBUTE(fallthrough) +# define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#else +# define FALLTRHOUGH /* FALLTHROUGH */ +#endif + + /***************************** EXCEPTION HANDLING *****************************/ #ifdef PNG_FREESTANDING_TESTS # include @@ -6589,12 +6596,12 @@ transform_info_imp(transform_display *dp, png_structp pp, png_infop pi) { case PNG_COLOR_TYPE_PALETTE: if (dp->output_bit_depth > 8) goto error; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ case PNG_COLOR_TYPE_GRAY: if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 || dp->output_bit_depth == 4) break; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ default: if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16) break; @@ -10001,7 +10008,7 @@ gamma_component_validate(const char *name, const validate_info *vi, use_background = (alpha >= 0 && alpha < 1); # endif # ifdef PNG_READ_ALPHA_MODE_SUPPORTED - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ case ALPHA_MODE_OFFSET + PNG_ALPHA_STANDARD: case ALPHA_MODE_OFFSET + PNG_ALPHA_BROKEN: case ALPHA_MODE_OFFSET + PNG_ALPHA_OPTIMIZED: diff --git a/contrib/tools/pngfix.c b/contrib/tools/pngfix.c index e4a5d5cf39..411010dbd5 100644 --- a/contrib/tools/pngfix.c +++ b/contrib/tools/pngfix.c @@ -31,6 +31,12 @@ # include "../../png.h" #endif +#if PNG_HAS_ATTRIBUTE(fallthrough) +# define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#else +# define FALLTRHOUGH /* FALLTHROUGH */ +#endif + #ifdef PNG_SETJMP_SUPPORTED #include @@ -2399,7 +2405,7 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes) endrc = ZLIB_TOO_FAR_BACK; break; } - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ default: zlib_message(zlib, 0/*stream error*/); @@ -2553,7 +2559,7 @@ zlib_run(struct zlib *zlib) list->lengths[i] -= zlib->extra_bytes; list->count = i+1; zlib->idat->idat_list_tail = list; - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ default: return rc; @@ -2656,7 +2662,7 @@ zlib_check(struct file *file, png_uint_32 offset) /* Truncated stream; unrecoverable, gets converted to ZLIB_FATAL */ zlib.z.msg = PNGZ_MSG_CAST("[truncated]"); zlib_message(&zlib, 0/*expected*/); - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ default: /* Unrecoverable error; skip the chunk; a zlib_message has already @@ -3324,7 +3330,7 @@ read_callback(png_structp png_ptr, png_bytep buffer, size_t count) if (file->state != STATE_IDAT && length > 0) setpos(chunk); } - /* FALLTHROUGH */ + FALLTHROUGH; /* FALLTHROUGH */ default: assert(chunk != NULL); diff --git a/pngconf.h b/pngconf.h index df9e099563..6e27dabd72 100644 --- a/pngconf.h +++ b/pngconf.h @@ -298,7 +298,7 @@ #ifndef PNG_EXPORTA # define PNG_EXPORTA(ordinal, type, name, args, attributes) \ PNG_FUNCTION(PNG_EXPORT_TYPE(type), (PNGAPI name), args, \ - PNG_LINKAGE_API attributes) + attributes PNG_LINKAGE_API) #endif /* ANSI-C (C90) does not permit a macro to be invoked with an empty argument, @@ -318,130 +318,166 @@ # define PNG_CALLBACK(type, name, args) type (PNGCBAPI name) args #endif -/* Support for compiler specific function attributes. These are used - * so that where compiler support is available incorrect use of API - * functions in png.h will generate compiler warnings. +/* "Pedantic" warnings. These are warnings which are about code which does not + * conform to style guidelines issued by one or other authority but which is + * still completely compliant with the C standards. * - * Added at libpng-1.2.41. + * Some (but not all) of these can be disabled by definining + * PNG_NO_PEDANTIC_WARNINGS when application code is compiled against pngconf.h + * All can be removed by PNG_NO_ATTRIBUTES + * + * "Informational" notations. These are notations which make statements about + * how the the libpng code. They cannot be disabled if the compiler supports + * them. + * + * Both these classes of notation are implemented using the "attribute" syntax + * defined along with the ISO-C23 standard. The test, however, is for the + * standard defined "attribute testing" mechanism. This is now supported in the + * common compilers, gcc clang and Microsoft VisualC in a consistent way. + * + * If necessary users of older compiles may define the individual macros to + * preempt the standard definition however it is much better to upgrade to a + * compiler with the ISO standard support! + * + * [[changed in libpng 1.8 to use the standard notation]] */ +#ifndef PNG_NO_ATTRIBUTES +# ifndef PNG_ATTRIBUTES_SUPPORTED +# define PNG_ATTRIBUTES_SUPPORTED +# endif +#endif + #ifndef PNG_NO_PEDANTIC_WARNINGS # ifndef PNG_PEDANTIC_WARNINGS_SUPPORTED # define PNG_PEDANTIC_WARNINGS_SUPPORTED # endif #endif -#ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED - /* Support for compiler specific function attributes. These are used - * so that where compiler support is available, incorrect use of API - * functions in png.h will generate compiler warnings. Added at libpng - * version 1.2.41. Disabling these removes the warnings but may also produce - * less efficient code. - */ -# if defined(__clang__) && defined(__has_attribute) - /* Clang defines both __clang__ and __GNUC__. Check __clang__ first. */ -# if !defined(PNG_USE_RESULT) && __has_attribute(__warn_unused_result__) -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# if !defined(PNG_NORETURN) && __has_attribute(__noreturn__) -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# if !defined(PNG_ALLOCATED) && __has_attribute(__malloc__) -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# if !defined(PNG_DEPRECATED) && __has_attribute(__deprecated__) -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# if !defined(PNG_PRIVATE) -# ifdef __has_extension -# if __has_extension(attribute_unavailable_with_message) -# define PNG_PRIVATE __attribute__((__unavailable__(\ - "This function is not exported by libpng."))) -# endif -# endif -# endif -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif +/* IMPORTANT: the following produces a warning with GCC if used with an + * attribute which GCC does not support even though it is part of the standard + * therefore a test on __has_c_attribute(token) is used below to prevent such + * warnings. + * + * If the build system provides a definition of PNG_ATTRIBUTE it must also + * define PNG_HAS_ATTRIBUTE somehow (e.g. to the value 1) to get the + * attributes to be used. + */ +#ifndef PNG_ATTRIBUTE +# if defined(PNG_ATTRIBUTES_SUPPORTED) && defined(__has_c_attribute) +# define PNG_ATTRIBUTE(token) [/**/[token]/**/] +# ifndef PNG_HAS_ATTRIBUTE +# define PNG_HAS_ATTRIBUTE(token) __has_c_attribute(token) +# endif +# else +# define PNG_ATTRIBUTE(token) /*token*/ +# endif +#endif -# elif defined(__GNUC__) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT __attribute__((__warn_unused_result__)) -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __attribute__((__noreturn__)) -# endif -# if __GNUC__ >= 3 -# ifndef PNG_ALLOCATED -# define PNG_ALLOCATED __attribute__((__malloc__)) -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __attribute__((__deprecated__)) -# endif -# ifndef PNG_PRIVATE -# if 0 /* Doesn't work so we use deprecated instead*/ -# define PNG_PRIVATE \ - __attribute__((warning("This function is not exported by libpng."))) -# else -# define PNG_PRIVATE \ - __attribute__((__deprecated__)) -# endif -# endif -# if ((__GNUC__ > 3) || !defined(__GNUC_MINOR__) || (__GNUC_MINOR__ >= 1)) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif -# endif /* __GNUC__.__GNUC_MINOR__ > 3.0 */ -# endif /* __GNUC__ >= 3 */ - -# elif defined(_MSC_VER) && (_MSC_VER >= 1300) -# ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* not supported */ -# endif -# ifndef PNG_NORETURN -# define PNG_NORETURN __declspec(noreturn) -# endif -# ifndef PNG_ALLOCATED -# if (_MSC_VER >= 1400) -# define PNG_ALLOCATED __declspec(restrict) -# endif -# endif -# ifndef PNG_DEPRECATED -# define PNG_DEPRECATED __declspec(deprecated) -# endif -# ifndef PNG_PRIVATE -# define PNG_PRIVATE __declspec(deprecated) -# endif -# ifndef PNG_RESTRICT -# if (_MSC_VER >= 1400) -# define PNG_RESTRICT __restrict -# endif -# endif +#ifndef PNG_HAS_ATTRIBUTE +# define PNG_HAS_ATTRIBUTE(token) 0 + /* Do this to be safe: */ +# undef PNG_ATTRIBUTE +# define PNG_ATTRIBUTE(token) /*token*/ +#endif -# elif defined(__WATCOMC__) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif +#ifndef PNG_WARN +# ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_WARN(token) PNG_ATTRIBUTE(token) +# else +# define PNG_WARN(token) /*token*/ # endif -#endif /* PNG_PEDANTIC_WARNINGS */ +#endif -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED /* Use of this function is deprecated */ +/* Hence these notations (or attributes as that is how they are implemented). + * + * NOTE: use __token__ forms here because these identifiers might otherwise be + * #defined in the application code. This is an issue because the token is + * passed in a macro argument, normally __has_c_attribute and [[token]] would + * not expand the token (apparently). + * + * The [[deprecated]] warning is now forced on unless disabled by the user + * of libpng (-DPNG_WARN=). This is deliberate to encourage users to remove + * deprecated functionality before it is removed. + * + * __malloc__ is a GNU extension (not standardized, or not yet standardized.) + */ +#ifndef PNG_DEPRECATE +# if PNG_HAS_ATTRIBUTE(__deprecated__) +# define PNG_DEPRECATE(reason) PNG_ATTRIBUTE(__deprecated__(reason)) +# else +# define PNG_DEPRECATE(reason) /*deprecated*/ +# endif #endif + #ifndef PNG_USE_RESULT -# define PNG_USE_RESULT /* The result of this function must be checked */ +# if PNG_HAS_ATTRIBUTE(__nodiscard__) +# define PNG_USE_RESULT PNG_WARN(__nodiscard__) +# define PNG_NODISCARD(reason) PNG_WARN(__nodiscard__(reason)) +# else +# define PNG_USE_RESULT /*nodiscard*/ +# define PNG_NODISCARD(reason) /*nodiscard*/ +# endif #endif + #ifndef PNG_NORETURN -# define PNG_NORETURN /* This function does not return */ +# if PNG_HAS_ATTRIBUTE(__noreturn__) +# define PNG_NORETURN PNG_ATTRIBUTE(__noreturn__) +# else +# define PNG_NORETURN /*noreturn*/ +# endif #endif + +#ifndef PNG_MALLOCED /* added to PNG_ALLOCATED below */ +# if PNG_HAS_ATTRIBUTE(__gnu__::__malloc__) + /* This is informational: it tells the caller that the result is a freshly + * allocated pointer. See the GNU documentation. + */ +# define PNG_MALLOCED PNG_ATTRIBUTE(__gnu__::__malloc__) +# else +# define PNG_MALLOCED /*allocated*/ +# endif +#endif + #ifndef PNG_ALLOCATED -# define PNG_ALLOCATED /* The result of the function is new memory */ +# define PNG_ALLOCATED PNG_NODISCARD(\ + "The pointer to allocated memory returned by this function is ignored.")\ + PNG_MALLOCED +#endif + +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED PNG_DEPRECATE(\ + "This function will be removed in the next major release of libpng.") #endif + #ifndef PNG_PRIVATE -# define PNG_PRIVATE /* This is a private libpng function */ + /* This warns that the build of the application code will fail to link: + */ +# define PNG_PRIVATE PNG_DEPRECATE(\ + "This function is not exported by this build of libpng.") #endif + +/* C99 'restrict' is not an attribute, it's just a type qualified like const + * or volatile. PNG_RESTRICT is defined to either 'restrict' (if available) + * or empty. Note that some environments, like 'configure' ones, work out + * a #define for 'restrict' so the following might evaluated to something other + * than the keyword 'restrict' on C99. + */ +#if !defined(PNG_RESTRICT) && defined(__STDC_VERSION__) +# if __STDC_VERSION__ >= 199901L/*C99*/ +# define PNG_RESTRICT restrict +# endif +#endif + +/* This is the case if the app has included something like the configure + * config.h file: + */ +#if !defined(PNG_RESTRICT) && defined(restrict) +# define PNG_RESTRICT restrict +#endif + #ifndef PNG_RESTRICT -# define PNG_RESTRICT /* The C99 "restrict" feature */ +# define PNG_RESTRICT /*restrict*/ #endif #ifndef PNG_FP_EXPORT /* A floating point API. */ diff --git a/pngerror.c b/pngerror.c index aa0ae58e15..757a757315 100644 --- a/pngerror.c +++ b/pngerror.c @@ -19,9 +19,8 @@ #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) -static PNG_FUNCTION(void /* PRIVATE */, -png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN); +PNG_FUNCTION(void, png_default_error,(png_const_structrp png_ptr, + png_const_charp error_message),PNG_NORETURN static); #ifdef PNG_WARNINGS_SUPPORTED static void /* PRIVATE */ @@ -163,7 +162,7 @@ png_format_number(png_const_charp start, png_charp end, int format, case PNG_NUMBER_FORMAT_02u: /* Expects at least 2 digits. */ mincount = 2; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case PNG_NUMBER_FORMAT_u: *--end = digits[number % 10]; @@ -173,7 +172,7 @@ png_format_number(png_const_charp start, png_charp end, int format, case PNG_NUMBER_FORMAT_02x: /* This format expects at least two digits */ mincount = 2; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case PNG_NUMBER_FORMAT_x: *--end = digits[number & 0xf]; @@ -707,9 +706,9 @@ png_free_jmpbuf(png_structrp png_ptr) * function is used by default, or if the program supplies NULL for the * error function pointer in png_set_error_fn(). */ -static PNG_FUNCTION(void /* PRIVATE */, +PNG_FUNCTION(void /* PRIVATE */, png_default_error,(png_const_structrp png_ptr, png_const_charp error_message), - PNG_NORETURN) + PNG_NORETURN static) { #ifdef PNG_CONSOLE_IO_SUPPORTED #ifdef PNG_ERROR_NUMBERS_SUPPORTED diff --git a/pngpriv.h b/pngpriv.h index 102ccbae2c..3b4ba36417 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -46,22 +46,6 @@ #define PNGLIB_BUILD /*libpng is being built, not used*/ -/* If HAVE_CONFIG_H is defined during the build then the build system must - * provide an appropriate "config.h" file on the include path. The header file - * must provide definitions as required below (search for "HAVE_CONFIG_H"); - * see configure.ac for more details of the requirements. The macro - * "PNG_NO_CONFIG_H" is provided for maintainers to test for dependencies on - * 'configure'; define this macro to prevent the configure build including the - * configure generated config.h. Libpng is expected to compile without *any* - * special build system support on a reasonably ANSI-C compliant system. - */ -#if defined(HAVE_CONFIG_H) && !defined(PNG_NO_CONFIG_H) -# include - - /* Pick up the definition of 'restrict' from config.h if it was read: */ -# define PNG_RESTRICT restrict -#endif - /* To support symbol prefixing it is necessary to know *before* including png.h * whether the fixed point (and maybe other) APIs are exported, because if they * are not internal definitions may be required. This is handled below just @@ -165,13 +149,12 @@ #ifndef PNG_INTERNAL_FUNCTION # define PNG_INTERNAL_FUNCTION(type, name, args, attributes)\ - PNG_LINKAGE_FUNCTION PNG_FUNCTION(type, name, args, PNG_EMPTY attributes) + PNG_FUNCTION(type, name, args, attributes PNG_LINKAGE_FUNCTION) #endif #ifndef PNG_INTERNAL_CALLBACK # define PNG_INTERNAL_CALLBACK(type, name, args, attributes)\ - PNG_LINKAGE_CALLBACK PNG_FUNCTION(type, (PNGCBAPI name), args,\ - PNG_EMPTY attributes) + PNG_FUNCTION(type, (PNGCBAPI name), args, attributes PNG_LINKAGE_CALLBACK) #endif /* If floating or fixed point APIs are disabled they may still be compiled @@ -247,16 +230,43 @@ # define PNG_MAX_MALLOC_64K #endif +#ifndef PNG_MAYBE_UNUSED + /* Unused formal parameter warnings can be silenced by using this macro + * to qualify the declaration, but see PNG_UNUSED below. + * macro. Note this is used in the #if code path where the parameter + * is not used. + */ +# if PNG_HAS_ATTRIBUTE(maybe_unused) +# define PNG_MAYBE_UNUSED PNG_ATTRIBUTE(maybe_unused) +# else +# define PNG_MAYBE_UNUSED /*maybe unused*/ +# endif +#endif + #ifndef PNG_UNUSED -/* Unused formal parameter warnings are silenced using the following macro - * which is expected to have no bad effects on performance (optimizing - * compilers will probably remove it entirely). Note that if you replace - * it with something other than whitespace, you must include the terminating - * semicolon. - */ + /* As a better alternative to the above use this macro in (at the end of) + * the #if code tree where the parameter is not used. Note that this macro + * includes a ";" if it is defined and the parameter must be a single token. + */ # define PNG_UNUSED(param) (void)param; #endif +#ifndef PNG_FALLTHROUGH + /* This notation is used immediately above a switch case label to indicate + * that the preceding code "falls through" to the next label. Some + * authorities regard this as a bad thing to do but libpng does it a lot. + * + * NOTE: this must be used in the form: + * + * PNG_FALLTHROUGH; + */ +# if PNG_HAS_ATTRIBUTE(fallthrough) +# define PNG_FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +# else +# define PNG_FALLTHROUGH /* FALLTHROUGH */ +# endif +#endif + /* Just a little check that someone hasn't tried to define something * contradictory. */ diff --git a/pngread.c b/pngread.c index 3ec5623a00..fab303ca13 100644 --- a/pngread.c +++ b/pngread.c @@ -1918,7 +1918,7 @@ png_create_colormap_entry(png_image_read_control *display, { case 4: entry[afirst ? 0 : 3] = (png_uint_16)alpha; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case 3: if (alpha < 65535) @@ -1940,7 +1940,7 @@ png_create_colormap_entry(png_image_read_control *display, case 2: entry[1 ^ afirst] = (png_uint_16)alpha; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case 1: if (alpha < 65535) @@ -1969,7 +1969,7 @@ png_create_colormap_entry(png_image_read_control *display, { case 4: entry[afirst ? 0 : 3] = (png_byte)alpha; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case 3: entry[afirst + (2 ^ bgr)] = (png_byte)blue; entry[afirst + 1] = (png_byte)green; @@ -1978,7 +1978,7 @@ png_create_colormap_entry(png_image_read_control *display, case 2: entry[1 ^ afirst] = (png_byte)alpha; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case 1: entry[afirst] = (png_byte)green; break; @@ -2898,7 +2898,7 @@ png_image_read_colormap(png_voidp argument) case P_sRGB: /* Change to 8-bit sRGB */ png_set_alpha_mode_fixed(png_ptr, PNG_ALPHA_PNG, PNG_GAMMA_sRGB); - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case P_FILE: if (png_ptr->bit_depth > 8) diff --git a/pngrtran.c b/pngrtran.c index e82e467bf5..b171bc047b 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -48,7 +48,7 @@ png_set_crc_action(png_structrp png_ptr, int crit_action, int ancil_action) case PNG_CRC_WARN_DISCARD: /* Not a valid action for critical data */ png_warning(png_ptr, "Can't discard critical data on CRC error"); - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case PNG_CRC_ERROR_QUIT: /* Error/quit */ case PNG_CRC_DEFAULT: @@ -1251,7 +1251,7 @@ png_init_rgb_transformations(png_structrp png_ptr) default: case 8: - /* FALLTHROUGH */ /* (Already 8 bits) */ + PNG_FALLTHROUGH; /* (Already 8 bits) */ /* FALLTHROUGH */ case 16: /* Already a full 16 bits */ diff --git a/pngrutil.c b/pngrutil.c index eacc88bd0b..f017ddef17 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -3104,7 +3104,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, case 2: png_ptr->user_chunk_cache_max = 1; png_chunk_benign_error(png_ptr, "no space in chunk cache"); - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case 1: /* NOTE: prior to 1.6.0 this case resulted in an unknown critical * chunk being skipped, now there will be a hard error below. @@ -3113,7 +3113,7 @@ png_handle_unknown(png_structrp png_ptr, png_inforp info_ptr, default: /* not at limit */ --(png_ptr->user_chunk_cache_max); - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case 0: /* no limit */ # endif /* USER_LIMITS */ /* Here when the limit isn't reached or when limits are compiled diff --git a/pngwrite.c b/pngwrite.c index 18b29e38a4..3488a236d7 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1043,7 +1043,7 @@ png_set_filter(png_structrp png_ptr, int method, int filters) case 6: case 7: png_app_error(png_ptr, "Unknown row filter for method 0"); #endif /* WRITE_FILTER */ - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case PNG_FILTER_VALUE_NONE: png_ptr->do_filter = PNG_FILTER_NONE; break; @@ -1887,7 +1887,7 @@ png_image_set_PLTE(png_image_write_control *display) tRNS[i] = entry[afirst ? 0 : 3]; if (tRNS[i] < 255) num_trans = i+1; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case 3: palette[i].blue = entry[afirst + (2 ^ bgr)]; palette[i].green = entry[afirst + 1]; @@ -1898,7 +1898,7 @@ png_image_set_PLTE(png_image_write_control *display) tRNS[i] = entry[1 ^ afirst]; if (tRNS[i] < 255) num_trans = i+1; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; /* FALLTHROUGH */ case 1: palette[i].blue = palette[i].red = palette[i].green = entry[afirst];