2 changes: 1 addition & 1 deletion clang-tools-extra/include-cleaner/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
set(LLVM_LINK_COMPONENTS Support)

add_clang_library(clangIncludeCleaner
add_clang_library(clangIncludeCleaner STATIC
Analysis.cpp
IncludeSpeller.cpp
FindHeaders.cpp
Expand Down
79 changes: 43 additions & 36 deletions clang/docs/ClangFormatStyleOptions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ the configuration (without a prefix: ``Auto``).
.. _AlignArrayOfStructures:

**AlignArrayOfStructures** (``ArrayInitializerAlignmentStyle``) :versionbadge:`clang-format 13` :ref:`ΒΆ <AlignArrayOfStructures>`
if not ``None``, when using initialization for an array of structs
If not ``None``, when using initialization for an array of structs
aligns the fields into columns.


Expand Down Expand Up @@ -307,11 +307,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -464,11 +465,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -621,11 +623,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -779,11 +782,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -1056,11 +1060,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -1211,11 +1216,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down Expand Up @@ -1366,11 +1372,12 @@ the configuration (without a prefix: ``Auto``).
Alignment options.

They can also be read as a whole for compatibility. The choices are:
- None
- Consecutive
- AcrossEmptyLines
- AcrossComments
- AcrossEmptyLinesAndComments

* ``None``
* ``Consecutive``
* ``AcrossEmptyLines``
* ``AcrossComments``
* ``AcrossEmptyLinesAndComments``

For example, to align across empty lines and not across comments, either
of these work.
Expand Down
6 changes: 4 additions & 2 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ Bug Fixes in This Version
- Fixed a crash when trying to transform a dependent address space type. Fixes #GH101685.
- Fixed a crash when diagnosing format strings and encountering an empty
delimited escape sequence (e.g., ``"\o{}"``). #GH102218
- The warning emitted for an unsupported register variable type now points to
the unsupported type instead of the ``register`` keyword (#GH109776).

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -644,8 +646,8 @@ New features
if class of allocation and deallocation function mismatches.
`Documentation <https://clang.llvm.org/docs/analyzer/checkers.html#unix-mismatcheddeallocator-c-c>`__.

- Function effects, e.g. the ``nonblocking`` and ``nonallocating`` "performance constraint"
attributes, are now verified. For example, for functions declared with the ``nonblocking``
- Function effects, e.g. the ``nonblocking`` and ``nonallocating`` "performance constraint"
attributes, are now verified. For example, for functions declared with the ``nonblocking``
attribute, the compiler can generate warnings about the use of any language features, or calls to
other functions, which may block.

Expand Down
13 changes: 7 additions & 6 deletions clang/include/clang/Format/Format.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ struct FormatStyle {
/// Don't align array initializer columns.
AIAS_None
};
/// if not ``None``, when using initialization for an array of structs
/// If not ``None``, when using initialization for an array of structs
/// aligns the fields into columns.
///
/// \note
Expand All @@ -145,11 +145,12 @@ struct FormatStyle {
/// Alignment options.
///
/// They can also be read as a whole for compatibility. The choices are:
/// - None
/// - Consecutive
/// - AcrossEmptyLines
/// - AcrossComments
/// - AcrossEmptyLinesAndComments
///
/// * ``None``
/// * ``Consecutive``
/// * ``AcrossEmptyLines``
/// * ``AcrossComments``
/// * ``AcrossEmptyLinesAndComments``
///
/// For example, to align across empty lines and not across comments, either
/// of these work.
Expand Down
14 changes: 11 additions & 3 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14325,9 +14325,17 @@ void ASTContext::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
Target->initFeatureMap(FeatureMap, getDiagnostics(), TargetCPU, Features);
}
} else if (const auto *TV = FD->getAttr<TargetVersionAttr>()) {
llvm::SmallVector<StringRef, 8> Feats;
TV->getFeatures(Feats);
std::vector<std::string> Features = getFMVBackendFeaturesFor(Feats);
std::vector<std::string> Features;
if (Target->getTriple().isRISCV()) {
ParsedTargetAttr ParsedAttr = Target->parseTargetAttr(TV->getName());
Features.insert(Features.begin(), ParsedAttr.Features.begin(),
ParsedAttr.Features.end());
} else {
assert(Target->getTriple().isAArch64());
llvm::SmallVector<StringRef, 8> Feats;
TV->getFeatures(Feats);
Features = getFMVBackendFeaturesFor(Feats);
}
Features.insert(Features.begin(),
Target->getTargetOpts().FeaturesAsWritten.begin(),
Target->getTargetOpts().FeaturesAsWritten.end());
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,7 @@ class StructAccessBase
}
const Expr *VisitCastExpr(const CastExpr *E) {
if (E->getCastKind() == CK_LValueToRValue)
return E;
return IsExpectedRecordDecl(E) ? E : nullptr;
return Visit(E->getSubExpr());
}
const Expr *VisitParenExpr(const ParenExpr *E) {
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4287,8 +4287,13 @@ void CodeGenModule::emitMultiVersionFunctions() {
} else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) {
if (TVA->isDefaultVersion() && IsDefined)
ShouldEmitResolver = true;
TVA->getFeatures(Feats);
llvm::Function *Func = createFunction(CurFD);
if (getTarget().getTriple().isRISCV()) {
Feats.push_back(TVA->getName());
} else {
assert(getTarget().getTriple().isAArch64());
TVA->getFeatures(Feats);
}
Options.emplace_back(Func, /*Architecture*/ "", Feats);
} else if (const auto *TC = CurFD->getAttr<TargetClonesAttr>()) {
if (IsDefined)
Expand Down
20 changes: 5 additions & 15 deletions clang/lib/Format/Format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,38 +50,33 @@ template <> struct MappingTraits<FormatStyle::AlignConsecutiveStyle> {
{/*Enabled=*/true, /*AcrossEmptyLines=*/false,
/*AcrossComments=*/false, /*AlignCompound=*/false,
/*AlignFunctionDeclarations=*/true,
/*AlignFunctionPointers=*/false,
/*PadOperators=*/true}));
/*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
IO.enumCase(Value, "AcrossEmptyLines",
FormatStyle::AlignConsecutiveStyle(
{/*Enabled=*/true, /*AcrossEmptyLines=*/true,
/*AcrossComments=*/false, /*AlignCompound=*/false,
/*AlignFunctionDeclarations=*/true,
/*AlignFunctionPointers=*/false,
/*PadOperators=*/true}));
/*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
IO.enumCase(Value, "AcrossComments",
FormatStyle::AlignConsecutiveStyle(
{/*Enabled=*/true, /*AcrossEmptyLines=*/false,
/*AcrossComments=*/true, /*AlignCompound=*/false,
/*AlignFunctionDeclarations=*/true,
/*AlignFunctionPointers=*/false,
/*PadOperators=*/true}));
/*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
IO.enumCase(Value, "AcrossEmptyLinesAndComments",
FormatStyle::AlignConsecutiveStyle(
{/*Enabled=*/true, /*AcrossEmptyLines=*/true,
/*AcrossComments=*/true, /*AlignCompound=*/false,
/*AlignFunctionDeclarations=*/true,
/*AlignFunctionPointers=*/false,
/*PadOperators=*/true}));
/*AlignFunctionPointers=*/false, /*PadOperators=*/true}));

// For backward compatibility.
IO.enumCase(Value, "true",
FormatStyle::AlignConsecutiveStyle(
{/*Enabled=*/true, /*AcrossEmptyLines=*/false,
/*AcrossComments=*/false, /*AlignCompound=*/false,
/*AlignFunctionDeclarations=*/true,
/*AlignFunctionPointers=*/false,
/*PadOperators=*/true}));
/*AlignFunctionPointers=*/false, /*PadOperators=*/true}));
IO.enumCase(Value, "false", FormatStyle::AlignConsecutiveStyle({}));
}

