-Wunused-private-field distracted by side effects

BaseAndFieldInfo::addFieldInitializer (lib/Sema/SemaDeclCXX.cpp) contains

    // Check whether this initializer makes the field "used".
    if (Init->getInit()->HasSideEffects(S.Context))
      S.UnusedPrivateFields.remove(Init->getAnyMember());

which filters out of the list of unused private member variables those with initializers that potentially incur side effects. That is, in

int f();
class C {
    int i, j;
public:
    C(): i(f()), j(1) {}
};

clang++ -Wall will emit a -Wunused-private-field for j but not for i.

Is that behavior intended? (Member variables of class type, where the constructor itself may have side effects, are already exempted from the UnusedPrivateFields list via the InitializationHasSideEffects() check elsewhere in lib/Sema/SemaDeclCXX.cpp.)

Of course, such a warning cannot in general be addressed by naively removing the member variable along with any initializers, but that is no different to e.g. -Wunused-variable, which does get emitted for

int f();
void g() {
    int i(f());
}

One arcane legitimate reason to not emit a -Wunused-private-field could be a case where f() needs to be called for side effects between construction of two other members, as in

int f();
struct S1 { /*...*/ };
struct S2 { /*...*/ };
class C {
    S1 s1;
    int dummy;
    S2 s2;
public:
    C(): s1(), dummy(f()), s2() {}
};

but that could arguably be required to use a __attribute__((unused)).

Stephan

BaseAndFieldInfo::addFieldInitializer (lib/Sema/SemaDeclCXX.cpp) contains

     // Check whether this initializer makes the field "used".

    if (Init->getInit()->HasSideEffects(S.Context))
      S.UnusedPrivateFields.remove(Init->getAnyMember());

which filters out of the list of unused private member variables those
with initializers that potentially incur side effects. That is, in

int f();

class C {
    int i, j;
public:
    C(): i(f()), j(1) {}
};

clang++ -Wall will emit a -Wunused-private-field for j but not for i.

Is that behavior intended? (Member variables of class type, where the
constructor itself may have side effects, are already exempted from the
UnusedPrivateFields list via the InitializationHasSideEffects() check
elsewhere in lib/Sema/SemaDeclCXX.cpp.)

Of course, such a warning cannot in general be addressed by naively
removing the member variable along with any initializers, but that is no
different to e.g. -Wunused-variable, which does get emitted for

int f();

void g() {
    int i(f());
}

One arcane legitimate reason to not emit a -Wunused-private-field could be
a case where f() needs to be called for side effects between construction
of two other members, as in

int f();

struct S1 { /*...*/ };
struct S2 { /*...*/ };
class C {
    S1 s1;
    int dummy;
    S2 s2;
public:
    C(): s1(), dummy(f()), s2() {}

This could still be achieved assuming s2 was at least move constructible:

s2({f(); return S2(); }());

};

but that could arguably be required to use a __attribute__((unused)).

But that seems not unreasonable as well.