diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 42 | ||||
-rw-r--r-- | clang/lib/Sema/SemaHLSL.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 48 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenACC.cpp | 21 |
4 files changed, 62 insertions, 59 deletions
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; diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 7ad7049..8471f02 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -2724,16 +2724,6 @@ Expr *GenerateReductionInitRecipeExpr(ASTContext &Context, return InitExpr; } -const Expr *StripOffBounds(const Expr *VarExpr) { - while (isa_and_present<ArraySectionExpr, ArraySubscriptExpr>(VarExpr)) { - if (const auto *AS = dyn_cast<ArraySectionExpr>(VarExpr)) - VarExpr = AS->getBase()->IgnoreParenImpCasts(); - else if (const auto *Sub = dyn_cast<ArraySubscriptExpr>(VarExpr)) - VarExpr = Sub->getBase()->IgnoreParenImpCasts(); - } - return VarExpr; -} - VarDecl *CreateAllocaDecl(ASTContext &Ctx, DeclContext *DC, SourceLocation BeginLoc, IdentifierInfo *VarName, QualType VarTy) { @@ -2794,17 +2784,18 @@ OpenACCPrivateRecipe SemaOpenACC::CreatePrivateInitRecipe(const Expr *VarExpr) { OpenACCFirstPrivateRecipe SemaOpenACC::CreateFirstPrivateInitRecipe(const Expr *VarExpr) { - // TODO: OpenACC: This shouldn't be necessary, see PrivateInitRecipe - VarExpr = StripOffBounds(VarExpr); - + // We don't strip bounds here, so that we are doing our recipe init at the + // 'lowest' possible level. Codegen is going to have to do its own 'looping'. if (!VarExpr || VarExpr->getType()->isDependentType()) return OpenACCFirstPrivateRecipe::Empty(); QualType VarTy = VarExpr->getType().getNonReferenceType().getUnqualifiedType(); - // TODO: OpenACC: for arrays/bounds versions, we're going to have to do a - // different initializer, but for now we can go ahead with this. + // Array sections are special, and we have to treat them that way. + if (const auto *ASE = + dyn_cast<ArraySectionExpr>(VarExpr->IgnoreParenImpCasts())) + VarTy = ArraySectionExpr::getBaseOriginalType(ASE); VarDecl *AllocaDecl = CreateAllocaDecl( getASTContext(), SemaRef.getCurContext(), VarExpr->getBeginLoc(), |