fuzion icon indicating copy to clipboard operation
fuzion copied to clipboard

Actual type parameters not checked sufficiently strictly resulting in crashes

Open fridis opened this issue 1 year ago • 1 comments

This small example defines feature a that receives an argument of type S type : Sequence U, but if U is bool, then S might be Seqence i32:

a(U type,
  S type : Sequence U,
  s S) U => s[0]

say (a bool (Sequence i32) [42])

which causes a crash in DFA:

 > ../clean/fuzion/build/bin/fz test_fun.fz

error 1: java.lang.Error: DFA encountered Unexpected value in match: class dev.flang.fuir.analysis.dfa.NumericValue 'i32:42'  for match of type bool
	at dev.flang.fuir.analysis.dfa.DFA$Analyze.matchSingleSubject(DFA.java:704)
	at dev.flang.fuir.analysis.dfa.DFA$Analyze.match(DFA.java:645)
	at dev.flang.fuir.analysis.dfa.DFA$Analyze.match(DFA.java:99)

A similar example with a function argument

a(U type,
  F type : Function U,
  f F) U => f.call

say (a bool B B)

B : Function (option i32) is
  redef call option i32 => 32

causes an error only during execution

 > ../clean/fuzion/build/bin/fz test_fun2.fz

error 1: java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    fzC_1a_bool_B.fzRoutine()Z @12: putfield
  Reason:
    Type 'fzC_option_i32' (current frame, stack[1]) is not assignable to integer
  Current Frame:
    bci: @12
    flags: { }
    locals: { 'fzC_1a_bool_B' }
    stack: { 'fzC_1a_bool_B', 'fzC_option_i32' }
  Bytecode:
    0000000: bb00 0259 b700 104b 2ab8 0016 b500 182a
    0000010: b400 18ac                              
  Stackmap Table:
    full_frame(@0,{},{})

	at fzC_universe.fzRoutine(--builtin--:5)
	at fzC_universe.fz_run(--builtin--)
	at dev.flang.be.jvm.runtime.FuzionThread.lambda$new$1(FuzionThread.java:104)
	at dev.flang.util.Errors.runAndExit(Errors.java:895)
	at dev.flang.be.jvm.runtime.FuzionThread.lambda$new$2(FuzionThread.java:116)
	at java.base/java.lang.Thread.run(Thread.java:1583)


*** fatal errors encountered, stopping.
one error.

fridis avatar Sep 11 '24 17:09 fridis

the following patch does not seem to suffice:

diff --git a/src/dev/flang/ast/Call.java b/src/dev/flang/ast/Call.java
index 16496b9a6..97af04ff5 100644
--- a/src/dev/flang/ast/Call.java
+++ b/src/dev/flang/ast/Call.java
@@ -1341,6 +1341,19 @@ public class Call extends AbstractCall
                 Generic g = frmlT.genericArgument();
                 var frmlTs = g.replaceOpen(g.feature() == _calledFeature
                                            ? _generics
+                                           /* example where this applies:
+                                            *
+                                            *      a(U type,
+                                            *        F type : Function U,
+                                            *        f F) U => f.call
+                                            *
+                                            *      say (a bool B B)
+                                            *
+                                            *      B : Function (option i32) is
+                                            *        redef call option i32 => 32
+                                            */
+                                           : _target.type().isGenericArgument()
+                                           ? _target.type().genericArgument().constraint(context).generics()
                                            : _target.type().generics());
                 addToResolvedFormalArgumentTypes(res, argnum + i, frmlTs.toArray(new AbstractType[frmlTs.size()]), frml);
                 i   = i   + frmlTs.size() - 1;

michaellilltokiwa avatar Sep 24 '24 08:09 michaellilltokiwa