gno icon indicating copy to clipboard operation
gno copied to clipboard

fix(gnovm): forbid start expression when value is not a pointer

Open omarsy opened this issue 1 year ago • 2 comments

closes: #1088

Contributors' checklist...
  • [ ] Added new tests, or not needed, or not feasible
  • [ ] Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory
  • [ ] Updated the official documentation or not needed
  • [ ] No breaking changes were made, or a BREAKING CHANGE: xxx message was included in the description
  • [ ] Added references to related issues and PRs
  • [ ] Provided any useful hints for running manual tests

omarsy avatar Oct 19 '24 15:10 omarsy

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 63.08%. Comparing base (f6bd2d3) to head (cc7ed1a). Report is 40 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #2984   +/-   ##
=======================================
  Coverage   63.08%   63.08%           
=======================================
  Files         563      563           
  Lines       79254    79258    +4     
=======================================
+ Hits        49998    50001    +3     
+ Misses      25896    25895    -1     
- Partials     3360     3362    +2     
Flag Coverage Δ
contribs/gnodev 60.62% <ø> (ø)
contribs/gnofaucet 14.82% <ø> (ø)
gno.land 67.56% <ø> (ø)
gnovm 67.25% <100.00%> (+<0.01%) :arrow_up:
misc/genstd 79.72% <ø> (ø)
misc/logos 19.45% <ø> (ø)
tm2 62.27% <ø> (+0.02%) :arrow_up:

Flags with carried forward coverage won't be shown. Click here to find out more.

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

codecov[bot] avatar Oct 19 '24 15:10 codecov[bot]

It looks fine to me. However, I found that for the following case, the error message slightly differs from what Go outputs:

package main

const VALUE = 5

func main() {
    println(*VALUE)
}

When this code is executed in Go, it produces the following error message:

invalid operation: cannot indirect VALUE (untyped int constant 5)

However, when run this code in gno, you can see const 5 is output instead of the constant name VALUE.

panic: invalid operation: cannot indirect (const (5 <untyped> bigint)) (variable of type <untyped> bigint) [recovered]
        panic: main/gnovm/tests/files/ptr10.gno:6:13: invalid operation: cannot indirect (const (5 <untyped> bigint)) (variable of type <untyped> bigint):
        --- preprocess stack ---
        stack 2: func main() { (const (println func(xs ...interface{})()))(*((const (5 <untyped> bigint)))) }
        stack 1: file{ package main; const VALUE<VPBlock(2,0)> = (const (5 <untyped> bigint)); func main() { (const (println func(xs ...interface{})()))(*((const (5 <untyped> bigint)))) } }
        stack 0: package(main)
        ------------------------

I think it would be helpful for debugging if it were made to output the constant's name like Go does.

Additionally, if you declare it with var instrade of const, VALUE is output correctly.

package main

var VALUE = 5

func main() {
    println(*VALUE)
}

// Output: panic: invalid operation: cannot indirect VALUE<VPBlock(3,0)> (variable of type int) [recovered]

notJoon avatar Oct 21 '24 08:10 notJoon

It looks fine to me. However, I found that for the following case, the error message slightly differs from what Go outputs:

package main

const VALUE = 5

func main() {
    println(*VALUE)
}

When this code is executed in Go, it produces the following error message:

invalid operation: cannot indirect VALUE (untyped int constant 5)

However, when run this code in gno, you can see const 5 is output instead of the constant name VALUE.

panic: invalid operation: cannot indirect (const (5 <untyped> bigint)) (variable of type <untyped> bigint) [recovered]
        panic: main/gnovm/tests/files/ptr10.gno:6:13: invalid operation: cannot indirect (const (5 <untyped> bigint)) (variable of type <untyped> bigint):
        --- preprocess stack ---
        stack 2: func main() { (const (println func(xs ...interface{})()))(*((const (5 <untyped> bigint)))) }
        stack 1: file{ package main; const VALUE<VPBlock(2,0)> = (const (5 <untyped> bigint)); func main() { (const (println func(xs ...interface{})()))(*((const (5 <untyped> bigint)))) } }
        stack 0: package(main)
        ------------------------

I think it would be helpful for debugging if it were made to output the constant's name like Go does.

Additionally, if you declare it with var instrade of const, VALUE is output correctly.

package main

var VALUE = 5

func main() {
    println(*VALUE)
}

// Output: panic: invalid operation: cannot indirect VALUE<VPBlock(3,0)> (variable of type int) [recovered]

@notJoon Thank you for your input! The difference in how ConstExpr and NameExpr are displayed stems from the specific formatting logic defined in their respective implementations. You can see this in the nodes_string.go file:

  • For ConstExpr, the display logic is found here.
  • For NameExpr, the relevant logic is located here.

omarsy avatar Oct 24 '24 23:10 omarsy

It looks fine to me. However, I found that for the following case, the error message slightly differs from what Go outputs:

package main

const VALUE = 5

func main() {
    println(*VALUE)
}

When this code is executed in Go, it produces the following error message:

invalid operation: cannot indirect VALUE (untyped int constant 5)

However, when run this code in gno, you can see const 5 is output instead of the constant name VALUE.

panic: invalid operation: cannot indirect (const (5 <untyped> bigint)) (variable of type <untyped> bigint) [recovered]
        panic: main/gnovm/tests/files/ptr10.gno:6:13: invalid operation: cannot indirect (const (5 <untyped> bigint)) (variable of type <untyped> bigint):
        --- preprocess stack ---
        stack 2: func main() { (const (println func(xs ...interface{})()))(*((const (5 <untyped> bigint)))) }
        stack 1: file{ package main; const VALUE<VPBlock(2,0)> = (const (5 <untyped> bigint)); func main() { (const (println func(xs ...interface{})()))(*((const (5 <untyped> bigint)))) } }
        stack 0: package(main)
        ------------------------

I think it would be helpful for debugging if it were made to output the constant's name like Go does. Additionally, if you declare it with var instrade of const, VALUE is output correctly.

package main

var VALUE = 5

func main() {
    println(*VALUE)
}

// Output: panic: invalid operation: cannot indirect VALUE<VPBlock(3,0)> (variable of type int) [recovered]

@notJoon Thank you for your input! The difference in how ConstExpr and NameExpr are displayed stems from the specific formatting logic defined in their respective implementations. You can see this in the nodes_string.go file:

* For `ConstExpr`, the display logic is found [here](https://github.com/gnolang/gno/blob/master/gnovm/pkg/gnolang/nodes_string.go#L552).

* For `NameExpr`, the relevant logic is located [here](https://github.com/gnolang/gno/blob/master/gnovm/pkg/gnolang/nodes_string.go#L98).

Thanks for response. it seems reasonable to me. So I'll remove the triage-pending flag.

notJoon avatar Oct 30 '24 02:10 notJoon