From 2b87f966085b9569e492934ffa05c251dc06ce4b Mon Sep 17 00:00:00 2001 From: jsm28 Date: Sat, 10 Apr 2004 18:47:50 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80584 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 5 +++ gcc/c-typeck.c | 19 ++++++++- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/c90-intprom-1.c | 47 ++++++++++++++++++++++ gcc/testsuite/gcc.dg/c99-intprom-1.c | 77 ++++++++++++++++++++++++++++++++++++ 5 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/c90-intprom-1.c create mode 100644 gcc/testsuite/gcc.dg/c99-intprom-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 44791b520a5..dd10d4e7d93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2004-04-10 Joseph S. Myers + + * c-typeck.c (common_type): Prefer long long to long when same + precision. + 2004-04-09 Zack Weinberg PR 14887 diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 26b83419d84..2170222d769 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 17cbd4d0cb5..040aac8a716 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-04-10 Joseph S. Myers + + * gcc.dg/c90-intprom-1.c, gcc.dg/c99-intprom-1.c: New tests. + 2004-04-09 Chris Demetriou * g++.dg/other/packed1.C: Mark xfail for mips*- not mips-. diff --git a/gcc/testsuite/gcc.dg/c90-intprom-1.c b/gcc/testsuite/gcc.dg/c90-intprom-1.c new file mode 100644 index 00000000000..78e4b39ef35 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c90-intprom-1.c @@ -0,0 +1,47 @@ +/* Test for integer promotion rules: C90 subset of types. */ +/* Origin: Joseph Myers */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */ + +#include + +#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); +} diff --git a/gcc/testsuite/gcc.dg/c99-intprom-1.c b/gcc/testsuite/gcc.dg/c99-intprom-1.c new file mode 100644 index 00000000000..0d7a33ee8be --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-intprom-1.c @@ -0,0 +1,77 @@ +/* Test for integer promotion rules: extended to long long by C99. */ +/* Origin: Joseph Myers */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +#include + +#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 +} -- 2.11.0