Skip to content

Commit c3468c0

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Various fixes.
- Fixed duplicate element handling when inheriting the same element from two base classes, where the element is a duplicate in one base class but not the other. - Added missing constant evaluation of unary minus for arrays. Belonging to [master]: - OpenModelica/OMCompiler#2483 - OpenModelica/OpenModelica-testsuite#968
1 parent afc94ce commit c3468c0

File tree

4 files changed

+67
-39
lines changed

4 files changed

+67
-39
lines changed

Compiler/NFFrontEnd/NFCeval.mo

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,12 @@ algorithm
879879
exp := match exp1
880880
case Expression.INTEGER() then Expression.INTEGER(-exp1.value);
881881
case Expression.REAL() then Expression.REAL(-exp1.value);
882+
case Expression.ARRAY()
883+
algorithm
884+
exp1.elements := list(evalUnaryMinus(e) for e in exp1.elements);
885+
then
886+
exp1;
887+
882888
else
883889
algorithm
884890
exp := Expression.UNARY(Operator.makeUMinus(Type.UNKNOWN()), exp1);

Compiler/NFFrontEnd/NFClassTree.mo

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ public
7575
case IMPORT() then entry.index;
7676
end match;
7777
end index;
78+
79+
function isEqual
80+
input Entry entry1;
81+
input Entry entry2;
82+
output Boolean isEqual = index(entry1) == index(entry2);
83+
end isEqual;
7884
end Entry;
7985

8086
import BaseAvlTree;
@@ -152,6 +158,15 @@ public
152158
output Entry entry = ENTRY(lentry, NONE(), {}, EntryType.ENTRY);
153159
end newEntry;
154160

161+
function idExistsInEntry
162+
input LookupTree.Entry id;
163+
input Entry entry;
164+
output Boolean exists;
165+
algorithm
166+
exists := LookupTree.Entry.isEqual(id, entry.entry) or
167+
List.exist(entry.children, function idExistsInEntry(id = id));
168+
end idExistsInEntry;
169+
155170
annotation(__OpenModelica_Interface="util");
156171
end DuplicateTree;
157172

@@ -1665,6 +1680,7 @@ public
16651680
DuplicateTree.Entry dup_entry;
16661681
Integer new_id = LookupTree.Entry.index(newEntry);
16671682
Integer old_id = LookupTree.Entry.index(oldEntry);
1683+
DuplicateTree.EntryType ty;
16681684
algorithm
16691685
dups := Mutable.access(duplicates);
16701686
opt_dup_entry := DuplicateTree.getOpt(dups, name);
@@ -1681,48 +1697,56 @@ public
16811697

