c-semantics icon indicating copy to clipboard operation
c-semantics copied to clipboard

GCC Builtins

Open mrigger opened this issue 7 years ago • 3 comments

We are currently studying the usage of GCC builtins by GitHub projects and how various tools support them. To that end, we are also developing a test suite for the most frequently used machine-independent GCC builtins (available at https://github.com/gcc-builtins/tests). We'd be glad to contribute the test suite (or parts of it) to the project, if you are interested.

kcc (the version from https://runtimeverification.com/match/download/) successfully runs test cases for 10 builtins (__builtin_alloca, __builtin_bswap64, __builtin_sub_overflow, __builtin_add_overflow, __sync_bool_compare_and_swap, __builtin_bswap32, __builtin_offsetof, __builtin_mul_overflow, __builtin_expect, and __builtin_bswap16).

Most other test cases fail because the builtin is unknown:

test-cases/9-__builtin_ctz.c:5:2: error: Trying to look up identifier __builtin_ctz, but no such identifier is in scope.

    Syntax error (SE-CID1):
        see C11 section 6.5.1:2 http://rvdoc.org/C11/6.5.1
        see CERT-C section DCL31-C http://rvdoc.org/CERT-C/DCL31-C

Two of the test cases fail during run time. The first test case is probably debatable:

#include <assert.h>
int main() { assert(__builtin_constant_p(0)); }

kcc does not infer that 0 is a constant, so the test case fails. The GCC docs mention that

A return of 0 does not indicate that the value is not a constant, but merely that GCC cannot prove it is a constant with the specified value of the -O option.

so that behavior is probably okay (although surprising). I assume that the builtin always returns 0?

The other test case that fails during run time is this one:

#include <assert.h>

int main() {
  assert(!__builtin_types_compatible_p(enum {foo, bar}, enum {hot, dog}));
}

This test case is derived from an example given by the GCC docs, which state:

An enum type is not considered to be compatible with another enum type even if both are compatible with the same integer type; this is what the C standard specifies. For example, enum {foo, bar} is not similar to enum {hot, dog}.

GCC, Clang, and ICC implement this builtin correctly.

Do you plan to add additional GCC builtins? I noticed that among the 10 most-commonly used GCC builtins (as determined by our study), __builtin_clz, __sync_synchronize, __sync_fetch_and_add, and __builtin_ctz are unsupported.

mrigger avatar Jul 12 '18 15:07 mrigger

Yes, we've recently been trying to add more support for gnuc builtins, so such a test suite would be very helpful.

We just #define __builtin_constant_p(x) 0 in a header, so that failure isn't surprising, but I'll look into the issue with enum type compatibility. Thanks!

chathhorn avatar Jul 12 '18 15:07 chathhorn

Also, I think there might be a mistake in the list of tests kcc succeeds on -- I wouldn't expect the *_overflow or __sync_bool_compare_and_swap to work either, although maybe kcc is failing in an unexpected way.

chathhorn avatar Jul 12 '18 16:07 chathhorn

I believe the bug in __builtin_types_compatible_p stems from CIL, as we found the same bug there (see https://github.com/cil-project/cil/issues/44).

mrigger avatar Jul 16 '18 16:07 mrigger