mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00

When compiling with "-Wall -Werror" gcc emits two errors: ../src/pcre2_jit_neon_inc.h:211:8: error: ‘cmp1b’ is used uninitialized in this function [-Werror=uninitialized] 211 | data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../src/pcre2_jit_neon_inc.h:212:9: error: ‘cmp2b’ is used uninitialized in this function [-Werror=uninitialized] 212 | data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The compiler emits the error message before inlining. Because the warning is based on an intra-procedural data flow analysis, the compiler does not see that cmp1b and cmp2b are not used when they are not initialized. Here is the code of that function, cmp2 is only used when ctype is compare_match2 or compare_match1i, and not when ctype is compare_match1: static inline vect_t fast_forward_char_pair_compare(compare_type ctype, vect_t dst, vect_t cmp1, vect_t cmp2) { if (ctype == compare_match2) { vect_t tmp = dst; dst = VCEQQ(dst, cmp1); tmp = VCEQQ(tmp, cmp2); dst = VORRQ(dst, tmp); return dst; } if (ctype == compare_match1i) dst = VORRQ(dst, cmp2); dst = VCEQQ(dst, cmp1); return dst; } The patch inlines by hand the case of compare_match1 such that the code avoids referring to cmp1b and cmp2b. Tested on aarch64-linux with `make check`.
343 lines
8.2 KiB
C
343 lines
8.2 KiB
C
/*************************************************
|
|
* Perl-Compatible Regular Expressions *
|
|
*************************************************/
|
|
|
|
/* PCRE is a library of functions to support regular expressions whose syntax
|
|
and semantics are as close as possible to those of the Perl 5 language.
|
|
|
|
Written by Philip Hazel
|
|
This module by Zoltan Herczeg and Sebastian Pop
|
|
Original API code Copyright (c) 1997-2012 University of Cambridge
|
|
New API code Copyright (c) 2016-2019 University of Cambridge
|
|
|
|
-----------------------------------------------------------------------------
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
* Redistributions of source code must retain the above copyright notice,
|
|
this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the University of Cambridge nor the names of its
|
|
contributors may be used to endorse or promote products derived from
|
|
this software without specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
-----------------------------------------------------------------------------
|
|
*/
|
|
|
|
# if defined(FFCS)
|
|
# if defined(FF_UTF)
|
|
# define FF_FUN ffcs_utf
|
|
# else
|
|
# define FF_FUN ffcs
|
|
# endif
|
|
|
|
# elif defined(FFCS_2)
|
|
# if defined(FF_UTF)
|
|
# define FF_FUN ffcs_2_utf
|
|
# else
|
|
# define FF_FUN ffcs_2
|
|
# endif
|
|
|
|
# elif defined(FFCS_MASK)
|
|
# if defined(FF_UTF)
|
|
# define FF_FUN ffcs_mask_utf
|
|
# else
|
|
# define FF_FUN ffcs_mask
|
|
# endif
|
|
|
|
# elif defined(FFCPS_0)
|
|
# if defined (FF_UTF)
|
|
# define FF_FUN ffcps_0_utf
|
|
# else
|
|
# define FF_FUN ffcps_0
|
|
# endif
|
|
|
|
# elif defined (FFCPS_1)
|
|
# if defined (FF_UTF)
|
|
# define FF_FUN ffcps_1_utf
|
|
# else
|
|
# define FF_FUN ffcps_1
|
|
# endif
|
|
|
|
# elif defined (FFCPS_DEFAULT)
|
|
# if defined (FF_UTF)
|
|
# define FF_FUN ffcps_default_utf
|
|
# else
|
|
# define FF_FUN ffcps_default
|
|
# endif
|
|
# endif
|
|
|
|
static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 *str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars)
|
|
#undef FF_FUN
|
|
{
|
|
quad_word qw;
|
|
int_char ic;
|
|
ic.x = chars;
|
|
|
|
#if defined(FFCS)
|
|
sljit_u8 c1 = ic.c.c1;
|
|
vect_t vc1 = VDUPQ(c1);
|
|
|
|
#elif defined(FFCS_2)
|
|
sljit_u8 c1 = ic.c.c1;
|
|
vect_t vc1 = VDUPQ(c1);
|
|
sljit_u8 c2 = ic.c.c2;
|
|
vect_t vc2 = VDUPQ(c2);
|
|
|
|
#elif defined(FFCS_MASK)
|
|
sljit_u8 c1 = ic.c.c1;
|
|
vect_t vc1 = VDUPQ(c1);
|
|
sljit_u8 mask = ic.c.c2;
|
|
vect_t vmask = VDUPQ(mask);
|
|
#endif
|
|
|
|
#if defined(FFCPS)
|
|
compare_type compare1_type = compare_match1;
|
|
compare_type compare2_type = compare_match1;
|
|
vect_t cmp1a, cmp1b, cmp2a, cmp2b;
|
|
const sljit_u32 diff = IN_UCHARS(offs1 - offs2);
|
|
PCRE2_UCHAR char1a = ic.c.c1;
|
|
PCRE2_UCHAR char2a = ic.c.c3;
|
|
|
|
# ifdef FFCPS_CHAR1A2A
|
|
cmp1a = VDUPQ(char1a);
|
|
cmp2a = VDUPQ(char2a);
|
|
cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
|
|
cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
|
|
# else
|
|
PCRE2_UCHAR char1b = ic.c.c2;
|
|
PCRE2_UCHAR char2b = ic.c.c4;
|
|
if (char1a == char1b)
|
|
{
|
|
cmp1a = VDUPQ(char1a);
|
|
cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
|
|
}
|
|
else
|
|
{
|
|
sljit_u32 bit1 = char1a ^ char1b;
|
|
if (is_powerof2(bit1))
|
|
{
|
|
compare1_type = compare_match1i;
|
|
cmp1a = VDUPQ(char1a | bit1);
|
|
cmp1b = VDUPQ(bit1);
|
|
}
|
|
else
|
|
{
|
|
compare1_type = compare_match2;
|
|
cmp1a = VDUPQ(char1a);
|
|
cmp1b = VDUPQ(char1b);
|
|
}
|
|
}
|
|
|
|
if (char2a == char2b)
|
|
{
|
|
cmp2a = VDUPQ(char2a);
|
|
cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
|
|
}
|
|
else
|
|
{
|
|
sljit_u32 bit2 = char2a ^ char2b;
|
|
if (is_powerof2(bit2))
|
|
{
|
|
compare2_type = compare_match1i;
|
|
cmp2a = VDUPQ(char2a | bit2);
|
|
cmp2b = VDUPQ(bit2);
|
|
}
|
|
else
|
|
{
|
|
compare2_type = compare_match2;
|
|
cmp2a = VDUPQ(char2a);
|
|
cmp2b = VDUPQ(char2b);
|
|
}
|
|
}
|
|
# endif
|
|
|
|
str_ptr += IN_UCHARS(offs1);
|
|
#endif
|
|
|
|
#if PCRE2_CODE_UNIT_WIDTH != 8
|
|
vect_t char_mask = VDUPQ(0xff);
|
|
#endif
|
|
|
|
#if defined(FF_UTF)
|
|
restart:;
|
|
#endif
|
|
|
|
#if defined(FFCPS)
|
|
sljit_u8 *p1 = str_ptr - diff;
|
|
#endif
|
|
sljit_s32 align_offset = ((uint64_t)str_ptr & 0xf);
|
|
str_ptr = (sljit_u8 *) ((uint64_t)str_ptr & ~0xf);
|
|
vect_t data = VLD1Q(str_ptr);
|
|
#if PCRE2_CODE_UNIT_WIDTH != 8
|
|
data = VANDQ(data, char_mask);
|
|
#endif
|
|
|
|
#if defined(FFCS)
|
|
vect_t eq = VCEQQ(data, vc1);
|
|
|
|
#elif defined(FFCS_2)
|
|
vect_t eq1 = VCEQQ(data, vc1);
|
|
vect_t eq2 = VCEQQ(data, vc2);
|
|
vect_t eq = VORRQ(eq1, eq2);
|
|
|
|
#elif defined(FFCS_MASK)
|
|
vect_t eq = VORRQ(data, vmask);
|
|
eq = VCEQQ(eq, vc1);
|
|
|
|
#elif defined(FFCPS)
|
|
# if defined(FFCPS_DIFF1)
|
|
vect_t prev_data = data;
|
|
# endif
|
|
|
|
vect_t data2;
|
|
if (p1 < str_ptr)
|
|
{
|
|
data2 = VLD1Q(str_ptr - diff);
|
|
#if PCRE2_CODE_UNIT_WIDTH != 8
|
|
data2 = VANDQ(data2, char_mask);
|
|
#endif
|
|
}
|
|
else
|
|
data2 = shift_left_n_lanes(data, offs1 - offs2);
|
|
|
|
if (compare1_type == compare_match1)
|
|
data = VCEQQ(data, cmp1a);
|
|
else
|
|
data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
|
|
|
|
if (compare2_type == compare_match1)
|
|
data2 = VCEQQ(data2, cmp2a);
|
|
else
|
|
data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
|
|
|
|
vect_t eq = VANDQ(data, data2);
|
|
#endif
|
|
|
|
VST1Q(qw.mem, eq);
|
|
/* Ignore matches before the first STR_PTR. */
|
|
if (align_offset < 8)
|
|
{
|
|
qw.dw[0] >>= align_offset * 8;
|
|
if (qw.dw[0])
|
|
{
|
|
str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8;
|
|
goto match;
|
|
}
|
|
if (qw.dw[1])
|
|
{
|
|
str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
|
|
goto match;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
qw.dw[1] >>= (align_offset - 8) * 8;
|
|
if (qw.dw[1])
|
|
{
|
|
str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8;
|
|
goto match;
|
|
}
|
|
}
|
|
str_ptr += 16;
|
|
|
|
while (str_ptr < str_end)
|
|
{
|
|
vect_t orig_data = VLD1Q(str_ptr);
|
|
#if PCRE2_CODE_UNIT_WIDTH != 8
|
|
orig_data = VANDQ(orig_data, char_mask);
|
|
#endif
|
|
data = orig_data;
|
|
|
|
#if defined(FFCS)
|
|
eq = VCEQQ(data, vc1);
|
|
|
|
#elif defined(FFCS_2)
|
|
eq1 = VCEQQ(data, vc1);
|
|
eq2 = VCEQQ(data, vc2);
|
|
eq = VORRQ(eq1, eq2);
|
|
|
|
#elif defined(FFCS_MASK)
|
|
eq = VORRQ(data, vmask);
|
|
eq = VCEQQ(eq, vc1);
|
|
#endif
|
|
|
|
#if defined(FFCPS)
|
|
# if defined (FFCPS_DIFF1)
|
|
data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1);
|
|
# else
|
|
data2 = VLD1Q(str_ptr - diff);
|
|
# if PCRE2_CODE_UNIT_WIDTH != 8
|
|
data2 = VANDQ(data2, char_mask);
|
|
# endif
|
|
# endif
|
|
|
|
# ifdef FFCPS_CHAR1A2A
|
|
data = VCEQQ(data, cmp1a);
|
|
data2 = VCEQQ(data2, cmp2a);
|
|
# else
|
|
if (compare1_type == compare_match1)
|
|
data = VCEQQ(data, cmp1a);
|
|
else
|
|
data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
|
|
if (compare2_type == compare_match1)
|
|
data2 = VCEQQ(data2, cmp2a);
|
|
else
|
|
data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
|
|
# endif
|
|
|
|
eq = VANDQ(data, data2);
|
|
#endif
|
|
|
|
VST1Q(qw.mem, eq);
|
|
if (qw.dw[0])
|
|
str_ptr += __builtin_ctzll(qw.dw[0]) / 8;
|
|
else if (qw.dw[1])
|
|
str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
|
|
else {
|
|
str_ptr += 16;
|
|
#if defined (FFCPS_DIFF1)
|
|
prev_data = orig_data;
|
|
#endif
|
|
continue;
|
|
}
|
|
|
|
match:;
|
|
if (str_ptr >= str_end)
|
|
/* Failed match. */
|
|
return NULL;
|
|
|
|
#if defined(FF_UTF)
|
|
if (utf_continue(str_ptr + IN_UCHARS(-offs1)))
|
|
{
|
|
/* Not a match. */
|
|
str_ptr += IN_UCHARS(1);
|
|
goto restart;
|
|
}
|
|
#endif
|
|
|
|
/* Match. */
|
|
#if defined (FFCPS)
|
|
str_ptr -= IN_UCHARS(offs1);
|
|
#endif
|
|
return str_ptr;
|
|
}
|
|
|
|
/* Failed match. */
|
|
return NULL;
|
|
}
|