/*
 * Oracle Linux DTrace.
 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */

/*
 * ASSERTION:  Integers are promoted correctly for mixed-type adds.
 *	       The .r results file can be generated by copying this file
 *	       to a .c file and compiling the resulting C program.
 *
 * SECTION: Types, Operators, and Expressions/Arithmetic Operators
 */
/* @@runtest-opts: -qC -DUSE_AS_D_SCRIPT */

#ifndef USE_AS_D_SCRIPT
#include <stdio.h>
#endif

signed char c;
short s;
int i;
long long l;
unsigned char C;
unsigned short S;
unsigned int I;
unsigned long long L;

#ifdef USE_AS_D_SCRIPT
#define FMT " %d"
#define USE_FMT(f)
#else
char *fmt;
#define FMT fmt
#define USE_FMT(f) fmt = f;
#endif

#define TEST(x, y) \
  x = -2; y = -3; printf(FMT, x + y); printf(FMT, y + x); \
  x = -2; y = +3; printf(FMT, x + y); printf(FMT, y + x); \
  x = +2; y = -3; printf(FMT, x + y); printf(FMT, y + x); \
  x = +2; y = +3; printf(FMT, x + y); printf(FMT, y + x); printf("\n");

#ifdef USE_AS_D_SCRIPT
BEGIN
#else
int main(int c_unused, char *v_unused)
#endif
{
	/* cast to signed char */
	USE_FMT(" %hhd");
	TEST(c, c)

	/* cast to unsigned char */
	USE_FMT(" %hhu");
	TEST(C, c)
	TEST(C, C)

	/* cast to short */
	USE_FMT(" %hd");
	TEST(s, c)
	TEST(s, C)
	TEST(s, s)

	/* cast to unsigned short */
	USE_FMT(" %hu");
	TEST(S, c)
	TEST(S, C)
	TEST(S, s)
	TEST(S, S)

	/* cast to int */
	USE_FMT(" %d");
	TEST(i, c)
	TEST(i, C)
	TEST(i, s)
	TEST(i, S)
	TEST(i, i)

	/* cast to unsigned int */
	USE_FMT(" %u");
	TEST(I, c)
	TEST(I, C)
	TEST(I, s)
	TEST(I, S)
	TEST(I, i)
	TEST(I, I)

	/* cast to long long */
	USE_FMT(" %lld");
	TEST(l, c)
	TEST(l, C)
	TEST(l, s)
	TEST(l, S)
	TEST(l, i)
	TEST(l, I)
	TEST(l, l)

	/* cast to unsigned long long */
	USE_FMT(" %llu");
	TEST(L, c)
	TEST(L, C)
	TEST(L, s)
	TEST(L, S)
	TEST(L, i)
	TEST(L, I)
	TEST(L, l)
	TEST(L, L)

#ifdef USE_AS_D_SCRIPT
	exit (0);
#else
	return 0;
#endif
}
