https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115987
--- Comment #19 from Dan Urosu <durosu at yahoo dot com> --- (In reply to Marek Polacek from comment #18) > But is unwrap_1 called in such a way that 'r' binds to a temporary? Did you mean 'u' binds to a temporary? In this case r1 is a temporary object and a reference to its inner value is returned by the function. The warning might have not been intended for this case, but all I'm saying is that this example shows a very common case of a dangling reference. (and is not flagged) full code ---- #include <iostream> #include <optional> // Compile: gcc -std=c++17 -Wall -Wextra -Werror -lstdc++ main_unwrap.cpp -o main_unwrap /** 'unwrap_1' and 'unwrap_2' are functionally identical. By introducing an additional template parameter, the code fails to compile, when unwrap_2 is used. The code should not give errors because the lifetime of the returned reference is tied to the lifetime of the 'wrapper' object. */ template <typename T> struct Wrapper { const T& value() const { return val.value(); } T& value() { return val.value(); } std::optional<T> val; }; template <typename T> const T& unwrap_1(const Wrapper<T>& r) { Wrapper<T> r1(r); // << TEMPORARY return r1.value(); // << TEMPORARY } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdangling-reference" template <typename T, typename FUNC> const T& unwrap_2(const Wrapper<T>& r, FUNC&&) { // note FUNC is not even used return r.value(); } #define UNWRAP_2(x, y) unwrap_2(x, y) #pragma GCC diagnostic pop #define WITH_FUNC_PARAM_ int main(int, char**) { const Wrapper<int> w{1234}; #ifndef WITH_FUNC_PARAM const auto& u = unwrap_1(w); // <<<<< here #else const auto& u = UNWRAP_2(w, 1); // This fails with error: possibly dangling reference to a temporary [-Werror=dangling-reference] #endif printf("Unwrapped value : %d\n", u); return 0; }