bugGNU Octave - Bugs: bug #67714, Add vecdim, nanflag, and direction...

 
 

bug #67714: Add vecdim, nanflag, and direction support to core Octave functions

Submitter:  Andreas Bertsatos <pr0m1th3as>
Submitted:  Mon 17 Nov 2025 07:23:33 PM UTC
   
 
Category:  Octave Function Severity:  5 - Blocker
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Ready For Test Assigned to:  None
Originator Name:  Open/Closed:  * Open
Release:  * dev Operating System:  * GNU/Linux
Fixed Release:  None Planned Release:  11.1.0 (current default)
* Mandatory Fields

Post a Comment

Add a New Comment Rich Markup
   

Discussion

Jump to the original submission

Wed 10 Dec 2025 02:58:16 PM UTC, comment #48: 

I was going to ask if this patch could be split into two, one for only the vecdim/nanflag/all additions, and the other for only the rms additions. But looking through bug #67724, it looks like the feedback there was for you to combine the work since you were going to be editing the statistics functions anyway for this bug 67714.

This leads to the slightly awkward situation of the same changeset addressing two different bugs, which are related but could be addressed independently as two patches applied one after the other. (In other words, it was possible to add vecdim support without requiring the new rms function, so the vecdim support patch could have gone first and the rms addition followed right behind making use of vecdim.)

Since you've already done the main work I won't ask you to redo it, but for future reference it's always OK to submit a set of related patches instead of one all-encompassing patch.

For this patch, I've edited the commit message to make the two bug reports look more like a single combined whole.

Pushed to default.

Marking as ready for test.

Arun Giridhar <arungiridhar>
Group Member
Wed 10 Dec 2025 12:48:42 PM UTC, comment #47: 

This patch [bug67714_m_functions.patch] adds *nanflag* and *vecdim* support (and a few other minor things) for all remaining statistics functions. It also adds the *rms* function to core.

Once merged, this bug report and its #67724 sibling cane be closed. And we should keep in mind to exclude *rms* from the signal package for Octave 11.

