Open
Description
Title: fix(reflect): recognize default constructor overload in @basic_value
.
Description:
Now that we have default function arguments,
it's possible for a default constructor
to overload with a constructor with default arguments.
Minimal reproducer (https://cpp2.godbolt.org/z/jrs6YYbab):
lineno_t: type == std::int32_t;
colno_t: type == std::int32_t; // not int16_t... encountered >80,000 char line during testing
index_t: type == std::int32_t;
source_position: @value type =
{
public lineno: lineno_t = 1; // one-based offset into program source
public colno: colno_t = 1; // one-based offset into line
operator=: (implicit out this, l: lineno_t = 1, c: colno_t = 1) =
{
lineno = l;
colno = c;
}
to_string: (this) -> std::string = "((lineno)$,(colno)$)";
}
main: () = {
_ = :source_position = ();
}
Commands:
cppfront main.cpp2
clang++-18 -std=c++26 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -Werror=unused-value -Werror=unused-parameter -Werror=unused-variable -I . main.cpp
Expected result: The default constructor not to be overloaded.
Actual result and error:
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
class source_position;
//=== Cpp2 type definitions and function declarations ===========================
using lineno_t = std::int32_t;
using colno_t = std::int32_t; // not int16_t... encountered >80,000 char line during testing
using index_t = std::int32_t;
class source_position
{
public: lineno_t lineno {1}; // one-based offset into program source
public: colno_t colno {1}; // one-based offset into line
public: source_position(cpp2::impl::in<lineno_t> l = 1, cpp2::impl::in<colno_t> c = 1);
public: [[nodiscard]] auto to_string() const& -> std::string;
public: [[nodiscard]] auto operator<=>(source_position const& that) const& -> std::strong_ordering = default;
public: source_position(source_position const& that);
public: auto operator=(source_position const& that) -> source_position& ;
public: source_position(source_position&& that) noexcept;
public: auto operator=(source_position&& that) noexcept -> source_position& ;
public: explicit source_position();
};
auto main() -> int;
//=== Cpp2 function definitions =================================================
source_position::source_position(cpp2::impl::in<lineno_t> l, cpp2::impl::in<colno_t> c)
: lineno{ l }
, colno{ c }
{
}
[[nodiscard]] auto source_position::to_string() const& -> std::string { return "(" + cpp2::to_string(lineno) + "," + cpp2::to_string(colno) + ")"; }
source_position::source_position(source_position const& that)
: lineno{ that.lineno }
, colno{ that.colno }{}
auto source_position::operator=(source_position const& that) -> source_position& {
lineno = that.lineno;
colno = that.colno;
return *this;}
source_position::source_position(source_position&& that) noexcept
: lineno{ std::move(that).lineno }
, colno{ std::move(that).colno }{}
auto source_position::operator=(source_position&& that) noexcept -> source_position& {
lineno = std::move(that).lineno;
colno = std::move(that).colno;
return *this;}
source_position::source_position(){}
auto main() -> int{
static_cast<void>(source_position{});
}
main.cpp2:18:21: error: call to constructor of 'source_position' is ambiguous
18 | static_cast<void>(source_position{});
| ^ ~~
main.cpp2:9:22: note: candidate constructor
9 | source_position::source_position(cpp2::impl::in<lineno_t> l, cpp2::impl::in<colno_t> c)
| ^
main.cpp2:33:18: note: candidate constructor
33 | source_position::source_position(){}
| ^
1 error generated.
See also:
- Commit 873b760.