Lines Matching +full:no +full:- +full:ct
1 //===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
29 if (const PointerType *PtrTy = T->getAs<PointerType>()) in GetUnderlyingFunction()
30 T = PtrTy->getPointeeType(); in GetUnderlyingFunction()
31 else if (const ReferenceType *RefTy = T->getAs<ReferenceType>()) in GetUnderlyingFunction()
32 T = RefTy->getPointeeType(); in GetUnderlyingFunction()
33 else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) in GetUnderlyingFunction()
34 T = MPTy->getPointeeType(); in GetUnderlyingFunction()
35 return T->getAs<FunctionProtoType>(); in GetUnderlyingFunction()
38 /// HACK: 2014-11-14 libstdc++ had a bug where it shadows std::swap with a
41 /// we're in such a case and turns off delay-parsing of exception
42 /// specifications. Libstdc++ 6.1 (released 2016-04-27) appears to have
43 /// resolved it as side-effect of commit ddb63209a8d (2015-06-05).
50 if (!RD || !RD->getIdentifier() || !RD->getDescribedClassTemplate() || in isLibstdcxxEagerExceptionSpecHack()
51 !D.getIdentifier() || !D.getIdentifier()->isStr("swap")) in isLibstdcxxEagerExceptionSpecHack()
54 auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext()); in isLibstdcxxEagerExceptionSpecHack()
58 bool IsInStd = ND->isStdNamespace(); in isLibstdcxxEagerExceptionSpecHack()
62 IdentifierInfo *II = ND->getIdentifier(); in isLibstdcxxEagerExceptionSpecHack()
63 if (!II || !(II->isStr("__debug") || II->isStr("__profile")) || in isLibstdcxxEagerExceptionSpecHack()
64 !ND->isInStdNamespace()) in isLibstdcxxEagerExceptionSpecHack()
72 return llvm::StringSwitch<bool>(RD->getIdentifier()->getName()) in isLibstdcxxEagerExceptionSpecHack()
91 CXXBoolLiteralExpr(false, Context.BoolTy, NoexceptExpr->getBeginLoc()); in ActOnNoexceptSpec()
97 if (Converted.get()->isValueDependent()) { in ActOnNoexceptSpec()
110 /// CheckSpecifiedExceptionType - Check if the given type is valid in an
119 // in an exception-specification is adjusted to type T, "pointer to T", or in CheckSpecifiedExceptionType()
123 if (T->isArrayType()) in CheckSpecifiedExceptionType()
125 else if (T->isFunctionType()) in CheckSpecifiedExceptionType()
130 if (const PointerType *PT = T->getAs<PointerType>()) { in CheckSpecifiedExceptionType()
131 PointeeT = PT->getPointeeType(); in CheckSpecifiedExceptionType()
136 if (PointeeT->isVoidType()) in CheckSpecifiedExceptionType()
138 } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) { in CheckSpecifiedExceptionType()
139 PointeeT = RT->getPointeeType(); in CheckSpecifiedExceptionType()
142 if (RT->isRValueReferenceType()) { in CheckSpecifiedExceptionType()
144 // A type denoted in an exception-specification shall not denote [...] in CheckSpecifiedExceptionType()
153 // A type denoted in an exception-specification shall not denote an in CheckSpecifiedExceptionType()
155 // A type denoted in an exception-specification shall not denote a in CheckSpecifiedExceptionType()
165 if (!(PointeeT->isRecordType() && in CheckSpecifiedExceptionType()
166 PointeeT->castAs<RecordType>()->isBeingDefined()) && in CheckSpecifiedExceptionType()
172 if (PointeeT->isSizelessType() && Kind != 1) { in CheckSpecifiedExceptionType()
181 /// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer
190 if (const PointerType *PT = T->getAs<PointerType>()) in CheckDistantExceptionSpec()
191 T = PT->getPointeeType(); in CheckDistantExceptionSpec()
192 else if (const MemberPointerType *PT = T->getAs<MemberPointerType>()) in CheckDistantExceptionSpec()
193 T = PT->getPointeeType(); in CheckDistantExceptionSpec()
197 const FunctionProtoType *FnT = T->getAs<FunctionProtoType>(); in CheckDistantExceptionSpec()
201 return FnT->hasExceptionSpec(); in CheckDistantExceptionSpec()
206 if (FPT->getExceptionSpecType() == EST_Unparsed) { in ResolveExceptionSpec()
211 if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) in ResolveExceptionSpec()
214 FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl(); in ResolveExceptionSpec()
216 SourceDecl->getType()->castAs<FunctionProtoType>(); in ResolveExceptionSpec()
219 if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType())) in ResolveExceptionSpec()
223 if (SourceFPT->getExceptionSpecType() == EST_Unevaluated) in ResolveExceptionSpec()
229 SourceDecl->getType()->castAs<FunctionProtoType>(); in ResolveExceptionSpec()
230 if (Proto->getExceptionSpecType() == clang::EST_Unparsed) { in ResolveExceptionSpec()
243 Listener->ResolvedExceptionSpec(FD); in UpdateExceptionSpec()
245 for (FunctionDecl *Redecl : FD->redecls()) in UpdateExceptionSpec()
254 auto EST = MD->getType()->castAs<FunctionProtoType>()->getExceptionSpecType(); in exceptionSpecNotKnownYet()
256 (EST == EST_Unevaluated && MD->getParent()->isBeingDefined()); in exceptionSpecNotKnownYet()
267 /// Determine whether a function has an implicitly-generated exception
271 Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete && in hasImplicitExceptionSpec()
272 Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) in hasImplicitExceptionSpec()
276 // - if this is a destructor, its exception specification is implicit. in hasImplicitExceptionSpec()
277 // - if this is 'operator delete' or 'operator delete[]', the exception in hasImplicitExceptionSpec()
278 // specification is as-if an explicit exception specification was given in hasImplicitExceptionSpec()
280 if (!Decl->getTypeSourceInfo()) in hasImplicitExceptionSpec()
283 auto *Ty = Decl->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>(); in hasImplicitExceptionSpec()
284 return !Ty->hasExceptionSpec(); in hasImplicitExceptionSpec()
288 // Just completely ignore this under -fno-exceptions prior to C++17. in CheckEquivalentExceptionSpec()
294 OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator(); in CheckEquivalentExceptionSpec()
318 Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(), in CheckEquivalentExceptionSpec()
319 New->getType()->getAs<FunctionProtoType>(), New->getLocation(), in CheckEquivalentExceptionSpec()
324 // exception-specification, other declarations of the function shall in CheckEquivalentExceptionSpec()
325 // not specify an exception-specification. in CheckEquivalentExceptionSpec()
328 Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch) in CheckEquivalentExceptionSpec()
330 if (Old->getLocation().isValid()) in CheckEquivalentExceptionSpec()
331 Diag(Old->getLocation(), diag::note_previous_declaration); in CheckEquivalentExceptionSpec()
342 New->getType()->castAs<FunctionProtoType>(); in CheckEquivalentExceptionSpec()
353 (Old->getLocation().isInvalid() || in CheckEquivalentExceptionSpec()
354 Context.getSourceManager().isInSystemHeader(Old->getLocation()) || in CheckEquivalentExceptionSpec()
355 Old->getBuiltinID()) && in CheckEquivalentExceptionSpec()
356 Old->isExternC()) { in CheckEquivalentExceptionSpec()
357 New->setType(Context.getFunctionType( in CheckEquivalentExceptionSpec()
358 NewProto->getReturnType(), NewProto->getParamTypes(), in CheckEquivalentExceptionSpec()
359 NewProto->getExtProtoInfo().withExceptionSpec(EST_DynamicNone))); in CheckEquivalentExceptionSpec()
364 Old->getType()->castAs<FunctionProtoType>(); in CheckEquivalentExceptionSpec()
366 FunctionProtoType::ExceptionSpecInfo ESI = OldProto->getExceptionSpecType(); in CheckEquivalentExceptionSpec()
370 ESI.Exceptions = OldProto->exceptions(); in CheckEquivalentExceptionSpec()
381 New->setInvalidDecl(); in CheckEquivalentExceptionSpec()
385 New->setType(Context.getFunctionType( in CheckEquivalentExceptionSpec()
386 NewProto->getReturnType(), NewProto->getParamTypes(), in CheckEquivalentExceptionSpec()
387 NewProto->getExtProtoInfo().withExceptionSpec(ESI))); in CheckEquivalentExceptionSpec()
394 } else if (New->isReplaceableGlobalAllocationFunction() && in CheckEquivalentExceptionSpec()
413 switch (OldProto->getExceptionSpecType()) { in CheckEquivalentExceptionSpec()
421 for (const auto &E : OldProto->exceptions()) { in CheckEquivalentExceptionSpec()
441 assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr"); in CheckEquivalentExceptionSpec()
442 OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy()); in CheckEquivalentExceptionSpec()
457 if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) { in CheckEquivalentExceptionSpec()
458 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); in CheckEquivalentExceptionSpec()
462 if (!FTLoc.getTypePtr()->hasTrailingReturn()) in CheckEquivalentExceptionSpec()
467 Diag(New->getLocation(), DiagID) in CheckEquivalentExceptionSpec()
470 Diag(New->getLocation(), DiagID) in CheckEquivalentExceptionSpec()
475 if (Old->getLocation().isValid()) in CheckEquivalentExceptionSpec()
476 Diag(Old->getLocation(), diag::note_previous_declaration); in CheckEquivalentExceptionSpec()
481 /// CheckEquivalentExceptionSpec - Check if the two types have equivalent
504 /// CheckEquivalentExceptionSpec - Check if the two types have compatible
530 // C++0x [except.spec]p3: Two exception-specifications are compatible if: in CheckEquivalentExceptionSpecImpl()
531 // - both are non-throwing, regardless of their form, in CheckEquivalentExceptionSpecImpl()
532 // - both have the form noexcept(constant-expression) and the constant- in CheckEquivalentExceptionSpecImpl()
534 // - both are dynamic-exception-specifications that have the same set of in CheckEquivalentExceptionSpecImpl()
537 // C++0x [except.spec]p12: An exception-specification is non-throwing if it is in CheckEquivalentExceptionSpecImpl()
538 // of the form throw(), noexcept, or noexcept(constant-expression) where the in CheckEquivalentExceptionSpecImpl()
539 // constant-expression yields true. in CheckEquivalentExceptionSpecImpl()
541 // C++0x [except.spec]p4: If any declaration of a function has an exception- in CheckEquivalentExceptionSpecImpl()
542 // specifier that is not a noexcept-specification allowing all exceptions, in CheckEquivalentExceptionSpecImpl()
544 // exception-specification. in CheckEquivalentExceptionSpecImpl()
546 // That last point basically means that noexcept(false) matches no spec. in CheckEquivalentExceptionSpecImpl()
549 ExceptionSpecificationType OldEST = Old->getExceptionSpecType(); in CheckEquivalentExceptionSpecImpl()
550 ExceptionSpecificationType NewEST = New->getExceptionSpecType(); in CheckEquivalentExceptionSpecImpl()
556 CanThrowResult OldCanThrow = Old->canThrow(); in CheckEquivalentExceptionSpecImpl()
557 CanThrowResult NewCanThrow = New->canThrow(); in CheckEquivalentExceptionSpecImpl()
559 // Any non-throwing specifications are compatible. in CheckEquivalentExceptionSpecImpl()
563 // Any throws-anything specifications are usually compatible. in CheckEquivalentExceptionSpecImpl()
578 // Two exception-specifications are compatible if [...] both have the form in CheckEquivalentExceptionSpecImpl()
579 // noexcept(constant-expression) and the constant-expressions are equivalent in CheckEquivalentExceptionSpecImpl()
582 Old->getNoexceptExpr()->Profile(OldFSN, S.Context, true); in CheckEquivalentExceptionSpecImpl()
583 New->getNoexceptExpr()->Profile(NewFSN, S.Context, true); in CheckEquivalentExceptionSpecImpl()
595 for (const auto &I : Old->exceptions()) in CheckEquivalentExceptionSpecImpl()
598 for (const auto &I : New->exceptions()) { in CheckEquivalentExceptionSpecImpl()
612 // As a special compatibility feature, under C++0x we accept no spec and in CheckEquivalentExceptionSpecImpl()
621 if (WithExceptions && WithExceptions->getNumExceptions() == 1) { in CheckEquivalentExceptionSpecImpl()
622 // One has no spec, the other throw(something). If that something is in CheckEquivalentExceptionSpecImpl()
624 QualType Exception = *WithExceptions->exception_begin(); in CheckEquivalentExceptionSpecImpl()
625 if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) { in CheckEquivalentExceptionSpecImpl()
626 IdentifierInfo* Name = ExRecord->getIdentifier(); in CheckEquivalentExceptionSpecImpl()
627 if (Name && Name->getName() == "bad_alloc") { in CheckEquivalentExceptionSpecImpl()
629 if (ExRecord->isInStdNamespace()) { in CheckEquivalentExceptionSpecImpl()
647 // and the new type has no exception specification, and the caller asked in CheckEquivalentExceptionSpecImpl()
679 const ReferenceType *RefTy = HandlerType->getAs<ReferenceType>(); in handlerCanCatch()
681 HandlerType = RefTy->getPointeeType(); in handlerCanCatch()
683 // -- the handler is of type cv T or cv T& and E and T are the same type in handlerCanCatch()
688 if (HandlerType->isPointerType() || HandlerType->isMemberPointerType()) { in handlerCanCatch()
693 // -- the handler is of type cv T or const T& where T is a pointer or in handlerCanCatch()
695 if (ExceptionType->isNullPtrType()) in handlerCanCatch()
698 // -- the handler is of type cv T or const T& where T is a pointer or in handlerCanCatch()
701 // -- a qualification conversion in handlerCanCatch()
702 // -- a function pointer conversion in handlerCanCatch()
712 // -- a standard pointer conversion [...] in handlerCanCatch()
713 if (!ExceptionType->isPointerType() || !HandlerType->isPointerType()) in handlerCanCatch()
719 ExceptionType->getPointeeType(), EQuals); in handlerCanCatch()
721 HandlerType->getPointeeType(), HQuals); in handlerCanCatch()
725 if (HandlerType->isVoidType() && ExceptionType->isObjectType()) in handlerCanCatch()
728 // The only remaining case is a derived-to-base conversion. in handlerCanCatch()
731 // -- the handler is of type cg T or cv T& and T is an unambiguous public in handlerCanCatch()
733 if (!ExceptionType->isRecordType() || !HandlerType->isRecordType()) in handlerCanCatch()
752 llvm_unreachable("access check delayed in non-declaration"); in handlerCanCatch()
757 /// CheckExceptionSpecSubset - Check whether the second function type's
769 // Just auto-succeed under -fno-exceptions. in CheckExceptionSpecSubset()
787 ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType(); in CheckExceptionSpecSubset()
788 ExceptionSpecificationType SubEST = Subset->getExceptionSpecType(); in CheckExceptionSpecSubset()
800 CanThrowResult SuperCanThrow = Superset->canThrow(); in CheckExceptionSpecSubset()
801 CanThrowResult SubCanThrow = Subset->canThrow(); in CheckExceptionSpecSubset()
831 "Exception spec subset: non-dynamic case slipped through."); in CheckExceptionSpecSubset()
834 for (QualType SubI : Subset->exceptions()) { in CheckExceptionSpecSubset()
835 if (const ReferenceType *RefTy = SubI->getAs<ReferenceType>()) in CheckExceptionSpecSubset()
836 SubI = RefTy->getPointeeType(); in CheckExceptionSpecSubset()
840 for (QualType SuperI : Superset->exceptions()) { in CheckExceptionSpecSubset()
880 /// CheckParamExceptionSpec - Check if the parameter and return types of the
883 /// of parameter function pointers recursively, as no sane programmer would
895 Target->getReturnType(), TargetLoc, Source->getReturnType(), in CheckParamExceptionSpec()
901 assert(Target->getNumParams() == Source->getNumParams() && in CheckParamExceptionSpec()
903 for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) { in CheckParamExceptionSpec()
908 Target->getParamType(i), TargetLoc, Source->getParamType(i), in CheckParamExceptionSpec()
919 if (!ToFunc || ToFunc->hasDependentExceptionSpec()) in CheckExceptionSpecCompatibility()
923 const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType()); in CheckExceptionSpecCompatibility()
924 if (!FromFunc || FromFunc->hasDependentExceptionSpec()) in CheckExceptionSpecCompatibility()
930 // match, but in that case we have a full-on type mismatch, not just a in CheckExceptionSpecCompatibility()
951 From->getSourceRange().getBegin(), FromFunc, SourceLocation()) && in CheckExceptionSpecCompatibility()
959 if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == in CheckOverridingFunctionExceptionSpec()
965 if (isa<CXXDestructorDecl>(New) && New->getParent()->isDependentType()) in CheckOverridingFunctionExceptionSpec()
971 // lexically-surrounding class. in CheckOverridingFunctionExceptionSpec()
984 Old->getType()->castAs<FunctionProtoType>(), in CheckOverridingFunctionExceptionSpec()
985 Old->getLocation(), in CheckOverridingFunctionExceptionSpec()
986 New->getType()->castAs<FunctionProtoType>(), in CheckOverridingFunctionExceptionSpec()
987 New->getLocation()); in CheckOverridingFunctionExceptionSpec()
992 for (const Stmt *SubStmt : S->children()) { in canSubStmtsThrow()
1006 if (D && isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) in canCalleeThrow()
1013 E = cast<CallExpr>(E)->getCallee(); in canCalleeThrow()
1014 T = E->getType(); in canCalleeThrow()
1015 if (T->isSpecificPlaceholderType(BuiltinType::BoundMember)) { in canCalleeThrow()
1018 E = E->IgnoreParenImpCasts(); in canCalleeThrow()
1020 // Could be a call to a pointer-to-member or a plain member access. in canCalleeThrow()
1022 assert(Op->getOpcode() == BO_PtrMemD || Op->getOpcode() == BO_PtrMemI); in canCalleeThrow()
1023 T = Op->getRHS()->getType() in canCalleeThrow()
1024 ->castAs<MemberPointerType>()->getPointeeType(); in canCalleeThrow()
1026 T = cast<MemberExpr>(E)->getMemberDecl()->getType(); in canCalleeThrow()
1030 T = VD->getType(); in canCalleeThrow()
1032 // If we have no clue what we're calling, assume the worst. in canCalleeThrow()
1036 if ((FT = T->getAs<FunctionProtoType>())) { in canCalleeThrow()
1037 } else if (const PointerType *PT = T->getAs<PointerType>()) in canCalleeThrow()
1038 FT = PT->getPointeeType()->getAs<FunctionProtoType>(); in canCalleeThrow()
1039 else if (const ReferenceType *RT = T->getAs<ReferenceType>()) in canCalleeThrow()
1040 FT = RT->getPointeeType()->getAs<FunctionProtoType>(); in canCalleeThrow()
1041 else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) in canCalleeThrow()
1042 FT = MT->getPointeeType()->getAs<FunctionProtoType>(); in canCalleeThrow()
1043 else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) in canCalleeThrow()
1044 FT = BT->getPointeeType()->getAs<FunctionProtoType>(); in canCalleeThrow()
1050 FT = S.ResolveExceptionSpec(Loc.isInvalid() ? E->getBeginLoc() : Loc, FT); in canCalleeThrow()
1054 return FT->canThrow(); in canCalleeThrow()
1058 CanThrowResult CT = CT_Cannot; in canVarDeclThrow() local
1061 if (!VD->isUsableInConstantExpressions(Self.Context)) in canVarDeclThrow()
1062 if (const Expr *Init = VD->getInit()) in canVarDeclThrow()
1063 CT = mergeCanThrow(CT, Self.canThrow(Init)); in canVarDeclThrow()
1066 if (VD->needsDestruction(Self.Context) == QualType::DK_cxx_destructor) { in canVarDeclThrow()
1068 VD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) { in canVarDeclThrow()
1069 if (auto *Dtor = RD->getDestructor()) { in canVarDeclThrow()
1070 CT = mergeCanThrow( in canVarDeclThrow()
1071 CT, Sema::canCalleeThrow(Self, nullptr, Dtor, VD->getLocation())); in canVarDeclThrow()
1078 for (auto *B : DD->bindings()) in canVarDeclThrow()
1079 if (auto *HD = B->getHoldingVar()) in canVarDeclThrow()
1080 CT = mergeCanThrow(CT, canVarDeclThrow(Self, HD)); in canVarDeclThrow()
1082 return CT; in canVarDeclThrow()
1086 if (DC->isTypeDependent()) in canDynamicCastThrow()
1089 if (!DC->getTypeAsWritten()->isReferenceType()) in canDynamicCastThrow()
1092 if (DC->getSubExpr()->isTypeDependent()) in canDynamicCastThrow()
1095 return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot; in canDynamicCastThrow()
1099 if (DC->isTypeOperand()) in canTypeidThrow()
1102 Expr *Op = DC->getExprOperand(); in canTypeidThrow()
1103 if (Op->isTypeDependent()) in canTypeidThrow()
1106 const RecordType *RT = Op->getType()->getAs<RecordType>(); in canTypeidThrow()
1110 if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) in canTypeidThrow()
1113 if (Op->Classify(S.Context).isPRValue()) in canTypeidThrow()
1121 // [Can throw] if in a potentially-evaluated context the expression would in canThrow()
1123 switch (S->getStmtClass()) { in canThrow()
1125 return canThrow(cast<ConstantExpr>(S)->getSubExpr()); in canThrow()
1128 // - a potentially evaluated throw-expression in canThrow()
1132 // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), in canThrow()
1133 // where T is a reference type, that requires a run-time check in canThrow()
1135 // FIXME: Properly determine whether a variably-modified type can throw. in canThrow()
1136 if (CE->getType()->isVariablyModifiedType()) in canThrow()
1138 CanThrowResult CT = canDynamicCastThrow(CE); in canThrow() local
1139 if (CT == CT_Can) in canThrow()
1140 return CT; in canThrow()
1141 return mergeCanThrow(CT, canSubStmtsThrow(*this, CE)); in canThrow()
1145 // - a potentially evaluated typeid expression applied to a glvalue in canThrow()
1149 // - a potentially evaluated call to a function, member function, function in canThrow()
1150 // pointer, or member function pointer that does not have a non-throwing in canThrow()
1151 // exception-specification in canThrow()
1157 CanThrowResult CT; in canThrow() local
1158 if (CE->isTypeDependent()) in canThrow()
1159 CT = CT_Dependent; in canThrow()
1160 else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) in canThrow()
1161 CT = CT_Cannot; in canThrow()
1163 CT = canCalleeThrow(*this, CE, CE->getCalleeDecl()); in canThrow()
1164 if (CT == CT_Can) in canThrow()
1165 return CT; in canThrow()
1166 return mergeCanThrow(CT, canSubStmtsThrow(*this, CE)); in canThrow()
1172 // FIXME: Properly determine whether a variably-modified type can throw. in canThrow()
1173 if (CE->getType()->isVariablyModifiedType()) in canThrow()
1175 CanThrowResult CT = canCalleeThrow(*this, CE, CE->getConstructor()); in canThrow() local
1176 if (CT == CT_Can) in canThrow()
1177 return CT; in canThrow()
1178 return mergeCanThrow(CT, canSubStmtsThrow(*this, CE)); in canThrow()
1183 return canCalleeThrow(*this, ICIE, ICIE->getConstructor()); in canThrow()
1188 CanThrowResult CT = CT_Cannot; in canThrow() local
1190 Cap = Lambda->capture_init_begin(), in canThrow()
1191 CapEnd = Lambda->capture_init_end(); in canThrow()
1193 CT = mergeCanThrow(CT, canThrow(*Cap)); in canThrow()
1194 return CT; in canThrow()
1199 CanThrowResult CT; in canThrow() local
1200 if (NE->isTypeDependent()) in canThrow()
1201 CT = CT_Dependent; in canThrow()
1203 CT = canCalleeThrow(*this, NE, NE->getOperatorNew()); in canThrow()
1204 if (CT == CT_Can) in canThrow()
1205 return CT; in canThrow()
1206 return mergeCanThrow(CT, canSubStmtsThrow(*this, NE)); in canThrow()
1211 CanThrowResult CT; in canThrow() local
1212 QualType DTy = DE->getDestroyedType(); in canThrow()
1213 if (DTy.isNull() || DTy->isDependentType()) { in canThrow()
1214 CT = CT_Dependent; in canThrow()
1216 CT = canCalleeThrow(*this, DE, DE->getOperatorDelete()); in canThrow()
1217 if (const RecordType *RT = DTy->getAs<RecordType>()) { in canThrow()
1218 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); in canThrow()
1219 const CXXDestructorDecl *DD = RD->getDestructor(); in canThrow()
1221 CT = mergeCanThrow(CT, canCalleeThrow(*this, DE, DD)); in canThrow()
1223 if (CT == CT_Can) in canThrow()
1224 return CT; in canThrow()
1226 return mergeCanThrow(CT, canSubStmtsThrow(*this, DE)); in canThrow()
1232 CanThrowResult CT = in canThrow() local
1233 canCalleeThrow(*this, BTE, BTE->getTemporary()->getDestructor()); in canThrow()
1234 if (CT == CT_Can) in canThrow()
1235 return CT; in canThrow()
1236 return mergeCanThrow(CT, canSubStmtsThrow(*this, BTE)); in canThrow()
1241 CanThrowResult CT = CT_Cannot; in canThrow() local
1242 for (const Expr *E : POE->semantics()) { in canThrow()
1243 CT = mergeCanThrow(CT, canThrow(E)); in canThrow()
1244 if (CT == CT_Can) in canThrow()
1247 return CT; in canThrow()
1294 // FIXME: Properly determine whether a variably-modified type can throw. in canThrow()
1295 if (cast<Expr>(S)->getType()->isVariablyModifiedType()) in canThrow()
1314 // FIXME: Properly determine whether a variably-modified type can throw. in canThrow()
1316 if (CE->getType()->isVariablyModifiedType()) in canThrow()
1318 CanThrowResult CT = in canThrow() local
1319 cast<Expr>(S)->isTypeDependent() ? CT_Dependent : CT_Cannot; in canThrow()
1320 return mergeCanThrow(CT, canSubStmtsThrow(*this, S)); in canThrow()
1324 return canThrow(cast<CXXDefaultArgExpr>(S)->getExpr()); in canThrow()
1327 return canThrow(cast<CXXDefaultInitExpr>(S)->getExpr()); in canThrow()
1331 if (CE->isTypeDependent() || CE->isValueDependent()) in canThrow()
1333 return canThrow(CE->getChosenSubExpr()); in canThrow()
1337 if (cast<GenericSelectionExpr>(S)->isResultDependent()) in canThrow()
1339 return canThrow(cast<GenericSelectionExpr>(S)->getResultExpr()); in canThrow()
1504 CanThrowResult CT = CT_Cannot; in canThrow() local
1505 for (const Decl *D : cast<DeclStmt>(S)->decls()) { in canThrow()
1507 CT = mergeCanThrow(CT, canVarDeclThrow(*this, VD)); in canThrow()
1509 // FIXME: Properly determine whether a variably-modified type can throw. in canThrow()
1511 if (TND->getUnderlyingType()->isVariablyModifiedType()) in canThrow()
1514 if (VD->getType()->isVariablyModifiedType()) in canThrow()
1517 return CT; in canThrow()
1522 CanThrowResult CT = CT_Cannot; in canThrow() local
1523 if (const Stmt *Init = IS->getInit()) in canThrow()
1524 CT = mergeCanThrow(CT, canThrow(Init)); in canThrow()
1525 if (const Stmt *CondDS = IS->getConditionVariableDeclStmt()) in canThrow()
1526 CT = mergeCanThrow(CT, canThrow(CondDS)); in canThrow()
1527 CT = mergeCanThrow(CT, canThrow(IS->getCond())); in canThrow()
1529 // For 'if constexpr', consider only the non-discarded case. in canThrow()
1531 if (Optional<const Stmt *> Case = IS->getNondiscardedCase(Context)) in canThrow()
1532 return *Case ? mergeCanThrow(CT, canThrow(*Case)) : CT; in canThrow()
1534 CanThrowResult Then = canThrow(IS->getThen()); in canThrow()
1535 CanThrowResult Else = IS->getElse() ? canThrow(IS->getElse()) : CT_Cannot; in canThrow()
1537 return mergeCanThrow(CT, Then); in canThrow()
1541 return mergeCanThrow(CT, IS->isConstexpr() ? CT_Dependent in canThrow()
1548 // Any other try-catch can throw if any substatement can throw. in canThrow()
1549 const CXXCatchStmt *FinalHandler = TS->getHandler(TS->getNumHandlers() - 1); in canThrow()
1550 if (!FinalHandler->getExceptionDecl()) in canThrow()
1551 return canThrow(FinalHandler->getHandlerBlock()); in canThrow()
1561 // @catch(...) need not be last in Objective-C. Walk backwards until we in canThrow()
1563 CanThrowResult CT = CT_Cannot; in canThrow() local
1564 if (const Stmt *Finally = TS->getFinallyStmt()) in canThrow()
1565 CT = mergeCanThrow(CT, canThrow(Finally)); in canThrow()
1566 for (unsigned I = TS->getNumCatchStmts(); I != 0; --I) { in canThrow()
1567 const ObjCAtCatchStmt *Catch = TS->getCatchStmt(I - 1); in canThrow()
1568 CT = mergeCanThrow(CT, canThrow(Catch)); in canThrow()
1569 // If we reach a @catch(...), no earlier exceptions can escape. in canThrow()
1570 if (Catch->hasEllipsis()) in canThrow()
1571 return CT; in canThrow()
1575 return mergeCanThrow(CT, canThrow(TS->getTryBody())); in canThrow()