OSDN Git Service

use GNU C89 extern inline semantics for __size_mul_overflow()
authorXia Yang <xiay@nvidia.com>
Thu, 21 Jan 2016 02:34:59 +0000 (18:34 -0800)
committerJosh Gao <jmgao@google.com>
Wed, 3 Feb 2016 01:28:16 +0000 (17:28 -0800)
__size_mul_overflow generates warning under following compilation envrionment:

-OX -D_FORTIFY_SOURCE=2 (X=1, 2, 3)

For example:

echo '#include <stdio.h>' | \
prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-gcc \
    -I bionic/libc/arch-arm/include \
    -I bionic/libc/include \
    -I bionic/libc/kernel/uapi \
    -I bionic/libc/kernel/common \
    -I bionic/libc/kernel/uapi/asm-arm \
    -I bionic/libm/include \
    -I bionic/libm/include/arm \
    -I bionic/libc/include \
    -Werror \
    -O1 \
    -D_FORTIFY_SOURCE=2 \
    -c \
    -x c \
    -

bionic/libc/include/stdio.h:360:13: error: '__size_mul_overflow' is
static but used in inline function 'fread' which is not static [-Werror]
         if (__size_mul_overflow(size, count, &total)) {
                          ^

C99 - 6.7.4
"An inline definition of a function with external linkage shall not contain
a definition of a modifiable object with static storage duration, and shall
not contain a reference to an identifier with internal linkage."

As standard does not require compiler to determine when it is safe to
reference an internal function in an external inline function, but instead
delegalizes such reference as a whole, gcc throws a warning for such code
under C99 compilation.  Warning produced by libc header is inhereted widely
and strips the option of using -Werror to track code sanity.

Replace static inline specifier with gnu89 extern inline. Latter "is used
only for inlining. In no case is the function compiled on its own", which
is slightly different from former semantically, but should produce the same
result here.

Change-Id: I6a3374498e5499d110e54468cf9d0d67d2debbe2

libc/include/sys/cdefs.h

index 342cfad..f51942b 100644 (file)
 #define __size_mul_overflow(a, b, result) __builtin_umul_overflow(a, b, result)
 #endif
 #else
-static __inline__ __always_inline int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b,
-                                                          __SIZE_TYPE__ *result) {
+extern __inline__ __always_inline __attribute__((gnu_inline))
+int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) {
     *result = a * b;
     static const __SIZE_TYPE__ mul_no_overflow = 1UL << (sizeof(__SIZE_TYPE__) * 4);
     return (a >= mul_no_overflow || b >= mul_no_overflow) && a > 0 && (__SIZE_TYPE__)-1 / a < b;