aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaARM.cpp4
-rw-r--r--clang/lib/Sema/SemaChecking.cpp4
-rw-r--r--clang/lib/Sema/SemaConcept.cpp26
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp42
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp39
-rw-r--r--clang/lib/Sema/SemaInit.cpp48
-rw-r--r--clang/lib/Sema/SemaOverload.cpp4
7 files changed, 99 insertions, 68 deletions
diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp
index e09c352..1c7c832d 100644
--- a/clang/lib/Sema/SemaARM.cpp
+++ b/clang/lib/Sema/SemaARM.cpp
@@ -603,8 +603,8 @@ static bool checkArmStreamingBuiltin(Sema &S, CallExpr *TheCall,
bool SatisfiesSME = Builtin::evaluateRequiredTargetFeatures(
StreamingBuiltinGuard, CallerFeatures);
- if ((SatisfiesSVE && SatisfiesSME) ||
- (SatisfiesSVE && FnType == SemaARM::ArmStreamingCompatible))
+ if (SatisfiesSVE && SatisfiesSME)
+ // Function type is irrelevant for streaming-agnostic builtins.
return false;
else if (SatisfiesSVE)
BuiltinType = SemaARM::ArmNonStreaming;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 3cc61b1..063db05 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -8811,8 +8811,10 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
case ArgType::Match:
case ArgType::MatchPromotion:
case ArgType::NoMatchPromotionTypeConfusion:
- case ArgType::NoMatchSignedness:
llvm_unreachable("expected non-matching");
+ case ArgType::NoMatchSignedness:
+ Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
+ break;
case ArgType::NoMatchPedantic:
Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
break;
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 999e302c..f4df63c 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -280,6 +280,11 @@ public:
if (T->getDepth() >= TemplateArgs.getNumLevels())
return true;
+ // There might not be a corresponding template argument before substituting
+ // into the parameter mapping, e.g. a sizeof... expression.
+ if (!TemplateArgs.hasTemplateArgument(T->getDepth(), T->getIndex()))
+ return true;
+
TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
if (T->isParameterPack() && SemaRef.ArgPackSubstIndex) {
@@ -300,6 +305,12 @@ public:
if (!NTTP)
return TraverseDecl(D);
+ if (NTTP->getDepth() >= TemplateArgs.getNumLevels())
+ return true;
+
+ if (!TemplateArgs.hasTemplateArgument(NTTP->getDepth(), NTTP->getIndex()))
+ return true;
+
TemplateArgument Arg = TemplateArgs(NTTP->getDepth(), NTTP->getPosition());
if (NTTP->isParameterPack() && SemaRef.ArgPackSubstIndex) {
assert(Arg.getKind() == TemplateArgument::Pack &&
@@ -326,17 +337,25 @@ public:
return inherited::TraverseDecl(D);
}
+ bool TraverseCallExpr(CallExpr *CE) {
+ inherited::TraverseStmt(CE->getCallee());
+
+ for (Expr *Arg : CE->arguments())
+ inherited::TraverseStmt(Arg);
+
+ return true;
+ }
+
bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) {
// We don't care about TypeLocs. So traverse Types instead.
- return TraverseType(TL.getType(), TraverseQualifier);
+ return TraverseType(TL.getType().getCanonicalType(), TraverseQualifier);
}
bool TraverseTagType(const TagType *T, bool TraverseQualifier) {
// T's parent can be dependent while T doesn't have any template arguments.
// We should have already traversed its qualifier.
// FIXME: Add an assert to catch cases where we failed to profile the
- // concept. assert(!T->isDependentType() && "We missed a case in profiling
- // concepts!");
+ // concept.
return true;
}
@@ -701,7 +720,6 @@ ExprResult ConstraintSatisfactionChecker::Evaluate(
if (auto Iter = S.UnsubstitutedConstraintSatisfactionCache.find(ID);
Iter != S.UnsubstitutedConstraintSatisfactionCache.end()) {
-
auto &Cached = Iter->second.Satisfaction;
Satisfaction.ContainsErrors = Cached.ContainsErrors;
Satisfaction.IsSatisfied = Cached.IsSatisfied;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index d27f767..215431c 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -9546,14 +9546,32 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
CXXMethodDecl *Decl = SMOR.getMethod();
FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
- int DiagKind = -1;
-
- if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted)
- DiagKind = !Decl ? 0 : 1;
- else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
- DiagKind = 2;
+ enum {
+ NotSet = -1,
+ NoDecl,
+ DeletedDecl,
+ MultipleDecl,
+ InaccessibleDecl,
+ NonTrivialDecl
+ } DiagKind = NotSet;
+
+ if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted) {
+ if (CSM == CXXSpecialMemberKind::DefaultConstructor && Field &&
+ Field->getParent()->isUnion()) {
+ // [class.default.ctor]p2:
+ // A defaulted default constructor for class X is defined as deleted if
+ // - X is a union that has a variant member with a non-trivial default
+ // constructor and no variant member of X has a default member
+ // initializer
+ const auto *RD = cast<CXXRecordDecl>(Field->getParent());
+ if (RD->hasInClassInitializer())
+ return false;
+ }
+ DiagKind = !Decl ? NoDecl : DeletedDecl;
+ } else if (SMOR.getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
+ DiagKind = MultipleDecl;
else if (!isAccessible(Subobj, Decl))
- DiagKind = 3;
+ DiagKind = InaccessibleDecl;
else if (!IsDtorCallInCtor && Field && Field->getParent()->isUnion() &&
!Decl->isTrivial()) {
// A member of a union must have a trivial corresponding special member.
@@ -9569,13 +9587,13 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
// initializer
const auto *RD = cast<CXXRecordDecl>(Field->getParent());
if (!RD->hasInClassInitializer())
- DiagKind = 4;
+ DiagKind = NonTrivialDecl;
} else {
- DiagKind = 4;
+ DiagKind = NonTrivialDecl;
}
}
- if (DiagKind == -1)
+ if (DiagKind == NotSet)
return false;
if (Diagnose) {
@@ -9593,9 +9611,9 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
<< /*IsObjCPtr*/ false;
}
- if (DiagKind == 1)
+ if (DiagKind == DeletedDecl)
S.NoteDeletedFunction(Decl);
- // FIXME: Explain inaccessibility if DiagKind == 3.
+ // FIXME: Explain inaccessibility if DiagKind == InaccessibleDecl.
}
return true;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 2b375b9..09e5d69 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -598,18 +598,17 @@ void SemaHLSL::ActOnFinishBuffer(Decl *Dcl, SourceLocation RBrace) {
validatePackoffset(SemaRef, BufDecl);
- // create buffer layout struct
createHostLayoutStructForBuffer(SemaRef, BufDecl);
- HLSLVkBindingAttr *VkBinding = Dcl->getAttr<HLSLVkBindingAttr>();
- HLSLResourceBindingAttr *RBA = Dcl->getAttr<HLSLResourceBindingAttr>();
- if (!VkBinding && (!RBA || !RBA->hasRegisterSlot())) {
+ // Handle implicit binding if needed.
+ ResourceBindingAttrs ResourceAttrs(Dcl);
+ if (!ResourceAttrs.isExplicit()) {
SemaRef.Diag(Dcl->getLocation(), diag::warn_hlsl_implicit_binding);
// Use HLSLResourceBindingAttr to transfer implicit binding order_ID
// to codegen. If it does not exist, create an implicit attribute.
uint32_t OrderID = getNextImplicitBindingOrderID();
- if (RBA)
- RBA->setImplicitBindingOrderID(OrderID);
+ if (ResourceAttrs.hasBinding())
+ ResourceAttrs.setImplicitOrderID(OrderID);
else
addImplicitBindingAttrToDecl(SemaRef, BufDecl,
BufDecl->isCBuffer() ? RegisterType::CBuffer
@@ -1289,8 +1288,8 @@ bool SemaHLSL::handleRootSignatureElements(
VerifyRegister(Loc, Descriptor->Reg.Number);
VerifySpace(Loc, Descriptor->Space);
- if (!llvm::hlsl::rootsig::verifyRootDescriptorFlag(
- Version, llvm::to_underlying(Descriptor->Flags)))
+ if (!llvm::hlsl::rootsig::verifyRootDescriptorFlag(Version,
+ Descriptor->Flags))
ReportFlagError(Loc);
} else if (const auto *Constants =
std::get_if<llvm::hlsl::rootsig::RootConstants>(&Elem)) {
@@ -1590,10 +1589,6 @@ void SemaHLSL::handleVkConstantIdAttr(Decl *D, const ParsedAttr &AL) {
}
void SemaHLSL::handleVkBindingAttr(Decl *D, const ParsedAttr &AL) {
- // The vk::binding attribute only applies to SPIR-V.
- if (!getASTContext().getTargetInfo().getTriple().isSPIRV())
- return;
-
uint32_t Binding = 0;
if (!SemaRef.checkUInt32Argument(AL, AL.getArgAsExpr(0), Binding))
return;
@@ -3780,17 +3775,15 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
// If the resource array does not have an explicit binding attribute,
// create an implicit one. It will be used to transfer implicit binding
// order_ID to codegen.
- if (!VD->hasAttr<HLSLVkBindingAttr>()) {
- HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
- if (!RBA || !RBA->hasRegisterSlot()) {
- uint32_t OrderID = getNextImplicitBindingOrderID();
- if (RBA)
- RBA->setImplicitBindingOrderID(OrderID);
- else
- addImplicitBindingAttrToDecl(
- SemaRef, VD, getRegisterType(getResourceArrayHandleType(VD)),
- OrderID);
- }
+ ResourceBindingAttrs Binding(VD);
+ if (!Binding.isExplicit()) {
+ uint32_t OrderID = getNextImplicitBindingOrderID();
+ if (Binding.hasBinding())
+ Binding.setImplicitOrderID(OrderID);
+ else
+ addImplicitBindingAttrToDecl(
+ SemaRef, VD, getRegisterType(getResourceArrayHandleType(VD)),
+ OrderID);
}
}
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 922fcac..543db46 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -3920,6 +3920,7 @@ bool InitializationSequence::isAmbiguous() const {
case FK_AddressOfUnaddressableFunction:
case FK_ParenthesizedListInitFailed:
case FK_DesignatedInitForNonAggregate:
+ case FK_HLSLInitListFlatteningFailed:
return false;
case FK_ReferenceInitOverloadFailed:
@@ -4882,8 +4883,10 @@ static void TryListInitialization(Sema &S,
bool TreatUnavailableAsInvalid) {
QualType DestType = Entity.getType();
- if (S.getLangOpts().HLSL && !S.HLSL().transformInitList(Entity, InitList))
+ if (S.getLangOpts().HLSL && !S.HLSL().transformInitList(Entity, InitList)) {
+ Sequence.SetFailed(InitializationSequence::FK_HLSLInitListFlatteningFailed);
return;
+ }
// C++ doesn't allow scalar initialization with more than one argument.
// But C99 complex numbers are scalars and it makes sense there.
@@ -6817,33 +6820,18 @@ void InitializationSequence::InitializeFrom(Sema &S,
assert(Args.size() >= 1 && "Zero-argument case handled above");
// For HLSL ext vector types we allow list initialization behavior for C++
- // constructor syntax. This is accomplished by converting initialization
- // arguments an InitListExpr late.
+ // functional cast expressions which look like constructor syntax. This is
+ // accomplished by converting initialization arguments to InitListExpr.
if (S.getLangOpts().HLSL && Args.size() > 1 && DestType->isExtVectorType() &&
(SourceType.isNull() ||
!Context.hasSameUnqualifiedType(SourceType, DestType))) {
-
- llvm::SmallVector<Expr *> InitArgs;
- for (auto *Arg : Args) {
- if (Arg->getType()->isExtVectorType()) {
- const auto *VTy = Arg->getType()->castAs<ExtVectorType>();
- unsigned Elm = VTy->getNumElements();
- for (unsigned Idx = 0; Idx < Elm; ++Idx) {
- InitArgs.emplace_back(new (Context) ArraySubscriptExpr(
- Arg,
- IntegerLiteral::Create(
- Context, llvm::APInt(Context.getIntWidth(Context.IntTy), Idx),
- Context.IntTy, SourceLocation()),
- VTy->getElementType(), Arg->getValueKind(), Arg->getObjectKind(),
- SourceLocation()));
- }
- } else
- InitArgs.emplace_back(Arg);
- }
- InitListExpr *ILE = new (Context) InitListExpr(
- S.getASTContext(), SourceLocation(), InitArgs, SourceLocation());
+ InitListExpr *ILE = new (Context)
+ InitListExpr(S.getASTContext(), Args.front()->getBeginLoc(), Args,
+ Args.back()->getEndLoc());
+ ILE->setType(DestType);
Args[0] = ILE;
- AddListInitializationStep(DestType);
+ TryListInitialization(S, Entity, Kind, ILE, *this,
+ TreatUnavailableAsInvalid);
return;
}
@@ -9301,6 +9289,14 @@ bool InitializationSequence::Diagnose(Sema &S,
break;
}
+ case InitializationSequence::FK_HLSLInitListFlatteningFailed: {
+ // Unlike C/C++ list initialization, there is no fallback if it fails. This
+ // allows us to diagnose the failure when it happens in the
+ // TryListInitialization call instead of delaying the diagnosis, which is
+ // beneficial because the flattening is also expensive.
+ break;
+ }
+
case FK_ExplicitConstructor: {
S.Diag(Kind.getLocation(), diag::err_selected_explicit_constructor)
<< Args[0]->getSourceRange();
@@ -9499,6 +9495,10 @@ void InitializationSequence::dump(raw_ostream &OS) const {
case FK_DesignatedInitForNonAggregate:
OS << "designated initializer for non-aggregate type";
break;
+
+ case FK_HLSLInitListFlatteningFailed:
+ OS << "HLSL initialization list flattening failed";
+ break;
}
OS << '\n';
return;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5657dfe..8d32ef6 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1087,14 +1087,14 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation OpLoc,
}
bool OverloadCandidateSet::OperatorRewriteInfo::allowsReversed(
- OverloadedOperatorKind Op) {
+ OverloadedOperatorKind Op) const {
if (!AllowRewrittenCandidates)
return false;
return Op == OO_EqualEqual || Op == OO_Spaceship;
}
bool OverloadCandidateSet::OperatorRewriteInfo::shouldAddReversed(
- Sema &S, ArrayRef<Expr *> OriginalArgs, FunctionDecl *FD) {
+ Sema &S, ArrayRef<Expr *> OriginalArgs, FunctionDecl *FD) const {
auto Op = FD->getOverloadedOperator();
if (!allowsReversed(Op))
return false;