(file #57942)

Andreas Bertsatos <pr0m1th3as>
Group Member
Thu 04 Dec 2025 03:13:03 PM UTC, comment #46: 

Tagging #50571 here as a duplicate.

Tagging #67724 here as relevant.

I will include rms in the forthcoming patch for core statistics functions.

Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 02 Dec 2025 05:37:00 PM UTC, comment #45: 

Yes, extra output argument. Not sure how many things that would break.

Also for extra bit of performance you can use `x == x` for `!isnan` (I guess it is 1 OP vs 2 OPs, I see ~30% speedup),
but still `isnan` rather than `x != x`

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Tue 02 Dec 2025 04:50:28 PM UTC, comment #44: 

Return nan counts as in a second output argument, you mean?

Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 02 Dec 2025 03:23:51 PM UTC, comment #43: 

The cset
(file bug67714_allnan_3.cset)

with fixed documentation strings is attached.

I also filled a separate bug report about sum(x) performance
(or lack thereof) with logical arrays

https://savannah. ... u.org/bugs/?67762

Dmitri.
--


(file #57905)

Dmitri A. Sergatskov <dasergatskov>
Tue 02 Dec 2025 01:33:30 PM UTC, comment #42: 

It is not that "isnan" slow (though it could be faster), it is sum() over `logical` array that is slow.

octave:18> x = rand(1e4);
octave:19> tic; bx = (! isnan(x)); toc
Elapsed time is 0.105592 seconds.
octave:20> tic; cx = (x == x); toc
Elapsed time is 0.0795498 seconds.
octave:21> tic; sum (x); toc
Elapsed time is 0.074883 seconds.
octave:22> tic; sum (bx); toc
Elapsed time is 0.536367 seconds.
octave:23>


If I add logical specialization to `sum` I see:
```
octave:1> x = rand(1e4);
octave:2> tic; bx = (! isnan(x)); toc
Elapsed time is 0.10775 seconds.
octave:3> tic; sum (x); toc
Elapsed time is 0.0748441 seconds.
octave:4> tic; sum (bx); toc
Elapsed time is 0.073128 seconds.
```
Here is this factor 7.8...

The diff (to sum() in data.cc) is
```
@@ -4207,7 +4222,11 @@
       else if (isnative)
         retval = arg.bool_array_value ().any (dim);
       else
-        retval = arg.array_value ().sum (dim);
+        {
+          // OPTIMIZED: Fast boolean sum without conversion to double array
+          boolNDArray m = arg.bool_array_value ();
+          retval = do_mx_red_op<double, bool> (m, dim, mx_inline_count);
+        }
       break;
-verbatim-

Another optimization to concider is if the functions can return NaN counts. Not sure if we can do to all the functions, but should be able to `sumsq` since it is Octave's own.

I will fix doc in cset soon.

Dmitri.
--
 

Dmitri A. Sergatskov <dasergatskov>
Tue 02 Dec 2025 10:04:21 AM UTC, comment #41: 

And for prod it should be 1.

Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 02 Dec 2025 10:03:15 AM UTC, comment #40: 

After a second though, I think we can't avoid the sum (! isnan (x)) part in meansq for "omitnan", so it won't make much difference. The result would be the same, instead of NaN/0, now we'll get 0/0.

Before merging, please modify the last paragraph of the help docstring in prod, sum, and sumsq functions. The last sentence

   To exclude NaN values set the value of NANFLAG to "omitnan".  The
     output will still contain NaN values if X consists of all NaN
     values in the operating dimension.

should be

   To exclude NaN values set the value of NANFLAG to "omitnan".  The
     output will be 0, if X consists of all NaN
     values in the operating dimension.


Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 02 Dec 2025 09:55:37 AM UTC, comment #39: 

This happens because meansq still handles nanflag internally due to the previous issue with processing time, which has been resolved.

Since nanflag has been integrated into liboctave, it is much more efficient to pass the nanflag into the compiled core functions. The other issue with the suggested change, is that we will have to handle nanflag inside rms, mape, and rmse functions eventually.

According to Rik's tests, https://savannah. ... u.org/bugs/?67724, there is a 7.8X performance penalty calling isnan. We could just avoid this overhead by implementing sumsq in a convenient way for the functions that are using it the most.

meansq, rms, mape, and rmse are very basic functions in statistics and I would guess for signal too. I prefer efficiency over mathematical verbosity.

Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 02 Dec 2025 07:26:03 AM UTC, comment #38: 

Currently (with cset applied):

octave:13> A = [NaN; NaN; NaN]
A =

   NaN
   NaN
   NaN

octave:14> meansq(A,"omitnan")
ans = NaN
octave:15> sumsq(A,"omitnan")
ans = 0

and this is expected behavior IMO.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Tue 02 Dec 2025 07:21:49 AM UTC, comment #37: 

The `mean*` functions are diffrent because for things like
A = [NaN; NaN; NaN] with "omitnan" flag is equivalent of
sum([])/0 and this is NaN.

So far everything looks self-consistent to me.
 
Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Tue 02 Dec 2025 07:15:06 AM UTC, comment #36: 

I disagree.
`sumsq(A, "omitnan")` should be the same as sum(A.^2, "omitnan").
Currently it tracks (with cset applied):

octave:7> A = [NaN; NaN; NaN]
A =

   NaN
   NaN
   NaN

octave:8> B=A.^2
B =

   NaN
   NaN
   NaN

octave:9> sum(B,"omitnan")
ans = 0
octave:10> sumsq(A,"omitnan")
ans = 0


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Tue 02 Dec 2025 07:10:48 AM UTC, comment #35: 

My only objection with Dmitri's cset is that sumsq should be treated differently from sum and prod.
First of all, it breaks meansq and rms, which they rely upon. It will also affect mape and rmse (not there yet but work in progress).

A good argument made by Dmitri (in personal communication) is that

octave:75> sum([])
ans = 0
octave:76> prod([])
ans = 1

which makes it consistent to sum or prod all NaNs into 0 or 1 respectively.

However

octave:77> [].^2
ans = [](0x0)

which implies that sumsq should not follow their pattern and it should be consistent with meansq, mean, meadian, and other functions that share this behavior when omitting NaNs.

Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 02 Dec 2025 04:51:39 AM UTC, comment #34: 


octave:1> A = [1, NaN; 2, NaN; 3, NaN];
octave:2> sumsq(A, 2, 'omitnan')
ans =

   NaN
   NaN
   NaN

octave:3> sum(A, 2, 'omitnan')
ans =

   NaN
   NaN
   NaN

octave:4> prod(A, 2, 'omitnan')
ans =

   NaN
   NaN
   NaN

octave:5> B = [NaN, NaN, NaN];
octave:6> sum(B, "omitnan")
ans = NaN
octave:7> prod(B, "omitnan")
ans = NaN
octave:8> sum(B, "omitnan")
ans = NaN
octave:9> ver
----------------------------------------------------------------------
GNU Octave Version: 11.0.0 (hg id: 8364bb87255e)


Those are all wrong.
The (file cp bug67714_allnan_2.cset) fixes that for me.
(I have also removed some tests that assume incorrect behavior.)

Dmitri.
--



(file #57893)

Dmitri A. Sergatskov <dasergatskov>
Mon 01 Dec 2025 12:58:46 PM UTC, comment #33: 

The aforementioned regressions have been fixed with [bug67714_v3.patch] and further work on fixing broadcasting of sparse arrays has been applied with [bug67714_v4_extra.patch].

I am attaching the patches here for historical purposes.

There are still another 12 functions in /scripts/statistics/ that need updates and I am currently working on. Let's keep this open until these are fixed as well.

(file #57889, file #57890)

Andreas Bertsatos <pr0m1th3as>
Group Member
Fri 28 Nov 2025 07:08:48 PM UTC, comment #32: 

Raising severity to Blocker because this change is causing a regression with min() and max(), as Dmitri found here: https://octave.di ... -dec-1st/7069/118

In short, max (0, zeros (0, 1)) used to return an empty array before this change but returns 0 after the change.

Arun Giridhar <arungiridhar>
Group Member
Thu 27 Nov 2025 06:52:15 AM UTC, comment #31: 

Here is the list of remaining core Octave functions that still lack support for vecdim and nanflag options.

  • bounds
  • center
  • iqr
  • kurtosis
  • meansq (needs update to pass all arguments to compiled sumsq)
  • mode
  • moment
  • prctile
  • range
  • skewness
  • statistics


And there is also rms which should be ported from the signal package. Relevant bug #67724

Andreas Bertsatos <pr0m1th3as>
Group Member
Thu 27 Nov 2025 04:16:49 AM UTC, comment #30: 

Also fine on MMacOS / Homebrew with Apple's clang.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Thu 27 Nov 2025 04:02:38 AM UTC, comment #29: 

I changed all instances of former abs (replaced by mapper_abs) to std::abs everywhere expect for the intNDArray path. I also replaced it in the mapper_abs function to avoid the warning about possible truncation that Arun posted on the bug tracker.

I made new paths for min/max and cummin/cummax in mx_inlines.cc that only take a bool realabs argument, so that we can work faster on integers when going through the reduction operations. For binary operations, I didn’t make any changes, because it would require a lot of boilerplate code without any significant gain (the nanflag argument is unused anyway). An also it would require changes in a lot of files.

The current patch compiles without any issues on Debian with gcc and passes make check. It applies cleanly on latest dev.

(file #57872)

Andreas Bertsatos <pr0m1th3as>
Group Member
Wed 26 Nov 2025 08:52:09 PM UTC, comment #28: 

With Clang on Linux, these are the only remaining warnings related to this change. Pls check if MacOS builds these:


../liboctave/numeric/mappers.h:56:16: warning: absolute value function 'abs' given an argument of type 'long' but has parameter of type 'int' which may cause truncation of value [-Wabsolute-value]
   56 |         return abs(x.value());
      |                ^
../liboctave/operators/mx-inlines.cc:1497:1: note: in instantiation of function template specialization 'mappers_abs<long>' requested here
 1497 | OP_MINMAX_FCN (mx_inline_max, >)
      | ^
../liboctave/operators/mx-inlines.cc:1431:17: note: expanded from macro 'OP_MINMAX_FCN'
 1431 |             if (mappers_abs (v[i]) OP mappers_abs (tmp))                \
      |                 ^
../liboctave/operators/mx-inlines.cc:1756:17: note: in instantiation of function template specialization 'mx_inline_max<octave_int<long>>' requested here
 1756 | OP_MINMAX_FCNN (mx_inline_max)
      |                 ^
../liboctave/array/intNDArray.cc:266:60: note: in instantiation of function template specialization 'mx_inline_max<octave_int<long>>' requested here
  266 |   return do_mx_minmax_op<T> (*this, dim, nanflag, realabs, mx_inline_max);
      |                                                            ^
../liboctave/numeric/mappers.h:56:16: note: use function 'std::abs' instead
   56 |         return abs(x.value());
      |                ^~~
      |                std::abs


Arun Giridhar <arungiridhar>
Group Member
Wed 26 Nov 2025 08:41:00 PM UTC, comment #27: 

I've pushed abs_2.diff under your name. Pls check if it builds on MacOS.

Arun Giridhar <arungiridhar>
Group Member
Wed 26 Nov 2025 08:34:23 PM UTC, comment #26: 

Here is a tweaked diff that uses mappers_abs instead of mx_inline_abs. It builds for me with very few warnings and passes "make check".



(file #57871)

Arun Giridhar <arungiridhar>
Group Member
Wed 26 Nov 2025 08:07:43 PM UTC, comment #25: 

Your fix makes sense but what is the difference between mx_inline_abs and mappers_abs? Can we directly call mappers_abs where the patch is currently calling mx_inline_abs?

Arun Giridhar <arungiridhar>
Group Member
Wed 26 Nov 2025 07:59:30 PM UTC, comment #24: 

It will not compile on MacOS. I kind-of fixed it by making:

diff -r b8e49cf05ba5 liboctave/numeric/mappers.h
--- a/liboctave/numeric/mappers.h       Wed Nov 26 13:03:26 2025 -0500
+++ b/liboctave/numeric/mappers.h       Wed Nov 26 14:52:44 2025 -0500
@@ -36,6 +36,27 @@
 #include "oct-cmplx.h"
 #include "oct-inttypes-fwd.h"

+// Provides some commonly repeated, basic loop templates.
+
+template <typename T>
+inline auto mappers_abs (const T& x)
+{
+    if constexpr (std::is_unsigned_v<T>)
+        return x;  // abs doesn't make sense for unsigned types
+    else
+        return std::abs(x);
+}
+// Specialization for octave_int types
+template <typename T>
+inline auto mappers_abs (const octave_int<T>& x)
+{
+    if constexpr (std::is_unsigned_v<T>)
+        return x;  // abs doesn't make sense for unsigned types
+    else
+        return abs(x.value());
+}
+
+
...

and then replacing all cals to abs() with mappers_abs().

And similarly in mx-inlines.cc (except the function call there is mx_inline_abs). The complete diff is attached.

(file abs_1.diff)

Dmitri.
--


(file #57870)

Dmitri A. Sergatskov <dasergatskov>
Wed 26 Nov 2025 06:15:06 PM UTC, comment #23: 

I've pushed bug67714.patch from comment #22 and one further fix from me to reduce the number of Clang warnings about std::abs().

We should expect some more warnings from CI along similar lines.

Arun Giridhar <arungiridhar>
Group Member
Wed 26 Nov 2025 01:16:52 PM UTC, comment #22: 

I just made a new patch [bug67714.patch], as a replacement for the [38085.patch], which cleanly applies to the current tip and in addition to implementing support for 'nanflag' and "ComparisonMethod" to the min, max, cummin, and cummax functions, it further fixes the performance issue of the previous patch for 'nanflag' support.

Building and testing locally:

Octave successfully built.  Now choose from the following:

   ./run-octave    - to run in place to test before installing
   make check      - to run the tests
   make install    - to install (PREFIX=/usr/local)

   HG ID for this build is "bd09a5c439c7+"


Summary:

  PASS                            20374
  FAIL                                0
  XFAIL (reported bug)               36
  SKIP (missing feature)            109
  SKIP (run-time condition)          29


The increase performance has been discussed on discourse and the relevant post can be found here https://octave.di ... 9/69?u=pr0m1th3as

Once applied, this latest patch will facilitate the simplification of the code in m functions in core statistics, since we don't need a separate path for 'nanflag' (it is now more efficient to pass it along to the core functions). See relevant discussion in https://savannah. ... u.org/bugs/?67724

This patch also addresses issues discussed in the following bug reports:
https://savannah. ... u.org/bugs/?50007
https://savannah. ... u.org/bugs/?50571

(file #57869)

Andreas Bertsatos <pr0m1th3as>
Group Member
Mon 24 Nov 2025 10:55:52 PM UTC, comment #21: 

For reference purposes, I upload here the next consecutive patch regarding vecdim, nanflag, and direction optional arguments in core Octave functions. This one [35058.patch] concerns min, max, cummin, and cummax functions.

(file #57860)

Andreas Bertsatos <pr0m1th3as>
Group Member
Thu 20 Nov 2025 06:01:53 PM UTC, comment #20: 

In the same C++17 spirit:


diff -r 4ef9c0698287 libinterp/corefcn/data.cc
--- a/libinterp/corefcn/data.cc Thu Nov 20 09:40:07 2025 +0100
+++ b/libinterp/corefcn/data.cc Thu Nov 20 12:57:17 2025 -0500
@@ -133,13 +133,7 @@
           // Add remaining dims to permutation vector
           for (int i = 0; i < ndims; i++)
             {
-              bool is_rem = true;
-              for (int j = 0; j < n; j++)
-                {
-                  if (vecdim[j] == i)
-                    is_rem = false;
-                }
-              if (is_rem)
+              if (std::find (vecdim.begin (), vecdim.end (), i) == vecdim.end ())
                 {
                   perm_vec(idx) = i;
                   new_sz(idx) = sz(i);


looks cleaner to me.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Thu 20 Nov 2025 04:11:47 PM UTC, comment #19: 

I'm a litte bit out of my depth with understanding autotools magic, but I believe that the configure script sets OCTAVE_IDX_TYPE to be either an int32_t or int64_t depending on if the system is 32 or 64 bit, respectively. That macro correspondingly sets `octave_idx_type`:


typedef OCTAVE_IDX_TYPE octave_idx_type;


So octave_idx_type would be an signed int either way.

Thomas <kolmanthomas>
Thu 20 Nov 2025 04:11:09 PM UTC, comment #18: 

I run with UBSAN and it does not complain. I think one may get compiler warning with `-Wconversion`.

IMHO it is even more stylistic than `static void` thing, and I think we can live it "as-is" for now.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Thu 20 Nov 2025 03:51:14 PM UTC, comment #17: 

"static" should be unnecessary for get_dim_vecdim_all() as the compiler will do the correct thing, but I also think that Dmitri is correct that it helps the programmer understand that this is a local function and not a library function.  And, Octave has chosen to be explicit about this in the rest of the code base so we should do that here as well.  I'll make that change, but won't commit it just yet because there may be further code cleanups.

As I was reviewing the changeset I realized that the entire Octave code base is a little casual about whether a dimension is of type "int" or of type "octave_idx_type".  Technically, it's true that a dimension should be of "octave_idx_type".  Here is the class member definition in liboctave/array/dim-vector.h.

class OCTAVE_API dim_vector
{
private:

  octave_idx_type m_num_dims;

  octave_idx_type *m_dims;

But, in practice, probably 99.99% of matrices used in Octave have dimensions less than or equal to 5.  The difference just isn't important.  This is such a large issue that if we want to be consistent this should be a code re-factoring exercise that starts at the beginning of the Octave 12 release cycle so there is plenty of time to get it right.

The C++ size_type is typically an alias for size_t which itself is typically unsigned int.  So, the code does assign an unsigned int to an int which would generally trigger a warning.  Has anyone run this code through lint yet?

Rik <rik5>
Group administrator
Thu 20 Nov 2025 03:33:06 PM UTC, comment #16: 

Yes I suppose it is safer to mark it `static`, I spoke too soon then.

Thomas <kolmanthomas>
Thu 20 Nov 2025 03:23:02 PM UTC, comment #15: 

Using `octave_idx_type` probably best, but it is def more involved change.

Making "get_dim_vecdim_all "  "static void" would prevent exporting this symbol by the resulting library, wouldn't it?
At least this would be an explicit sign that this is an internal function, this this typical usage in Octave sources.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Thu 20 Nov 2025 03:15:31 PM UTC, comment #14: 

`get_dim_vecdim_all` shouldn't be marked inline, it doesn't do anything in a .cpp file AFAIK. Marking it as static shouldn't matter if there's no corresponding function signature in the header file.

But I believe indices should be typed as `octave_idx_type`, which could be either an int or a long int. Thankfully, `octave_idx_type` is a signed int, so no problems with integer underflow. So IMO instead of casting everything to an int, the method `octave_idx_type_vector_value()` should be used instead to get an Array<octave_idx_type>. I'll upload a patch shortly with some modifications.

Thomas <kolmanthomas>
Thu 20 Nov 2025 01:55:20 PM UTC, comment #13: 

Prompted by Rik's diff "4ef9c0698287"

Should not "get_dim_vecdim_all " be "static void" ?

Should "int n = vecdim.size ()" be "int n = static_cast<int>(vecdim.size ());" (possible problem of signed vs unsigned int)?


diff -r 4ef9c0698287 libinterp/corefcn/data.cc
--- a/libinterp/corefcn/data.cc Thu Nov 20 09:40:07 2025 +0100
+++ b/libinterp/corefcn/data.cc Thu Nov 20 08:49:36 2025 -0500
@@ -68,7 +68,7 @@

 OCTAVE_BEGIN_NAMESPACE(octave)

-void
+static void
 get_dim_vecdim_all (const octave_value& dimarg, octave_value& arg,
                     int& dim, Array<int>& perm_vec, bool& do_perm,
                     bool& allflag, const char *fcn)
@@ -94,7 +94,7 @@
           if (vec(i) < ndims)
             vecdim.push_back (vec(i));
         }
-      int n = vecdim.size ();
+      int n = static_cast<int>(vecdim.size ());
       // If no dimensions left, set DIM = ndims to return input as is
       if (n == 0)
         {
-vebatim-

Not terribly important, but I think lint would complain.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Tue 18 Nov 2025 04:13:59 PM UTC, comment #12: 

This last revision (35036_v2. patch) improves the error message for invalid optional arguments.

it used to be 'invalid type argument' since the sum function was originally only supporting 'outtype' for "double" and "native". I think the more generic invalid type argument is more appropriate.

Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 18 Nov 2025 07:55:26 AM UTC, comment #11: 

I uploaded a new revision of the patch in 35036_v1.patch
It builds and passes all tests on my system.

Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 18 Nov 2025 07:34:30 AM UTC, comment #10: 

Patch on top of the patch looks messy, I think it easier to make a new one (until it get pushed in).

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Tue 18 Nov 2025 07:31:32 AM UTC, comment #9: 

My initial thought was two for loops, but then I though that it could be done in one with some indexing. Never thought that this could lead to memory corruption. Thank you very much for scrutinizing my code and pointing this out.

Do you want me to prepare a new patch with the new changes (the c++17 edition) or you will ammend these directly on the existing patch?

Andreas Bertsatos <pr0m1th3as>
Group Member
Tue 18 Nov 2025 06:40:56 AM UTC, comment #8: 

Also those two loops can be re-written in C++17 w/o direct indexing.

  105       // Check for duplicate dims and add VECDIM to permutation vector
  106       perm_vec.resize (dim_vector (1, n_dims));
  107       std::sort (vecdim.begin (), vecdim.end ());
  108       // Check for duplicates FIRST before any array writes
  109       if (auto dup = std::adjacent_find (vecdim.begin (), vecdim.end ());
  110           dup != vecdim.end ())
  111         {
  112           error ("%s: duplicate dimension in VECDIM = %d", fcn, *dup + 1);
  113         }
  114       //  Now we know vecdim has unique entries in [0, n_dims-1],
  115       //  hence n <= n_dims
  116       int out_pos = n_dims - n;
  117       for (int d : vecdim)
  118         {
  119           szvecdim *= sz (d);
  120           perm_vec(out_pos++) = d;
  121         }
  122
  123       // If vecdim contains all dimensions revert to all flag


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Mon 17 Nov 2025 10:18:24 PM UTC, comment #7: 

I think "perm_vec(n_dims - n + i) = vecdim[i]" is problematic since when there are duplicates n could be bigger than n_dims.
You need to check for dups first and only after that do array assignments. If I change the code to:

 105       // Check for duplicate dims and add VECDIM to permutation vector
  106       perm_vec.resize (dim_vector (1, n_dims));
  107       std::sort (vecdim.begin (), vecdim.end ());
  108       // Check for duplicates FIRST before any array writes
  109       for (int i = 0; i < n - 1; i++)
  110         {
  111           if (vecdim[i] == vecdim[i + 1])
  112             error ("%s: duplicate dimension in VECDIM = %d", fcn, vecdim[i] + 1);
  113         }
  114       // Now safe to populate perm_vec and compute szvecdim
  115       for (int i = 0; i < n - 1; i++)
  116         {
  117
  118           szvecdim = szvecdim * sz(vecdim[i]);
  119           perm_vec(n_dims - n + i) = vecdim[i];
  120         }

it works for me:

octave:1> test data.cc-tst
***** test <51086> assert (class (horzcat (struct (), cell (0))), "struct")
!!!!! known bug: https://octave.org/testfailure/?51086
octave_base_value::cell_value(): wrong type argument 'scalar struct'
shared variables
    xs =

Compressed Column Sparse (rows = 1, cols = 4, nnz = 3 [75%])

  (1, 2) -> 1
  (1, 3) -> 2
  (1, 4) -> 3

***** test <31974>
 assert (Inf + Inf*i, complex (Inf, Inf))

 assert (1 + Inf*i, complex (1, Inf))
 assert (1 + Inf*j, complex (1, Inf))

 ## whitespace should not affect parsing
 assert (1+Inf*i, complex (1, Inf))
 assert (1+Inf*j, complex (1, Inf))

 assert (NaN*j, complex (0, NaN))

 assert (Inf * 4j, complex (0, Inf))
!!!!! known bug: https://octave.org/testfailure/?31974
ASSERT errors for:  assert (Inf + Inf * i,complex (Inf, Inf))

  Location  |  Observed  |  Expected  |  Reason
     ()        NaN+Infi     Inf+Infi     'NaN' mismatch
shared variables
    xs =

Compressed Column Sparse (rows = 1, cols = 4, nnz = 3 [75%])

  (1, 2) -> 1
  (1, 3) -> 2
  (1, 4) -> 3

***** test <31974>
 x = Inf;
 assert (x * j, complex (0, Inf))
 j = complex (0, 1);
 assert (Inf * j, complex (0, Inf))
!!!!! known bug: https://octave.org/testfailure/?31974
ASSERT errors for:  assert (x * j,complex (0, Inf))

  Location  |  Observed  |  Expected  |  Reason
     ()        NaN+Infi      0+Infi      'NaN' mismatch
shared variables
    xs =

Compressed Column Sparse (rows = 1, cols = 4, nnz = 3 [75%])

  (1, 2) -> 1
  (1, 3) -> 2
  (1, 4) -> 3

***** test <31974>
 exp = complex (zeros (2, 2), Inf (2, 2));
 assert (Inf (2, 2) * j, exp)
 assert (Inf (2, 2) .* j, exp)
 assert (Inf * (ones (2, 2) * j), exp)
 assert (Inf (2, 2) .* (ones (2, 2) * j), exp)
!!!!! known bug: https://octave.org/testfailure/?31974
ASSERT errors for:  assert (Inf (2, 2) * j,exp)

  Location  |  Observed  |  Expected  |  Reason
   (1,1)       NaN+Infi      0+Infi      'NaN' mismatch
   (2,1)       NaN+Infi      0+Infi      'NaN' mismatch
   (1,2)       NaN+Infi      0+Infi      'NaN' mismatch
   (2,2)       NaN+Infi      0+Infi      'NaN' mismatch
shared variables
    xs =

Compressed Column Sparse (rows = 1, cols = 4, nnz = 3 [75%])

  (1, 2) -> 1
  (1, 3) -> 2
  (1, 4) -> 3

***** test <31974>
 assert ([Inf; 0] * [i, 0], complex ([NaN NaN; 0 0], [Inf NaN; 0 0]))
 assert ([Inf, 0] * [i; 0], complex (NaN, Inf))
 assert ([Inf, 0] .* [i, 0], complex ([0 0], [Inf 0]))
!!!!! known bug: https://octave.org/testfailure/?31974
ASSERT errors for:  assert (([Inf, 0]) .* ([i, 0]),complex (([0, 0]), ([Inf, 0])))

  Location  |  Observed  |  Expected  |  Reason
    (1)        NaN+Infi      0+Infi      'NaN' mismatch
shared variables
    xs =

Compressed Column Sparse (rows = 1, cols = 4, nnz = 3 [75%])

  (1, 2) -> 1
  (1, 3) -> 2
  (1, 4) -> 3

***** test <31974>
 m = @(x, y) x * y;
 d = @(x, y) x / y;
 assert (m (Inf, i), complex (0, +Inf))
 assert (d (Inf, i), complex (0, -Inf))
!!!!! known bug: https://octave.org/testfailure/?31974
ASSERT errors for:  assert (m (Inf, i),complex (0, +Inf))

  Location  |  Observed  |  Expected  |  Reason
     ()        NaN+Infi      0+Infi      'NaN' mismatch
shared variables
    xs =

Compressed Column Sparse (rows = 1, cols = 4, nnz = 3 [75%])

  (1, 2) -> 1
  (1, 3) -> 2
  (1, 4) -> 3

***** testif ; ! __have_feature__ ("QNAN_WITH_PAYLOAD") <59830>
 assert (single (NA ("double")), NA ("single"))
----- skipped test (runtime test)

***** testif ; ! __have_feature__ ("QNAN_WITH_PAYLOAD") <59830>
 assert (double (NA ("single")), NA ("double"))
----- skipped test (runtime test)

PASSES 1417 out of 1423 tests (6 known bugs)
Skipped 2 tests due to run-time conditions


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Mon 17 Nov 2025 10:04:44 PM UTC, comment #6: 

Is there a way to make this memory safe? I don't understand the semantics between different compile options I am afraid. But I am happy to help in any way I can.

Andreas Bertsatos <pr0m1th3as>
Group Member
Mon 17 Nov 2025 10:01:26 PM UTC, comment #5: 

I see it intermittent with normal (-O3) compile; that is an indication of memory corruption. So that is why I checked it with
ASAN. I used `clang` (seems to work better with sanitizers) -Og and " --enable-address-sanitizer-flags" configure flag.

Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Mon 17 Nov 2025 09:56:14 PM UTC, comment #4: 

This should be caught as an error at line 110.

Testing on my build, I get

octave:1> all (ones (3,3), [1 2 2])
error: all: duplicate dimension in VECDIM = 2


Andreas Bertsatos <pr0m1th3as>
Group Member
Mon 17 Nov 2025 09:49:23 PM UTC, comment #3: 

The only thing I can understand from the ASAN output is that there is something off with the `get_dim_vecdim_all` function at line 114:

perm_vec(n_dims - n + i) = vecdim[i];


The logic is to add vecdim dimensions at the end of the permutation vector so that they can be merged (with reshape) into a single operating dimension as the last dimensions.

Can you elaborate on what is wrong according to the sanitizer output?

Andreas Bertsatos <pr0m1th3as>
Group Member
Mon 17 Nov 2025 09:42:31 PM UTC, comment #2: 

The actual code that crashes octave:

octave:1> all (ones (3,3), [1 2 2])
=================================================================
==1779033==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7b1c5766658c at pc 0x7efc5e6cfe88 bp 0x7ffdb7d92a10 sp 0x7ffdb7d92a08
WRITE of size 4 at 0x7b1c5766658c thread T0
    #0 0x7efc5e6cfe87 in octave::get_dim_vecdim_all(octave_value const&, octave_value&, int&, Array<int, std::allocator<int>>&, bool&, bool&, char const*) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:114:36
    #1 0x7efc5e611d95 in octave::Fall(octave_value_list const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:219:7
    #2 0x7efc5e3723bb in octave::tree_evaluator::execute_builtin_function(octave_builtin&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3557:14
    #3 0x7efc5dfe2756 in octave_builtin::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-builtin.cc:49:13
    #4 0x7efc5e0b6c8f in octave_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-fcn.cc:86:10
    #5 0x7efc5e3a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #6 0x7efc5e3aecf2 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.h:108:32
    #7 0x7efc5e346d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #8 0x7efc5e3479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #9 0x7efc5e35152f in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #10 0x7efc5e35152f in octave::tree_evaluator::eval(std::shared_ptr<octave::tree_statement_list>&, bool) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:1006:18
    #11 0x7efc5e35380f in octave::tree_evaluator::repl() /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:823:19
    #12 0x7efc5eddc4cb in octave::interpreter::main_loop() /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:1374:22
    #13 0x7efc5eddc4cb in octave::interpreter::execute() /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:904:27
    #14 0x0000004ebdee in main /home/dmitri/src/dev/octave/clang_asan/../src/main-cli.cc:150:17
    #15 0x7efc590e15b4 in __libc_start_call_main (/lib64/libc.so.6+0x35b4) (BuildId: b1556adba4fb835078af59a0c8bb38367dc860ed)
    #16 0x7efc590e1667 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3667) (BuildId: b1556adba4fb835078af59a0c8bb38367dc860ed)
    #17 0x0000004007f4 in _start (/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-cli+0x4007f4) (BuildId: d8e768581aee35906502e122624c5bf841aca36e)

0x7b1c5766658c is located 4 bytes before 8-byte region [0x7b1c57666590,0x7b1c57666598)
allocated by thread T0 here:
    #0 0x0000004e9fd1 in operator new(unsigned long) (/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-cli+0x4e9fd1) (BuildId: d8e768581aee35906502e122624c5bf841aca36e)
    #1 0x7efc5b687409 in std::__new_allocator<int>::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/new_allocator.h:151:27
    #2 0x7efc5b687409 in std::allocator_traits<std::allocator<int>>::allocate(std::allocator<int>&, unsigned long) /usr/bin/../lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/alloc_traits.h:614:20
    #3 0x7efc5b687409 in Array<int, std::allocator<int>>::ArrayRep::allocate(unsigned long) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.h:214:22
    #4 0x7efc5b687409 in Array<int, std::allocator<int>>::ArrayRep::ArrayRep(long) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.h:177:27
    #5 0x7efc5b6880cd in Array<int, std::allocator<int>>::Array(dim_vector const&) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.h:303:18
    #6 0x7efc5b695e4d in Array<int, std::allocator<int>>::resize2(long, long, int const&) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.cc:998:29
    #7 0x7efc5b697662 in Array<int, std::allocator<int>>::resize(dim_vector const&, int const&) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.cc:1035:5
    #8 0x7efc5e6cfcce in Array<int, std::allocator<int>>::resize(dim_vector const&) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.h:729:5
    #9 0x7efc5e6cfcce in octave::get_dim_vecdim_all(octave_value const&, octave_value&, int&, Array<int, std::allocator<int>>&, bool&, bool&, char const*) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:106:16
    #10 0x7efc5e611d95 in octave::Fall(octave_value_list const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:219:7
    #11 0x7efc5e3723bb in octave::tree_evaluator::execute_builtin_function(octave_builtin&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3557:14
    #12 0x7efc5dfe2756 in octave_builtin::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-builtin.cc:49:13
    #13 0x7efc5e0b6c8f in octave_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-fcn.cc:86:10
    #14 0x7efc5e3a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #15 0x7efc5e3aecf2 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.h:108:32
    #16 0x7efc5e346d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #17 0x7efc5e3479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #18 0x7efc5e35152f in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #19 0x7efc5e35152f in octave::tree_evaluator::eval(std::shared_ptr<octave::tree_statement_list>&, bool) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:1006:18
    #20 0x7efc5e35380f in octave::tree_evaluator::repl() /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:823:19
    #21 0x7efc5eddc4cb in octave::interpreter::main_loop() /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:1374:22
    #22 0x7efc5eddc4cb in octave::interpreter::execute() /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:904:27
    #23 0x0000004ebdee in main /home/dmitri/src/dev/octave/clang_asan/../src/main-cli.cc:150:17
    #24 0x7efc590e15b4 in __libc_start_call_main (/lib64/libc.so.6+0x35b4) (BuildId: b1556adba4fb835078af59a0c8bb38367dc860ed)
    #25 0x7efc590e1667 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3667) (BuildId: b1556adba4fb835078af59a0c8bb38367dc860ed)
    #26 0x0000004007f4 in _start (/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-cli+0x4007f4) (BuildId: d8e768581aee35906502e122624c5bf841aca36e)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:114:36 in octave::get_dim_vecdim_all(octave_value const&, octave_value&, int&, Array<int, std::allocator<int>>&, bool&, bool&, char const*)
Shadow bytes around the buggy address:
  0x7b1c57666300: fa fa fd fd fa fa 00 00 fa fa 00 00 fa fa fd fd
  0x7b1c57666380: fa fa fd fd fa fa 00 00 fa fa fd fd fa fa fd fd
  0x7b1c57666400: fa fa fd fd fa fa fd fd fa fa 00 04 fa fa fd fd
  0x7b1c57666480: fa fa 00 00 fa fa 00 00 fa fa fd fa fa fa fd fa
  0x7b1c57666500: fa fa 00 00 fa fa fd fd fa fa fd fd fa fa fd fd
=>0x7b1c57666580: fa[fa]00 fa fa fa 00 00 fa fa fa fa fa fa fa fa
  0x7b1c57666600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b1c57666680: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b1c57666700: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b1c57666780: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b1c57666800: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==1779033==ABORTING


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Mon 17 Nov 2025 09:16:45 PM UTC, comment #1: 

I have some rundom crashes during "test data.cc-tst". Running with ASAN:

  libinterp/corefcn/data.cc-tst ..................................=================================================================
==1774686==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7b5f6991e14c at pc 0x7f3f708cfe88 bp 0x7b3e451f7cf0 sp 0x7b3e451f7ce8
WRITE of size 4 at 0x7b5f6991e14c thread T10 (QThread)
    #0 0x7f3f708cfe87 in octave::get_dim_vecdim_all(octave_value const&, octave_value&, int&, Array<int, std::allocator<int>>&, bool&, bool&, char const*) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:114:36
    #1 0x7f3f70811d95 in octave::Fall(octave_value_list const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:219:7
    #2 0x7f3f705723bb in octave::tree_evaluator::execute_builtin_function(octave_builtin&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3557:14
    #3 0x7f3f701e2756 in octave_builtin::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-builtin.cc:49:13
    #4 0x7f3f702b6c8f in octave_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-fcn.cc:86:10
    #5 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #6 0x7f3f705aecf2 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.h:108:32
    #7 0x7f3f70546d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #8 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #9 0x7f3f70574bc5 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #10 0x7f3f70574bc5 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3806:19
    #11 0x7f3f703a7806 in octave_user_function::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:574:13
    #12 0x7f3f703a75cd in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:567:10
    #13 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #14 0x7f3f70555af3 in octave::tree_evaluator::eval_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, int&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:1074:34
    #15 0x7f3f70557828 in octave::tree_evaluator::eval(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:1136:10
    #16 0x7f3f70fe2c94 in octave::interpreter::eval(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:1558:22
    #17 0x7f3f704ef7f5 in octave::Feval(octave::interpreter&, octave_value_list const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/oct-parse.yy:5984:19
    #18 0x7f3f70572449 in octave::tree_evaluator::execute_builtin_function(octave_builtin&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3562:16
    #19 0x7f3f701e2756 in octave_builtin::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-builtin.cc:49:13
    #20 0x7f3f702b6c8f in octave_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-fcn.cc:86:10
    #21 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #22 0x7f3f705aecf2 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.h:108:32
    #23 0x7f3f70546d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #24 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #25 0x7f3f70547df7 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #26 0x7f3f70547df7 in octave::tree_evaluator::visit_try_catch_command(octave::tree_try_catch_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4280:21
    #27 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #28 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #29 0x7f3f70545aa2 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #30 0x7f3f70545aa2 in octave::tree_evaluator::visit_if_command_list(octave::tree_if_command_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3928:23
    #31 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #32 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #33 0x7f3f70545aa2 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #34 0x7f3f70545aa2 in octave::tree_evaluator::visit_if_command_list(octave::tree_if_command_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3928:23
    #35 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #36 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #37 0x7f3f70548702 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #38 0x7f3f70548702 in octave::tree_evaluator::visit_unwind_protect_command(octave::tree_unwind_protect_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4425:32
    #39 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #40 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #41 0x7f3f70589807 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #42 0x7f3f70589807 in void octave::tree_evaluator::execute_range_loop<double>(octave::range<double, void> const&, int, octave::octave_lvalue&, octave::tree_statement_list*) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3221:20
    #43 0x7f3f7054266a in octave::tree_evaluator::visit_simple_for_command(octave::tree_simple_for_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3268:11
    #44 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #45 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #46 0x7f3f70574bc5 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #47 0x7f3f70574bc5 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3806:19
    #48 0x7f3f703a7806 in octave_user_function::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:574:13
    #49 0x7f3f703a75cd in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:567:10
    #50 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #51 0x7f3f705284b1 in octave::tree_multi_assignment::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-assign.cc:199:49
    #52 0x7f3f7052ce52 in octave::tree_multi_assignment::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-assign.h:159:32
    #53 0x7f3f70546d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #54 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #55 0x7f3f70545aa2 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #56 0x7f3f70545aa2 in octave::tree_evaluator::visit_if_command_list(octave::tree_if_command_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3928:23
    #57 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #58 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #59 0x7f3f70545aa2 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #60 0x7f3f70545aa2 in octave::tree_evaluator::visit_if_command_list(octave::tree_if_command_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3928:23
    #61 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #62 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #63 0x7f3f70589807 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #64 0x7f3f70589807 in void octave::tree_evaluator::execute_range_loop<double>(octave::range<double, void> const&, int, octave::octave_lvalue&, octave::tree_statement_list*) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3221:20
    #65 0x7f3f7054266a in octave::tree_evaluator::visit_simple_for_command(octave::tree_simple_for_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3268:11
    #66 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #67 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #68 0x7f3f70548702 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #69 0x7f3f70548702 in octave::tree_evaluator::visit_unwind_protect_command(octave::tree_unwind_protect_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4425:32
    #70 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #71 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #72 0x7f3f70574bc5 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #73 0x7f3f70574bc5 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3806:19
    #74 0x7f3f703a7806 in octave_user_function::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:574:13
    #75 0x7f3f703a75cd in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:567:10
    #76 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #77 0x7f3f705284b1 in octave::tree_multi_assignment::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-assign.cc:199:49
    #78 0x7f3f7052ce52 in octave::tree_multi_assignment::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-assign.h:159:32
    #79 0x7f3f70546d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #80 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #81 0x7f3f70545aa2 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #82 0x7f3f70545aa2 in octave::tree_evaluator::visit_if_command_list(octave::tree_if_command_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3928:23
    #83 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #84 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #85 0x7f3f70589807 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #86 0x7f3f70589807 in void octave::tree_evaluator::execute_range_loop<double>(octave::range<double, void> const&, int, octave::octave_lvalue&, octave::tree_statement_list*) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3221:20
    #87 0x7f3f7054266a in octave::tree_evaluator::visit_simple_for_command(octave::tree_simple_for_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3268:11
    #88 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #89 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #90 0x7f3f70574bc5 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #91 0x7f3f70574bc5 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3806:19
    #92 0x7f3f703a7806 in octave_user_function::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:574:13
    #93 0x7f3f703a75cd in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:567:10
    #94 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #95 0x7f3f705284b1 in octave::tree_multi_assignment::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-assign.cc:199:49
    #96 0x7f3f7052ce52 in octave::tree_multi_assignment::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-assign.h:159:32
    #97 0x7f3f70546d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #98 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #99 0x7f3f70589807 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #100 0x7f3f70589807 in void octave::tree_evaluator::execute_range_loop<double>(octave::range<double, void> const&, int, octave::octave_lvalue&, octave::tree_statement_list*) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3221:20
    #101 0x7f3f7054266a in octave::tree_evaluator::visit_simple_for_command(octave::tree_simple_for_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3268:11
    #102 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #103 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #104 0x7f3f70547df7 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #105 0x7f3f70547df7 in octave::tree_evaluator::visit_try_catch_command(octave::tree_try_catch_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4280:21
    #106 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #107 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #108 0x7f3f70548702 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #109 0x7f3f70548702 in octave::tree_evaluator::visit_unwind_protect_command(octave::tree_unwind_protect_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4425:32
    #110 0x7f3f70546c0c in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4055:20
    #111 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #112 0x7f3f70574bc5 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #113 0x7f3f70574bc5 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3806:19
    #114 0x7f3f703a7806 in octave_user_function::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:574:13
    #115 0x7f3f703a75cd in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:567:10
    #116 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #117 0x7f3f705aecf2 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.h:108:32
    #118 0x7f3f70546d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #119 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #120 0x7f3f70573294 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #121 0x7f3f70573294 in octave::tree_evaluator::execute_user_script(octave_user_script&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3641:13
    #122 0x7f3f703a4806 in octave_user_script::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:232:13
    #123 0x7f3f703a468f in octave_user_script::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:225:10
    #124 0x7f3f70564695 in octave::tree_evaluator::source_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:2218:9
    #125 0x7f3f70fe1362 in octave::interpreter::source_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:1782:15
    #126 0x7f3f70fe1362 in octave::interpreter::safe_source_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, bool) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:2281:7
    #127 0x7f3f70fdf03b in octave::interpreter::execute_command_line_file() /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:1366:10
    #128 0x7f3f70fdc39b in octave::interpreter::execute() /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:864:28
    #129 0x7f3f74944d1f in octave::interpreter_qobject::execute() /home/dmitri/src/dev/octave/clang_asan/../libgui/src/interpreter-qobject.cc:81:32
    #130 0x7f3f72559a4b in QObject::event(QEvent*) (/lib64/libQt6Core.so.6+0x159a4b) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #131 0x7f3f7383db1e in QApplicationPrivate::notify_helper(QObject*, QEvent*) (/lib64/libQt6Widgets.so.6+0x3db1e) (BuildId: dd7167d5ff5f9a05f0950f1911a91a803cec4918)
    #132 0x7f3f74a37c01 in octave::octave_qapplication::notify(QObject*, QEvent*) /home/dmitri/src/dev/octave/clang_asan/../libgui/src/octave-qobject.cc:153:28
    #133 0x7f3f724fcaa7 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/lib64/libQt6Core.so.6+0xfcaa7) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #134 0x7f3f725000d8 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/lib64/libQt6Core.so.6+0x1000d8) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #135 0x7f3f7282186e  (/lib64/libQt6Core.so.6+0x42186e) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #136 0x7f3f6ada62a2  (/lib64/libglib-2.0.so.0+0x412a2) (BuildId: e06d79ca6a0879accff6de7371a1576511f00c6a)
    #137 0x7f3f6adaf1f7  (/lib64/libglib-2.0.so.0+0x4a1f7) (BuildId: e06d79ca6a0879accff6de7371a1576511f00c6a)
    #138 0x7f3f6adaf3a2 in g_main_context_iteration (/lib64/libglib-2.0.so.0+0x4a3a2) (BuildId: e06d79ca6a0879accff6de7371a1576511f00c6a)
    #139 0x7f3f728210ac in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/lib64/libQt6Core.so.6+0x4210ac) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #140 0x7f3f72509602 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/lib64/libQt6Core.so.6+0x109602) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #141 0x7f3f7262db05 in QThread::exec() (/lib64/libQt6Core.so.6+0x22db05) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #142 0x7f3f726d364d  (/lib64/libQt6Core.so.6+0x2d364d) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #143 0x0000004a358a in asan_thread_start(void*) asan_interceptors.cpp.o
    #144 0x7f3f6b67e463 in start_thread (/lib64/libc.so.6+0x72463) (BuildId: b1556adba4fb835078af59a0c8bb38367dc860ed)
    #145 0x7f3f6b7015ab in __GI___clone3 (/lib64/libc.so.6+0xf55ab) (BuildId: b1556adba4fb835078af59a0c8bb38367dc860ed)

0x7b5f6991e14c is located 4 bytes before 8-byte region [0x7b5f6991e150,0x7b5f6991e158)
allocated by thread T10 (QThread) here:
    #0 0x0000004e9ff1 in operator new(unsigned long) (/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-gui+0x4e9ff1) (BuildId: 39b22c27639fe1b3d688655786532fed128a2f1c)
    #1 0x7f3f6d887409 in std::__new_allocator<int>::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/new_allocator.h:151:27
    #2 0x7f3f6d887409 in std::allocator_traits<std::allocator<int>>::allocate(std::allocator<int>&, unsigned long) /usr/bin/../lib/gcc/x86_64-redhat-linux/15/../../../../include/c++/15/bits/alloc_traits.h:614:20
    #3 0x7f3f6d887409 in Array<int, std::allocator<int>>::ArrayRep::allocate(unsigned long) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.h:214:22
    #4 0x7f3f6d887409 in Array<int, std::allocator<int>>::ArrayRep::ArrayRep(long) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.h:177:27
    #5 0x7f3f6d8880cd in Array<int, std::allocator<int>>::Array(dim_vector const&) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.h:303:18
    #6 0x7f3f6d895e4d in Array<int, std::allocator<int>>::resize2(long, long, int const&) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.cc:998:29
    #7 0x7f3f6d897662 in Array<int, std::allocator<int>>::resize(dim_vector const&, int const&) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.cc:1035:5
    #8 0x7f3f708cfcce in Array<int, std::allocator<int>>::resize(dim_vector const&) /home/dmitri/src/dev/octave/clang_asan/../liboctave/array/Array-base.h:729:5
    #9 0x7f3f708cfcce in octave::get_dim_vecdim_all(octave_value const&, octave_value&, int&, Array<int, std::allocator<int>>&, bool&, bool&, char const*) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:106:16
    #10 0x7f3f70811d95 in octave::Fall(octave_value_list const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:219:7
    #11 0x7f3f705723bb in octave::tree_evaluator::execute_builtin_function(octave_builtin&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3557:14
    #12 0x7f3f701e2756 in octave_builtin::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-builtin.cc:49:13
    #13 0x7f3f702b6c8f in octave_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-fcn.cc:86:10
    #14 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #15 0x7f3f705aecf2 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.h:108:32
    #16 0x7f3f70546d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #17 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #18 0x7f3f70574bc5 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #19 0x7f3f70574bc5 in octave::tree_evaluator::execute_user_function(octave_user_function&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3806:19
    #20 0x7f3f703a7806 in octave_user_function::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:574:13
    #21 0x7f3f703a75cd in octave_user_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-usr-fcn.cc:567:10
    #22 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #23 0x7f3f70555af3 in octave::tree_evaluator::eval_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, bool, int&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:1074:34
    #24 0x7f3f70557828 in octave::tree_evaluator::eval(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:1136:10
    #25 0x7f3f70fe2c94 in octave::interpreter::eval(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/interpreter.cc:1558:22
    #26 0x7f3f704ef7f5 in octave::Feval(octave::interpreter&, octave_value_list const&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/oct-parse.yy:5984:19
    #27 0x7f3f70572449 in octave::tree_evaluator::execute_builtin_function(octave_builtin&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:3562:16
    #28 0x7f3f701e2756 in octave_builtin::execute(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-builtin.cc:49:13
    #29 0x7f3f702b6c8f in octave_function::call(octave::tree_evaluator&, int, octave_value_list const&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/octave-value/ov-fcn.cc:86:10
    #30 0x7f3f705a668d in octave::tree_index_expression::evaluate_n(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.cc:523:33
    #31 0x7f3f705aecf2 in octave::tree_index_expression::evaluate(octave::tree_evaluator&, int) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-idx.h:108:32
    #32 0x7f3f70546d8e in octave::tree_evaluator::visit_statement(octave::tree_statement&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4080:47
    #33 0x7f3f705479ab in octave::tree_evaluator::visit_statement_list(octave::tree_statement_list&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4165:16
    #34 0x7f3f70547df7 in octave::tree_statement_list::accept(octave::tree_walker&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-stmt.h:232:8
    #35 0x7f3f70547df7 in octave::tree_evaluator::visit_try_catch_command(octave::tree_try_catch_command&) /home/dmitri/src/dev/octave/clang_asan/../libinterp/parse-tree/pt-eval.cc:4280:21

Thread T10 (QThread) created by T0 here:
    #0 0x000000489ec5 in pthread_create (/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-gui+0x489ec5) (BuildId: 39b22c27639fe1b3d688655786532fed128a2f1c)
    #1 0x7f3f726d3173 in QThread::start(QThread::Priority) (/lib64/libQt6Core.so.6+0x2d3173) (BuildId: eb351ca7de09857e4d5db750bc4d887880dc6651)
    #2 0x7f3f74a3a128 in octave::base_qobject::start_main_thread() /home/dmitri/src/dev/octave/clang_asan/../libgui/src/octave-qobject.cc:467:18
    #3 0x7f3f74a3a128 in octave::base_qobject::base_qobject(octave::qt_application&, bool) /home/dmitri/src/dev/octave/clang_asan/../libgui/src/octave-qobject.cc:328:3
    #4 0x7f3f74a7232b in octave::qt_application::execute() /home/dmitri/src/dev/octave/clang_asan/../libgui/src/qt-application.cc:97:16
    #5 0x0000004ec2a4 in main /home/dmitri/src/dev/octave/clang_asan/../src/main-gui.cc:168:17
    #6 0x7f3f6b60f5b4 in __libc_start_call_main (/lib64/libc.so.6+0x35b4) (BuildId: b1556adba4fb835078af59a0c8bb38367dc860ed)
    #7 0x7f3f6b60f667 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x3667) (BuildId: b1556adba4fb835078af59a0c8bb38367dc860ed)
    #8 0x000000400814 in _start (/home/dmitri/src/dev/octave/clang_asan/src/.libs/octave-gui+0x400814) (BuildId: 39b22c27639fe1b3d688655786532fed128a2f1c)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/dmitri/src/dev/octave/clang_asan/../libinterp/corefcn/data.cc:114:36 in octave::get_dim_vecdim_all(octave_value const&, octave_value&, int&, Array<int, std::allocator<int>>&, bool&, bool&, char const*)
Shadow bytes around the buggy address:
  0x7b5f6991de80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b5f6991df00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b5f6991df80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b5f6991e000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b5f6991e080: fa fa 00 00 fa fa fa fa fa fa fa fa fa fa fd fd
=>0x7b5f6991e100: fa fa fd fd fa fa fa fa fa[fa]00 fa fa fa fa fa
  0x7b5f6991e180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b5f6991e200: fa fa fa fa fa fa fa fa fa fa 00 00 fa fa fd fd
  0x7b5f6991e280: fa fa 00 00 fa fa fa fa fa fa fa fa fa fa fd fd
  0x7b5f6991e300: fa fa fa fa fa fa fa fa fa fa fd fd fa fa fd fd
  0x7b5f6991e380: fa fa 00 04 fa fa fd fd fa fa 00 00 fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==1774686==ABORTING


Dmitri.
--

Dmitri A. Sergatskov <dasergatskov>
Mon 17 Nov 2025 07:23:33 PM UTC, original submission:  

I have just finished testing my changes to a rather large patch (mainly on libinterp/corefcn/data.cc, but also in other files).

I’ve been working on adding vecdim (including "all" option) and nanflag support for the main core functions in data.cc, but I also added support for direction for the cumprod and cumsum functions.

For more info see https://octave.di ... 9/10?u=pr0m1th3as

I am also working on updating the relevant functionality of functions in the statistics folder, which rely on the changes of this patch. The patch has already been tested and I made best effort to be consistent with coding style. Please review the commit message and the notice in the NEWS file.

Andreas Bertsatos <pr0m1th3as>
Group Member

 

Attached Files

Attached Files
file #57905:  bug67714_allnan_3.cset added by dasergatskov (10KiB - application/octet-stream)
file #57893:  bug67714_allnan_2.cset added by dasergatskov (8.7KiB - application/octet-stream)
file #57889:  bug67714_v3.patch added by pr0m1th3as (25KiB - text/x-patch)
file #57890:  bug67714_v4_extra.patch added by pr0m1th3as (27KiB - text/x-patch)
file #57872:  bug67714_v1.patch added by pr0m1th3as (77KiB - text/x-patch)
file #57871:  abs_2.diff added by arungiridhar (32KiB - text/x-patch)
file #57870:  abs_1.diff added by dasergatskov (32KiB - application/octet-stream)
file #57869:  bug67714.patch added by pr0m1th3as (533KiB - text/x-patch)
file #57860:  35058.patch added by pr0m1th3as (365KiB - text/x-patch)
file #57824:  35036_v2.patch added by pr0m1th3as (106KiB - text/x-patch)
file #57818:  35036_v1.patch added by pr0m1th3as (105KiB - text/x-patch)
file #57815:  35036.patch added by pr0m1th3as (105KiB - text/x-patch)

(Note: upload size limit is set to 4.0MiB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

 

Dependencies

This item does not depend on any other items.

No items depend on this one.

 

Mail Notification Carbon-Copy List

Carbon-Copy List
  • -email is unavailable- added by arungiridhar (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by kolmanthomas (Posted a comment)
  • -email is unavailable- added by dasergatskov (Posted a comment)
  • -email is unavailable- added by pr0m1th3as (Submitted the item)
  •  

    Votes

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

    History

    Follow 17 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-12-10 arungiridhar StatusPatch Submitted Ready For Test
    2025-12-10 pr0m1th3as StatusNone Patch Submitted
    2025-12-10 pr0m1th3as Attached File- Added bug67714_m_functions.patch, #57942
    2025-12-02 dasergatskov Attached File- Added bug67714_allnan_3.cset, #57905
    2025-12-02 dasergatskov Attached File- Added bug67714_allnan_2.cset, #57893
    2025-12-01 pr0m1th3as Attached File- Added bug67714_v3.patch, #57889
        Attached File- Added bug67714_v4_extra.patch, #57890
    2025-11-28 arungiridhar Planned ReleaseNone 11.1.0 (current default)
    2025-11-28 arungiridhar Severity3 - Normal 5 - Blocker
    2025-11-27 pr0m1th3as Attached File- Added bug67714_v1.patch, #57872
    2025-11-26 arungiridhar Attached File- Added abs_2.diff, #57871
    2025-11-26 dasergatskov Attached File- Added abs_1.diff, #57870
    2025-11-26 pr0m1th3as Attached File- Added bug67714.patch, #57869
    2025-11-24 pr0m1th3as Attached File- Added 35058.patch, #57860
    2025-11-18 pr0m1th3as Attached File- Added 35036_v2.patch, #57824
    2025-11-18 pr0m1th3as Attached File- Added 35036_v1.patch, #57818
    2025-11-17 pr0m1th3as Attached File- Added 35036.patch, #57815

    Back to the top

    Powered by Savane 3.16-a7ba.
    Corresponding source code