Skip to content

Commit

Permalink
Fix a bug causing generic variables used in a coforall to crash com…
Browse files Browse the repository at this point in the history
…pilation (chapel-lang#24301)

Resolves chapel-lang#21272.

Fix a bug that caused a generic class variable mentioned in a `coforall`
to crash the program with an internal assertion.

Remove the internal assertion. It asserts that actuals passed to a task
function are not generic, but it is possible for this to be the case if
we are already in an error state. In that case, we should continue to
the end of the pass rather than crash.

While here, adjust the class section of the spec to indicate that for a
class type `C`, the expression `C` is taken to mean generic management
except in the `new` expression, where it implies `owned C`.

TESTING

- [x] `linux64`, `standard`

Reviewed by @vasslitvinov. Thanks!
  • Loading branch information
dlongnecke-cray authored Jan 31, 2024
2 parents e5b0bdd + a1c5ba8 commit 52ae31c
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 4 deletions.
6 changes: 5 additions & 1 deletion compiler/resolution/functionResolution.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7201,7 +7201,11 @@ static void handleTaskIntentArgs(CallInfo& info, FnSymbol* taskFn) {

// If 'call' is in a generic function, it will have been instantiated by
// now. Otherwise our task function has to remain generic.
INT_ASSERT(varActual->type->symbol->hasFlag(FLAG_GENERIC) == false);
//
// ---> It's possible for this assert to fire if the caller is generic
// and we are already in an error state. Remove it for now so that we
// can make progress.
// INT_ASSERT(varActual->type->symbol->hasFlag(FLAG_GENERIC) == false);

if (formal->id == breakOnResolveID)
gdbShouldBreakHere();
Expand Down
7 changes: 4 additions & 3 deletions doc/rst/language/spec/classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,10 @@ specified, may appear in the inheritance lists of other class
declarations.

If a class type's memory management strategy is unspecified, it will be
generic. (This is not the case for instances of classes. When a new class
instance is created with an unspecified memory management strategy it
will default to ``owned``.)
generic. (This is not the case for class instances created using the
``new`` expression (see :ref:`Class_New`). When a ``new`` expression
does not specify a memory management strategy, then the management will
default to ``owned``.)

Variables of class type cannot store ``nil`` unless the class type is
nilable (:ref:`Nilable_Classes`).
Expand Down
15 changes: 15 additions & 0 deletions test/statements/loops/CoforallDefaultInitBug.chpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class MyClass {
proc func() {
return 2 + 2;
}
}

// Split-init error should fire at this point. It would be nice if the error
// would mention a note about the use within the `coforall`, but that isn't
// necessary - and would require modification to map `m` to temporaries
// introduced for the `coforall` block function.
var m: MyClass;

coforall idx in 0..3 {
m.func();
}
3 changes: 3 additions & 0 deletions test/statements/loops/CoforallDefaultInitBug.good
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CoforallDefaultInitBug.chpl:13: error: cannot default-initialize a variable with generic type
CoforallDefaultInitBug.chpl:13: note: 'm' has generic type 'MyClass'
CoforallDefaultInitBug.chpl:13: note: cannot find initialization point to split-init this variable

0 comments on commit 52ae31c

Please sign in to comment.