From ef8f03ed83a6a31803b373dd449fce5d125aa2d0 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Fri, 6 Sep 2024 16:53:22 -0700 Subject: [PATCH 1/2] Use ISO standard attributes This removes the compiler specific code in favour of the newly standardized __has_c_attribute. This is supported in the principle compilers (gcc, clang, vc) and, now that it is standard, should be supported in other compilers too, for example icc and, presumably if they are maintained, Watcom and Borland. Passes multiple tests with gcc and clang including cross-compilation with gcc. Signed-off-by: John Bowler --- contrib/libtests/pngstest.c | 19 ++-- contrib/libtests/pngunknown.c | 12 ++- contrib/libtests/pngvalid.c | 13 ++- contrib/tools/pngfix.c | 12 ++- pngconf.h | 194 ++++++++++++++++------------------ pngerror.c | 13 ++- pngpriv.h | 52 ++++----- pngread.c | 10 +- pngrtran.c | 4 +- pngrutil.c | 4 +- pngwrite.c | 6 +- 11 files changed, 170 insertions(+), 169 deletions(-) diff --git a/contrib/libtests/pngstest.c b/contrib/libtests/pngstest.c index 973e60f525..694ea80057 100644 --- a/contrib/libtests/pngstest.c +++ b/contrib/libtests/pngstest.c @@ -1,8 +1,7 @@ - /* pngstest.c * * Copyright (c) 2021 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 @@ -47,6 +46,10 @@ #ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* Else nothing can be done */ #include "../tools/sRGB.h" +#ifndef FALLTHROUGH +# define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#endif + /* KNOWN ISSUES * * These defines switch on alternate algorithms for format conversions to match @@ -2888,13 +2891,13 @@ compare_two_images(Image *a, Image *b, int via_linear, { case 4: if (pua[btoa[3]] != pub[3]) break; - /* FALLTHROUGH */ + FALLTHROUGH; case 3: if (pua[btoa[2]] != pub[2]) break; - /* FALLTHROUGH */ + FALLTHROUGH; case 2: if (pua[btoa[1]] != pub[1]) break; - /* FALLTHROUGH */ + FALLTHROUGH; case 1: if (pua[btoa[0]] != pub[0]) break; if (alpha_added != 4 && pub[alpha_added] != 65535) break; @@ -2910,13 +2913,13 @@ compare_two_images(Image *a, Image *b, int via_linear, { case 4: if (psa[btoa[3]] != psb[3]) break; - /* FALLTHROUGH */ + FALLTHROUGH; case 3: if (psa[btoa[2]] != psb[2]) break; - /* FALLTHROUGH */ + FALLTHROUGH; case 2: if (psa[btoa[1]] != psb[1]) break; - /* 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 dfa9d10a1a..af3a037d11 100644 --- a/contrib/libtests/pngunknown.c +++ b/contrib/libtests/pngunknown.c @@ -3,6 +3,7 @@ * * Copyright (c) 2021 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. @@ -39,6 +40,9 @@ # define SKIP 0 #endif +#ifndef FALLTHROUGH +# define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#endif /* Since this program tests the ability to change the unknown chunk handling * these must be defined: @@ -437,7 +441,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); @@ -461,7 +465,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); @@ -627,7 +631,7 @@ get_unknown(display *d, png_infop info_ptr, int after_IDAT) ++(d->error_count); break; } - /* FALLTHROUGH */ /* (safe) */ + FALLTHROUGH; /* (safe) */ case PNG_HANDLE_CHUNK_ALWAYS: break; } @@ -1108,7 +1112,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 3d66154dd4..04530faffa 100644 --- a/contrib/libtests/pngvalid.c +++ b/contrib/libtests/pngvalid.c @@ -1,8 +1,7 @@ - /* pngvalid.c - validate libpng by constructing then reading png files. * * Copyright (c) 2021 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 @@ -157,6 +156,10 @@ typedef png_byte *png_const_bytep; # endif #endif +#ifndef FALLTHROUGH +# define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#endif + /***************************** EXCEPTION HANDLING *****************************/ #ifdef PNG_FREESTANDING_TESTS # include @@ -6595,12 +6598,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; case PNG_COLOR_TYPE_GRAY: if (dp->output_bit_depth == 1 || dp->output_bit_depth == 2 || dp->output_bit_depth == 4) break; - /* FALLTHROUGH */ + FALLTHROUGH; default: if (dp->output_bit_depth == 8 || dp->output_bit_depth == 16) break; @@ -10007,7 +10010,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; 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 8d5dc46c22..b0bb081003 100644 --- a/contrib/tools/pngfix.c +++ b/contrib/tools/pngfix.c @@ -35,6 +35,10 @@ # error "pngfix will not work with libpng prior to 1.6.3" #endif +#ifndef FALLTHROUGH +# define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#endif + #ifdef PNG_SETJMP_SUPPORTED #include @@ -2405,7 +2409,7 @@ zlib_advance(struct zlib *zlib, png_uint_32 nbytes) endrc = ZLIB_TOO_FAR_BACK; break; } - /* FALLTHROUGH */ + FALLTHROUGH; default: zlib_message(zlib, 0/*stream error*/); @@ -2559,7 +2563,7 @@ zlib_run(struct zlib *zlib) list->lengths[i] -= zlib->extra_bytes; list->count = i+1; zlib->idat->idat_list_tail = list; - /* FALLTHROUGH */ + FALLTHROUGH; default: return rc; @@ -2662,7 +2666,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; default: /* Unrecoverable error; skip the chunk; a zlib_message has already @@ -3330,7 +3334,7 @@ read_callback(png_structp png_ptr, png_bytep buffer, size_t count) if (file->state != STATE_IDAT && length > 0) setpos(chunk); } - /* FALLTHROUGH */ + FALLTHROUGH; default: assert(chunk != NULL); diff --git a/pngconf.h b/pngconf.h index 41785a3ca2..52340b2222 100644 --- a/pngconf.h +++ b/pngconf.h @@ -299,7 +299,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, @@ -319,11 +319,27 @@ # 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 + * + * "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_PEDANTIC_WARNINGS @@ -332,117 +348,87 @@ # 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 - -# 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 - -# elif defined(__WATCOMC__) -# ifndef PNG_RESTRICT -# define PNG_RESTRICT __restrict -# endif +#ifndef PNG_ATTRIBUTE /* BEWARE: this must be a function-style macro! */ +# ifdef __has_c_attribute +# define PNG_ATTRIBUTE(token) [/**/[token]/**/] +# else +# error UNEXPECTED: unsuppported attribute +# define PNG_ATTRIBUTE(token) /*token*/ # endif -#endif /* PNG_PEDANTIC_WARNINGS */ +#endif -#ifndef PNG_DEPRECATED -# define PNG_DEPRECATED /* Use of this function is deprecated */ +#ifndef PNG_WARN +# ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED +# define PNG_WARN(token) PNG_ATTRIBUTE(token) +# else +# define PNG_WARN(token) /*token*/ +# endif #endif + +/* 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_USE_RESULT -# define PNG_USE_RESULT /* The result of this function must be checked */ +# define PNG_USE_RESULT PNG_WARN(__nodiscard__) #endif #ifndef PNG_NORETURN -# define PNG_NORETURN /* This function does not return */ +# define PNG_NORETURN PNG_ATTRIBUTE(__noreturn__) #endif #ifndef PNG_ALLOCATED -# define PNG_ALLOCATED /* The result of the function is new memory */ +# define PNG_ALLOCATED PNG_WARN(__nodiscard__(\ + "The pointer to allocated memory returned by this function is ignored."))\ + PNG_WARN(__gnu__::__malloc__) +#endif +#ifndef PNG_DEPRECATED +# define PNG_DEPRECATED PNG_ATTRIBUTE(__deprecated__(\ + "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_ATTRIBUTE(__deprecated__(\ + "This function is not exported by this build of libpng.")) #endif + +/* [[added in libpng1.8]] */ +#ifndef PNG_UNSEQUENCED +# define PNG_UNSEQUENCED PNG_ATTRIBUTE(__unsequenced__) +#endif +#ifndef PNG_REPRODUCIBLE +# define PNG_REPRODUCEIBLE PNG_ATTRIBUTE(__reproducible__) +#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 1babf9f8d2..5d904cd51e 100644 --- a/pngerror.c +++ b/pngerror.c @@ -20,9 +20,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 */ @@ -164,7 +163,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; case PNG_NUMBER_FORMAT_u: *--end = digits[number % 10]; @@ -174,7 +173,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; case PNG_NUMBER_FORMAT_x: *--end = digits[number & 0xf]; @@ -708,9 +707,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 b59084e7eb..af71d70db8 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -47,22 +47,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 @@ -355,13 +339,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 @@ -437,16 +420,35 @@ # 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. + */ +# define PNG_MAYBE_UNUSED PNG_ATTRIBUTE(maybe_unused) +#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; + */ +# define PNG_FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#endif + /* Just a little check that someone hasn't tried to define something * contradictory. */ diff --git a/pngread.c b/pngread.c index 07a39df6e2..fb174d908e 100644 --- a/pngread.c +++ b/pngread.c @@ -1906,7 +1906,7 @@ png_create_colormap_entry(png_image_read_control *display, { case 4: entry[afirst ? 0 : 3] = (png_uint_16)alpha; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; case 3: if (alpha < 65535) @@ -1928,7 +1928,7 @@ png_create_colormap_entry(png_image_read_control *display, case 2: entry[1 ^ afirst] = (png_uint_16)alpha; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; case 1: if (alpha < 65535) @@ -1957,7 +1957,7 @@ png_create_colormap_entry(png_image_read_control *display, { case 4: entry[afirst ? 0 : 3] = (png_byte)alpha; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; case 3: entry[afirst + (2 ^ bgr)] = (png_byte)blue; entry[afirst + 1] = (png_byte)green; @@ -1966,7 +1966,7 @@ png_create_colormap_entry(png_image_read_control *display, case 2: entry[1 ^ afirst] = (png_byte)alpha; - /* FALLTHROUGH */ + PNG_FALLTHROUGH; case 1: entry[afirst] = (png_byte)green; break; @@ -2886,7 +2886,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; case P_FILE: if (png_ptr->bit_depth > 8) diff --git a/pngrtran.c b/pngrtran.c index 1526123e02..a808b3c22c 100644 --- a/pngrtran.c +++ b/pngrtran.c @@ -60,7 +60,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; case PNG_CRC_ERROR_QUIT: /* Error/quit */ case PNG_CRC_DEFAULT: @@ -1263,7 +1263,7 @@ png_init_rgb_transformations(png_structrp png_ptr) default: case 8: - /* FALLTHROUGH */ /* (Already 8 bits) */ + PNG_FALLTHROUGH; /* (Already 8 bits) */ case 16: /* Already a full 16 bits */ diff --git a/pngrutil.c b/pngrutil.c index d31dc21dae..e279e746c8 100644 --- a/pngrutil.c +++ b/pngrutil.c @@ -3071,7 +3071,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; 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. @@ -3080,7 +3080,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; 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 77e412f43d..51e7f33d21 100644 --- a/pngwrite.c +++ b/pngwrite.c @@ -1034,7 +1034,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; case PNG_FILTER_VALUE_NONE: png_ptr->do_filter = PNG_FILTER_NONE; break; @@ -1909,7 +1909,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; case 3: palette[i].blue = entry[afirst + (2 ^ bgr)]; palette[i].green = entry[afirst + 1]; @@ -1920,7 +1920,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; case 1: palette[i].blue = palette[i].red = palette[i].green = entry[afirst]; From f91b06fce3578aa5a2b8ef5b368679d5ceaed2a8 Mon Sep 17 00:00:00 2001 From: John Bowler Date: Sat, 7 Sep 2024 04:54:22 -0700 Subject: [PATCH 2/2] Remove attribute warnings GCC issues warnings for unsupported attributes and quite possibly other compilers do too. This changes the pngconf.h implementation to explicitly check for each attribute when defining a macro based on it. Signed-off-by: John Bowler --- contrib/libtests/pngstest.c | 10 +++- contrib/libtests/pngunknown.c | 5 +- contrib/libtests/pngvalid.c | 5 +- contrib/tools/pngfix.c | 4 +- pngconf.h | 90 +++++++++++++++++++++++++++-------- pngpriv.h | 12 ++++- 6 files changed, 100 insertions(+), 26 deletions(-) diff --git a/contrib/libtests/pngstest.c b/contrib/libtests/pngstest.c index 694ea80057..3a097450c6 100644 --- a/contrib/libtests/pngstest.c +++ b/contrib/libtests/pngstest.c @@ -46,8 +46,16 @@ #ifdef PNG_SIMPLIFIED_READ_SUPPORTED /* Else nothing can be done */ #include "../tools/sRGB.h" -#ifndef FALLTHROUGH +/* 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 diff --git a/contrib/libtests/pngunknown.c b/contrib/libtests/pngunknown.c index af3a037d11..1d08d65ce4 100644 --- a/contrib/libtests/pngunknown.c +++ b/contrib/libtests/pngunknown.c @@ -40,10 +40,13 @@ # define SKIP 0 #endif -#ifndef FALLTHROUGH +#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: */ diff --git a/contrib/libtests/pngvalid.c b/contrib/libtests/pngvalid.c index 04530faffa..5cafc3462d 100644 --- a/contrib/libtests/pngvalid.c +++ b/contrib/libtests/pngvalid.c @@ -156,10 +156,13 @@ typedef png_byte *png_const_bytep; # endif #endif -#ifndef FALLTHROUGH +#if PNG_HAS_ATTRIBUTE(fallthrough) # define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#else +# define FALLTRHOUGH /* FALLTHROUGH */ #endif + /***************************** EXCEPTION HANDLING *****************************/ #ifdef PNG_FREESTANDING_TESTS # include diff --git a/contrib/tools/pngfix.c b/contrib/tools/pngfix.c index b0bb081003..8d242511f7 100644 --- a/contrib/tools/pngfix.c +++ b/contrib/tools/pngfix.c @@ -35,8 +35,10 @@ # error "pngfix will not work with libpng prior to 1.6.3" #endif -#ifndef FALLTHROUGH +#if PNG_HAS_ATTRIBUTE(fallthrough) # define FALLTHROUGH PNG_ATTRIBUTE(fallthrough) +#else +# define FALLTRHOUGH /* FALLTHROUGH */ #endif #ifdef PNG_SETJMP_SUPPORTED diff --git a/pngconf.h b/pngconf.h index 52340b2222..e615a3c6de 100644 --- a/pngconf.h +++ b/pngconf.h @@ -325,6 +325,7 @@ * * 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 @@ -342,21 +343,45 @@ * [[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 -#ifndef PNG_ATTRIBUTE /* BEWARE: this must be a function-style macro! */ -# ifdef __has_c_attribute +/* 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 -# error UNEXPECTED: unsuppported attribute # define PNG_ATTRIBUTE(token) /*token*/ # 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 + #ifndef PNG_WARN # ifdef PNG_PEDANTIC_WARNINGS_SUPPORTED # define PNG_WARN(token) PNG_ATTRIBUTE(token) @@ -378,34 +403,59 @@ * * __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 PNG_WARN(__nodiscard__) +# 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 PNG_ATTRIBUTE(__noreturn__) +# 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 PNG_WARN(__nodiscard__(\ - "The pointer to allocated memory returned by this function is ignored."))\ - PNG_WARN(__gnu__::__malloc__) +# 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_ATTRIBUTE(__deprecated__(\ - "This function will be removed in the next major release of libpng.")) +# define PNG_DEPRECATED PNG_DEPRECATE(\ + "This function will be removed in the next major release of libpng.") #endif + #ifndef PNG_PRIVATE /* This warns that the build of the application code will fail to link: */ -# define PNG_PRIVATE PNG_ATTRIBUTE(__deprecated__(\ - "This function is not exported by this build of libpng.")) -#endif - -/* [[added in libpng1.8]] */ -#ifndef PNG_UNSEQUENCED -# define PNG_UNSEQUENCED PNG_ATTRIBUTE(__unsequenced__) -#endif -#ifndef PNG_REPRODUCIBLE -# define PNG_REPRODUCEIBLE PNG_ATTRIBUTE(__reproducible__) +# 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 diff --git a/pngpriv.h b/pngpriv.h index af71d70db8..c5acb74c26 100644 --- a/pngpriv.h +++ b/pngpriv.h @@ -426,7 +426,11 @@ * macro. Note this is used in the #if code path where the parameter * is not used. */ -# define PNG_MAYBE_UNUSED PNG_ATTRIBUTE(maybe_unused) +# 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 @@ -446,7 +450,11 @@ * * PNG_FALLTHROUGH; */ -# define PNG_FALLTHROUGH PNG_ATTRIBUTE(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