Skip to content

[Clang] Fix build with GCC 14 on ARM #78704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 19, 2024
Merged

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Jan 19, 2024

GCC 14 defines __arm_streaming as a macro expanding to [[arm::streaming]]. Due to the nested macro use, this gets expanded prior to concatenation.

It doesn't look like C++ has a really clean way to prevent macro expansion. The best I have found is to use EMPTY ## X where EMPTY is an empty macro argument, so this is the hack I'm implementing here.

Fixes #78691.

GCC 14 defines `__arm_streaming` as a macro expanding to
`[[arm::streaming]]`. Due to the nested macro use, this gets
expanded prior to concatenation.

It doesn't look like C++ has a really clean way to prevent
macro expansion. The best I have found is to use `EMPTY ## X` where
`EMPTY` is an empty macro argument, so this is the hack I'm
implementing here.

Fixes llvm#78691.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 19, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 19, 2024

@llvm/pr-subscribers-clang

Author: Nikita Popov (nikic)

Changes

GCC 14 defines __arm_streaming as a macro expanding to [[arm::streaming]]. Due to the nested macro use, this gets expanded prior to concatenation.

It doesn't look like C++ has a really clean way to prevent macro expansion. The best I have found is to use EMPTY ## X where EMPTY is an empty macro argument, so this is the hack I'm implementing here.

Fixes #78691.


Full diff: https://github.com/llvm/llvm-project/pull/78704.diff

3 Files Affected:

  • (modified) clang/include/clang/Basic/AttributeCommonInfo.h (+1-1)
  • (modified) clang/include/clang/Basic/TokenKinds.def (+2-1)
  • (modified) clang/utils/TableGen/ClangAttrEmitter.cpp (+1-1)
diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h
index d787e4959bfee3..ef2ddf525c9814 100644
--- a/clang/include/clang/Basic/AttributeCommonInfo.h
+++ b/clang/include/clang/Basic/AttributeCommonInfo.h
@@ -260,7 +260,7 @@ inline bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind) {
   switch (Kind) {
   default:
     return false;
-#define KEYWORD_ATTRIBUTE(NAME, HASARG)                                        \
+#define KEYWORD_ATTRIBUTE(NAME, HASARG, ...)                                   \
   case tok::kw_##NAME:                                                         \
     return HASARG;
 #include "clang/Basic/RegularKeywordAttrInfo.inc"
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index d15e4970b7d8f1..c10e2adfbe6e96 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -760,8 +760,9 @@ KEYWORD(__builtin_available              , KEYALL)
 KEYWORD(__builtin_sycl_unique_stable_name, KEYSYCL)
 
 // Keywords defined by Attr.td.
+// The "EMPTY ## X" is used to prevent early macro-expansion of the keyword.
 #ifndef KEYWORD_ATTRIBUTE
-#define KEYWORD_ATTRIBUTE(X, ...) KEYWORD(X, KEYALL)
+#define KEYWORD_ATTRIBUTE(X, HASARG, EMPTY) KEYWORD(EMPTY ## X, KEYALL)
 #endif
 #include "clang/Basic/RegularKeywordAttrInfo.inc"
 
diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index a1827f8ce0ead8..3888e6c08ab0f4 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -3589,7 +3589,7 @@ void EmitClangRegularKeywordAttributeInfo(RecordKeeper &Records,
 
       OS << "KEYWORD_ATTRIBUTE("
          << S.getSpellingRecord().getValueAsString("Name") << ", "
-         << (HasArgs ? "true" : "false") << ")\n";
+         << (HasArgs ? "true" : "false") << ", )\n";
     }
   OS << "#undef KEYWORD_ATTRIBUTE\n";
 }

#ifndef KEYWORD_ATTRIBUTE
#define KEYWORD_ATTRIBUTE(X, ...) KEYWORD(X, KEYALL)
#define KEYWORD_ATTRIBUTE(X, HASARG, EMPTY) KEYWORD(EMPTY ## X, KEYALL)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the following suffice?

#define EMPTY
#define KEYWORD_ATTRIBUTE(X, HASARG) KEYWORD(EMPTY ## X, KEYALL)

Or is the crux of this fix that EMPTY must be an argument to the same macro in order for it not to get expanded?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Macros don't get expanded in ## so this will produce something like EMPTY__arm_streaming. I believe the only way to actually get an empty concatenation is via an empty macro argument.

Here's a godbolt to experiment: https://cpp.godbolt.org/z/d9zc7hs3a

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks for sharing the example.

@nikic nikic merged commit d54dfdd into llvm:main Jan 19, 2024
@nikic nikic deleted the arm-streaming-fix branch January 19, 2024 14:19
wanghao75 pushed a commit to openeuler-mirror/llvm-project that referenced this pull request Sep 12, 2024
Reference: llvm/llvm-project#78704

GCC 14 defines `__arm_streaming` as a macro expanding to
`[[arm::streaming]]`. Due to the nested macro use, this gets expanded
prior to concatenation.

It doesn't look like C++ has a really clean way to prevent macro
expansion. The best I have found is to use `EMPTY ## X` where `EMPTY` is
an empty macro argument, so this is the hack I'm implementing here.

Fixes llvm/llvm-project#78691.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clang fails to build on with GCC 14 on ARM
3 participants