summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.rules5
-rw-r--r--autoconf/ast_check_raii.m456
-rw-r--r--autoconf/ast_check_strsep_array_bounds.m481
-rwxr-xr-xconfigure215
-rw-r--r--configure.ac39
-rw-r--r--include/asterisk/autoconfig.h.in8
-rw-r--r--makeopts.in1
7 files changed, 298 insertions, 107 deletions
diff --git a/Makefile.rules b/Makefile.rules
index a24cc72b7..a274c9572 100644
--- a/Makefile.rules
+++ b/Makefile.rules
@@ -65,6 +65,11 @@ endif
CC_CFLAGS=$(PTHREAD_CFLAGS) $(_ASTCFLAGS) $(ASTCFLAGS)
CXX_CFLAGS=$(PTHREAD_CFLAGS) $(filter-out -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations $(AST_DECLARATION_AFTER_STATEMENT),$(_ASTCFLAGS) $(ASTCFLAGS))
+# Clang -Werror warning suppressions
+ifeq ($(C_COMPILER_FAMILY),clang)
+ CC_CFLAGS+=-Wno-unused-value -Wno-parentheses-equality
+endif
+
ifeq ($(GNU_LD),1)
SO_SUPPRESS_SYMBOLS=-Wl,--version-script,$(subst .so,.exports,$@),--warn-common
ifneq ($(wildcard $(subst .so,.dynamics,$@)),)
diff --git a/autoconf/ast_check_raii.m4 b/autoconf/ast_check_raii.m4
new file mode 100644
index 000000000..e39a43d2e
--- /dev/null
+++ b/autoconf/ast_check_raii.m4
@@ -0,0 +1,56 @@
+dnl check RAII requirements
+dnl
+dnl gcc / llvm-gcc: -fnested-functions
+dnl clang : -fblocks / -fblocks and -lBlocksRuntime"
+AC_DEFUN([AST_CHECK_RAII], [
+ AC_MSG_CHECKING([for RAII support])
+ AST_C_COMPILER_FAMILY=""
+ AC_LINK_IFELSE(
+ [AC_LANG_PROGRAM([], [
+ int main() {
+ #if defined(__clang__)
+ choke
+ #endif
+ return 0;
+ }
+ ])
+ ],[
+ dnl Nested functions required for RAII implementation
+ AC_MSG_CHECKING(for gcc -fnested-functions)
+ AC_COMPILE_IFELSE(
+ dnl Prototype needed due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36774
+ [
+ AC_LANG_PROGRAM([], [auto void foo(void); void foo(void) {}])
+ ],[
+ AST_NESTED_FUNCTIONS=""
+ AC_MSG_RESULT(no)
+ ],[
+ AST_NESTED_FUNCTIONS="-fnested-functions"
+ AC_MSG_RESULT(yes)
+ ]
+ )
+ AC_SUBST(AST_NESTED_FUNCTIONS)
+ AST_C_COMPILER_FAMILY="gcc"
+ ],[
+ AC_MSG_CHECKING(for clang -fblocks)
+ if test "`echo "int main(){return ^{return 42;}();}" | ${CC} -o /dev/null -fblocks -x c - 2>&1`" = ""; then
+ AST_CLANG_BLOCKS_LIBS=""
+ AST_CLANG_BLOCKS="-Wno-unknown-warning-option -fblocks"
+ AC_MSG_RESULT(yes)
+ elif test "`echo "int main(){return ^{return 42;}();}" | ${CC} -o /dev/null -fblocks -x c -lBlocksRuntime - 2>&1`" = ""; then
+ AST_CLANG_BLOCKS_LIBS="-lBlocksRuntime"
+ AST_CLANG_BLOCKS="-fblocks"
+ AC_MSG_RESULT(yes)
+ else
+ AC_MSG_ERROR([BlocksRuntime is required for clang, please install libblocksruntime])
+ fi
+ AC_SUBST(AST_CLANG_BLOCKS_LIBS)
+ AC_SUBST(AST_CLANG_BLOCKS)
+ AST_C_COMPILER_FAMILY="clang"
+ ]
+ )
+ if test -z "${AST_C_COMPILER_FAMILY}"; then
+ AC_MSG_ERROR([Compiler ${CC} not supported. Mminimum required gcc-4.3 / llvm-gcc-4.3 / clang-3.3 + libblocksruntime-dev])
+ fi
+ AC_SUBST(AST_C_COMPILER_FAMILY)
+])
diff --git a/autoconf/ast_check_strsep_array_bounds.m4 b/autoconf/ast_check_strsep_array_bounds.m4
new file mode 100644
index 000000000..47a41e58a
--- /dev/null
+++ b/autoconf/ast_check_strsep_array_bounds.m4
@@ -0,0 +1,81 @@
+dnl macro AST_CHECK_STRSEP_ARRAY_BOUNDS0
+dnl
+dnl The optimized strcmp and strsep macro's in
+dnl /usr/include/xxx-linux-gnu/bits/string2.h produce a warning (-Warray-bounds)
+dnl when compiled with clang (+ -O1), when the delimiter parameter is
+dnl passed in as a char *, instead of the expected char[]
+dnl
+dnl Instead of replacing all occurrences of strsep and strcmp, looking like:
+dnl xxx_name = strsep(&rest, ",");
+dnl
+dnl with:
+dnl char delimiters[] = ",";
+dnl xxx_name = strsep(&rest, delimiters);
+dnl
+dnl to get around this warning, without having to suppress the warning completely.
+dnl This macro detects the warning and force these 'optimizations' to be
+dnl switched off (Clang already has a set of builtin optimizers which should result
+dnl in good performance for these type of functions).
+dnl
+dnl When the issue is detected it will add a define to autoconfig.h which will prevent
+dnl bits/string2.h from replacing the standard implementation of strsep/strcmp with it's
+dnl macro optimized version. bits/string.h checks these defines before inserting it's
+dnl replacements.
+dnl
+dnl When bits/string2.h get's fixed in the future, this macro should be able to
+dnl detect the new behaviour, and when no warning is generated, it will use the optimize
+dnl version from bits/string2.h
+dnl
+dnl
+dnl See 'define __strcmp_gc(s1, s2, l2) in bits/string2.h'
+dnl
+dnl llvm-comment: Normally, this array-bounds warning are suppressed for macros, so that
+dnl unused paths like the one that accesses __s1[3] are not warned about. But if you
+dnl preprocess manually, and feed the result to another instance of clang, it will warn
+dnl about all the possible forks of this particular if statement.
+dnl
+dnl Instead of switching of this optimization, another solution would be to run the pre-
+dnl processing step with -frewrite-includes, which should preserve enough information
+dnl so that clang should still be able to suppress the diagnostic at the compile step
+dnl later on.
+dnl
+dnl See also "https://llvm.org/bugs/show_bug.cgi?id=20144"
+dnl See also "https://llvm.org/bugs/show_bug.cgi?id=11536"
+dnl
+AC_DEFUN([AST_CHECK_STRSEP_ARRAY_BOUNDS], [
+ AC_MSG_CHECKING([for clang strsep/strcmp optimization])
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -O1 -Werror=array-bounds"
+ AC_COMPILE_IFELSE(
+ [
+ AC_LANG_SOURCE([
+ #include <stdio.h>
+ #include <string.h>
+
+ /* fails with clang and -O1 */
+ void test_strsep_strcmp (void) {
+ char *haystackstr = "test1,test2";
+ char *outstr;
+ if (!strcmp(haystackstr, ",")) {
+ printf("fail\n");
+ }
+ if ((outstr = strsep(&haystackstr, ","))) {
+ printf("fail:%s\n", outstr);
+ }
+ }
+ int main(int argc, char *argv[]) {
+ test_strsep_strcmp();
+ return 0;
+ }
+ ])
+ ],[
+ AC_MSG_RESULT(no)
+ ],[
+ dnl setting this define in autoconfig.h will prevent bits/string2.h from replacing the standard implementation of strsep/strcmp
+ AC_DEFINE([_HAVE_STRING_ARCH_strcmp], 1, [Prevent clang array-bounds warning by not using strcmp from bits/string2.h])
+ AC_DEFINE([_HAVE_STRING_ARCH_strsep], 1, [Prevent clang array-bounds warning by not using strsep from bits/string2.h])
+ AC_MSG_RESULT([prevent use of __string2_1bptr_p / strsep / strcmp from bits/string2.h])
+ ]
+ )
+ CFLAGS="$save_CFLAGS"
+])
diff --git a/configure b/configure
index c539ee94b..9f7a862d3 100755
--- a/configure
+++ b/configure
@@ -687,9 +687,6 @@ PBX_RTLD_NOLOAD
PBX_GLOB_BRACE
PBX_GLOB_NOMAGIC
AST_RPATH
-AST_CLANG_BLOCKS
-AST_CLANG_BLOCKS_LIBS
-AST_NESTED_FUNCTIONS
AST_NATIVE_ARCH
AST_SHADOW_WARNINGS
AST_NO_STRICT_OVERFLOW
@@ -1148,6 +1145,10 @@ PBX_ALSA
ALSA_DIR
ALSA_INCLUDE
ALSA_LIB
+AST_C_COMPILER_FAMILY
+AST_CLANG_BLOCKS
+AST_CLANG_BLOCKS_LIBS
+AST_NESTED_FUNCTIONS
AST_CODE_COVERAGE
AST_DEVMODE_STRICT
AST_DEVMODE
@@ -8227,6 +8228,146 @@ fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for RAII support" >&5
+$as_echo_n "checking for RAII support... " >&6; }
+ AST_C_COMPILER_FAMILY=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ int main() {
+ #if defined(__clang__)
+ choke
+ #endif
+ return 0;
+ }
+
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc -fnested-functions" >&5
+$as_echo_n "checking for gcc -fnested-functions... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+auto void foo(void); void foo(void) {}
+ ;
+ return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ AST_NESTED_FUNCTIONS=""
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+ AST_NESTED_FUNCTIONS="-fnested-functions"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ AST_C_COMPILER_FAMILY="gcc"
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang -fblocks" >&5
+$as_echo_n "checking for clang -fblocks... " >&6; }
+ if test "`echo "int main(){return ^{return 42;}();}" | ${CC} -o /dev/null -fblocks -x c - 2>&1`" = ""; then
+ AST_CLANG_BLOCKS_LIBS=""
+ AST_CLANG_BLOCKS="-Wno-unknown-warning-option -fblocks"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ elif test "`echo "int main(){return ^{return 42;}();}" | ${CC} -o /dev/null -fblocks -x c -lBlocksRuntime - 2>&1`" = ""; then
+ AST_CLANG_BLOCKS_LIBS="-lBlocksRuntime"
+ AST_CLANG_BLOCKS="-fblocks"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ as_fn_error $? "BlocksRuntime is required for clang, please install libblocksruntime" "$LINENO" 5
+ fi
+
+
+ AST_C_COMPILER_FAMILY="clang"
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test -z "${AST_C_COMPILER_FAMILY}"; then
+ as_fn_error $? "Compiler ${CC} not supported. Mminimum required gcc-4.3 / llvm-gcc-4.3 / clang-3.3 + libblocksruntime-dev" "$LINENO" 5
+ fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang strsep/strcmp optimization" >&5
+$as_echo_n "checking for clang strsep/strcmp optimization... " >&6; }
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -O1 -Werror=array-bounds"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+ #include <stdio.h>
+ #include <string.h>
+
+ /* fails with clang and -O1 */
+ void test_strsep_strcmp (void) {
+ char *haystackstr = "test1,test2";
+ char *outstr;
+ if (!strcmp(haystackstr, ",")) {
+ printf("fail\n");
+ }
+ if ((outstr = strsep(&haystackstr, ","))) {
+ printf("fail:%s\n", outstr);
+ }
+ }
+ int main(int argc, char *argv) {
+ test_strsep_strcmp();
+ return 0;
+ }
+
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+else
+
+
+$as_echo "#define _HAVE_STRING_ARCH_strcmp 1" >>confdefs.h
+
+
+$as_echo "#define _HAVE_STRING_ARCH_strsep 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: prevent use of __string2_1bptr_p / strsep / strcmp from bits/string2.h" >&5
+$as_echo "prevent use of __string2_1bptr_p / strsep / strcmp from bits/string2.h" >&6; }
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ CFLAGS="$save_CFLAGS"
+
+
# AST_EXT_LIB_SETUP is used to tell configure to handle variables for
# various packages.
# $1 is the prefix for the variables in makeopts and autoconfig.h
@@ -17430,74 +17571,6 @@ $as_echo "no" >&6; }
fi
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- #if defined(__clang__)
- choke
- #endif
-
- ;
- return 0;
-}
-
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc -fnested-functions" >&5
-$as_echo_n "checking for gcc -fnested-functions... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-auto void foo(void); void foo(void) {}
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
- AST_NESTED_FUNCTIONS=
-else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- AST_NESTED_FUNCTIONS=-fnested-functions
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-
-else
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for clang -fblocks" >&5
-$as_echo_n "checking for clang -fblocks... " >&6; }
- if test "`echo "int main(){return ^{return 42;}();}" | ${CC} -o /dev/null -fblocks -x c - 2>&1`" = ""; then
- AST_CLANG_BLOCKS_LIBS=""
- AST_CLANG_BLOCKS="-Wno-unknown-warning-option -fblocks"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- elif test "`echo "int main(){return ^{return 42;}();}" | ${CC} -o /dev/null -fblocks -x c -lBlocksRuntime - 2>&1`" = ""; then
- AST_CLANG_BLOCKS_LIBS="-lBlocksRuntime"
- AST_CLANG_BLOCKS="-fblocks"
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
- else
- as_fn_error $? "\"BlocksRuntime is required for clang\"" "$LINENO" 5
- fi
-
-
-
-
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
# Check whether --enable-rpath was given.
if test "${enable_rpath+set}" = set; then :
diff --git a/configure.ac b/configure.ac
index 8a3707543..c09d30a7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -386,6 +386,9 @@ AC_ARG_ENABLE([coverage],
esac])
AC_SUBST(AST_CODE_COVERAGE)
+AST_CHECK_RAII()
+AST_CHECK_STRSEP_ARRAY_BOUNDS()
+
# AST_EXT_LIB_SETUP is used to tell configure to handle variables for
# various packages.
# $1 is the prefix for the variables in makeopts and autoconfig.h
@@ -1134,42 +1137,6 @@ else
fi
AC_SUBST(AST_NATIVE_ARCH)
-dnl Nested functions required for RAII implementation
-AC_LINK_IFELSE(
- [AC_LANG_PROGRAM([], [
- #if defined(__clang__)
- choke
- #endif
- ])
- ],[
- dnl Nested functions required for RAII implementation
- AC_MSG_CHECKING(for gcc -fnested-functions)
- AC_COMPILE_IFELSE(
- dnl Prototype needed due to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36774
- [AC_LANG_PROGRAM([], [auto void foo(void); void foo(void) {}])],
- AC_MSG_RESULT(no)
- [AST_NESTED_FUNCTIONS=],
- AC_MSG_RESULT(yes)
- [AST_NESTED_FUNCTIONS=-fnested-functions]
- )
- AC_SUBST(AST_NESTED_FUNCTIONS)
- ],[
- AC_MSG_CHECKING(for clang -fblocks)
- if test "`echo "int main(){return ^{return 42;}();}" | ${CC} -o /dev/null -fblocks -x c - 2>&1`" = ""; then
- [AST_CLANG_BLOCKS_LIBS=""]
- [AST_CLANG_BLOCKS="-Wno-unknown-warning-option -fblocks"]
- AC_MSG_RESULT(yes)
- elif test "`echo "int main(){return ^{return 42;}();}" | ${CC} -o /dev/null -fblocks -x c -lBlocksRuntime - 2>&1`" = ""; then
- [AST_CLANG_BLOCKS_LIBS="-lBlocksRuntime"]
- [AST_CLANG_BLOCKS="-fblocks"]
- AC_MSG_RESULT(yes)
- else
- AC_MSG_ERROR("BlocksRuntime is required for clang")
- fi
- AC_SUBST(AST_CLANG_BLOCKS_LIBS)
- AC_SUBST(AST_CLANG_BLOCKS)
- ]
-)
dnl Check to see if rpath should be set in LDFLAGS
AC_ARG_ENABLE(rpath,
diff --git a/include/asterisk/autoconfig.h.in b/include/asterisk/autoconfig.h.in
index 474fb8c31..6b41a8c9a 100644
--- a/include/asterisk/autoconfig.h.in
+++ b/include/asterisk/autoconfig.h.in
@@ -1314,6 +1314,14 @@
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
+/* Prevent clang array-bounds warning by not using strcmp from bits/string2.h
+ */
+#undef _HAVE_STRING_ARCH_strcmp
+
+/* Prevent clang array-bounds warning by not using strsep from bits/string2.h
+ */
+#undef _HAVE_STRING_ARCH_strsep
+
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#undef _LARGEFILE_SOURCE
diff --git a/makeopts.in b/makeopts.in
index cc233109d..69636f18e 100644
--- a/makeopts.in
+++ b/makeopts.in
@@ -111,6 +111,7 @@ AST_SHADOW_WARNINGS=@AST_SHADOW_WARNINGS@
AST_NESTED_FUNCTIONS=@AST_NESTED_FUNCTIONS@
AST_CLANG_BLOCKS=@AST_CLANG_BLOCKS@
AST_CLANG_BLOCKS_LIBS=@AST_CLANG_BLOCKS_LIBS@
+C_COMPILER_FAMILY=@AST_C_COMPILER_FAMILY@
AST_RPATH=@AST_RPATH@
AST_FORTIFY_SOURCE=@AST_FORTIFY_SOURCE@
AST_MARCH_NATIVE=@AST_MARCH_NATIVE@