Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macro generating lambda containing ident("auto") and genSym causes SIGSEGV #24048

Closed
johanobergman opened this issue Sep 2, 2024 · 3 comments · Fixed by #24050
Closed

Macro generating lambda containing ident("auto") and genSym causes SIGSEGV #24048

johanobergman opened this issue Sep 2, 2024 · 3 comments · Fixed by #24050

Comments

@johanobergman
Copy link

johanobergman commented Sep 2, 2024

Description

The macro aBug defined below generates the following code:

# echo repr result:
map(proc (val: auto): void =
  let variable_536870972 = 123)

Calling the macro crashes with SIGSEGV: Illegal storage access. (Attempt to read from nil?).
It seems to be caused by a combination of the use of genSym, and auto as the type for the lambda parameter val.

Reproduction

import macros

proc map(fn: proc(val: int): void) = fn(1)

# This works fine, and is the exact same function call as what's
# generated by the macro `aBug`.
map proc(val: auto): void =
  let variable = 123

macro aBug() =
  # 1. let sym = ident("variable")
  let sym = genSym(nskLet, "variable")
  let letStmt = newLetStmt(sym, newLit(123))

  let lambda = newProc(
    params = @[
      ident("void"),
      newIdentDefs(ident("val"), ident("auto")),
      # 2. newIdentDefs(ident("val"), ident("int")),
    ],
    body = newStmtList(letStmt),
    procType = nnkLambda
  )

  result = newCall(bindSym("map"), lambda)

  echo repr result
  echo treeRepr result

aBug()

Using 1. ident instead of genSym doesn't crash but doesn't generate a unique name.
Using 2. int instead of auto as the type for val doesn't crash.

Nim Version

Nim Compiler Version 2.0.8 [MacOSX: amd64]
Compiled at 2024-09-02
Copyright (c) 2006-2023 by Andreas Rumpf

Current Output

SIGSEGV: Illegal storage access. (Attempt to read from nil?)

# echo treeRepr result:
Call
  Sym "map"
  Lambda
    Empty
    Empty
    Empty
    FormalParams
      Ident "void"
      IdentDefs
        Ident "val"
        Ident "auto"
        Empty
    Empty
    Empty
    StmtList
      LetSection
        IdentDefs
          Sym "variable"
          Empty
          IntLit 123

Expected Output

No response

Known Workarounds

No response

Additional Information

No response

