https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115987

--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Firstly, you're reporting a false positive warning, so using -Werror just
confuses things. Some warnings have false positives, that's unavoidable. But it
only fails to compile because you used -Werror. Don't use -Werror if you don't
like the warnings being errors, or use -Wno-error=dangling-reference so it's
just a warning not an error. GCC turning wanrings into errors when you ask it
to do that is not a bug.

(In reply to Dan Urosu from comment #2)
> I cannot use "#pragma GCC diagnostic ignored" because we have thousands of
> call sites where we plan to use this kind of code.

You don't need to use it at the call site:

#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();
}
#pragma GCC diagnostic pop


> And we don't want to disable globally this warning either.
> 
> Would "no_dangling (with GCC 14+) " disable globally this check as well?

No, only for calls to a function that uses the attribute:

template <typename T, typename FUNC>
    [[gnu::no_dangling]]
    const T& unwrap_2(const Wrapper<T>& r, FUNC&&) { // note FUNC is not even
used
  return r.value();
}

(In reply to Dan Urosu from comment #3)
> The 109642 is not a duplicate of the attached code.
> The error is the same but the code that causes it is completely different.

Andrew already said it's not an exact duplicate, but he's right that this is
another case of a -Wdangling-reference false positive that can be suppressed
the same way.

> Also, the "solution" to disable the warning/error is not actually resolving
> the issue but merely hiding it.

What's the difference between hiding a warning and stopping a false positive
warning from being emitted? You want the warning to go away, right?

The suggested solution is not just to disable the warning, but to decorate the
unwrap_2 function to tell the compiler not to warn there. That's not the same
as -Wno-dangling-reference globally.

The warning for your original example seems reasonable, the function is called
with a temporary of type int (binding to the FUN&& parameter) and returns a
const int&, which certainly could be a dangling reference.

But I don't understand why it warns for this version:

template <typename T>
struct Wrapper {
    T val;
};

template <typename T, typename FUNC>
    const T& unwrap_2(const Wrapper<T>& r, FUNC&&) {
  return r.val;
}

int main(int, char**) {
  const Wrapper<int> w{1234};
  const auto& u = unwrap_2(w, 1L);
  __builtin_printf("Unwrapped value : %d\n", u);
}

Here we have a temporary of type long, so the return const int& can't bind to
that.

Reply via email to