/*      $NetBSD: lex_integer.c,v 1.11 2023/03/28 14:44:34 rillig Exp $  */
# 3 "lex_integer.c"

/*
* Tests for lexical analysis of integer constants.
*
* C99 6.4.4.1 "Integer constants"
*/

/* lint1-only-if: lp64 */
/* lint1-extra-flags: -X 351 */

long signed_long;
unsigned long long unsigned_long_long_var;

struct s {
       int member;
};
/*
* When lint tries to convert the argument to 'struct s', it prints the
* actual type of the argument as a side effect.
*/
void print_type(struct s);

void
no_suffix(void)
{
       /* expect+1: ... passing 'int' ... */
       print_type(0);
       /* The '-' is not part of the constant, it is a unary operator. */
       /* expect+1: ... passing 'int' ... */
       print_type(-1);

       /* expect+1: ... passing 'int' ... */
       print_type(2147483647);
       /* expect+1: ... passing 'int' ... */
       print_type(0x7fffffff);
       /* expect+1: ... passing 'int' ... */
       print_type(017777777777);

       /* expect+1: ... passing 'unsigned int' ... */
       print_type(0x80000000);
       /* expect+1: ... passing 'unsigned int' ... */
       print_type(020000000000);
       /* expect+1: ... passing 'unsigned int' ... */
       print_type(0xffffffff);

       /* expect+1: ... passing 'long' ... */
       print_type(2147483648);
       /* expect+1: ... passing 'long' ... */
       print_type(0x0000000100000000);
       /* expect+1: ... passing 'long' ... */
       print_type(0x7fffffffffffffff);

       /* expect+1: ... passing 'unsigned long' ... */
       print_type(0x8000000000000000);
       /* expect+1: ... passing 'unsigned long' ... */
       print_type(0xffffffffffffffff);

       /* expect+2: warning: integer constant out of range [252] */
       /* expect+1: ... passing 'unsigned long' ... */
       print_type(0x00010000000000000000);
}

void
suffix_u(void)
{
       /* expect+1: ... passing 'unsigned int' ... */
       print_type(3U);
       /* expect+1: ... passing 'unsigned int' ... */
       print_type(3u);

       /* expect+1: ... passing 'unsigned int' ... */
       print_type(4294967295U);
       /* expect+1: ... passing 'unsigned long' ... */
       print_type(4294967296U);
}

void
suffix_l(void)
{
       /* expect+1: ... passing 'long' ... */
       print_type(3L);

       /* expect+1: ... passing 'long' ... */
       print_type(3l);
}

void
suffix_ul(void)
{
       /* expect+1: ... passing 'unsigned long' ... */
       print_type(3UL);
       /* expect+1: ... passing 'unsigned long' ... */
       print_type(3LU);
}

void
suffix_ll(void)
{
       /* expect+1: ... passing 'long long' ... */
       print_type(3LL);

       /* The 'Ll' must not use mixed case. Checked by the compiler. */
       /* expect+1: ... passing 'long long' ... */
       print_type(3Ll);

       /* expect+1: ... passing 'long long' ... */
       print_type(3ll);
}

void
suffix_ull(void)
{
       /* expect+1: ... passing 'unsigned long long' ... */
       print_type(3llu);
       /* expect+1: ... passing 'unsigned long long' ... */
       print_type(3Ull);

       /* The 'LL' must not be split. Checked by the compiler. */
       /* expect+1: ... passing 'unsigned long long' ... */
       print_type(3lul);

       /* The 'Ll' must not use mixed case. Checked by the compiler. */
       /* expect+1: ... passing 'unsigned long long' ... */
       print_type(3ULl);
}

void
suffix_too_many(void)
{
       /* expect+2: warning: malformed integer constant [251] */
       /* expect+1: ... passing 'long long' ... */
       print_type(3LLL);

       /* expect+2: warning: malformed integer constant [251] */
       /* expect+1: ... passing 'unsigned int' ... */
       print_type(3uu);
}

/* https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html */
void
binary_literal(void)
{
       /* This is a GCC extension, but lint doesn't know that. */
       /* expect+1: ... passing 'int' ... */
       print_type(0b1111000001011010);

       /* expect+1: ... passing 'unsigned int' ... */
       print_type(0b11110000111100001111000011110000);
}