diff options
| author | Paul Eggert | 2011-05-05 23:03:30 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-05-05 23:03:30 -0700 |
| commit | 9991d78e8cd74e986a9b7625c12a43fbf7a283b3 (patch) | |
| tree | 07af5416a46bc002e97c8d1ee30337f2c15b0f6f /lib | |
| parent | 122b0c864338fa0c428b0ff2afbed2454dd2d1c7 (diff) | |
| download | emacs-9991d78e8cd74e986a9b7625c12a43fbf7a283b3.tar.gz emacs-9991d78e8cd74e986a9b7625c12a43fbf7a283b3.zip | |
Merge from gnulib.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/verify.h | 130 |
1 files changed, 79 insertions, 51 deletions
diff --git a/lib/verify.h b/lib/verify.h index 6bca43f6a9b..e5065ffa00b 100644 --- a/lib/verify.h +++ b/lib/verify.h | |||
| @@ -17,42 +17,37 @@ | |||
| 17 | 17 | ||
| 18 | /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ | 18 | /* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */ |
| 19 | 19 | ||
| 20 | #ifndef VERIFY_H | 20 | #ifndef _GL_VERIFY_H |
| 21 | # define VERIFY_H 1 | 21 | # define _GL_VERIFY_H |
| 22 | 22 | ||
| 23 | /* Define HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the | 23 | |
| 24 | /* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per the | ||
| 24 | C1X draft N1548 section 6.7.10. This is supported by GCC 4.6.0 and | 25 | C1X draft N1548 section 6.7.10. This is supported by GCC 4.6.0 and |
| 25 | later, in C mode, and its use here generates easier-to-read diagnostics | 26 | later, in C mode, and its use here generates easier-to-read diagnostics |
| 26 | when verify (R) fails. | 27 | when verify (R) fails. |
| 27 | 28 | ||
| 28 | Define HAVE_STATIC_ASSERT to 1 if static_assert works as per the | 29 | Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per the |
| 29 | C1X draft N1548 section 7.2 or the C++0X draft N3242 section 7.(4). | 30 | C++0X draft N3242 section 7.(4). |
| 30 | This will likely be supported by future GCC versions, in C++ mode. | 31 | This will likely be supported by future GCC versions, in C++ mode. |
| 31 | 32 | ||
| 32 | For now, use this only with GCC. Eventually whether _Static_assert | 33 | Use this only with GCC. If we were willing to slow 'configure' |
| 33 | and static_assert works should be determined by 'configure'. */ | 34 | down we could also use it with other compilers, but since this |
| 35 | affects only the quality of diagnostics, why bother? */ | ||
| 34 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus | 36 | # if (4 < __GNUC__ || (__GNUC__ == 4 && 6 <= __GNUC_MINOR__)) && !defined __cplusplus |
| 35 | # define HAVE__STATIC_ASSERT 1 | 37 | # define _GL_HAVE__STATIC_ASSERT 1 |
| 36 | # endif | 38 | # endif |
| 37 | /* The condition (99 < __GNUC__) is temporary, until we know about the | 39 | /* The condition (99 < __GNUC__) is temporary, until we know about the |
| 38 | first G++ release that supports static_assert. */ | 40 | first G++ release that supports static_assert. */ |
| 39 | # if (99 < __GNUC__) && defined __cplusplus | 41 | # if (99 < __GNUC__) && defined __cplusplus |
| 40 | # define HAVE_STATIC_ASSERT 1 | 42 | # define _GL_HAVE_STATIC_ASSERT 1 |
| 41 | # endif | 43 | # endif |
| 42 | 44 | ||
| 43 | /* Each of these macros verifies that its argument R is nonzero. To | 45 | /* Each of these macros verifies that its argument R is nonzero. To |
| 44 | be portable, R should be an integer constant expression. Unlike | 46 | be portable, R should be an integer constant expression. Unlike |
| 45 | assert (R), there is no run-time overhead. | 47 | assert (R), there is no run-time overhead. |
| 46 | 48 | ||
| 47 | There are two macros, since no single macro can be used in all | ||
| 48 | contexts in C. verify_true (R) is for scalar contexts, including | ||
| 49 | integer constant expression contexts. verify (R) is for declaration | ||
| 50 | contexts, e.g., the top level. | ||
| 51 | |||
| 52 | Symbols ending in "__" are private to this header. | ||
| 53 | |||
| 54 | If _Static_assert works, verify (R) uses it directly. Similarly, | 49 | If _Static_assert works, verify (R) uses it directly. Similarly, |
| 55 | verify_true (R) works by packaging a _Static_assert inside a struct | 50 | _GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct |
| 56 | that is an operand of sizeof. | 51 | that is an operand of sizeof. |
| 57 | 52 | ||
| 58 | The code below uses several ideas for C++ compilers, and for C | 53 | The code below uses several ideas for C++ compilers, and for C |
| @@ -64,7 +59,9 @@ | |||
| 64 | constant and nonnegative. | 59 | constant and nonnegative. |
| 65 | 60 | ||
| 66 | * Next this expression W is wrapped in a type | 61 | * Next this expression W is wrapped in a type |
| 67 | struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }. | 62 | struct _gl_verify_type { |
| 63 | unsigned int _gl_verify_error_if_negative: W; | ||
| 64 | }. | ||
| 68 | If W is negative, this yields a compile-time error. No compiler can | 65 | If W is negative, this yields a compile-time error. No compiler can |
| 69 | deal with a bit-field of negative size. | 66 | deal with a bit-field of negative size. |
| 70 | 67 | ||
| @@ -78,7 +75,7 @@ | |||
| 78 | 75 | ||
| 79 | void function (int n) { verify (n < 0); } | 76 | void function (int n) { verify (n < 0); } |
| 80 | 77 | ||
| 81 | * For the verify macro, the struct verify_type__ will need to | 78 | * For the verify macro, the struct _gl_verify_type will need to |
| 82 | somehow be embedded into a declaration. To be portable, this | 79 | somehow be embedded into a declaration. To be portable, this |
| 83 | declaration must declare an object, a constant, a function, or a | 80 | declaration must declare an object, a constant, a function, or a |
| 84 | typedef name. If the declared entity uses the type directly, | 81 | typedef name. If the declared entity uses the type directly, |
| @@ -116,11 +113,11 @@ | |||
| 116 | Which of the following alternatives can be used? | 113 | Which of the following alternatives can be used? |
| 117 | 114 | ||
| 118 | extern int dummy [sizeof (struct {...})]; | 115 | extern int dummy [sizeof (struct {...})]; |
| 119 | extern int dummy [sizeof (struct verify_type__ {...})]; | 116 | extern int dummy [sizeof (struct _gl_verify_type {...})]; |
| 120 | extern void dummy (int [sizeof (struct {...})]); | 117 | extern void dummy (int [sizeof (struct {...})]); |
| 121 | extern void dummy (int [sizeof (struct verify_type__ {...})]); | 118 | extern void dummy (int [sizeof (struct _gl_verify_type {...})]); |
| 122 | extern int (*dummy (void)) [sizeof (struct {...})]; | 119 | extern int (*dummy (void)) [sizeof (struct {...})]; |
| 123 | extern int (*dummy (void)) [sizeof (struct verify_type__ {...})]; | 120 | extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})]; |
| 124 | 121 | ||
| 125 | In the second and sixth case, the struct type is exported to the | 122 | In the second and sixth case, the struct type is exported to the |
| 126 | outer scope; two such declarations therefore collide. GCC warns | 123 | outer scope; two such declarations therefore collide. GCC warns |
| @@ -159,44 +156,75 @@ | |||
| 159 | possible. */ | 156 | possible. */ |
| 160 | # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) | 157 | # define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER) |
| 161 | 158 | ||
| 162 | /* Verify requirement R at compile-time, as an integer constant expression. | 159 | /* Verify requirement R at compile-time, as an integer constant expression |
| 163 | Return 1. */ | 160 | that returns 1. If R is false, fail at compile-time, preferably |
| 161 | with a diagnostic that includes the string-literal DIAGNOSTIC. */ | ||
| 162 | |||
| 163 | # define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \ | ||
| 164 | (!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC))) | ||
| 164 | 165 | ||
| 165 | # ifdef __cplusplus | 166 | # ifdef __cplusplus |
| 166 | template <int w> | 167 | template <int w> |
| 167 | struct verify_type__ { unsigned int verify_error_if_negative_size__: w; }; | 168 | struct _gl_verify_type { |
| 168 | # define verify_true(R) \ | 169 | unsigned int _gl_verify_error_if_negative: w; |
| 169 | (!!sizeof (verify_type__<(R) ? 1 : -1>)) | 170 | }; |
| 170 | # elif HAVE__STATIC_ASSERT | 171 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
| 171 | # define verify_true(R) \ | 172 | _gl_verify_type<(R) ? 1 : -1> |
| 172 | (!!sizeof \ | 173 | # elif defined _GL_HAVE__STATIC_ASSERT |
| 173 | (struct { \ | 174 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
| 174 | _Static_assert (R, "verify_true (" #R ")"); \ | 175 | struct { \ |
| 175 | int verify_dummy__; \ | 176 | _Static_assert (R, DIAGNOSTIC); \ |
| 176 | })) | 177 | int _gl_dummy; \ |
| 177 | # elif HAVE_STATIC_ASSERT | 178 | } |
| 178 | # define verify_true(R) \ | ||
| 179 | (!!sizeof \ | ||
| 180 | (struct { \ | ||
| 181 | static_assert (R, "verify_true (" #R ")"); \ | ||
| 182 | int verify_dummy__; \ | ||
| 183 | })) | ||
| 184 | # else | 179 | # else |
| 185 | # define verify_true(R) \ | 180 | # define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \ |
| 186 | (!!sizeof \ | 181 | struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; } |
| 187 | (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; })) | ||
| 188 | # endif | 182 | # endif |
| 189 | 183 | ||
| 190 | /* Verify requirement R at compile-time, as a declaration without a | 184 | /* Verify requirement R at compile-time, as a declaration without a |
| 191 | trailing ';'. */ | 185 | trailing ';'. If R is false, fail at compile-time, preferably |
| 186 | with a diagnostic that includes the string-literal DIAGNOSTIC. | ||
| 187 | |||
| 188 | Unfortunately, unlike C1X, this implementation must appear as an | ||
| 189 | ordinary declaration, and cannot appear inside struct { ... }. */ | ||
| 190 | |||
| 191 | # ifdef _GL_HAVE__STATIC_ASSERT | ||
| 192 | # define _GL_VERIFY _Static_assert | ||
| 193 | # else | ||
| 194 | # define _GL_VERIFY(R, DIAGNOSTIC) \ | ||
| 195 | extern int (*_GL_GENSYM (_gl_verify_function) (void)) \ | ||
| 196 | [_GL_VERIFY_TRUE (R, DIAGNOSTIC)] | ||
| 197 | # endif | ||
| 192 | 198 | ||
| 193 | # if HAVE__STATIC_ASSERT | 199 | /* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */ |
| 194 | # define verify(R) _Static_assert (R, "verify (" #R ")") | 200 | # ifdef _GL_STATIC_ASSERT_H |
| 195 | # elif HAVE_STATIC_ASSERT | 201 | # if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert |
| 196 | # define verify(R) static_assert (R, "verify (" #R ")") | 202 | # define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC) |
| 203 | # endif | ||
| 204 | # if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert | ||
| 205 | # define static_assert _Static_assert /* Draft C1X requires this #define. */ | ||
| 206 | # endif | ||
| 197 | # else | 207 | # else |
| 198 | # define verify(R) \ | 208 | |
| 199 | extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)] | 209 | /* Each of these macros verifies that its argument R is nonzero. To |
| 210 | be portable, R should be an integer constant expression. Unlike | ||
| 211 | assert (R), there is no run-time overhead. | ||
| 212 | |||
| 213 | There are two macros, since no single macro can be used in all | ||
| 214 | contexts in C. verify_true (R) is for scalar contexts, including | ||
| 215 | integer constant expression contexts. verify (R) is for declaration | ||
| 216 | contexts, e.g., the top level. */ | ||
| 217 | |||
| 218 | /* Verify requirement R at compile-time, as an integer constant expression. | ||
| 219 | Return 1. */ | ||
| 220 | |||
| 221 | # define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")") | ||
| 222 | |||
| 223 | /* Verify requirement R at compile-time, as a declaration without a | ||
| 224 | trailing ';'. */ | ||
| 225 | |||
| 226 | # define verify(R) _GL_VERIFY (R, "verify (" #R ")") | ||
| 227 | |||
| 200 | # endif | 228 | # endif |
| 201 | 229 | ||
| 202 | #endif | 230 | #endif |