This is an archive of the discontinued LLVM Phabricator instance.

[ObjC] warn about availability attributes missing from a method's declaration when they're specified for a method's definition
Needs RevisionPublic

Authored by arphaman on Nov 10 2017, 11:31 AM.

Details

Summary

This patch extends the -Wavailability warning to warn about cases where a method declaration is missing an availability attribute clause that's present in the method's definition. We also warn about missing deprecated attributes as well.

rdar://15540962

Diff Detail

Repository
rL LLVM

Event Timeline

arphaman created this revision.Nov 10 2017, 11:31 AM

Any thoughts on having this for regular functions and C++ member functions? Seems just as useful there.

include/clang/Sema/Sema.h
2406

Looks longer than 80 chars!

lib/Sema/SemaDeclAttr.cpp
2300

I hate to rewrite your function, but have you considered just doing the second loop over the attrs inline instead of hidden in the lambda? I think it would make the function more simple to avoid all the lambdas and callbacks:

for (auto *A : Implementation->specific_attrs<AvailabilityAttr>()) {
  for (auto *B : Original->specific_attrs<AvailabilityAttr>()) {
    if (A->getPlatform() != B->getPlatform()) continue;
    if (A->getIntroduced() != B->getIntroduced() || ...) {
      Diag();
    }
  }
}

You can do the deprecated check outside of the loop like:

if (Impl->hasAttr<Dep>() && !Original->hasAttr<Dep>())
arphaman added inline comments.Nov 13 2017, 3:40 PM
lib/Sema/SemaDeclAttr.cpp
2300

Nice, that's much better! Updated.

arphaman updated this revision to Diff 122740.Nov 13 2017, 3:41 PM
  • formatting
  • simplify checks
  • support c++
arphaman marked 2 inline comments as done.Nov 13 2017, 3:41 PM
ahatanak edited edge metadata.Nov 13 2017, 7:31 PM

Is it not necessary to print a diagnostic when a non-member function declaration is missing an availability attribute?

void foo1();

__attribute__((availability(macos, introduced=10.1)))
void foo1() {
}

Is it not necessary to print a diagnostic when a non-member function declaration is missing an availability attribute?

void foo1();

__attribute__((availability(macos, introduced=10.1)))
void foo1() {
}

It's harder as we don't know the distinction between declaration/definition at merge time. Right now the C++ implementation of this warning actually checks the attributes too late, after they're merged. I'll take out the C++/C support completely and keep to ObjC in this patch for simplicity. The rest can be supported later.

arphaman updated this revision to Diff 122949.Nov 14 2017, 4:49 PM

Remove C++ support for now (it will be in a followup patch along with non-member function support).

erik.pilkington accepted this revision.Nov 17 2017, 6:31 AM

It's harder as we don't know the distinction between declaration/definition at merge time. Right now the C++ implementation of this warning actually checks the attributes too late, after they're merged. I'll take out the C++/C support completely and keep to ObjC in this patch for simplicity. The rest can be supported later.

That sounds fine for now! LGTM

This revision is now accepted and ready to land.Nov 17 2017, 6:31 AM
ahatanak accepted this revision.Nov 25 2017, 12:10 AM

LGTM

lib/Sema/SemaDeclAttr.cpp
2295

I feel like using "if" is easier to understand than a conditional operator, but it's up to you:

if (MissingIntroduced)
  MissingIntroduced = Decl->getIntroduced().empty();
aaron.ballman requested changes to this revision.Nov 25 2017, 6:48 AM
aaron.ballman added a subscriber: aaron.ballman.
aaron.ballman added inline comments.
include/clang/Basic/DiagnosticSemaKinds.td
2921

Please quote 'availability' in the diagnostic wording. Same for the note.

2925

Please quote 'deprecated' in the diagnostic wording. Same for the note.

One concern I have about this diagnostic is that it suggests this will happen for *all* deprecated attributes when it does not.

include/clang/Sema/Sema.h
2406–2407

These should be const pointers.

Does this *only* warn on missing clauses, or does it also warn on conflicting clauses as the first sentence suggests?

lib/Sema/SemaDecl.cpp
3581–3582

Please do not use isa<> followed by cast<> (same below). Rather than use this complex if statement, it might be better to split things out into local variables.

lib/Sema/SemaDeclAttr.cpp
2286

const auto *

2291

const auto *

2295

The pattern we usually see is: MissingIntroduced = MissingIntroduced && Decl->getIntroduced().empty();

This revision now requires changes to proceed.Nov 25 2017, 6:48 AM