diff options
Diffstat (limited to 'autoconf')
-rw-r--r-- | autoconf/ast_check_raii.m4 | 56 | ||||
-rw-r--r-- | autoconf/ast_check_strsep_array_bounds.m4 | 81 |
2 files changed, 137 insertions, 0 deletions
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" +]) |