[clang] [Clang][Driver] Skip empty strings in getAArch64MultilibFlags (PR #97827)
Simon Tatham via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 5 07:19:36 PDT 2024
https://github.com/statham-arm created https://github.com/llvm/llvm-project/pull/97827
In a multilib setting, if you compile with a command line such as `clang --target=aarch64-none-elf -march=armv8.9-a+rcpc3`, `getAArch64MultilibFlags` returns an ill-formed string containing two consecutive `+` signs, of the form `...+rcpc++rcpc3+...`, causing later stages of multilib selection to get confused.
The `++` arises from the entry in `AArch64::Extensions` for the SubtargetFeature `rcpc-immo`, which is a dependency of the `rcpc3` SubtargetFeature, but doesn't have an _extension_ name for the purposes of the `-march=foo+bar` option. So its `UserVisibleName` field is the empty string.
To fix this, I've excluded extensions from consideration in `getAArch64MultilibFlags` if they have an empty `UserVisibleName`. Since the input to this function is not derived from a completely general set of SubtargetFeatures, but from a set that has only just been converted _from_ a clang driver command line, the only extensions skipped by this check should be cases like this one, where the anonymous extension was only included because it was a dependency of one mentioned explicitly.
I've also made the analogous change in `getARMMultilibFlags`. I don't think it's necessary right now, because the architecture extensions for ARM (defined in `ARMTargetParser.def` rather than Tablegen) don't include any anonymous ones. But it seems sensible to add the check anyway, in case future refactoring introduces anonymous array elements in the same way that AArch64 did, and also in case someone writes a function for another platform by using either of these as example code.
>From 8b39cbbdbe3646062dd1cdb60eab18339f9ca490 Mon Sep 17 00:00:00 2001
From: Simon Tatham <simon.tatham at arm.com>
Date: Fri, 5 Jul 2024 11:57:19 +0100
Subject: [PATCH] [Clang][Driver] Skip empty strings in getAArch64MultilibFlags
In a multilib setting, if you compile with a command line such as
`clang --target=aarch64-none-elf -march=armv8.9-a+rcpc3`,
`getAArch64MultilibFlags` returns an ill-formed string containing two
consecutive `+` signs, of the form `...+rcpc++rcpc3+...`, causing
later stages of multilib selection to get confused.
The `++` arises from the entry in `AArch64::Extensions` for the
SubtargetFeature `rcpc-immo`, which is a dependency of the `rcpc3`
SubtargetFeature, but doesn't have an _extension_ name for the
purposes of the `-march=foo+bar` option. So its `UserVisibleName`
field is the empty string.
To fix this, I've excluded extensions from consideration in
`getAArch64MultilibFlags` if they have an empty `UserVisibleName`.
Since the input to this function is not derived from a completely
general set of SubtargetFeatures, but from a set that has only just
been converted _from_ a clang driver command line, the only extensions
skipped by this check should be cases like this one, where the
anonymous extension was only included because it was a dependency of
one mentioned explicitly.
I've also made the analogous change in `getARMMultilibFlags`. I don't
think it's necessary right now, because the architecture extensions
for ARM (defined in `ARMTargetParser.def` rather than Tablegen) don't
include any anonymous ones. But it seems sensible to add the check
anyway, in case future refactoring introduces anonymous array elements
in the same way that AArch64 did, and also in case someone writes a
function for another platform by using either of these as example
code.
---
clang/lib/Driver/ToolChain.cpp | 20 ++++++++++++--------
clang/test/Driver/aarch64-multilib-rcpc3.c | 4 ++++
2 files changed, 16 insertions(+), 8 deletions(-)
create mode 100644 clang/test/Driver/aarch64-multilib-rcpc3.c
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 977e08390800d..9ac428caab3b9 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -195,11 +195,13 @@ static void getAArch64MultilibFlags(const Driver &D,
UnifiedFeatures.end());
std::vector<std::string> MArch;
for (const auto &Ext : AArch64::Extensions)
- if (FeatureSet.contains(Ext.PosTargetFeature))
- MArch.push_back(Ext.UserVisibleName.str());
+ if (!Ext.UserVisibleName.empty())
+ if (FeatureSet.contains(Ext.PosTargetFeature))
+ MArch.push_back(Ext.UserVisibleName.str());
for (const auto &Ext : AArch64::Extensions)
- if (FeatureSet.contains(Ext.NegTargetFeature))
- MArch.push_back(("no" + Ext.UserVisibleName).str());
+ if (!Ext.UserVisibleName.empty())
+ if (FeatureSet.contains(Ext.NegTargetFeature))
+ MArch.push_back(("no" + Ext.UserVisibleName).str());
StringRef ArchName;
for (const auto &ArchInfo : AArch64::ArchInfos)
if (FeatureSet.contains(ArchInfo->ArchFeature))
@@ -221,11 +223,13 @@ static void getARMMultilibFlags(const Driver &D,
UnifiedFeatures.end());
std::vector<std::string> MArch;
for (const auto &Ext : ARM::ARCHExtNames)
- if (FeatureSet.contains(Ext.Feature))
- MArch.push_back(Ext.Name.str());
+ if (!Ext.Name.empty())
+ if (FeatureSet.contains(Ext.Feature))
+ MArch.push_back(Ext.Name.str());
for (const auto &Ext : ARM::ARCHExtNames)
- if (FeatureSet.contains(Ext.NegFeature))
- MArch.push_back(("no" + Ext.Name).str());
+ if (!Ext.Name.empty())
+ if (FeatureSet.contains(Ext.NegFeature))
+ MArch.push_back(("no" + Ext.Name).str());
MArch.insert(MArch.begin(), ("-march=" + Triple.getArchName()).str());
Result.push_back(llvm::join(MArch, "+"));
diff --git a/clang/test/Driver/aarch64-multilib-rcpc3.c b/clang/test/Driver/aarch64-multilib-rcpc3.c
new file mode 100644
index 0000000000000..b839079e0442d
--- /dev/null
+++ b/clang/test/Driver/aarch64-multilib-rcpc3.c
@@ -0,0 +1,4 @@
+// RUN: %clang --target=aarch64-none-elf -march=armv8.9-a+rcpc3 -print-multi-flags-experimental -c %s 2>&1 | FileCheck %s
+
+// CHECK: -march=armv8.9-a
+// CHECK-SAME: +rcpc+rcpc3+
More information about the cfe-commits
mailing list