diff --git a/CMakeLists.txt b/CMakeLists.txt index 301a713..baa8890 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,6 +87,7 @@ # 2020-03-16 PH renamed dftables as pcre2_dftables (as elsewhere) # 2020-03-24 PH changed CMAKE_MODULE_PATH definition to add, not replace # 2020-04-08 Carlo added function check for secure_getenv, fixed strerror +# 2020-04-16 enh added check for __attribute__((uninitialized)) PROJECT(PCRE2 C) @@ -113,8 +114,9 @@ FIND_PACKAGE( Editline ) # Configuration checks -INCLUDE(CheckIncludeFile) +INCLUDE(CheckCSourceCompiles) INCLUDE(CheckFunctionExists) +INCLUDE(CheckIncludeFile) INCLUDE(CheckTypeSize) CHECK_INCLUDE_FILE(dirent.h HAVE_DIRENT_H) @@ -130,6 +132,14 @@ CHECK_FUNCTION_EXISTS(memmove HAVE_MEMMOVE) CHECK_FUNCTION_EXISTS(strerror HAVE_STRERROR) CHECK_FUNCTION_EXISTS(secure_getenv HAVE_SECURE_GETENV) +set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) +set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror") +CHECK_C_SOURCE_COMPILES( + "int main() { char buf[128] __attribute__((uninitialized)); (void)buf; return 0; }" + HAVE_ATTRIBUTE_UNINITIALIZED +) +set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS}) + # User-configurable options # # Note: CMakeSetup displays these in alphabetical order, regardless of diff --git a/ChangeLog b/ChangeLog index f9663b2..546e740 100644 --- a/ChangeLog +++ b/ChangeLog @@ -104,6 +104,12 @@ LIST(APPEND...) to allow a setting from the command line to be included. 25. Avoid using [-1] as a suffix in pcre2test because it can provoke a compiler warning. +26. Added tests for __attribute__((uninitialized)) to both the configure and +CMake build files, and then applied this attribute to the variable called +stack_frames_vector[] in pcre2_match(). When implemented, this disables +automatic initialization (a facility in clang), which can take time on big +variables. + Version 10.34 21-November-2019 ------------------------------ diff --git a/config-cmake.h.in b/config-cmake.h.in index 108f86c..3c5e0d3 100644 --- a/config-cmake.h.in +++ b/config-cmake.h.in @@ -1,5 +1,6 @@ /* config.h for CMake builds */ +#cmakedefine HAVE_ATTRIBUTE_UNINITIALIZED 1 #cmakedefine HAVE_DIRENT_H 1 #cmakedefine HAVE_INTTYPES_H 1 #cmakedefine HAVE_STDINT_H 1 diff --git a/configure.ac b/configure.ac index 4553fcd..0213d8e 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,7 @@ dnl be defined as -RC2, for example. For real releases, it should be empty. m4_define(pcre2_major, [10]) m4_define(pcre2_minor, [35]) -m4_define(pcre2_prerelease, [-RC1]) +m4_define(pcre2_prerelease, [-RC2]) m4_define(pcre2_date, [2020-04-15]) # NOTE: The CMakeLists.txt file searches for the above variables in the first @@ -72,6 +72,24 @@ AC_PROG_LN_S PCRE2_VISIBILITY +# Check for Clang __attribute__((uninitialized)) feature + +AC_MSG_CHECKING([for __attribute__((uninitialized))]) +AC_LANG_PUSH([C]) +tmp_CFLAGS=$CFLAGS +CFLAGS="$CFLAGS -Werror" +AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, + [[char buf[128] __attribute__((uninitialized));(void)buf]])], + [pcre2_cc_cv_attribute_uninitialized=yes], + [pcre2_cc_cv_attribute_uninitialized=no]) +AC_MSG_RESULT([$pcre2_cc_cv_attribute_uninitialized]) +if test "$pcre2_cc_cv_attribute_uninitialized" = yes; then + AC_DEFINE([HAVE_ATTRIBUTE_UNINITIALIZED], 1, [Define this if your compiler + supports __attribute__((uninitialized))]) +fi +CFLAGS=$tmp_CFLAGS +AC_LANG_POP([C]) + # Versioning PCRE2_MAJOR="pcre2_major" diff --git a/src/config.h.in b/src/config.h.in index 6b8eb7e..5406da0 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -52,6 +52,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__((uninitialized)) */ +#undef HAVE_ATTRIBUTE_UNINITIALIZED + /* Define to 1 if you have the `bcopy' function. */ #undef HAVE_BCOPY diff --git a/src/pcre2_internal.h b/src/pcre2_internal.h index cb81199..d8fad1e 100644 --- a/src/pcre2_internal.h +++ b/src/pcre2_internal.h @@ -76,6 +76,17 @@ typedef int BOOL; #include #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 +such arrays. */ + +#ifdef HAVE_ATTRIBUTE_UNINITIALIZED +#define PCRE2_KEEP_UNINITIALIZED __attribute__((uninitialized)) +#else +#define PCRE2_KEEP_UNINITIALIZED +#endif + /* Older versions of MSVC lack snprintf(). This define allows for warning/error-free compilation and testing with MSVC compilers back to at least MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */ diff --git a/src/pcre2_match.c b/src/pcre2_match.c index 5115b53..11289d5 100644 --- a/src/pcre2_match.c +++ b/src/pcre2_match.c @@ -6164,7 +6164,8 @@ proves to be too small, it is replaced by a larger one on the heap. To get a vector of the size required that is aligned for pointers, allocate it as a vector of pointers. */ -PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)]; +PCRE2_SPTR stack_frames_vector[START_FRAMES_SIZE/sizeof(PCRE2_SPTR)] + PCRE2_KEEP_UNINITIALIZED; mb->stack_frames = (heapframe *)stack_frames_vector; /* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated