012-kbuild-add-macro-for-controlling-warnings-to-linux-c.patch 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. From: Arnd Bergmann <arnd@arndb.de>
  2. Date: Tue, 19 Jun 2018 13:14:56 -0700
  3. Subject: [PATCH] kbuild: add macro for controlling warnings to
  4. linux/compiler.h
  5. I have occasionally run into a situation where it would make sense to
  6. control a compiler warning from a source file rather than doing so from
  7. a Makefile using the $(cc-disable-warning, ...) or $(cc-option, ...)
  8. helpers.
  9. The approach here is similar to what glibc uses, using __diag() and
  10. related macros to encapsulate a _Pragma("GCC diagnostic ...") statement
  11. that gets turned into the respective "#pragma GCC diagnostic ..." by
  12. the preprocessor when the macro gets expanded.
  13. Like glibc, I also have an argument to pass the affected compiler
  14. version, but decided to actually evaluate that one. For now, this
  15. supports GCC_4_6, GCC_4_7, GCC_4_8, GCC_4_9, GCC_5, GCC_6, GCC_7,
  16. GCC_8 and GCC_9. Adding support for CLANG_5 and other interesting
  17. versions is straightforward here. GNU compilers starting with gcc-4.2
  18. could support it in principle, but "#pragma GCC diagnostic push"
  19. was only added in gcc-4.6, so it seems simpler to not deal with those
  20. at all. The same versions show a large number of warnings already,
  21. so it seems easier to just leave it at that and not do a more
  22. fine-grained control for them.
  23. The use cases I found so far include:
  24. - turning off the gcc-8 -Wattribute-alias warning inside of the
  25. SYSCALL_DEFINEx() macro without having to do it globally.
  26. - Reducing the build time for a simple re-make after a change,
  27. once we move the warnings from ./Makefile and
  28. ./scripts/Makefile.extrawarn into linux/compiler.h
  29. - More control over the warnings based on other configurations,
  30. using preprocessor syntax instead of Makefile syntax. This should make
  31. it easier for the average developer to understand and change things.
  32. - Adding an easy way to turn the W=1 option on unconditionally
  33. for a subdirectory or a specific file. This has been requested
  34. by several developers in the past that want to have their subsystems
  35. W=1 clean.
  36. - Integrating clang better into the build systems. Clang supports
  37. more warnings than GCC, and we probably want to classify them
  38. as default, W=1, W=2 etc, but there are cases in which the
  39. warnings should be classified differently due to excessive false
  40. positives from one or the other compiler.
  41. - Adding a way to turn the default warnings into errors (e.g. using
  42. a new "make E=0" tag) while not also turning the W=1 warnings into
  43. errors.
  44. This patch for now just adds the minimal infrastructure in order to
  45. do the first of the list above. As the #pragma GCC diagnostic
  46. takes precedence over command line options, the next step would be
  47. to convert a lot of the individual Makefiles that set nonstandard
  48. options to use __diag() instead.
  49. [paul.burton@mips.com:
  50. - Rebase atop current master.
  51. - Add __diag_GCC, or more generally __diag_<compiler>, abstraction to
  52. avoid code outside of linux/compiler-gcc.h needing to duplicate
  53. knowledge about different GCC versions.
  54. - Add a comment argument to __diag_{ignore,warn,error} which isn't
  55. used in the expansion of the macros but serves to push people to
  56. document the reason for using them - per feedback from Kees Cook.
  57. - Translate severity to GCC-specific pragmas in linux/compiler-gcc.h
  58. rather than using GCC-specific in linux/compiler_types.h.
  59. - Drop all but GCC 8 macros, since we only need to define macros for
  60. versions that we need to introduce pragmas for, and as of this
  61. series that's just GCC 8.
  62. - Capitalize comments in linux/compiler-gcc.h to match the style of
  63. the rest of the file.
  64. - Line up macro definitions with tabs in linux/compiler-gcc.h.]
  65. Signed-off-by: Arnd Bergmann <arnd@arndb.de>
  66. Signed-off-by: Paul Burton <paul.burton@mips.com>
  67. Tested-by: Christophe Leroy <christophe.leroy@c-s.fr>
  68. Tested-by: Stafford Horne <shorne@gmail.com>
  69. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
  70. ---
  71. --- a/include/linux/compiler-gcc.h
  72. +++ b/include/linux/compiler-gcc.h
  73. @@ -372,3 +372,30 @@
  74. #if GCC_VERSION >= 50100
  75. #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1
  76. #endif
  77. +
  78. +
  79. +/*
  80. + * Turn individual warnings and errors on and off locally, depending
  81. + * on version.
  82. + */
  83. +#define __diag_GCC(version, severity, s) \
  84. + __diag_GCC_ ## version(__diag_GCC_ ## severity s)
  85. +
  86. +/* Severity used in pragma directives */
  87. +#define __diag_GCC_ignore ignored
  88. +#define __diag_GCC_warn warning
  89. +#define __diag_GCC_error error
  90. +
  91. +/* Compilers before gcc-4.6 do not understand "#pragma GCC diagnostic push" */
  92. +#if GCC_VERSION >= 40600
  93. +#define __diag_str1(s) #s
  94. +#define __diag_str(s) __diag_str1(s)
  95. +#define __diag(s) _Pragma(__diag_str(GCC diagnostic s))
  96. +#endif
  97. +
  98. +#if GCC_VERSION >= 80000
  99. +#define __diag_GCC_8(s) __diag(s)
  100. +#else
  101. +#define __diag_GCC_8(s)
  102. +#endif
  103. +
  104. --- a/include/linux/compiler_types.h
  105. +++ b/include/linux/compiler_types.h
  106. @@ -287,4 +287,22 @@ struct ftrace_likely_data {
  107. # define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long))
  108. #endif
  109. +#ifndef __diag
  110. +#define __diag(string)
  111. +#endif
  112. +
  113. +#ifndef __diag_GCC
  114. +#define __diag_GCC(version, severity, string)
  115. +#endif
  116. +
  117. +#define __diag_push() __diag(push)
  118. +#define __diag_pop() __diag(pop)
  119. +
  120. +#define __diag_ignore(compiler, version, option, comment) \
  121. + __diag_ ## compiler(version, ignore, option)
  122. +#define __diag_warn(compiler, version, option, comment) \
  123. + __diag_ ## compiler(version, warn, option)
  124. +#define __diag_error(compiler, version, option, comment) \
  125. + __diag_ ## compiler(version, error, option)
  126. +
  127. #endif /* __LINUX_COMPILER_TYPES_H */