Skip to content

Commit

Permalink
fix(cpp1): emit correct UFCS in function signature
Browse files Browse the repository at this point in the history
  • Loading branch information
JohelEGP committed Aug 7, 2023
1 parent 7bad57e commit eb1dd68
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 32 deletions.
25 changes: 25 additions & 0 deletions regression-tests/mixed-bugfix-for-ufcs-non-local.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
template<bool> struct t { };
constexpr bool f(const t<true>&) { return true; }
constexpr t<true> o{};

// Variables.

// _: <V: t<o.f()>> bool = (); // Blocked on #389, [GCC109781][].

_: t<o.f()> = ();

_: bool = o.f();

// Functions.

// g: <V: t<o.f()>> () = { } // Blocked on [GCC109781][].

g: (x: t<o.f()>) = { }

g: () [[pre: o.f()]] = { }

h: () -> t<o.f()> = o;

main: () = { }

// [GCC109781]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109781
4 changes: 0 additions & 4 deletions regression-tests/mixed-bugfix-for-ufcs-sfinae.cpp2

This file was deleted.

5 changes: 5 additions & 0 deletions regression-tests/pure2-bugfix-for-ufcs-sfinae.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
f: <T> () -> std::type_identity_t<decltype(T().a())> = { }
B: type = { }
main: () = {
static_assert(!std::invocable<decltype(:<T> (x: T) -> std::void_t<decltype(f<T>())> = {}), B>);
}
Empty file.
Empty file.
59 changes: 59 additions & 0 deletions regression-tests/test-results/mixed-bugfix-for-ufcs-non-local.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@


//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"



//=== Cpp2 type definitions and function declarations ===========================

template<bool> struct t { };
constexpr bool f(const t<true>&) { return true; }
constexpr t<true> o{};

// Variables.

// _: <V: t<o.f()>> bool = (); // Blocked on #389, [GCC109781][].

#line 9 "mixed-bugfix-for-ufcs-non-local.cpp2"
extern t<CPP2_UFCS(,,(f),(o),())> auto_9_1;

extern bool auto_11_1;

// Functions.

// g: <V: t<o.f()>> () = { } // Blocked on [GCC109781][].

auto g(cpp2::in<t<CPP2_UFCS(,,(f),(o),())>> x) -> void;

auto g() -> void;

[[nodiscard]] auto h() -> t<CPP2_UFCS(,,(f),(o),())>;

auto main() -> int;

// [GCC109781]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109781


//=== Cpp2 function definitions =================================================


#line 9 "mixed-bugfix-for-ufcs-non-local.cpp2"
t<CPP2_UFCS(,,(f),(o),())> auto_9_1 {};

bool auto_11_1 {CPP2_UFCS(,,(f),(o),())};

#line 17 "mixed-bugfix-for-ufcs-non-local.cpp2"
auto g(cpp2::in<t<CPP2_UFCS(,,(f),(o),())>> x) -> void{}

auto g() -> void{
cpp2::Default.expects(CPP2_UFCS(&,,(f),(o),()), "");
#line 19 "mixed-bugfix-for-ufcs-non-local.cpp2"
}

[[nodiscard]] auto h() -> t<CPP2_UFCS(,,(f),(o),())> { return o; }

auto main() -> int{}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mixed-bugfix-for-ufcs-non-local.cpp2... ok (mixed Cpp1/Cpp2, Cpp2 code passes safety checks)

24 changes: 0 additions & 24 deletions regression-tests/test-results/mixed-bugfix-for-ufcs-sfinae.cpp

This file was deleted.

This file was deleted.

36 changes: 36 additions & 0 deletions regression-tests/test-results/pure2-bugfix-for-ufcs-sfinae.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@

#define CPP2_USE_MODULES Yes

//=== Cpp2 type declarations ====================================================


#include "cpp2util.h"


#line 2 "pure2-bugfix-for-ufcs-sfinae.cpp2"
class B;


//=== Cpp2 type definitions and function declarations ===========================

#line 1 "pure2-bugfix-for-ufcs-sfinae.cpp2"
template<typename T> [[nodiscard]] auto f() -> std::type_identity_t<decltype(CPP2_UFCS(,,(a),(T()),()))>;
class B {
public: B() = default;
public: B(B const&) = delete; /* No 'that' constructor, suppress copy */
public: auto operator=(B const&) -> void = delete;

#line 2 "pure2-bugfix-for-ufcs-sfinae.cpp2"
};
auto main() -> int;


//=== Cpp2 function definitions =================================================

#line 1 "pure2-bugfix-for-ufcs-sfinae.cpp2"
template<typename T> [[nodiscard]] auto f() -> std::type_identity_t<decltype(CPP2_UFCS(,,(a),(T()),()))>{}

auto main() -> int {
static_assert(!(std::invocable<decltype([]<typename T>(T const& x) -> std::void_t<decltype(f<T>())>{}),B>));
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pure2-bugfix-for-ufcs-sfinae.cpp2... ok (all Cpp2, passes safety checks)

21 changes: 19 additions & 2 deletions source/cppfront.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,8 @@ class cppfront
bool violates_initialization_safety = false;
bool suppress_move_from_last_use = false;

declaration_node const* having_signature_emitted = {};

declaration_node const* generating_assignment_from = {};
declaration_node const* generating_move_from = {};
bool emitting_that_function = false;
Expand Down Expand Up @@ -2946,7 +2948,13 @@ class cppfront
if (
current_declarations.back()->is_namespace()
|| (
current_declarations.back()->is_object()
(
current_declarations.back()->is_object()
|| (
current_declarations.back()->is_function()
&& current_declarations.back() == having_signature_emitted
)
)
&& current_declarations.back()->parent_is_namespace()
)
)
Expand Down Expand Up @@ -4829,6 +4837,13 @@ class cppfront
printer.print_extra("\n");
}

auto stack_value = []<typename T>(T& var, std::type_identity_t<T> const& value) {
return finally([&var, old = std::exchange(var, value)]() {
var = old;
});
};
auto stack = stack_value(having_signature_emitted, &n);

// Handle aliases

if (n.is_alias())
Expand Down Expand Up @@ -5613,7 +5628,8 @@ class cppfront
function_returns.emplace_back(nullptr); // no return type at all
}

for (auto&& c : func->contracts)
for (auto stack = stack_value(having_signature_emitted, nullptr);
auto&& c : func->contracts)
{
auto print = std::string();
printer.emit_to_string(&print);
Expand Down Expand Up @@ -5680,6 +5696,7 @@ class cppfront

emit_requires_clause();

having_signature_emitted = nullptr;
emit(
*n.initializer,
true, func->position(), func->returns.index() == function_type_node::empty,
Expand Down

0 comments on commit eb1dd68

Please sign in to comment.