Open
Description
Title: in
parameter optimization should be less observable.
Description:
Some in
parameters are optimized to pass-by-value.
This can result in code that inadvertently depends on the optimization or lack thereof.
Minimal reproducer (https://cpp2.godbolt.org/z/nWKea3xGx):
#include <array>
f: (x: std::array<int, 42>) -> _ = x&;
f: (x: int) -> _ = x&;
main: () = {
(arr := std::array<int, 42>())
[[assert: f(arr) == arr&]]
(i := 42)
[[assert: f(i) != i&]]
}
Commands:
cppfront main.cpp2
clang++17 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cpp
Expected result:
More consistent results between the operations done on in
parameters regardless of optimization.
This overload f
has different semantics for optimized and non-optimized in
parameters.
The overload could be called address
,
in which case it's very obviously wrong for int
,
but very much passes for std::array<int, 42>
in today's Cppfront,
even though the meaning could change for a lower number of elements.
Actual result and error:
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
//=== Cpp2 type definitions and function declarations ===========================
#include <array>
[[nodiscard]] auto f(cpp2::in<std::array<int,42>> x) -> auto;
[[nodiscard]] auto f(cpp2::in<int> x) -> auto;
auto main() -> int;
//=== Cpp2 function definitions =================================================
[[nodiscard]] auto f(cpp2::in<std::array<int,42>> x) -> auto { return &x; }
[[nodiscard]] auto f(cpp2::in<int> x) -> auto { return &x; }
auto main() -> int{
{
auto const& arr = std::array<int,42>();
cpp2::Default.expects(f(arr) == &arr, "");
}
{
auto const& i = 42;
cpp2::Default.expects(f(i) != &i, "");
}
}
main.cpp2:3:57: warning: address of stack memory associated with parameter 'x' returned [-Wreturn-stack-address]
3 | [[nodiscard]] auto f(cpp2::in<int> x) -> auto { return &x; }
| ^
1 warning generated.