aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp4
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp42
-rw-r--r--clang/lib/Sema/SemaHLSL.cpp10
-rw-r--r--clang/lib/Sema/SemaInit.cpp48
4 files changed, 59 insertions, 45 deletions
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/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 fa30c66b..a662b72 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -1289,8 +1289,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)) {
@@ -3571,9 +3571,6 @@ bool SemaHLSL::CanPerformAggregateSplatCast(Expr *Src, QualType DestTy) {
if (SrcVecTy)
SrcTy = SrcVecTy->getElementType();
- if (ContainsBitField(DestTy))
- return false;
-
llvm::SmallVector<QualType> DestTypes;
BuildFlattenedTypeList(DestTy, DestTypes);
@@ -3600,9 +3597,6 @@ bool SemaHLSL::CanPerformElementwiseCast(Expr *Src, QualType DestTy) {
(DestTy->isScalarType() || DestTy->isVectorType()))
return false;
- if (ContainsBitField(DestTy) || ContainsBitField(SrcTy))
- return false;
-
llvm::SmallVector<QualType> DestTypes;
BuildFlattenedTypeList(DestTy, DestTypes);
llvm::SmallVector<QualType> SrcTypes;
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;