Skip to content

Commit

Permalink
Check type when redeclaring non-replaceable component (#11701)
Browse files Browse the repository at this point in the history
- Don't allow redeclaration of non-replaceable component when the
  redeclare changes the type of the component.

Fixes #11697
  • Loading branch information
perost committed Dec 8, 2023
1 parent c23055d commit 269ed53
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 13 deletions.
7 changes: 3 additions & 4 deletions OMCompiler/Compiler/FrontEnd/NFSCodeCheck.mo
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ algorithm
SCode.CLASS(prefixes = SCode.PREFIXES()))
algorithm
ty := SCodeDump.restrictionStringPP(res);
ok := checkClassRedeclarationReplaceable(name, ty, repl, inInfo, info);
ok := checkClassRedeclarationReplaceable(name, repl, inInfo, info);
ok := checkRedeclarationFinal(name, ty, fin, inInfo, info) and ok;
//checkRedeclarationVisibility(name, ty, vis1, vis2, inInfo, info);
true := ok;
Expand Down Expand Up @@ -263,7 +263,6 @@ end checkRedeclaredElementPrefix;

protected function checkClassRedeclarationReplaceable
input SCode.Ident inName;
input String inType;
input SCode.Replaceable inReplaceable;
input SourceInfo inOriginInfo;
input SourceInfo inInfo;
Expand All @@ -273,7 +272,7 @@ algorithm
case SCode.NOT_REPLACEABLE() guard not Flags.getConfigBool(Flags.IGNORE_REPLACEABLE)
algorithm
Error.addMultiSourceMessage(Error.REDECLARE_NON_REPLACEABLE,
{inType, inName}, {inOriginInfo, inInfo});
{inName}, {inOriginInfo, inInfo});
then
false;

Expand Down Expand Up @@ -301,7 +300,7 @@ algorithm
case SCode.NOT_REPLACEABLE() guard not Flags.getConfigBool(Flags.IGNORE_REPLACEABLE)
algorithm
Error.addMultiSourceMessage(Error.REDECLARE_NON_REPLACEABLE,
{"component", inName}, {inOriginInfo, inInfo});
{inName}, {inOriginInfo, inInfo});
then
fail();

Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/FrontEnd/NFSCodeLookup.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,7 @@ algorithm
_, SCode.NOT_REPLACEABLE(), _, _)
equation
Error.addSourceMessage(Error.ERROR_FROM_HERE, {}, inInfo);
Error.addSourceMessage(Error.REDECLARE_NON_REPLACEABLE, {"class", name}, info);
Error.addSourceMessage(Error.REDECLARE_NON_REPLACEABLE, {name}, info);
then
fail();

Expand Down
8 changes: 8 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFInst.mo
Original file line number Diff line number Diff line change
Expand Up @@ -2081,6 +2081,14 @@ algorithm
new_comp := match (orig_comp, rdcl_comp)
case (Component.COMPONENT(ty = orig_ty as Type.UNTYPED()), Component.COMPONENT(ty = rdcl_ty as Type.UNTYPED()))
algorithm
if not InstNode.isReplaceable(orig_node) and
not InstContext.inInstanceAPI(context) and
not Type.isEqual(Type.arrayElementType(orig_ty), Type.arrayElementType(rdcl_ty)) then
Error.addMultiSourceMessage(Error.REDECLARE_NON_REPLACEABLE,
{InstNode.name(orig_node)}, {InstNode.info(orig_node), InstNode.info(rdcl_node)});
fail();
end if;

// Take the binding from the outer modifier, the redeclare, or the
// original component, in that order of priority.
binding := Modifier.binding(outerMod);
Expand Down
10 changes: 6 additions & 4 deletions OMCompiler/Compiler/NFFrontEnd/NFInstNode.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1527,11 +1527,13 @@ uniontype InstNode
if referenceEq(n1, n2) then
same := true;
return;
// TODO: This is not enough. We need a better way.
elseif stringEqual(name(n1), name(n2)) then
same := true;
return;
end if;

try
same := referenceEq(definition(node1), definition(node2));
else
same := false;
end try;
end isSame;

function checkIdentical
Expand Down
3 changes: 2 additions & 1 deletion OMCompiler/Compiler/NFFrontEnd/NFType.mo
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ public
elementTy := match ty
case ARRAY() then ty.elementType;
case CONDITIONAL_ARRAY() then arrayElementType(ty.trueType);
case UNTYPED() guard not arrayEmpty(ty.dimensions) then UNTYPED(ty.typeNode, listArray({}));
else ty;
end match;
end arrayElementType;
Expand Down Expand Up @@ -1197,7 +1198,7 @@ public
case (COMPLEX(), COMPLEX()) then InstNode.isSame(ty1.cls, ty2.cls);

