Skip to content

Commit 306ef69

Browse files
committed
Add compatibility feature and releasenotes
1 parent c07677e commit 306ef69

File tree

7 files changed

+57
-8
lines changed

7 files changed

+57
-8
lines changed

RELEASENOTES.docu

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,4 +1771,12 @@ extern typedef struct { } my_type_t;</pre> </add-note></build-id>
17711771
m(conf_object_t)</tt> for function pointers is only permitted
17721772
when this feature is enabled. The feature will be disabled in
17731773
Simics API versions > 7.</add-note></build-id>
1774+
<build-id _6="next" _7="next"><add-note>Typechecking has been reworked
1775+
to be more strict, and more accurately reject type mismatch that would
1776+
result in invalid C. To avoid breakage in corners where DMLC is entirely
1777+
responsible for proper typechecking, such as uses of <tt>extern</tt>
1778+
macros or method overrides, the legacy lenient typechecking is still used
1779+
by default with Simics API version 7 or below. The strict typechecking can
1780+
be enabled by passing <tt>--no-compat=lenient_typechecking</tt> to
1781+
DMLC.</add-note></build-id>
17741782
</rn>

lib/1.2/dml-builtins.dml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ template device {
214214
parameter _compat_io_memory auto;
215215
parameter _compat_shared_logs_on_device auto;
216216
parameter _compat_suppress_WLOGMIXUP auto;
217+
parameter _compat_lenient_typechecking auto;
217218
parameter _compat_dml12_inline auto;
218219
parameter _compat_dml12_not auto;
219220
parameter _compat_dml12_goto auto;

lib/1.4/dml-builtins.dml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,7 @@ template device {
560560
param _compat_io_memory auto;
561561
param _compat_shared_logs_on_device auto;
562562
param _compat_suppress_WLOGMIXUP auto;
563+
param _compat_lenient_typechecking auto;
563564
param _compat_dml12_inline auto;
564565
param _compat_dml12_not auto;
565566
param _compat_dml12_goto auto;

py/dml/compat.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,23 @@ class suppress_WLOGMIXUP(CompatFeature):
178178
last_api_version = api_6
179179

180180

181+
@feature
182+
class lenient_typechecking(CompatFeature):
183+
'''This compatibility feature makes DMLC's type checking very inexact and
184+
lenient in multiple respects when compared to GCC's type checking of the
185+
generated C.
186+
This discrepency mostly affects method overrides or uses of `extern`:d C
187+
macros, because in those scenarios DMLC can become wholly responsible for
188+
proper type checking.
189+
190+
While migrating from this feature, novel type errors due to uses of
191+
`extern`:d macros can often be resolved by changing the signature of
192+
the `extern` declaration to more accurately reflect the macro's effective
193+
type.
194+
'''
195+
short = "Make type checking inexact and lenient"
196+
last_api_version = api_7
197+
181198
@feature
182199
class dml12_inline(CompatFeature):
183200
'''When using `inline` to inline a method in a DML 1.2 device,

py/dml/structure.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,13 @@ def typecheck_method_override(m1, m2, location):
674674
# TODO move to caller
675675
(_, type1) = eval_type(t1, a1.site, location, global_scope)
676676
(_, type2) = eval_type(t2, a2.site, location, global_scope)
677-
if safe_realtype_unconst(type1).cmp(
678-
safe_realtype_unconst(type2)) != 0:
677+
type1 = safe_realtype_unconst(type1)
678+
type2 = safe_realtype_unconst(type2)
679+
680+
ok = (type1.cmp_fuzzy(type2)
681+
if compat.lenient_typechecking in dml.globals.enabled_compat
682+
else type1.cmp(type2)) == 0
683+
if not ok:
679684
raise EMETH(a1.site, a2.site,
680685
f"mismatching types in input argument {n1}")
681686

@@ -684,8 +689,12 @@ def typecheck_method_override(m1, m2, location):
684689
((n1, t1), (n2, t2)) = (a1.args, a2.args)
685690
(_, type1) = eval_type(t1, a1.site, location, global_scope)
686691
(_, type2) = eval_type(t2, a2.site, location, global_scope)
687-
if safe_realtype_unconst(type1).cmp(
688-
safe_realtype_unconst(type2)) != 0:
692+
type1 = safe_realtype_unconst(type1)
693+
type2 = safe_realtype_unconst(type2)
694+
ok = (type1.cmp_fuzzy(type2)
695+
if compat.lenient_typechecking in dml.globals.enabled_compat
696+
else type1.cmp(type2)) == 0
697+
if not ok:
689698
msg = "mismatching types in return value"
690699
if len(outp1) > 1:
691700
msg += f" {i + 1}"

py/dml/traits.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import contextlib
88
import abc
99
import os
10-
from . import objects, logging, crep, codegen, toplevel, topsort
10+
from . import objects, logging, crep, codegen, toplevel, topsort, compat
1111
from .logging import *
1212
from .codegen import *
1313
from .symtab import *
@@ -398,11 +398,21 @@ def typecheck_method_override(left, right):
398398
if throws0 != throws1:
399399
raise EMETH(site0, site1, "different nothrow annotations")
400400
for ((n, t0), (_, t1)) in zip(inp0, inp1):
401-
if safe_realtype_unconst(t0).cmp(safe_realtype_unconst(t1)) != 0:
401+
t0 = safe_realtype_unconst(t0)
402+
t1 = safe_realtype_unconst(t1)
403+
ok = (t0.cmp_fuzzy(t1)
404+
if compat.lenient_typechecking in dml.globals.enabled_compat
405+
else t0.cmp(t1)) == 0
406+
if not ok:
402407
raise EMETH(site0, site1,
403408
"mismatching types in input argument %s" % (n,))
404409
for (i, ((_, t0), (_, t1))) in enumerate(zip(outp0, outp1)):
405-
if safe_realtype_unconst(t0).cmp(safe_realtype_unconst(t1)) != 0:
410+
t0 = safe_realtype_unconst(t0)
411+
t1 = safe_realtype_unconst(t1)
412+
ok = (t0.cmp_fuzzy(t1)
413+
if compat.lenient_typechecking in dml.globals.enabled_compat
414+
else t0.cmp(t1)) == 0
415+
if not ok:
406416
raise EMETH(site0, site1,
407417
"mismatching types in output argument %d" % (i + 1,))
408418

py/dml/types.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,8 @@ def canstore(self, other):
936936
and shallow_const(other.base))
937937
if self.base.void or other.base.void:
938938
ok = True
939+
if compat.lenient_typechecking in dml.globals.enabled_compat:
940+
constviol = False
939941
else:
940942
unconst_self_base = safe_realtype_unconst(self.base)
941943
unconst_other_base = safe_realtype_unconst(other.base)
@@ -945,7 +947,8 @@ def canstore(self, other):
945947
else unconst_self_base.cmp)(unconst_other_base)
946948
== 0)
947949
elif isinstance(other, TFunction):
948-
ok = safe_realtype_unconst(self.base).cmp(other) == 0
950+
ok = (compat.lenient_typechecking in dml.globals.enabled_compat
951+
or safe_realtype_unconst(self.base).cmp(other) == 0)
949952
# TODO gate this behind dml.globals.dml_version == (1, 2) or
950953
# dml12_misc?
951954
if self.base.void and isinstance(other, TDevice):

0 commit comments

Comments
 (0)