This is an archive of the discontinued LLVM Phabricator instance.

[clang] Don't define predefined macros multiple times
ClosedPublic

Authored by john.brawn on May 19 2023, 7:40 AM.

Details

Summary

Fix several instances of macros being defined multiple times in several targets. Most of these are just simple duplication in a TargetInfo or OSTargetInfo of things already defined in InitializePredefinedMacros or InitializeStandardPredefinedMacros, but there are a few that aren't:

  • AArch64 defines a couple of feature macros for armv8.1a that are handled generically by getTargetDefines.
  • CSKY needs to take care when CPUName and ArchName are the same.
  • Many os/target combinations result in ELF being defined twice. Instead define ELF just once in InitPreprocessor based on the Triple, which already knows what the object format is based on os and target.

These changes shouldn't change the final result of which macros are defined, with the exception of the changes to ELF where if you explicitly specify the object type in the triple then this affects if ELF is defined, e.g. --target=i686-windows-elf results in it being defined where it wasn't before, but this is more accurate as an ELF file is in fact generated.

Diff Detail

Event Timeline

john.brawn created this revision.May 19 2023, 7:40 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 19 2023, 7:40 AM
john.brawn requested review of this revision.May 19 2023, 7:40 AM

Is it possible/worth to add an assertion to Builder.defineMacro to enforce this one definition rule?

clang/lib/Frontend/InitPreprocessor.cpp
1305

Redundant braces.

Q: What is it the -Wsystem-header can warn about? I mean, no system header is included by the test, what can go wrong?

clang/test/Preprocessor/predefined-macros-no-warnings.c
3

Remove redundant braces, explain more in test comment.

john.brawn marked 2 inline comments as done.

Send test output to /dev/null

Is it possible/worth to add an assertion to Builder.defineMacro to enforce this one definition rule?

It just appends a string to a raw_ostream, so it's not possible to check what's previously been written.

Q: What is it the -Wsystem-header can warn about? I mean, no system header is included by the test, what can go wrong?

The <built-in> buffer is treated as a system header. I've expanded on the comment to explain this more.

Q: What is it the -Wsystem-header can warn about? I mean, no system header is included by the test, what can go wrong?

The <built-in> buffer is treated as a system header. I've expanded on the comment to explain this more.

Thanks, I didn't know that <built-in> is treated as a system header, but I was mostly interested in this part

Check that the predefined macros don't contain anything that causes a warning

What is 'anything', exactly? Does it include duplicate predefined macros, or it tests something else?
Sorry for the silly question.

Check that the predefined macros don't contain anything that causes a warning

What is 'anything', exactly? Does it include duplicate predefined macros, or it tests something else?
Sorry for the silly question.

D144654 caused a failure http://45.33.8.238/macm1/60903/step_7.txt that caused it to be reverted. The failure was in tests that use -Wsystem-headers and was because the host that clang was built on (aarch64 macos) had duplicate predefines and those tests don't specify a target and so the default (i.e. host) target is used. This test is mainly so that we have a test that uses -Wsystem-headers that doesn't depend on the host machine so that I know D144654 won't cause further problems when I re-commit it.

aaron.ballman added inline comments.May 22 2023, 7:30 AM
clang/lib/Basic/Targets/AArch64.cpp
241–242
343–347