@johanobergman johanobergman changed the title Macro generating lambda containing ident("auto") and genSym` causes SIGSEGV Macro generating lambda containing ident("auto") and genSym causes SIGSEGV Sep 2, 2024
@juancarlospaco
Copy link
Collaborator

!nim c

import macros

proc map(fn: proc(val: int): void) = fn(1)

# This works fine, and is the exact same function call as what's
# generated by the macro `aBug`.
map proc(val: auto): void =
  let variable = 123

macro aBug() =
  # 1. let sym = ident("variable")
  let sym = genSym(nskLet, "variable")
  let letStmt = newLetStmt(sym, newLit(123))

  let lambda = newProc(
    params = @[
      ident("void"),
      newIdentDefs(ident("val"), ident("auto")),
      # 2. newIdentDefs(ident("val"), ident("int")),
    ],
    body = newStmtList(letStmt),
    procType = nnkLambda
  )

  result = newCall(bindSym("map"), lambda)

  echo repr result
  echo treeRepr result

aBug()

Copy link
Contributor

github-actions bot commented Sep 2, 2024

🐧 Linux bisect by @juancarlospaco (collaborator)
devel 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-09-02T21:14:51
  • Finished 2024-09-02T21:14:51
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    newIdentNode("macros")
  ),
  nnkProcDef.newTree(
    newIdentNode("map"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode(),
      nnkIdentDefs.newTree(
        newIdentNode("fn"),
        nnkProcTy.newTree(
          nnkFormalParams.newTree(
            newIdentNode("void"),
            nnkIdentDefs.newTree(
              newIdentNode("val"),
              newIdentNode("int"),
              newEmptyNode()
            )
          ),
          newEmptyNode()
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkCall.newTree(
        newIdentNode("fn"),
        newLit(1)
      )
    )
  ),
  nnkCommand.newTree(
    newIdentNode("map"),
    nnkLambda.newTree(
      newEmptyNode(),
      newEmptyNode(),
      newEmptyNode(),
      nnkFormalParams.newTree(
        newIdentNode("void"),
        nnkIdentDefs.newTree(
          newIdentNode("val"),
          newIdentNode("auto"),
          newEmptyNode()
        )
      ),
      newEmptyNode(),
      newEmptyNode(),
      nnkStmtList.newTree(
        nnkLetSection.newTree(
          nnkIdentDefs.newTree(
            newIdentNode("variable"),
            newEmptyNode(),
            newLit(123)
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    newIdentNode("aBug"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("sym"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("genSym"),
            newIdentNode("nskLet"),
            newLit("variable")
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("letStmt"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newLetStmt"),
            newIdentNode("sym"),
            nnkCall.newTree(
              newIdentNode("newLit"),
              newLit(123)
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("lambda"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newProc"),
            nnkExprEqExpr.newTree(
              newIdentNode("params"),
              nnkPrefix.newTree(
                newIdentNode("@"),
                nnkBracket.newTree(
                  nnkCall.newTree(
                    newIdentNode("ident"),
                    newLit("void")
                  ),
                  nnkCall.newTree(
                    newIdentNode("newIdentDefs"),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("val")
                    ),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("auto")
                    )
                  )
                )
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("body"),
              nnkCall.newTree(
                newIdentNode("newStmtList"),
                newIdentNode("letStmt")
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("procType"),
              newIdentNode("nnkLambda")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newCall"),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            newLit("map")
          ),
          newIdentNode("lambda")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("repr"),
          newIdentNode("result")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("treeRepr"),
          newIdentNode("result")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("aBug")
  )
)
stable 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-09-02T21:14:55
  • Finished 2024-09-02T21:14:55
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    newIdentNode("macros")
  ),
  nnkProcDef.newTree(
    newIdentNode("map"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode(),
      nnkIdentDefs.newTree(
        newIdentNode("fn"),
        nnkProcTy.newTree(
          nnkFormalParams.newTree(
            newIdentNode("void"),
            nnkIdentDefs.newTree(
              newIdentNode("val"),
              newIdentNode("int"),
              newEmptyNode()
            )
          ),
          newEmptyNode()
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkCall.newTree(
        newIdentNode("fn"),
        newLit(1)
      )
    )
  ),
  nnkCommand.newTree(
    newIdentNode("map"),
    nnkLambda.newTree(
      newEmptyNode(),
      newEmptyNode(),
      newEmptyNode(),
      nnkFormalParams.newTree(
        newIdentNode("void"),
        nnkIdentDefs.newTree(
          newIdentNode("val"),
          newIdentNode("auto"),
          newEmptyNode()
        )
      ),
      newEmptyNode(),
      newEmptyNode(),
      nnkStmtList.newTree(
        nnkLetSection.newTree(
          nnkIdentDefs.newTree(
            newIdentNode("variable"),
            newEmptyNode(),
            newLit(123)
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    newIdentNode("aBug"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("sym"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("genSym"),
            newIdentNode("nskLet"),
            newLit("variable")
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("letStmt"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newLetStmt"),
            newIdentNode("sym"),
            nnkCall.newTree(
              newIdentNode("newLit"),
              newLit(123)
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("lambda"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newProc"),
            nnkExprEqExpr.newTree(
              newIdentNode("params"),
              nnkPrefix.newTree(
                newIdentNode("@"),
                nnkBracket.newTree(
                  nnkCall.newTree(
                    newIdentNode("ident"),
                    newLit("void")
                  ),
                  nnkCall.newTree(
                    newIdentNode("newIdentDefs"),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("val")
                    ),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("auto")
                    )
                  )
                )
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("body"),
              nnkCall.newTree(
                newIdentNode("newStmtList"),
                newIdentNode("letStmt")
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("procType"),
              newIdentNode("nnkLambda")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newCall"),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            newLit("map")
          ),
          newIdentNode("lambda")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("repr"),
          newIdentNode("result")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("treeRepr"),
          newIdentNode("result")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("aBug")
  )
)
2.0.8 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-09-02T21:14:56
  • Finished 2024-09-02T21:14:56
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    newIdentNode("macros")
  ),
  nnkProcDef.newTree(
    newIdentNode("map"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode(),
      nnkIdentDefs.newTree(
        newIdentNode("fn"),
        nnkProcTy.newTree(
          nnkFormalParams.newTree(
            newIdentNode("void"),
            nnkIdentDefs.newTree(
              newIdentNode("val"),
              newIdentNode("int"),
              newEmptyNode()
            )
          ),
          newEmptyNode()
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkCall.newTree(
        newIdentNode("fn"),
        newLit(1)
      )
    )
  ),
  nnkCommand.newTree(
    newIdentNode("map"),
    nnkLambda.newTree(
      newEmptyNode(),
      newEmptyNode(),
      newEmptyNode(),
      nnkFormalParams.newTree(
        newIdentNode("void"),
        nnkIdentDefs.newTree(
          newIdentNode("val"),
          newIdentNode("auto"),
          newEmptyNode()
        )
      ),
      newEmptyNode(),
      newEmptyNode(),
      nnkStmtList.newTree(
        nnkLetSection.newTree(
          nnkIdentDefs.newTree(
            newIdentNode("variable"),
            newEmptyNode(),
            newLit(123)
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    newIdentNode("aBug"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("sym"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("genSym"),
            newIdentNode("nskLet"),
            newLit("variable")
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("letStmt"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newLetStmt"),
            newIdentNode("sym"),
            nnkCall.newTree(
              newIdentNode("newLit"),
              newLit(123)
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("lambda"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newProc"),
            nnkExprEqExpr.newTree(
              newIdentNode("params"),
              nnkPrefix.newTree(
                newIdentNode("@"),
                nnkBracket.newTree(
                  nnkCall.newTree(
                    newIdentNode("ident"),
                    newLit("void")
                  ),
                  nnkCall.newTree(
                    newIdentNode("newIdentDefs"),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("val")
                    ),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("auto")
                    )
                  )
                )
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("body"),
              nnkCall.newTree(
                newIdentNode("newStmtList"),
                newIdentNode("letStmt")
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("procType"),
              newIdentNode("nnkLambda")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newCall"),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            newLit("map")
          ),
          newIdentNode("lambda")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("repr"),
          newIdentNode("result")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("treeRepr"),
          newIdentNode("result")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("aBug")
  )
)
2.0.0 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-09-02T21:14:59
  • Finished 2024-09-02T21:14:59
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    newIdentNode("macros")
  ),
  nnkProcDef.newTree(
    newIdentNode("map"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode(),
      nnkIdentDefs.newTree(
        newIdentNode("fn"),
        nnkProcTy.newTree(
          nnkFormalParams.newTree(
            newIdentNode("void"),
            nnkIdentDefs.newTree(
              newIdentNode("val"),
              newIdentNode("int"),
              newEmptyNode()
            )
          ),
          newEmptyNode()
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkCall.newTree(
        newIdentNode("fn"),
        newLit(1)
      )
    )
  ),
  nnkCommand.newTree(
    newIdentNode("map"),
    nnkLambda.newTree(
      newEmptyNode(),
      newEmptyNode(),
      newEmptyNode(),
      nnkFormalParams.newTree(
        newIdentNode("void"),
        nnkIdentDefs.newTree(
          newIdentNode("val"),
          newIdentNode("auto"),
          newEmptyNode()
        )
      ),
      newEmptyNode(),
      newEmptyNode(),
      nnkStmtList.newTree(
        nnkLetSection.newTree(
          nnkIdentDefs.newTree(
            newIdentNode("variable"),
            newEmptyNode(),
            newLit(123)
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    newIdentNode("aBug"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("sym"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("genSym"),
            newIdentNode("nskLet"),
            newLit("variable")
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("letStmt"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newLetStmt"),
            newIdentNode("sym"),
            nnkCall.newTree(
              newIdentNode("newLit"),
              newLit(123)
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("lambda"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newProc"),
            nnkExprEqExpr.newTree(
              newIdentNode("params"),
              nnkPrefix.newTree(
                newIdentNode("@"),
                nnkBracket.newTree(
                  nnkCall.newTree(
                    newIdentNode("ident"),
                    newLit("void")
                  ),
                  nnkCall.newTree(
                    newIdentNode("newIdentDefs"),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("val")
                    ),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("auto")
                    )
                  )
                )
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("body"),
              nnkCall.newTree(
                newIdentNode("newStmtList"),
                newIdentNode("letStmt")
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("procType"),
              newIdentNode("nnkLambda")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newCall"),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            newLit("map")
          ),
          newIdentNode("lambda")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("repr"),
          newIdentNode("result")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("treeRepr"),
          newIdentNode("result")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("aBug")
  )
)
1.6.20 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-09-02T21:15:02
  • Finished 2024-09-02T21:15:03
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    newIdentNode("macros")
  ),
  nnkProcDef.newTree(
    newIdentNode("map"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode(),
      nnkIdentDefs.newTree(
        newIdentNode("fn"),
        nnkProcTy.newTree(
          nnkFormalParams.newTree(
            newIdentNode("void"),
            nnkIdentDefs.newTree(
              newIdentNode("val"),
              newIdentNode("int"),
              newEmptyNode()
            )
          ),
          newEmptyNode()
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkCall.newTree(
        newIdentNode("fn"),
        newLit(1)
      )
    )
  ),
  nnkCommand.newTree(
    newIdentNode("map"),
    nnkLambda.newTree(
      newEmptyNode(),
      newEmptyNode(),
      newEmptyNode(),
      nnkFormalParams.newTree(
        newIdentNode("void"),
        nnkIdentDefs.newTree(
          newIdentNode("val"),
          newIdentNode("auto"),
          newEmptyNode()
        )
      ),
      newEmptyNode(),
      newEmptyNode(),
      nnkStmtList.newTree(
        nnkLetSection.newTree(
          nnkIdentDefs.newTree(
            newIdentNode("variable"),
            newEmptyNode(),
            newLit(123)
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    newIdentNode("aBug"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("sym"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("genSym"),
            newIdentNode("nskLet"),
            newLit("variable")
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("letStmt"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newLetStmt"),
            newIdentNode("sym"),
            nnkCall.newTree(
              newIdentNode("newLit"),
              newLit(123)
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("lambda"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newProc"),
            nnkExprEqExpr.newTree(
              newIdentNode("params"),
              nnkPrefix.newTree(
                newIdentNode("@"),
                nnkBracket.newTree(
                  nnkCall.newTree(
                    newIdentNode("ident"),
                    newLit("void")
                  ),
                  nnkCall.newTree(
                    newIdentNode("newIdentDefs"),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("val")
                    ),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("auto")
                    )
                  )
                )
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("body"),
              nnkCall.newTree(
                newIdentNode("newStmtList"),
                newIdentNode("letStmt")
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("procType"),
              newIdentNode("nnkLambda")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newCall"),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            newLit("map")
          ),
          newIdentNode("lambda")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("repr"),
          newIdentNode("result")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("treeRepr"),
          newIdentNode("result")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("aBug")
  )
)
1.4.8 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-09-02T21:15:05
  • Finished 2024-09-02T21:15:05
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    newIdentNode("macros")
  ),
  nnkProcDef.newTree(
    newIdentNode("map"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode(),
      nnkIdentDefs.newTree(
        newIdentNode("fn"),
        nnkProcTy.newTree(
          nnkFormalParams.newTree(
            newIdentNode("void"),
            nnkIdentDefs.newTree(
              newIdentNode("val"),
              newIdentNode("int"),
              newEmptyNode()
            )
          ),
          newEmptyNode()
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkCall.newTree(
        newIdentNode("fn"),
        newLit(1)
      )
    )
  ),
  nnkCommand.newTree(
    newIdentNode("map"),
    nnkLambda.newTree(
      newEmptyNode(),
      newEmptyNode(),
      newEmptyNode(),
      nnkFormalParams.newTree(
        newIdentNode("void"),
        nnkIdentDefs.newTree(
          newIdentNode("val"),
          newIdentNode("auto"),
          newEmptyNode()
        )
      ),
      newEmptyNode(),
      newEmptyNode(),
      nnkStmtList.newTree(
        nnkLetSection.newTree(
          nnkIdentDefs.newTree(
            newIdentNode("variable"),
            newEmptyNode(),
            newLit(123)
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    newIdentNode("aBug"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("sym"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("genSym"),
            newIdentNode("nskLet"),
            newLit("variable")
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("letStmt"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newLetStmt"),
            newIdentNode("sym"),
            nnkCall.newTree(
              newIdentNode("newLit"),
              newLit(123)
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("lambda"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newProc"),
            nnkExprEqExpr.newTree(
              newIdentNode("params"),
              nnkPrefix.newTree(
                newIdentNode("@"),
                nnkBracket.newTree(
                  nnkCall.newTree(
                    newIdentNode("ident"),
                    newLit("void")
                  ),
                  nnkCall.newTree(
                    newIdentNode("newIdentDefs"),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("val")
                    ),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("auto")
                    )
                  )
                )
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("body"),
              nnkCall.newTree(
                newIdentNode("newStmtList"),
                newIdentNode("letStmt")
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("procType"),
              newIdentNode("nnkLambda")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newCall"),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            newLit("map")
          ),
          newIdentNode("lambda")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("repr"),
          newIdentNode("result")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("treeRepr"),
          newIdentNode("result")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("aBug")
  )
)
1.2.18 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-09-02T21:15:08
  • Finished 2024-09-02T21:15:08
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    newIdentNode("macros")
  ),
  nnkProcDef.newTree(
    newIdentNode("map"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode(),
      nnkIdentDefs.newTree(
        newIdentNode("fn"),
        nnkProcTy.newTree(
          nnkFormalParams.newTree(
            newIdentNode("void"),
            nnkIdentDefs.newTree(
              newIdentNode("val"),
              newIdentNode("int"),
              newEmptyNode()
            )
          ),
          newEmptyNode()
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkCall.newTree(
        newIdentNode("fn"),
        newLit(1)
      )
    )
  ),
  nnkCommand.newTree(
    newIdentNode("map"),
    nnkLambda.newTree(
      newEmptyNode(),
      newEmptyNode(),
      newEmptyNode(),
      nnkFormalParams.newTree(
        newIdentNode("void"),
        nnkIdentDefs.newTree(
          newIdentNode("val"),
          newIdentNode("auto"),
          newEmptyNode()
        )
      ),
      newEmptyNode(),
      newEmptyNode(),
      nnkStmtList.newTree(
        nnkLetSection.newTree(
          nnkIdentDefs.newTree(
            newIdentNode("variable"),
            newEmptyNode(),
            newLit(123)
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    newIdentNode("aBug"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("sym"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("genSym"),
            newIdentNode("nskLet"),
            newLit("variable")
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("letStmt"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newLetStmt"),
            newIdentNode("sym"),
            nnkCall.newTree(
              newIdentNode("newLit"),
              newLit(123)
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("lambda"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newProc"),
            nnkExprEqExpr.newTree(
              newIdentNode("params"),
              nnkPrefix.newTree(
                newIdentNode("@"),
                nnkBracket.newTree(
                  nnkCall.newTree(
                    newIdentNode("ident"),
                    newLit("void")
                  ),
                  nnkCall.newTree(
                    newIdentNode("newIdentDefs"),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("val")
                    ),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("auto")
                    )
                  )
                )
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("body"),
              nnkCall.newTree(
                newIdentNode("newStmtList"),
                newIdentNode("letStmt")
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("procType"),
              newIdentNode("nnkLambda")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newCall"),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            newLit("map")
          ),
          newIdentNode("lambda")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("repr"),
          newIdentNode("result")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("treeRepr"),
          newIdentNode("result")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("aBug")
  )
)
1.0.10 👎 FAIL

Output


IR

Compiled filesize 0 (0 bytes)

Stats

  • Started 2024-09-02T21:15:11
  • Finished 2024-09-02T21:15:11
  • Duration

AST

nnkStmtList.newTree(
  nnkImportStmt.newTree(
    newIdentNode("macros")
  ),
  nnkProcDef.newTree(
    newIdentNode("map"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode(),
      nnkIdentDefs.newTree(
        newIdentNode("fn"),
        nnkProcTy.newTree(
          nnkFormalParams.newTree(
            newIdentNode("void"),
            nnkIdentDefs.newTree(
              newIdentNode("val"),
              newIdentNode("int"),
              newEmptyNode()
            )
          ),
          newEmptyNode()
        ),
        newEmptyNode()
      )
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkCall.newTree(
        newIdentNode("fn"),
        newLit(1)
      )
    )
  ),
  nnkCommand.newTree(
    newIdentNode("map"),
    nnkLambda.newTree(
      newEmptyNode(),
      newEmptyNode(),
      newEmptyNode(),
      nnkFormalParams.newTree(
        newIdentNode("void"),
        nnkIdentDefs.newTree(
          newIdentNode("val"),
          newIdentNode("auto"),
          newEmptyNode()
        )
      ),
      newEmptyNode(),
      newEmptyNode(),
      nnkStmtList.newTree(
        nnkLetSection.newTree(
          nnkIdentDefs.newTree(
            newIdentNode("variable"),
            newEmptyNode(),
            newLit(123)
          )
        )
      )
    )
  ),
  nnkMacroDef.newTree(
    newIdentNode("aBug"),
    newEmptyNode(),
    newEmptyNode(),
    nnkFormalParams.newTree(
      newEmptyNode()
    ),
    newEmptyNode(),
    newEmptyNode(),
    nnkStmtList.newTree(
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("sym"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("genSym"),
            newIdentNode("nskLet"),
            newLit("variable")
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("letStmt"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newLetStmt"),
            newIdentNode("sym"),
            nnkCall.newTree(
              newIdentNode("newLit"),
              newLit(123)
            )
          )
        )
      ),
      nnkLetSection.newTree(
        nnkIdentDefs.newTree(
          newIdentNode("lambda"),
          newEmptyNode(),
          nnkCall.newTree(
            newIdentNode("newProc"),
            nnkExprEqExpr.newTree(
              newIdentNode("params"),
              nnkPrefix.newTree(
                newIdentNode("@"),
                nnkBracket.newTree(
                  nnkCall.newTree(
                    newIdentNode("ident"),
                    newLit("void")
                  ),
                  nnkCall.newTree(
                    newIdentNode("newIdentDefs"),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("val")
                    ),
                    nnkCall.newTree(
                      newIdentNode("ident"),
                      newLit("auto")
                    )
                  )
                )
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("body"),
              nnkCall.newTree(
                newIdentNode("newStmtList"),
                newIdentNode("letStmt")
              )
            ),
            nnkExprEqExpr.newTree(
              newIdentNode("procType"),
              newIdentNode("nnkLambda")
            )
          )
        )
      ),
      nnkAsgn.newTree(
        newIdentNode("result"),
        nnkCall.newTree(
          newIdentNode("newCall"),
          nnkCall.newTree(
            newIdentNode("bindSym"),
            newLit("map")
          ),
          newIdentNode("lambda")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("repr"),
          newIdentNode("result")
        )
      ),
      nnkCommand.newTree(
        newIdentNode("echo"),
        nnkCommand.newTree(
          newIdentNode("treeRepr"),
          newIdentNode("result")
        )
      )
    )
  ),
  nnkCall.newTree(
    newIdentNode("aBug")
  )
)
Stats
  • GCC 11.4.0
  • Clang 14.0.0
  • NodeJS 20.4
  • Created 2024-09-02T21:14:23Z
  • Comments 1
  • Commands nim c --run -d:nimDebug -d:nimDebugDlOpen -d:ssl -d:nimDisableCertificateValidation --forceBuild:on --colors:off --verbosity:0 --hints:off --lineTrace:off --nimcache:/home/runner/work/Nim/Nim --out:/home/runner/work/Nim/Nim/temp /home/runner/work/Nim/Nim/temp.nim

🤖 Bug found in 22 mins bisecting 8 commits at 0 commits per second

metagn added a commit to metagn/Nim that referenced this issue Sep 2, 2024
Araq pushed a commit that referenced this issue Sep 3, 2024
fixes #24048

Generic lambdas get instantiated via `replaceTypesInBody` which calls
`replaceTypeVarsN` on the body of the lambda. This body can contain sym
nodes of gensym symbols generated by macros, which have `nil` type. But
a piece of code in `replaceTypeVarsN` checks whether the type of a
symbol is equal to `void` without checking if it's `nil` first, which
causes a segfault. Now it also checks that the type of the symbol isn't
`nil` for it to be `void`.
@johanobergman
Copy link
Author

That was quick - thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants