This is an archive of the discontinued LLVM Phabricator instance.

Sema: add support for `__attribute__((__swift_error__))`
ClosedPublic

Authored by compnerd on Sep 8 2020, 2:49 PM.

Details

Summary

Introduce a new attribute that is used to indicate the error handling
convention used by a function. This is used to translate the error
semantics from the decorated interface to a compatible Swift interface.

The supported error convention is one of:

  • none: no error handling
  • nonnull_error: a non-null error parameter indicates an error signifier
  • null_result: a return value of NULL is an error signifier
  • zero_result: a return value of 0 is an error signifier
  • nonzero_result: a non-zero return value is an error signifier

Since this is the first of the attributes needed to support the semantic
annotation for Swift, this change also includes the necessary supporting
infrastructure for a new category of attributes (Swift).

This is based on the work of the original changes in
https://github.com/llvm/llvm-project-staging/commit/8afaf3aad2af43cfedca7a24cd817848c4e95c0c

Diff Detail

Event Timeline

compnerd created this revision.Sep 8 2020, 2:49 PM
Herald added a project: Restricted Project. · View Herald Transcript
compnerd requested review of this revision.Sep 8 2020, 2:49 PM
rjmccall accepted this revision.Sep 8 2020, 2:51 PM

LGTM. :)

This revision is now accepted and ready to land.Sep 8 2020, 2:51 PM

Oh, there are a ton of typos in this documentation.

clang/include/clang/Basic/AttrDocs.td
3491

Please split this sentence: "...API. When calling the API, Swift will always pass a valid
address initialized to a null pointer."

3499

Typo: "default"

3504

Typo: "integral"

3510

Typo: "integral"

compnerd marked 4 inline comments as done.Sep 8 2020, 4:01 PM
compnerd updated this revision to Diff 290601.Sep 8 2020, 4:05 PM
  • correct typos
  • apply clang-format changes
  • const correct a few declarations.
rjmccall accepted this revision.Sep 8 2020, 6:18 PM

LGTM, thanks!

aaron.ballman added inline comments.Sep 9 2020, 5:55 AM
clang/include/clang/Basic/Attr.td
2134

Is this attribute also supported by GCC? It looked like it wasn't from my quick check, so I'd recommend switching the spelling to be Clang instead. Note, this will give you [[clang::swift_error(...)]] in both C and C++ as well. If you only want the GNU spelling, use GNU.

2140

Should this apply to function-like things such as blocks or function pointers? If so, you should use HasFunctionProto.

clang/include/clang/Basic/AttrDocs.td
3485

the dynamic -> which dynamic

3489

Canonical type or are typedefs to these types also fine? May want to mention that the type has to be cv-unqualified, but I do wonder whether something like NSError * const * is fine.

clang/lib/Sema/SemaDeclAttr.cpp
5536

const auto *?

5551–5552

No need to repeat this condition three times (and in some cases repeat the check). You can hoist this out of all of the lambdas and call it once.

5560

You should just be able to pass in AL directly (the diagnostics engine handles formatting the name properly), or is there a reason you want to call getNormalizedFullName() explicitly?

5576

Same here as above, but also, you can just pass in Ident.

5590

Same here as above.

5596

convention -> Convention per usual naming rules.

5600

Same here as above.

clang/test/SemaObjC/attr-swift-error.m
11

You should also have some tests where the attribute accepts no args, too many args, and unknown enum value.

compnerd marked 10 inline comments as done.Sep 9 2020, 10:44 AM
compnerd added inline comments.
clang/include/clang/Basic/Attr.td
2134

Ah, oops, this should be GNU.

2140

I believe not.

clang/include/clang/Basic/AttrDocs.td
3489

I am definitely not the authority on this, but I believe that the common thing is to take NSError ** or CFErrorRef ** by canonical name. The cv-qualified versions, except on the outermost pointer, is something that can be treated as valid, though it is certainly extremely unusual. I've added test cases for them as well.

compnerd updated this revision to Diff 290767.Sep 9 2020, 10:45 AM
compnerd marked an inline comment as done.

Address feedback from @aaron.ballman

rjmccall added inline comments.Sep 9 2020, 11:06 AM
clang/include/clang/Basic/Attr.td
2140

Correct, it's just declared functions for now.

clang/include/clang/Basic/AttrDocs.td
3489

NSError * const * actually does not really work; the whole point is that this is an out-parameter.

compnerd added inline comments.Sep 9 2020, 12:35 PM
clang/include/clang/Basic/AttrDocs.td
3489

Oh right, its the const NSError ** const that can work, because the outer pointer can be non-mutable as it is a pointer by-reference scenario. Should we diagnose the NSError * const * case then? Any const qualified value is really unidiomatic to say the least.

const qualification isn't the most meaningful thing for Objective-C objects anyway.

gribozavr2 accepted this revision.Sep 10 2020, 4:28 AM
gribozavr2 added inline comments.
clang/include/clang/Basic/AttrDocs.td
3472–3477
3494
clang/test/SemaObjC/attr-swift-error.m
56
98
compnerd marked 2 inline comments as done.Sep 10 2020, 8:45 AM
compnerd added inline comments.
clang/test/SemaObjC/attr-swift-error.m
56

Removed the test case in light of John's comment.

98

Similar

compnerd updated this revision to Diff 290990.Sep 10 2020, 8:48 AM

Address @gribozavr2's comments

aaron.ballman added inline comments.Sep 10 2020, 10:52 AM
clang/include/clang/Basic/Attr.td
2140

SGTM, thank you for verifying.

clang/include/clang/Basic/AttrDocs.td
3489

I think we should diagnose (as an error) any case that can't work.

I think it may make sense to diagnose (as a warning) any case where we want to ignore the qualifiers, in case we want to give semantics to those qualifiers in this situation later. So this means we'd error on NSError * const * but warn and ignore the qualifiers on volatile NSError **. However, I don't insist on warning in this case unless there's a situation that the user might actually appreciate the warning because it matters (it's not clear to me if such a situation exists). Also, it's not clear to me whether we should or should not warn on a restrict-qualified pointer.

compnerd added inline comments.Sep 10 2020, 1:41 PM
clang/include/clang/Basic/AttrDocs.td
3489

I think that the newer diagnostics would make sense as a follow up improvement in the case that @rjmccall believe that they would be useful to users. As John mentioned, const is rarely used with ObjectiveC, so the use of that is pretty unidiomatic. In fact, trying to return the error would cause a warning in the first place (due to the assignment of a value to a const parameter).

Discussed this with @aaron.ballman offline; he is okay with this since this is not going to permit incorrect code through without a diagnostic, even if it is not the most clear and the attribute wont be accidentally ignored. We can add more diagnostics as a follow up if it is useful.

This revision was automatically updated to reflect the committed changes.