[PATCH] D41335: [InlineFunction] Inline vararg functions that do not access varargs.

Chih-Hung Hsieh via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 25 12:41:00 PST 2018


chh added a comment.

Hi, I am trying to build Android with clang 7.0.
This change generates wrong inlined sprintf because Android bionic
used fortified version wrapper with __attribute__((__always_inline__)).

Please try this simplified sprintf.c code.

  typedef __builtin_va_list va_list;
  void do_sprintf1(char*, const char*, va_list);
  void do_sprintf2(char*, const char*, va_list);
  static inline __attribute__((__always_inline__))
  void mysprintf1(char *dest, const char* format, ...)
  {
      va_list va;
      __builtin_va_start(va, format);
      do_sprintf1(dest, format, va);
      __builtin_va_end(va);
  }
  static inline
  void mysprintf2(char *dest, const char* format, ...)
  {
      va_list va;
      __builtin_va_start(va, format);
      do_sprintf2(dest, format, va);
      __builtin_va_end(va);
  }
  char* test_sprintf(char *dest, const char *format)
  {
      mysprintf1(dest, format, 1);
      mysprintf2(dest, format, 2);
      return dest;
  }

When compiled with gcc, gcc rejects that attribute:

  $ gcc -S sprintf.c
  sprintf.c: In function 'mysprintf1':
  sprintf.c:6:6: error: function 'mysprintf1' can never be inlined because it uses variable argument lists
   void mysprintf1(char *dest, const char* format, ...)
        ^~~~~~~~~~

When compiled with older clang compiler, the __always_inline__ attribute was ignored.
Neither mysprintf1 or mysprintf2 was inlined.

With this change, mysprintf1 is inlined incorrectly due to the __always_inline__ attribute.

Could someone suggest a fix or revert this change?
Thanks.


Repository:
  rL LLVM

https://reviews.llvm.org/D41335





More information about the llvm-commits mailing list