On Tue, Oct 15, 2019 at 01:17:17PM -0400, Marek Polacek wrote:
> 2019-10-15 Marek Polacek <[email protected]>
>
> PR c++/92106 - ICE with structured bindings and -Wreturn-local-addr.
> * typeck.c (maybe_warn_about_returning_address_of_local): Avoid
> recursing on null initializer.
>
> * g++.dg/cpp1z/decomp50.C: New test.
>
> diff --git gcc/cp/typeck.c gcc/cp/typeck.c
> index 141d86f50c9..1825540016f 100644
> --- gcc/cp/typeck.c
> +++ gcc/cp/typeck.c
> @@ -9354,10 +9354,8 @@ maybe_warn_about_returning_address_of_local (tree
> retval)
> binding. */
> tree base = DECL_DECOMP_BASE (whats_returned);
> if (TYPE_REF_P (TREE_TYPE (base)))
> - {
> - tree init = DECL_INITIAL (base);
> + if (tree init = DECL_INITIAL (base))
> return maybe_warn_about_returning_address_of_local (init);
> - }
Actually, seeing the dg-warning in the testcase, I think we shouldn't warn,
for range-for it is just too hard to find out if it will be returning
address of a local or not. &value in itself is not address of a local
variable when the structured binding is a reference.
Well, in the testcase as is it actually is (perhaps just in the reduced
one and not original):
const struct J & D.2293;
const int name [value-expr: D.2293->name];
const int value [value-expr: D.2293->value];
...
struct reference D.2352;
try
{
D.2352 = D<A::J*, int>::operator* (&__for_begin);
D.2293 = &D.2352;
but a small change to the testcase:
template <typename _Iterator, typename> class D {
public:
- typename B<_Iterator>::reference operator*();
+ typename B<_Iterator>::reference &operator*();
void operator++();
};
results in D.2293 = D<A::J*, int>::operator* (&__for_begin);
and then it might very well not be address of a local variable.
This isn't just about a false positive warning, when
maybe_warn_about_returning_address_of_local returns true, then
we actually return NULL pointer instead of the value user wanted.
So, I think you want to add and do else return false;
if init is NULL.
> + for (const auto &[name, value] : members)
> + return &value; // { dg-warning "address of local variable" }
> + return nullptr;
> + }
> +};
> +int main() {
> + A a;
> + a.find("");
> +}
Jakub