Skip to content

Elixir: def with when guard not translated to FuncDef in generic AST #602

@dimitris-m

Description

@dimitris-m

Summary

When an Elixir def has a when guard, the generic AST translation falls back to a raw Call("def", ...) instead of producing a DefStmt/FuncDef node. Clauses without guards are correctly translated.

Reproduction

defmodule Fibonacci do
  def fib(0) do
    0
  end

  def fib(1) do
    1
  end

  def fib(n) when n > 1 do
    fib(n - 1) + fib(n - 2)
  end
end
opengrep-core -lang elixir -dump_ast fibonacci.ex

Observed AST (simplified)

ModuleDef("Fibonacci",
  ModuleStruct([
    DefStmt("fib", FuncDef(params=[OtherParam(0)], body=0)),        # OK
    DefStmt("fib", FuncDef(params=[OtherParam(1)], body=1)),        # OK
    ExprStmt(Call("def", [When(fib(n), n > 1), ArgKwd("do", ...)]))  # wrong
  ]))

Clauses 1 and 2 (no guard) are properly translated to DefStmt/FuncDef. Clause 3 (with when guard) is left as a raw Call("def", ...) with the guard buried inside OtherExpr("When", ...).

Expected behaviour

All three clauses should produce DefStmt/FuncDef nodes regardless of whether a when guard is present. The guard should be represented within the FuncDef structure (e.g. as a precondition or conditional in the body).

Note

Guards on fn lambdas already work correctly for taint analysis — see tests/tainting_rules/elixir/taint-lambda.ex line 41 (fn x when sink(x) -> x end). The issue is specific to def/defp with guards.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinglangAdd or improve language support

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions