Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcc13.1 warning: possibly dangling reference to a temporary w/ostream operator #3415

Closed
mcharneyamp opened this issue May 1, 2023 · 5 comments

Comments

@mcharneyamp
Copy link

mcharneyamp commented May 1, 2023

Hi. Using current to of tree (02cae7e), I see this warning with aarch64 gcc 13.1 -Wall. On godbolt, I used "arm64 gcc trunk" to compile and got this error (They don't have an arm64 gcc 13.1 listed yet). Oddly, I don't see the error with x86-64 gcc13.1. No error with gcc 11.3 or 12.2 on aarch64.

/opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:1674:15: warning: possibly dangling reference to a temporary [-Wdangling-reference]
 1674 |   const auto& arg = arg_mapper<Context>().map(FMT_FORWARD(val));
      |               ^~~
/opt/compiler-explorer/libs/fmt/trunk/include/fmt/core.h:1674:46: note: the temporary was destroyed at the end of the full expression 'fmt::v9::detail::arg_mapper<fmt::v9::basic_format_context<fmt::v9::appender, char> >().fmt::v9::detail::arg_mapper<fmt::v9::basic_format_context<fmt::v9::appender, char> >::map<foo&>((* & val))'
 1674 |   const auto& arg = arg_mapper<Context>().map(FMT_FORWARD(val));
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
Compiler returned: 0

Here is a godbolt repro link:

https://godbolt.org/z/ajsGKe4nE

#include <cstdint>
#include <ostream>
#include <string>
#include <fmt/core.h>
#include <fmt/ranges.h>
#include <fmt/ostream.h>

class foo {
public:
    int a;
    std::string b;

    foo(int aa, std::string bb) : a(aa), b(bb) {}

    friend std::ostream& operator<< (std::ostream& os, const foo& obj);
};

template <> struct fmt::formatter<foo> : ostream_formatter {};
std::ostream& operator<< (std::ostream& os, const foo& obj) {
    os << obj.a << " " << obj.b;
    return os;
}



int main(int argc, char** argv) {
    foo f(5,"hello");
    fmt::print("{}\n", f);
}

@pattop
Copy link

pattop commented May 4, 2023

Also happens when a specialisation of fmt::formatter is added, e.g https://godbolt.org/z/r657Yhc9Y

enum class foo { a, b };

template<>
struct fmt::formatter<foo> {
	constexpr auto parse(fmt::format_parse_context &ctx)
	{
		return ctx.begin();
	}

	auto format(const foo &f, fmt::format_context &ctx)
	{
		switch (f) {
		case foo::a:
			return fmt::format_to(ctx.out(), "a");
		case foo::b:
			return fmt::format_to(ctx.out(), "b");
		default:
			return fmt::format_to(ctx.out(), "wtf");
		}
	}
};

int main(int argc, const char** argv) {
	fmt::print("{}\n", foo::a);
	return 0;
}

@vitaut
Copy link
Contributor

vitaut commented May 6, 2023

This is clearly a false positive because T is foo& and the chain of calls is

fmt/include/fmt/core.h

Lines 1453 to 1462 in 192df93

template <typename T, typename U = remove_cvref_t<T>,
FMT_ENABLE_IF((std::is_class<U>::value || std::is_enum<U>::value ||
std::is_union<U>::value) &&
!is_string<U>::value && !is_char<U>::value &&
!is_named_arg<U>::value &&
!std::is_arithmetic<format_as_t<U>>::value)>
FMT_CONSTEXPR FMT_INLINE auto map(T&& val)
-> decltype(this->do_map(std::forward<T>(val))) {
return do_map(std::forward<T>(val));
}

fmt/include/fmt/core.h

Lines 1444 to 1447 in 192df93

template <typename T, FMT_ENABLE_IF(formattable<T>::value)>
FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& {
return val;
}

which passes the reference through without any temporaries involved.

f61f15c implements a workaround but please report a bug to gcc.

@vitaut vitaut closed this as completed May 6, 2023
@sunmy2019
Copy link
Contributor

sunmy2019 commented May 6, 2023

GCC will temporarily move the warning to -Wextra
https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=6b927b1297e66e26e62e722bf15c921dcbbd25b9

Currently it's producing many false positives.

@vitaut
Copy link
Contributor

vitaut commented May 6, 2023

Thanks for the link!

@mcharneyamp
Copy link
Author

Thanks everyone!

jgalar added a commit to lttng/lttng-tools that referenced this issue Jun 6, 2023
gcc 13.1 erroneously warns of dangling references when using our custom
formatters. This was reported to both fmtlib and gcc and fixes have been
provided, but are not released yet.

This change backports two fixes from the master branch to our vendored
version:
fmtlib/fmt@f61f15c
fmtlib/fmt@ef55d4f

For more information on the issue, see:
fmtlib/fmt#3415
https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=6b927b1297e66e26e62e722bf15c921dcbbd25b9

Signed-off-by: Jérémie Galarneau <[email protected]>
Change-Id: I30bbbbe5e0aa2729e50228acdb528ee060d9df23
emmanuelthome added a commit to cado-nfs/cado-nfs that referenced this issue Jun 28, 2023
…m fmtlib trunk

/builds/cado-nfs/cado-nfs/utils/badideals.cpp:164:27:   required from here
/builds/cado-nfs/cado-nfs/utils/embedded/fmt/core.h:1735:15: error: possibly dangling reference to a temporary [-Werror=dangling-reference]
 1735 |   const auto& arg = arg_mapper<Context>().map(FMT_FORWARD(val));
      |               ^~~
/builds/cado-nfs/cado-nfs/utils/embedded/fmt/core.h:1735:46: note: the temporary was destroyed at the end of the full expression 'fmt::v9::detail::arg_mapper<fmt::v9::basic_format_context<fmt::v9::appender, char> >().fmt::v9::detail::arg_mapper<fmt::v9::basic_format_context<fmt::v9::appender, char> >::map<cxx_mpz&>((* & val))'
 1735 |   const auto& arg = arg_mapper<Context>().map(FMT_FORWARD(val));
      |                     ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~

This is the same as fmtlib/fmt#3415
ibmibmibm added a commit to WasmEdge/WasmEdge that referenced this issue Nov 3, 2023
ibmibmibm added a commit to WasmEdge/WasmEdge that referenced this issue Nov 3, 2023
ibmibmibm added a commit to WasmEdge/WasmEdge that referenced this issue Nov 3, 2023
ibmibmibm added a commit to WasmEdge/WasmEdge that referenced this issue Nov 3, 2023
hydai pushed a commit to WasmEdge/WasmEdge that referenced this issue Nov 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants