NilFoundation / zkLLVM

Zero-Knowledge Proof Systems Circuit Compiler
https://docs.nil.foundation/zkllvm
286 stars 48 forks source link

[Possible bug] fails when array.end() iterator is passed as a function parameter #519

Closed ETatuzova closed 8 months ago

ETatuzova commented 8 months ago

On this example:

#include <nil/crypto3/algebra/curves/pallas.hpp>

using namespace nil::crypto3::algebra::curves;

int f(std::array<int,5>::iterator it_begin, std::array<int,5>::iterator it_end) {
    return *it_begin;
}

[[circuit]] int field_for_example() {
    std::array<int, 5> v = {1, 2, 3, 4, 5};

    return f(v.begin(), v.end());
}

assigner fails with undef_type->isAggregateType() error.

akokoshn commented 8 months ago

Fail happens on processing parameters of call:

%5 = call noundef i32 @_Z1fPiS_(ptr noundef %3, ptr poison)

'v.end()' is special llvm constant poison which is UndefValue and not AggregateType, so we have no it in frame of stack. It means now end iterator can't be used as parameter of instruction. But valid expressions based on end iterator is ok: *(v.en() - 1)

akokoshn commented 8 months ago

possible solution - process poison value as undefined integer constant:

if (undef_type->isIntegerTy() || undef_type->isFieldTy() || llvm::isa<llvm::PoisonValue>(c)) {
akokoshn commented 8 months ago

Fix: https://github.com/NilFoundation/zkllvm-assigner/pull/179