aboutsummaryrefslogtreecommitdiff
path: root/type.c
diff options
context:
space:
mode:
authorMichael Forney <mforney@mforney.org>2019-04-23 21:22:25 -0700
committerMichael Forney <mforney@mforney.org>2019-04-23 21:23:19 -0700
commita98385a607aafe373c14d2a6fb2778d21a600c30 (patch)
tree2b4c71cfb8f7ceab26e65f4489905a85488f6791 /type.c
parente0b772b836265b77686e9a7aa8ad01bb1fca53e7 (diff)
Fix integer promotion on bit-fields
Fixes #47.
Diffstat (limited to 'type.c')
-rw-r--r--type.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/type.c b/type.c
index 30ca520..b05898e 100644
--- a/type.c
+++ b/type.c
@@ -149,7 +149,7 @@ typecompatible(struct type *t1, struct type *t2)
return false;
if (!t2->func.paraminfo) {
for (p1 = t1->func.params; p1; p1 = p1->next) {
- if (!typecompatible(p1->type, typeargpromote(p1->type)))
+ if (!typecompatible(p1->type, typepromote(p1->type, -1)))
return false;
}
return true;
@@ -157,7 +157,7 @@ typecompatible(struct type *t1, struct type *t2)
for (p1 = t1->func.params, p2 = t2->func.params; p1 && p2; p1 = p1->next, p2 = p2->next) {
if (p1->qual != p2->qual)
return false;
- tmp = t2->func.isprototype ? p2->type : typeargpromote(p2->type);
+ tmp = t2->func.isprototype ? p2->type : typepromote(p2->type, -1);
if (!typecompatible(p1->type, tmp))
return false;
}
@@ -186,23 +186,20 @@ typecomposite(struct type *t1, struct type *t2)
}
struct type *
-typeintpromote(struct type *t)
-{
- if (t->prop & PROPINT && typerank(t) <= typerank(&typeint))
- return t->size < typeint.size || t->basic.issigned ? &typeint : &typeuint;
- return t;
-}
-
-struct type *
-typeargpromote(struct type *t)
+typepromote(struct type *t, unsigned width)
{
if (t == &typefloat)
return &typedouble;
- return typeintpromote(t);
+ if (t->prop & PROPINT && (typerank(t) <= typerank(&typeint) || width <= typeint.size * 8)) {
+ if (width == -1)
+ width = t->size * 8;
+ return width - t->basic.issigned < typeint.size * 8 ? &typeint : &typeuint;
+ }
+ return t;
}
struct type *
-typecommonreal(struct type *t1, struct type *t2)
+typecommonreal(struct type *t1, unsigned w1, struct type *t2, unsigned w2)
{
struct type *tmp;
@@ -215,8 +212,8 @@ typecommonreal(struct type *t1, struct type *t2)
return &typedouble;
if (t1 == &typefloat || t2 == &typefloat)
return &typefloat;
- t1 = typeintpromote(t1);
- t2 = typeintpromote(t2);
+ t1 = typepromote(t1, w1);
+ t2 = typepromote(t2, w2);
if (t1 == t2)
return t1;
if (t1->basic.issigned == t2->basic.issigned)