[clang] [clang] Improve diagnostics for constraints of inline asm (NFC) (PR #96363)
Evgenii Kudriashov via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 26 19:30:40 PDT 2024
https://github.com/e-kud updated https://github.com/llvm/llvm-project/pull/96363
>From 4f8504878da33925609d52912e8d0e1f64c41066 Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Fri, 21 Jun 2024 14:00:58 -0700
Subject: [PATCH 1/2] [clang] Improve diagnostics for constraints of inline asm
Introduce more detailed diagnostics for the constrains. Also provide an
opportunity for backends to provide detailed diagnostics for target
specific constraints based on enabled features.
---
.../clang/Basic/DiagnosticCommonKinds.td | 33 +++++++++
.../clang/Basic/DiagnosticSemaKinds.td | 4 --
clang/include/clang/Basic/TargetInfo.h | 19 +++--
clang/lib/Basic/TargetInfo.cpp | 63 +++++++++++-----
clang/lib/Basic/Targets/AArch64.cpp | 6 +-
clang/lib/Basic/Targets/AArch64.h | 4 +-
clang/lib/Basic/Targets/AMDGPU.h | 7 +-
clang/lib/Basic/Targets/ARC.h | 4 +-
clang/lib/Basic/Targets/ARM.cpp | 6 +-
clang/lib/Basic/Targets/ARM.h | 4 +-
clang/lib/Basic/Targets/AVR.h | 4 +-
clang/lib/Basic/Targets/BPF.h | 4 +-
clang/lib/Basic/Targets/CSKY.cpp | 6 +-
clang/lib/Basic/Targets/CSKY.h | 4 +-
clang/lib/Basic/Targets/DirectX.h | 4 +-
clang/lib/Basic/Targets/Hexagon.h | 4 +-
clang/lib/Basic/Targets/Lanai.h | 4 +-
clang/lib/Basic/Targets/Le64.h | 4 +-
clang/lib/Basic/Targets/LoongArch.cpp | 3 +-
clang/lib/Basic/Targets/LoongArch.h | 4 +-
clang/lib/Basic/Targets/M68k.cpp | 30 ++++----
clang/lib/Basic/Targets/M68k.h | 4 +-
clang/lib/Basic/Targets/MSP430.h | 4 +-
clang/lib/Basic/Targets/Mips.h | 4 +-
clang/lib/Basic/Targets/NVPTX.h | 4 +-
clang/lib/Basic/Targets/PNaCl.h | 4 +-
clang/lib/Basic/Targets/PPC.h | 4 +-
clang/lib/Basic/Targets/RISCV.cpp | 6 +-
clang/lib/Basic/Targets/RISCV.h | 4 +-
clang/lib/Basic/Targets/SPIR.cpp | 5 +-
clang/lib/Basic/Targets/SPIR.h | 8 ++-
clang/lib/Basic/Targets/Sparc.h | 6 +-
clang/lib/Basic/Targets/SystemZ.cpp | 6 +-
clang/lib/Basic/Targets/SystemZ.h | 4 +-
clang/lib/Basic/Targets/TCE.h | 4 +-
clang/lib/Basic/Targets/VE.h | 4 +-
clang/lib/Basic/Targets/WebAssembly.h | 4 +-
clang/lib/Basic/Targets/X86.cpp | 6 +-
clang/lib/Basic/Targets/X86.h | 4 +-
clang/lib/Basic/Targets/XCore.h | 4 +-
clang/lib/CodeGen/CGStmt.cpp | 21 ++++--
clang/lib/Sema/SemaStmtAsm.cpp | 18 ++---
clang/test/Sema/asm.c | 72 ++++++++++---------
43 files changed, 287 insertions(+), 134 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index de758cbe679dc..d4b0862337165 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -309,6 +309,39 @@ def err_asm_invalid_type : Error<
def err_ms_asm_bitfield_unsupported : Error<
"an inline asm block cannot have an operand which is a bit-field">;
+def asm_invalid_constraint_generic : TextSubstitution<
+ "invalid %select{input|output}0 constraint '%1' in asm">;
+def err_asm_invalid_constraint : Error<
+ "%sub{asm_invalid_constraint_generic}0,1">;
+def err_asm_invalid_constraint_start : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: output constraint must start with"
+ " '=' or '+'">;
+def err_asm_invalid_constraint_rw_clobber : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: early clobber with a read-write"
+ " constraint must be a register">;
+def err_asm_invalid_constraint_mem_or_reg : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: constraint must allow either"
+ " memory or register operands">;
+def err_asm_invalid_constraint_missing_bracket : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: missing ']'">;
+def err_asm_invalid_constraint_wrong_symbol : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: cannot find an output constraint"
+ " with the specified name">;
+def err_asm_invalid_constraint_empty : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: empty constraint has been"
+ " provided">;
+def err_asm_invalid_constraint_oob : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: the index is out of bounds">;
+def err_asm_invalid_constraint_missing : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: references to a non-existing output"
+ " constraint">;
+def err_asm_invalid_constraint_wrongly_tied : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: tied constraint must be tied to"
+ " the same operand referenced to by the number">;
+def err_asm_invalid_constraint_output_only : Error<
+ "%sub{asm_invalid_constraint_generic}0,1: must refer to an output only"
+ " operand">;
+
def warn_stack_clash_protection_inline_asm : Warning<
"unable to protect inline asm that clobbers stack pointer against stack "
"clash">, InGroup<DiagGroup<"stack-protector">>;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 25a87078a5709..3cb5b05d23dd0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9280,12 +9280,8 @@ let CategoryName = "Inline Assembly Issue" in {
: Error<"cannot pass a pointer-to-member through register-constrained "
"inline assembly parameter">;
def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">;
- def err_asm_invalid_output_constraint : Error<
- "invalid output constraint '%0' in asm">;
def err_asm_invalid_lvalue_in_input : Error<
"invalid lvalue in asm input for constraint '%0'">;
- def err_asm_invalid_input_constraint : Error<
- "invalid input constraint '%0' in asm">;
def err_asm_tying_incompatible_types : Error<
"unsupported inline asm: input with type "
"%diff{$ matching output with type $|}0,1">;
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 9b0ae2102e098..0d2773546d2f3 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -17,6 +17,7 @@
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/BitmaskEnum.h"
#include "clang/Basic/CodeGenOptions.h"
+#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Specifiers.h"
@@ -1197,9 +1198,12 @@ class TargetInfo : public TransferrableTargetInfo,
// validateOutputConstraint, validateInputConstraint - Checks that
// a constraint is valid and provides information about it.
// FIXME: These should return a real error instead of just true/false.
- bool validateOutputConstraint(ConstraintInfo &Info) const;
- bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints,
- ConstraintInfo &info) const;
+ bool validateOutputConstraint(ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const;
+ bool validateInputConstraint(
+ MutableArrayRef<ConstraintInfo> OutputConstraints, ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap, diag::kind &Diag) const;
virtual bool validateOutputSize(const llvm::StringMap<bool> &FeatureMap,
StringRef /*Constraint*/,
@@ -1219,13 +1223,14 @@ class TargetInfo : public TransferrableTargetInfo,
std::string &/*SuggestedModifier*/) const {
return true;
}
- virtual bool
- validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const = 0;
+ virtual bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const = 0;
bool resolveSymbolicName(const char *&Name,
ArrayRef<ConstraintInfo> OutputConstraints,
- unsigned &Index) const;
+ unsigned &Index, diag::kind &Diag) const;
// Constraint parm will be left pointing at the last character of
// the constraint. In practice, it won't be changed unless the
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index 29f5cd14e46e1..adc168410bfe5 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -722,11 +722,15 @@ StringRef TargetInfo::getNormalizedGCCRegisterName(StringRef Name,
return Name;
}
-bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
+bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const {
const char *Name = Info.getConstraintStr().c_str();
// An output constraint must start with '=' or '+'
- if (*Name != '=' && *Name != '+')
+ if (*Name != '=' && *Name != '+') {
+ Diag = diag::err_asm_invalid_constraint_start;
return false;
+ }
if (*Name == '+')
Info.setIsReadWrite();
@@ -735,7 +739,7 @@ bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
while (*Name) {
switch (*Name) {
default:
- if (!validateAsmConstraint(Name, Info)) {
+ if (!validateAsmConstraint(Name, Info, FeatureMap, Diag)) {
// FIXME: We temporarily return false
// so we can add more constraints as we hit it.
// Eventually, an unknown constraint should just be treated as 'g'.
@@ -788,17 +792,23 @@ bool TargetInfo::validateOutputConstraint(ConstraintInfo &Info) const {
// Early clobber with a read-write constraint which doesn't permit registers
// is invalid.
- if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister())
+ if (Info.earlyClobber() && Info.isReadWrite() && !Info.allowsRegister()) {
+ Diag = diag::err_asm_invalid_constraint_rw_clobber;
return false;
+ }
// If a constraint allows neither memory nor register operands it contains
// only modifiers. Reject it.
- return Info.allowsMemory() || Info.allowsRegister();
+ if (!Info.allowsMemory() && !Info.allowsRegister()) {
+ Diag = diag::err_asm_invalid_constraint_mem_or_reg;
+ return false;
+ }
+ return true;
}
bool TargetInfo::resolveSymbolicName(const char *&Name,
ArrayRef<ConstraintInfo> OutputConstraints,
- unsigned &Index) const {
+ unsigned &Index, diag::kind &Diag) const {
assert(*Name == '[' && "Symbolic name did not start with '['");
Name++;
const char *Start = Name;
@@ -807,6 +817,7 @@ bool TargetInfo::resolveSymbolicName(const char *&Name,
if (!*Name) {
// Missing ']'
+ Diag = diag::err_asm_invalid_constraint_missing_bracket;
return false;
}
@@ -816,16 +827,19 @@ bool TargetInfo::resolveSymbolicName(const char *&Name,
if (SymbolicName == OutputConstraints[Index].getName())
return true;
+ Diag = diag::err_asm_invalid_constraint_wrong_symbol;
return false;
}
bool TargetInfo::validateInputConstraint(
- MutableArrayRef<ConstraintInfo> OutputConstraints,
- ConstraintInfo &Info) const {
+ MutableArrayRef<ConstraintInfo> OutputConstraints, ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap, diag::kind &Diag) const {
const char *Name = Info.ConstraintStr.c_str();
- if (!*Name)
+ if (!*Name) {
+ Diag = diag::err_asm_invalid_constraint_empty;
return false;
+ }
while (*Name) {
switch (*Name) {
@@ -838,25 +852,34 @@ bool TargetInfo::validateInputConstraint(
const char *DigitEnd = Name;
unsigned i;
if (StringRef(DigitStart, DigitEnd - DigitStart + 1)
- .getAsInteger(10, i))
+ .getAsInteger(10, i)) {
+ Diag = diag::err_asm_invalid_constraint_oob;
return false;
+ }
// Check if matching constraint is out of bounds.
- if (i >= OutputConstraints.size()) return false;
+ if (i >= OutputConstraints.size()) {
+ Diag = diag::err_asm_invalid_constraint_missing;
+ return false;
+ }
// A number must refer to an output only operand.
- if (OutputConstraints[i].isReadWrite())
+ if (OutputConstraints[i].isReadWrite()) {
+ Diag = diag::err_asm_invalid_constraint_output_only;
return false;
+ }
// If the constraint is already tied, it must be tied to the
// same operand referenced to by the number.
- if (Info.hasTiedOperand() && Info.getTiedOperand() != i)
+ if (Info.hasTiedOperand() && Info.getTiedOperand() != i) {
+ Diag = diag::err_asm_invalid_constraint_wrongly_tied;
return false;
+ }
// The constraint should have the same info as the respective
// output constraint.
Info.setTiedOperand(i, OutputConstraints[i]);
- } else if (!validateAsmConstraint(Name, Info)) {
+ } else if (!validateAsmConstraint(Name, Info, FeatureMap, Diag)) {
// FIXME: This error return is in place temporarily so we can
// add more constraints as we hit it. Eventually, an unknown
// constraint should just be treated as 'g'.
@@ -865,17 +888,21 @@ bool TargetInfo::validateInputConstraint(
break;
case '[': {
unsigned Index = 0;
- if (!resolveSymbolicName(Name, OutputConstraints, Index))
+ if (!resolveSymbolicName(Name, OutputConstraints, Index, Diag))
return false;
// If the constraint is already tied, it must be tied to the
// same operand referenced to by the number.
- if (Info.hasTiedOperand() && Info.getTiedOperand() != Index)
+ if (Info.hasTiedOperand() && Info.getTiedOperand() != Index) {
+ Diag = diag::err_asm_invalid_constraint_wrongly_tied;
return false;
+ }
// A number must refer to an output only operand.
- if (OutputConstraints[Index].isReadWrite())
+ if (OutputConstraints[Index].isReadWrite()) {
+ Diag = diag::err_asm_invalid_constraint_output_only;
return false;
+ }
Info.setTiedOperand(Index, OutputConstraints[Index]);
break;
@@ -896,7 +923,7 @@ bool TargetInfo::validateInputConstraint(
case 'N':
case 'O':
case 'P':
- if (!validateAsmConstraint(Name, Info))
+ if (!validateAsmConstraint(Name, Info, FeatureMap, Diag))
return false;
break;
case 'r': // general register.
diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp
index 31d8121b91d10..4cd2b7fa821ca 100644
--- a/clang/lib/Basic/Targets/AArch64.cpp
+++ b/clang/lib/Basic/Targets/AArch64.cpp
@@ -1339,8 +1339,10 @@ AArch64TargetInfo::convertConstraint(const char *&Constraint) const {
return R;
}
-bool AArch64TargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+bool AArch64TargetInfo::validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h
index 71510fe289510..2cea2d4a3852a 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -176,7 +176,9 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
std::string convertConstraint(const char *&Constraint) const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
bool
validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
std::string &SuggestedModifier) const override;
diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index 94d9ba93ed226..75ddcb3d582a2 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -137,7 +137,9 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
/// {s[n:m]}
/// {a[n:m]}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
static const ::llvm::StringSet<> SpecialRegs({
"exec", "vcc", "flat_scratch", "m0", "scc", "tba", "tma",
"flat_scratch_lo", "flat_scratch_hi", "vcc_lo", "vcc_hi", "exec_lo",
@@ -232,7 +234,8 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
const char *Begin = Constraint;
TargetInfo::ConstraintInfo Info("", "");
- if (validateAsmConstraint(Constraint, Info))
+ diag::kind AsmDiag;
+ if (validateAsmConstraint(Constraint, Info, nullptr, AsmDiag))
return std::string(Begin).substr(0, Constraint - Begin + 1);
Constraint = Begin;
diff --git a/clang/lib/Basic/Targets/ARC.h b/clang/lib/Basic/Targets/ARC.h
index fcbfdd6eec586..fc4755f48fd4a 100644
--- a/clang/lib/Basic/Targets/ARC.h
+++ b/clang/lib/Basic/Targets/ARC.h
@@ -64,7 +64,9 @@ class LLVM_LIBRARY_VISIBILITY ARCTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
return false;
}
diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp
index 7423626d7c3cb..f1f1ccd3ca103 100644
--- a/clang/lib/Basic/Targets/ARM.cpp
+++ b/clang/lib/Basic/Targets/ARM.cpp
@@ -1136,8 +1136,10 @@ ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
return llvm::ArrayRef(GCCRegAliases);
}
-bool ARMTargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+bool ARMTargetInfo::validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const {
switch (*Name) {
default:
break;
diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h
index df9855a52e61c..59e1b7ad64d5f 100644
--- a/clang/lib/Basic/Targets/ARM.h
+++ b/clang/lib/Basic/Targets/ARM.h
@@ -204,7 +204,9 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
std::string convertConstraint(const char *&Constraint) const override;
bool
validateConstraintModifier(StringRef Constraint, char Modifier, unsigned Size,
diff --git a/clang/lib/Basic/Targets/AVR.h b/clang/lib/Basic/Targets/AVR.h
index feeb04f37eeba..6e2061960e591 100644
--- a/clang/lib/Basic/Targets/AVR.h
+++ b/clang/lib/Basic/Targets/AVR.h
@@ -94,7 +94,9 @@ class LLVM_LIBRARY_VISIBILITY AVRTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
// There aren't any multi-character AVR specific constraints.
if (StringRef(Name).size() > 1)
return false;
diff --git a/clang/lib/Basic/Targets/BPF.h b/clang/lib/Basic/Targets/BPF.h
index d19b37dd4df7a..94a0fe90a3c68 100644
--- a/clang/lib/Basic/Targets/BPF.h
+++ b/clang/lib/Basic/Targets/BPF.h
@@ -72,7 +72,9 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
switch (*Name) {
default:
break;
diff --git a/clang/lib/Basic/Targets/CSKY.cpp b/clang/lib/Basic/Targets/CSKY.cpp
index c8bf8b9234d24..f6af91bbe278b 100644
--- a/clang/lib/Basic/Targets/CSKY.cpp
+++ b/clang/lib/Basic/Targets/CSKY.cpp
@@ -289,8 +289,10 @@ ArrayRef<TargetInfo::GCCRegAlias> CSKYTargetInfo::getGCCRegAliases() const {
return llvm::ArrayRef(GCCRegAliases);
}
-bool CSKYTargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+bool CSKYTargetInfo::validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/CSKY.h b/clang/lib/Basic/Targets/CSKY.h
index 94d4eeb9a1fff..971bdc5e8b18d 100644
--- a/clang/lib/Basic/Targets/CSKY.h
+++ b/clang/lib/Basic/Targets/CSKY.h
@@ -80,7 +80,9 @@ class LLVM_LIBRARY_VISIBILITY CSKYTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
std::string_view getClobbers() const override { return ""; }
diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h
index a084e2823453f..6a10409f844c3 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -83,7 +83,9 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
return true;
}
diff --git a/clang/lib/Basic/Targets/Hexagon.h b/clang/lib/Basic/Targets/Hexagon.h
index cdb47dbae7999..1dc8cb498603d 100644
--- a/clang/lib/Basic/Targets/Hexagon.h
+++ b/clang/lib/Basic/Targets/Hexagon.h
@@ -68,7 +68,9 @@ class LLVM_LIBRARY_VISIBILITY HexagonTargetInfo : public TargetInfo {
ArrayRef<Builtin::Info> getTargetBuiltins() const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
switch (*Name) {
case 'v':
case 'q':
diff --git a/clang/lib/Basic/Targets/Lanai.h b/clang/lib/Basic/Targets/Lanai.h
index 144cbc7de9893..aea2feca2336a 100644
--- a/clang/lib/Basic/Targets/Lanai.h
+++ b/clang/lib/Basic/Targets/Lanai.h
@@ -83,7 +83,9 @@ class LLVM_LIBRARY_VISIBILITY LanaiTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
return false;
}
diff --git a/clang/lib/Basic/Targets/Le64.h b/clang/lib/Basic/Targets/Le64.h
index 45f6a4e9dd75d..2c1880470d1d9 100644
--- a/clang/lib/Basic/Targets/Le64.h
+++ b/clang/lib/Basic/Targets/Le64.h
@@ -52,7 +52,9 @@ class LLVM_LIBRARY_VISIBILITY Le64TargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
return false;
}
diff --git a/clang/lib/Basic/Targets/LoongArch.cpp b/clang/lib/Basic/Targets/LoongArch.cpp
index 280bd1d8033cc..f50f91306f1eb 100644
--- a/clang/lib/Basic/Targets/LoongArch.cpp
+++ b/clang/lib/Basic/Targets/LoongArch.cpp
@@ -119,7 +119,8 @@ LoongArchTargetInfo::getGCCRegAliases() const {
}
bool LoongArchTargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+ const char *&Name, TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap, diag::kind &Diag) const {
// See the GCC definitions here:
// https://gcc.gnu.org/onlinedocs/gccint/Machine-Constraints.html
// Note that the 'm' constraint is handled in TargetInfo.
diff --git a/clang/lib/Basic/Targets/LoongArch.h b/clang/lib/Basic/Targets/LoongArch.h
index 5fc223483951e..49ef549f85e94 100644
--- a/clang/lib/Basic/Targets/LoongArch.h
+++ b/clang/lib/Basic/Targets/LoongArch.h
@@ -81,7 +81,9 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public TargetInfo {
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
std::string convertConstraint(const char *&Constraint) const override;
bool hasBitIntType() const override { return true; }
diff --git a/clang/lib/Basic/Targets/M68k.cpp b/clang/lib/Basic/Targets/M68k.cpp
index 8b8bf97d6f99a..a61dd0003f363 100644
--- a/clang/lib/Basic/Targets/M68k.cpp
+++ b/clang/lib/Basic/Targets/M68k.cpp
@@ -144,47 +144,49 @@ ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const {
return llvm::ArrayRef(GCCRegAliases);
}
-bool M68kTargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &info) const {
+bool M68kTargetInfo::validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const {
switch (*Name) {
case 'a': // address register
case 'd': // data register
- info.setAllowsRegister();
+ Info.setAllowsRegister();
return true;
case 'I': // constant integer in the range [1,8]
- info.setRequiresImmediate(1, 8);
+ Info.setRequiresImmediate(1, 8);
return true;
case 'J': // constant signed 16-bit integer
- info.setRequiresImmediate(std::numeric_limits<int16_t>::min(),
+ Info.setRequiresImmediate(std::numeric_limits<int16_t>::min(),
std::numeric_limits<int16_t>::max());
return true;
case 'K': // constant that is NOT in the range of [-0x80, 0x80)
- info.setRequiresImmediate();
+ Info.setRequiresImmediate();
return true;
case 'L': // constant integer in the range [-8,-1]
- info.setRequiresImmediate(-8, -1);
+ Info.setRequiresImmediate(-8, -1);
return true;
case 'M': // constant that is NOT in the range of [-0x100, 0x100]
- info.setRequiresImmediate();
+ Info.setRequiresImmediate();
return true;
case 'N': // constant integer in the range [24,31]
- info.setRequiresImmediate(24, 31);
+ Info.setRequiresImmediate(24, 31);
return true;
case 'O': // constant integer 16
- info.setRequiresImmediate(16);
+ Info.setRequiresImmediate(16);
return true;
case 'P': // constant integer in the range [8,15]
- info.setRequiresImmediate(8, 15);
+ Info.setRequiresImmediate(8, 15);
return true;
case 'C':
++Name;
switch (*Name) {
case '0': // constant integer 0
- info.setRequiresImmediate(0);
+ Info.setRequiresImmediate(0);
return true;
case 'i': // constant integer
case 'j': // integer constant that doesn't fit in 16 bits
- info.setRequiresImmediate();
+ Info.setRequiresImmediate();
return true;
default:
break;
@@ -194,7 +196,7 @@ bool M68kTargetInfo::validateAsmConstraint(
case 'U': // address register indirect w/ constant offset addressing
// TODO: Handle 'S' (basically 'm' when pc-rel is enforced) when
// '-mpcrel' flag is properly handled by the driver.
- info.setAllowsMemory();
+ Info.setAllowsMemory();
return true;
default:
break;
diff --git a/clang/lib/Basic/Targets/M68k.h b/clang/lib/Basic/Targets/M68k.h
index b732add77e034..602033e29ebc8 100644
--- a/clang/lib/Basic/Targets/M68k.h
+++ b/clang/lib/Basic/Targets/M68k.h
@@ -50,7 +50,9 @@ class LLVM_LIBRARY_VISIBILITY M68kTargetInfo : public TargetInfo {
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
std::string convertConstraint(const char *&Constraint) const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
std::optional<std::string> handleAsmEscapedChar(char EscChar) const override;
std::string_view getClobbers() const override;
BuiltinVaListKind getBuiltinVaListKind() const override;
diff --git a/clang/lib/Basic/Targets/MSP430.h b/clang/lib/Basic/Targets/MSP430.h
index 25639b8c1e0ad..f23548e16f9cd 100644
--- a/clang/lib/Basic/Targets/MSP430.h
+++ b/clang/lib/Basic/Targets/MSP430.h
@@ -75,7 +75,9 @@ class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
// FIXME: implement
switch (*Name) {
case 'K': // the constant 1
diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h
index b6f110249fa78..3bc3453e295be 100644
--- a/clang/lib/Basic/Targets/Mips.h
+++ b/clang/lib/Basic/Targets/Mips.h
@@ -235,7 +235,9 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index f476d49047c01..a8f1b5d73dcd9 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -95,7 +95,9 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/PNaCl.h b/clang/lib/Basic/Targets/PNaCl.h
index 595c4d83b1d1c..6b6286007a094 100644
--- a/clang/lib/Basic/Targets/PNaCl.h
+++ b/clang/lib/Basic/Targets/PNaCl.h
@@ -65,7 +65,9 @@ class LLVM_LIBRARY_VISIBILITY PNaClTargetInfo : public TargetInfo {
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
return false;
}
diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h
index fc23c30c68523..f6f33ef1d3fc3 100644
--- a/clang/lib/Basic/Targets/PPC.h
+++ b/clang/lib/Basic/Targets/PPC.h
@@ -210,7 +210,9 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/RISCV.cpp b/clang/lib/Basic/Targets/RISCV.cpp
index 25ae7d64b577e..2fdd14fad4267 100644
--- a/clang/lib/Basic/Targets/RISCV.cpp
+++ b/clang/lib/Basic/Targets/RISCV.cpp
@@ -71,8 +71,10 @@ ArrayRef<TargetInfo::GCCRegAlias> RISCVTargetInfo::getGCCRegAliases() const {
return llvm::ArrayRef(GCCRegAliases);
}
-bool RISCVTargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+bool RISCVTargetInfo::validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index d0e9cdc6da07b..ffa50c7dd0a98 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -89,7 +89,9 @@ class RISCVTargetInfo : public TargetInfo {
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
std::string convertConstraint(const char *&Constraint) const override;
diff --git a/clang/lib/Basic/Targets/SPIR.cpp b/clang/lib/Basic/Targets/SPIR.cpp
index 040303983594f..b45ba0b532805 100644
--- a/clang/lib/Basic/Targets/SPIR.cpp
+++ b/clang/lib/Basic/Targets/SPIR.cpp
@@ -72,8 +72,9 @@ bool SPIRV64AMDGCNTargetInfo::initFeatureMap(
}
bool SPIRV64AMDGCNTargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
- return AMDGPUTI.validateAsmConstraint(Name, Info);
+ const char *&Name, TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap, diag::kind &Diag) const {
+ return AMDGPUTI.validateAsmConstraint(Name, Info, FeatureMap, Diag);
}
std::string
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 37cf9d7921bac..1fd5ca02fe1c9 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -170,7 +170,9 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
return true;
}
@@ -401,7 +403,9 @@ class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final
const std::vector<std::string> &) const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
std::string convertConstraint(const char *&Constraint) const override;
diff --git a/clang/lib/Basic/Targets/Sparc.h b/clang/lib/Basic/Targets/Sparc.h
index 3357bee33e1ac..9f2cc452d57c9 100644
--- a/clang/lib/Basic/Targets/Sparc.h
+++ b/clang/lib/Basic/Targets/Sparc.h
@@ -58,7 +58,9 @@ class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo {
ArrayRef<const char *> getGCCRegNames() const override;
ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
// FIXME: Implement!
switch (*Name) {
case 'I': // Signed 13-bit constant
@@ -72,7 +74,7 @@ class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo {
case 'f':
case 'e':
- info.setAllowsRegister();
+ Info.setAllowsRegister();
return true;
}
return false;
diff --git a/clang/lib/Basic/Targets/SystemZ.cpp b/clang/lib/Basic/Targets/SystemZ.cpp
index 06f08db2eadd4..0f9d9ddf5340c 100644
--- a/clang/lib/Basic/Targets/SystemZ.cpp
+++ b/clang/lib/Basic/Targets/SystemZ.cpp
@@ -53,8 +53,10 @@ ArrayRef<TargetInfo::AddlRegName> SystemZTargetInfo::getGCCAddlRegNames() const
return llvm::ArrayRef(GCCAddlRegNames);
}
-bool SystemZTargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+bool SystemZTargetInfo::validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h
index 3bc6f2c1d3083..3b097cef94f30 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -88,7 +88,9 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
std::string convertConstraint(const char *&Constraint) const override {
switch (Constraint[0]) {
diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h
index dcf684fe6dbc0..60e576c550116 100644
--- a/clang/lib/Basic/Targets/TCE.h
+++ b/clang/lib/Basic/Targets/TCE.h
@@ -110,7 +110,9 @@ class LLVM_LIBRARY_VISIBILITY TCETargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
return true;
}
diff --git a/clang/lib/Basic/Targets/VE.h b/clang/lib/Basic/Targets/VE.h
index 7e8fdf6096ef2..e533115bee222 100644
--- a/clang/lib/Basic/Targets/VE.h
+++ b/clang/lib/Basic/Targets/VE.h
@@ -158,7 +158,9 @@ class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h
index e4a449d1ff304..65e2e1decdd22 100644
--- a/clang/lib/Basic/Targets/WebAssembly.h
+++ b/clang/lib/Basic/Targets/WebAssembly.h
@@ -132,7 +132,9 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const final {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const final {
return false;
}
diff --git a/clang/lib/Basic/Targets/X86.cpp b/clang/lib/Basic/Targets/X86.cpp
index 036a655a4d073..bf4633327f23b 100644
--- a/clang/lib/Basic/Targets/X86.cpp
+++ b/clang/lib/Basic/Targets/X86.cpp
@@ -1393,8 +1393,10 @@ static unsigned matchAsmCCConstraint(const char *Name) {
return RV;
}
-bool X86TargetInfo::validateAsmConstraint(
- const char *&Name, TargetInfo::ConstraintInfo &Info) const {
+bool X86TargetInfo::validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const {
switch (*Name) {
default:
return false;
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index 9b2ae87adb2e7..56f0c9f64b80e 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -239,7 +239,9 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
std::optional<unsigned> getCPUCacheLineSize() const override;
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &info) const override;
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override;
bool validateGlobalRegisterVariable(StringRef RegName, unsigned RegSize,
bool &HasSizeMismatch) const override {
diff --git a/clang/lib/Basic/Targets/XCore.h b/clang/lib/Basic/Targets/XCore.h
index a58d3e8acf479..4b358a9478a84 100644
--- a/clang/lib/Basic/Targets/XCore.h
+++ b/clang/lib/Basic/Targets/XCore.h
@@ -64,7 +64,9 @@ class LLVM_LIBRARY_VISIBILITY XCoreTargetInfo : public TargetInfo {
}
bool validateAsmConstraint(const char *&Name,
- TargetInfo::ConstraintInfo &Info) const override {
+ TargetInfo::ConstraintInfo &Info,
+ llvm::StringMap<bool> *FeatureMap,
+ diag::kind &Diag) const override {
return false;
}
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 39222c0e65353..57b46a35e9b48 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -2280,6 +2280,7 @@ static std::string
SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
SmallVectorImpl<TargetInfo::ConstraintInfo> *OutCons=nullptr) {
std::string Result;
+ diag::kind Diag;
while (*Constraint) {
switch (*Constraint) {
@@ -2313,8 +2314,9 @@ SimplifyConstraint(const char *Constraint, const TargetInfo &Target,
assert(OutCons &&
"Must pass output names to constraints with a symbolic name");
unsigned Index;
- bool result = Target.resolveSymbolicName(Constraint, *OutCons, Index);
- assert(result && "Could not resolve symbolic name"); (void)result;
+ [[maybe_unused]] bool result =
+ Target.resolveSymbolicName(Constraint, *OutCons, Index, Diag);
+ assert(result && "Could not resolve symbolic name");
Result += llvm::utostr(Index);
break;
}
@@ -2351,7 +2353,8 @@ AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr,
// We're using validateOutputConstraint here because we only care if
// this is a register constraint.
TargetInfo::ConstraintInfo Info(Constraint, "");
- if (Target.validateOutputConstraint(Info) &&
+ diag::kind AsmDiag;
+ if (Target.validateOutputConstraint(Info, nullptr, AsmDiag) &&
!Info.allowsRegister()) {
CGM.ErrorUnsupported(&Stmt, "__asm__");
return Constraint;
@@ -2626,14 +2629,20 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
SmallVector<TargetInfo::ConstraintInfo, 4> OutputConstraintInfos;
SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
+ const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);
+ llvm::StringMap<bool> FeatureMap;
+ CGM.getContext().getFunctionFeatureMap(FeatureMap, FD);
+
bool IsHipStdPar = getLangOpts().HIPStdPar && getLangOpts().CUDAIsDevice;
bool IsValidTargetAsm = true;
+ diag::kind AsmDiag;
for (unsigned i = 0, e = S.getNumOutputs(); i != e && IsValidTargetAsm; i++) {
StringRef Name;
if (const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
Name = GAS->getOutputName(i);
TargetInfo::ConstraintInfo Info(S.getOutputConstraint(i), Name);
- bool IsValid = getTarget().validateOutputConstraint(Info); (void)IsValid;
+ bool IsValid =
+ getTarget().validateOutputConstraint(Info, &FeatureMap, AsmDiag);
if (IsHipStdPar && !IsValid)
IsValidTargetAsm = false;
else
@@ -2646,8 +2655,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
if (const GCCAsmStmt *GAS = dyn_cast<GCCAsmStmt>(&S))
Name = GAS->getInputName(i);
TargetInfo::ConstraintInfo Info(S.getInputConstraint(i), Name);
- bool IsValid =
- getTarget().validateInputConstraint(OutputConstraintInfos, Info);
+ bool IsValid = getTarget().validateInputConstraint(
+ OutputConstraintInfos, Info, &FeatureMap, AsmDiag);
if (IsHipStdPar && !IsValid)
IsValidTargetAsm = false;
else
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 32d42f3c3f3bb..72cc4888bc4d2 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -271,11 +271,12 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
OutputName = Names[i]->getName();
TargetInfo::ConstraintInfo Info(Literal->getString(), OutputName);
- if (!Context.getTargetInfo().validateOutputConstraint(Info) &&
+ diag::kind AsmDiag = diag::err_asm_invalid_constraint;
+ if (!Context.getTargetInfo().validateOutputConstraint(Info, &FeatureMap,
+ AsmDiag) &&
!(LangOpts.HIPStdPar && LangOpts.CUDAIsDevice)) {
- targetDiag(Literal->getBeginLoc(),
- diag::err_asm_invalid_output_constraint)
- << Info.getConstraintStr();
+ targetDiag(Literal->getBeginLoc(), AsmDiag)
+ << 1 << Info.getConstraintStr();
return new (Context)
GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
NumInputs, Names, Constraints, Exprs.data(), AsmString,
@@ -363,10 +364,11 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
InputName = Names[i]->getName();
TargetInfo::ConstraintInfo Info(Literal->getString(), InputName);
- if (!Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,
- Info)) {
- targetDiag(Literal->getBeginLoc(), diag::err_asm_invalid_input_constraint)
- << Info.getConstraintStr();
+ diag::kind AsmDiag = diag::err_asm_invalid_constraint;
+ if (!Context.getTargetInfo().validateInputConstraint(
+ OutputConstraintInfos, Info, &FeatureMap, AsmDiag)) {
+ targetDiag(Literal->getBeginLoc(), AsmDiag)
+ << 0 << Info.getConstraintStr();
return new (Context)
GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs,
NumInputs, Names, Constraints, Exprs.data(), AsmString,
diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
index 630a5e85dd913..edf61864b0127 100644
--- a/clang/test/Sema/asm.c
+++ b/clang/test/Sema/asm.c
@@ -10,12 +10,12 @@ void f(void) {
asm ("foo\n" : "=a" (i + 2)); // expected-error {{invalid lvalue in asm output}}
asm ("foo\n" : [symbolic_name] "=a" (i) : "[symbolic_name]" (i));
- asm ("foo\n" : "=a" (i) : "[" (i)); // expected-error {{invalid input constraint '[' in asm}}
- asm ("foo\n" : "=a" (i) : "[foo" (i)); // expected-error {{invalid input constraint '[foo' in asm}}
- asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm}}
+ asm ("foo\n" : "=a" (i) : "[" (i)); // expected-error {{invalid input constraint '[' in asm: missing ']'}}
+ asm ("foo\n" : "=a" (i) : "[foo" (i)); // expected-error {{invalid input constraint '[foo' in asm: missing ']'}}
+ asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm: cannot find an output constraint with the specified name}}
- asm ("foo\n" : : "" (i)); // expected-error {{invalid input constraint '' in asm}}
- asm ("foo\n" : "=a" (i) : "" (i)); // expected-error {{invalid input constraint '' in asm}}
+ asm ("foo\n" : : "" (i)); // expected-error {{invalid input constraint '' in asm: empty constraint has been provided}}
+ asm ("foo\n" : "=a" (i) : "" (i)); // expected-error {{invalid input constraint '' in asm: empty constraint has been provided}}
}
void clobbers(void) {
@@ -91,13 +91,13 @@ int test7(unsigned long long b) {
// PR3904
void test8(int i) {
// A number in an input constraint can't point to a read-write constraint.
- asm("" : "+r" (i), "=r"(i) : "0" (i)); // expected-error{{invalid input constraint '0' in asm}}
+ asm("" : "+r" (i), "=r"(i) : "0" (i)); // expected-error{{invalid input constraint '0' in asm: must refer to an output only operand}}
}
// PR3905
void test9(int i) {
- asm("" : [foo] "=r" (i), "=r"(i) : "1[foo]"(i)); // expected-error{{invalid input constraint '1[foo]' in asm}}
- asm("" : [foo] "=r" (i), "=r"(i) : "[foo]1"(i)); // expected-error{{invalid input constraint '[foo]1' in asm}}
+ asm("" : [foo] "=r" (i), "=r"(i) : "1[foo]"(i)); // expected-error{{invalid input constraint '1[foo]' in asm: tied constraint must be tied to the same operand referenced to by the number}}
+ asm("" : [foo] "=r" (i), "=r"(i) : "[foo]1"(i)); // expected-error{{invalid input constraint '[foo]1' in asm: tied constraint must be tied to the same operand referenced to by the number}}
}
void test10(void){
@@ -139,14 +139,14 @@ void test14(struct S *s) {
// PR15759.
double test15(void) {
double ret = 0;
- __asm("0.0":"="(ret)); // expected-error {{invalid output constraint '=' in asm}}
- __asm("0.0":"=&"(ret)); // expected-error {{invalid output constraint '=&' in asm}}
- __asm("0.0":"+?"(ret)); // expected-error {{invalid output constraint '+?' in asm}}
- __asm("0.0":"+!"(ret)); // expected-error {{invalid output constraint '+!' in asm}}
- __asm("0.0":"+#"(ret)); // expected-error {{invalid output constraint '+#' in asm}}
- __asm("0.0":"+*"(ret)); // expected-error {{invalid output constraint '+*' in asm}}
- __asm("0.0":"=%"(ret)); // expected-error {{invalid output constraint '=%' in asm}}
- __asm("0.0":"=,="(ret)); // expected-error {{invalid output constraint '=,=' in asm}}
+ __asm("0.0":"="(ret)); // expected-error {{invalid output constraint '=' in asm: constraint must allow either memory or register operands}}
+ __asm("0.0":"=&"(ret)); // expected-error {{invalid output constraint '=&' in asm: constraint must allow either memory or register operands}}
+ __asm("0.0":"+?"(ret)); // expected-error {{invalid output constraint '+?' in asm: constraint must allow either memory or register operands}}
+ __asm("0.0":"+!"(ret)); // expected-error {{invalid output constraint '+!' in asm: constraint must allow either memory or register operands}}
+ __asm("0.0":"+#"(ret)); // expected-error {{invalid output constraint '+#' in asm: constraint must allow either memory or register operands}}
+ __asm("0.0":"+*"(ret)); // expected-error {{invalid output constraint '+*' in asm: constraint must allow either memory or register operands}}
+ __asm("0.0":"=%"(ret)); // expected-error {{invalid output constraint '=%' in asm: constraint must allow either memory or register operands}}
+ __asm("0.0":"=,="(ret)); // expected-error {{invalid output constraint '=,=' in asm: constraint must allow either memory or register operands}}
__asm("0.0":"=,g"(ret)); // no-error
__asm("0.0":"=g"(ret)); // no-error
return ret;
@@ -158,33 +158,33 @@ void iOutputConstraint(int x){
__asm ("nop" : "=ig" (x) : :); // no-error
__asm ("nop" : "=im" (x) : :); // no-error
__asm ("nop" : "=imr" (x) : :); // no-error
- __asm ("nop" : "=i" (x) : :); // expected-error{{invalid output constraint '=i' in asm}}
- __asm ("nop" : "+i" (x) : :); // expected-error{{invalid output constraint '+i' in asm}}
- __asm ("nop" : "=ii" (x) : :); // expected-error{{invalid output constraint '=ii' in asm}}
+ __asm ("nop" : "=i" (x) : :); // expected-error{{invalid output constraint '=i' in asm: constraint must allow either memory or register operands}}
+ __asm ("nop" : "+i" (x) : :); // expected-error{{invalid output constraint '+i' in asm: constraint must allow either memory or register operands}}
+ __asm ("nop" : "=ii" (x) : :); // expected-error{{invalid output constraint '=ii' in asm: constraint must allow either memory or register operands}}
__asm ("nop" : "=nr" (x) : :); // no-error
__asm ("nop" : "=rn" (x) : :); // no-error
__asm ("nop" : "=ng" (x) : :); // no-error
__asm ("nop" : "=nm" (x) : :); // no-error
__asm ("nop" : "=nmr" (x) : :); // no-error
- __asm ("nop" : "=n" (x) : :); // expected-error{{invalid output constraint '=n' in asm}}
- __asm ("nop" : "+n" (x) : :); // expected-error{{invalid output constraint '+n' in asm}}
- __asm ("nop" : "=nn" (x) : :); // expected-error{{invalid output constraint '=nn' in asm}}
+ __asm ("nop" : "=n" (x) : :); // expected-error{{invalid output constraint '=n' in asm: constraint must allow either memory or register operands}}
+ __asm ("nop" : "+n" (x) : :); // expected-error{{invalid output constraint '+n' in asm: constraint must allow either memory or register operands}}
+ __asm ("nop" : "=nn" (x) : :); // expected-error{{invalid output constraint '=nn' in asm: constraint must allow either memory or register operands}}
__asm ("nop" : "=Fr" (x) : :); // no-error
__asm ("nop" : "=rF" (x) : :); // no-error
__asm ("nop" : "=Fg" (x) : :); // no-error
__asm ("nop" : "=Fm" (x) : :); // no-error
__asm ("nop" : "=Fmr" (x) : :); // no-error
- __asm ("nop" : "=F" (x) : :); // expected-error{{invalid output constraint '=F' in asm}}
- __asm ("nop" : "+F" (x) : :); // expected-error{{invalid output constraint '+F' in asm}}
- __asm ("nop" : "=FF" (x) : :); // expected-error{{invalid output constraint '=FF' in asm}}
+ __asm ("nop" : "=F" (x) : :); // expected-error{{invalid output constraint '=F' in asm: constraint must allow either memory or register operands}}
+ __asm ("nop" : "+F" (x) : :); // expected-error{{invalid output constraint '+F' in asm: constraint must allow either memory or register operands}}
+ __asm ("nop" : "=FF" (x) : :); // expected-error{{invalid output constraint '=FF' in asm: constraint must allow either memory or register operands}}
__asm ("nop" : "=Er" (x) : :); // no-error
__asm ("nop" : "=rE" (x) : :); // no-error
__asm ("nop" : "=Eg" (x) : :); // no-error
__asm ("nop" : "=Em" (x) : :); // no-error
__asm ("nop" : "=Emr" (x) : :); // no-error
- __asm ("nop" : "=E" (x) : :); // expected-error{{invalid output constraint '=E' in asm}}
- __asm ("nop" : "+E" (x) : :); // expected-error{{invalid output constraint '+E' in asm}}
- __asm ("nop" : "=EE" (x) : :); // expected-error{{invalid output constraint '=EE' in asm}}
+ __asm ("nop" : "=E" (x) : :); // expected-error{{invalid output constraint '=E' in asm: constraint must allow either memory or register operands}}
+ __asm ("nop" : "+E" (x) : :); // expected-error{{invalid output constraint '+E' in asm: constraint must allow either memory or register operands}}
+ __asm ("nop" : "=EE" (x) : :); // expected-error{{invalid output constraint '=EE' in asm: constraint must allow either memory or register operands}}
}
// PR19837
@@ -214,13 +214,13 @@ void fn1(void) {
void fn2(void) {
int l;
__asm__(""
- : "+&m"(l)); // expected-error {{invalid output constraint '+&m' in asm}}
+ : "+&m"(l)); // expected-error {{invalid output constraint '+&m' in asm: early clobber with a read-write constraint must be a register}}
}
void fn3(void) {
int l;
__asm__(""
- : "+#r"(l)); // expected-error {{invalid output constraint '+#r' in asm}}
+ : "+#r"(l)); // expected-error {{invalid output constraint '+#r' in asm: constraint must allow either memory or register operands}}
}
void fn4(void) {
@@ -234,14 +234,14 @@ void fn5(void) {
int l;
__asm__(""
: [g] "+r"(l)
- : "[g]"(l)); // expected-error {{invalid input constraint '[g]' in asm}}
+ : "[g]"(l)); // expected-error {{invalid input constraint '[g]' in asm: must refer to an output only operand}}
}
void fn6(void) {
int a;
__asm__(""
: "=rm"(a), "=rm"(a)
- : "11m"(a)); // expected-error {{invalid input constraint '11m' in asm}}
+ : "11m"(a)); // expected-error {{invalid input constraint '11m' in asm: references to a non-existing output constraint}}
}
// PR14269
@@ -359,3 +359,11 @@ void test19(long long x)
// FIXME: This case should be supported by codegen, but it fails now.
asm ("" : "=rm" (x): "0" (e)); // expected-error {{unsupported inline asm: input with type 'st_size128' (aka 'struct _st_size128') matching output with type 'long long'}}
}
+
+void test20(long long x)
+{
+ st_size64 a;
+ asm ("" : "=rm" (a): "1" (1)); // expected-error {{invalid input constraint '1' in asm: references to a non-existing output constraint}}
+ asm ("" : "=rm" (a): "9876543210" (1)); // expected-error {{invalid input constraint '9876543210' in asm: the index is out of bounds}}
+ asm ("" : "rm" (a): "0" (1)); // expected-error {{invalid output constraint 'rm' in asm: output constraint must start with '=' or '+'}}
+}
>From 7837dcaea1c615c86225436150fa5567f8274c96 Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Wed, 26 Jun 2024 19:12:51 -0700
Subject: [PATCH 2/2] Address the comments
---
clang/include/clang/Basic/DiagnosticCommonKinds.td | 6 +++---
clang/include/clang/Basic/TargetInfo.h | 1 -
clang/test/Sema/asm.c | 9 ++++-----
3 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td
index d4b0862337165..60dc459d7b5b4 100644
--- a/clang/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td
@@ -325,7 +325,7 @@ def err_asm_invalid_constraint_mem_or_reg : Error<
def err_asm_invalid_constraint_missing_bracket : Error<
"%sub{asm_invalid_constraint_generic}0,1: missing ']'">;
def err_asm_invalid_constraint_wrong_symbol : Error<
- "%sub{asm_invalid_constraint_generic}0,1: cannot find an output constraint"
+ "%sub{asm_invalid_constraint_generic}0,1: no matching output constraint"
" with the specified name">;
def err_asm_invalid_constraint_empty : Error<
"%sub{asm_invalid_constraint_generic}0,1: empty constraint has been"
@@ -333,13 +333,13 @@ def err_asm_invalid_constraint_empty : Error<
def err_asm_invalid_constraint_oob : Error<
"%sub{asm_invalid_constraint_generic}0,1: the index is out of bounds">;
def err_asm_invalid_constraint_missing : Error<
- "%sub{asm_invalid_constraint_generic}0,1: references to a non-existing output"
+ "%sub{asm_invalid_constraint_generic}0,1: references non-existent output"
" constraint">;
def err_asm_invalid_constraint_wrongly_tied : Error<
"%sub{asm_invalid_constraint_generic}0,1: tied constraint must be tied to"
" the same operand referenced to by the number">;
def err_asm_invalid_constraint_output_only : Error<
- "%sub{asm_invalid_constraint_generic}0,1: must refer to an output only"
+ "%sub{asm_invalid_constraint_generic}0,1: must refer to an output-only"
" operand">;
def warn_stack_clash_protection_inline_asm : Warning<
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 0d2773546d2f3..c8e810c6f5d83 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1197,7 +1197,6 @@ class TargetInfo : public TransferrableTargetInfo,
// validateOutputConstraint, validateInputConstraint - Checks that
// a constraint is valid and provides information about it.
- // FIXME: These should return a real error instead of just true/false.
bool validateOutputConstraint(ConstraintInfo &Info,
llvm::StringMap<bool> *FeatureMap,
diag::kind &Diag) const;
diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c
index edf61864b0127..3e260c7106f91 100644
--- a/clang/test/Sema/asm.c
+++ b/clang/test/Sema/asm.c
@@ -12,7 +12,7 @@ void f(void) {
asm ("foo\n" : [symbolic_name] "=a" (i) : "[symbolic_name]" (i));
asm ("foo\n" : "=a" (i) : "[" (i)); // expected-error {{invalid input constraint '[' in asm: missing ']'}}
asm ("foo\n" : "=a" (i) : "[foo" (i)); // expected-error {{invalid input constraint '[foo' in asm: missing ']'}}
- asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm: cannot find an output constraint with the specified name}}
+ asm ("foo\n" : "=a" (i) : "[symbolic_name]" (i)); // expected-error {{invalid input constraint '[symbolic_name]' in asm: no matching output constraint with the specified name}}
asm ("foo\n" : : "" (i)); // expected-error {{invalid input constraint '' in asm: empty constraint has been provided}}
asm ("foo\n" : "=a" (i) : "" (i)); // expected-error {{invalid input constraint '' in asm: empty constraint has been provided}}
@@ -91,7 +91,7 @@ int test7(unsigned long long b) {
// PR3904
void test8(int i) {
// A number in an input constraint can't point to a read-write constraint.
- asm("" : "+r" (i), "=r"(i) : "0" (i)); // expected-error{{invalid input constraint '0' in asm: must refer to an output only operand}}
+ asm("" : "+r" (i), "=r"(i) : "0" (i)); // expected-error{{invalid input constraint '0' in asm: must refer to an output-only operand}}
}
// PR3905
@@ -234,14 +234,14 @@ void fn5(void) {
int l;
__asm__(""
: [g] "+r"(l)
- : "[g]"(l)); // expected-error {{invalid input constraint '[g]' in asm: must refer to an output only operand}}
+ : "[g]"(l)); // expected-error {{invalid input constraint '[g]' in asm: must refer to an output-only operand}}
}
void fn6(void) {
int a;
__asm__(""
: "=rm"(a), "=rm"(a)
- : "11m"(a)); // expected-error {{invalid input constraint '11m' in asm: references to a non-existing output constraint}}
+ : "11m"(a)); // expected-error {{invalid input constraint '11m' in asm: references non-existent output constraint}}
}
// PR14269
@@ -363,7 +363,6 @@ void test19(long long x)
void test20(long long x)
{
st_size64 a;
- asm ("" : "=rm" (a): "1" (1)); // expected-error {{invalid input constraint '1' in asm: references to a non-existing output constraint}}
asm ("" : "=rm" (a): "9876543210" (1)); // expected-error {{invalid input constraint '9876543210' in asm: the index is out of bounds}}
asm ("" : "rm" (a): "0" (1)); // expected-error {{invalid output constraint 'rm' in asm: output constraint must start with '=' or '+'}}
}
More information about the cfe-commits
mailing list