(rule *CompiledRule, iss *cel.Issues)
| 466 | } |
| 467 | |
| 468 | func (c *compiler) checkUnreachableCode(rule *CompiledRule, iss *cel.Issues) { |
| 469 | compiledMatches := rule.Matches() |
| 470 | matchCount := len(compiledMatches) |
| 471 | for i := matchCount - 1; i >= 0; i-- { |
| 472 | m := compiledMatches[i] |
| 473 | triviallyTrue := m.ConditionIsLiteral(types.True) |
| 474 | |
| 475 | if m.ConditionIsLiteral(types.False) { |
| 476 | iss.ReportErrorAtID(m.SourceID(), "Condition is always false") |
| 477 | } |
| 478 | |
| 479 | // If the match is a single output or a nested rule that always returns a value, it is |
| 480 | // exhaustive. If the condition is trivially true, then all subsequent branches are unreachable. |
| 481 | isExhaustive := triviallyTrue && (m.NestedRule() == nil || !m.NestedRule().HasOptionalOutput()) |
| 482 | if rule.semantic == firstMatch && isExhaustive && i != matchCount-1 { |
| 483 | if m.Output() != nil { |
| 484 | iss.ReportErrorAtID(m.SourceID(), "match creates unreachable outputs") |
| 485 | } |
| 486 | if m.NestedRule() != nil { |
| 487 | iss.ReportErrorAtID(m.NestedRule().SourceID(), "rule creates unreachable outputs") |
| 488 | } |
| 489 | break |
| 490 | } |
| 491 | } |
| 492 | } |
| 493 | |
| 494 | func (c *compiler) relSource(pstr ValueString) *RelativeSource { |
| 495 | line := 0 |
no test coverage detected