From 5cd8f35563c3ccfba9cab3329fbfd835a7477bcf Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 09:37:19 +0200 Subject: [PATCH 01/17] UPDATE: silence clang warning: unannotated fall-through between switch labels [-Wimplicit-fallthrough]. --- src/pcre2_auto_possess.c | 8 ++++---- src/pcre2_compile.c | 34 +++++++++++++++++----------------- src/pcre2_compile_class.c | 4 ++-- src/pcre2_convert.c | 8 ++++---- src/pcre2_dfa_match.c | 12 ++++++------ src/pcre2_match.c | 18 +++++++++--------- src/pcre2_printint_inc.h | 18 +++++++++--------- src/pcre2_study.c | 22 +++++++++++----------- src/pcre2grep.c | 2 +- src/pcre2test.c | 6 +++--- 10 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c index 049b71593..8bec35b9b 100644 --- a/src/pcre2_auto_possess.c +++ b/src/pcre2_auto_possess.c @@ -804,21 +804,21 @@ for(;;) case OP_NOT_DIGIT: invert_bits = TRUE; - /* Fall through */ + __attribute__((fallthrough)); case OP_DIGIT: set2 = (const uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; - /* Fall through */ + __attribute__((fallthrough)); case OP_WHITESPACE: set2 = (const uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; - /* Fall through */ + __attribute__((fallthrough)); case OP_WORDCHAR: set2 = (const uint8_t *)(cb->cbits + cbit_word); break; @@ -1101,7 +1101,7 @@ for(;;) case OP_NCLASS: if (chr > 255) return FALSE; - /* Fall through */ + __attribute__((fallthrough)); case OP_CLASS: if (chr > 255) break; diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 64ceb8048..545519459 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -1936,7 +1936,7 @@ else if (c >= CHAR_8) break; - /* Fall through */ + __attribute__((fallthrough)); /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least @@ -2908,21 +2908,21 @@ switch(escape) { case ESC_D: prop = ESC_P; - /* Fall through */ + __attribute__((fallthrough)); case ESC_d: ascii_option = PCRE2_EXTRA_ASCII_BSD; break; case ESC_S: prop = ESC_P; - /* Fall through */ + __attribute__((fallthrough)); case ESC_s: ascii_option = PCRE2_EXTRA_ASCII_BSS; break; case ESC_W: prop = ESC_P; - /* Fall through */ + __attribute__((fallthrough)); case ESC_w: ascii_option = PCRE2_EXTRA_ASCII_BSW; break; @@ -4560,7 +4560,7 @@ while (ptr < ptrend) default: PCRE2_DEBUG_UNREACHABLE(); - /* Fall through */ + __attribute__((fallthrough)); case ESC_A: case ESC_Z: @@ -5224,7 +5224,7 @@ while (ptr < ptrend) ++ptr; goto FAILED_FORWARD; } - /* Fall through */ + __attribute__((fallthrough)); case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: @@ -5974,7 +5974,7 @@ for (;;) case OP_UCP_WORD_BOUNDARY: case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; - /* Fall through */ + __attribute__((fallthrough)); case OP_CALLOUT: case OP_CREF: @@ -6493,7 +6493,7 @@ for (;; pptr++) case META_PRUNE: case META_SKIP: cb->had_pruneorskip = TRUE; - /* Fall through */ + __attribute__((fallthrough)); case META_COMMIT: case META_FAIL: *code++ = verbops[(meta - META_MARK) >> 16]; @@ -6518,7 +6518,7 @@ for (;; pptr++) case META_PRUNE_ARG: case META_SKIP_ARG: cb->had_pruneorskip = TRUE; - /* Fall through */ + __attribute__((fallthrough)); case META_MARK: case META_COMMIT_ARG: VERB_ARG: @@ -7498,7 +7498,7 @@ for (;; pptr++) group_return = -1; /* Set "may match empty string" */ /* Now treat as a repeated OP_BRA. */ - /* Fall through */ + __attribute__((fallthrough)); /* If previous was a bracket group, we may have to replicate it in certain cases. Note that at this point we can encounter only the "basic" @@ -8348,7 +8348,7 @@ for (;; pptr++) if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : OP_UCP_WORD_BOUNDARY; - /* Fall through */ + __attribute__((fallthrough)); case ESC_A: if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; @@ -9282,7 +9282,7 @@ do { case OP_EXACT: scode += IMM2_SIZE; - /* Fall through */ + __attribute__((fallthrough)); case OP_CHAR: case OP_PLUS: @@ -9295,7 +9295,7 @@ do { case OP_EXACTI: scode += IMM2_SIZE; - /* Fall through */ + __attribute__((fallthrough)); case OP_CHARI: case OP_PLUSI: @@ -9727,7 +9727,7 @@ for (;; pptr++) case META_BACKREF_BYNAME: if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0) goto ISNOTFIXED; - /* Fall through */ + __attribute__((fallthrough)); case META_RECURSE_BYNAME: { @@ -9776,7 +9776,7 @@ for (;; pptr++) goto RECURSE_OR_BACKREF_LENGTH; } - /* Fall through */ + __attribute__((fallthrough)); /* For groups >= 10 - picking up group twice does no harm. */ /* A true recursion implies not fixed length, but a subroutine call may @@ -9856,7 +9856,7 @@ for (;; pptr++) case META_CAPTURE: group = META_DATA(*pptr); - /* Fall through */ + __attribute__((fallthrough)); case META_ATOMIC: case META_NOCAPTURE: @@ -9903,7 +9903,7 @@ for (;; pptr++) else itemlength = (max - 1) * lastitemlength; break; } - /* Fall through */ + __attribute__((fallthrough)); /* Any other item means this branch does not have a fixed length. */ diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c index 47d151387..3e8120252 100644 --- a/src/pcre2_compile_class.c +++ b/src/pcre2_compile_class.c @@ -65,7 +65,7 @@ b) none of the cases here: #define CLASS_END_CASES(meta) \ default: \ PCRE2_ASSERT((meta) <= META_END); \ - /* Fall through */ \ + __attribute__((fallthrough)); \ case META_CLASS: \ case META_CLASS_NOT: \ case META_CLASS_EMPTY: \ @@ -2169,7 +2169,7 @@ switch (meta) } ptr++; - /* Fall through */ + __attribute__((fallthrough)); default: /* Scan forward characters, ranges, and properties. diff --git a/src/pcre2_convert.c b/src/pcre2_convert.c index 10d5acc0d..f0b6f5430 100644 --- a/src/pcre2_convert.c +++ b/src/pcre2_convert.c @@ -226,7 +226,7 @@ while (plength > 0) posix++; continue; /* With next character after :] */ } - /* Fall through */ + __attribute__((fallthrough)); case POSIX_CLASS_NOT_STARTED: if (c == CHAR_LEFT_SQUARE_BRACKET) @@ -321,7 +321,7 @@ while (plength > 0) case CHAR_LEFT_PARENTHESIS: bracount++; - /* Fall through */ + __attribute__((fallthrough)); case CHAR_QUESTION_MARK: case CHAR_PLUS: @@ -329,7 +329,7 @@ while (plength > 0) case CHAR_RIGHT_CURLY_BRACKET: case CHAR_VERTICAL_LINE: if (!extended) goto ESCAPE_LITERAL; - /* Fall through */ + __attribute__((fallthrough)); case CHAR_DOT: case CHAR_DOLLAR_SIGN: @@ -358,7 +358,7 @@ while (plength > 0) posix_state = POSIX_ANCHORED; goto COPY_SPECIAL; } - /* Fall through */ + __attribute__((fallthrough)); default: if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL) diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c index c74d07dc0..19d1bb1f7 100644 --- a/src/pcre2_dfa_match.c +++ b/src/pcre2_dfa_match.c @@ -2328,7 +2328,7 @@ for (;;) case 0x2029: #endif /* Not EBCDIC */ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - /* Fall through */ + __attribute__((fallthrough)); case CHAR_LF: ADD_NEW(state_offset + 1, 0); @@ -2440,7 +2440,7 @@ for (;;) caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - /* Fall through */ + __attribute__((fallthrough)); case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2484,7 +2484,7 @@ for (;;) case OP_NOTPOSQUERYI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - /* Fall through */ + __attribute__((fallthrough)); case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2525,7 +2525,7 @@ for (;;) case OP_NOTPOSSTARI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - /* Fall through */ + __attribute__((fallthrough)); case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2562,7 +2562,7 @@ for (;;) case OP_NOTEXACTI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - /* Fall through */ + __attribute__((fallthrough)); case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ @@ -2597,7 +2597,7 @@ for (;;) case OP_NOTPOSUPTOI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - /* Fall through */ + __attribute__((fallthrough)); case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: diff --git a/src/pcre2_match.c b/src/pcre2_match.c index 1591219d4..c9369af85 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -970,7 +970,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += 1 + LINK_SIZE; continue; } - /* Fall through */ + __attribute__((fallthrough)); /* OP_END itself can never be reached within a recursion because that is picked up when the OP_KET that always precedes OP_END is reached. */ @@ -1054,7 +1054,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, mb->hitend = TRUE; if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; } - /* Fall through */ + __attribute__((fallthrough)); /* Match any single character whatsoever. */ @@ -6062,7 +6062,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); Foffset_top = assert_accept_frame->offset_top; - /* Fall through */ + __attribute__((fallthrough)); /* In the case of a match, the captures have already been put into the current frame. */ @@ -6360,7 +6360,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NA: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - /* Fall through */ + __attribute__((fallthrough)); case OP_ASSERT_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -6374,12 +6374,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - /* Fall through */ + __attribute__((fallthrough)); case OP_ASSERT: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; - /* Fall through */ + __attribute__((fallthrough)); /* For an atomic group, discard internal backtracking points. We must also ensure that any remaining branches within the top-level of the group @@ -6403,7 +6403,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NOT: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - /* Fall through */ + __attribute__((fallthrough)); case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); @@ -6537,7 +6537,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; - /* Fall through */ + __attribute__((fallthrough)); /* Unconditional end of subject assertion (\z). */ case OP_EOD: @@ -7938,7 +7938,7 @@ for(;;) new_start_match = mb->verb_skip_ptr; break; } - /* Fall through */ + __attribute__((fallthrough)); /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. Unset ignore SKIP-with-argument. */ diff --git a/src/pcre2_printint_inc.h b/src/pcre2_printint_inc.h index 49319a2a5..a825fdfca 100644 --- a/src/pcre2_printint_inc.h +++ b/src/pcre2_printint_inc.h @@ -583,7 +583,7 @@ if (type == OP_XCLASS) { case XCL_NOTPROP: notch = "^"; - /* Fall through */ + __attribute__((fallthrough)); case XCL_PROP: { unsigned int ptype = *ccode++; @@ -799,7 +799,7 @@ for(;;) case OP_MINQUERYI: case OP_POSQUERYI: flag = "/i"; - /* Fall through */ + __attribute__((fallthrough)); case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -838,7 +838,7 @@ for(;;) case OP_MINUPTOI: case OP_POSUPTOI: flag = "/i"; - /* Fall through */ + __attribute__((fallthrough)); case OP_EXACT: case OP_UPTO: case OP_MINUPTO: @@ -871,7 +871,7 @@ for(;;) case OP_NOTI: flag = "/i"; - /* Fall through */ + __attribute__((fallthrough)); case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); @@ -888,7 +888,7 @@ for(;;) case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: flag = "/i"; - /* Fall through */ + __attribute__((fallthrough)); case OP_NOTSTAR: case OP_NOTMINSTAR: @@ -909,7 +909,7 @@ for(;;) case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: flag = "/i"; - /* Fall through */ + __attribute__((fallthrough)); case OP_NOTEXACT: case OP_NOTUPTO: @@ -934,7 +934,7 @@ for(;;) case OP_REFI: flag = "/i"; - /* Fall through */ + __attribute__((fallthrough)); case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); i = (*code == OP_REFI)? code[1 + IMM2_SIZE] : 0; @@ -944,7 +944,7 @@ for(;;) case OP_DNREFI: flag = "/i"; - /* Fall through */ + __attribute__((fallthrough)); case OP_DNREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; @@ -1111,7 +1111,7 @@ for(;;) case OP_CIRCM: case OP_DOLLM: flag = "/m"; - /* Fall through */ + __attribute__((fallthrough)); /* Anything else is just an item with no data, but possibly a flag. */ diff --git a/src/pcre2_study.c b/src/pcre2_study.c index 38400e698..477504104 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -175,7 +175,7 @@ for (;;) cc += 1 + LINK_SIZE; break; } - /* Fall through */ + __attribute__((fallthrough)); case OP_ONCE: case OP_SCRIPT_RUN: @@ -252,7 +252,7 @@ for (;;) case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); - /* Fall through */ + __attribute__((fallthrough)); /* Skip over things that don't match chars */ @@ -352,7 +352,7 @@ for (;;) case OP_PROP: case OP_NOTPROP: cc += 2; - /* Fall through */ + __attribute__((fallthrough)); case OP_NOT_DIGIT: case OP_DIGIT: @@ -433,7 +433,7 @@ for (;;) case OP_CRMINPLUS: case OP_CRPOSPLUS: branchlength++; - /* Fall through */ + __attribute__((fallthrough)); case OP_CRSTAR: case OP_CRMINSTAR: @@ -1303,7 +1303,7 @@ do case OP_PROP: if (ncode[1] != PT_CLIST) break; - /* Fall through */ + __attribute__((fallthrough)); case OP_ANYNL: case OP_CHAR: case OP_CHARI: @@ -1327,7 +1327,7 @@ do tcode = ncode; continue; /* With the following significant opcode */ } - /* Fall through */ + __attribute__((fallthrough)); /* For a group bracket or a positive assertion without an immediately following mandatory setting, recurse to set bits from within the @@ -1455,7 +1455,7 @@ do case OP_EXACT: tcode += IMM2_SIZE; - /* Fall through */ + __attribute__((fallthrough)); case OP_CHAR: case OP_PLUS: case OP_MINPLUS: @@ -1466,7 +1466,7 @@ do case OP_EXACTI: tcode += IMM2_SIZE; - /* Fall through */ + __attribute__((fallthrough)); case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: @@ -1602,7 +1602,7 @@ do case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - tcode += IMM2_SIZE; /* Fall through */ + tcode += IMM2_SIZE; __attribute__((fallthrough)); case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -1783,7 +1783,7 @@ do /* It seems that the fall through comment must be outside the #ifdef if it is to avoid the gcc compiler warning. */ - /* Fall through */ + __attribute__((fallthrough)); /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter @@ -1801,7 +1801,7 @@ do #elif PCRE2_CODE_UNIT_WIDTH != 8 SET_BIT(0xFF); /* For characters >= 255 */ #endif - /* Fall through */ + __attribute__((fallthrough)); /* Enter here for a positive non-XCLASS. If we have fallen through from an XCLASS, classmap will already be set; just advance the code pointer. diff --git a/src/pcre2grep.c b/src/pcre2grep.c index 15bec99be..d1884063e 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -2053,7 +2053,7 @@ switch (*(++string)) break; } - /* Fall through */ + __attribute__((fallthrough)); /* The maximum capture number is 65535, so any number greater than that will always be an unknown capture number. We just stop incrementing, in order to diff --git a/src/pcre2test.c b/src/pcre2test.c index 3233d1c9e..8b75e9250 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -4445,7 +4445,7 @@ for (;;) *((uint32_t *)field) = (uint32_t)(m->value); break; } - /* Fall through */ + __attribute__((fallthrough)); case MOD_INT: /* Unsigned integer */ if (!isdigit(*pp)) goto INVALID_VALUE; @@ -7542,7 +7542,7 @@ if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0) case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK: fprintf(f, "Backtrack\nNo other matching paths\n"); - /* Fall through */ + __attribute__((fallthrough)); case PCRE2_CALLOUT_STARTMATCH: fprintf(f, "New match attempt\n"); @@ -10216,7 +10216,7 @@ for (i = 0; i < MODLISTCOUNT; i++) break; default: printf("** Unknown type for modifier \"%s\"\n", m->name); - /* Fall through */ + __attribute__((fallthrough)); case MOD_PD: /* Pattern or subject */ case MOD_PDP: /* As PD, OK for Perl-compatible test */ is_pattern = for_pattern; From deb1078544035fab0328492786de49b385abeef6 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 11:22:40 +0200 Subject: [PATCH 02/17] UPDATE: check whether compiler supports __attribute__((fallthrough)) to define PCRE2_FALLTHROUGH similar to PCRE2_UNDEFINED. --- CMakeLists.txt | 20 ++++++++++++++++++++ build.zig | 1 + configure.ac | 20 ++++++++++++++++++++ src/config-cmake.h.in | 1 + src/config.h.generic | 3 +++ src/pcre2_auto_possess.c | 8 ++++---- src/pcre2_compile.c | 34 +++++++++++++++++----------------- src/pcre2_compile_class.c | 4 ++-- src/pcre2_convert.c | 8 ++++---- src/pcre2_dfa_match.c | 12 ++++++------ src/pcre2_internal.h | 8 ++++++++ src/pcre2_match.c | 18 +++++++++--------- src/pcre2_printint_inc.h | 18 +++++++++--------- src/pcre2_study.c | 22 +++++++++++----------- src/pcre2grep.c | 8 +++++++- src/pcre2test.c | 6 +++--- vms/configure.com | 3 +++ 17 files changed, 128 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f38665905..a933fa924 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,6 +194,26 @@ if(NOT MSVC AND NOT CMAKE_C_COMPILER_ID STREQUAL "XL" AND NOT CMAKE_C_COMPILER_I set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror") endif() +check_c_source_compiles( + [=[ + volatile int x; + volatile int y; + int main(void) { + switch (x) + { + case 2: + if (y > 100) + return 1; + __attribute__ ((fallthrough)); + default: + break; + } + return 0; + } + ]=] + HAVE_ATTRIBUTE_FALLTHROUGH +) + check_c_source_compiles( "int main(void) { char buf[128] __attribute__((uninitialized)); (void)buf; return 0; }" HAVE_ATTRIBUTE_UNINITIALIZED diff --git a/build.zig b/build.zig index 94cea6415..40705ea35 100644 --- a/build.zig +++ b/build.zig @@ -26,6 +26,7 @@ pub fn build(b: *std.Build) !void { .HAVE_UNISTD_H = (target.result.os.tag != .windows), .HAVE_WINDOWS_H = (target.result.os.tag == .windows), + .HAVE_ATTRIBUTE_FALLTHROUGH = true, .HAVE_ATTRIBUTE_UNINITIALIZED = true, .HAVE_BUILTIN_MUL_OVERFLOW = true, .HAVE_BUILTIN_UNREACHABLE = true, diff --git a/configure.ac b/configure.ac index 49f1689bc..15db06748 100644 --- a/configure.ac +++ b/configure.ac @@ -89,6 +89,26 @@ PCRE2_VISIBILITY AX_CHECK_VSCRIPT +# Check for compiler __attribute__((fallthrough)) feature + +AC_MSG_CHECKING([for __attribute__((fallthrough))]) +AC_LANG_PUSH([C]) +tmp_CFLAGS=$CFLAGS +if test $WORKING_WERROR -eq 1; then + CFLAGS="$CFLAGS -Werror -Wimplicit-fallthrough" +fi +AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, + [[volatile int x; volatile int y; int main(void) { switch (x) { case 2: if (y > 100) return 1; __attribute__ ((fallthrough)); default: break; } return 0; }]])], + [pcre2_cc_cv_attribute_fallthrough=yes], + [pcre2_cc_cv_attribute_fallthrough=no]) +AC_MSG_RESULT([$pcre2_cc_cv_attribute_fallthrough]) +if test "$pcre2_cc_cv_attribute_fallthrough" = yes; then + AC_DEFINE([HAVE_ATTRIBUTE_FALLTHROUGH], 1, [Define this if your compiler + supports __attribute__((fallthrough))]) +fi +CFLAGS=$tmp_CFLAGS +AC_LANG_POP([C]) + # Check for Clang __attribute__((uninitialized)) feature AC_MSG_CHECKING([for __attribute__((uninitialized))]) diff --git a/src/config-cmake.h.in b/src/config-cmake.h.in index 4e13e0bc1..cc1ae340c 100644 --- a/src/config-cmake.h.in +++ b/src/config-cmake.h.in @@ -4,6 +4,7 @@ #cmakedefine HAVE_BUILTIN_ASSUME 1 #cmakedefine HAVE_BUILTIN_MUL_OVERFLOW 1 #cmakedefine HAVE_BUILTIN_UNREACHABLE 1 +#cmakedefine HAVE_ATTRIBUTE_FALLTHROUGH 1 #cmakedefine HAVE_ATTRIBUTE_UNINITIALIZED 1 #cmakedefine HAVE_DIRENT_H 1 #cmakedefine HAVE_SYS_STAT_H 1 diff --git a/src/config.h.generic b/src/config.h.generic index ed0149007..73f11961d 100644 --- a/src/config.h.generic +++ b/src/config.h.generic @@ -60,6 +60,9 @@ sure both macros are undefined; an emulation function will then be used. */ /* Define to 1 if you have the header file. */ /* #undef HAVE_ASSERT_H */ +/* Define this if your compiler supports __attribute__((fallthrough)) */ +/* #undef HAVE_ATTRIBUTE_FALLTHROUGH */ + /* Define this if your compiler supports __attribute__((uninitialized)) */ /* #undef HAVE_ATTRIBUTE_UNINITIALIZED */ diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c index 8bec35b9b..8835a753d 100644 --- a/src/pcre2_auto_possess.c +++ b/src/pcre2_auto_possess.c @@ -804,21 +804,21 @@ for(;;) case OP_NOT_DIGIT: invert_bits = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_DIGIT: set2 = (const uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_WHITESPACE: set2 = (const uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_WORDCHAR: set2 = (const uint8_t *)(cb->cbits + cbit_word); break; @@ -1101,7 +1101,7 @@ for(;;) case OP_NCLASS: if (chr > 255) return FALSE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CLASS: if (chr > 255) break; diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 545519459..192e9a5aa 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -1936,7 +1936,7 @@ else if (c >= CHAR_8) break; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least @@ -2908,21 +2908,21 @@ switch(escape) { case ESC_D: prop = ESC_P; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_d: ascii_option = PCRE2_EXTRA_ASCII_BSD; break; case ESC_S: prop = ESC_P; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_s: ascii_option = PCRE2_EXTRA_ASCII_BSS; break; case ESC_W: prop = ESC_P; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_w: ascii_option = PCRE2_EXTRA_ASCII_BSW; break; @@ -4560,7 +4560,7 @@ while (ptr < ptrend) default: PCRE2_DEBUG_UNREACHABLE(); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_A: case ESC_Z: @@ -5224,7 +5224,7 @@ while (ptr < ptrend) ++ptr; goto FAILED_FORWARD; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: @@ -5974,7 +5974,7 @@ for (;;) case OP_UCP_WORD_BOUNDARY: case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CALLOUT: case OP_CREF: @@ -6493,7 +6493,7 @@ for (;; pptr++) case META_PRUNE: case META_SKIP: cb->had_pruneorskip = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case META_COMMIT: case META_FAIL: *code++ = verbops[(meta - META_MARK) >> 16]; @@ -6518,7 +6518,7 @@ for (;; pptr++) case META_PRUNE_ARG: case META_SKIP_ARG: cb->had_pruneorskip = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case META_MARK: case META_COMMIT_ARG: VERB_ARG: @@ -7498,7 +7498,7 @@ for (;; pptr++) group_return = -1; /* Set "may match empty string" */ /* Now treat as a repeated OP_BRA. */ - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* If previous was a bracket group, we may have to replicate it in certain cases. Note that at this point we can encounter only the "basic" @@ -8348,7 +8348,7 @@ for (;; pptr++) if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : OP_UCP_WORD_BOUNDARY; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_A: if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; @@ -9282,7 +9282,7 @@ do { case OP_EXACT: scode += IMM2_SIZE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CHAR: case OP_PLUS: @@ -9295,7 +9295,7 @@ do { case OP_EXACTI: scode += IMM2_SIZE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CHARI: case OP_PLUSI: @@ -9727,7 +9727,7 @@ for (;; pptr++) case META_BACKREF_BYNAME: if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0) goto ISNOTFIXED; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case META_RECURSE_BYNAME: { @@ -9776,7 +9776,7 @@ for (;; pptr++) goto RECURSE_OR_BACKREF_LENGTH; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* For groups >= 10 - picking up group twice does no harm. */ /* A true recursion implies not fixed length, but a subroutine call may @@ -9856,7 +9856,7 @@ for (;; pptr++) case META_CAPTURE: group = META_DATA(*pptr); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case META_ATOMIC: case META_NOCAPTURE: @@ -9903,7 +9903,7 @@ for (;; pptr++) else itemlength = (max - 1) * lastitemlength; break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Any other item means this branch does not have a fixed length. */ diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c index 3e8120252..ea7a444cc 100644 --- a/src/pcre2_compile_class.c +++ b/src/pcre2_compile_class.c @@ -65,7 +65,7 @@ b) none of the cases here: #define CLASS_END_CASES(meta) \ default: \ PCRE2_ASSERT((meta) <= META_END); \ - __attribute__((fallthrough)); \ + PCRE2_FALLTHROUGH; \ case META_CLASS: \ case META_CLASS_NOT: \ case META_CLASS_EMPTY: \ @@ -2169,7 +2169,7 @@ switch (meta) } ptr++; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; default: /* Scan forward characters, ranges, and properties. diff --git a/src/pcre2_convert.c b/src/pcre2_convert.c index f0b6f5430..7985d442c 100644 --- a/src/pcre2_convert.c +++ b/src/pcre2_convert.c @@ -226,7 +226,7 @@ while (plength > 0) posix++; continue; /* With next character after :] */ } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case POSIX_CLASS_NOT_STARTED: if (c == CHAR_LEFT_SQUARE_BRACKET) @@ -321,7 +321,7 @@ while (plength > 0) case CHAR_LEFT_PARENTHESIS: bracount++; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case CHAR_QUESTION_MARK: case CHAR_PLUS: @@ -329,7 +329,7 @@ while (plength > 0) case CHAR_RIGHT_CURLY_BRACKET: case CHAR_VERTICAL_LINE: if (!extended) goto ESCAPE_LITERAL; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case CHAR_DOT: case CHAR_DOLLAR_SIGN: @@ -358,7 +358,7 @@ while (plength > 0) posix_state = POSIX_ANCHORED; goto COPY_SPECIAL; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; default: if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL) diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c index 19d1bb1f7..112bf60c0 100644 --- a/src/pcre2_dfa_match.c +++ b/src/pcre2_dfa_match.c @@ -2328,7 +2328,7 @@ for (;;) case 0x2029: #endif /* Not EBCDIC */ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case CHAR_LF: ADD_NEW(state_offset + 1, 0); @@ -2440,7 +2440,7 @@ for (;;) caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2484,7 +2484,7 @@ for (;;) case OP_NOTPOSQUERYI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2525,7 +2525,7 @@ for (;;) case OP_NOTPOSSTARI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2562,7 +2562,7 @@ for (;;) case OP_NOTEXACTI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ @@ -2597,7 +2597,7 @@ for (;;) case OP_NOTPOSUPTOI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: diff --git a/src/pcre2_internal.h b/src/pcre2_internal.h index e8471489c..5163408b5 100644 --- a/src/pcre2_internal.h +++ b/src/pcre2_internal.h @@ -109,6 +109,14 @@ functions, or at the top-level of a file. */ #include #endif +/* Used to annotate allowed intentional fallthrough between switch labels */ + +#ifdef HAVE_ATTRIBUTE_FALLTHROUGH +#define PCRE2_FALLTHROUGH __attribute__((fallthrough)) +#else +#define PCRE2_FALLTHROUGH +#endif + /* -ftrivial-auto-var-init support supports initializing all local variables to avoid some classes of bug, but this can cause an unacceptable slowdown for large on-stack arrays in hot functions. This macro lets us annotate diff --git a/src/pcre2_match.c b/src/pcre2_match.c index c9369af85..1625b2991 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -970,7 +970,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += 1 + LINK_SIZE; continue; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* OP_END itself can never be reached within a recursion because that is picked up when the OP_KET that always precedes OP_END is reached. */ @@ -1054,7 +1054,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, mb->hitend = TRUE; if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Match any single character whatsoever. */ @@ -6062,7 +6062,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); Foffset_top = assert_accept_frame->offset_top; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* In the case of a match, the captures have already been put into the current frame. */ @@ -6360,7 +6360,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NA: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ASSERT_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -6374,12 +6374,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ASSERT: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* For an atomic group, discard internal backtracking points. We must also ensure that any remaining branches within the top-level of the group @@ -6403,7 +6403,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NOT: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); @@ -6537,7 +6537,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Unconditional end of subject assertion (\z). */ case OP_EOD: @@ -7938,7 +7938,7 @@ for(;;) new_start_match = mb->verb_skip_ptr; break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. Unset ignore SKIP-with-argument. */ diff --git a/src/pcre2_printint_inc.h b/src/pcre2_printint_inc.h index a825fdfca..4999dda6e 100644 --- a/src/pcre2_printint_inc.h +++ b/src/pcre2_printint_inc.h @@ -583,7 +583,7 @@ if (type == OP_XCLASS) { case XCL_NOTPROP: notch = "^"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case XCL_PROP: { unsigned int ptype = *ccode++; @@ -799,7 +799,7 @@ for(;;) case OP_MINQUERYI: case OP_POSQUERYI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -838,7 +838,7 @@ for(;;) case OP_MINUPTOI: case OP_POSUPTOI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_EXACT: case OP_UPTO: case OP_MINUPTO: @@ -871,7 +871,7 @@ for(;;) case OP_NOTI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); @@ -888,7 +888,7 @@ for(;;) case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_NOTSTAR: case OP_NOTMINSTAR: @@ -909,7 +909,7 @@ for(;;) case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_NOTEXACT: case OP_NOTUPTO: @@ -934,7 +934,7 @@ for(;;) case OP_REFI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); i = (*code == OP_REFI)? code[1 + IMM2_SIZE] : 0; @@ -944,7 +944,7 @@ for(;;) case OP_DNREFI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_DNREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; @@ -1111,7 +1111,7 @@ for(;;) case OP_CIRCM: case OP_DOLLM: flag = "/m"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Anything else is just an item with no data, but possibly a flag. */ diff --git a/src/pcre2_study.c b/src/pcre2_study.c index 477504104..909e90185 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -175,7 +175,7 @@ for (;;) cc += 1 + LINK_SIZE; break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ONCE: case OP_SCRIPT_RUN: @@ -252,7 +252,7 @@ for (;;) case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Skip over things that don't match chars */ @@ -352,7 +352,7 @@ for (;;) case OP_PROP: case OP_NOTPROP: cc += 2; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_NOT_DIGIT: case OP_DIGIT: @@ -433,7 +433,7 @@ for (;;) case OP_CRMINPLUS: case OP_CRPOSPLUS: branchlength++; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CRSTAR: case OP_CRMINSTAR: @@ -1303,7 +1303,7 @@ do case OP_PROP: if (ncode[1] != PT_CLIST) break; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ANYNL: case OP_CHAR: case OP_CHARI: @@ -1327,7 +1327,7 @@ do tcode = ncode; continue; /* With the following significant opcode */ } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* For a group bracket or a positive assertion without an immediately following mandatory setting, recurse to set bits from within the @@ -1455,7 +1455,7 @@ do case OP_EXACT: tcode += IMM2_SIZE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CHAR: case OP_PLUS: case OP_MINPLUS: @@ -1466,7 +1466,7 @@ do case OP_EXACTI: tcode += IMM2_SIZE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: @@ -1602,7 +1602,7 @@ do case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - tcode += IMM2_SIZE; __attribute__((fallthrough)); + tcode += IMM2_SIZE; PCRE2_FALLTHROUGH; case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -1783,7 +1783,7 @@ do /* It seems that the fall through comment must be outside the #ifdef if it is to avoid the gcc compiler warning. */ - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter @@ -1801,7 +1801,7 @@ do #elif PCRE2_CODE_UNIT_WIDTH != 8 SET_BIT(0xFF); /* For characters >= 255 */ #endif - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Enter here for a positive non-XCLASS. If we have fallen through from an XCLASS, classmap will already be set; just advance the code pointer. diff --git a/src/pcre2grep.c b/src/pcre2grep.c index d1884063e..511bea608 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -205,6 +205,12 @@ point. */ #define STDOUT_NL_CODE 0x7fffffffu +/* Used to annotate allowed intentional fallthrough between switch labels */ +#ifdef HAVE_ATTRIBUTE_FALLTHROUGH +#define PCRE2_FALLTHROUGH __attribute__((fallthrough)) +#else +#define PCRE2_FALLTHROUGH +#endif /************************************************* @@ -2053,7 +2059,7 @@ switch (*(++string)) break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* The maximum capture number is 65535, so any number greater than that will always be an unknown capture number. We just stop incrementing, in order to diff --git a/src/pcre2test.c b/src/pcre2test.c index 8b75e9250..e257aea22 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -4445,7 +4445,7 @@ for (;;) *((uint32_t *)field) = (uint32_t)(m->value); break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case MOD_INT: /* Unsigned integer */ if (!isdigit(*pp)) goto INVALID_VALUE; @@ -7542,7 +7542,7 @@ if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0) case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK: fprintf(f, "Backtrack\nNo other matching paths\n"); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case PCRE2_CALLOUT_STARTMATCH: fprintf(f, "New match attempt\n"); @@ -10216,7 +10216,7 @@ for (i = 0; i < MODLISTCOUNT; i++) break; default: printf("** Unknown type for modifier \"%s\"\n", m->name); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case MOD_PD: /* Pattern or subject */ case MOD_PDP: /* As PD, OK for Perl-compatible test */ is_pattern = for_pattern; diff --git a/vms/configure.com b/vms/configure.com index 19c9ff5bb..2de4890da 100644 --- a/vms/configure.com +++ b/vms/configure.com @@ -493,6 +493,9 @@ sure both macros are undefined; an emulation function will then be used. */ LF does in an ASCII/Unicode environment. */ #undef EBCDIC_NL25 +/* Define this if your compiler supports __attribute__((fallthrough)) */ +#undef HAVE_ATTRIBUTE_FALLTHROUGH + /* Define this if your compiler supports __attribute__((uninitialized)) */ #undef HAVE_ATTRIBUTE_UNINITIALIZED From eb48177b66b1791a31492a735c6fdce08ba3a449 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 11:59:49 +0200 Subject: [PATCH 03/17] Revert "UPDATE: check whether compiler supports __attribute__((fallthrough)) to define PCRE2_FALLTHROUGH similar to PCRE2_UNDEFINED." This reverts commit deb1078544035fab0328492786de49b385abeef6. --- CMakeLists.txt | 20 -------------------- build.zig | 1 - configure.ac | 20 -------------------- src/config-cmake.h.in | 1 - src/config.h.generic | 3 --- src/pcre2_auto_possess.c | 8 ++++---- src/pcre2_compile.c | 34 +++++++++++++++++----------------- src/pcre2_compile_class.c | 4 ++-- src/pcre2_convert.c | 8 ++++---- src/pcre2_dfa_match.c | 12 ++++++------ src/pcre2_internal.h | 8 -------- src/pcre2_match.c | 18 +++++++++--------- src/pcre2_printint_inc.h | 18 +++++++++--------- src/pcre2_study.c | 22 +++++++++++----------- src/pcre2grep.c | 8 +------- src/pcre2test.c | 6 +++--- vms/configure.com | 3 --- 17 files changed, 66 insertions(+), 128 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a933fa924..f38665905 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -194,26 +194,6 @@ if(NOT MSVC AND NOT CMAKE_C_COMPILER_ID STREQUAL "XL" AND NOT CMAKE_C_COMPILER_I set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror") endif() -check_c_source_compiles( - [=[ - volatile int x; - volatile int y; - int main(void) { - switch (x) - { - case 2: - if (y > 100) - return 1; - __attribute__ ((fallthrough)); - default: - break; - } - return 0; - } - ]=] - HAVE_ATTRIBUTE_FALLTHROUGH -) - check_c_source_compiles( "int main(void) { char buf[128] __attribute__((uninitialized)); (void)buf; return 0; }" HAVE_ATTRIBUTE_UNINITIALIZED diff --git a/build.zig b/build.zig index 40705ea35..94cea6415 100644 --- a/build.zig +++ b/build.zig @@ -26,7 +26,6 @@ pub fn build(b: *std.Build) !void { .HAVE_UNISTD_H = (target.result.os.tag != .windows), .HAVE_WINDOWS_H = (target.result.os.tag == .windows), - .HAVE_ATTRIBUTE_FALLTHROUGH = true, .HAVE_ATTRIBUTE_UNINITIALIZED = true, .HAVE_BUILTIN_MUL_OVERFLOW = true, .HAVE_BUILTIN_UNREACHABLE = true, diff --git a/configure.ac b/configure.ac index 15db06748..49f1689bc 100644 --- a/configure.ac +++ b/configure.ac @@ -89,26 +89,6 @@ PCRE2_VISIBILITY AX_CHECK_VSCRIPT -# Check for compiler __attribute__((fallthrough)) feature - -AC_MSG_CHECKING([for __attribute__((fallthrough))]) -AC_LANG_PUSH([C]) -tmp_CFLAGS=$CFLAGS -if test $WORKING_WERROR -eq 1; then - CFLAGS="$CFLAGS -Werror -Wimplicit-fallthrough" -fi -AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, - [[volatile int x; volatile int y; int main(void) { switch (x) { case 2: if (y > 100) return 1; __attribute__ ((fallthrough)); default: break; } return 0; }]])], - [pcre2_cc_cv_attribute_fallthrough=yes], - [pcre2_cc_cv_attribute_fallthrough=no]) -AC_MSG_RESULT([$pcre2_cc_cv_attribute_fallthrough]) -if test "$pcre2_cc_cv_attribute_fallthrough" = yes; then - AC_DEFINE([HAVE_ATTRIBUTE_FALLTHROUGH], 1, [Define this if your compiler - supports __attribute__((fallthrough))]) -fi -CFLAGS=$tmp_CFLAGS -AC_LANG_POP([C]) - # Check for Clang __attribute__((uninitialized)) feature AC_MSG_CHECKING([for __attribute__((uninitialized))]) diff --git a/src/config-cmake.h.in b/src/config-cmake.h.in index cc1ae340c..4e13e0bc1 100644 --- a/src/config-cmake.h.in +++ b/src/config-cmake.h.in @@ -4,7 +4,6 @@ #cmakedefine HAVE_BUILTIN_ASSUME 1 #cmakedefine HAVE_BUILTIN_MUL_OVERFLOW 1 #cmakedefine HAVE_BUILTIN_UNREACHABLE 1 -#cmakedefine HAVE_ATTRIBUTE_FALLTHROUGH 1 #cmakedefine HAVE_ATTRIBUTE_UNINITIALIZED 1 #cmakedefine HAVE_DIRENT_H 1 #cmakedefine HAVE_SYS_STAT_H 1 diff --git a/src/config.h.generic b/src/config.h.generic index 73f11961d..ed0149007 100644 --- a/src/config.h.generic +++ b/src/config.h.generic @@ -60,9 +60,6 @@ sure both macros are undefined; an emulation function will then be used. */ /* Define to 1 if you have the header file. */ /* #undef HAVE_ASSERT_H */ -/* Define this if your compiler supports __attribute__((fallthrough)) */ -/* #undef HAVE_ATTRIBUTE_FALLTHROUGH */ - /* Define this if your compiler supports __attribute__((uninitialized)) */ /* #undef HAVE_ATTRIBUTE_UNINITIALIZED */ diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c index 8835a753d..8bec35b9b 100644 --- a/src/pcre2_auto_possess.c +++ b/src/pcre2_auto_possess.c @@ -804,21 +804,21 @@ for(;;) case OP_NOT_DIGIT: invert_bits = TRUE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_DIGIT: set2 = (const uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_WHITESPACE: set2 = (const uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_WORDCHAR: set2 = (const uint8_t *)(cb->cbits + cbit_word); break; @@ -1101,7 +1101,7 @@ for(;;) case OP_NCLASS: if (chr > 255) return FALSE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_CLASS: if (chr > 255) break; diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 192e9a5aa..545519459 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -1936,7 +1936,7 @@ else if (c >= CHAR_8) break; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least @@ -2908,21 +2908,21 @@ switch(escape) { case ESC_D: prop = ESC_P; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case ESC_d: ascii_option = PCRE2_EXTRA_ASCII_BSD; break; case ESC_S: prop = ESC_P; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case ESC_s: ascii_option = PCRE2_EXTRA_ASCII_BSS; break; case ESC_W: prop = ESC_P; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case ESC_w: ascii_option = PCRE2_EXTRA_ASCII_BSW; break; @@ -4560,7 +4560,7 @@ while (ptr < ptrend) default: PCRE2_DEBUG_UNREACHABLE(); - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case ESC_A: case ESC_Z: @@ -5224,7 +5224,7 @@ while (ptr < ptrend) ++ptr; goto FAILED_FORWARD; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: @@ -5974,7 +5974,7 @@ for (;;) case OP_UCP_WORD_BOUNDARY: case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_CALLOUT: case OP_CREF: @@ -6493,7 +6493,7 @@ for (;; pptr++) case META_PRUNE: case META_SKIP: cb->had_pruneorskip = TRUE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case META_COMMIT: case META_FAIL: *code++ = verbops[(meta - META_MARK) >> 16]; @@ -6518,7 +6518,7 @@ for (;; pptr++) case META_PRUNE_ARG: case META_SKIP_ARG: cb->had_pruneorskip = TRUE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case META_MARK: case META_COMMIT_ARG: VERB_ARG: @@ -7498,7 +7498,7 @@ for (;; pptr++) group_return = -1; /* Set "may match empty string" */ /* Now treat as a repeated OP_BRA. */ - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* If previous was a bracket group, we may have to replicate it in certain cases. Note that at this point we can encounter only the "basic" @@ -8348,7 +8348,7 @@ for (;; pptr++) if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : OP_UCP_WORD_BOUNDARY; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case ESC_A: if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; @@ -9282,7 +9282,7 @@ do { case OP_EXACT: scode += IMM2_SIZE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_CHAR: case OP_PLUS: @@ -9295,7 +9295,7 @@ do { case OP_EXACTI: scode += IMM2_SIZE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_CHARI: case OP_PLUSI: @@ -9727,7 +9727,7 @@ for (;; pptr++) case META_BACKREF_BYNAME: if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0) goto ISNOTFIXED; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case META_RECURSE_BYNAME: { @@ -9776,7 +9776,7 @@ for (;; pptr++) goto RECURSE_OR_BACKREF_LENGTH; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* For groups >= 10 - picking up group twice does no harm. */ /* A true recursion implies not fixed length, but a subroutine call may @@ -9856,7 +9856,7 @@ for (;; pptr++) case META_CAPTURE: group = META_DATA(*pptr); - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case META_ATOMIC: case META_NOCAPTURE: @@ -9903,7 +9903,7 @@ for (;; pptr++) else itemlength = (max - 1) * lastitemlength; break; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* Any other item means this branch does not have a fixed length. */ diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c index ea7a444cc..3e8120252 100644 --- a/src/pcre2_compile_class.c +++ b/src/pcre2_compile_class.c @@ -65,7 +65,7 @@ b) none of the cases here: #define CLASS_END_CASES(meta) \ default: \ PCRE2_ASSERT((meta) <= META_END); \ - PCRE2_FALLTHROUGH; \ + __attribute__((fallthrough)); \ case META_CLASS: \ case META_CLASS_NOT: \ case META_CLASS_EMPTY: \ @@ -2169,7 +2169,7 @@ switch (meta) } ptr++; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); default: /* Scan forward characters, ranges, and properties. diff --git a/src/pcre2_convert.c b/src/pcre2_convert.c index 7985d442c..f0b6f5430 100644 --- a/src/pcre2_convert.c +++ b/src/pcre2_convert.c @@ -226,7 +226,7 @@ while (plength > 0) posix++; continue; /* With next character after :] */ } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case POSIX_CLASS_NOT_STARTED: if (c == CHAR_LEFT_SQUARE_BRACKET) @@ -321,7 +321,7 @@ while (plength > 0) case CHAR_LEFT_PARENTHESIS: bracount++; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case CHAR_QUESTION_MARK: case CHAR_PLUS: @@ -329,7 +329,7 @@ while (plength > 0) case CHAR_RIGHT_CURLY_BRACKET: case CHAR_VERTICAL_LINE: if (!extended) goto ESCAPE_LITERAL; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case CHAR_DOT: case CHAR_DOLLAR_SIGN: @@ -358,7 +358,7 @@ while (plength > 0) posix_state = POSIX_ANCHORED; goto COPY_SPECIAL; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); default: if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL) diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c index 112bf60c0..19d1bb1f7 100644 --- a/src/pcre2_dfa_match.c +++ b/src/pcre2_dfa_match.c @@ -2328,7 +2328,7 @@ for (;;) case 0x2029: #endif /* Not EBCDIC */ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case CHAR_LF: ADD_NEW(state_offset + 1, 0); @@ -2440,7 +2440,7 @@ for (;;) caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2484,7 +2484,7 @@ for (;;) case OP_NOTPOSQUERYI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2525,7 +2525,7 @@ for (;;) case OP_NOTPOSSTARI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2562,7 +2562,7 @@ for (;;) case OP_NOTEXACTI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ @@ -2597,7 +2597,7 @@ for (;;) case OP_NOTPOSUPTOI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: diff --git a/src/pcre2_internal.h b/src/pcre2_internal.h index 5163408b5..e8471489c 100644 --- a/src/pcre2_internal.h +++ b/src/pcre2_internal.h @@ -109,14 +109,6 @@ functions, or at the top-level of a file. */ #include #endif -/* Used to annotate allowed intentional fallthrough between switch labels */ - -#ifdef HAVE_ATTRIBUTE_FALLTHROUGH -#define PCRE2_FALLTHROUGH __attribute__((fallthrough)) -#else -#define PCRE2_FALLTHROUGH -#endif - /* -ftrivial-auto-var-init support supports initializing all local variables to avoid some classes of bug, but this can cause an unacceptable slowdown for large on-stack arrays in hot functions. This macro lets us annotate diff --git a/src/pcre2_match.c b/src/pcre2_match.c index 1625b2991..c9369af85 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -970,7 +970,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += 1 + LINK_SIZE; continue; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* OP_END itself can never be reached within a recursion because that is picked up when the OP_KET that always precedes OP_END is reached. */ @@ -1054,7 +1054,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, mb->hitend = TRUE; if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* Match any single character whatsoever. */ @@ -6062,7 +6062,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); Foffset_top = assert_accept_frame->offset_top; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* In the case of a match, the captures have already been put into the current frame. */ @@ -6360,7 +6360,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NA: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_ASSERT_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -6374,12 +6374,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_ASSERT: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* For an atomic group, discard internal backtracking points. We must also ensure that any remaining branches within the top-level of the group @@ -6403,7 +6403,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NOT: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); @@ -6537,7 +6537,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* Unconditional end of subject assertion (\z). */ case OP_EOD: @@ -7938,7 +7938,7 @@ for(;;) new_start_match = mb->verb_skip_ptr; break; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. Unset ignore SKIP-with-argument. */ diff --git a/src/pcre2_printint_inc.h b/src/pcre2_printint_inc.h index 4999dda6e..a825fdfca 100644 --- a/src/pcre2_printint_inc.h +++ b/src/pcre2_printint_inc.h @@ -583,7 +583,7 @@ if (type == OP_XCLASS) { case XCL_NOTPROP: notch = "^"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case XCL_PROP: { unsigned int ptype = *ccode++; @@ -799,7 +799,7 @@ for(;;) case OP_MINQUERYI: case OP_POSQUERYI: flag = "/i"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -838,7 +838,7 @@ for(;;) case OP_MINUPTOI: case OP_POSUPTOI: flag = "/i"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_EXACT: case OP_UPTO: case OP_MINUPTO: @@ -871,7 +871,7 @@ for(;;) case OP_NOTI: flag = "/i"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); @@ -888,7 +888,7 @@ for(;;) case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: flag = "/i"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_NOTSTAR: case OP_NOTMINSTAR: @@ -909,7 +909,7 @@ for(;;) case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: flag = "/i"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_NOTEXACT: case OP_NOTUPTO: @@ -934,7 +934,7 @@ for(;;) case OP_REFI: flag = "/i"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); i = (*code == OP_REFI)? code[1 + IMM2_SIZE] : 0; @@ -944,7 +944,7 @@ for(;;) case OP_DNREFI: flag = "/i"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_DNREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; @@ -1111,7 +1111,7 @@ for(;;) case OP_CIRCM: case OP_DOLLM: flag = "/m"; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* Anything else is just an item with no data, but possibly a flag. */ diff --git a/src/pcre2_study.c b/src/pcre2_study.c index 909e90185..477504104 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -175,7 +175,7 @@ for (;;) cc += 1 + LINK_SIZE; break; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_ONCE: case OP_SCRIPT_RUN: @@ -252,7 +252,7 @@ for (;;) case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* Skip over things that don't match chars */ @@ -352,7 +352,7 @@ for (;;) case OP_PROP: case OP_NOTPROP: cc += 2; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_NOT_DIGIT: case OP_DIGIT: @@ -433,7 +433,7 @@ for (;;) case OP_CRMINPLUS: case OP_CRPOSPLUS: branchlength++; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_CRSTAR: case OP_CRMINSTAR: @@ -1303,7 +1303,7 @@ do case OP_PROP: if (ncode[1] != PT_CLIST) break; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_ANYNL: case OP_CHAR: case OP_CHARI: @@ -1327,7 +1327,7 @@ do tcode = ncode; continue; /* With the following significant opcode */ } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* For a group bracket or a positive assertion without an immediately following mandatory setting, recurse to set bits from within the @@ -1455,7 +1455,7 @@ do case OP_EXACT: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_CHAR: case OP_PLUS: case OP_MINPLUS: @@ -1466,7 +1466,7 @@ do case OP_EXACTI: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: @@ -1602,7 +1602,7 @@ do case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - tcode += IMM2_SIZE; PCRE2_FALLTHROUGH; + tcode += IMM2_SIZE; __attribute__((fallthrough)); case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -1783,7 +1783,7 @@ do /* It seems that the fall through comment must be outside the #ifdef if it is to avoid the gcc compiler warning. */ - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter @@ -1801,7 +1801,7 @@ do #elif PCRE2_CODE_UNIT_WIDTH != 8 SET_BIT(0xFF); /* For characters >= 255 */ #endif - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* Enter here for a positive non-XCLASS. If we have fallen through from an XCLASS, classmap will already be set; just advance the code pointer. diff --git a/src/pcre2grep.c b/src/pcre2grep.c index 511bea608..d1884063e 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -205,12 +205,6 @@ point. */ #define STDOUT_NL_CODE 0x7fffffffu -/* Used to annotate allowed intentional fallthrough between switch labels */ -#ifdef HAVE_ATTRIBUTE_FALLTHROUGH -#define PCRE2_FALLTHROUGH __attribute__((fallthrough)) -#else -#define PCRE2_FALLTHROUGH -#endif /************************************************* @@ -2059,7 +2053,7 @@ switch (*(++string)) break; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); /* The maximum capture number is 65535, so any number greater than that will always be an unknown capture number. We just stop incrementing, in order to diff --git a/src/pcre2test.c b/src/pcre2test.c index e257aea22..8b75e9250 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -4445,7 +4445,7 @@ for (;;) *((uint32_t *)field) = (uint32_t)(m->value); break; } - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case MOD_INT: /* Unsigned integer */ if (!isdigit(*pp)) goto INVALID_VALUE; @@ -7542,7 +7542,7 @@ if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0) case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK: fprintf(f, "Backtrack\nNo other matching paths\n"); - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case PCRE2_CALLOUT_STARTMATCH: fprintf(f, "New match attempt\n"); @@ -10216,7 +10216,7 @@ for (i = 0; i < MODLISTCOUNT; i++) break; default: printf("** Unknown type for modifier \"%s\"\n", m->name); - PCRE2_FALLTHROUGH; + __attribute__((fallthrough)); case MOD_PD: /* Pattern or subject */ case MOD_PDP: /* As PD, OK for Perl-compatible test */ is_pattern = for_pattern; diff --git a/vms/configure.com b/vms/configure.com index 2de4890da..19c9ff5bb 100644 --- a/vms/configure.com +++ b/vms/configure.com @@ -493,9 +493,6 @@ sure both macros are undefined; an emulation function will then be used. */ LF does in an ASCII/Unicode environment. */ #undef EBCDIC_NL25 -/* Define this if your compiler supports __attribute__((fallthrough)) */ -#undef HAVE_ATTRIBUTE_FALLTHROUGH - /* Define this if your compiler supports __attribute__((uninitialized)) */ #undef HAVE_ATTRIBUTE_UNINITIALIZED From 2f078428b37e928d6b4c374bd9d4fa1a824540af Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 12:28:26 +0200 Subject: [PATCH 04/17] UPDATE: introduce PCRE2_FALLTHROUGH macro to allow portable annotation of intential fall-through between switch labels. --- src/pcre2_auto_possess.c | 8 ++++---- src/pcre2_compile.c | 34 +++++++++++++++++----------------- src/pcre2_compile_class.c | 4 ++-- src/pcre2_convert.c | 8 ++++---- src/pcre2_dfa_match.c | 12 ++++++------ src/pcre2_match.c | 18 +++++++++--------- src/pcre2_printint_inc.h | 18 +++++++++--------- src/pcre2_study.c | 22 +++++++++++----------- src/pcre2_util.h | 17 +++++++++++++++++ src/pcre2grep.c | 4 +++- src/pcre2test.c | 6 +++--- 11 files changed, 85 insertions(+), 66 deletions(-) diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c index 8bec35b9b..8835a753d 100644 --- a/src/pcre2_auto_possess.c +++ b/src/pcre2_auto_possess.c @@ -804,21 +804,21 @@ for(;;) case OP_NOT_DIGIT: invert_bits = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_DIGIT: set2 = (const uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_WHITESPACE: set2 = (const uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_WORDCHAR: set2 = (const uint8_t *)(cb->cbits + cbit_word); break; @@ -1101,7 +1101,7 @@ for(;;) case OP_NCLASS: if (chr > 255) return FALSE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CLASS: if (chr > 255) break; diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 545519459..192e9a5aa 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -1936,7 +1936,7 @@ else if (c >= CHAR_8) break; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least @@ -2908,21 +2908,21 @@ switch(escape) { case ESC_D: prop = ESC_P; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_d: ascii_option = PCRE2_EXTRA_ASCII_BSD; break; case ESC_S: prop = ESC_P; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_s: ascii_option = PCRE2_EXTRA_ASCII_BSS; break; case ESC_W: prop = ESC_P; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_w: ascii_option = PCRE2_EXTRA_ASCII_BSW; break; @@ -4560,7 +4560,7 @@ while (ptr < ptrend) default: PCRE2_DEBUG_UNREACHABLE(); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_A: case ESC_Z: @@ -5224,7 +5224,7 @@ while (ptr < ptrend) ++ptr; goto FAILED_FORWARD; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: @@ -5974,7 +5974,7 @@ for (;;) case OP_UCP_WORD_BOUNDARY: case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CALLOUT: case OP_CREF: @@ -6493,7 +6493,7 @@ for (;; pptr++) case META_PRUNE: case META_SKIP: cb->had_pruneorskip = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case META_COMMIT: case META_FAIL: *code++ = verbops[(meta - META_MARK) >> 16]; @@ -6518,7 +6518,7 @@ for (;; pptr++) case META_PRUNE_ARG: case META_SKIP_ARG: cb->had_pruneorskip = TRUE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case META_MARK: case META_COMMIT_ARG: VERB_ARG: @@ -7498,7 +7498,7 @@ for (;; pptr++) group_return = -1; /* Set "may match empty string" */ /* Now treat as a repeated OP_BRA. */ - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* If previous was a bracket group, we may have to replicate it in certain cases. Note that at this point we can encounter only the "basic" @@ -8348,7 +8348,7 @@ for (;; pptr++) if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : OP_UCP_WORD_BOUNDARY; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case ESC_A: if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; @@ -9282,7 +9282,7 @@ do { case OP_EXACT: scode += IMM2_SIZE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CHAR: case OP_PLUS: @@ -9295,7 +9295,7 @@ do { case OP_EXACTI: scode += IMM2_SIZE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CHARI: case OP_PLUSI: @@ -9727,7 +9727,7 @@ for (;; pptr++) case META_BACKREF_BYNAME: if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0) goto ISNOTFIXED; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case META_RECURSE_BYNAME: { @@ -9776,7 +9776,7 @@ for (;; pptr++) goto RECURSE_OR_BACKREF_LENGTH; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* For groups >= 10 - picking up group twice does no harm. */ /* A true recursion implies not fixed length, but a subroutine call may @@ -9856,7 +9856,7 @@ for (;; pptr++) case META_CAPTURE: group = META_DATA(*pptr); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case META_ATOMIC: case META_NOCAPTURE: @@ -9903,7 +9903,7 @@ for (;; pptr++) else itemlength = (max - 1) * lastitemlength; break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Any other item means this branch does not have a fixed length. */ diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c index 3e8120252..ea7a444cc 100644 --- a/src/pcre2_compile_class.c +++ b/src/pcre2_compile_class.c @@ -65,7 +65,7 @@ b) none of the cases here: #define CLASS_END_CASES(meta) \ default: \ PCRE2_ASSERT((meta) <= META_END); \ - __attribute__((fallthrough)); \ + PCRE2_FALLTHROUGH; \ case META_CLASS: \ case META_CLASS_NOT: \ case META_CLASS_EMPTY: \ @@ -2169,7 +2169,7 @@ switch (meta) } ptr++; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; default: /* Scan forward characters, ranges, and properties. diff --git a/src/pcre2_convert.c b/src/pcre2_convert.c index f0b6f5430..7985d442c 100644 --- a/src/pcre2_convert.c +++ b/src/pcre2_convert.c @@ -226,7 +226,7 @@ while (plength > 0) posix++; continue; /* With next character after :] */ } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case POSIX_CLASS_NOT_STARTED: if (c == CHAR_LEFT_SQUARE_BRACKET) @@ -321,7 +321,7 @@ while (plength > 0) case CHAR_LEFT_PARENTHESIS: bracount++; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case CHAR_QUESTION_MARK: case CHAR_PLUS: @@ -329,7 +329,7 @@ while (plength > 0) case CHAR_RIGHT_CURLY_BRACKET: case CHAR_VERTICAL_LINE: if (!extended) goto ESCAPE_LITERAL; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case CHAR_DOT: case CHAR_DOLLAR_SIGN: @@ -358,7 +358,7 @@ while (plength > 0) posix_state = POSIX_ANCHORED; goto COPY_SPECIAL; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; default: if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL) diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c index 19d1bb1f7..112bf60c0 100644 --- a/src/pcre2_dfa_match.c +++ b/src/pcre2_dfa_match.c @@ -2328,7 +2328,7 @@ for (;;) case 0x2029: #endif /* Not EBCDIC */ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case CHAR_LF: ADD_NEW(state_offset + 1, 0); @@ -2440,7 +2440,7 @@ for (;;) caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2484,7 +2484,7 @@ for (;;) case OP_NOTPOSQUERYI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2525,7 +2525,7 @@ for (;;) case OP_NOTPOSSTARI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2562,7 +2562,7 @@ for (;;) case OP_NOTEXACTI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ @@ -2597,7 +2597,7 @@ for (;;) case OP_NOTPOSUPTOI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: diff --git a/src/pcre2_match.c b/src/pcre2_match.c index c9369af85..1625b2991 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -970,7 +970,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += 1 + LINK_SIZE; continue; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* OP_END itself can never be reached within a recursion because that is picked up when the OP_KET that always precedes OP_END is reached. */ @@ -1054,7 +1054,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, mb->hitend = TRUE; if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Match any single character whatsoever. */ @@ -6062,7 +6062,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); Foffset_top = assert_accept_frame->offset_top; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* In the case of a match, the captures have already been put into the current frame. */ @@ -6360,7 +6360,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NA: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ASSERT_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -6374,12 +6374,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ASSERT: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* For an atomic group, discard internal backtracking points. We must also ensure that any remaining branches within the top-level of the group @@ -6403,7 +6403,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NOT: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); @@ -6537,7 +6537,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Unconditional end of subject assertion (\z). */ case OP_EOD: @@ -7938,7 +7938,7 @@ for(;;) new_start_match = mb->verb_skip_ptr; break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. Unset ignore SKIP-with-argument. */ diff --git a/src/pcre2_printint_inc.h b/src/pcre2_printint_inc.h index a825fdfca..4999dda6e 100644 --- a/src/pcre2_printint_inc.h +++ b/src/pcre2_printint_inc.h @@ -583,7 +583,7 @@ if (type == OP_XCLASS) { case XCL_NOTPROP: notch = "^"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case XCL_PROP: { unsigned int ptype = *ccode++; @@ -799,7 +799,7 @@ for(;;) case OP_MINQUERYI: case OP_POSQUERYI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -838,7 +838,7 @@ for(;;) case OP_MINUPTOI: case OP_POSUPTOI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_EXACT: case OP_UPTO: case OP_MINUPTO: @@ -871,7 +871,7 @@ for(;;) case OP_NOTI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); @@ -888,7 +888,7 @@ for(;;) case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_NOTSTAR: case OP_NOTMINSTAR: @@ -909,7 +909,7 @@ for(;;) case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_NOTEXACT: case OP_NOTUPTO: @@ -934,7 +934,7 @@ for(;;) case OP_REFI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); i = (*code == OP_REFI)? code[1 + IMM2_SIZE] : 0; @@ -944,7 +944,7 @@ for(;;) case OP_DNREFI: flag = "/i"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_DNREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; @@ -1111,7 +1111,7 @@ for(;;) case OP_CIRCM: case OP_DOLLM: flag = "/m"; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Anything else is just an item with no data, but possibly a flag. */ diff --git a/src/pcre2_study.c b/src/pcre2_study.c index 477504104..909e90185 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -175,7 +175,7 @@ for (;;) cc += 1 + LINK_SIZE; break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ONCE: case OP_SCRIPT_RUN: @@ -252,7 +252,7 @@ for (;;) case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Skip over things that don't match chars */ @@ -352,7 +352,7 @@ for (;;) case OP_PROP: case OP_NOTPROP: cc += 2; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_NOT_DIGIT: case OP_DIGIT: @@ -433,7 +433,7 @@ for (;;) case OP_CRMINPLUS: case OP_CRPOSPLUS: branchlength++; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CRSTAR: case OP_CRMINSTAR: @@ -1303,7 +1303,7 @@ do case OP_PROP: if (ncode[1] != PT_CLIST) break; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_ANYNL: case OP_CHAR: case OP_CHARI: @@ -1327,7 +1327,7 @@ do tcode = ncode; continue; /* With the following significant opcode */ } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* For a group bracket or a positive assertion without an immediately following mandatory setting, recurse to set bits from within the @@ -1455,7 +1455,7 @@ do case OP_EXACT: tcode += IMM2_SIZE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CHAR: case OP_PLUS: case OP_MINPLUS: @@ -1466,7 +1466,7 @@ do case OP_EXACTI: tcode += IMM2_SIZE; - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: @@ -1602,7 +1602,7 @@ do case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - tcode += IMM2_SIZE; __attribute__((fallthrough)); + tcode += IMM2_SIZE; PCRE2_FALLTHROUGH; case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -1783,7 +1783,7 @@ do /* It seems that the fall through comment must be outside the #ifdef if it is to avoid the gcc compiler warning. */ - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter @@ -1801,7 +1801,7 @@ do #elif PCRE2_CODE_UNIT_WIDTH != 8 SET_BIT(0xFF); /* For characters >= 255 */ #endif - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* Enter here for a positive non-XCLASS. If we have fallen through from an XCLASS, classmap will already be set; just advance the code pointer. diff --git a/src/pcre2_util.h b/src/pcre2_util.h index ea8635552..3de733266 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -127,6 +127,23 @@ the reason and the actions that should be taken if it ever triggers. */ #define PCRE2_ASSERT(x) do {} while(0) #endif +/* We define this fallthrough macro for suppressing -Wno-implicit-fallthrough warnings. +Clang only allows this via an attribute, whereas other compilers (eg. GCC) match attributes +and also specially-formatted comments. + +For maximum portability, please use this macro as: + + PCRE2_FALLTHROUGH // Fall through // */ + +#if defined(__has_attribute) +#if __has_attribute(fallthrough) +#define PCRE2_FALLTHROUGH __attribute__((fallthrough)); +#endif +#endif +#ifndef PCRE2_FALLTHROUGH +#define PCRE2_FALLTHROUGH +#endif + #endif /* PCRE2_UTIL_H_IDEMPOTENT_GUARD */ /* End of pcre2_util.h */ diff --git a/src/pcre2grep.c b/src/pcre2grep.c index d1884063e..469452c2d 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -48,6 +48,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "config.h" #endif +#include "pcre2_util.h" + #include #include #include @@ -2053,7 +2055,7 @@ switch (*(++string)) break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; /* The maximum capture number is 65535, so any number greater than that will always be an unknown capture number. We just stop incrementing, in order to diff --git a/src/pcre2test.c b/src/pcre2test.c index 8b75e9250..e257aea22 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -4445,7 +4445,7 @@ for (;;) *((uint32_t *)field) = (uint32_t)(m->value); break; } - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case MOD_INT: /* Unsigned integer */ if (!isdigit(*pp)) goto INVALID_VALUE; @@ -7542,7 +7542,7 @@ if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0) case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK: fprintf(f, "Backtrack\nNo other matching paths\n"); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case PCRE2_CALLOUT_STARTMATCH: fprintf(f, "New match attempt\n"); @@ -10216,7 +10216,7 @@ for (i = 0; i < MODLISTCOUNT; i++) break; default: printf("** Unknown type for modifier \"%s\"\n", m->name); - __attribute__((fallthrough)); + PCRE2_FALLTHROUGH; case MOD_PD: /* Pattern or subject */ case MOD_PDP: /* As PD, OK for Perl-compatible test */ is_pattern = for_pattern; From db25c8b0cf037192a797b9b2f8082fb224fd1368 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 12:29:34 +0200 Subject: [PATCH 05/17] UPDATE: fix comment. --- src/pcre2_util.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pcre2_util.h b/src/pcre2_util.h index 3de733266..37f3fc1d4 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -127,7 +127,7 @@ the reason and the actions that should be taken if it ever triggers. */ #define PCRE2_ASSERT(x) do {} while(0) #endif -/* We define this fallthrough macro for suppressing -Wno-implicit-fallthrough warnings. +/* We define this fallthrough macro for suppressing -Wimplicit-fallthrough warnings. Clang only allows this via an attribute, whereas other compilers (eg. GCC) match attributes and also specially-formatted comments. From bd6fdc0ef6c18343bae9392ed0578d446ec7462e Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 12:56:28 +0200 Subject: [PATCH 06/17] UPDATE: point out to use the define in conjunction with a comment (I hope single-line comment is acceptable for this) and apply that guideline to all affected locations. if not supported by the compiler let the fallback be the same as for other macro defines. --- src/pcre2_auto_possess.c | 8 ++++---- src/pcre2_compile.c | 34 +++++++++++++++++----------------- src/pcre2_compile_class.c | 4 ++-- src/pcre2_convert.c | 8 ++++---- src/pcre2_dfa_match.c | 12 ++++++------ src/pcre2_match.c | 18 +++++++++--------- src/pcre2_printint_inc.h | 18 +++++++++--------- src/pcre2_study.c | 23 ++++++++++++----------- src/pcre2_util.h | 8 ++++---- src/pcre2grep.c | 2 +- src/pcre2test.c | 6 +++--- 11 files changed, 71 insertions(+), 70 deletions(-) diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c index 8835a753d..3eae9b7d4 100644 --- a/src/pcre2_auto_possess.c +++ b/src/pcre2_auto_possess.c @@ -804,21 +804,21 @@ for(;;) case OP_NOT_DIGIT: invert_bits = TRUE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_DIGIT: set2 = (const uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_WHITESPACE: set2 = (const uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_WORDCHAR: set2 = (const uint8_t *)(cb->cbits + cbit_word); break; @@ -1101,7 +1101,7 @@ for(;;) case OP_NCLASS: if (chr > 255) return FALSE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_CLASS: if (chr > 255) break; diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 192e9a5aa..a4679e148 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -1936,7 +1936,7 @@ else if (c >= CHAR_8) break; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least @@ -2908,21 +2908,21 @@ switch(escape) { case ESC_D: prop = ESC_P; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case ESC_d: ascii_option = PCRE2_EXTRA_ASCII_BSD; break; case ESC_S: prop = ESC_P; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case ESC_s: ascii_option = PCRE2_EXTRA_ASCII_BSS; break; case ESC_W: prop = ESC_P; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case ESC_w: ascii_option = PCRE2_EXTRA_ASCII_BSW; break; @@ -4560,7 +4560,7 @@ while (ptr < ptrend) default: PCRE2_DEBUG_UNREACHABLE(); - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case ESC_A: case ESC_Z: @@ -5224,7 +5224,7 @@ while (ptr < ptrend) ++ptr; goto FAILED_FORWARD; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: @@ -5974,7 +5974,7 @@ for (;;) case OP_UCP_WORD_BOUNDARY: case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_CALLOUT: case OP_CREF: @@ -6493,7 +6493,7 @@ for (;; pptr++) case META_PRUNE: case META_SKIP: cb->had_pruneorskip = TRUE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case META_COMMIT: case META_FAIL: *code++ = verbops[(meta - META_MARK) >> 16]; @@ -6518,7 +6518,7 @@ for (;; pptr++) case META_PRUNE_ARG: case META_SKIP_ARG: cb->had_pruneorskip = TRUE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case META_MARK: case META_COMMIT_ARG: VERB_ARG: @@ -7498,7 +7498,7 @@ for (;; pptr++) group_return = -1; /* Set "may match empty string" */ /* Now treat as a repeated OP_BRA. */ - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* If previous was a bracket group, we may have to replicate it in certain cases. Note that at this point we can encounter only the "basic" @@ -8348,7 +8348,7 @@ for (;; pptr++) if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : OP_UCP_WORD_BOUNDARY; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case ESC_A: if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; @@ -9282,7 +9282,7 @@ do { case OP_EXACT: scode += IMM2_SIZE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_CHAR: case OP_PLUS: @@ -9295,7 +9295,7 @@ do { case OP_EXACTI: scode += IMM2_SIZE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_CHARI: case OP_PLUSI: @@ -9727,7 +9727,7 @@ for (;; pptr++) case META_BACKREF_BYNAME: if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0) goto ISNOTFIXED; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case META_RECURSE_BYNAME: { @@ -9776,7 +9776,7 @@ for (;; pptr++) goto RECURSE_OR_BACKREF_LENGTH; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* For groups >= 10 - picking up group twice does no harm. */ /* A true recursion implies not fixed length, but a subroutine call may @@ -9856,7 +9856,7 @@ for (;; pptr++) case META_CAPTURE: group = META_DATA(*pptr); - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case META_ATOMIC: case META_NOCAPTURE: @@ -9903,7 +9903,7 @@ for (;; pptr++) else itemlength = (max - 1) * lastitemlength; break; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* Any other item means this branch does not have a fixed length. */ diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c index ea7a444cc..0424a04dc 100644 --- a/src/pcre2_compile_class.c +++ b/src/pcre2_compile_class.c @@ -65,7 +65,7 @@ b) none of the cases here: #define CLASS_END_CASES(meta) \ default: \ PCRE2_ASSERT((meta) <= META_END); \ - PCRE2_FALLTHROUGH; \ + PCRE2_FALLTHROUGH; // Fall through \ case META_CLASS: \ case META_CLASS_NOT: \ case META_CLASS_EMPTY: \ @@ -2169,7 +2169,7 @@ switch (meta) } ptr++; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through default: /* Scan forward characters, ranges, and properties. diff --git a/src/pcre2_convert.c b/src/pcre2_convert.c index 7985d442c..34d56349f 100644 --- a/src/pcre2_convert.c +++ b/src/pcre2_convert.c @@ -226,7 +226,7 @@ while (plength > 0) posix++; continue; /* With next character after :] */ } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case POSIX_CLASS_NOT_STARTED: if (c == CHAR_LEFT_SQUARE_BRACKET) @@ -321,7 +321,7 @@ while (plength > 0) case CHAR_LEFT_PARENTHESIS: bracount++; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case CHAR_QUESTION_MARK: case CHAR_PLUS: @@ -329,7 +329,7 @@ while (plength > 0) case CHAR_RIGHT_CURLY_BRACKET: case CHAR_VERTICAL_LINE: if (!extended) goto ESCAPE_LITERAL; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case CHAR_DOT: case CHAR_DOLLAR_SIGN: @@ -358,7 +358,7 @@ while (plength > 0) posix_state = POSIX_ANCHORED; goto COPY_SPECIAL; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through default: if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL) diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c index 112bf60c0..f15ab5fee 100644 --- a/src/pcre2_dfa_match.c +++ b/src/pcre2_dfa_match.c @@ -2328,7 +2328,7 @@ for (;;) case 0x2029: #endif /* Not EBCDIC */ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case CHAR_LF: ADD_NEW(state_offset + 1, 0); @@ -2440,7 +2440,7 @@ for (;;) caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2484,7 +2484,7 @@ for (;;) case OP_NOTPOSQUERYI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2525,7 +2525,7 @@ for (;;) case OP_NOTPOSSTARI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2562,7 +2562,7 @@ for (;;) case OP_NOTEXACTI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ @@ -2597,7 +2597,7 @@ for (;;) case OP_NOTPOSUPTOI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: diff --git a/src/pcre2_match.c b/src/pcre2_match.c index 1625b2991..1ee1ee4c7 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -970,7 +970,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += 1 + LINK_SIZE; continue; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* OP_END itself can never be reached within a recursion because that is picked up when the OP_KET that always precedes OP_END is reached. */ @@ -1054,7 +1054,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, mb->hitend = TRUE; if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* Match any single character whatsoever. */ @@ -6062,7 +6062,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); Foffset_top = assert_accept_frame->offset_top; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* In the case of a match, the captures have already been put into the current frame. */ @@ -6360,7 +6360,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NA: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_ASSERT_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -6374,12 +6374,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_ASSERT: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* For an atomic group, discard internal backtracking points. We must also ensure that any remaining branches within the top-level of the group @@ -6403,7 +6403,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NOT: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); @@ -6537,7 +6537,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* Unconditional end of subject assertion (\z). */ case OP_EOD: @@ -7938,7 +7938,7 @@ for(;;) new_start_match = mb->verb_skip_ptr; break; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. Unset ignore SKIP-with-argument. */ diff --git a/src/pcre2_printint_inc.h b/src/pcre2_printint_inc.h index 4999dda6e..4dce36369 100644 --- a/src/pcre2_printint_inc.h +++ b/src/pcre2_printint_inc.h @@ -583,7 +583,7 @@ if (type == OP_XCLASS) { case XCL_NOTPROP: notch = "^"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case XCL_PROP: { unsigned int ptype = *ccode++; @@ -799,7 +799,7 @@ for(;;) case OP_MINQUERYI: case OP_POSQUERYI: flag = "/i"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -838,7 +838,7 @@ for(;;) case OP_MINUPTOI: case OP_POSUPTOI: flag = "/i"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_EXACT: case OP_UPTO: case OP_MINUPTO: @@ -871,7 +871,7 @@ for(;;) case OP_NOTI: flag = "/i"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); @@ -888,7 +888,7 @@ for(;;) case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: flag = "/i"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_NOTSTAR: case OP_NOTMINSTAR: @@ -909,7 +909,7 @@ for(;;) case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: flag = "/i"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_NOTEXACT: case OP_NOTUPTO: @@ -934,7 +934,7 @@ for(;;) case OP_REFI: flag = "/i"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); i = (*code == OP_REFI)? code[1 + IMM2_SIZE] : 0; @@ -944,7 +944,7 @@ for(;;) case OP_DNREFI: flag = "/i"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_DNREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; @@ -1111,7 +1111,7 @@ for(;;) case OP_CIRCM: case OP_DOLLM: flag = "/m"; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* Anything else is just an item with no data, but possibly a flag. */ diff --git a/src/pcre2_study.c b/src/pcre2_study.c index 909e90185..c34419fa1 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -175,7 +175,7 @@ for (;;) cc += 1 + LINK_SIZE; break; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_ONCE: case OP_SCRIPT_RUN: @@ -252,7 +252,7 @@ for (;;) case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* Skip over things that don't match chars */ @@ -352,7 +352,7 @@ for (;;) case OP_PROP: case OP_NOTPROP: cc += 2; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_NOT_DIGIT: case OP_DIGIT: @@ -433,7 +433,7 @@ for (;;) case OP_CRMINPLUS: case OP_CRPOSPLUS: branchlength++; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_CRSTAR: case OP_CRMINSTAR: @@ -1303,7 +1303,7 @@ do case OP_PROP: if (ncode[1] != PT_CLIST) break; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_ANYNL: case OP_CHAR: case OP_CHARI: @@ -1327,7 +1327,7 @@ do tcode = ncode; continue; /* With the following significant opcode */ } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* For a group bracket or a positive assertion without an immediately following mandatory setting, recurse to set bits from within the @@ -1455,7 +1455,7 @@ do case OP_EXACT: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_CHAR: case OP_PLUS: case OP_MINPLUS: @@ -1466,7 +1466,7 @@ do case OP_EXACTI: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: @@ -1602,7 +1602,8 @@ do case OP_TYPEUPTO: case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: - tcode += IMM2_SIZE; PCRE2_FALLTHROUGH; + tcode += IMM2_SIZE; + PCRE2_FALLTHROUGH; // Fall through case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -1783,7 +1784,7 @@ do /* It seems that the fall through comment must be outside the #ifdef if it is to avoid the gcc compiler warning. */ - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter @@ -1801,7 +1802,7 @@ do #elif PCRE2_CODE_UNIT_WIDTH != 8 SET_BIT(0xFF); /* For characters >= 255 */ #endif - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* Enter here for a positive non-XCLASS. If we have fallen through from an XCLASS, classmap will already be set; just advance the code pointer. diff --git a/src/pcre2_util.h b/src/pcre2_util.h index 37f3fc1d4..6a87330f4 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -131,17 +131,17 @@ the reason and the actions that should be taken if it ever triggers. */ Clang only allows this via an attribute, whereas other compilers (eg. GCC) match attributes and also specially-formatted comments. -For maximum portability, please use this macro as: +For maximum portability, please use this macro together with a fall through comment: - PCRE2_FALLTHROUGH // Fall through // */ + PCRE2_FALLTHROUGH; // Fall through */ #if defined(__has_attribute) #if __has_attribute(fallthrough) -#define PCRE2_FALLTHROUGH __attribute__((fallthrough)); +#define PCRE2_FALLTHROUGH __attribute__((fallthrough)) #endif #endif #ifndef PCRE2_FALLTHROUGH -#define PCRE2_FALLTHROUGH +#define PCRE2_FALLTHROUGH do {} while(0) #endif #endif /* PCRE2_UTIL_H_IDEMPOTENT_GUARD */ diff --git a/src/pcre2grep.c b/src/pcre2grep.c index 469452c2d..ac2746fa4 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -2055,7 +2055,7 @@ switch (*(++string)) break; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through /* The maximum capture number is 65535, so any number greater than that will always be an unknown capture number. We just stop incrementing, in order to diff --git a/src/pcre2test.c b/src/pcre2test.c index e257aea22..baa9e1ffc 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -4445,7 +4445,7 @@ for (;;) *((uint32_t *)field) = (uint32_t)(m->value); break; } - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case MOD_INT: /* Unsigned integer */ if (!isdigit(*pp)) goto INVALID_VALUE; @@ -7542,7 +7542,7 @@ if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0) case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK: fprintf(f, "Backtrack\nNo other matching paths\n"); - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case PCRE2_CALLOUT_STARTMATCH: fprintf(f, "New match attempt\n"); @@ -10216,7 +10216,7 @@ for (i = 0; i < MODLISTCOUNT; i++) break; default: printf("** Unknown type for modifier \"%s\"\n", m->name); - PCRE2_FALLTHROUGH; + PCRE2_FALLTHROUGH; // Fall through case MOD_PD: /* Pattern or subject */ case MOD_PDP: /* As PD, OK for Perl-compatible test */ is_pattern = for_pattern; From 04f83d2675aaa23441909a764dec539313d8c213 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 13:15:38 +0200 Subject: [PATCH 07/17] UPDATE: use C comments. also add that explictly to the comment on how to use the macro. note that some compilers might complain about /* ... /* .. */, such as clang which would yield error: '/*' within block comment [-Werror,-Wcomment]. I hope that is acceptable. --- src/pcre2_auto_possess.c | 8 ++++---- src/pcre2_compile.c | 34 +++++++++++++++++----------------- src/pcre2_compile_class.c | 4 ++-- src/pcre2_convert.c | 8 ++++---- src/pcre2_dfa_match.c | 12 ++++++------ src/pcre2_match.c | 18 +++++++++--------- src/pcre2_printint_inc.h | 18 +++++++++--------- src/pcre2_study.c | 22 +++++++++++----------- src/pcre2_util.h | 2 +- src/pcre2grep.c | 2 +- src/pcre2test.c | 6 +++--- 11 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c index 3eae9b7d4..4fad4c612 100644 --- a/src/pcre2_auto_possess.c +++ b/src/pcre2_auto_possess.c @@ -804,21 +804,21 @@ for(;;) case OP_NOT_DIGIT: invert_bits = TRUE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_DIGIT: set2 = (const uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_WHITESPACE: set2 = (const uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_WORDCHAR: set2 = (const uint8_t *)(cb->cbits + cbit_word); break; @@ -1101,7 +1101,7 @@ for(;;) case OP_NCLASS: if (chr > 255) return FALSE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CLASS: if (chr > 255) break; diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index a4679e148..465dc1363 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -1936,7 +1936,7 @@ else if (c >= CHAR_8) break; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least @@ -2908,21 +2908,21 @@ switch(escape) { case ESC_D: prop = ESC_P; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case ESC_d: ascii_option = PCRE2_EXTRA_ASCII_BSD; break; case ESC_S: prop = ESC_P; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case ESC_s: ascii_option = PCRE2_EXTRA_ASCII_BSS; break; case ESC_W: prop = ESC_P; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case ESC_w: ascii_option = PCRE2_EXTRA_ASCII_BSW; break; @@ -4560,7 +4560,7 @@ while (ptr < ptrend) default: PCRE2_DEBUG_UNREACHABLE(); - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case ESC_A: case ESC_Z: @@ -5224,7 +5224,7 @@ while (ptr < ptrend) ++ptr; goto FAILED_FORWARD; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: @@ -5974,7 +5974,7 @@ for (;;) case OP_UCP_WORD_BOUNDARY: case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CALLOUT: case OP_CREF: @@ -6493,7 +6493,7 @@ for (;; pptr++) case META_PRUNE: case META_SKIP: cb->had_pruneorskip = TRUE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case META_COMMIT: case META_FAIL: *code++ = verbops[(meta - META_MARK) >> 16]; @@ -6518,7 +6518,7 @@ for (;; pptr++) case META_PRUNE_ARG: case META_SKIP_ARG: cb->had_pruneorskip = TRUE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case META_MARK: case META_COMMIT_ARG: VERB_ARG: @@ -7498,7 +7498,7 @@ for (;; pptr++) group_return = -1; /* Set "may match empty string" */ /* Now treat as a repeated OP_BRA. */ - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* If previous was a bracket group, we may have to replicate it in certain cases. Note that at this point we can encounter only the "basic" @@ -8348,7 +8348,7 @@ for (;; pptr++) if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : OP_UCP_WORD_BOUNDARY; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case ESC_A: if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; @@ -9282,7 +9282,7 @@ do { case OP_EXACT: scode += IMM2_SIZE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CHAR: case OP_PLUS: @@ -9295,7 +9295,7 @@ do { case OP_EXACTI: scode += IMM2_SIZE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CHARI: case OP_PLUSI: @@ -9727,7 +9727,7 @@ for (;; pptr++) case META_BACKREF_BYNAME: if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0) goto ISNOTFIXED; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case META_RECURSE_BYNAME: { @@ -9776,7 +9776,7 @@ for (;; pptr++) goto RECURSE_OR_BACKREF_LENGTH; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* For groups >= 10 - picking up group twice does no harm. */ /* A true recursion implies not fixed length, but a subroutine call may @@ -9856,7 +9856,7 @@ for (;; pptr++) case META_CAPTURE: group = META_DATA(*pptr); - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case META_ATOMIC: case META_NOCAPTURE: @@ -9903,7 +9903,7 @@ for (;; pptr++) else itemlength = (max - 1) * lastitemlength; break; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* Any other item means this branch does not have a fixed length. */ diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c index 0424a04dc..813c8a914 100644 --- a/src/pcre2_compile_class.c +++ b/src/pcre2_compile_class.c @@ -65,7 +65,7 @@ b) none of the cases here: #define CLASS_END_CASES(meta) \ default: \ PCRE2_ASSERT((meta) <= META_END); \ - PCRE2_FALLTHROUGH; // Fall through \ + PCRE2_FALLTHROUGH; /* Fall through */ \ case META_CLASS: \ case META_CLASS_NOT: \ case META_CLASS_EMPTY: \ @@ -2169,7 +2169,7 @@ switch (meta) } ptr++; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ default: /* Scan forward characters, ranges, and properties. diff --git a/src/pcre2_convert.c b/src/pcre2_convert.c index 34d56349f..a7893c17e 100644 --- a/src/pcre2_convert.c +++ b/src/pcre2_convert.c @@ -226,7 +226,7 @@ while (plength > 0) posix++; continue; /* With next character after :] */ } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case POSIX_CLASS_NOT_STARTED: if (c == CHAR_LEFT_SQUARE_BRACKET) @@ -321,7 +321,7 @@ while (plength > 0) case CHAR_LEFT_PARENTHESIS: bracount++; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case CHAR_QUESTION_MARK: case CHAR_PLUS: @@ -329,7 +329,7 @@ while (plength > 0) case CHAR_RIGHT_CURLY_BRACKET: case CHAR_VERTICAL_LINE: if (!extended) goto ESCAPE_LITERAL; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case CHAR_DOT: case CHAR_DOLLAR_SIGN: @@ -358,7 +358,7 @@ while (plength > 0) posix_state = POSIX_ANCHORED; goto COPY_SPECIAL; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ default: if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL) diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c index f15ab5fee..ad94f9a8f 100644 --- a/src/pcre2_dfa_match.c +++ b/src/pcre2_dfa_match.c @@ -2328,7 +2328,7 @@ for (;;) case 0x2029: #endif /* Not EBCDIC */ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case CHAR_LF: ADD_NEW(state_offset + 1, 0); @@ -2440,7 +2440,7 @@ for (;;) caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2484,7 +2484,7 @@ for (;;) case OP_NOTPOSQUERYI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2525,7 +2525,7 @@ for (;;) case OP_NOTPOSSTARI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2562,7 +2562,7 @@ for (;;) case OP_NOTEXACTI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ @@ -2597,7 +2597,7 @@ for (;;) case OP_NOTPOSUPTOI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: diff --git a/src/pcre2_match.c b/src/pcre2_match.c index 1ee1ee4c7..de3bf6d00 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -970,7 +970,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += 1 + LINK_SIZE; continue; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* OP_END itself can never be reached within a recursion because that is picked up when the OP_KET that always precedes OP_END is reached. */ @@ -1054,7 +1054,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, mb->hitend = TRUE; if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* Match any single character whatsoever. */ @@ -6062,7 +6062,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); Foffset_top = assert_accept_frame->offset_top; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* In the case of a match, the captures have already been put into the current frame. */ @@ -6360,7 +6360,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NA: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_ASSERT_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -6374,12 +6374,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_ASSERT: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* For an atomic group, discard internal backtracking points. We must also ensure that any remaining branches within the top-level of the group @@ -6403,7 +6403,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NOT: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); @@ -6537,7 +6537,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* Unconditional end of subject assertion (\z). */ case OP_EOD: @@ -7938,7 +7938,7 @@ for(;;) new_start_match = mb->verb_skip_ptr; break; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. Unset ignore SKIP-with-argument. */ diff --git a/src/pcre2_printint_inc.h b/src/pcre2_printint_inc.h index 4dce36369..c1033777e 100644 --- a/src/pcre2_printint_inc.h +++ b/src/pcre2_printint_inc.h @@ -583,7 +583,7 @@ if (type == OP_XCLASS) { case XCL_NOTPROP: notch = "^"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case XCL_PROP: { unsigned int ptype = *ccode++; @@ -799,7 +799,7 @@ for(;;) case OP_MINQUERYI: case OP_POSQUERYI: flag = "/i"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -838,7 +838,7 @@ for(;;) case OP_MINUPTOI: case OP_POSUPTOI: flag = "/i"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_EXACT: case OP_UPTO: case OP_MINUPTO: @@ -871,7 +871,7 @@ for(;;) case OP_NOTI: flag = "/i"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); @@ -888,7 +888,7 @@ for(;;) case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: flag = "/i"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_NOTSTAR: case OP_NOTMINSTAR: @@ -909,7 +909,7 @@ for(;;) case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: flag = "/i"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_NOTEXACT: case OP_NOTUPTO: @@ -934,7 +934,7 @@ for(;;) case OP_REFI: flag = "/i"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_REF: fprintf(f, " %s \\%d", flag, GET2(code,1)); i = (*code == OP_REFI)? code[1 + IMM2_SIZE] : 0; @@ -944,7 +944,7 @@ for(;;) case OP_DNREFI: flag = "/i"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_DNREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; @@ -1111,7 +1111,7 @@ for(;;) case OP_CIRCM: case OP_DOLLM: flag = "/m"; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* Anything else is just an item with no data, but possibly a flag. */ diff --git a/src/pcre2_study.c b/src/pcre2_study.c index c34419fa1..1cfcfc8a5 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -175,7 +175,7 @@ for (;;) cc += 1 + LINK_SIZE; break; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_ONCE: case OP_SCRIPT_RUN: @@ -252,7 +252,7 @@ for (;;) case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* Skip over things that don't match chars */ @@ -352,7 +352,7 @@ for (;;) case OP_PROP: case OP_NOTPROP: cc += 2; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_NOT_DIGIT: case OP_DIGIT: @@ -433,7 +433,7 @@ for (;;) case OP_CRMINPLUS: case OP_CRPOSPLUS: branchlength++; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CRSTAR: case OP_CRMINSTAR: @@ -1303,7 +1303,7 @@ do case OP_PROP: if (ncode[1] != PT_CLIST) break; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_ANYNL: case OP_CHAR: case OP_CHARI: @@ -1327,7 +1327,7 @@ do tcode = ncode; continue; /* With the following significant opcode */ } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* For a group bracket or a positive assertion without an immediately following mandatory setting, recurse to set bits from within the @@ -1455,7 +1455,7 @@ do case OP_EXACT: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CHAR: case OP_PLUS: case OP_MINPLUS: @@ -1466,7 +1466,7 @@ do case OP_EXACTI: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: @@ -1603,7 +1603,7 @@ do case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -1784,7 +1784,7 @@ do /* It seems that the fall through comment must be outside the #ifdef if it is to avoid the gcc compiler warning. */ - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter @@ -1802,7 +1802,7 @@ do #elif PCRE2_CODE_UNIT_WIDTH != 8 SET_BIT(0xFF); /* For characters >= 255 */ #endif - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* Enter here for a positive non-XCLASS. If we have fallen through from an XCLASS, classmap will already be set; just advance the code pointer. diff --git a/src/pcre2_util.h b/src/pcre2_util.h index 6a87330f4..4f1ae62fb 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -131,7 +131,7 @@ the reason and the actions that should be taken if it ever triggers. */ Clang only allows this via an attribute, whereas other compilers (eg. GCC) match attributes and also specially-formatted comments. -For maximum portability, please use this macro together with a fall through comment: +For maximum portability, please use this macro together with a fall through C comment: PCRE2_FALLTHROUGH; // Fall through */ diff --git a/src/pcre2grep.c b/src/pcre2grep.c index ac2746fa4..d26f50889 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -2055,7 +2055,7 @@ switch (*(++string)) break; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ /* The maximum capture number is 65535, so any number greater than that will always be an unknown capture number. We just stop incrementing, in order to diff --git a/src/pcre2test.c b/src/pcre2test.c index baa9e1ffc..284c7ee0c 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -4445,7 +4445,7 @@ for (;;) *((uint32_t *)field) = (uint32_t)(m->value); break; } - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case MOD_INT: /* Unsigned integer */ if (!isdigit(*pp)) goto INVALID_VALUE; @@ -7542,7 +7542,7 @@ if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0) case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK: fprintf(f, "Backtrack\nNo other matching paths\n"); - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case PCRE2_CALLOUT_STARTMATCH: fprintf(f, "New match attempt\n"); @@ -10216,7 +10216,7 @@ for (i = 0; i < MODLISTCOUNT; i++) break; default: printf("** Unknown type for modifier \"%s\"\n", m->name); - PCRE2_FALLTHROUGH; // Fall through + PCRE2_FALLTHROUGH; /* Fall through */ case MOD_PD: /* Pattern or subject */ case MOD_PDP: /* As PD, OK for Perl-compatible test */ is_pattern = for_pattern; From 38a5f1c95d06ee1fca1b6eeb5eefe598aad2ae3d Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 13:23:20 +0200 Subject: [PATCH 08/17] UPDATE: use single line comment to show an example usage. --- src/pcre2_util.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pcre2_util.h b/src/pcre2_util.h index 4f1ae62fb..437adf40a 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -131,9 +131,9 @@ the reason and the actions that should be taken if it ever triggers. */ Clang only allows this via an attribute, whereas other compilers (eg. GCC) match attributes and also specially-formatted comments. -For maximum portability, please use this macro together with a fall through C comment: +For maximum portability, please use this macro together with a fall through C comment, for example: */ - PCRE2_FALLTHROUGH; // Fall through */ +// PCRE2_FALLTHROUGH; /* Fall through */ #if defined(__has_attribute) #if __has_attribute(fallthrough) From ddb00400f25d484a51aa4198ca0b17ea94927d74 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 13:27:55 +0200 Subject: [PATCH 09/17] UPDATE: add -Wimplicit-fallthrough. I hope this is the correct spot to change. --- .github/workflows/build.yml | 2 +- .github/workflows/dev.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7ac5d8a98..74eceb342 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,7 @@ permissions: contents: read env: - CFLAGS_GCC_STYLE: '-Wall -Wextra -pedantic -Wdeclaration-after-statement -Wshadow -Wno-overlength-strings' + CFLAGS_GCC_STYLE: '-Wall -Wextra -pedantic -Wdeclaration-after-statement -Wshadow -Wno-overlength-strings -Wimplicit-fallthrough' CFLAGS_MSVC: '/W3' CFLAGS_SOLARIS_CC: '-errtags=yes -erroff=E_STATEMENT_NOT_REACHED' CMAKE_FLAGS: '-Wdev -Werror=dev -Wdeprecated -Werror=deprecated --warn-uninitialized' diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index abf7c8baf..e77f696c7 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -10,7 +10,7 @@ permissions: contents: read env: - CFLAGS_GCC_STYLE: '-Wall -Wextra -pedantic -Wdeclaration-after-statement -Wshadow -Wno-overlength-strings' + CFLAGS_GCC_STYLE: '-Wall -Wextra -pedantic -Wdeclaration-after-statement -Wshadow -Wno-overlength-strings -Wimplicit-fallthrough' CFLAGS_MSVC: '/W3' CMAKE_FLAGS: '-Wdev -Werror=dev -Wdeprecated -Werror=deprecated --warn-uninitialized' From 7a2c156555f8567a278415a8aca8e1fee77b5987 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 13:31:30 +0200 Subject: [PATCH 10/17] UPDATE: introduce __has_c_attribute to check whether compiler supports [[fallthrough]]. if not, fallback to previous behavior. --- src/pcre2_util.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/pcre2_util.h b/src/pcre2_util.h index 437adf40a..c464291c9 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -135,7 +135,12 @@ For maximum portability, please use this macro together with a fall through C co // PCRE2_FALLTHROUGH; /* Fall through */ -#if defined(__has_attribute) +#if defined(__has_c_attribute) +#if __has_c_attribute(fallthrough) +#define PCRE2_FALLTHROUGH [[fallthrough]] +#endif +#endif +#if defined(__has_attribute) && !defined(PCRE2_FALLTHROUGH) #if __has_attribute(fallthrough) #define PCRE2_FALLTHROUGH __attribute__((fallthrough)) #endif From 1f8a83fdba15bd5ba33dc08b682208e6614fc3c6 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 13:52:29 +0200 Subject: [PATCH 11/17] UPDATE: check the C standard version. replace [[fallthrough]] by [[__fallthrough__]] so there is no possibility of an accidental '#define fallthrough'. --- src/pcre2_util.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pcre2_util.h b/src/pcre2_util.h index c464291c9..6729432a9 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -136,8 +136,8 @@ For maximum portability, please use this macro together with a fall through C co // PCRE2_FALLTHROUGH; /* Fall through */ #if defined(__has_c_attribute) -#if __has_c_attribute(fallthrough) -#define PCRE2_FALLTHROUGH [[fallthrough]] +#if __has_c_attribute(fallthrough) && __STDC_VERSION__ >= 202311L +#define PCRE2_FALLTHROUGH [[__fallthrough__]] #endif #endif #if defined(__has_attribute) && !defined(PCRE2_FALLTHROUGH) From 9a72a66f6fe52853338a7928cca52c4404eded59 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 14:17:15 +0200 Subject: [PATCH 12/17] UPDATE: use underscored version of fallthrough attribute. mind that is inconsistent to, e.g., __attribute__((uninitialized)) from pcre2_internal.h (yet, making the usage of attributes consistent is IMHO outside the scope of this pull request). --- src/pcre2_util.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pcre2_util.h b/src/pcre2_util.h index 6729432a9..0cda54361 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -136,13 +136,13 @@ For maximum portability, please use this macro together with a fall through C co // PCRE2_FALLTHROUGH; /* Fall through */ #if defined(__has_c_attribute) -#if __has_c_attribute(fallthrough) && __STDC_VERSION__ >= 202311L +#if __has_c_attribute(__fallthrough__) && __STDC_VERSION__ >= 202311L #define PCRE2_FALLTHROUGH [[__fallthrough__]] #endif #endif #if defined(__has_attribute) && !defined(PCRE2_FALLTHROUGH) -#if __has_attribute(fallthrough) -#define PCRE2_FALLTHROUGH __attribute__((fallthrough)) +#if __has_attribute(__fallthrough__) +#define PCRE2_FALLTHROUGH __attribute__((__fallthrough__)) #endif #endif #ifndef PCRE2_FALLTHROUGH From 424078615d61870fd174afef37be46e79abcd6e1 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 14:33:40 +0200 Subject: [PATCH 13/17] UPDATE: first test C standard version then check for __fallthrough__ C attribute support. --- src/pcre2_util.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/pcre2_util.h b/src/pcre2_util.h index 0cda54361..f076008af 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -135,11 +135,13 @@ For maximum portability, please use this macro together with a fall through C co // PCRE2_FALLTHROUGH; /* Fall through */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L #if defined(__has_c_attribute) -#if __has_c_attribute(__fallthrough__) && __STDC_VERSION__ >= 202311L +#if __has_c_attribute(__fallthrough__) #define PCRE2_FALLTHROUGH [[__fallthrough__]] #endif #endif +#endif #if defined(__has_attribute) && !defined(PCRE2_FALLTHROUGH) #if __has_attribute(__fallthrough__) #define PCRE2_FALLTHROUGH __attribute__((__fallthrough__)) From 53f1896ea7411dbb3442758e566fea8549e382cd Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 14:50:05 +0200 Subject: [PATCH 14/17] UPDATE: add missing PCRE2_FALLTHROUGH for JIT compiler. --- src/pcre2_jit_char_inc.h | 4 ++-- src/pcre2_jit_compile.c | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/pcre2_jit_char_inc.h b/src/pcre2_jit_char_inc.h index 475895405..d975d75ab 100644 --- a/src/pcre2_jit_char_inc.h +++ b/src/pcre2_jit_char_inc.h @@ -570,7 +570,7 @@ while (*cc == XCL_PROP || *cc == XCL_NOTPROP) break; } compares++; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case PT_SC: status |= XCLASS_HAS_SCRIPT; @@ -770,7 +770,7 @@ if (status & XCLASS_NEEDS_UCD) case PT_SCX: if (cc[-1] == XCL_NOTPROP) break; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case PT_SC: compares--; diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c index f50a73cd1..b31c1c408 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c @@ -1245,7 +1245,7 @@ while (cc < ccend) case OP_DNREFI: case OP_DNREF: locals_size = ref_update_local_size(common, cc, locals_size); - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_DNCREF: count = GET2(cc, 1 + IMM2_SIZE); slot = common->name_table + GET2(cc, 1) * common->name_entry_size; @@ -1334,7 +1334,7 @@ while (cc < ccend) if (common->utf && locals_size <= 3 * SSIZE_OF(sw)) locals_size = 3 * SSIZE_OF(sw); #endif - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ default: cc = next_opcode(common, cc); if (cc == NULL) @@ -1483,7 +1483,7 @@ do case OP_TYPEMINPLUS: if (count == 2) count = 3; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_TYPESTAR: case OP_TYPEPLUS: @@ -1512,7 +1512,7 @@ do case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: cc += IMM2_SIZE; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_TYPEQUERY: case OP_TYPEMINQUERY: @@ -1533,7 +1533,7 @@ do case OP_NOTMINPLUSI: if (count == 2) count = 3; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_STAR: case OP_PLUS: @@ -1586,7 +1586,7 @@ do case OP_NOTEXACTI: case OP_NOTPOSUPTOI: cc += IMM2_SIZE; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_QUERY: case OP_MINQUERY: @@ -1626,7 +1626,7 @@ do case OP_CRMINPLUS: if (count == 2) count = 3; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CRSTAR: case OP_CRPLUS: @@ -1648,7 +1648,7 @@ do } cc += 2 * IMM2_SIZE; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CRQUERY: case OP_CRMINQUERY: case OP_CRPOSQUERY: @@ -5947,7 +5947,7 @@ while (TRUE) { case OP_CHARI: caseless = TRUE; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CHAR: last = FALSE; cc++; @@ -5984,7 +5984,7 @@ while (TRUE) case OP_MINPLUSI: case OP_POSPLUSI: caseless = TRUE; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -5993,7 +5993,7 @@ while (TRUE) case OP_EXACTI: caseless = TRUE; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_EXACT: repeat = GET2(cc, 1); last = FALSE; @@ -6004,7 +6004,7 @@ while (TRUE) case OP_MINQUERYI: case OP_POSQUERYI: caseless = TRUE; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -6219,7 +6219,7 @@ while (TRUE) case OP_CRMINQUERY: case OP_CRPOSQUERY: last = FALSE; - /* Fall through */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPOSSTAR: From e666bb136c4e3ee633739011886580875a8c83e5 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Wed, 3 Sep 2025 15:13:49 +0200 Subject: [PATCH 15/17] UPDATE: add further missing PCRE2_FALLTHROUGH for JIT compiler. --- src/pcre2_jit_compile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c index b31c1c408..59527991f 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c @@ -1284,7 +1284,7 @@ while (cc < ccend) case OP_THEN_ARG: common->has_then = TRUE; common->control_head_ptr = 1; - /* Fall through. */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_COMMIT_ARG: case OP_PRUNE_ARG: @@ -2268,7 +2268,7 @@ while (cc < ccend) default: stack_restore = TRUE; - /* Fall through. */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: @@ -6136,7 +6136,7 @@ while (TRUE) case OP_NOT: case OP_NOTI: cc++; - /* Fall through. */ + PCRE2_FALLTHROUGH; /* Fall through */ case OP_NOT_DIGIT: case OP_NOT_WHITESPACE: case OP_NOT_WORDCHAR: From 6a67aa29fd5cccc519b8203355a0f3fc65dc9095 Mon Sep 17 00:00:00 2001 From: Gernot Gebhard Date: Thu, 4 Sep 2025 07:07:33 +0200 Subject: [PATCH 16/17] UPDATE: (try to) fix compile issue of manyconfig test. --- src/pcre2_study.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pcre2_study.c b/src/pcre2_study.c index 1cfcfc8a5..b33765fa5 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -1799,10 +1799,11 @@ do re->start_bitmap[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ memset(re->start_bitmap+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ } + PCRE2_FALLTHROUGH; /* Fall through */ #elif PCRE2_CODE_UNIT_WIDTH != 8 SET_BIT(0xFF); /* For characters >= 255 */ -#endif PCRE2_FALLTHROUGH; /* Fall through */ +#endif /* Enter here for a positive non-XCLASS. If we have fallen through from an XCLASS, classmap will already be set; just advance the code pointer. From 4a87255848fe7b13e831a1b04df3c645b2fb5c1e Mon Sep 17 00:00:00 2001 From: Nicholas Wilson Date: Fri, 12 Sep 2025 13:23:57 +0000 Subject: [PATCH 17/17] Update with further changes from the sljit PRs --- src/pcre2_auto_possess.c | 8 ++++---- src/pcre2_compile.c | 34 +++++++++++++++++----------------- src/pcre2_compile_class.c | 4 ++-- src/pcre2_convert.c | 8 ++++---- src/pcre2_dfa_match.c | 12 ++++++------ src/pcre2_jit_char_inc.h | 4 ++-- src/pcre2_jit_compile.c | 32 ++++++++++++++++---------------- src/pcre2_match.c | 18 +++++++++--------- src/pcre2_printint_inc.h | 18 +++++++++--------- src/pcre2_study.c | 26 +++++++++++++------------- src/pcre2_util.h | 37 ++++++++++++++++++++++++++----------- src/pcre2grep.c | 2 +- src/pcre2test.c | 6 +++--- 13 files changed, 112 insertions(+), 97 deletions(-) diff --git a/src/pcre2_auto_possess.c b/src/pcre2_auto_possess.c index 4fad4c612..2f706b791 100644 --- a/src/pcre2_auto_possess.c +++ b/src/pcre2_auto_possess.c @@ -804,21 +804,21 @@ for(;;) case OP_NOT_DIGIT: invert_bits = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_DIGIT: set2 = (const uint8_t *)(cb->cbits + cbit_digit); break; case OP_NOT_WHITESPACE: invert_bits = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_WHITESPACE: set2 = (const uint8_t *)(cb->cbits + cbit_space); break; case OP_NOT_WORDCHAR: invert_bits = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_WORDCHAR: set2 = (const uint8_t *)(cb->cbits + cbit_word); break; @@ -1101,7 +1101,7 @@ for(;;) case OP_NCLASS: if (chr > 255) return FALSE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CLASS: if (chr > 255) break; diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index 465dc1363..fbb1cecce 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -1936,7 +1936,7 @@ else if (c >= CHAR_8) break; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. The original code used just to take the least @@ -2908,21 +2908,21 @@ switch(escape) { case ESC_D: prop = ESC_P; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case ESC_d: ascii_option = PCRE2_EXTRA_ASCII_BSD; break; case ESC_S: prop = ESC_P; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case ESC_s: ascii_option = PCRE2_EXTRA_ASCII_BSS; break; case ESC_W: prop = ESC_P; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case ESC_w: ascii_option = PCRE2_EXTRA_ASCII_BSW; break; @@ -4560,7 +4560,7 @@ while (ptr < ptrend) default: PCRE2_DEBUG_UNREACHABLE(); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case ESC_A: case ESC_Z: @@ -5224,7 +5224,7 @@ while (ptr < ptrend) ++ptr; goto FAILED_FORWARD; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9: @@ -5974,7 +5974,7 @@ for (;;) case OP_UCP_WORD_BOUNDARY: case OP_NOT_UCP_WORD_BOUNDARY: if (!skipassert) return code; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CALLOUT: case OP_CREF: @@ -6493,7 +6493,7 @@ for (;; pptr++) case META_PRUNE: case META_SKIP: cb->had_pruneorskip = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case META_COMMIT: case META_FAIL: *code++ = verbops[(meta - META_MARK) >> 16]; @@ -6518,7 +6518,7 @@ for (;; pptr++) case META_PRUNE_ARG: case META_SKIP_ARG: cb->had_pruneorskip = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case META_MARK: case META_COMMIT_ARG: VERB_ARG: @@ -7498,7 +7498,7 @@ for (;; pptr++) group_return = -1; /* Set "may match empty string" */ /* Now treat as a repeated OP_BRA. */ - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* If previous was a bracket group, we may have to replicate it in certain cases. Note that at this point we can encounter only the "basic" @@ -8348,7 +8348,7 @@ for (;; pptr++) if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0) meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY : OP_UCP_WORD_BOUNDARY; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case ESC_A: if (cb->max_lookbehind == 0) cb->max_lookbehind = 1; @@ -9282,7 +9282,7 @@ do { case OP_EXACT: scode += IMM2_SIZE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CHAR: case OP_PLUS: @@ -9295,7 +9295,7 @@ do { case OP_EXACTI: scode += IMM2_SIZE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CHARI: case OP_PLUSI: @@ -9727,7 +9727,7 @@ for (;; pptr++) case META_BACKREF_BYNAME: if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0) goto ISNOTFIXED; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case META_RECURSE_BYNAME: { @@ -9776,7 +9776,7 @@ for (;; pptr++) goto RECURSE_OR_BACKREF_LENGTH; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* For groups >= 10 - picking up group twice does no harm. */ /* A true recursion implies not fixed length, but a subroutine call may @@ -9856,7 +9856,7 @@ for (;; pptr++) case META_CAPTURE: group = META_DATA(*pptr); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case META_ATOMIC: case META_NOCAPTURE: @@ -9903,7 +9903,7 @@ for (;; pptr++) else itemlength = (max - 1) * lastitemlength; break; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* Any other item means this branch does not have a fixed length. */ diff --git a/src/pcre2_compile_class.c b/src/pcre2_compile_class.c index 813c8a914..edd5ab316 100644 --- a/src/pcre2_compile_class.c +++ b/src/pcre2_compile_class.c @@ -65,7 +65,7 @@ b) none of the cases here: #define CLASS_END_CASES(meta) \ default: \ PCRE2_ASSERT((meta) <= META_END); \ - PCRE2_FALLTHROUGH; /* Fall through */ \ + PCRE2_FALLTHROUGH /* Fall through */ \ case META_CLASS: \ case META_CLASS_NOT: \ case META_CLASS_EMPTY: \ @@ -2169,7 +2169,7 @@ switch (meta) } ptr++; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ default: /* Scan forward characters, ranges, and properties. diff --git a/src/pcre2_convert.c b/src/pcre2_convert.c index a7893c17e..6b1da1ba8 100644 --- a/src/pcre2_convert.c +++ b/src/pcre2_convert.c @@ -226,7 +226,7 @@ while (plength > 0) posix++; continue; /* With next character after :] */ } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case POSIX_CLASS_NOT_STARTED: if (c == CHAR_LEFT_SQUARE_BRACKET) @@ -321,7 +321,7 @@ while (plength > 0) case CHAR_LEFT_PARENTHESIS: bracount++; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case CHAR_QUESTION_MARK: case CHAR_PLUS: @@ -329,7 +329,7 @@ while (plength > 0) case CHAR_RIGHT_CURLY_BRACKET: case CHAR_VERTICAL_LINE: if (!extended) goto ESCAPE_LITERAL; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case CHAR_DOT: case CHAR_DOLLAR_SIGN: @@ -358,7 +358,7 @@ while (plength > 0) posix_state = POSIX_ANCHORED; goto COPY_SPECIAL; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ default: if (c < 255 && strchr(pcre2_escaped_literals, c) != NULL) diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c index ad94f9a8f..3a7902454 100644 --- a/src/pcre2_dfa_match.c +++ b/src/pcre2_dfa_match.c @@ -2328,7 +2328,7 @@ for (;;) case 0x2029: #endif /* Not EBCDIC */ if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case CHAR_LF: ADD_NEW(state_offset + 1, 0); @@ -2440,7 +2440,7 @@ for (;;) caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -2484,7 +2484,7 @@ for (;;) case OP_NOTPOSQUERYI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -2525,7 +2525,7 @@ for (;;) case OP_NOTPOSSTARI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -2562,7 +2562,7 @@ for (;;) case OP_NOTEXACTI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_EXACT: case OP_NOTEXACT: count = current_state->count; /* Number already matched */ @@ -2597,7 +2597,7 @@ for (;;) case OP_NOTPOSUPTOI: caseless = TRUE; codevalue -= OP_STARI - OP_STAR; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_UPTO: case OP_MINUPTO: case OP_POSUPTO: diff --git a/src/pcre2_jit_char_inc.h b/src/pcre2_jit_char_inc.h index d975d75ab..864a5fdeb 100644 --- a/src/pcre2_jit_char_inc.h +++ b/src/pcre2_jit_char_inc.h @@ -570,7 +570,7 @@ while (*cc == XCL_PROP || *cc == XCL_NOTPROP) break; } compares++; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case PT_SC: status |= XCLASS_HAS_SCRIPT; @@ -770,7 +770,7 @@ if (status & XCLASS_NEEDS_UCD) case PT_SCX: if (cc[-1] == XCL_NOTPROP) break; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case PT_SC: compares--; diff --git a/src/pcre2_jit_compile.c b/src/pcre2_jit_compile.c index 59527991f..af8ca45ad 100644 --- a/src/pcre2_jit_compile.c +++ b/src/pcre2_jit_compile.c @@ -1245,7 +1245,7 @@ while (cc < ccend) case OP_DNREFI: case OP_DNREF: locals_size = ref_update_local_size(common, cc, locals_size); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_DNCREF: count = GET2(cc, 1 + IMM2_SIZE); slot = common->name_table + GET2(cc, 1) * common->name_entry_size; @@ -1284,7 +1284,7 @@ while (cc < ccend) case OP_THEN_ARG: common->has_then = TRUE; common->control_head_ptr = 1; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_COMMIT_ARG: case OP_PRUNE_ARG: @@ -1334,7 +1334,7 @@ while (cc < ccend) if (common->utf && locals_size <= 3 * SSIZE_OF(sw)) locals_size = 3 * SSIZE_OF(sw); #endif - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ default: cc = next_opcode(common, cc); if (cc == NULL) @@ -1483,7 +1483,7 @@ do case OP_TYPEMINPLUS: if (count == 2) count = 3; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_TYPESTAR: case OP_TYPEPLUS: @@ -1512,7 +1512,7 @@ do case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: cc += IMM2_SIZE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_TYPEQUERY: case OP_TYPEMINQUERY: @@ -1533,7 +1533,7 @@ do case OP_NOTMINPLUSI: if (count == 2) count = 3; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_STAR: case OP_PLUS: @@ -1586,7 +1586,7 @@ do case OP_NOTEXACTI: case OP_NOTPOSUPTOI: cc += IMM2_SIZE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_QUERY: case OP_MINQUERY: @@ -1626,7 +1626,7 @@ do case OP_CRMINPLUS: if (count == 2) count = 3; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CRSTAR: case OP_CRPLUS: @@ -1648,7 +1648,7 @@ do } cc += 2 * IMM2_SIZE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CRQUERY: case OP_CRMINQUERY: case OP_CRPOSQUERY: @@ -2268,7 +2268,7 @@ while (cc < ccend) default: stack_restore = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: @@ -5947,7 +5947,7 @@ while (TRUE) { case OP_CHARI: caseless = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CHAR: last = FALSE; cc++; @@ -5984,7 +5984,7 @@ while (TRUE) case OP_MINPLUSI: case OP_POSPLUSI: caseless = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_PLUS: case OP_MINPLUS: case OP_POSPLUS: @@ -5993,7 +5993,7 @@ while (TRUE) case OP_EXACTI: caseless = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_EXACT: repeat = GET2(cc, 1); last = FALSE; @@ -6004,7 +6004,7 @@ while (TRUE) case OP_MINQUERYI: case OP_POSQUERYI: caseless = TRUE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_QUERY: case OP_MINQUERY: case OP_POSQUERY: @@ -6136,7 +6136,7 @@ while (TRUE) case OP_NOT: case OP_NOTI: cc++; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_NOT_DIGIT: case OP_NOT_WHITESPACE: case OP_NOT_WORDCHAR: @@ -6219,7 +6219,7 @@ while (TRUE) case OP_CRMINQUERY: case OP_CRPOSQUERY: last = FALSE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPOSSTAR: diff --git a/src/pcre2_match.c b/src/pcre2_match.c index de3bf6d00..53f9080b0 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -970,7 +970,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, Fecode += 1 + LINK_SIZE; continue; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* OP_END itself can never be reached within a recursion because that is picked up when the OP_KET that always precedes OP_END is reached. */ @@ -1054,7 +1054,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, mb->hitend = TRUE; if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* Match any single character whatsoever. */ @@ -6062,7 +6062,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, assert_accept_frame->offset_top * sizeof(PCRE2_SIZE)); Foffset_top = assert_accept_frame->offset_top; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* In the case of a match, the captures have already been put into the current frame. */ @@ -6360,7 +6360,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NA: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_ASSERT_NA: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; @@ -6374,12 +6374,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_ASSERT: if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr; Feptr = P->eptr; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* For an atomic group, discard internal backtracking points. We must also ensure that any remaining branches within the top-level of the group @@ -6403,7 +6403,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, case OP_ASSERTBACK_NOT: if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr) RRETURN(MATCH_NOMATCH); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_ASSERT_NOT: RRETURN(MATCH_MATCH); @@ -6537,7 +6537,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode, if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH); if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* Unconditional end of subject assertion (\z). */ case OP_EOD: @@ -7938,7 +7938,7 @@ for(;;) new_start_match = mb->verb_skip_ptr; break; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* NOMATCH and PRUNE advance by one character. THEN at this level acts exactly like PRUNE. Unset ignore SKIP-with-argument. */ diff --git a/src/pcre2_printint_inc.h b/src/pcre2_printint_inc.h index 78c29b9ac..4dd689e38 100644 --- a/src/pcre2_printint_inc.h +++ b/src/pcre2_printint_inc.h @@ -583,7 +583,7 @@ if (type == OP_XCLASS) { case XCL_NOTPROP: notch = "^"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case XCL_PROP: { unsigned int ptype = *ccode++; @@ -773,7 +773,7 @@ for(;;) case OP_MINQUERYI: case OP_POSQUERYI: flag = "/i"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_STAR: case OP_MINSTAR: case OP_POSSTAR: @@ -812,7 +812,7 @@ for(;;) case OP_MINUPTOI: case OP_POSUPTOI: flag = "/i"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_EXACT: case OP_UPTO: case OP_MINUPTO: @@ -845,7 +845,7 @@ for(;;) case OP_NOTI: flag = "/i"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_NOT: fprintf(f, " %s [^", flag); extra = print_char(f, code + 1, utf); @@ -862,7 +862,7 @@ for(;;) case OP_NOTMINQUERYI: case OP_NOTPOSQUERYI: flag = "/i"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_NOTSTAR: case OP_NOTMINSTAR: @@ -883,7 +883,7 @@ for(;;) case OP_NOTMINUPTOI: case OP_NOTPOSUPTOI: flag = "/i"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_NOTEXACT: case OP_NOTUPTO: @@ -908,7 +908,7 @@ for(;;) case OP_REFI: flag = "/i"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_REF: fprintf(f, " %s \\g{%d}", flag, GET2(code, 1)); i = (*code == OP_REFI)? code[1 + IMM2_SIZE] : 0; @@ -918,7 +918,7 @@ for(;;) case OP_DNREFI: flag = "/i"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_DNREF: { PCRE2_SPTR entry = nametable + (GET2(code, 1) * nesize) + IMM2_SIZE; @@ -1081,7 +1081,7 @@ for(;;) case OP_CIRCM: case OP_DOLLM: flag = "/m"; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* Anything else is just an item with no data, but possibly a flag. */ diff --git a/src/pcre2_study.c b/src/pcre2_study.c index b33765fa5..5dc339b0d 100644 --- a/src/pcre2_study.c +++ b/src/pcre2_study.c @@ -175,7 +175,7 @@ for (;;) cc += 1 + LINK_SIZE; break; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_ONCE: case OP_SCRIPT_RUN: @@ -252,7 +252,7 @@ for (;;) case OP_ASSERT_SCS: case OP_ASSERTBACK_NA: do cc += GET(cc, 1); while (*cc == OP_ALT); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* Skip over things that don't match chars */ @@ -352,7 +352,7 @@ for (;;) case OP_PROP: case OP_NOTPROP: cc += 2; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_NOT_DIGIT: case OP_DIGIT: @@ -433,7 +433,7 @@ for (;;) case OP_CRMINPLUS: case OP_CRPOSPLUS: branchlength++; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CRSTAR: case OP_CRMINSTAR: @@ -1303,7 +1303,7 @@ do case OP_PROP: if (ncode[1] != PT_CLIST) break; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_ANYNL: case OP_CHAR: case OP_CHARI: @@ -1327,7 +1327,7 @@ do tcode = ncode; continue; /* With the following significant opcode */ } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* For a group bracket or a positive assertion without an immediately following mandatory setting, recurse to set bits from within the @@ -1455,7 +1455,7 @@ do case OP_EXACT: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CHAR: case OP_PLUS: case OP_MINPLUS: @@ -1466,7 +1466,7 @@ do case OP_EXACTI: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_CHARI: case OP_PLUSI: case OP_MINPLUSI: @@ -1603,7 +1603,7 @@ do case OP_TYPEMINUPTO: case OP_TYPEPOSUPTO: tcode += IMM2_SIZE; - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case OP_TYPESTAR: case OP_TYPEMINSTAR: @@ -1784,7 +1784,7 @@ do /* It seems that the fall through comment must be outside the #ifdef if it is to avoid the gcc compiler warning. */ - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* Enter here for a negative non-XCLASS. In the 8-bit library, if we are in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter @@ -1799,15 +1799,15 @@ do re->start_bitmap[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ memset(re->start_bitmap+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ #elif PCRE2_CODE_UNIT_WIDTH != 8 SET_BIT(0xFF); /* For characters >= 255 */ - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ #endif /* Enter here for a positive non-XCLASS. If we have fallen through from an XCLASS, classmap will already be set; just advance the code pointer. - Otherwise, set up classmap for a a non-XCLASS and advance past it. */ + Otherwise, set up classmap for a non-XCLASS and advance past it. */ case OP_CLASS: if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else diff --git a/src/pcre2_util.h b/src/pcre2_util.h index f076008af..0fe5b5503 100644 --- a/src/pcre2_util.h +++ b/src/pcre2_util.h @@ -131,24 +131,39 @@ the reason and the actions that should be taken if it ever triggers. */ Clang only allows this via an attribute, whereas other compilers (eg. GCC) match attributes and also specially-formatted comments. -For maximum portability, please use this macro together with a fall through C comment, for example: */ +This macro should be used with no following semicolon, and ideally with a comment: */ -// PCRE2_FALLTHROUGH; /* Fall through */ +// PCRE2_FALLTHROUGH /* Fall through */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L -#if defined(__has_c_attribute) -#if __has_c_attribute(__fallthrough__) -#define PCRE2_FALLTHROUGH [[__fallthrough__]] -#endif +#ifndef PCRE2_FALLTHROUGH + +#if defined(__cplusplus) && __cplusplus >= 202002L && \ + defined(__has_cpp_attribute) +/* Standards-compatible C++ variant. */ +#if __has_cpp_attribute(fallthrough) +#define PCRE2_FALLTHROUGH [[fallthrough]]; #endif +#elif !defined(__cplusplus) && \ + defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L && \ + defined(__has_c_attribute) +/* Standards-compatible C variant. */ +#if __has_c_attribute(fallthrough) +#define PCRE2_FALLTHROUGH [[fallthrough]]; #endif -#if defined(__has_attribute) && !defined(PCRE2_FALLTHROUGH) -#if __has_attribute(__fallthrough__) -#define PCRE2_FALLTHROUGH __attribute__((__fallthrough__)) +#elif ((defined(__clang__) && __clang_major__ >= 10) || \ + (defined(__GNUC__) && __GNUC__ >= 7)) && \ + defined(__has_attribute) +/* Clang and GCC syntax. Rule out old versions because apparently Clang at + least has a broken implementation of __has_attribute. */ +#if __has_attribute(fallthrough) +#define PCRE2_FALLTHROUGH __attribute__((fallthrough)); #endif #endif + +#endif /* !PCRE2_FALLTHROUGH */ + #ifndef PCRE2_FALLTHROUGH -#define PCRE2_FALLTHROUGH do {} while(0) +#define PCRE2_FALLTHROUGH #endif #endif /* PCRE2_UTIL_H_IDEMPOTENT_GUARD */ diff --git a/src/pcre2grep.c b/src/pcre2grep.c index d26f50889..4b8887ee6 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -2055,7 +2055,7 @@ switch (*(++string)) break; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ /* The maximum capture number is 65535, so any number greater than that will always be an unknown capture number. We just stop incrementing, in order to diff --git a/src/pcre2test.c b/src/pcre2test.c index 31d07988a..88e570a6b 100644 --- a/src/pcre2test.c +++ b/src/pcre2test.c @@ -4445,7 +4445,7 @@ for (;;) *((uint32_t *)field) = (uint32_t)(m->value); break; } - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case MOD_INT: /* Unsigned integer */ if (!isdigit(*pp)) goto INVALID_VALUE; @@ -7542,7 +7542,7 @@ if ((dat_datctl.control2 & CTL2_CALLOUT_EXTRA) != 0) case PCRE2_CALLOUT_STARTMATCH|PCRE2_CALLOUT_BACKTRACK: fprintf(f, "Backtrack\nNo other matching paths\n"); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case PCRE2_CALLOUT_STARTMATCH: fprintf(f, "New match attempt\n"); @@ -10221,7 +10221,7 @@ for (i = 0; i < MODLISTCOUNT; i++) break; default: printf("** Unknown type for modifier \"%s\"\n", m->name); - PCRE2_FALLTHROUGH; /* Fall through */ + PCRE2_FALLTHROUGH /* Fall through */ case MOD_PD: /* Pattern or subject */ case MOD_PDP: /* As PD, OK for Perl-compatible test */ is_pattern = for_pattern;