Add -fdeclspec to NXT_RUBY_CFLAGS for Clang, if it's available.
Clang incorrectly reports 1 for __has_declspec_attribute(x) in
some cases, such as MacOS or Cygwin. That causes ruby code to
break. ruby added -fdeclspec to their CFLAGS in 2019 to
workaround this bug, since it enables __declspec() and therefore,
the compiler behavior matches what it reports.
Since we don't know what are all the architectures that trigger
the clang bug, let's add the flag for all of them (especially
since it should be harmless).
Add this workaround only at the time of configuring the ruby
module. This way we don't clutter the global NXT_CFLAGS with an
unnecessary flag.
Link: unit bug <https://github.com/nginx/unit/issues/653>
Link: ruby bug <https://bugs.ruby-lang.org/issues/18616>
Link: LLVM bug <https://github.com/llvm/llvm-project/issues/49958>
Commit: LLVM: Add -fdeclspec <d170c4b57a91adc74ca89c6d4af616a00323b12c>
Commit: ruby: Use -fdeclspec <0958e19ffb047781fe1506760c7cbd8d7fe74e57>
When testing some configurations of compilers and OSes, I noticed
that clang(1) 13 on Debian caused a function to be compiled but
unused, and the compiler triggered a compile error.
To avoid that error, use __attribute__((__unused__)). Let's call
our wrapper NXT_MAYBE_UNUSED, since it describes itself more
precisely than the GCC attribute name. It's also the name that
C2x (likely C23) has given to the standard attribute, which is
[[maybe_unused]], so it's also likely to be more readable because
of that name being in ISO C.
The previous commit added more generic APIs for handling
NXT_CONF_VALUE_ARRAY and non-NXT_CONF_VALUE_ARRAY together.
Modify calling code to remove special cases for arrays and
non-arrays, taking special care that the path for non arrays is
logically equivalent to the previous special cased code.
Use the now-generic array code only.
Similar to how C pointers to variables can always be considered as
pointers to the first element of an array of size 1 (see the
following code for an example of how they are equivalent),
treating non-NXT_CONF_VALUE_ARRAY as if they were
NXT_CONF_VALUE_ARRAYs of size 1 allows for simpler and more
generic code.
void foo(ptrdiff_t sz, int arr[sz])
{
for (ptrdiff_t i = 0; i < sz; i++)
arr[i] = 0;
}
void bar(void)
{
int x;
int y[1];
foo(1, &x);
foo(1, y);
}
nxt_conf_array_elements_count_or_1():
Similar to nxt_conf_array_elements_count().
Return a size of 1 when input is non-array, instead of
causing undefined behavior. That value (1) makes sense
because it will be used as the limiter of a loop that
loops over the array and calls
nxt_conf_get_array_element_or_itself(), which will return
a correct element for such loops.
nxt_conf_get_array_element_or_itself():
Similar to nxt_conf_get_array_element().
Return the input pointer unmodified (i.e., a pointer to
the unique element of a hypothetical array), instead of
returning NULL, which wasn't very useful.
nxt_conf_array_qsort():
Since it's a no-op for non-arrays, this API can be reused.