Clang is missing one of the conditions for C99 6.5.9p2, where comparison between pointers must either both point to incomplete types or both point to complete types. This patch adds an extra check to the clause where two pointers are of compatible types.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
@efriedma I think you were the last person to touch this code regarding cases where pointer comparisons are invalid. Could you have a look at my changes and gimme some feedback?
I'm not sure how you derive this requirement from the standard; the section in question doesn't use the words "complete" or "incomplete" at all. Am I missing something obvious?
Oh, wait, I was looking at the C11 version. This diagnostic needs to be restricted to C99 or earlier, and only to relational comparisons, I think.
And given it isn't really a valuable diagnostic, I think it should be off by default (an "Extension" diagnostic).
Ah, you're right. I don't see the clause in the C11 standard. I'll see what I can do. Thanks!
Hey @efriedma, thanks again for the comments.
Yes, you were correct in that this message should only be emitted for relational comparisons.
Regarding having the warning off by default, I did want to point out that GCC enables this warning by default: https://c.godbolt.org/z/W_NgYA.
Do you still think that the warning be off by default? I am OK with either.
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
6448 | ext_typecheck_compare_complete_incomplete_pointers should be InGroup<C11> | |
6449 | warn_typecheck_compare_complete_incomplete_pointers should be a Warning, not an ExtWarn. And should be DefaultIgnore. And should indicate why we're warning. And should be in the group C99Compat. |
ext_typecheck_compare_complete_incomplete_pointers:
- Moved to group C11.
ext_typecheck_compare_complete_incomplete_pointers:
- Changed to Warning from ExtWarn
- Moved to group C99Compat
- Added DefaultIgnore
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
6449 | I'm confused by what you mean for "indicate why we're warning". Should I change the warning text? |
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
6449 | Yes; try taking a look at the text of the other C99Compat warnings. |
clang/lib/Sema/SemaExpr.cpp | ||
---|---|---|
11571 | I think this condition is backwards? Should be !getLangOpts().C11. You want the warning with -std=c99 -pedantic, you don't want the warning with std=c11 -pedantic. |
clang/lib/Sema/SemaExpr.cpp | ||
---|---|---|
11571 | I don't think it's backwards. If getLangOpts().C11, then it is an extension. Otherwise, it is the warning. I can switch the conditions if it is confusing though. |
clang/lib/Sema/SemaExpr.cpp | ||
---|---|---|
11571 | "Extension" means "this is invalid code that we're accepting anyway" -- that's what this is in C99. In C11, I think we shouldn't be diagnosing at all. Has anyone checked whether WG14 removed this restriction in C11 as a DR resolution? If so, we shouldn't be diagnosing it at all, in any language mode. |
clang/lib/Sema/SemaExpr.cpp | ||
---|---|---|
11571 | I tracked down the proposal for the change; it's http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1439.pdf . Beyond the reference to http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_314.htm , I can't find any relevant defect report. |
clang/lib/Sema/SemaExpr.cpp | ||
---|---|---|
11571 | I have updated the diff to diagnose only for C99. Does the existence of the proposal mean we shouldn't be diagnosing in any language mode? Also, how did you track down the proposal that quickly? Even after skimming through it, I still can't find it through searching. |
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
6451 | InGroup<C11> | |
clang/lib/Sema/SemaExpr.cpp | ||
11571 |
It wasn't really that quick, but the thing that eventually worked was that I googled for site:open-std.org "At various points within a translation unit". |
clang/lib/Sema/SemaExpr.cpp | ||
---|---|---|
11571 | I tried to get some clarity from WG14 as to whether they intended N1439 to be interpreted as applying retroactively, but it seems like their stance is that they do not do maintenance work on past standards, and have no mechanism for identifying whether papers should be encouraged for retroactive application or only for implementations intending to conform to later standards. In the absence of guidance either way from WG14, I think our best bet is to follow GCC and the literal standards text as this patch does. |
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
6451 | Sorry, I'm not sure I understand. Isn't this a C99 warning? Why is it being put in the C11 group? | |
clang/lib/Sema/SemaExpr.cpp | ||
11571 | GCC has left this warning on by default in any language mode, FWIW. Should we still restrict this warning to only C99 mode? |
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
6451 | Because C11 really means C11Extensions, and this is a C11 extension (ie, it's code that's valid in C11 but not valid in C99): // A warning group for warnings about using C11 features as extensions. def C11 : DiagGroup<"c11-extensions">; | |
clang/lib/Sema/SemaExpr.cpp | ||
11571 | Yes, I think so. I assume the GCC folks haven't noticed that this rule was relaxed in C11. I've filed a bug against GCC for this: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95630 |
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
6451 | Got it, thank you! |
LGTM
I'll merge for you; how do you want to be credited on the "Author" line of the commit message?
ext_typecheck_compare_complete_incomplete_pointers should be InGroup<C11>