compiler.h 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. /* SPDX-License-Identifier: LGPL-2.1-only OR MIT */
  2. /*
  3. * rseq/compiler.h
  4. *
  5. * Work-around asm goto compiler bugs.
  6. *
  7. * (C) Copyright 2021 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  8. */
  9. #ifndef RSEQ_COMPILER_H
  10. #define RSEQ_COMPILER_H
  11. /*
  12. * gcc prior to 4.8.2 miscompiles asm goto.
  13. * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
  14. *
  15. * gcc prior to 8.1.0 miscompiles asm goto at O1.
  16. * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103908
  17. *
  18. * clang prior to version 13.0.1 miscompiles asm goto at O2.
  19. * https://github.com/llvm/llvm-project/issues/52735
  20. *
  21. * Work around these issues by adding a volatile inline asm with
  22. * memory clobber in the fallthrough after the asm goto and at each
  23. * label target. Emit this for all compilers in case other similar
  24. * issues are found in the future.
  25. */
  26. #define rseq_after_asm_goto() asm volatile ("" : : : "memory")
  27. /* Combine two tokens. */
  28. #define RSEQ__COMBINE_TOKENS(_tokena, _tokenb) \
  29. _tokena##_tokenb
  30. #define RSEQ_COMBINE_TOKENS(_tokena, _tokenb) \
  31. RSEQ__COMBINE_TOKENS(_tokena, _tokenb)
  32. #ifdef __cplusplus
  33. #define rseq_unqual_scalar_typeof(x) \
  34. std::remove_cv<std::remove_reference<decltype(x)>::type>::type
  35. #else
  36. #define rseq_scalar_type_to_expr(type) \
  37. unsigned type: (unsigned type)0, \
  38. signed type: (signed type)0
  39. /*
  40. * Use C11 _Generic to express unqualified type from expression. This removes
  41. * volatile qualifier from expression type.
  42. */
  43. #define rseq_unqual_scalar_typeof(x) \
  44. __typeof__( \
  45. _Generic((x), \
  46. char: (char)0, \
  47. rseq_scalar_type_to_expr(char), \
  48. rseq_scalar_type_to_expr(short), \
  49. rseq_scalar_type_to_expr(int), \
  50. rseq_scalar_type_to_expr(long), \
  51. rseq_scalar_type_to_expr(long long), \
  52. default: (x) \
  53. ) \
  54. )
  55. #endif
  56. #endif /* RSEQ_COMPILER_H_ */