ast_check_strsep_array_bounds.m4 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. dnl macro AST_CHECK_STRSEP_ARRAY_BOUNDS0
  2. dnl
  3. dnl The optimized strcmp and strsep macro's in
  4. dnl /usr/include/xxx-linux-gnu/bits/string2.h produce a warning (-Warray-bounds)
  5. dnl when compiled with clang (+ -O1), when the delimiter parameter is
  6. dnl passed in as a char *, instead of the expected char[]
  7. dnl
  8. dnl Instead of replacing all occurrences of strsep and strcmp, looking like:
  9. dnl xxx_name = strsep(&rest, ",");
  10. dnl
  11. dnl with:
  12. dnl char delimiters[] = ",";
  13. dnl xxx_name = strsep(&rest, delimiters);
  14. dnl
  15. dnl to get around this warning, without having to suppress the warning completely.
  16. dnl This macro detects the warning and force these 'optimizations' to be
  17. dnl switched off (Clang already has a set of builtin optimizers which should result
  18. dnl in good performance for these type of functions).
  19. dnl
  20. dnl When the issue is detected it will add a define to autoconfig.h which will prevent
  21. dnl bits/string2.h from replacing the standard implementation of strsep/strcmp with it's
  22. dnl macro optimized version. bits/string.h checks these defines before inserting it's
  23. dnl replacements.
  24. dnl
  25. dnl When bits/string2.h get's fixed in the future, this macro should be able to
  26. dnl detect the new behaviour, and when no warning is generated, it will use the optimize
  27. dnl version from bits/string2.h
  28. dnl
  29. dnl
  30. dnl See 'define __strcmp_gc(s1, s2, l2) in bits/string2.h'
  31. dnl
  32. dnl llvm-comment: Normally, this array-bounds warning are suppressed for macros, so that
  33. dnl unused paths like the one that accesses __s1[3] are not warned about. But if you
  34. dnl preprocess manually, and feed the result to another instance of clang, it will warn
  35. dnl about all the possible forks of this particular if statement.
  36. dnl
  37. dnl Instead of switching of this optimization, another solution would be to run the pre-
  38. dnl processing step with -frewrite-includes, which should preserve enough information
  39. dnl so that clang should still be able to suppress the diagnostic at the compile step
  40. dnl later on.
  41. dnl
  42. dnl See also "https://llvm.org/bugs/show_bug.cgi?id=20144"
  43. dnl See also "https://llvm.org/bugs/show_bug.cgi?id=11536"
  44. dnl
  45. AC_DEFUN([AST_CHECK_STRSEP_ARRAY_BOUNDS], [
  46. AC_MSG_CHECKING([for clang strsep/strcmp optimization])
  47. save_CFLAGS="$CFLAGS"
  48. CFLAGS="$CFLAGS -O1 -Werror=array-bounds"
  49. AC_COMPILE_IFELSE(
  50. [
  51. AC_LANG_SOURCE([
  52. #include <stdio.h>
  53. #include <string.h>
  54. /* fails with clang and -O1 */
  55. void test_strsep_strcmp (void) {
  56. char *haystackstr = "test1,test2";
  57. char *outstr;
  58. if (!strcmp(haystackstr, ",")) {
  59. printf("fail\n");
  60. }
  61. if ((outstr = strsep(&haystackstr, ","))) {
  62. printf("fail:%s\n", outstr);
  63. }
  64. }
  65. int main(int argc, char *argv[]) {
  66. test_strsep_strcmp();
  67. return 0;
  68. }
  69. ])
  70. ],[
  71. AC_MSG_RESULT(no)
  72. ],[
  73. dnl setting this define in autoconfig.h will prevent bits/string2.h from replacing the standard implementation of strsep/strcmp
  74. AC_DEFINE([_HAVE_STRING_ARCH_strcmp], 1, [Prevent clang array-bounds warning by not using strcmp from bits/string2.h])
  75. AC_DEFINE([_HAVE_STRING_ARCH_strsep], 1, [Prevent clang array-bounds warning by not using strsep from bits/string2.h])
  76. AC_MSG_RESULT([prevent use of __string2_1bptr_p / strsep / strcmp from bits/string2.h])
  77. ]
  78. )
  79. CFLAGS="$save_CFLAGS"
  80. ])