This is an archive of the discontinued LLVM Phabricator instance.

[clang] Add a diagnostic for line directive of a gnu extension
ClosedPublic

Authored by ken-matsui on Apr 27 2022, 9:19 AM.

Diff Detail

Event Timeline

ken-matsui created this revision.Apr 27 2022, 9:19 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 27 2022, 9:19 AM
ken-matsui requested review of this revision.Apr 27 2022, 9:19 AM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptApr 27 2022, 9:19 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
This comment was removed by ken-matsui.
aaron.ballman added a subscriber: aaron.ballman.

Thank you for working on this new diagnostic!

clang-tools-extra/test/clang-apply-replacements/Inputs/crlf/crlf.cpp
1 ↗(On Diff #425537)

I think this file (and the next one) are making unintended line ending changes and should be reverted.

clang/include/clang/Basic/DiagnosticLexKinds.td
430

Tweaking for grammar, but mostly, this should be marked as an Extension rather than a Warning so that it's controlled only via -pedantic rather than another warning group.

clang/test/Misc/warning-flags.c
21 ↗(On Diff #425537)

Once you make the diagnostic an extension, the changes to this file can be reverted. (It's worth noting that two lines above we document that this list should not grow.)

clang/test/Preprocessor/line-directive.c
30–31

This should get the same diagnostic.

35

As should this form.

Add a diagnostic for line directive of a gnu extension

Hi @aaron.ballman,

Thank you for your review! I updated the code.

ken-matsui retitled this revision from Add a warning diagnostic for line directive of a gnu extension to Add a diagnostic for line directive of a gnu extension.Apr 27 2022, 1:51 PM
ken-matsui edited the summary of this revision. (Show Details)
aaron.ballman added inline comments.Apr 28 2022, 11:01 AM
clang/include/clang/Basic/DiagnosticLexKinds.td
431

Oops, I missed this last time around, but we need this to be in a warning group as well.

I think you should add: def GNULineMarker : DiagGroup<"gnu-line-marker">; to DiagnosticGroups.td and then add GNULineMarker to the GNU warning group.

Then here, you can make these changes.

clang/lib/Lex/PPDirectives.cpp
1401

I think you need to add another call to Diag() here.

clang/test/Misc/warning-flags.c
93 ↗(On Diff #425601)

Oops, I missed this before -- two lines up, it also says this count should never grow. This should be fixed by my suggestion to add it to a warning group.

clang/test/Preprocessor/line-directive.c
35

It looks like this form isn't getting the warning we'd expect.

119–120

These should also get the warning.

Add a diagnostic for line directive of a gnu extension

Hi, @aaron.ballman

Thanks for your kind reviews!
I’ve updated the code, but is this what you’d expected?

Hi, @aaron.ballman

Thanks for your kind reviews!
I’ve updated the code, but is this what you’d expected?

It looks like the precommit CI pipeline can't test your patch -- I think you may have uploaded just the changes since last time rather than the full set of changes against the tree. I don't think we're quite there yet, but we're not too far off either, I think. Thank you for continuing to work on this!

clang/include/clang/Basic/DiagnosticGroups.td
1116–1118

You'll likely also need to re-flow the line to the usual 80-col limit.

clang/lib/Lex/PPDirectives.cpp
1350

I speculate that this change is wrong.

The goal here is to diagnose any time there's a GNU line marker and now we're only trigging the diagnostic when the line marker's value is 1; that misses diagnostics when the marker value is something else.

That's why I suggested warning each place we return false from this function -- those are the situations when the line marker is syntactically correct and we're going to make use of it in the caller. (We don't want to warn about use of a line marker when we're going to generate an error anyway.)

ken-matsui added inline comments.Apr 29 2022, 9:12 AM
clang/lib/Lex/PPDirectives.cpp
1350

@aaron.ballman

Thank you!

Just to confirm, do I need to remove the call of Diag after GetLineValue and put Diags into all branches of returning false in this function?
If so, I think putting Diag after the call of this function would be better.

aaron.ballman added inline comments.Apr 29 2022, 11:25 AM
clang/lib/Lex/PPDirectives.cpp
1350

If so, I think putting Diag after the call of this function would be better.

You are correct and I agree, good suggestion!

ken-matsui added inline comments.Apr 29 2022, 1:21 PM
clang/lib/Lex/PPDirectives.cpp
1350

@aaron.ballman
Thank you for your response!

I've updated the code as mentioned, but a bunch of other tests with the -pedantic option failed as the following warnings:

******************** TEST 'Clang :: CXX/expr/expr.const/p2-0x.cpp' FAILED ********************
Script:
--
: 'RUN: at line 1';   /tmp/llvm/llvm-project/build/bin/clang -cc1 -internal-isystem /tmp/llvm/llvm-project/build/lib/clang/15.0.0/include -nostdsysteminc -fsyntax-only -std=c++11 -pedantic -verify=expected,cxx11 -fcxx-exceptions /tmp/llvm/llvm-project/clang/test/CXX/expr/expr.const/p2-0x.cpp -fconstexpr-depth 128 -triple i686-pc-linux-gnu
: 'RUN: at line 2';   /tmp/llvm/llvm-project/build/bin/clang -cc1 -internal-isystem /tmp/llvm/llvm-project/build/lib/clang/15.0.0/include -nostdsysteminc -fsyntax-only -std=c++2a -pedantic -verify=expected,cxx20 -fcxx-exceptions /tmp/llvm/llvm-project/clang/test/CXX/expr/expr.const/p2-0x.cpp -fconstexpr-depth 128 -triple i686-pc-linux-gnu
--
Exit Code: 1

Command Output (stderr):
--
error: 'warning' diagnostics seen but not expected: 
  Line 0: this style of line directive is a GNU extension
  Line 0: this style of line directive is a GNU extension
2 errors generated.

...

I personally think it would be preferable if the only change of tests would be line-directive.c.
So, how about reducing Diag calls until the warning doesn't spill over into other tests?

Add a diagnostic for line directive of a gnu extension

ken-matsui retitled this revision from Add a diagnostic for line directive of a gnu extension to [clang] Add a diagnostic for line directive of a gnu extension.Apr 29 2022, 4:40 PM
aaron.ballman added inline comments.May 2 2022, 6:10 AM
clang/lib/Lex/PPDirectives.cpp
1350

I personally think it would be preferable if the only change of tests would be line-directive.c.
So, how about reducing Diag calls until the warning doesn't spill over into other tests?

No, this is expected. We're adding a diagnostic where there wasn't one previously, so some files are going to get caught by that. You can either add the // expected-warning {{}} comments to those lines, or if the test has a lot of those lines but isn't really specific to line markers (it just happens to use them to test other functionality) you can disable the diagnostic for that test with -Wno-gnu-line-marker.

ken-matsui added inline comments.May 3 2022, 10:31 AM
clang/lib/Lex/PPDirectives.cpp
1350

Ah, I see. I'm going to work on it. Thank you!

@aaron.ballman

If so, I think putting Diag after the call of this function would be better.

With the above change, I tried to add comments to failed tests, but there were over 300 files.

During my investigation, I found most tests printed warnings without file information strangely.

error: 'warning' diagnostics seen but not expected: 
  Line 0: this style of line directive is a GNU extension
  Line 0: this style of line directive is a GNU extension
2 errors generated.

If warnings have file information, it should be like:

error: 'warning' diagnostics seen but not expected: 
  File /tmp/llvm-project/clang/test/Preprocessor/line-directive.c Line 9: this style of line directive is a GNU extension
1 error generated.

Even tests that completely do not use preprocessor directives, such as clang/test/SemaCXX/matrix-type.cpp, failed with the above strange warnings.

Thus, I suspect that the warnings without file paths have come from internally included SDK (I'm using macOS that includes /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk) or something that is not related to target test files.

What do you think?

@aaron.ballman

If so, I think putting Diag after the call of this function would be better.

With the above change, I tried to add comments to failed tests, but there were over 300 files.

During my investigation, I found most tests printed warnings without file information strangely.

error: 'warning' diagnostics seen but not expected: 
  Line 0: this style of line directive is a GNU extension
  Line 0: this style of line directive is a GNU extension
2 errors generated.

That is rather unexpected.

If warnings have file information, it should be like:

error: 'warning' diagnostics seen but not expected: 
  File /tmp/llvm-project/clang/test/Preprocessor/line-directive.c Line 9: this style of line directive is a GNU extension
1 error generated.

Even tests that completely do not use preprocessor directives, such as clang/test/SemaCXX/matrix-type.cpp, failed with the above strange warnings.

Thus, I suspect that the warnings without file paths have come from internally included SDK (I'm using macOS that includes /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk) or something that is not related to target test files.

What do you think?

The tests run in -cc1 mode and don't #include anything, so I don't think the issue is an internally included SDK. I think the issue could be from this: https://github.com/llvm/llvm-project/blob/main/clang/lib/Frontend/InitPreprocessor.cpp#L1355 and https://github.com/llvm/llvm-project/blob/main/clang/lib/Frontend/InitPreprocessor.cpp#L1368. You may have to hook up to a debugger to see why we're issuing those surprising warnings. If it turns out that it's these inserted directives, you may have to look at the source location of the digit token to see if isWrittenInBuiltinFile() is true or not (and we may need to also check isWrittenInScratchSpace() as well, perhaps).

The tests run in -cc1 mode and don't #include anything, so I don't think the issue is an internally included SDK. I think the issue could be from this: https://github.com/llvm/llvm-project/blob/main/clang/lib/Frontend/InitPreprocessor.cpp#L1355 and https://github.com/llvm/llvm-project/blob/main/clang/lib/Frontend/InitPreprocessor.cpp#L1368. You may have to hook up to a debugger to see why we're issuing those surprising warnings. If it turns out that it's these inserted directives, you may have to look at the source location of the digit token to see if isWrittenInBuiltinFile() is true or not (and we may need to also check isWrittenInScratchSpace() as well, perhaps).

Thank you for the information! I'm going to look into the source code.

ken-matsui updated this revision to Diff 427482.May 5 2022, 3:58 PM

Update codes as reviewed

@aaron.ballman

I could suppress the strange warnings by using isWrittenInBuiltinFile and isWrittenInCommandLineFile. Thank you!
Could you please review this patch?

It looks like there's still something not quite right because it's warning on some instances but not others and I'm not certain why. Can you investigate?

clang/test/Preprocessor/line-directive.c
35–36

Something is still not quite correct -- these should also be diagnosed as an extension (it's the same feature just with flags).

63

This should also be diagnosed.

@aaron.ballman

Thank you for your review and sorry to have missed those directives!

I also found additional directives that I might have to diagnose.
Could you please tell me if these are also required?

clang/test/Preprocessor/line-directive.c
69–79

Should these directives also be diagnosed?

After some investigations, some directives behave weirdly.
I will continue investigating, but do you have any suggestions here?

clang/test/Preprocessor/line-directive.c
35

This didn't cause a warning on this test file, but another test file I created caused a warning.

// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify -pedantic %s

# 42 "foo" 1 3  // enter: expected-warning {{this style of line directive is a GNU extension}}
63

This directive didn't cause a warning when marking both # 192 "glomp.h" and this. Marking only either directive works.

Works:

...
# 192 "glomp.h" // not a system header.: expected-warning {{this style of line directive is a GNU extension}}
typedef int x;  // expected-note {{previous definition is here}}
typedef int x;  // expected-warning {{redefinition of typedef 'x' is a C11 feature}}

# 192 "glomp.h" 3 // System header.
...

Works:

...
# 192 "glomp.h" // not a system header.
typedef int x;  // expected-note {{previous definition is here}}
typedef int x;  // expected-warning {{redefinition of typedef 'x' is a C11 feature}}

# 192 "glomp.h" 3 // System header.: expected-warning {{this style of line directive is a GNU extension}}
...

Does NOT work:

...
# 192 "glomp.h" // not a system header.: expected-warning {{this style of line directive is a GNU extension}}
typedef int x;  // expected-note {{previous definition is here}}
typedef int x;  // expected-warning {{redefinition of typedef 'x' is a C11 feature}}

# 192 "glomp.h" 3 // System header.: expected-warning {{this style of line directive is a GNU extension}}
...
Command Output (stderr):
--
error: 'warning' diagnostics expected but not seen: 
  File /tmp/llvm/llvm-project/clang/test/Preprocessor/line-directive.c Line 191: this style of line directive is a GNU extension
1 error generated.
aaron.ballman added inline comments.May 9 2022, 5:55 AM
clang/test/Preprocessor/line-directive.c
35

Oooohhhh, wait a tick! This is entering a system header! Perhaps we're silencing the warning because it's "in" a system header!

That's a neat edge case for us to think about -- do users of this diagnostic *expect* such a construct to be diagnosed? What about the exit from the system header? GCC seems to diagnose the entrance to the system header, but not the exit: https://godbolt.org/z/PKGd4jh64 and I don't know if we want to follow their behavior or not. Our current behavior is defensible, if it marks the entrance to a system header or the exit from a system header, we're silent. User who want to see the system header diagnostics can use -Wsystem-headers to get them. So I think I've talked myself into the current behavior here being correct -- but we should probably add a RUN line that enables diagnostics in system headers to show our behavior there.

69–79

Yes, but this may be a case of the directive being in a system header and thus the diagnostic is suppressed.

Add a test file that uses the -Wsystem-headers option.

ken-matsui marked an inline comment as not done.May 10 2022, 12:00 AM
ken-matsui added inline comments.
clang/test/Preprocessor/line-directive.c
35

Ah, I'm quite not familiar with a preprocessor, so I couldn't have understood what was going on. Thank you for your clear explanation.

I've added a new file that tests with -Wsystem-headers. This test shows that it seems mostly correct expectations.

Thanks, I think we're getting pretty close!

clang/test/Preprocessor/line-directive-system-headers.c
2–6

I think we're losing a bunch of test coverage from this. Why did you drop these?

57–58

It took me a moment, but we get these diagnostics because we asked for warnings in a system header. So I think we're losing test coverage from this change -- previously the test was checking that we suppressed the diagnostics as expected.

I think you should have two RUN lines, one with -Wsystem-headers and one without, so you can test the behavior of both situations. Note, you can do -verify=system on the one with -Wsystem-headers so that you can write // system-warning {{whatever}} on the diagnostics expected to only appear from that RUN line.

Alternatively, you could make this test solely about system header behavior and modify line-directive.c to not do anything with system headers. But I think that's a much more invasive change.

clang/test/Preprocessor/line-directive.c
35–36

Thank you for your review!

clang/test/Preprocessor/line-directive-system-headers.c
2–6

These are also tested on line-directive.c and possibly redundant, so I removed them.
Should I keep them?

57–58

Thank you! I'm going to edit this file, not line-directive.c.

aaron.ballman added inline comments.May 10 2022, 5:11 AM
clang/test/Preprocessor/line-directive-system-headers.c
2–6

You're right, those are redundant; I'm fine removing them here.

ken-matsui added inline comments.May 10 2022, 5:18 AM
clang/test/Preprocessor/line-directive-system-headers.c
2–6

I see 👍

Update test codes as reviewed

aaron.ballman added inline comments.May 10 2022, 10:07 AM
clang/test/Preprocessor/line-directive-system-headers.c
2–3

There's nothing specific to C99 that I can see in the test, so I think these can be dropped.

20–22

Might as well make this consistent with the other parts of the test and use @#6 instead of @-1. Same applies elsewhere.

41–51

Let's change "no expected warning" into "Warnings silenced when -Wsystem-headers isn't passed." so it sounds less like "we don't expect the warning directly below this comment to happen".

Thank you for your review! I'm going to fix them :)

Fix the test as reviewed

aaron.ballman accepted this revision.May 10 2022, 2:16 PM

LGTM, thank you for all the hard work on this! I assume you need me to land this on your behalf -- if so, can you let me know what name and email address you would like me to use for patch attribution?

I think we should add a release note for this to let folks know about the new warning group (there's a "Improvements to Clang's diagnostics" in clang/docs/ReleaseNotes.rst). You can either add one to this patch, or I can add one for you when I go to land, I'm fine either way.

This revision is now accepted and ready to land.May 10 2022, 2:16 PM

LGTM, thank you for all the hard work on this! I assume you need me to land this on your behalf -- if so, can you let me know what name and email address you would like me to use for patch attribution?

Thank you so much for your support and approval!

Yes, I do not have commit access; could you please use the following info for this patch?

Name: Ken Matsui
Email: 26405363+ken-matsui@users.noreply.github.com

(I use this info for every commit on GitHub, but is this what you expected? Please let me know if you need an email where you can be reached out.)

I think we should add a release note for this to let folks know about the new warning group (there's a "Improvements to Clang's diagnostics" in clang/docs/ReleaseNotes.rst). You can either add one to this patch, or I can add one for you when I go to land, I'm fine either way.

Could you please add it to this patch for this time?
I would like to add one next time by referring to how you do.

This revision was landed with ongoing or failed builds.May 11 2022, 3:42 AM
This revision was automatically updated to reflect the committed changes.

LGTM, thank you for all the hard work on this! I assume you need me to land this on your behalf -- if so, can you let me know what name and email address you would like me to use for patch attribution?

Thank you so much for your support and approval!

Happy to help!

Yes, I do not have commit access; could you please use the following info for this patch?

Name: Ken Matsui
Email: 26405363+ken-matsui@users.noreply.github.com

(I use this info for every commit on GitHub, but is this what you expected? Please let me know if you need an email where you can be reached out.)

That looks to be exactly what I needed, but you can double-check that you were properly attributed here: https://github.com/llvm/llvm-project/commit/786c721c2bbd2e0646e314671e010859550423bf

I think we should add a release note for this to let folks know about the new warning group (there's a "Improvements to Clang's diagnostics" in clang/docs/ReleaseNotes.rst). You can either add one to this patch, or I can add one for you when I go to land, I'm fine either way.

Could you please add it to this patch for this time?
I would like to add one next time by referring to how you do.

I added one when I landed. I also adjusted the commit message slightly from what you have here in Phab for some added clarity.

(I use this info for every commit on GitHub, but is this what you expected? Please let me know if you need an email where you can be reached out.)

That looks to be exactly what I needed, but you can double-check that you were properly attributed here: https://github.com/llvm/llvm-project/commit/786c721c2bbd2e0646e314671e010859550423bf

Actually, it does raise an interesting issue -- I don't think you'll get build failure emails when using that address. After a patch is landed, a bunch of build bots test the patch out and when there's a failure, they send email to everyone on the blame list. You should probably use an email address that receives email for future commits (or when you go to obtain your own commit privileges) so that you can receive those emails.

That looks to be exactly what I needed, but you can double-check that you were properly attributed here: https://github.com/llvm/llvm-project/commit/786c721c2bbd2e0646e314671e010859550423bf
I added one when I landed. I also adjusted the commit message slightly from what you have here in Phab for some added clarity.

Thank you! I was able to confirm that I was attributed.

(I use this info for every commit on GitHub, but is this what you expected? Please let me know if you need an email where you can be reached out.)

That looks to be exactly what I needed, but you can double-check that you were properly attributed here: https://github.com/llvm/llvm-project/commit/786c721c2bbd2e0646e314671e010859550423bf

Actually, it does raise an interesting issue -- I don't think you'll get build failure emails when using that address. After a patch is landed, a bunch of build bots test the patch out and when there's a failure, they send email to everyone on the blame list. You should probably use an email address that receives email for future commits (or when you go to obtain your own commit privileges) so that you can receive those emails.

Ah, sorry. I also have a public email for GitHub (just mostly used the private one), so I'll share a public one in the future.

Hi, this patch causes a test failure on AIX https://lab.llvm.org/buildbot/#/builders/214/builds/1221/steps/6/logs/FAIL__Clang__noinline_cu

Could you please make a fix or revert if it takes too long?

Hello @Jake-Egan,

I believe the problem was already fixed by the @aaron.ballman's patch here.

Thank you for fixing it, @aaron.ballman!