c-typeck.c (common_type): Prefer long long to long when same precision.

* c-typeck.c (common_type): Prefer long long to long when same
	precision.

testsuite:
	* gcc.dg/c90-intprom-1.c, gcc.dg/c99-intprom-1.c: New tests.

From-SVN: r80584
This commit is contained in:
Joseph Myers 2004-04-10 19:47:50 +01:00 committed by Joseph Myers
parent 11554edce6
commit c7e1876bf5
5 changed files with 151 additions and 1 deletions

View File

@ -1,3 +1,8 @@
2004-04-10 Joseph S. Myers <jsm@polyomino.org.uk>
* c-typeck.c (common_type): Prefer long long to long when same
precision.
2004-04-09 Zack Weinberg <zack@codesourcery.com>
PR 14887

View File

@ -274,7 +274,24 @@ common_type (tree t1, tree t2)
else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
return build_type_attribute_variant (t2, attributes);
/* Same precision. Prefer longs to ints even when same size. */
/* Same precision. Prefer long longs to longs to ints when the
same precision, following the C99 rules on integer type rank
(which are equivalent to the C90 rules for C90 types). */
if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
|| TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
return build_type_attribute_variant (long_long_unsigned_type_node,
attributes);
if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
|| TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
{
if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
t1 = long_long_unsigned_type_node;
else
t1 = long_long_integer_type_node;
return build_type_attribute_variant (t1, attributes);
}
if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
|| TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)

View File

@ -1,3 +1,7 @@
2004-04-10 Joseph S. Myers <jsm@polyomino.org.uk>
* gcc.dg/c90-intprom-1.c, gcc.dg/c99-intprom-1.c: New tests.
2004-04-09 Chris Demetriou <cgd@broadcom.com>
* g++.dg/other/packed1.C: Mark xfail for mips*- not mips-.

View File

@ -0,0 +1,47 @@
/* Test for integer promotion rules: C90 subset of types. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
#include <limits.h>
#define CHECK(T1, T2, TC) \
do { \
T1 a = 0; \
T2 b = 0; \
TC *c = 0; \
__typeof__(a+b) *d = 0; \
c = d; \
d = c; \
} while (0)
void
f (void)
{
/* One type is unsigned long. */
CHECK(unsigned long, unsigned long, unsigned long);
CHECK(unsigned int, unsigned long, unsigned long);
CHECK(unsigned long, unsigned int, unsigned long);
CHECK(int, unsigned long, unsigned long);
CHECK(long, unsigned long, unsigned long);
CHECK(unsigned long, int, unsigned long);
CHECK(unsigned long, long, unsigned long);
/* long and unsigned int. */
#if LONG_MAX >= UINT_MAX
CHECK(unsigned int, long, long);
CHECK(long, unsigned int, long);
#else
CHECK(unsigned int, long, unsigned long);
CHECK(long, unsigned int, unsigned long);
#endif
/* One type is long. */
CHECK(long, long, long);
CHECK(int, long, long);
CHECK(long, int, long);
/* One type is unsigned int. */
CHECK(unsigned int, unsigned int, unsigned int);
CHECK(int, unsigned int, unsigned int);
CHECK(unsigned int, int, unsigned int);
/* Otherwise int. */
CHECK(int, int, int);
}

View File

@ -0,0 +1,77 @@
/* Test for integer promotion rules: extended to long long by C99. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
#include <limits.h>
#define CHECK(T1, T2, TC) \
do { \
T1 a = 0; \
T2 b = 0; \
TC *c = 0; \
__typeof__(a+b) *d = 0; \
c = d; \
d = c; \
} while (0)
void
f (void)
{
/* Same type. */
CHECK(int, int, int);
CHECK(unsigned int, unsigned int, unsigned int);
CHECK(long, long, long);
CHECK(unsigned long, unsigned long, unsigned long);
CHECK(long long, long long, long long);
CHECK(unsigned long long, unsigned long long, unsigned long long);
/* Both signed. */
CHECK(int, long, long);
CHECK(int, long long, long long);
CHECK(long, int, long);
CHECK(long, long long, long long);
CHECK(long long, int, long long);
CHECK(long long, long, long long);
/* Both unsigned. */
CHECK(unsigned int, unsigned long, unsigned long);
CHECK(unsigned int, unsigned long long, unsigned long long);
CHECK(unsigned long, unsigned int, unsigned long);
CHECK(unsigned long, unsigned long long, unsigned long long);
CHECK(unsigned long long, unsigned int, unsigned long long);
CHECK(unsigned long long, unsigned long, unsigned long long);
/* Unsigned of greater or equal rank. */
CHECK(int, unsigned int, unsigned int);
CHECK(int, unsigned long, unsigned long);
CHECK(int, unsigned long long, unsigned long long);
CHECK(unsigned int, int, unsigned int);
CHECK(long, unsigned long, unsigned long);
CHECK(long, unsigned long long, unsigned long long);
CHECK(unsigned long, int, unsigned long);
CHECK(unsigned long, long, unsigned long);
CHECK(long long, unsigned long long, unsigned long long);
CHECK(unsigned long long, int, unsigned long long);
CHECK(unsigned long long, long, unsigned long long);
CHECK(unsigned long long, long long, unsigned long long);
/* Signed of greater rank. */
#if LONG_MAX >= UINT_MAX
CHECK(unsigned int, long, long);
CHECK(long, unsigned int, long);
#else
CHECK(unsigned int, long, unsigned long);
CHECK(long, unsigned int, unsigned long);
#endif
#if LLONG_MAX >= UINT_MAX
CHECK(unsigned int, long long, long long);
CHECK(long long, unsigned int, long long);
#else
CHECK(unsigned int, long long, unsigned long long);
CHECK(long long, unsigned int, unsigned long long);
#endif
#if LLONG_MAX >= ULONG_MAX
CHECK(unsigned long, long long, long long);
CHECK(long long, unsigned long, long long);
#else
CHECK(unsigned long, long long, unsigned long long);
CHECK(long long, unsigned long, unsigned long long);
#endif
}