This is an archive of the discontinued LLVM Phabricator instance.

AvailabilityAttrs: Refactor context checking when diagnosing an availability violation
ClosedPublic

Authored by erik.pilkington on Oct 5 2016, 10:04 AM.

Details

Summary

This patch removes some redundant functions that implement checking availability against context, and implements a new, more correct one: ShouldDiagnoseAvailabilityInContext. This is done to more easily allow delaying AD_NotYetIntroduced diagnostics, which is a patch I'll submit right after this!

As it happens, this fixes a bug:

int unavailable_global __attribute__((unavailable));

__attribute__((unavailable))
@interface Foo
- meth;
@end

@implementation Foo
- meth {
  (void) unavailable_global; // no error
  (void) ^{
    (void) unavailable_global; // incorrect-error: 'unavailable_global' is not available
  };
}
@end

Here, there is a reference to an unavailable declaration, unavailable, in the context of a block. We shouldn't emit an error here because 'meth' is implicitly unavailable, meaning that we should be able to reference other unavailable declarations inside it

The problem is that, though both isDeclUnavailable() and getCurContextAvailability() check the reference to unavailable_global, isDeclUnavailable doesn't infer availability attributes from @interface to @implementation (But does consider nested contexts), and getCurContextAvailability() doesn't consider non-immediate contexts (But does infer from @interface -> @implementation). Since they both don't catch this case, this error is emitted when it really shouldn't be!

Thanks for taking a look!

Diff Detail

Repository
rL LLVM

Event Timeline

erik.pilkington retitled this revision from to AvailabilityAttrs: Refactor context checking when diagnosing an availability violation.
erik.pilkington updated this object.
erik.pilkington added a reviewer: manmanren.
erik.pilkington added a subscriber: cfe-commits.
aaron.ballman added a subscriber: aaron.ballman.
aaron.ballman added inline comments.
include/clang/Sema/Sema.h
9747 ↗(On Diff #73657)

Since you're altering the doxygen comments, it would be nice to add a comment for Message.

lib/Sema/SemaDeclAttr.cpp
6346 ↗(On Diff #73657)

Please add an explanatory string literal to the condition.

6350 ↗(On Diff #73657)

Please do not use auto here; the type is not spelled out in the initialization.

6368 ↗(On Diff #73657)

Same comment here as well.

6372 ↗(On Diff #73657)

You can use auto here though. :-)

6398 ↗(On Diff #73657)

Please do not use auto here; the type is not spelled out in the initialization.

6699 ↗(On Diff #73657)

s/then/than

manmanren edited edge metadata.Oct 10 2016, 12:45 PM

This is a nice cleanup!

Manman

lib/Sema/SemaDeclAttr.cpp
6348 ↗(On Diff #73657)

Can you add a comment for the lambda?

lib/Sema/SemaExpr.cpp
179 ↗(On Diff #73657)

I don't quite get why we can remove the above logic (i.e why we can avoid passing ContextVersion when diagnosing the availability). Is it because we move the logic to DoEmitAvailabilityWarning?

erik.pilkington edited edge metadata.

This new patch fixes the style issues @aaron.ballman and @manmanren brought up.
Thanks,
Erik

lib/Sema/SemaExpr.cpp
179 ↗(On Diff #73657)

Yep. It doesn't make sense to check context here because we may delay the diagnostic, in which case we have to check again in the new context (this what isDecl(Deprecated|Unavailable) does). I think it makes more sense to do all the checking in DoEmitAvailabilityWarning, because at that point the paths for delayed and normal diagnostics meet again, and we always have the correct context.

aaron.ballman accepted this revision.Oct 14 2016, 7:26 AM
aaron.ballman edited edge metadata.

LGTM

This revision is now accepted and ready to land.Oct 14 2016, 7:26 AM
This revision was automatically updated to reflect the committed changes.