asterisk/autoconf/ast_check_strsep_array_bounds.m4
Diederik de Groot 305ce3defd Update configure.ac/Makefile for clang
Created autoconf/ast_check_raii.m4: contains AST_CHECK_RAII which
checks compiler requirements for RAII:
gcc: -fnested-functions support
clang: -fblocks (and if required -lBlocksRuntime)
The original check was implemented in configure.ac and now has it's
own file. This function also sets C_COMPILER_FAMILY to either gcc or
clang for use by makefile

Created autoconf/ast_check_strsep_array_bounds.m4 (contains
AST_CHECK_STRSEP_ARRAY_BOUNDS):
which checks if clang is able to handle the optimized strsep & strcmp
functions (linux). If not, the standard libc implementation should be
used instead. Clang + the optimized macro's work with:
strsep(char *, char []), but not with strsepo(char *, char *).
Instead of replacing all the occurences throughout the source code,
not using the optimized macro version seemed easier

See 'define __strcmp_gc(s1, s2, l2) in bits/string2.h':
llvm-comment: Normally, this array-bounds warning are suppressed for
macros, so that unused paths like the one that accesses __s1[3] are
not warned about.  But if you preprocess manually, and feed the
result to another instance of clang, it will warn about all the
possible forks of this particular if statement. Instead of switching
of this optimization, another solution would be to run the preproces-
sing step with -frewrite-includes, which should preserve enough
information so that clang should still be able to suppress the diag-
nostic at the compile step later on.

See also "https://llvm.org/bugs/show_bug.cgi?id=20144"
See also "https://llvm.org/bugs/show_bug.cgi?id=11536"

Makefile.rules: If C_COMPILER_FAMILY=clang then add two warning
suppressions:
-Wno-unused-value
-Wno-parentheses-equality
In an earlier review (reviewboard: 4550 and 4554), they were deemed a
nuisace and less than benefitial.

configure.ac:
Added AST_CHECK_RAII() see earlier
Added AST_CHECK_STRSEP_ARRAY_BOUNDS() see earlier
Removed moved content

ASTERISK-24917
Change-Id: I12ea29d3bda2254ad3908e279b7effbbac6a97cb
2015-05-03 10:05:07 -05:00

82 lines
3.2 KiB
Text

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"
])