#16945·solidity

Only the first duplicate-definition group is reported per name: `reported.count(i)` is in the loop condition instead of the body

Author: Lokkw0510Created Aug 26, 2026Updated Sep 10, 2026
Labelsbug :bug:low impact

Description

When one name has more than one group of duplicate definitions, only the first group is reported. The remaining duplicates are silently dropped from the diagnostics.

libsolidity/analysis/ContractLevelChecker.cpp:239, in findDuplicateDefinitions<T>:

cpp
for (size_t i = 0; i < overloads.size() && !reported.count(i); ++i)

reported holds the indices already covered by an earlier error (populated at :260). The test for it sits in the loop condition, so reaching an already-reported index terminates the entire loop rather than skipping that one index and continuing.

The bookkeeping itself suggests this isn't intended: if the goal were "stop after the first report", a bool would be enough. Maintaining a std::set<size_t> of indices only makes sense if those indices are meant to be skipped when they come round as i — i.e. this looks like a continue written as a loop exit.

Expected: one error per duplicate group.

Actual: one error total, per name.

This is a diagnostics-completeness issue rather than a soundness one, and I'd suggest triaging it as such. Index 0 can never be in reported, so the first group always reports and a contract containing duplicates always fails to compile — nothing invalid is accepted. The cost is that a developer fixes one duplicate, recompiles, and discovers the next.

Environment

  • Compiler version: 0.8.36+commit.8a079791 (source byte-identical on current develop; the line dates to d054a3b85, 2018-11-29, which moved it in already written this way)
  • Compilation pipeline (legacy, IR, SSA CFG): all — this is in the analysis phase, before codegen
  • Target EVM version (as per compiler settings): default (osaka); not EVM-version dependent
  • Framework/IDE (e.g. Foundry, Hardhat, Remix): solc command line directly
  • EVM execution environment / backend / blockchain client: n/a — compile-time only
  • Operating system: macOS 26.5.2

Steps to Reproduce

poc.sol — one name, two independent duplicate groups:

solidity
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

contract C {
    function f(uint) public {}
    function f(uint) public {}
    function f(string memory) public {}
    function f(string memory) public {}
}
solc poc.sol

Expected: two errors — f(uint) is defined twice and f(string) is defined twice, at separate source locations.

Actual: one error.

Error: Function with same name and parameter types defined twice.

Control — identical duplicate structure under two different names reports both, because each name gets its own overloads vector:

solidity
contract C {
    function f(uint) public {}
    function f(uint) public {}
    function g(string memory) public {}
    function g(string memory) public {}
}
Error: Function with same name and parameter types defined twice.
Error: Function with same name and parameter types defined twice.

Extent:

source errors emitted expected
one name, 2 duplicate groups 1 2
one name, 3 duplicate groups 1 3
two names, 1 group each (control) 2 2
one name, 1 group (control) 1 1
events, one name, 2 groups 1 2

The last row reaches EventDefinition (error 5883), since findDuplicateDefinitions is a template used by both checkDuplicateFunctions (:188) and checkDuplicateEvents (:200).