Expand Down Expand Up @@ -1445,11 +1440,6 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) {
LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
LLVMStyle.AlignArrayOfStructures = FormatStyle::AIAS_None;
LLVMStyle.AlignConsecutiveAssignments = {};
LLVMStyle.AlignConsecutiveAssignments.AcrossComments = false;
LLVMStyle.AlignConsecutiveAssignments.AcrossEmptyLines = false;
LLVMStyle.AlignConsecutiveAssignments.AlignCompound = false;
LLVMStyle.AlignConsecutiveAssignments.AlignFunctionPointers = false;
LLVMStyle.AlignConsecutiveAssignments.Enabled = false;
LLVMStyle.AlignConsecutiveAssignments.PadOperators = true;
LLVMStyle.AlignConsecutiveBitFields = {};
LLVMStyle.AlignConsecutiveDeclarations = {};
Expand Down
26 changes: 14 additions & 12 deletions clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4910,6 +4910,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
if (Left.is(tok::star) && Right.is(tok::comment))
return true;

const auto *BeforeLeft = Left.Previous;

if (IsCpp) {
if (Left.is(TT_OverloadedOperator) &&
Right.isOneOf(TT_TemplateOpener, TT_TemplateCloser)) {
Expand Down Expand Up @@ -4962,7 +4964,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
if (Left.Tok.getIdentifierInfo() && Right.Tok.isLiteral())
return true;
} else if (Style.isProto()) {
if (Right.is(tok::period) &&
if (Right.is(tok::period) && !(BeforeLeft && BeforeLeft->is(tok::period)) &&
Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
Keywords.kw_repeated, Keywords.kw_extend)) {
return true;
Expand Down Expand Up @@ -5070,8 +5072,8 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
if (Left.is(TT_FatArrow))
return true;
// for await ( ...
if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && Left.Previous &&
Left.Previous->is(tok::kw_for)) {
if (Right.is(tok::l_paren) && Left.is(Keywords.kw_await) && BeforeLeft &&
BeforeLeft->is(tok::kw_for)) {
return true;
}
if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
Expand Down Expand Up @@ -5108,7 +5110,7 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
return false;
// Valid JS method names can include keywords, e.g. `foo.delete()` or
// `bar.instanceof()`. Recognize call positions by preceding period.
if (Left.Previous && Left.Previous->is(tok::period) &&
if (BeforeLeft && BeforeLeft->is(tok::period) &&
Left.Tok.getIdentifierInfo()) {
return false;
}
Expand All @@ -5126,22 +5128,22 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
// "of" is only a keyword if it appears after another identifier
// (e.g. as "const x of y" in a for loop), or after a destructuring
// operation (const [x, y] of z, const {a, b} of c).
(Left.is(Keywords.kw_of) && Left.Previous &&
(Left.Previous->is(tok::identifier) ||
Left.Previous->isOneOf(tok::r_square, tok::r_brace)))) &&
(!Left.Previous || Left.Previous->isNot(tok::period))) {
(Left.is(Keywords.kw_of) && BeforeLeft &&
(BeforeLeft->is(tok::identifier) ||
BeforeLeft->isOneOf(tok::r_square, tok::r_brace)))) &&
(!BeforeLeft || BeforeLeft->isNot(tok::period))) {
return true;
}
if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && Left.Previous &&
Left.Previous->is(tok::period) && Right.is(tok::l_paren)) {
if (Left.isOneOf(tok::kw_for, Keywords.kw_as) && BeforeLeft &&
BeforeLeft->is(tok::period) && Right.is(tok::l_paren)) {
return false;
}
if (Left.is(Keywords.kw_as) &&
Right.isOneOf(tok::l_square, tok::l_brace, tok::l_paren)) {
return true;
}
if (Left.is(tok::kw_default) && Left.Previous &&
Left.Previous->is(tok::kw_export)) {
if (Left.is(tok::kw_default) && BeforeLeft &&
BeforeLeft->is(tok::kw_export)) {
return true;
}
if (Left.is(Keywords.kw_is) && Right.is(tok::l_brace))
Expand Down
13 changes: 10 additions & 3 deletions clang/lib/Headers/pmmintrin.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
__min_vector_width__(128)))
#endif

#if defined(__cplusplus) && (__cplusplus >= 201103L)
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS constexpr
#else
#define __DEFAULT_FN_ATTRS_CONSTEXPR __DEFAULT_FN_ATTRS
#endif

/// Loads data from an unaligned memory location to elements in a 128-bit
/// vector.
///
Expand Down Expand Up @@ -128,7 +134,7 @@ _mm_hsub_ps(__m128 __a, __m128 __b)
/// destination.
/// \returns A 128-bit vector of [4 x float] containing the moved and duplicated
/// values.
static __inline__ __m128 __DEFAULT_FN_ATTRS
static __inline__ __m128 __DEFAULT_FN_ATTRS_CONSTEXPR
_mm_movehdup_ps(__m128 __a)
{
return __builtin_shufflevector((__v4sf)__a, (__v4sf)__a, 1, 1, 3, 3);
Expand All @@ -149,7 +155,7 @@ _mm_movehdup_ps(__m128 __a)
/// destination.
/// \returns A 128-bit vector of [4 x float] containing the moved and duplicated
/// values.
static __inline__ __m128 __DEFAULT_FN_ATTRS
static __inline__ __m128 __DEFAULT_FN_ATTRS_CONSTEXPR
_mm_moveldup_ps(__m128 __a)
{
return __builtin_shufflevector((__v4sf)__a, (__v4sf)__a, 0, 0, 2, 2);
Expand Down Expand Up @@ -250,7 +256,7 @@ _mm_hsub_pd(__m128d __a, __m128d __b)
/// [127:64] and [63:0] of the destination.
/// \returns A 128-bit vector of [2 x double] containing the moved and
/// duplicated values.
static __inline__ __m128d __DEFAULT_FN_ATTRS
static __inline__ __m128d __DEFAULT_FN_ATTRS_CONSTEXPR
_mm_movedup_pd(__m128d __a)
{
return __builtin_shufflevector((__v2df)__a, (__v2df)__a, 0, 0);
Expand Down Expand Up @@ -303,5 +309,6 @@ _mm_mwait(unsigned __extensions, unsigned __hints)
}

#undef __DEFAULT_FN_ATTRS
#undef __DEFAULT_FN_ATTRS_CONSTEXPR

#endif /* __PMMINTRIN_H */
10 changes: 2 additions & 8 deletions clang/lib/Sema/SemaARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,23 +567,17 @@ static bool checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
// * When compiling for SVE only, the caller must be in non-streaming mode.
// * When compiling for both SVE and SME, the caller can be in either mode.
if (BuiltinType == SemaARM::VerifyRuntimeMode) {
auto DisableFeatures = [](llvm::StringMap<bool> &Map, StringRef S) {
for (StringRef K : Map.keys())
if (K.starts_with(S))
Map[K] = false;
};

llvm::StringMap<bool> CallerFeatureMapWithoutSVE;
S.Context.getFunctionFeatureMap(CallerFeatureMapWithoutSVE, FD);
DisableFeatures(CallerFeatureMapWithoutSVE, "sve");
CallerFeatureMapWithoutSVE["sve"] = false;

// Avoid emitting diagnostics for a function that can never compile.
if (FnType == SemaARM::ArmStreaming && !CallerFeatureMapWithoutSVE["sme"])
return false;

llvm::StringMap<bool> CallerFeatureMapWithoutSME;
S.Context.getFunctionFeatureMap(CallerFeatureMapWithoutSME, FD);
DisableFeatures(CallerFeatureMapWithoutSME, "sme");
CallerFeatureMapWithoutSME["sme"] = false;

// We know the builtin requires either some combination of SVE flags, or
// some combination of SME flags, but we need to figure out which part
Expand Down
23 changes: 18 additions & 5 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7957,7 +7957,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}

if (!R->isIntegralType(Context) && !R->isPointerType()) {
Diag(D.getBeginLoc(), diag::err_asm_bad_register_type);
Diag(TInfo->getTypeLoc().getBeginLoc(), diag::err_asm_bad_register_type)
<< TInfo->getTypeLoc().getSourceRange();
NewVD->setInvalidDecl(true);
}
}
Expand Down Expand Up @@ -10329,7 +10330,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Handle attributes.
ProcessDeclAttributes(S, NewFD, D);
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
if (NewTVA && !NewTVA->isDefaultVersion() &&
if (Context.getTargetInfo().getTriple().isAArch64() && NewTVA &&
!NewTVA->isDefaultVersion() &&
!Context.getTargetInfo().hasFeature("fmv")) {
// Don't add to scope fmv functions declarations if fmv disabled
AddToScope = false;
Expand Down Expand Up @@ -11038,7 +11040,16 @@ static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) {

if (TVA) {
llvm::SmallVector<StringRef, 8> Feats;
TVA->getFeatures(Feats);
ParsedTargetAttr ParseInfo;
if (S.getASTContext().getTargetInfo().getTriple().isRISCV()) {
ParseInfo =
S.getASTContext().getTargetInfo().parseTargetAttr(TVA->getName());
for (auto &Feat : ParseInfo.Features)
Feats.push_back(StringRef{Feat}.substr(1));
} else {
assert(S.getASTContext().getTargetInfo().getTriple().isAArch64());
TVA->getFeatures(Feats);
}
for (const auto &Feat : Feats) {
if (!TargetInfo.validateCpuSupports(Feat)) {
S.Diag(FD->getLocation(), diag::err_bad_multiversion_option)
Expand Down Expand Up @@ -11324,7 +11335,8 @@ static bool PreviousDeclsHaveMultiVersionAttribute(const FunctionDecl *FD) {
}

static void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) {
if (!From->getASTContext().getTargetInfo().getTriple().isAArch64())
if (!From->getASTContext().getTargetInfo().getTriple().isAArch64() &&
!From->getASTContext().getTargetInfo().getTriple().isRISCV())
return;

MultiVersionKind MVKindFrom = From->getMultiVersionKind();
Expand Down Expand Up @@ -15511,7 +15523,8 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
FD->setInvalidDecl();
}
if (const auto *Attr = FD->getAttr<TargetVersionAttr>()) {
if (!Context.getTargetInfo().hasFeature("fmv") &&
if (Context.getTargetInfo().getTriple().isAArch64() &&
!Context.getTargetInfo().hasFeature("fmv") &&
!Attr->isDefaultVersion()) {
// If function multi versioning disabled skip parsing function body
// defined with non-default target_version attribute
Expand Down
48 changes: 48 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3040,6 +3040,54 @@ bool Sema::checkTargetVersionAttr(SourceLocation LiteralLoc, Decl *D,
enum SecondParam { None };
enum ThirdParam { Target, TargetClones, TargetVersion };
llvm::SmallVector<StringRef, 8> Features;
if (Context.getTargetInfo().getTriple().isRISCV()) {
llvm::SmallVector<StringRef, 8> AttrStrs;
AttrStr.split(AttrStrs, ';');

bool HasArch = false;
bool HasPriority = false;
bool HasDefault = false;
bool DuplicateAttr = false;
for (auto &AttrStr : AttrStrs) {
// Only support arch=+ext,... syntax.
if (AttrStr.starts_with("arch=+")) {
if (HasArch)
DuplicateAttr = true;
HasArch = true;
ParsedTargetAttr TargetAttr =
Context.getTargetInfo().parseTargetAttr(AttrStr);

if (TargetAttr.Features.empty() ||
llvm::any_of(TargetAttr.Features, [&](const StringRef Ext) {
return !RISCV().isValidFMVExtension(Ext);
}))
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << AttrStr << TargetVersion;
} else if (AttrStr.starts_with("default")) {
if (HasDefault)
DuplicateAttr = true;
HasDefault = true;
} else if (AttrStr.consume_front("priority=")) {
if (HasPriority)
DuplicateAttr = true;
HasPriority = true;
int Digit;
if (AttrStr.getAsInteger(0, Digit))
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << AttrStr << TargetVersion;
} else {
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << AttrStr << TargetVersion;
}
}

if (((HasPriority || HasArch) && HasDefault) || DuplicateAttr ||
(HasPriority && !HasArch))
return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
<< Unsupported << None << AttrStr << TargetVersion;

return false;
}
AttrStr.split(Features, "+");
for (auto &CurFeature : Features) {
CurFeature = CurFeature.trim();
Expand Down
11 changes: 5 additions & 6 deletions clang/lib/Sema/SemaFunctionEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1048,15 +1048,14 @@ class Analyzer {
}

void checkIndirectCall(CallExpr *Call, QualType CalleeType) {
auto *FPT =
CalleeType->getAs<FunctionProtoType>(); // Null if FunctionType.
FunctionEffectKindSet CalleeEffects;
if (FPT)
CalleeEffects.insert(FPT->getFunctionEffects());
if (FunctionEffectsRef Effects = FunctionEffectsRef::get(CalleeType);
!Effects.empty())
CalleeEffects.insert(Effects);

auto Check1Effect = [&](FunctionEffect Effect, bool Inferring) {
if (FPT == nullptr || Effect.shouldDiagnoseFunctionCall(
/*direct=*/false, CalleeEffects))
if (Effect.shouldDiagnoseFunctionCall(
/*direct=*/false, CalleeEffects))
addViolation(Inferring, Effect, ViolationID::CallsExprWithoutEffect,
Call->getBeginLoc());
};
Expand Down
19 changes: 19 additions & 0 deletions clang/test/CodeGen/X86/sse3-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,22 @@ __m128 test_mm_moveldup_ps(__m128 A) {
// CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x i32> <i32 0, i32 0, i32 2, i32 2>
return _mm_moveldup_ps(A);
}

// Test constexpr handling.
#if defined(__cplusplus) && (__cplusplus >= 201103L)

void test_constexpr() {
constexpr __m128d kd1 {+7.0,-7.0};
constexpr __m128 kf1 {+1.0f,-1.0f,+2.0f,+4.0f};

constexpr __m128d v_mm_movedup_pd = _mm_movedup_pd(kd1);
static_assert(v_mm_movedup_pd[0] == +7.0 && v_mm_movedup_pd[1] == +7.0);

constexpr __m128 v_mm_movehdup_ps = _mm_movehdup_ps(kf1);
static_assert(v_mm_movehdup_ps[0] == -1.0f && v_mm_movehdup_ps[1] == -1.0f && v_mm_movehdup_ps[2] == +4.0f && v_mm_movehdup_ps[3] == +4.0f);

constexpr __m128 v_mm_moveldup_ps = _mm_moveldup_ps(kf1);
static_assert(v_mm_moveldup_ps[0] == +1.0f && v_mm_moveldup_ps[1] == +1.0f && v_mm_moveldup_ps[2] == +2.0f && v_mm_moveldup_ps[3] == +2.0f);
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

// REQUIRES: aarch64-registered-target

// RUN: %clang_cc1 -triple aarch64 -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s

#include <arm_sme.h>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

// REQUIRES: aarch64-registered-target

// RUN: %clang_cc1 -triple aarch64 -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK
// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s

#include <arm_sme.h>

Expand Down
13 changes: 13 additions & 0 deletions clang/test/CodeGen/attr-target-version-riscv-invalid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: not %clang_cc1 -triple riscv64 -target-feature +i -emit-llvm -o - %s 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORT-OS

// CHECK-UNSUPPORT-OS: error: function multiversioning is currently only supported on Linux
__attribute__((target_version("default"))) int foo(void) {
return 2;
}

__attribute__((target_version("arch=+c"))) int foo(void) {
return 2;
}


int bar() { return foo(); }
443 changes: 443 additions & 0 deletions clang/test/CodeGen/attr-target-version-riscv.c

Large diffs are not rendered by default.

432 changes: 432 additions & 0 deletions clang/test/CodeGenCXX/attr-target-version-riscv.cpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions clang/test/Modules/embed-files-compressed.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// RUN: %clang_cc1 -fmodules -I%t -fmodules-cache-path=%t -fmodule-name=a -emit-module %t/modulemap -fmodules-embed-all-files -o %t/a.pcm
//
// The above embeds ~4.5MB of highly-predictable /s and \ns into the pcm file.
// Check that the resulting file is under 60KB:
// Check that the resulting file is under 80KB:
//
// RUN: wc -c %t/a.pcm | FileCheck --check-prefix=CHECK-SIZE %s
// CHECK-SIZE: {{(^|[^0-9])[1-5][0-9][0-9][0-9][0-9]($|[^0-9])}}
// CHECK-SIZE: {{(^|[^0-9])[1-7][0-9][0-9][0-9][0-9]($|[^0-9])}}
16 changes: 8 additions & 8 deletions clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_add_sub_za16.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@

void test_features(uint32_t slice, svfloat16x2_t zn2, svfloat16x4_t zn4,
svbfloat16x2_t bzn2, svbfloat16x4_t bzn4) __arm_streaming __arm_inout("za") {
// expected-error@+1 {{'svadd_za16_f16_vg1x2' needs target feature sme-f16f16|sme-f8f16}}
// expected-error@+1 {{'svadd_za16_f16_vg1x2' needs target feature sme,(sme-f16f16|sme-f8f16)}}
svadd_za16_f16_vg1x2(slice, zn2);
// expected-error@+1 {{'svadd_za16_f16_vg1x4' needs target feature sme-f16f16|sme-f8f16}}
// expected-error@+1 {{'svadd_za16_f16_vg1x4' needs target feature sme,(sme-f16f16|sme-f8f16)}}
svadd_za16_f16_vg1x4(slice, zn4);
// expected-error@+1 {{'svsub_za16_f16_vg1x2' needs target feature sme-f16f16|sme-f8f16}}
// expected-error@+1 {{'svsub_za16_f16_vg1x2' needs target feature sme,(sme-f16f16|sme-f8f16)}}
svsub_za16_f16_vg1x2(slice, zn2);
// expected-error@+1 {{'svsub_za16_f16_vg1x4' needs target feature sme-f16f16|sme-f8f16}}
// expected-error@+1 {{'svsub_za16_f16_vg1x4' needs target feature sme,(sme-f16f16|sme-f8f16)}}
svsub_za16_f16_vg1x4(slice, zn4);

// expected-error@+1 {{'svadd_za16_bf16_vg1x2' needs target feature sme-b16b16}}
// expected-error@+1 {{'svadd_za16_bf16_vg1x2' needs target feature sme,sme-b16b16}}
svadd_za16_bf16_vg1x2(slice, bzn2);
// expected-error@+1 {{'svadd_za16_bf16_vg1x4' needs target feature sme-b16b16}}
// expected-error@+1 {{'svadd_za16_bf16_vg1x4' needs target feature sme,sme-b16b16}}
svadd_za16_bf16_vg1x4(slice, bzn4);
// expected-error@+1 {{'svsub_za16_bf16_vg1x2' needs target feature sme-b16b16}}
// expected-error@+1 {{'svsub_za16_bf16_vg1x2' needs target feature sme,sme-b16b16}}
svsub_za16_bf16_vg1x2(slice, bzn2);
// expected-error@+1 {{'svsub_za16_bf16_vg1x4' needs target feature sme-b16b16}}
// expected-error@+1 {{'svsub_za16_bf16_vg1x4' needs target feature sme,sme-b16b16}}
svsub_za16_bf16_vg1x4(slice, bzn4);
}

Expand Down
38 changes: 19 additions & 19 deletions clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_b16b16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,45 @@

void test_b16b16( svbfloat16_t bf16, svbfloat16x2_t bf16x2, svbfloat16x4_t bf16x4) __arm_streaming
{
// expected-error@+1 {{'svclamp_single_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svclamp_single_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svclamp_single_bf16_x2(bf16x2, bf16, bf16);
// expected-error@+1 {{'svclamp_single_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svclamp_single_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svclamp_single_bf16_x4(bf16x4, bf16, bf16);

// expected-error@+1 {{'svmax_single_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmax_single_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svmax_single_bf16_x2(bf16x2, bf16);
// expected-error@+1 {{'svmax_single_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmax_single_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svmax_single_bf16_x4(bf16x4, bf16);
// expected-error@+1 {{'svmax_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmax_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svmax_bf16_x2(bf16x2, bf16x2);
// expected-error@+1 {{'svmax_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmax_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svmax_bf16_x4(bf16x4, bf16x4);

// expected-error@+1 {{'svmaxnm_single_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmaxnm_single_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svmaxnm_single_bf16_x2(bf16x2, bf16);
// expected-error@+1 {{'svmaxnm_single_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmaxnm_single_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svmaxnm_single_bf16_x4(bf16x4, bf16);
// expected-error@+1 {{'svmaxnm_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmaxnm_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svmaxnm_bf16_x2(bf16x2, bf16x2);
// expected-error@+1 {{'svmaxnm_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmaxnm_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svmaxnm_bf16_x4(bf16x4, bf16x4);

// expected-error@+1 {{'svmin_single_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmin_single_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svmin_single_bf16_x2(bf16x2, bf16);
// expected-error@+1 {{'svmin_single_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmin_single_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svmin_single_bf16_x4(bf16x4, bf16);
// expected-error@+1 {{'svmin_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmin_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svmin_bf16_x2(bf16x2, bf16x2);
// expected-error@+1 {{'svmin_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svmin_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svmin_bf16_x4(bf16x4, bf16x4);

// expected-error@+1 {{'svminnm_single_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svminnm_single_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svminnm_single_bf16_x2(bf16x2, bf16);
// expected-error@+1 {{'svminnm_single_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svminnm_single_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svminnm_single_bf16_x4(bf16x4, bf16);

// expected-error@+1 {{'svminnm_bf16_x2' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svminnm_bf16_x2' needs target feature sme,sme2,sve-b16b16}}
svminnm_bf16_x2(bf16x2, bf16x2);
// expected-error@+1 {{'svminnm_bf16_x4' needs target feature sme2,sve-b16b16}}
// expected-error@+1 {{'svminnm_bf16_x4' needs target feature sme,sme2,sve-b16b16}}
svminnm_bf16_x4(bf16x4, bf16x4);
}
}
48 changes: 24 additions & 24 deletions clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_fmlas16.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,54 +14,54 @@ void test_features_f16f16(uint32_t slice,
svbfloat16x4_t bzn4, svbfloat16x4_t bzm4)

__arm_streaming __arm_inout("za") {
// expected-error@+1 {{'svmla_single_za16_f16_vg1x2' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmla_single_za16_f16_vg1x2' needs target feature sme,sme-f16f16}}
svmla_single_za16_f16_vg1x2(slice, zn2, zm);
// expected-error@+1 {{'svmla_single_za16_f16_vg1x4' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmla_single_za16_f16_vg1x4' needs target feature sme,sme-f16f16}}
svmla_single_za16_f16_vg1x4(slice, zn4, zm);
// expected-error@+1 {{'svmls_single_za16_f16_vg1x2' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmls_single_za16_f16_vg1x2' needs target feature sme,sme-f16f16}}
svmls_single_za16_f16_vg1x2(slice, zn2, zm);
// expected-error@+1 {{'svmls_single_za16_f16_vg1x4' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmls_single_za16_f16_vg1x4' needs target feature sme,sme-f16f16}}
svmls_single_za16_f16_vg1x4(slice, zn4, zm);
// expected-error@+1 {{'svmla_za16_f16_vg1x2' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmla_za16_f16_vg1x2' needs target feature sme,sme-f16f16}}
svmla_za16_f16_vg1x2(slice, zn2, zm2);
// expected-error@+1 {{'svmla_za16_f16_vg1x4' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmla_za16_f16_vg1x4' needs target feature sme,sme-f16f16}}
svmla_za16_f16_vg1x4(slice, zn4, zm4);
// expected-error@+1 {{'svmls_za16_f16_vg1x2' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmls_za16_f16_vg1x2' needs target feature sme,sme-f16f16}}
svmls_za16_f16_vg1x2(slice, zn2, zm2);
// expected-error@+1 {{'svmls_za16_f16_vg1x4' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmls_za16_f16_vg1x4' needs target feature sme,sme-f16f16}}
svmls_za16_f16_vg1x4(slice, zn4, zm4);
// expected-error@+1 {{'svmla_lane_za16_f16_vg1x2' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmla_lane_za16_f16_vg1x2' needs target feature sme,sme-f16f16}}
svmla_lane_za16_f16_vg1x2(slice, zn2, zm, 7);
// expected-error@+1 {{'svmla_lane_za16_f16_vg1x4' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmla_lane_za16_f16_vg1x4' needs target feature sme,sme-f16f16}}
svmla_lane_za16_f16_vg1x4(slice, zn4, zm, 7);
// expected-error@+1 {{'svmls_lane_za16_f16_vg1x2' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmls_lane_za16_f16_vg1x2' needs target feature sme,sme-f16f16}}
svmls_lane_za16_f16_vg1x2(slice, zn2, zm, 7);
// expected-error@+1 {{'svmls_lane_za16_f16_vg1x4' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmls_lane_za16_f16_vg1x4' needs target feature sme,sme-f16f16}}
svmls_lane_za16_f16_vg1x4(slice, zn4, zm, 7);

// expected-error@+1 {{'svmla_single_za16_bf16_vg1x2' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmla_single_za16_bf16_vg1x2' needs target feature sme,sme-b16b16}}
svmla_single_za16_bf16_vg1x2(slice, bzn2, bzm);
// expected-error@+1 {{'svmla_single_za16_bf16_vg1x4' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmla_single_za16_bf16_vg1x4' needs target feature sme,sme-b16b16}}
svmla_single_za16_bf16_vg1x4(slice, bzn4, bzm);
// expected-error@+1 {{'svmls_single_za16_bf16_vg1x2' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmls_single_za16_bf16_vg1x2' needs target feature sme,sme-b16b16}}
svmls_single_za16_bf16_vg1x2(slice, bzn2, bzm);
// expected-error@+1 {{'svmls_single_za16_bf16_vg1x4' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmls_single_za16_bf16_vg1x4' needs target feature sme,sme-b16b16}}
svmls_single_za16_bf16_vg1x4(slice, bzn4, bzm);
// expected-error@+1 {{'svmla_za16_bf16_vg1x2' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmla_za16_bf16_vg1x2' needs target feature sme,sme-b16b16}}
svmla_za16_bf16_vg1x2(slice, bzn2, bzm2);
// expected-error@+1 {{'svmla_za16_bf16_vg1x4' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmla_za16_bf16_vg1x4' needs target feature sme,sme-b16b16}}
svmla_za16_bf16_vg1x4(slice, bzn4, bzm4);
// expected-error@+1 {{'svmls_za16_bf16_vg1x2' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmls_za16_bf16_vg1x2' needs target feature sme,sme-b16b16}}
svmls_za16_bf16_vg1x2(slice, bzn2, bzm2);
// expected-error@+1 {{'svmls_za16_bf16_vg1x4' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmls_za16_bf16_vg1x4' needs target feature sme,sme-b16b16}}
svmls_za16_bf16_vg1x4(slice, bzn4, bzm4);
// expected-error@+1 {{'svmla_lane_za16_bf16_vg1x2' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmla_lane_za16_bf16_vg1x2' needs target feature sme,sme-b16b16}}
svmla_lane_za16_bf16_vg1x2(slice, bzn2, bzm, 7);
// expected-error@+1 {{'svmla_lane_za16_bf16_vg1x4' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmla_lane_za16_bf16_vg1x4' needs target feature sme,sme-b16b16}}
svmla_lane_za16_bf16_vg1x4(slice, bzn4, bzm, 7);
// expected-error@+1 {{'svmls_lane_za16_bf16_vg1x2' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmls_lane_za16_bf16_vg1x2' needs target feature sme,sme-b16b16}}
svmls_lane_za16_bf16_vg1x2(slice, bzn2, bzm, 7);
// expected-error@+1 {{'svmls_lane_za16_bf16_vg1x4' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmls_lane_za16_bf16_vg1x4' needs target feature sme,sme-b16b16}}
svmls_lane_za16_bf16_vg1x4(slice, bzn4, bzm, 7);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ void test_features(svbool_t pn, svbool_t pm,
svfloat16_t zn, svfloat16_t zm,
svbfloat16_t znb, svbfloat16_t zmb)
__arm_streaming __arm_inout("za") {
// expected-error@+1 {{'svmopa_za16_bf16_m' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmopa_za16_bf16_m' needs target feature sme,sme-b16b16}}
svmopa_za16_bf16_m(0, pn, pm, znb, zmb);
// expected-error@+1 {{'svmops_za16_bf16_m' needs target feature sme-b16b16}}
// expected-error@+1 {{'svmops_za16_bf16_m' needs target feature sme,sme-b16b16}}
svmops_za16_bf16_m(0, pn, pm, znb, zmb);
// expected-error@+1 {{'svmopa_za16_f16_m' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmopa_za16_f16_m' needs target feature sme,sme-f16f16}}
svmopa_za16_f16_m(0, pn, pm, zn, zm);
// expected-error@+1 {{'svmops_za16_f16_m' needs target feature sme-f16f16}}
// expected-error@+1 {{'svmops_za16_f16_m' needs target feature sme,sme-f16f16}}
svmops_za16_f16_m(0, pn, pm, zn, zm);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ svfloat32_t good6(svfloat32_t a, svfloat32_t b, svfloat32_t c) __arm_streaming_c
return svclamp(a, b, c);
}

// Test that the +sve-b16b16 is not considered an SVE flag (it applies to both)
__attribute__((target("+sme2,+sve2,+sve-b16b16")))
svbfloat16_t good7(svbfloat16_t a, svbfloat16_t b, svbfloat16_t c) __arm_streaming {
return svclamp_bf16(a, b, c);
}

// Without '+sme2', the builtin is only valid in non-streaming mode.
__attribute__((target("+sve2p1,+sme")))
svfloat32_t bad1(svfloat32_t a, svfloat32_t b, svfloat32_t c) __arm_streaming {
Expand Down
6,580 changes: 3,290 additions & 3,290 deletions clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2.cpp

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,116 +14,116 @@

void test(uint8_t u8, uint16_t u16, uint32_t u32, uint64_t u64)
{
// expected-error@+2 {{'svaesd_u8' needs target feature sve2-aes}}
// overload-error@+1 {{'svaesd' needs target feature sve2-aes}}
// expected-error@+2 {{'svaesd_u8' needs target feature sve,sve2-aes}}
// overload-error@+1 {{'svaesd' needs target feature sve,sve2-aes}}
SVE_ACLE_FUNC(svaesd,_u8,,)(svundef_u8(), svundef_u8());
// expected-error@+2 {{'svaese_u8' needs target feature sve2-aes}}
// overload-error@+1 {{'svaese' needs target feature sve2-aes}}
// expected-error@+2 {{'svaese_u8' needs target feature sve,sve2-aes}}
// overload-error@+1 {{'svaese' needs target feature sve,sve2-aes}}
SVE_ACLE_FUNC(svaese,_u8,,)(svundef_u8(), svundef_u8());
// expected-error@+2 {{'svaesimc_u8' needs target feature sve2-aes}}
// overload-error@+1 {{'svaesimc' needs target feature sve2-aes}}
// expected-error@+2 {{'svaesimc_u8' needs target feature sve,sve2-aes}}
// overload-error@+1 {{'svaesimc' needs target feature sve,sve2-aes}}
SVE_ACLE_FUNC(svaesimc,_u8,,)(svundef_u8());
// expected-error@+2 {{'svaesmc_u8' needs target feature sve2-aes}}
// overload-error@+1 {{'svaesmc' needs target feature sve2-aes}}
// expected-error@+2 {{'svaesmc_u8' needs target feature sve,sve2-aes}}
// overload-error@+1 {{'svaesmc' needs target feature sve,sve2-aes}}
SVE_ACLE_FUNC(svaesmc,_u8,,)(svundef_u8());
// expected-error@+2 {{'svbdep_u8' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbdep_u8' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbdep,_u8,,)(svundef_u8(), svundef_u8());
// expected-error@+2 {{'svbdep_n_u8' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbdep_n_u8' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbdep,_n_u8,,)(svundef_u8(), u8);
// expected-error@+2 {{'svbext_u8' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbext_u8' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbext,_u8,,)(svundef_u8(), svundef_u8());
// expected-error@+2 {{'svbext_n_u8' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbext_n_u8' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbext,_n_u8,,)(svundef_u8(), u8);
// expected-error@+2 {{'svbgrp_u8' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbgrp_u8' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbgrp,_u8,,)(svundef_u8(), svundef_u8());
// expected-error@+2 {{'svbgrp_n_u8' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbgrp_n_u8' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbgrp,_n_u8,,)(svundef_u8(), u8);

// expected-error@+2 {{'svbdep_u16' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbdep_u16' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbdep,_u16,,)(svundef_u16(), svundef_u16());
// expected-error@+2 {{'svbdep_n_u16' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbdep_n_u16' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbdep,_n_u16,,)(svundef_u16(), u16);
// expected-error@+2 {{'svbext_u16' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbext_u16' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbext,_u16,,)(svundef_u16(), svundef_u16());
// expected-error@+2 {{'svbext_n_u16' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbext_n_u16' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbext,_n_u16,,)(svundef_u16(), u16);
// expected-error@+2 {{'svbgrp_u16' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbgrp_u16' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbgrp,_u16,,)(svundef_u16(), svundef_u16());
// expected-error@+2 {{'svbgrp_n_u16' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbgrp_n_u16' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbgrp,_n_u16,,)(svundef_u16(), u16);

// expected-error@+2 {{'svbdep_u32' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbdep_u32' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbdep,_u32,,)(svundef_u32(), svundef_u32());
// expected-error@+2 {{'svbdep_n_u32' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbdep_n_u32' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbdep,_n_u32,,)(svundef_u32(), u32);
// expected-error@+2 {{'svbext_u32' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbext_u32' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbext,_u32,,)(svundef_u32(), svundef_u32());
// expected-error@+2 {{'svbext_n_u32' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbext_n_u32' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbext,_n_u32,,)(svundef_u32(), u32);
// expected-error@+2 {{'svbgrp_u32' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbgrp_u32' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbgrp,_u32,,)(svundef_u32(), svundef_u32());
// expected-error@+2 {{'svbgrp_n_u32' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbgrp_n_u32' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbgrp,_n_u32,,)(svundef_u32(), u32);
// expected-error@+2 {{'svsm4e_u32' needs target feature sve2-sm4}}
// overload-error@+1 {{'svsm4e' needs target feature sve2-sm4}}
// expected-error@+2 {{'svsm4e_u32' needs target feature sve,sve2-sm4}}
// overload-error@+1 {{'svsm4e' needs target feature sve,sve2-sm4}}
SVE_ACLE_FUNC(svsm4e,_u32,,)(svundef_u32(), svundef_u32());
// expected-error@+2 {{'svsm4ekey_u32' needs target feature sve2-sm4}}
// overload-error@+1 {{'svsm4ekey' needs target feature sve2-sm4}}
// expected-error@+2 {{'svsm4ekey_u32' needs target feature sve,sve2-sm4}}
// overload-error@+1 {{'svsm4ekey' needs target feature sve,sve2-sm4}}
SVE_ACLE_FUNC(svsm4ekey,_u32,,)(svundef_u32(), svundef_u32());

// expected-error@+2 {{'svbdep_u64' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbdep_u64' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbdep,_u64,,)(svundef_u64(), svundef_u64());
// expected-error@+2 {{'svbdep_n_u64' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbdep_n_u64' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbdep' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbdep,_n_u64,,)(svundef_u64(), u64);
// expected-error@+2 {{'svbext_u64' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbext_u64' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbext,_u64,,)(svundef_u64(), svundef_u64());
// expected-error@+2 {{'svbext_n_u64' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbext_n_u64' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbext' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbext,_n_u64,,)(svundef_u64(), u64);
// expected-error@+2 {{'svbgrp_u64' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbgrp_u64' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbgrp,_u64,,)(svundef_u64(), svundef_u64());
// expected-error@+2 {{'svbgrp_n_u64' needs target feature sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve2-bitperm}}
// expected-error@+2 {{'svbgrp_n_u64' needs target feature sve,sve2-bitperm}}
// overload-error@+1 {{'svbgrp' needs target feature sve,sve2-bitperm}}
SVE_ACLE_FUNC(svbgrp,_n_u64,,)(svundef_u64(), u64);
// expected-error@+2 {{'svpmullb_pair_u64' needs target feature sve2-aes}}
// overload-error@+1 {{'svpmullb_pair' needs target feature sve2-aes}}
// expected-error@+2 {{'svpmullb_pair_u64' needs target feature sve,sve2-aes}}
// overload-error@+1 {{'svpmullb_pair' needs target feature sve,sve2-aes}}
SVE_ACLE_FUNC(svpmullb_pair,_u64,,)(svundef_u64(), svundef_u64());
// expected-error@+2 {{'svpmullb_pair_n_u64' needs target feature sve2-aes}}
// overload-error@+1 {{'svpmullb_pair' needs target feature sve2-aes}}
// expected-error@+2 {{'svpmullb_pair_n_u64' needs target feature sve,sve2-aes}}
// overload-error@+1 {{'svpmullb_pair' needs target feature sve,sve2-aes}}
SVE_ACLE_FUNC(svpmullb_pair,_n_u64,,)(svundef_u64(), u64);
// expected-error@+2 {{'svpmullt_pair_u64' needs target feature sve2-aes}}
// overload-error@+1 {{'svpmullt_pair' needs target feature sve2-aes}}
// expected-error@+2 {{'svpmullt_pair_u64' needs target feature sve,sve2-aes}}
// overload-error@+1 {{'svpmullt_pair' needs target feature sve,sve2-aes}}
SVE_ACLE_FUNC(svpmullt_pair,_u64,,)(svundef_u64(), svundef_u64());
// expected-error@+2 {{'svpmullt_pair_n_u64' needs target feature sve2-aes}}
// overload-error@+1 {{'svpmullt_pair' needs target feature sve2-aes}}
// expected-error@+2 {{'svpmullt_pair_n_u64' needs target feature sve,sve2-aes}}
// overload-error@+1 {{'svpmullt_pair' needs target feature sve,sve2-aes}}
SVE_ACLE_FUNC(svpmullt_pair,_n_u64,,)(svundef_u64(), u64);
// expected-error@+2 {{'svrax1_u64' needs target feature sve2-sha3}}
// overload-error@+1 {{'svrax1' needs target feature sve2-sha3}}
// expected-error@+2 {{'svrax1_u64' needs target feature sve,sve2-sha3}}
// overload-error@+1 {{'svrax1' needs target feature sve,sve2-sha3}}
SVE_ACLE_FUNC(svrax1,_u64,,)(svundef_u64(), svundef_u64());

// expected-error@+2 {{'svrax1_s64' needs target feature sve2-sha3}}
// overload-error@+1 {{'svrax1' needs target feature sve2-sha3}}
// expected-error@+2 {{'svrax1_s64' needs target feature sve,sve2-sha3}}
// overload-error@+1 {{'svrax1' needs target feature sve,sve2-sha3}}
SVE_ACLE_FUNC(svrax1,_s64,,)(svundef_s64(), svundef_s64());
}
16 changes: 8 additions & 8 deletions clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_bfloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@

void test_bfloat(const bfloat16_t *const_bf16_ptr, svbfloat16_t bf16, svbfloat16x2_t bf16x2)
{
// expected-error@+2 {{'svwhilerw_bf16' needs target feature (sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svwhilerw' needs target feature (sve2,bf16)|(sme,bf16)}}
// expected-error@+2 {{'svwhilerw_bf16' needs target feature (sve,sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svwhilerw' needs target feature (sve,sve2,bf16)|(sme,bf16)}}
SVE_ACLE_FUNC(svwhilerw,_bf16,,)(const_bf16_ptr, const_bf16_ptr);
// expected-error@+2 {{'svtbx_bf16' needs target feature (sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svtbx' needs target feature (sve2,bf16)|(sme,bf16)}}
// expected-error@+2 {{'svtbx_bf16' needs target feature (sve,sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svtbx' needs target feature (sve,sve2,bf16)|(sme,bf16)}}
SVE_ACLE_FUNC(svtbx,_bf16,,)(bf16, bf16, svundef_u16());
// expected-error@+2 {{'svtbl2_bf16' needs target feature (sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svtbl2' needs target feature (sve2,bf16)|(sme,bf16)}}
// expected-error@+2 {{'svtbl2_bf16' needs target feature (sve,sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svtbl2' needs target feature (sve,sve2,bf16)|(sme,bf16)}}
SVE_ACLE_FUNC(svtbl2,_bf16,,)(bf16x2, svundef_u16());
// expected-error@+2 {{'svwhilewr_bf16' needs target feature (sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svwhilewr' needs target feature (sve2,bf16)|(sme,bf16)}}
// expected-error@+2 {{'svwhilewr_bf16' needs target feature (sve,sve2,bf16)|(sme,bf16)}}
// overload-error@+1 {{'svwhilewr' needs target feature (sve,sve2,bf16)|(sme,bf16)}}
SVE_ACLE_FUNC(svwhilewr,_bf16,,)(const_bf16_ptr, const_bf16_ptr);
}
24 changes: 12 additions & 12 deletions clang/test/Sema/aarch64-sve2p1-intrinsics/acle_sve2p1_b16b16.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,28 +29,28 @@ void test_with_sve_b16b16(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfl

void test_no_sve_b16b16(svbool_t pg, svbfloat16_t op1, svbfloat16_t op2, svbfloat16_t op3) MODE_ATTR
{
// expected-error@+1 {{'svclamp_bf16' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svclamp_bf16' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svclamp_bf16(op1, op2, op3);
// expected-error@+1 {{'svadd_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svadd_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svadd_bf16_m(pg, op1, op2);
// expected-error@+1 {{'svmax_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svmax_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svmax_bf16_m(pg, op1, op2);
// expected-error@+1 {{'svmaxnm_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svmaxnm_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svmaxnm_bf16_m(pg, op1, op2);
// expected-error@+1 {{'svmin_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svmin_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svmin_bf16_m(pg, op1, op2);
// expected-error@+1 {{'svminnm_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svminnm_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svminnm_bf16_m(pg, op1, op2);
// expected-error@+1 {{'svmla_lane_bf16' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svmla_lane_bf16' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svmla_lane_bf16(op1, op2, op3, 1);
// expected-error@+1 {{'svmla_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svmla_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svmla_bf16_m(pg, op1, op2, op3);
// expected-error@+1 {{'svmls_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svmls_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svmls_bf16_m(pg, op1, op2, op3);
// expected-error@+1 {{'svmul_lane_bf16' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svmul_lane_bf16' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svmul_lane_bf16(op1, op2, 1);
// expected-error@+1 {{'svmul_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svmul_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svmul_bf16_m(pg, op1, op2);
// expected-error@+1 {{'svsub_bf16_m' needs target feature (sve2,sve-b16b16)|(sme2,sve-b16b16)}}
// expected-error@+1 {{'svsub_bf16_m' needs target feature (sve,sve2,sve-b16b16)|(sme,sme2,sve-b16b16)}}
svsub_bf16_m(pg, op1, op2);
}
11 changes: 11 additions & 0 deletions clang/test/Sema/attr-nonblocking-constraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,17 @@ void nb10(
static_cast<void (*)()>(fp1)(); // expected-warning {{function with 'nonblocking' attribute must not call non-'nonblocking' expression}}
}

// Expression involving indirection
int nb10a() [[clang::nonblocking]];
int nb10b() [[clang::nonblocking]];
int blocking();

int nb10c(bool x) [[clang::nonblocking]]
{
int y = (x ? nb10a : blocking)(); // expected-warning {{attribute 'nonblocking' should not be added via type conversion}}
return (x ? nb10a : nb10b)(); // No diagnostic.
}

// Interactions with nonblocking(false)
void nb11_no_inference_1() [[clang::nonblocking(false)]] // expected-note {{function does not permit inference of 'nonblocking'}}
{
Expand Down
20 changes: 20 additions & 0 deletions clang/test/Sema/caret-diags-register-variable.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: not %clang_cc1 -triple i386-pc-linux-gnu -std=c++11 -fsyntax-only -fno-diagnostics-show-line-numbers -fcaret-diagnostics-max-lines=5 %s 2>&1 | FileCheck %s -strict-whitespace

struct foo {
int a;
};

//CHECK: {{.*}}: error: bad type for named register variable
//CHECK-NEXT: {{^}}register struct foo bar asm("esp");
//CHECK-NEXT: {{^}} ^~~~~~~~~~{{$}}
register struct foo bar asm("esp");

//CHECK: {{.*}}: error: register 'edi' unsuitable for global register variables on this target
//CHECK-NEXT: {{^}}register int r0 asm ("edi");
//CHECK-NEXT: {{^}} ^{{$}}
register int r0 asm ("edi");

//CHECK: {{.*}}: error: size of register 'esp' does not match variable size
//CHECK-NEXT: {{^}}register long long r1 asm ("esp");
//CHECK-NEXT: {{^}} ^{{$}}
register long long r1 asm ("esp");
113 changes: 113 additions & 0 deletions clang/test/SemaCXX/attr-target-version-riscv.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// RUN: %clang_cc1 -triple riscv64-linux-gnu -fsyntax-only -verify -fexceptions -fcxx-exceptions %s -std=c++14

// expected-warning@+2 {{unsupported 'arch=rv64gcv' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("arch=rv64gcv"))) int fullArchString(void) { return 2; }
// expected-error@+2 {{redefinition of 'fullArchString'}}
// expected-warning@+1 {{unsupported 'arch=default' in the 'target_version' attribute string; 'target_version' attribute ignored}}
__attribute__((target_version("arch=default"))) int fullArchString(void) { return 2; }

// expected-warning@+2 {{unsupported 'mcpu=sifive-u74' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("mcpu=sifive-u74"))) int mcpu(void) { return 2; }
// expected-error@+1 {{redefinition of 'mcpu'}}
__attribute__((target_version("default"))) int mcpu(void) { return 2; }

// expected-warning@+2 {{unsupported 'mtune=sifive-u74' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("mtune=sifive-u74"))) int mtune(void) { return 2; }
// expected-error@+1 {{redefinition of 'mtune'}}
__attribute__((target_version("default"))) int mtune(void) { return 2; }

// expected-warning@+2 {{unsupported '' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version(""))) int emptyVersion(void) { return 2; }
// expected-error@+1 {{redefinition of 'emptyVersion'}}
__attribute__((target_version("default"))) int emptyVersion(void) { return 2; }

// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("arch=+c"))) int dupVersion(void) { return 2; }
// expected-error@+1 {{redefinition of 'dupVersion'}}
__attribute__((target_version("arch=+c"))) int dupVersion(void) { return 2; }
__attribute__((target_version("default"))) int dupVersion(void) { return 2; }

// expected-warning@+2 {{unsupported 'arch=+zicsr' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("arch=+zicsr"))) int UnsupportBitMaskExt(void) { return 2; }
// expected-error@+1 {{redefinition of 'UnsupportBitMaskExt'}}
__attribute__((target_version("default"))) int UnsupportBitMaskExt(void) { return 2; }

// expected-warning@+2 {{unsupported 'NotADigit' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("arch=+c;priority=NotADigit"))) int UnsupportPriority(void) { return 2; }
// expected-error@+1 {{redefinition of 'UnsupportPriority'}}
__attribute__((target_version("default"))) int UnsupportPriority(void) { return 2;}

// expected-warning@+1 {{unsupported 'default;priority=2' in the 'target_version' attribute string; 'target_version' attribute ignored}}
__attribute__((target_version("default;priority=2"))) int UnsupportDefaultPriority(void) { return 2; }

// expected-warning@+2 {{unsupported 'arch=+c,zbb' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("arch=+c,zbb"))) int WithoutAddSign(void) { return 2;}
// expected-error@+1 {{redefinition of 'WithoutAddSign'}}
__attribute__((target_version("default"))) int WithoutAddSign(void) { return 2; }

// expected-warning@+2 {{unsupported 'arch=+c;default' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("arch=+c;default"))) int DefaultInVersion(void) { return 2;}
// expected-error@+1 {{redefinition of 'DefaultInVersion'}}
__attribute__((target_version("default"))) int DefaultInVersion(void) { return 2; }

// expected-warning@+2 {{unsupported '' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("arch=+c;"))) int EmptyVersionAfterSemiColon(void) { return 2;}
// expected-error@+1 {{redefinition of 'EmptyVersionAfterSemiColon'}}
__attribute__((target_version("default"))) int EmptyVersionAfterSemiColon(void) { return 2; }

// expected-warning@+2 {{unsupported 'arch=+c;arch=+f' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("arch=+c;arch=+f"))) int dupArch(void) { return 2; }
// expected-error@+1 {{redefinition of 'dupArch'}}
__attribute__((target_version("default"))) int dupArch(void) { return 2; }

// expected-warning@+2 {{unsupported 'default;default' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("default;default"))) int dupDefault(void) { return 2;}
// expected-error@+1 {{redefinition of 'dupDefault'}}
__attribute__((target_version("default"))) int dupDefault(void) { return 2; }

// expected-warning@+2 {{unsupported 'priority=1;priority=2' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("priority=1;priority=2"))) int dupPriority(void) { return 2; }
// expected-error@+1 {{redefinition of 'dupPriority'}}
__attribute__((target_version("default"))) int dupPriority(void) { return 2; }

// expected-warning@+2 {{unsupported '=1' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("=1"))) int invalidVerson1(void) { return 2; }
// expected-error@+1 {{redefinition of 'invalidVerson1'}}
__attribute__((target_version("default"))) int invalidVerson1(void) { return 2; }

// expected-warning@+2 {{unsupported '=+v' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("=+v"))) int invalidVerson2(void) { return 2; }
// expected-error@+1 {{redefinition of 'invalidVerson2'}}
__attribute__((target_version("default"))) int invalidVerson2(void) { return 2; }

// expected-warning@+2 {{unsupported 'v' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("v"))) int invalidVerson3(void) { return 2; }
// expected-error@+1 {{redefinition of 'invalidVerson3'}}
__attribute__((target_version("default"))) int invalidVerson3(void) { return 2; }

// expected-warning@+2 {{unsupported '' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version(";"))) int invalidVerson4(void) { return 2; }
// expected-error@+1 {{redefinition of 'invalidVerson4'}}
__attribute__((target_version("default"))) int invalidVerson4(void) { return 2; }

// expected-warning@+2 {{unsupported 'priority=1' in the 'target_version' attribute string; 'target_version' attribute ignored}}
// expected-note@+1 {{previous definition is here}}
__attribute__((target_version("priority=1"))) int prioriyWithoutArch(void) { return 2; }
// expected-error@+1 {{redefinition of 'prioriyWithoutArch'}}
__attribute__((target_version("default"))) int prioriyWithoutArch(void) { return 2; }
8 changes: 8 additions & 0 deletions clang/unittests/Format/ConfigParseTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,13 @@ TEST(ConfigParseTest, ParsesConfiguration) {
/*AcrossComments=*/false, /*AlignCompound=*/false, \
/*AlignFunctionDeclarations=*/true, \
/*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
CHECK_PARSE( \
#FIELD ": AcrossComments", FIELD, \
FormatStyle::AlignConsecutiveStyle( \
{/*Enabled=*/true, /*AcrossEmptyLines=*/false, \
/*AcrossComments=*/true, /*AlignCompound=*/false, \
/*AlignFunctionDeclarations=*/true, \
/*AlignFunctionPointers=*/false, /*PadOperators=*/true})); \
CHECK_PARSE( \
#FIELD ": AcrossEmptyLinesAndComments", FIELD, \
FormatStyle::AlignConsecutiveStyle( \
Expand All @@ -339,6 +346,7 @@ TEST(ConfigParseTest, ParsesConfiguration) {
CHECK_PARSE_NESTED_BOOL(FIELD, AcrossComments); \
CHECK_PARSE_NESTED_BOOL(FIELD, AlignCompound); \
CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionDeclarations); \
CHECK_PARSE_NESTED_BOOL(FIELD, AlignFunctionPointers); \
CHECK_PARSE_NESTED_BOOL(FIELD, PadOperators); \
} while (false)

Expand Down
1 change: 1 addition & 0 deletions clang/unittests/Format/FormatTestProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ TEST_F(FormatTestProto, MessageFieldAttributes) {
" aaaaaaaaaaaaaaaa: true\n"
" }\n"
"];");
verifyFormat("repeated A a = 1 [(annotation).int32.repeated.test = true];");
}

TEST_F(FormatTestProto, DoesntWrapFileOptions) {
Expand Down
15 changes: 13 additions & 2 deletions clang/utils/TableGen/SveEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -953,9 +953,20 @@ Intrinsic::Intrinsic(StringRef Name, StringRef Proto, uint64_t MergeTy,
SVEEmitter &Emitter, StringRef SVEGuard,
StringRef SMEGuard)
: Name(Name.str()), LLVMName(LLVMName), Proto(Proto.str()),
BaseTypeSpec(BT), Class(Class), SVEGuard(SVEGuard.str()),
SMEGuard(SMEGuard.str()), MergeSuffix(MergeSuffix.str()),
BaseTypeSpec(BT), Class(Class), MergeSuffix(MergeSuffix.str()),
BaseType(BT, 'd'), Flags(Flags), ImmChecks(Checks) {

auto FormatGuard = [](StringRef Guard, StringRef Base) -> std::string {
if (Guard.contains('|'))
return Base.str() + ",(" + Guard.str() + ")";
if (Guard.empty() || Guard == Base || Guard.starts_with(Base.str() + ","))
return Guard.str();
return Base.str() + "," + Guard.str();
};

this->SVEGuard = FormatGuard(SVEGuard, "sve");
this->SMEGuard = FormatGuard(SMEGuard, "sme");

// Types[0] is the return value.
for (unsigned I = 0; I < (getNumParams() + 1); ++I) {
char Mod;
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/include/sanitizer/ubsan_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#ifndef SANITIZER_UBSAN_INTERFACE_H
#define SANITIZER_UBSAN_INTERFACE_H

#include <sanitizer/common_interface_defs.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
5 changes: 4 additions & 1 deletion compiler-rt/lib/rtsan/rtsan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@ static auto OnViolationAction(DiagnosticsInfo info) {
handle.inc_use_count_unsafe();
}

if (flags().halt_on_error)
if (flags().halt_on_error) {
if (flags().print_stats_on_exit)
PrintStatisticsSummary();
Die();
}
};
}

Expand Down
3 changes: 1 addition & 2 deletions compiler-rt/lib/rtsan/rtsan_assertions.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ template <typename OnViolationAction>
void ExpectNotRealtime(Context &context, OnViolationAction &&OnViolation) {
CHECK(__rtsan_is_initialized());
if (context.InRealtimeContext() && !context.IsBypassed()) {
context.BypassPush();
ScopedBypass sb{context};
OnViolation();
context.BypassPop();
}
}

Expand Down
17 changes: 17 additions & 0 deletions compiler-rt/lib/rtsan/rtsan_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,22 @@ class Context {
int bypass_depth_{0};
};

class ScopedBypass {
public:
[[nodiscard]] explicit ScopedBypass(Context &context) : context_(context) {
context_.BypassPush();
}

~ScopedBypass() { context_.BypassPop(); }

ScopedBypass(const ScopedBypass &) = delete;
ScopedBypass &operator=(const ScopedBypass &) = delete;
ScopedBypass(ScopedBypass &&) = delete;
ScopedBypass &operator=(ScopedBypass &&) = delete;

private:
Context &context_;
};

Context &GetContextForThisThread();
} // namespace __rtsan
4 changes: 2 additions & 2 deletions compiler-rt/lib/rtsan/tests/rtsan_test_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ TEST(TestRtsanInterceptors, SpinLockLockDiesWhenRealtime) {

TEST(TestRtsanInterceptors, PthreadCondSignalDiesWhenRealtime) {
pthread_cond_t cond{};
pthread_cond_init(&cond, NULL);
ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));

auto Func = [&cond]() { pthread_cond_signal(&cond); };
ExpectRealtimeDeath(Func, "pthread_cond_signal");
Expand All @@ -550,7 +550,7 @@ TEST(TestRtsanInterceptors, PthreadCondSignalDiesWhenRealtime) {

TEST(TestRtsanInterceptors, PthreadCondBroadcastDiesWhenRealtime) {
pthread_cond_t cond{};
pthread_cond_init(&cond, NULL);
ASSERT_EQ(0, pthread_cond_init(&cond, nullptr));

auto Func = [&cond]() { pthread_cond_broadcast(&cond); };
ExpectRealtimeDeath(Func, "pthread_cond_broadcast");
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/scudo/standalone/combined.h
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,9 @@ class Allocator {
// A corrupted chunk will not be reported as owned, which is WAI.
bool isOwned(const void *Ptr) {
initThreadMaybe();
// If the allocation is not owned, the tags could be wrong.
ScopedDisableMemoryTagChecks x(
useMemoryTagging<AllocatorConfig>(Primary.Options.load()));
#ifdef GWP_ASAN_HOOKS
if (GuardedAlloc.pointerIsMine(Ptr))
return true;
Expand Down
9 changes: 7 additions & 2 deletions compiler-rt/lib/scudo/standalone/memtag.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,12 @@ inline NORETURN void enableSystemMemoryTaggingTestOnly() {

class ScopedDisableMemoryTagChecks {
uptr PrevTCO;
bool active;

public:
ScopedDisableMemoryTagChecks() {
ScopedDisableMemoryTagChecks(bool cond = true) : active(cond) {
if (!active)
return;
__asm__ __volatile__(
R"(
.arch_extension memtag
Expand All @@ -135,6 +138,8 @@ class ScopedDisableMemoryTagChecks {
}

~ScopedDisableMemoryTagChecks() {
if (!active)
return;
__asm__ __volatile__(
R"(
.arch_extension memtag
Expand Down Expand Up @@ -269,7 +274,7 @@ inline NORETURN void enableSystemMemoryTaggingTestOnly() {
}

struct ScopedDisableMemoryTagChecks {
ScopedDisableMemoryTagChecks() {}
ScopedDisableMemoryTagChecks(UNUSED bool cond = true) {}
};

inline NORETURN uptr selectRandomTag(uptr Ptr, uptr ExcludeMask) {
Expand Down
33 changes: 14 additions & 19 deletions compiler-rt/test/rtsan/blocking_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,23 @@
#include <stdio.h>
#include <stdlib.h>

// TODO: Remove when [[blocking]] is implemented.
extern "C" void __rtsan_notify_blocking_call(const char *function_name);

void custom_blocking_function() {
// TODO: When [[blocking]] is implemented, don't call this directly.
__rtsan_notify_blocking_call(__func__);
}

void safe_call() {
// TODO: When [[blocking]] is implemented, don't call this directly.
__rtsan_notify_blocking_call(__func__);
void custom_blocking_function() [[clang::blocking]] {
printf("In blocking function\n");
}

void process() [[clang::nonblocking]] { custom_blocking_function(); }
void realtime_function() [[clang::nonblocking]] { custom_blocking_function(); }
void nonrealtime_function() { custom_blocking_function(); }

int main() {
safe_call(); // This shouldn't die, because it isn't in nonblocking context.
process();
nonrealtime_function();
realtime_function();
return 0;
// CHECK-NOT: {{.*safe_call*}}
// CHECK: ==ERROR: RealtimeSanitizer: blocking-call
// CHECK-NEXT: Call to blocking function `custom_blocking_function` in real-time context!
// CHECK-NEXT: {{.*custom_blocking_function*}}
// CHECK-NEXT: {{.*process*}}
}

// CHECK: ==ERROR: RealtimeSanitizer: blocking-call
// CHECK-NEXT: Call to blocking function `custom_blocking_function()` in real-time context!
// CHECK-NEXT: {{.*custom_blocking_function*}}
// CHECK-NEXT: {{.*realtime_function*}}

// should only occur once
// CHECK-NOT: ==ERROR: RealtimeSanitizer: blocking-call
7 changes: 6 additions & 1 deletion compiler-rt/test/rtsan/exit_stats.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// RUN: %clangxx -fsanitize=realtime %s -o %t
// RUN: env RTSAN_OPTIONS="halt_on_error=false,print_stats_on_exit=true" %run %t 2>&1 | FileCheck %s
// RUN: %env_rtsan_opts="halt_on_error=false,print_stats_on_exit=true" %run %t 2>&1 | FileCheck %s
// RUN: %env_rtsan_opts="halt_on_error=true,print_stats_on_exit=true" not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HALT

// UNSUPPORTED: ios

Expand All @@ -22,3 +23,7 @@ int main() {
// CHECK: RealtimeSanitizer exit stats:
// CHECK-NEXT: Total error count: 10
// CHECK-NEXT: Unique error count: 1

// CHECK-HALT: RealtimeSanitizer exit stats:
// CHECK-HALT-NEXT: Total error count: 1
// CHECK-HALT-NEXT: Unique error count: 1
3 changes: 2 additions & 1 deletion flang/include/flang/Common/Fortran-features.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
IgnoredIntrinsicFunctionType, PreviousScalarUse,
RedeclaredInaccessibleComponent, ImplicitShared, IndexVarRedefinition,
IncompatibleImplicitInterfaces, BadTypeForTarget,
VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg)
VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg,
MismatchingDummyProcedure)

using LanguageFeatures = EnumSet<LanguageFeature, LanguageFeature_enumSize>;
using UsageWarnings = EnumSet<UsageWarning, UsageWarning_enumSize>;
Expand Down
7 changes: 4 additions & 3 deletions flang/lib/Optimizer/Transforms/AddDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,8 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
if (debugLevel == mlir::LLVM::DIEmissionKind::LineTablesOnly) {
auto spAttr = mlir::LLVM::DISubprogramAttr::get(
context, id, compilationUnit, Scope, funcName, fullName, funcFileAttr,
line, line, subprogramFlags, subTypeAttr, /*retainedNodes=*/{});
line, line, subprogramFlags, subTypeAttr, /*retainedNodes=*/{},
/*annotations=*/{});
funcOp->setLoc(builder.getFusedLoc({l}, spAttr));
return;
}
Expand All @@ -368,7 +369,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
auto spAttr = mlir::LLVM::DISubprogramAttr::get(
context, recId, /*isRecSelf=*/true, id, compilationUnit, Scope, funcName,
fullName, funcFileAttr, line, line, subprogramFlags, subTypeAttr,
/*retainedNodes=*/{});
/*retainedNodes=*/{}, /*annotations=*/{});

// There is no direct information in the IR for any 'use' statement in the
// function. We have to extract that information from the DeclareOp. We do
Expand Down Expand Up @@ -401,7 +402,7 @@ void AddDebugInfoPass::handleFuncOp(mlir::func::FuncOp funcOp,
spAttr = mlir::LLVM::DISubprogramAttr::get(
context, recId, /*isRecSelf=*/false, id2, compilationUnit, Scope,
funcName, fullName, funcFileAttr, line, line, subprogramFlags,
subTypeAttr, entities);
subTypeAttr, entities, /*annotations=*/{});
funcOp->setLoc(builder.getFusedLoc({l}, spAttr));

funcOp.walk([&](fir::cg::XDeclareOp declOp) {
Expand Down
79 changes: 50 additions & 29 deletions flang/lib/Semantics/check-call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ static void ConvertIntegerActual(evaluate::Expr<evaluate::SomeType> &actual,
if (!semanticsContext.IsEnabled(
common::LanguageFeature::ActualIntegerConvertedToSmallerKind)) {
messages.Say(
"Actual argument scalar expression of type INTEGER(%d) cannot beimplicitly converted to smaller dummy argument type INTEGER(%d)"_err_en_US,
"Actual argument scalar expression of type INTEGER(%d) cannot be implicitly converted to smaller dummy argument type INTEGER(%d)"_err_en_US,
actualType.type().kind(), dummyType.type().kind());
} else if (semanticsContext.ShouldWarn(common::LanguageFeature::
ActualIntegerConvertedToSmallerKind)) {
Expand Down Expand Up @@ -300,12 +300,15 @@ static void ConvertLogicalActual(evaluate::Expr<evaluate::SomeType> &actual,
}

static bool DefersSameTypeParameters(
const DerivedTypeSpec &actual, const DerivedTypeSpec &dummy) {
for (const auto &pair : actual.parameters()) {
const ParamValue &actualValue{pair.second};
const ParamValue *dummyValue{dummy.FindParameter(pair.first)};
if (!dummyValue || (actualValue.isDeferred() != dummyValue->isDeferred())) {
return false;
const DerivedTypeSpec *actual, const DerivedTypeSpec *dummy) {
if (actual && dummy) {
for (const auto &pair : actual->parameters()) {
const ParamValue &actualValue{pair.second};
const ParamValue *dummyValue{dummy->FindParameter(pair.first)};
if (!dummyValue ||
(actualValue.isDeferred() != dummyValue->isDeferred())) {
return false;
}
}
}
return true;
Expand Down Expand Up @@ -370,9 +373,37 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}
bool dummyIsAssumedRank{dummy.type.attrs().test(
characteristics::TypeAndShape::Attr::AssumedRank)};
bool actualIsAssumedSize{actualType.attrs().test(
characteristics::TypeAndShape::Attr::AssumedSize)};
bool actualIsAssumedRank{evaluate::IsAssumedRank(actual)};
bool actualIsPointer{evaluate::IsObjectPointer(actual)};
bool actualIsAllocatable{evaluate::IsAllocatableDesignator(actual)};
bool actualMayBeAssumedSize{actualIsAssumedSize ||
(actualIsAssumedRank && !actualIsPointer && !actualIsAllocatable)};
bool actualIsPolymorphic{actualType.type().IsPolymorphic()};
const auto *actualDerived{evaluate::GetDerivedTypeSpec(actualType.type())};
if (typesCompatible) {
if (isElemental) {
} else if (dummyIsAssumedRank) {
if (actualMayBeAssumedSize && dummy.intent == common::Intent::Out) {
// An INTENT(OUT) dummy might be a no-op at run time
bool dummyHasSignificantIntentOut{actualIsPolymorphic ||
(actualDerived &&
(actualDerived->HasDefaultInitialization(
/*ignoreAllocatable=*/false, /*ignorePointer=*/true) ||
actualDerived->HasDestruction()))};
const char *actualDesc{
actualIsAssumedSize ? "Assumed-size" : "Assumed-rank"};
if (dummyHasSignificantIntentOut) {
messages.Say(
"%s actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization"_err_en_US,
actualDesc);
} else {
context.Warn(common::UsageWarning::Portability, messages.at(),
"%s actual argument should not be associated with INTENT(OUT) assumed-rank dummy argument"_port_en_US,
actualDesc);
}
}
} else if (dummy.ignoreTKR.test(common::IgnoreTKR::Rank)) {
} else if (dummyRank > 0 && !dummyIsAllocatableOrPointer &&
!dummy.type.attrs().test(
Expand Down Expand Up @@ -401,11 +432,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
dummy.type.type().AsFortran());
}

bool actualIsPolymorphic{actualType.type().IsPolymorphic()};
bool dummyIsPolymorphic{dummy.type.type().IsPolymorphic()};
bool actualIsCoindexed{ExtractCoarrayRef(actual).has_value()};
bool actualIsAssumedSize{actualType.attrs().test(
characteristics::TypeAndShape::Attr::AssumedSize)};
bool dummyIsAssumedSize{dummy.type.attrs().test(
characteristics::TypeAndShape::Attr::AssumedSize)};
bool dummyIsAsynchronous{
Expand All @@ -414,7 +441,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
dummy.attrs.test(characteristics::DummyDataObject::Attr::Volatile)};
bool dummyIsValue{
dummy.attrs.test(characteristics::DummyDataObject::Attr::Value)};

bool dummyIsPolymorphic{dummy.type.type().IsPolymorphic()};
if (actualIsPolymorphic && dummyIsPolymorphic &&
actualIsCoindexed) { // 15.5.2.4(2)
messages.Say(
Expand All @@ -434,37 +461,36 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
actualFirstSymbol && actualFirstSymbol->attrs().test(Attr::ASYNCHRONOUS)};
bool actualIsVolatile{
actualFirstSymbol && actualFirstSymbol->attrs().test(Attr::VOLATILE)};
const auto *derived{evaluate::GetDerivedTypeSpec(actualType.type())};
if (derived && !derived->IsVectorType()) {
if (actualDerived && !actualDerived->IsVectorType()) {
if (dummy.type.type().IsAssumedType()) {
if (!derived->parameters().empty()) { // 15.5.2.4(2)
if (!actualDerived->parameters().empty()) { // 15.5.2.4(2)
messages.Say(
"Actual argument associated with TYPE(*) %s may not have a parameterized derived type"_err_en_US,
dummyName);
}
if (const Symbol *
tbp{FindImmediateComponent(*derived, [](const Symbol &symbol) {
tbp{FindImmediateComponent(*actualDerived, [](const Symbol &symbol) {
return symbol.has<ProcBindingDetails>();
})}) { // 15.5.2.4(2)
evaluate::SayWithDeclaration(messages, *tbp,
"Actual argument associated with TYPE(*) %s may not have type-bound procedure '%s'"_err_en_US,
dummyName, tbp->name());
}
auto finals{FinalsForDerivedTypeInstantiation(*derived)};
auto finals{FinalsForDerivedTypeInstantiation(*actualDerived)};
if (!finals.empty()) { // 15.5.2.4(2)
SourceName name{finals.front()->name()};
if (auto *msg{messages.Say(
"Actual argument associated with TYPE(*) %s may not have derived type '%s' with FINAL subroutine '%s'"_err_en_US,
dummyName, derived->typeSymbol().name(), name)}) {
dummyName, actualDerived->typeSymbol().name(), name)}) {
msg->Attach(name, "FINAL subroutine '%s' in derived type '%s'"_en_US,
name, derived->typeSymbol().name());
name, actualDerived->typeSymbol().name());
}
}
}
if (actualIsCoindexed) {
if (dummy.intent != common::Intent::In && !dummyIsValue) {
if (auto bad{
FindAllocatableUltimateComponent(*derived)}) { // 15.5.2.4(6)
if (auto bad{FindAllocatableUltimateComponent(
*actualDerived)}) { // 15.5.2.4(6)
evaluate::SayWithDeclaration(messages, *bad,
"Coindexed actual argument with ALLOCATABLE ultimate component '%s' must be associated with a %s with VALUE or INTENT(IN) attributes"_err_en_US,
bad.BuildResultDesignatorName(), dummyName);
Expand All @@ -484,7 +510,7 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}
}
if (actualIsVolatile != dummyIsVolatile) { // 15.5.2.4(22)
if (auto bad{semantics::FindCoarrayUltimateComponent(*derived)}) {
if (auto bad{semantics::FindCoarrayUltimateComponent(*actualDerived)}) {
evaluate::SayWithDeclaration(messages, *bad,
"VOLATILE attribute must match for %s when actual argument has a coarray ultimate component '%s'"_err_en_US,
dummyName, bad.BuildResultDesignatorName());
Expand All @@ -501,8 +527,6 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
? actualLastSymbol->detailsIf<ObjectEntityDetails>()
: nullptr};
int actualRank{actualType.Rank()};
bool actualIsPointer{evaluate::IsObjectPointer(actual)};
bool actualIsAssumedRank{evaluate::IsAssumedRank(actual)};
if (dummy.type.attrs().test(
characteristics::TypeAndShape::Attr::AssumedShape)) {
// 15.5.2.4(16)
Expand Down Expand Up @@ -730,7 +754,6 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}

// 15.5.2.6 -- dummy is ALLOCATABLE
bool actualIsAllocatable{evaluate::IsAllocatableDesignator(actual)};
bool dummyIsOptional{
dummy.attrs.test(characteristics::DummyDataObject::Attr::Optional)};
bool actualIsNull{evaluate::IsNullPointer(actual)};
Expand Down Expand Up @@ -851,10 +874,8 @@ static void CheckExplicitDataArg(const characteristics::DummyDataObject &dummy,
}
}
// 15.5.2.5(4)
const auto *derived{evaluate::GetDerivedTypeSpec(actualType.type())};
if ((derived &&
!DefersSameTypeParameters(*derived,
*evaluate::GetDerivedTypeSpec(dummy.type.type()))) ||
const auto *dummyDerived{evaluate::GetDerivedTypeSpec(dummy.type.type())};
if (!DefersSameTypeParameters(actualDerived, dummyDerived) ||
dummy.type.type().HasDeferredTypeParameter() !=
actualType.type().HasDeferredTypeParameter()) {
messages.Say(
Expand Down
14 changes: 11 additions & 3 deletions flang/lib/Semantics/check-declarations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3765,12 +3765,20 @@ void SubprogramMatchHelper::CheckDummyDataObject(const Symbol &symbol1,
void SubprogramMatchHelper::CheckDummyProcedure(const Symbol &symbol1,
const Symbol &symbol2, const DummyProcedure &proc1,
const DummyProcedure &proc2) {
std::string whyNot;
if (!CheckSameIntent(symbol1, symbol2, proc1.intent, proc2.intent)) {
} else if (!CheckSameAttrs(symbol1, symbol2, proc1.attrs, proc2.attrs)) {
} else if (proc1 != proc2) {
} else if (!proc2.IsCompatibleWith(proc1, &whyNot)) {
Say(symbol1, symbol2,
"Dummy procedure '%s' does not match the corresponding argument in"
" the interface body"_err_en_US);
"Dummy procedure '%s' is not compatible with the corresponding argument in the interface body: %s"_err_en_US,
whyNot);
} else if (proc1 != proc2) {
evaluate::AttachDeclaration(
symbol1.owner().context().Warn(
common::UsageWarning::MismatchingDummyProcedure,
"Dummy procedure '%s' does not exactly match the corresponding argument in the interface body"_warn_en_US,
symbol1.name()),
symbol2);
}
}

Expand Down
8 changes: 5 additions & 3 deletions flang/lib/Semantics/tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ bool IsInitialized(const Symbol &symbol, bool ignoreDataStatements,
} else if (IsNamedConstant(symbol)) {
return false;
} else if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
if (!object->isDummy() && object->type()) {
if ((!object->isDummy() || IsIntentOut(symbol)) && object->type()) {
if (const auto *derived{object->type()->AsDerived()}) {
return derived->HasDefaultInitialization(
ignoreAllocatable, ignorePointer);
Expand All @@ -705,7 +705,7 @@ bool IsDestructible(const Symbol &symbol, const Symbol *derivedTypeSymbol) {
IsPointer(symbol)) {
return false;
} else if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
if (!object->isDummy() && object->type()) {
if ((!object->isDummy() || IsIntentOut(symbol)) && object->type()) {
if (const auto *derived{object->type()->AsDerived()}) {
return &derived->typeSymbol() != derivedTypeSymbol &&
derived->HasDestruction();
Expand Down Expand Up @@ -1649,7 +1649,9 @@ bool HasDefinedIo(common::DefinedIo which, const DerivedTypeSpec &derived,
}
}
}
return false;
// Check for inherited defined I/O
const auto *parentType{derived.typeSymbol().GetParentTypeSpec()};
return parentType && HasDefinedIo(which, *parentType, scope);
}

void WarnOnDeferredLengthCharacterScalar(SemanticsContext &context,
Expand Down
138 changes: 138 additions & 0 deletions flang/test/Semantics/call42.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
! RUN: %python %S/test_errors.py %s %flang_fc1 -pedantic
module m
type boring
end type
type hasAlloc
real, allocatable :: x
end type
type hasInit
real :: x = 1.
end type
type hasFinal
contains
final final
end type
contains
elemental subroutine final(x)
type(hasFinal), intent(in out) :: x
end

recursive subroutine typeOutAssumedRank(a,b,c,d)
type(boring), intent(out) :: a(..)
type(hasAlloc), intent(out) :: b(..)
type(hasInit), intent(out) :: c(..)
type(hasFinal), intent(out) :: d(..)
!PORTABILITY: Assumed-rank actual argument should not be associated with INTENT(OUT) assumed-rank dummy argument
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call typeOutAssumedRank(a, b, c, d)
!PORTABILITY: Assumed-rank actual argument should not be associated with INTENT(OUT) assumed-rank dummy argument
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call classOutAssumedRank(a, b, c, d)
!PORTABILITY: Assumed-rank actual argument should not be associated with INTENT(OUT) assumed-rank dummy argument
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call unlimitedOutAssumedRank(a, b, c, d)
end
recursive subroutine typeOutAssumedRankAlloc(a,b,c,d)
type(boring), intent(out), allocatable :: a(..)
type(hasAlloc), intent(out), allocatable :: b(..)
type(hasInit), intent(out), allocatable :: c(..)
type(hasFinal), intent(out), allocatable :: d(..)
call typeOutAssumedRank(a, b, c, d)
call typeOutAssumedRankAlloc(a, b, c, d)
end
recursive subroutine classOutAssumedRank(a,b,c,d)
class(boring), intent(out) :: a(..)
class(hasAlloc), intent(out) :: b(..)
class(hasInit), intent(out) :: c(..)
class(hasFinal), intent(out) :: d(..)
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call typeOutAssumedRank(a, b, c, d)
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call classOutAssumedRank(a, b, c, d)
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call unlimitedOutAssumedRank(a, b, c, d)
end
recursive subroutine classOutAssumedRankAlloc(a,b,c,d)
class(boring), intent(out), allocatable :: a(..)
class(hasAlloc), intent(out), allocatable :: b(..)
class(hasInit), intent(out), allocatable :: c(..)
class(hasFinal), intent(out), allocatable :: d(..)
call classOutAssumedRank(a, b, c, d)
call classOutAssumedRankAlloc(a, b, c, d)
call unlimitedOutAssumedRank(a, b, c, d)
end
recursive subroutine unlimitedOutAssumedRank(a,b,c,d)
class(*), intent(out) :: a(..), b(..), c(..), d(..)
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-rank actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call unlimitedOutAssumedRank(a, b, c, d)
end
recursive subroutine unlimitedOutAssumedRankAlloc(a,b,c,d)
class(*), intent(out), allocatable :: a(..), b(..), c(..), d(..)
call unlimitedOutAssumedRank(a, b, c, d)
call unlimitedOutAssumedRankAlloc(a, b, c, d)
end

subroutine typeAssumedSize(a,b,c,d)
type(boring) a(*)
type(hasAlloc) b(*)
type(hasInit) c(*)
type(hasFinal) d(*)
!PORTABILITY: Assumed-size actual argument should not be associated with INTENT(OUT) assumed-rank dummy argument
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call typeOutAssumedRank(a,b,c,d)
!PORTABILITY: Assumed-size actual argument should not be associated with INTENT(OUT) assumed-rank dummy argument
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call classOutAssumedRank(a,b,c,d)
!PORTABILITY: Assumed-size actual argument should not be associated with INTENT(OUT) assumed-rank dummy argument
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call unlimitedOutAssumedRank(a,b,c,d)
end
subroutine classAssumedSize(a,b,c,d)
class(boring) a(*)
class(hasAlloc) b(*)
class(hasInit) c(*)
class(hasFinal) d(*)
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call classOutAssumedRank(a,b,c,d)
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call unlimitedOutAssumedRank(a,b,c,d)
end
subroutine unlimitedAssumedSize(a,b,c,d)
class(*) a(*), b(*), c(*), d(*)
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
!ERROR: Assumed-size actual argument may not be associated with INTENT(OUT) assumed-rank dummy argument requiring finalization, destruction, or initialization
call unlimitedOutAssumedRank(a, b, c, d)
end
end
Loading