16821698
dups := DuplicateTree.add(dups, name, dup_entry);
16831699
Mutable.update(duplicates, dups);
1684-
elseif isNone(DuplicateTree.getOpt(extDuplicates, name)) then
1685-
// If a duplicate entry does exist, but not in the extends node's duplicate
1686-
// tree, then we need to add the inherited element to the existing entry.
1687-
// This happens when the element is not a duplicate in its own scope.
1700+
else
16881701
SOME(dup_entry) := opt_dup_entry;
1689-
1690-
// TODO: Change this to an if-statement when compiler bug #4502 is fixed.
1691-
() := match dup_entry.ty
1692-
case DuplicateTree.EntryType.REDECLARE
1693-
algorithm
1694-
// If the existing entry is for a redeclare, then the position of
1695-
// the element doesn't matter and the new entry should be added as
1696-
// a child to the redeclare.
1702+
ty := dup_entry.ty;
1703+
1704+
// Here it's possible for either the new or the old entry to not exist in the duplicate entry.
1705+
// The new might not exist simply because it hasn't been added yet, while the old might not
1706+
// exist because it wasn't a duplicate in its own scope. At least one of them must exist though,
1707+
// since duplicate entries are added for any name occurring more than once.
1708+
if not DuplicateTree.idExistsInEntry(newEntry, dup_entry) then
1709+
if ty == DuplicateTree.EntryType.REDECLARE then
1710+
// If the existing entry is for a redeclare, then the position of the element
1711+
// doesn't matter and the new entry should be added as a child to the redeclare.
1712+
entry := newEntry;
1713+
dup_entry.children := DuplicateTree.newEntry(newEntry) :: dup_entry.children;
1714+
else
1715+
// Otherwise we need to keep the 'first' element as the parent.
1716+
// Note that this only actually works for components, since we don't
1717+
// preserve the order for classes. But which class we choose shouldn't
1718+
// matter since they should be identical. We might also compare e.g. a
1719+
// component to a class here, but that will be caught in checkDuplicates.
1720+
if new_id < old_id then
16971721
entry := newEntry;
1722+
dup_entry := DuplicateTree.Entry.ENTRY(newEntry, NONE(),
1723+
DuplicateTree.newEntry(oldEntry) :: dup_entry.children, dup_entry.ty);
1724+
else
1725+
entry := oldEntry;
16981726
dup_entry.children := DuplicateTree.newEntry(newEntry) :: dup_entry.children;
1699-
then
1700-
();
1727+
end if;
1728+
end if;
1729+
1730+
dups := DuplicateTree.update(dups, name, dup_entry);
1731+
Mutable.update(duplicates, dups);
1732+
elseif not DuplicateTree.idExistsInEntry(oldEntry, dup_entry) then
1733+
// Same as above but we add the old entry instead.
1734+
if ty == DuplicateTree.EntryType.REDECLARE or new_id < old_id then
1735+
entry := newEntry;
1736+
dup_entry.children := DuplicateTree.newEntry(oldEntry) :: dup_entry.children;
17011737
else
1702-
algorithm
1703-
// Otherwise we need to keep the 'first' element as the parent.
1704-
// Note that this only actually works for components, since we don't
1705-
// preserve the order for classes. But which class we choose shouldn't
1706-
// matter since they should be identical. We might also compare e.g. a
1707-
// component to a class here, but that will be caught in checkDuplicates.
1708-
if new_id < old_id then
1709-
entry := newEntry;
1710-
dup_entry := DuplicateTree.Entry.ENTRY(newEntry, NONE(),
1711-
DuplicateTree.newEntry(oldEntry) :: dup_entry.children, dup_entry.ty);
1712-
else
1713-
entry := oldEntry;
1714-
dup_entry.children := DuplicateTree.newEntry(newEntry) :: dup_entry.children;
1715-
end if;
1716-
then
1717-
();
1718-
end match;
1738+
entry := newEntry;
1739+
dup_entry := DuplicateTree.Entry.ENTRY(newEntry, NONE(),
1740+
DuplicateTree.newEntry(oldEntry) :: dup_entry.children, dup_entry.ty);
1741+
end if;
17191742

1720-
dups := DuplicateTree.update(dups, name, dup_entry);
1721-
Mutable.update(duplicates, dups);
1722-
else
1723-
// If an entry does exist in both duplicate tree, then it's already been
1724-
// added by expandExtends and nothing more needs to be done here.
1725-
entry := if new_id < old_id then newEntry else oldEntry;
1743+
dups := DuplicateTree.update(dups, name, dup_entry);
1744+
Mutable.update(duplicates, dups);
1745+
else
1746+
// If both the old and the new entry already exists, which can happen if the
1747+
// new entry was added by expandExtents, then we don't need to add anything.
1748+
entry := if new_id < old_id then newEntry else oldEntry;
1749+
end if;
17261750
end if;
17271751
end addInheritedElementConflict;
17281752

Compiler/NFFrontEnd/NFType.mo

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,6 @@ public
368368
isNumeric := match ty
369369
case REAL() then true;
370370
case INTEGER() then true;
371-
case FUNCTION() then isBasicNumeric(ty.resultType);
372371
else false;
373372
end match;
374373
end isBasicNumeric;

Compiler/NFFrontEnd/NFTypeCheck.mo

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1689,7 +1689,6 @@ algorithm
16891689
if matchKind <> MatchKind.NOT_COMPATIBLE then
16901690
matchKind := MatchKind.PLUG_COMPATIBLE;
16911691
end if;
1692-
16931692
then
16941693
();
16951694

0 commit comments

Comments
 (0)