]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUILD: threads/plock: fix a build issue on Clang without optimization
authorWilly Tarreau <w@1wt.eu>
Mon, 20 Nov 2017 18:25:18 +0000 (19:25 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 20 Nov 2017 20:06:35 +0000 (21:06 +0100)
[ plock commit 4c53fd3a0b2b1892817cebd0db012a52f4087850 ]

Pieter Baauw reported a build issue affecting haproxy after plock was
included. It happens that expressions of the form :

     if ((const) ? (expr1) : (expr2))
       do_something()

always produce code for both expr1 and expr2 on Clang when building
without optimization. The resulting asm code is even funny, basically
doing :

     mov reg, 1
     cmp reg, 1
     ...

This causes our sizeof() tests to fail to build because we purposely
dereference a fake function that reports the location and nature of the
inconsistency, but this fake function appears in the object code despite
all conditions being there to avoid it.

However the compiler is still smart enough to optimize away code doing

    if (const)
       do_something()

So we simply repeat the condition before do_something(), and the dummy
function is not referenced anymore unless really required.

include/import/atomic-ops.h
include/import/plock.h

index 9d0e4f582b2b3b9d678974dcd58a3efb8db9d1ca..0081f9a6985cabd9abad6619c11c203219d0be51 100644 (file)
@@ -78,7 +78,9 @@
                ret; /* return value */                                       \
        }) : ({                                                               \
                void __unsupported_argument_size_for_pl_inc__(char *,int);    \
-               __unsupported_argument_size_for_pl_inc__(__FILE__,__LINE__);  \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                      \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \
+                       __unsupported_argument_size_for_pl_inc__(__FILE__,__LINE__);   \
                0;                                                            \
        })                                                                    \
 )
                ret; /* return value */                                       \
        }) : ({                                                               \
                void __unsupported_argument_size_for_pl_dec__(char *,int);    \
-               __unsupported_argument_size_for_pl_dec__(__FILE__,__LINE__);  \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                      \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \
+                       __unsupported_argument_size_for_pl_dec__(__FILE__,__LINE__);   \
                0;                                                            \
        })                                                                    \
 )
                             : "cc");                                         \
        } else {                                                              \
                void __unsupported_argument_size_for_pl_inc_noret__(char *,int);   \
-               __unsupported_argument_size_for_pl_inc_noret__(__FILE__,__LINE__); \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                          \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8))     \
+                       __unsupported_argument_size_for_pl_inc_noret__(__FILE__,__LINE__); \
        }                                                                     \
 })
 
                             : "cc");                                         \
        } else {                                                              \
                void __unsupported_argument_size_for_pl_dec_noret__(char *,int);   \
-               __unsupported_argument_size_for_pl_dec_noret__(__FILE__,__LINE__); \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                          \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8))     \
+                       __unsupported_argument_size_for_pl_dec_noret__(__FILE__,__LINE__); \
        }                                                                     \
 })
 
                             : "cc");                                         \
        } else {                                                              \
                void __unsupported_argument_size_for_pl_add__(char *,int);    \
-               __unsupported_argument_size_for_pl_add__(__FILE__,__LINE__);  \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                          \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8))     \
+                       __unsupported_argument_size_for_pl_add__(__FILE__,__LINE__);       \
        }                                                                     \
 })
 
                             : "cc");                                         \
        } else {                                                              \
                void __unsupported_argument_size_for_pl_sub__(char *,int);    \
-               __unsupported_argument_size_for_pl_sub__(__FILE__,__LINE__);  \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                      \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \
+                       __unsupported_argument_size_for_pl_sub__(__FILE__,__LINE__);   \
        }                                                                     \
 })
 
                             : "cc");                                         \
        } else {                                                              \
                void __unsupported_argument_size_for_pl_and__(char *,int);    \
-               __unsupported_argument_size_for_pl_and__(__FILE__,__LINE__);  \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                       \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8))  \
+                       __unsupported_argument_size_for_pl_and__(__FILE__,__LINE__);    \
        }                                                                     \
 })
 
                             : "cc");                                         \
        } else {                                                              \
                void __unsupported_argument_size_for_pl_or__(char *,int);     \
-               __unsupported_argument_size_for_pl_or__(__FILE__,__LINE__);   \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                       \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8))  \
+                       __unsupported_argument_size_for_pl_or__(__FILE__,__LINE__);     \
        }                                                                     \
 })
 
                             : "cc");                                         \
        } else {                                                              \
                void __unsupported_argument_size_for_pl_xor__(char *,int);    \
-               __unsupported_argument_size_for_pl_xor__(__FILE__,__LINE__);  \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                       \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8))  \
+               __unsupported_argument_size_for_pl_xor__(__FILE__,__LINE__);            \
        }                                                                     \
 })
 
                ret; /* return value */                                       \
        }) : ({                                                               \
                void __unsupported_argument_size_for_pl_bts__(char *,int);    \
-               __unsupported_argument_size_for_pl_bts__(__FILE__,__LINE__);  \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                      \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \
+                       __unsupported_argument_size_for_pl_bts__(__FILE__,__LINE__);   \
                0;                                                            \
        })                                                                    \
 )
                ret; /* return value */                                       \
        }) : ({                                                               \
                void __unsupported_argument_size_for_pl_xadd__(char *,int);   \
-               __unsupported_argument_size_for_pl_xadd__(__FILE__,__LINE__); \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                       \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8))  \
+                       __unsupported_argument_size_for_pl_xadd__(__FILE__,__LINE__);   \
                0;                                                            \
        })                                                                    \
 )
                ret; /* return value */                                       \
        }) : ({                                                               \
                void __unsupported_argument_size_for_pl_xchg__(char *,int);   \
-               __unsupported_argument_size_for_pl_xchg__(__FILE__,__LINE__); \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                       \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8))  \
+               __unsupported_argument_size_for_pl_xchg__(__FILE__,__LINE__);           \
                0;                                                            \
        })                                                                    \
 )
                ret; /* return value */                                       \
        }) : ({                                                               \
                void __unsupported_argument_size_for_pl_cmpxchg__(char *,int);   \
-               __unsupported_argument_size_for_pl_cmpxchg__(__FILE__,__LINE__); \
+               if (sizeof(*(ptr)) != 1 && sizeof(*(ptr)) != 2 &&                      \
+                   sizeof(*(ptr)) != 4 && (sizeof(long) != 8 || sizeof(*(ptr)) != 8)) \
+               __unsupported_argument_size_for_pl_cmpxchg__(__FILE__,__LINE__);       \
                0;                                                            \
        })                                                                    \
 )