case (UNTYPED(), UNTYPED())
then InstNode.refEqual(ty1.typeNode, ty2.typeNode) and
then InstNode.isSame(ty1.typeNode, ty2.typeNode) and
Array.isEqualOnTrue(ty1.dimensions, ty2.dimensions, Dimension.isEqualKnown);

else true;
Expand Down
2 changes: 1 addition & 1 deletion OMCompiler/Compiler/Util/Error.mo
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public constant ErrorTypes.Message LOOKUP_BASECLASS_ERROR = ErrorTypes.MESSAGE(3
public constant ErrorTypes.Message INVALID_REDECLARE_AS = ErrorTypes.MESSAGE(40, ErrorTypes.TRANSLATION(), ErrorTypes.ERROR(),
Gettext.gettext("Invalid redeclaration of %s %s as %s."));
public constant ErrorTypes.Message REDECLARE_NON_REPLACEABLE = ErrorTypes.MESSAGE(41, ErrorTypes.TRANSLATION(), ErrorTypes.ERROR(),
Gettext.gettext("Trying to redeclare %1 %2 but %1 not declared as replaceable."));
Gettext.gettext("Redeclaration with a new type requires '%s' to be replaceable."));
public constant ErrorTypes.Message COMPONENT_INPUT_OUTPUT_MISMATCH = ErrorTypes.MESSAGE(42, ErrorTypes.TRANSLATION(), ErrorTypes.ERROR(),
Gettext.gettext("Component declared as %s when having the variable %s declared as %s."));
public constant ErrorTypes.Message ARRAY_DIMENSION_MISMATCH = ErrorTypes.MESSAGE(43, ErrorTypes.TRANSLATION(), ErrorTypes.ERROR(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ end RedeclareModifierInvalid1;
// Result:
// Error processing file: RedeclareModifierInvalid1.mo
// [flattening/modelica/redeclare/RedeclareModifierInvalid1.mo:16:3-16:40:writable] Notification: From here:
// [flattening/modelica/redeclare/RedeclareModifierInvalid1.mo:11:3-11:9:writable] Error: Trying to redeclare component x but component not declared as replaceable.
// [flattening/modelica/redeclare/RedeclareModifierInvalid1.mo:11:3-11:9:writable] Error: Redeclaration with a new type requires 'x' to be replaceable.
// Error: Error occurred while flattening model RedeclareModifierInvalid1
//
// # Error encountered! Exiting...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ end RedeclareModifierInvalid2;
// Result:
// Error processing file: RedeclareModifierInvalid2.mo
// [flattening/modelica/redeclare/RedeclareModifierInvalid2.mo:15:3-15:37:writable] Notification: From here:
// [flattening/modelica/redeclare/RedeclareModifierInvalid2.mo:10:3-10:18:writable] Error: Trying to redeclare model m2 but model not declared as replaceable.
// [flattening/modelica/redeclare/RedeclareModifierInvalid2.mo:10:3-10:18:writable] Error: Redeclaration with a new type requires 'm2' to be replaceable.
// Error: Error occurred while flattening model RedeclareModifierInvalid2
//
// # Error encountered! Exiting...
Expand Down
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,7 @@ RedeclareMod8.mo \
RedeclareMod9.mo \
RedeclareMod10.mo \
RedeclareMod11.mo \
RedeclareNonReplaceable1.mo \
redeclare10.mo \
redeclare11.mo \
redeclare12.mo \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// name: RedeclareNonReplaceable1
// keywords:
// status: incorrect
// cflags: -d=newInst
//

model A
Real x = 1;
end A;

model B
extends A;
Real y = 3;
end B;

model C
A a;
end C;

model RedeclareNonReplaceable1
extends C(redeclare B a);
end RedeclareNonReplaceable1;

// Result:
// Error processing file: RedeclareNonReplaceable1.mo
// [flattening/modelica/scodeinst/RedeclareNonReplaceable1.mo:21:13-21:26:writable] Error: Redeclaration with a new type requires 'a' to be replaceable.
//
// # Error encountered! Exiting...
// # Please check the error message and the flags.
//
// Execution failed!
// endResult

0 comments on commit 269ed53

Please sign in to comment.