aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorAlexandros Lamprineas <alexandros.lamprineas@arm.com>2024-07-04 20:04:11 +0100
committerGitHub <noreply@github.com>2024-07-04 20:04:11 +0100
commitd1c911ffe48eef23817d11c900dec30e0e3b5ae4 (patch)
tree1e2332194224c21ebe3a6d246bf0b9d91c2bf20a /clang/lib/Sema/SemaDecl.cpp
parent093ddac68c6855b5c2d786a99475b793e35e2342 (diff)
downloadllvm-d1c911ffe48eef23817d11c900dec30e0e3b5ae4.zip
llvm-d1c911ffe48eef23817d11c900dec30e0e3b5ae4.tar.gz
llvm-d1c911ffe48eef23817d11c900dec30e0e3b5ae4.tar.bz2
[clang][FMV] Do not omit explicit default target_version attribute. (#96628)
Fixes a crash and cleans up some dead code. namespace Foo { int bar(); __attribute((target_version("default"))) int bar() { return 0; } __attribute((target_version("mops"))) int bar() { return 1; } } $ clang++ --target=aarch64-linux-gnu --rtlib=compiler-rt fmv.cpp None multiversion type isn't valid here UNREACHABLE executed at clang/lib/CodeGen/CodeGenModule.cpp:1840! ... getMangledNameImpl clang::CodeGen::CodeGenModule::getMangledName clang::CodeGen::CodeGenModule::EmitGlobal
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp74
1 files changed, 23 insertions, 51 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 262a254..b3bfdac 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11201,6 +11201,10 @@ static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD) {
// otherwise it is treated as a normal function.
if (TA && !TA->isDefaultVersion())
return false;
+ // The target_version attribute only causes Multiversioning if this
+ // declaration is NOT the default version.
+ if (TVA && TVA->isDefaultVersion())
+ return false;
if ((TA || TVA) && CheckMultiVersionValue(S, FD)) {
FD->setInvalidDecl();
@@ -11234,18 +11238,16 @@ static void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) {
if (MVKindTo == MultiVersionKind::None &&
(MVKindFrom == MultiVersionKind::TargetVersion ||
- MVKindFrom == MultiVersionKind::TargetClones)) {
- To->setIsMultiVersion();
+ MVKindFrom == MultiVersionKind::TargetClones))
To->addAttr(TargetVersionAttr::CreateImplicit(
To->getASTContext(), "default", To->getSourceRange()));
- }
}
-static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
- FunctionDecl *NewFD,
- bool &Redeclaration,
- NamedDecl *&OldDecl,
- LookupResult &Previous) {
+static bool CheckDeclarationCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
+ FunctionDecl *NewFD,
+ bool &Redeclaration,
+ NamedDecl *&OldDecl,
+ LookupResult &Previous) {
assert(!OldFD->isMultiVersion() && "Unexpected MultiVersion");
// The definitions should be allowed in any order. If we have discovered
@@ -11256,13 +11258,16 @@ static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
const auto *NewTA = NewFD->getAttr<TargetAttr>();
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
const auto *OldTA = OldFD->getAttr<TargetAttr>();
- const auto *OldTVA = OldFD->getAttr<TargetVersionAttr>();
+
// If the old decl is NOT MultiVersioned yet, and we don't cause that
// to change, this is a simple redeclaration.
- if ((NewTA && !NewTA->isDefaultVersion() &&
- (!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr())) ||
- (NewTVA && !NewTVA->isDefaultVersion() &&
- (!OldTVA || OldTVA->getName() == NewTVA->getName())))
+ if (NewTA && !NewTA->isDefaultVersion() &&
+ (!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr()))
+ return false;
+
+ // The target_version attribute only causes Multiversioning if this
+ // declaration is NOT the default version.
+ if (NewTVA && NewTVA->isDefaultVersion())
return false;
// Otherwise, this decl causes MultiVersioning.
@@ -11279,8 +11284,7 @@ static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
}
// If this is 'default', permit the forward declaration.
- if ((NewTA && NewTA->isDefaultVersion() && !OldTA) ||
- (NewTVA && NewTVA->isDefaultVersion() && !OldTVA)) {
+ if (NewTA && NewTA->isDefaultVersion() && !OldTA) {
Redeclaration = true;
OldDecl = OldFD;
OldFD->setIsMultiVersion();
@@ -11312,22 +11316,6 @@ static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
}
}
- if (NewTVA) {
- llvm::SmallVector<StringRef, 8> Feats;
- OldTVA->getFeatures(Feats);
- llvm::sort(Feats);
- llvm::SmallVector<StringRef, 8> NewFeats;
- NewTVA->getFeatures(NewFeats);
- llvm::sort(NewFeats);
-
- if (Feats == NewFeats) {
- S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate);
- S.Diag(OldFD->getLocation(), diag::note_previous_declaration);
- NewFD->setInvalidDecl();
- return true;
- }
- }
-
for (const auto *FD : OldFD->redecls()) {
const auto *CurTA = FD->getAttr<TargetAttr>();
const auto *CurTVA = FD->getAttr<TargetVersionAttr>();
@@ -11683,24 +11671,8 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD,
FunctionDecl *OldFD = OldDecl->getAsFunction();
- if (!OldFD->isMultiVersion() && MVKind == MultiVersionKind::None) {
- if (NewTVA || !OldFD->getAttr<TargetVersionAttr>())
- return false;
- if (!NewFD->getType()->getAs<FunctionProtoType>()) {
- // Multiversion declaration doesn't have prototype.
- S.Diag(NewFD->getLocation(), diag::err_multiversion_noproto);
- NewFD->setInvalidDecl();
- } else {
- // No "target_version" attribute is equivalent to "default" attribute.
- NewFD->addAttr(TargetVersionAttr::CreateImplicit(
- S.Context, "default", NewFD->getSourceRange()));
- NewFD->setIsMultiVersion();
- OldFD->setIsMultiVersion();
- OldDecl = OldFD;
- Redeclaration = true;
- }
- return true;
- }
+ if (!OldFD->isMultiVersion() && MVKind == MultiVersionKind::None)
+ return false;
// Multiversioned redeclarations aren't allowed to omit the attribute, except
// for target_clones and target_version.
@@ -11717,8 +11689,8 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD,
switch (MVKind) {
case MultiVersionKind::Target:
case MultiVersionKind::TargetVersion:
- return CheckTargetCausesMultiVersioning(S, OldFD, NewFD, Redeclaration,
- OldDecl, Previous);
+ return CheckDeclarationCausesMultiVersioning(
+ S, OldFD, NewFD, Redeclaration, OldDecl, Previous);
case MultiVersionKind::TargetClones:
if (OldFD->isUsed(false)) {
NewFD->setInvalidDecl();