index 40bf50bf7bc37b256f0cc4b26f51760572dc0f3b..22244c5a64b86cfee459ac7494b87127d07bd2ee 100644 (file)
@@ -69,7 +69,8 @@
                !__pl_r; /* return value */                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_try_r__(char *,int);                   \
-               __unsupported_argument_size_for_pl_try_r__(__FILE__,__LINE__);                 \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_try_r__(__FILE__,__LINE__);         \
                0;                                                                             \
        })                                                                                     \
 )
@@ -89,7 +90,8 @@
                pl_sub(lock, PLOCK32_RL_1);                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_drop_r__(char *,int);                  \
-               __unsupported_argument_size_for_pl_drop_r__(__FILE__,__LINE__);                \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_drop_r__(__FILE__,__LINE__);        \
        })                                                                                     \
 )
 
                !__pl_r; /* return value */                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_try_s__(char *,int);                   \
-               __unsupported_argument_size_for_pl_try_s__(__FILE__,__LINE__);                 \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_try_s__(__FILE__,__LINE__);         \
                0;                                                                             \
        })                                                                                     \
 )
                pl_sub(lock, PLOCK32_SL_1 + PLOCK32_RL_1);                                     \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_drop_s__(char *,int);                  \
-               __unsupported_argument_size_for_pl_drop_s__(__FILE__,__LINE__);                \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_drop_s__(__FILE__,__LINE__);        \
        })                                                                                     \
 )
 
                pl_sub(lock, PLOCK32_SL_1);                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_stor__(char *,int);                    \
-               __unsupported_argument_size_for_pl_stor__(__FILE__,__LINE__);                  \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_stor__(__FILE__,__LINE__);          \
        })                                                                                     \
 )
 
                        __pl_r = pl_deref_int(lock);                                           \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_stow__(char *,int);                    \
-               __unsupported_argument_size_for_pl_stow__(__FILE__,__LINE__);                  \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_stow__(__FILE__,__LINE__);          \
        })                                                                                     \
 )
 
                pl_sub(lock, PLOCK32_WL_1);                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_wtos__(char *,int);                    \
-               __unsupported_argument_size_for_pl_wtos__(__FILE__,__LINE__);                  \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_wtos__(__FILE__,__LINE__);          \
        })                                                                                     \
 )
 
                pl_sub(lock, PLOCK32_WL_1 | PLOCK32_SL_1);                                     \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_wtor__(char *,int);                    \
-               __unsupported_argument_size_for_pl_wtor__(__FILE__,__LINE__);                  \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_wtor__(__FILE__,__LINE__);          \
        })                                                                                     \
 )
 
                !__pl_r; /* return value */                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_try_w__(char *,int);                   \
-               __unsupported_argument_size_for_pl_try_w__(__FILE__,__LINE__);                 \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_try_w__(__FILE__,__LINE__);         \
                0;                                                                             \
        })                                                                                     \
 )
                pl_sub(lock, PLOCK32_WL_1 | PLOCK32_SL_1 | PLOCK32_RL_1);                      \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_drop_w__(char *,int);                  \
-               __unsupported_argument_size_for_pl_drop_w__(__FILE__,__LINE__);                \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_drop_w__(__FILE__,__LINE__);        \
        })                                                                                     \
 )
 
                !__pl_r; /* return value */                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_try_rtos__(char *,int);                \
-               __unsupported_argument_size_for_pl_try_rtos__(__FILE__,__LINE__);              \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_try_rtos__(__FILE__,__LINE__);      \
                0;                                                                             \
        })                                                                                     \
 )
                !__pl_r; /* return value */                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_try_a__(char *,int);                   \
-               __unsupported_argument_size_for_pl_try_a__(__FILE__,__LINE__);                 \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_try_a__(__FILE__,__LINE__);         \
                0;                                                                             \
        })                                                                                     \
 )
                pl_sub(lock, PLOCK32_WL_1);                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_drop_a__(char *,int);                  \
-               __unsupported_argument_size_for_pl_drop_a__(__FILE__,__LINE__);                \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_drop_a__(__FILE__,__LINE__);        \
        })                                                                                     \
 )
 
                !__pl_r; /* return value */                                                    \
        }) : ({                                                                                \
                void __unsupported_argument_size_for_pl_try_rtoa__(char *,int);                \
-               __unsupported_argument_size_for_pl_try_rtoa__(__FILE__,__LINE__);              \
+               if (sizeof(*(lock)) != 4 && (sizeof(long) != 8 || sizeof(*(lock)) != 8))       \
+                       __unsupported_argument_size_for_pl_try_rtoa__(__FILE__,__LINE__);      \
                0;                                                                             \
        })                                                                                     \
 )