From cf1ee60d72ed497da17665c97f8c8aa5e2dd5084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Thu, 17 Aug 2023 11:37:01 +0200 Subject: [PATCH] Improve handling of enumeration(:) (#11056) - Fix redeclaration of `enumeration(:)` when the redeclaring type is a derived type. - Add check that there are no components with type `enumeration(:)` in the model. Fixes #11053 --- .CI/compliance.failures | 1 - OMCompiler/Compiler/NFFrontEnd/NFClass.mo | 17 ++++++++++++ OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo | 17 ++++++++++++ OMCompiler/Compiler/NFFrontEnd/NFInst.mo | 14 ++++++++++ OMCompiler/Compiler/Util/Error.mo | 2 ++ .../modelica/scodeinst/EnumUnspecified1.mo | 20 ++++++++++++++ .../flattening/modelica/scodeinst/Makefile | 3 +++ .../modelica/scodeinst/RedeclareEnum5.mo | 23 ++++++++++++++++ .../modelica/scodeinst/RedeclareEnum6.mo | 27 +++++++++++++++++++ 9 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 testsuite/flattening/modelica/scodeinst/EnumUnspecified1.mo create mode 100644 testsuite/flattening/modelica/scodeinst/RedeclareEnum5.mo create mode 100644 testsuite/flattening/modelica/scodeinst/RedeclareEnum6.mo diff --git a/.CI/compliance.failures b/.CI/compliance.failures index bf1cc1258f0..8548c147d1c 100644 --- a/.CI/compliance.failures +++ b/.CI/compliance.failures @@ -3,7 +3,6 @@ ModelicaCompliance.Algorithms.For.ShadowedIterator ModelicaCompliance.Algorithms.For.StringRange ModelicaCompliance.Arrays.Functions.Conversion.DimConversionMatrix ModelicaCompliance.Classes.Declarations.Long.QuotedIdentifiers.?abfnrtv -ModelicaCompliance.Classes.Enumeration.EnumUnspecified ModelicaCompliance.Classes.Predefined.AttributeStateSelectInvalidAlways ModelicaCompliance.Classes.Predefined.AttributeStateSelectInvalidNever ModelicaCompliance.Classes.Predefined.ReservedBooleanComp diff --git a/OMCompiler/Compiler/NFFrontEnd/NFClass.mo b/OMCompiler/Compiler/NFFrontEnd/NFClass.mo index bae48a2b53f..03f773d8a76 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFClass.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFClass.mo @@ -710,6 +710,18 @@ constant Prefixes DEFAULT_PREFIXES = Prefixes.PREFIXES( input output Class cls; algorithm () := match cls + case PARTIAL_CLASS() + algorithm + cls.prefixes := prefs; + then + (); + + case PARTIAL_BUILTIN() + algorithm + cls.prefixes := prefs; + then + (); + case EXPANDED_CLASS() algorithm cls.prefixes := prefs; @@ -722,6 +734,11 @@ constant Prefixes DEFAULT_PREFIXES = Prefixes.PREFIXES( then (); + case INSTANCED_CLASS() + algorithm + cls.prefixes := prefs; + then + (); end match; end setPrefixes; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo b/OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo index 66cd95dd4e4..66cd47d89b4 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFFlatten.mo @@ -617,6 +617,7 @@ protected Prefix pre; algorithm Component.COMPONENT(ty = ty, binding = binding, attributes = comp_attr, comment = cmt, info = info) := comp; + checkUnspecifiedEnumType(ty, node, info); var := comp_attr.variability; if isSome(outerBinding) then @@ -667,6 +668,22 @@ algorithm vars := Variable.VARIABLE(name, ty, binding, visibility, comp_attr, ty_attrs, children, cmt, info, NFBackendExtension.DUMMY_BACKEND_INFO) :: vars; end flattenSimpleComponent; +function checkUnspecifiedEnumType + input Type ty; + input InstNode node; + input SourceInfo info; +algorithm + () := match ty + case Type.ENUMERATION(literals = {}) + algorithm + Error.addSourceMessage(Error.UNSPECIFIED_ENUM_COMPONENT, {InstNode.name(node)}, info); + then + fail(); + + else (); + end match; +end checkUnspecifiedEnumType; + function flattenTypeAttribute input Modifier attr; input Prefix prefix; diff --git a/OMCompiler/Compiler/NFFrontEnd/NFInst.mo b/OMCompiler/Compiler/NFFrontEnd/NFInst.mo index 5f4ec1a8186..0a44fbc2d88 100644 --- a/OMCompiler/Compiler/NFFrontEnd/NFInst.mo +++ b/OMCompiler/Compiler/NFFrontEnd/NFInst.mo @@ -1664,10 +1664,24 @@ function redeclareEnum input InstNode originalNode; output Class redeclaredClass = redeclareClass; algorithm + // Expand the redeclare node so we can check whether it's an enumeration or not. + expand(redeclareNode); + redeclaredClass := InstNode.getClass(redeclareNode); + redeclaredClass := match (redeclaredClass, originalClass) local list lits1, lits2; + // Redeclare enumeration(:). + case (_, Class.PARTIAL_BUILTIN(ty = Type.ENUMERATION(literals = {}))) + guard InstNode.isEnumerationType(redeclareNode) + algorithm + redeclaredClass := Class.setPrefixes(prefixes, redeclaredClass); + redeclaredClass := Class.mergeModifier(outerMod, redeclaredClass); + then + redeclaredClass; + + // Redeclare normal enumeration. case (Class.PARTIAL_BUILTIN(ty = Type.ENUMERATION(literals = lits1)), Class.PARTIAL_BUILTIN(ty = Type.ENUMERATION(literals = lits2))) algorithm diff --git a/OMCompiler/Compiler/Util/Error.mo b/OMCompiler/Compiler/Util/Error.mo index 6fb22c3b1f1..e2eda64a71e 100644 --- a/OMCompiler/Compiler/Util/Error.mo +++ b/OMCompiler/Compiler/Util/Error.mo @@ -887,6 +887,8 @@ public constant ErrorTypes.Message PARTIAL_DERIVATIVE_INPUT_INVALID_TYPE = Error Gettext.gettext("'%s' in partial derivative of '%s' is not a scalar Real input parameter of the function.")); public constant ErrorTypes.Message CONNECT_TYPE_MISMATCH = ErrorTypes.MESSAGE(406, ErrorTypes.TRANSLATION(), ErrorTypes.ERROR(), Gettext.gettext("The connectors in connect(%s, %s) are not type compatible.")); +public constant ErrorTypes.Message UNSPECIFIED_ENUM_COMPONENT = ErrorTypes.MESSAGE(407, ErrorTypes.TRANSLATION(), ErrorTypes.ERROR(), + Gettext.gettext("Component '%s' has an unspecified enumeration type (enumeration(:)).")); public constant ErrorTypes.Message INITIALIZATION_NOT_FULLY_SPECIFIED = ErrorTypes.MESSAGE(496, ErrorTypes.TRANSLATION(), ErrorTypes.WARNING(), Gettext.gettext("The initial conditions are not fully specified. %s.")); diff --git a/testsuite/flattening/modelica/scodeinst/EnumUnspecified1.mo b/testsuite/flattening/modelica/scodeinst/EnumUnspecified1.mo new file mode 100644 index 00000000000..cc906735114 --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/EnumUnspecified1.mo @@ -0,0 +1,20 @@ +// name: EnumUnspecified1 +// keywords: +// status: incorrect +// cflags: -d=newInst +// + +model EnumUnspecified1 + replaceable type E = enumeration(:); + E e; +end EnumUnspecified1; + +// Result: +// Error processing file: EnumUnspecified1.mo +// [flattening/modelica/scodeinst/EnumUnspecified1.mo:9:3-9:6:writable] Error: Component 'e' has an unspecified enumeration type (enumeration(:)). +// +// # Error encountered! Exiting... +// # Please check the error message and the flags. +// +// Execution failed! +// endResult diff --git a/testsuite/flattening/modelica/scodeinst/Makefile b/testsuite/flattening/modelica/scodeinst/Makefile index 2a85b1fb467..758055d79ba 100644 --- a/testsuite/flattening/modelica/scodeinst/Makefile +++ b/testsuite/flattening/modelica/scodeinst/Makefile @@ -407,6 +407,7 @@ EnumConversion1.mo \ EnumConversion2.mo \ EnumInvalidLiteralName1.mo \ EnumRangeBinding1.mo \ +EnumUnspecified1.mo \ eq1.mo \ eq2.mo \ eq3.mo \ @@ -996,6 +997,8 @@ RedeclareEnum1.mo \ RedeclareEnum2.mo \ RedeclareEnum3.mo \ RedeclareEnum4.mo \ +RedeclareEnum5.mo \ +RedeclareEnum6.mo \ RedeclareFunction1.mo \ RedeclareInvalidConnectorType1.mo \ RedeclareInvalidVariability1.mo \ diff --git a/testsuite/flattening/modelica/scodeinst/RedeclareEnum5.mo b/testsuite/flattening/modelica/scodeinst/RedeclareEnum5.mo new file mode 100644 index 00000000000..4157d125f7f --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/RedeclareEnum5.mo @@ -0,0 +1,23 @@ +// name: RedeclareEnum5 +// keywords: +// status: correct +// cflags: -d=newInst +// + +model A + replaceable type E = enumeration(:); + E e; +end A; + +model RedeclareEnum5 + extends A(redeclare type E = E3); + type E2 = enumeration(a, b, c); + type E3 = E2; +end RedeclareEnum5; + + +// Result: +// class RedeclareEnum5 +// enumeration(a, b, c) e; +// end RedeclareEnum5; +// endResult diff --git a/testsuite/flattening/modelica/scodeinst/RedeclareEnum6.mo b/testsuite/flattening/modelica/scodeinst/RedeclareEnum6.mo new file mode 100644 index 00000000000..809fd9f4ffb --- /dev/null +++ b/testsuite/flattening/modelica/scodeinst/RedeclareEnum6.mo @@ -0,0 +1,27 @@ +// name: RedeclareEnum6 +// keywords: +// status: incorrect +// cflags: -d=newInst +// + +model A + replaceable type E = enumeration(:); + E e; +end A; + +model RedeclareEnum6 + extends A(redeclare type E = E2); + type E2 = Real; +end RedeclareEnum6; + + +// Result: +// Error processing file: RedeclareEnum6.mo +// [flattening/modelica/scodeinst/RedeclareEnum6.mo:13:23-13:34:writable] Notification: From here: +// [flattening/modelica/scodeinst/RedeclareEnum6.mo:8:15-8:38:writable] Error: Redeclaration of enumeration 'E' is not a subtype of the redeclared element. +// +// # Error encountered! Exiting... +// # Please check the error message and the flags. +// +// Execution failed! +// endResult