I think this is correct -- the other definition has a different predicate (https://github.com/llvm/llvm-project/blob/11926e6149d2a68ecb0652b248efe6890c163846/clang/lib/Frontend/InitPreprocessor.cpp#L949) but I think it ends up being define in exactly the same scenarios.

clang/lib/Basic/Targets/VE.cpp
30–32

Shouldn't this be calling DefineStd(Builder, "unix", Opts); like all the others?

35

This is technically a breaking change but I think it's a good breaking change. The VE target seems to imply that there's never a freestanding mode unlike the general utility: https://github.com/llvm/llvm-project/blob/11926e6149d2a68ecb0652b248efe6890c163846/clang/lib/Frontend/InitPreprocessor.cpp#L431

john.brawn added inline comments.May 22 2023, 8:56 AM
clang/lib/Basic/Targets/AArch64.cpp
241–242

AArch64TargetInfo::setArchFeatures sets HasCRC and HasLSE to true for >= 8.1. This does mean that if you do -march=armv8.1-a+nocrc then the current behaviour is that __ARM_FEATURE_CRC32 is defined but the behaviour with this patch is that it's not defined, but the new behaviour is correct as we shouldn't be defining it in that case.

clang/lib/Basic/Targets/VE.cpp
30–32

Only the OS target should be defining OS-related macros, and in AllocateTarget in Targets.cpp VETargetInfo is hardcoded to always use LinuxTargetInfo, which calls DefineStd(Builder, "unix", Opts);.

aaron.ballman added inline comments.May 22 2023, 9:52 AM
clang/lib/Basic/Targets/AArch64.cpp
241–242

Ah, okay! I think it's worth adding a test case for that scenario to show we've made a bugfix here, not just an NFC change.

clang/lib/Basic/Targets/VE.cpp
30–32
35

This might also be worth an explicit test case so it's clear that the behavioral change is intentional.

Add VE test.

john.brawn marked an inline comment as done.May 23 2023, 6:50 AM
john.brawn added inline comments.
clang/lib/Basic/Targets/AArch64.cpp
241–242

Actually I went and double-checked and I'm wrong, -march=armv8.N+nowhatever doesn't cause __ARM_FEATURE_WHATEVER to be undefined. Which seems wrong, but it's beyond the scope of this patch.

clang/lib/Basic/Targets/VE.cpp
30–32

Most of these are TargetInfos that combine OS plus target, e.g. CygwinARMTargetInfo is both Cygwin OS and ARM Target. The only exception is Le64, and I have no idea if it's correct or not for it to be doing that.

Basically LG though I had a question about the test case.

clang/lib/Basic/Targets/AArch64.cpp
241–242

Yeah, that does seem wrong. Agreed it's not in scope for this patch, but if you would file an issue in GitHub so we don't lose track of it, that'd be appreciated.

clang/lib/Basic/Targets/VE.cpp
30–32

Ahhh, that's a good point about being combined OS + target. Thanks for pointing that out!

clang/test/Preprocessor/predefined-macros-no-warnings.c
5

So the expectation is that any warnings that are emitted would be upgraded to an error and the test would be flagged as a failure because %clang_cc1 would return nonzero in that case?

(I was thrown for a loop by not using -verify and // expected-no-diagnostics)

Pretty sure -Eonly is equivalent (it runs the preprocessor without emitting output, so no extra overhead from piping to /dev/null).

john.brawn added inline comments.May 24 2023, 7:06 AM
clang/lib/Basic/Targets/AArch64.cpp
241–242
clang/test/Preprocessor/predefined-macros-no-warnings.c
5

Yes the intent is for the test to fail on any warning. Using -Werror and not -verify means that on failure you get which macro caused the error:

Exit Code: 1

Command Output (stderr):
--
<built-in>:351:9: error: redefining builtin macro [-Werror,-Wbuiltin-macro-redefined]
#define __LITTLE_ENDIAN__ 1
        ^
1 error generated.

--

whereas -verify just outputs

Exit Code: 1

Command Output (stderr):
--
error: 'error' diagnostics seen but not expected:
  Line 351: redefining builtin macro
1 error generated.

--

Using -Eonly makes sense, I'll do that.

Use -Eonly in test.

aaron.ballman accepted this revision.May 24 2023, 9:13 AM

LGTM

clang/test/Preprocessor/predefined-macros-no-warnings.c
5

Oh, that's a handy failure mechanism, thank you for pointing that out!

This revision is now accepted and ready to land.May 24 2023, 9:13 AM
This revision was landed with ongoing or failed builds.May 24 2023, 9:28 AM
This revision was automatically updated to reflect the committed changes.