nickdesaulniers added inline comments.
================
Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:11172
+def err_attribute_removed_on_redeclaration : Error<
+ "'%0' attribute removed from redeclared variable">;
----------------
aaron.ballman wrote:
> This diagnostic is a bit confusing to me -- should this be a warning about
> the attribute being ignored in this case, rather than an error?
> Alternatively, should this be re-worded to say that the attribute must appear
> on the first declaration? If the latter, we have some diagnostics that could
> maybe be combined into using a `%select` for this:
> `err_noreturn_missing_on_first_decl` and `err_internal_linkage_redeclaration`
> are awfully similar to the same thing.
Rebased onto D107613; reusing `diag::err_attribute_missing_on_first_decl` now.
done.
================
Comment at: clang/lib/Sema/SemaDecl.cpp:2982
+ // If redeclaration removes error or warning attribute...
+ if (auto *EA = New->getAttr<ErrorAttr>())
----------------
aaron.ballman wrote:
> The comment doesn't seem to match the code -- this is when the redeclaration
> *adds* the attribute. And don't we want to silently accept that if the
> redeclaration adds the same annotation with the same message? e.g.,
> ```
> __attribute__((error("derp"))) void func();
> __attribute__((error("derp"))) void func(); // fine
> __attribute__((error("derp"))) void func() {} // fine
> ```
Rebased onto D107613, so this block was moved from `Sema::mergeDeclAttributes`
(which should be for `Attributes` on any subclass of `Decl`, which is too
generic for a `FunctionDecl` only `Attribute`) to `Sema::MergeFunctionDecl`
(which is only for `FunctionDecl` `Attribute`s).
I had a similar test case already in clang/test/Sema/attr-error.c testing
`__attribute__((error("foo"), error("foo"))) int good1(void);`, but I will add
a test to that file for redeclarations with matching attributes. done.
================
Comment at: clang/lib/Sema/SemaDeclAttr.cpp:955
+
+ if (const auto *EA = D->getAttr<ErrorAttr>()) {
+ unsigned NewAttrSpellingIndex = AL.getAttributeSpellingListIndex();
----------------
aaron.ballman wrote:
> This logic will catch the case where the attributes are processed in a group
> (e.g., two attributes in one specifier or two attributes on the same
> declaration) but it won't handle the redeclaration merging case. I think you
> need to follow the attribute merge pattern used in SemaDecl.cpp.
I'm not sure that I need to change anything here; redeclarations of
`ErrorAttr`s are checked in `Sema::MergeFunctionDecl`.
But when I was playing around with something else here earlier this week, I
noticed a pre-existing inconsistency (or maybe just a difference, described
below) of `handle*Attr` functionns vs `merge*Attr` functions.
`mergeDeclAttribute` in `clang/lib/Sema/SemaDecl.cpp` has a large `if`/`else`
chain for new attrs, which calls `merge*Attr` methods of `Sema`, but it doesn't
give your a reference to any "`Old`"/pre-existing attr that may be in conflict.
A comment in `mergeDeclAttribute` seems to confirm this.
>> // This function copies an attribute Attr from a previous declaration to the
>>
>>
>> // new declaration D if the new declaration doesn't itself have that
>> attribute
>>
>> // yet or if that attribute allows duplicates.
Because we do not allow this `Attribute` to be added on subsequent `Decl`s, I
_do not think_ we need to follow the attribute merge pattern used in
SemaDecl.cpp. But I could be wrong; please triple check.
================
Comment at: clang/lib/Sema/SemaDeclAttr.cpp:964-965
+ bool match =
+ (EA->isError() && NewAttrSpellingIndex < ErrorAttr::GNU_warning) ||
+ (EA->isWarning() && NewAttrSpellingIndex >= ErrorAttr::GNU_warning);
+ if (!match) {
----------------
aaron.ballman wrote:
> It's a bit tricky for me to tell from the patch -- are the enumerators in the
> correct order that this logic still works for when the [[]] spelling is used?
For reference, the generated `enum Spelling` looks like:
```
3611 public:
3612 enum Spelling {
3613 GNU_error = 0,
3614 CXX11_gnu_error = 1,
3615 C2x_gnu_error = 2,
3616 GNU_warning = 3,
3617 CXX11_gnu_warning = 4,
3618 C2x_gnu_warning = 5,
3619 SpellingNotCalculated = 15
3620
3621 };
```
while using `getAttributeSpellingListIndex` rather than `getNormalizedFullName`
allows us to avoid a pair of string comparisons in favor of a pair of
`unsigned` comparisons, we now have an issue because there are technically six
spellings. (I guess it's not clear to me what's `CXX11_gnu_*` vs `C2x_gnu_*`?)
We could be explicit against checking all six rather than two comparisons.
Or I can use local variables with more helpful identifiers like:
```
bool NewAttrIsError = NewAttrSpellingIndex < ErrorAttr::GNU_warning;
bool NewAttrIsWarning = NewAttrSpellingIndex >= ErrorAttr::GNU_warning;
bool Match = (EA->isError() && NewAttrIsError) || (EA->isWarning() &&
NewAttrIsWarning);
```
WDYT?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D106030/new/
https://reviews.llvm.org/D106030
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits