22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/SmallString.h"
45 auto *RD = dyn_cast<CXXRecordDecl>(
CurContext);
50 if (!RD || !RD->getIdentifier() || !RD->getDescribedClassTemplate() ||
54 auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext());
58 bool IsInStd = ND->isStdNamespace();
63 if (!II || !(II->
isStr(
"__debug") || II->
isStr(
"__profile")) ||
64 !ND->isInStdNamespace())
72 return llvm::StringSwitch<bool>(RD->getIdentifier()->getName())
74 .Case(
"pair", IsInStd)
75 .Case(
"priority_queue", IsInStd)
76 .Case(
"stack", IsInStd)
77 .Case(
"queue", IsInStd)
146 if (RT->isRValueReferenceType()) {
150 Diag(Range.getBegin(), diag::err_rref_in_exception_spec)
163 unsigned DiagID = diag::err_incomplete_in_exception_spec;
164 bool ReturnValueOnError =
true;
166 DiagID = diag::ext_incomplete_in_exception_spec;
167 ReturnValueOnError =
false;
172 return ReturnValueOnError;
177 Diag(Range.getBegin(), diag::err_sizeless_in_exception_spec)
178 << (
Kind == 2 ? 1 : 0) << PointeeT << Range;
211 Diag(Loc, diag::err_exception_spec_not_parsed);
235 Diag(Loc, diag::err_exception_spec_not_parsed);
247 Listener->ResolvedExceptionSpec(FD);
254 auto *MD = dyn_cast<CXXMethodDecl>(FD);
264 Sema &S,
const PartialDiagnostic &DiagID,
const PartialDiagnostic &NoteID,
265 const FunctionProtoType *Old, SourceLocation OldLoc,
266 const FunctionProtoType *New, SourceLocation NewLoc,
267 bool *MissingExceptionSpecification =
nullptr,
268 bool *MissingEmptyExceptionSpecification =
nullptr,
269 bool AllowNoexceptAllMatchWithNoSpec =
false,
bool IsOperatorNew =
false);
274 if (!isa<CXXDestructorDecl>(
Decl) &&
275 Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete &&
276 Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
284 if (!
Decl->getTypeSourceInfo())
285 return isa<CXXDestructorDecl>(
Decl);
299 bool IsOperatorNew = OO == OO_New || OO == OO_Array_New;
300 bool MissingExceptionSpecification =
false;
301 bool MissingEmptyExceptionSpecification =
false;
303 unsigned DiagID = diag::err_mismatched_exception_spec;
304 bool ReturnValueOnError =
true;
306 DiagID = diag::ext_mismatched_exception_spec;
307 ReturnValueOnError =
false;
321 *
this,
PDiag(DiagID),
PDiag(diag::note_previous_declaration),
324 &MissingExceptionSpecification, &MissingEmptyExceptionSpecification,
325 true, IsOperatorNew)) {
342 if (!MissingExceptionSpecification)
343 return ReturnValueOnError;
355 if (MissingEmptyExceptionSpecification &&
361 NewProto->getReturnType(), NewProto->getParamTypes(),
388 NewProto->getReturnType(), NewProto->getParamTypes(),
389 NewProto->getExtProtoInfo().withExceptionSpec(ESI)));
393 DiagID = diag::ext_missing_exception_specification;
394 ReturnValueOnError =
false;
399 DiagID = diag::ext_missing_exception_specification;
400 ReturnValueOnError =
false;
408 DiagID = diag::ext_missing_exception_specification;
409 ReturnValueOnError =
false;
411 DiagID = diag::err_missing_exception_specification;
412 ReturnValueOnError =
true;
417 llvm::raw_svector_ostream OS(ExceptionSpecString);
418 switch (OldProto->getExceptionSpecType()) {
425 bool OnFirstException =
true;
426 for (
const auto &E : OldProto->exceptions()) {
427 if (OnFirstException)
428 OnFirstException =
false;
446 assert(OldProto->getNoexceptExpr() !=
nullptr &&
"Expected non-null Expr");
451 OS <<
"__attribute__((nothrow))";
458 llvm_unreachable(
"This spec type is compatible with none.");
467 if (!FTLoc.getTypePtr()->hasTrailingReturn())
483 return ReturnValueOnError;
496 unsigned DiagID = diag::err_mismatched_exception_spec;
498 DiagID = diag::ext_mismatched_exception_spec;
500 *
this,
PDiag(DiagID),
PDiag(diag::note_previous_declaration),
501 Old, OldLoc, New, NewLoc);
519 bool *MissingExceptionSpecification,
520 bool *MissingEmptyExceptionSpecification,
521 bool AllowNoexceptAllMatchWithNoSpec,
bool IsOperatorNew) {
522 if (MissingExceptionSpecification)
523 *MissingExceptionSpecification =
false;
525 if (MissingEmptyExceptionSpecification)
526 *MissingEmptyExceptionSpecification =
false;
559 "Shouldn't see unknown exception specifications here");
573 if (!AllowNoexceptAllMatchWithNoSpec &&
586 llvm::FoldingSetNodeID OldFSN, NewFSN;
589 if (OldFSN == NewFSN)
605 if (OldTypes.count(TypePtr))
606 NewTypes.insert(TypePtr);
613 if (Success && OldTypes.size() == NewTypes.size())
620 if (S.
getLangOpts().CPlusPlus11 && IsOperatorNew) {
623 WithExceptions = New;
625 WithExceptions = Old;
632 if (Name && Name->getName() ==
"bad_alloc") {
634 if (ExRecord->isInStdNamespace()) {
644 if (MissingExceptionSpecification && OldEST !=
EST_None &&
648 *MissingExceptionSpecification =
true;
650 if (MissingEmptyExceptionSpecification && OldCanThrow ==
CT_Cannot) {
654 *MissingEmptyExceptionSpecification =
true;
660 S.
Diag(NewLoc, DiagID);
662 S.
Diag(OldLoc, NoteID);
755 llvm_unreachable(
"access check dependent for unprivileged context");
757 llvm_unreachable(
"access check delayed in non-declaration");
759 llvm_unreachable(
"unexpected access check result");
796 "Shouldn't see unknown exception specifications here");
819 Diag(SubLoc, NoThrowDiagID);
821 Diag(SuperLoc, NoteID);
829 Diag(SubLoc, DiagID);
831 Diag(SuperLoc, NoteID);
836 "Exception spec subset: non-dynamic case slipped through.");
841 SubI = RefTy->getPointeeType();
844 bool Contained =
false;
858 Diag(SubLoc, DiagID);
860 Diag(SuperLoc, NoteID);
896 auto RetDiag = DiagID;
899 *
this, RetDiag,
PDiag(),
907 "Functions have different argument counts.");
908 for (
unsigned i = 0, E =
Target->getNumParams(); i != E; ++i) {
909 auto ParamDiag = DiagID;
912 *
this, ParamDiag,
PDiag(),
932 unsigned DiagID = diag::err_incompatible_exception_specs;
933 unsigned NestedDiagID = diag::err_deep_exception_specs_differ;
938 DiagID = diag::warn_incompatible_exception_specs;
939 NestedDiagID = diag::warn_deep_exception_specs_differ;
982 unsigned DiagID = diag::err_override_exception_spec;
984 DiagID = diag::ext_override_exception_spec;
986 PDiag(diag::err_deep_exception_specs_differ),
987 PDiag(diag::note_overridden_virtual_function),
988 PDiag(diag::ext_override_exception_spec),
997 for (
const Stmt *SubStmt : S->children()) {
1011 if (D && isa<FunctionDecl>(D) && D->
hasAttr<NoThrowAttr>())
1017 if (S.getLangOpts().CPlusPlus17 && E && isa<CallExpr>(E)) {
1018 E = cast<CallExpr>(E)->getCallee();
1026 if (
auto *Op = dyn_cast<BinaryOperator>(E)) {
1027 assert(Op->getOpcode() == BO_PtrMemD || Op->getOpcode() == BO_PtrMemI);
1028 T = Op->getRHS()->getType()
1031 T = cast<MemberExpr>(E)->getMemberDecl()->getType();
1034 }
else if (
const ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D))
1074 if (
auto *Dtor = RD->getDestructor()) {
1082 if (
auto *DD = dyn_cast<DecompositionDecl>(VD))
1083 for (
auto *B : DD->bindings())
1084 if (
auto *HD = B->getHoldingVar())
1115 if (!cast<CXXRecordDecl>(RT->
getDecl())->isPolymorphic())
1128 switch (S->getStmtClass()) {
1129 case Expr::ConstantExprClass:
1130 return canThrow(cast<ConstantExpr>(S)->getSubExpr());
1132 case Expr::CXXThrowExprClass:
1136 case Expr::CXXDynamicCastExprClass: {
1139 auto *CE = cast<CXXDynamicCastExpr>(S);
1141 if (CE->getType()->isVariablyModifiedType())
1149 case Expr::CXXTypeidExprClass:
1157 case Expr::CallExprClass:
1158 case Expr::CXXMemberCallExprClass:
1159 case Expr::CXXOperatorCallExprClass:
1160 case Expr::UserDefinedLiteralClass: {
1161 const CallExpr *CE = cast<CallExpr>(S);
1174 case Expr::CXXConstructExprClass:
1175 case Expr::CXXTemporaryObjectExprClass: {
1176 auto *CE = cast<CXXConstructExpr>(S);
1178 if (CE->getType()->isVariablyModifiedType())
1186 case Expr::CXXInheritedCtorInitExprClass: {
1187 auto *ICIE = cast<CXXInheritedCtorInitExpr>(S);
1191 case Expr::LambdaExprClass: {
1192 const LambdaExpr *Lambda = cast<LambdaExpr>(S);
1197 Cap != CapEnd; ++Cap)
1202 case Expr::CXXNewExprClass: {
1203 auto *
NE = cast<CXXNewExpr>(S);
1205 if (
NE->isTypeDependent())
1214 case Expr::CXXDeleteExprClass: {
1215 auto *DE = cast<CXXDeleteExpr>(S);
1217 QualType DTy = DE->getDestroyedType();
1223 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
1234 case Expr::CXXBindTemporaryExprClass: {
1235 auto *BTE = cast<CXXBindTemporaryExpr>(S);
1238 canCalleeThrow(*
this, BTE, BTE->getTemporary()->getDestructor());
1244 case Expr::PseudoObjectExprClass: {
1245 auto *POE = cast<PseudoObjectExpr>(S);
1247 for (
const Expr *E : POE->semantics()) {
1257 case Expr::ObjCMessageExprClass:
1258 case Expr::ObjCPropertyRefExprClass:
1259 case Expr::ObjCSubscriptRefExprClass:
1265 case Expr::ObjCArrayLiteralClass:
1266 case Expr::ObjCDictionaryLiteralClass:
1267 case Expr::ObjCBoxedExprClass:
1272 case Expr::CoawaitExprClass:
1273 case Expr::ConditionalOperatorClass:
1274 case Expr::CoyieldExprClass:
1275 case Expr::CXXRewrittenBinaryOperatorClass:
1276 case Expr::CXXStdInitializerListExprClass:
1277 case Expr::DesignatedInitExprClass:
1278 case Expr::DesignatedInitUpdateExprClass:
1279 case Expr::ExprWithCleanupsClass:
1280 case Expr::ExtVectorElementExprClass:
1281 case Expr::InitListExprClass:
1282 case Expr::ArrayInitLoopExprClass:
1283 case Expr::MemberExprClass:
1284 case Expr::ObjCIsaExprClass:
1285 case Expr::ObjCIvarRefExprClass:
1286 case Expr::ParenExprClass:
1287 case Expr::ParenListExprClass:
1288 case Expr::ShuffleVectorExprClass:
1289 case Expr::StmtExprClass:
1290 case Expr::ConvertVectorExprClass:
1291 case Expr::VAArgExprClass:
1294 case Expr::CompoundLiteralExprClass:
1295 case Expr::CXXConstCastExprClass:
1296 case Expr::CXXAddrspaceCastExprClass:
1297 case Expr::CXXReinterpretCastExprClass:
1298 case Expr::BuiltinBitCastExprClass:
1300 if (cast<Expr>(S)->getType()->isVariablyModifiedType())
1305 case Expr::ArraySubscriptExprClass:
1306 case Expr::MatrixSubscriptExprClass:
1307 case Expr::OMPArraySectionExprClass:
1308 case Expr::OMPArrayShapingExprClass:
1309 case Expr::OMPIteratorExprClass:
1310 case Expr::BinaryOperatorClass:
1311 case Expr::DependentCoawaitExprClass:
1312 case Expr::CompoundAssignOperatorClass:
1313 case Expr::CStyleCastExprClass:
1314 case Expr::CXXStaticCastExprClass:
1315 case Expr::CXXFunctionalCastExprClass:
1316 case Expr::ImplicitCastExprClass:
1317 case Expr::MaterializeTemporaryExprClass:
1318 case Expr::UnaryOperatorClass: {
1320 if (
auto *CE = dyn_cast<CastExpr>(S))
1321 if (CE->getType()->isVariablyModifiedType())
1328 case Expr::CXXDefaultArgExprClass:
1329 return canThrow(cast<CXXDefaultArgExpr>(S)->getExpr());
1331 case Expr::CXXDefaultInitExprClass:
1332 return canThrow(cast<CXXDefaultInitExpr>(S)->getExpr());
1334 case Expr::ChooseExprClass: {
1335 auto *CE = cast<ChooseExpr>(S);
1336 if (CE->isTypeDependent() || CE->isValueDependent())
1338 return canThrow(CE->getChosenSubExpr());
1341 case Expr::GenericSelectionExprClass:
1342 if (cast<GenericSelectionExpr>(S)->isResultDependent())
1344 return canThrow(cast<GenericSelectionExpr>(S)->getResultExpr());
1347 case Expr::CXXDependentScopeMemberExprClass:
1348 case Expr::CXXUnresolvedConstructExprClass:
1349 case Expr::DependentScopeDeclRefExprClass:
1350 case Expr::CXXFoldExprClass:
1351 case Expr::RecoveryExprClass:
1354 case Expr::AsTypeExprClass:
1355 case Expr::BinaryConditionalOperatorClass:
1356 case Expr::BlockExprClass:
1357 case Expr::CUDAKernelCallExprClass:
1358 case Expr::DeclRefExprClass:
1359 case Expr::ObjCBridgedCastExprClass:
1360 case Expr::ObjCIndirectCopyRestoreExprClass:
1361 case Expr::ObjCProtocolExprClass:
1362 case Expr::ObjCSelectorExprClass:
1363 case Expr::ObjCAvailabilityCheckExprClass:
1364 case Expr::OffsetOfExprClass:
1365 case Expr::PackExpansionExprClass:
1366 case Expr::SubstNonTypeTemplateParmExprClass:
1367 case Expr::SubstNonTypeTemplateParmPackExprClass:
1368 case Expr::FunctionParmPackExprClass:
1369 case Expr::UnaryExprOrTypeTraitExprClass:
1370 case Expr::UnresolvedLookupExprClass:
1371 case Expr::UnresolvedMemberExprClass:
1372 case Expr::TypoExprClass:
1376 case Expr::AddrLabelExprClass:
1377 case Expr::ArrayTypeTraitExprClass:
1378 case Expr::AtomicExprClass:
1379 case Expr::TypeTraitExprClass:
1380 case Expr::CXXBoolLiteralExprClass:
1381 case Expr::CXXNoexceptExprClass:
1382 case Expr::CXXNullPtrLiteralExprClass:
1383 case Expr::CXXPseudoDestructorExprClass:
1384 case Expr::CXXScalarValueInitExprClass:
1385 case Expr::CXXThisExprClass:
1386 case Expr::CXXUuidofExprClass:
1387 case Expr::CharacterLiteralClass:
1388 case Expr::ExpressionTraitExprClass:
1389 case Expr::FloatingLiteralClass:
1390 case Expr::GNUNullExprClass:
1391 case Expr::ImaginaryLiteralClass:
1392 case Expr::ImplicitValueInitExprClass:
1393 case Expr::IntegerLiteralClass:
1394 case Expr::FixedPointLiteralClass:
1395 case Expr::ArrayInitIndexExprClass:
1396 case Expr::NoInitExprClass:
1397 case Expr::ObjCEncodeExprClass:
1398 case Expr::ObjCStringLiteralClass:
1399 case Expr::ObjCBoolLiteralExprClass:
1400 case Expr::OpaqueValueExprClass:
1401 case Expr::PredefinedExprClass:
1402 case Expr::SizeOfPackExprClass:
1403 case Expr::StringLiteralClass:
1404 case Expr::SourceLocExprClass:
1405 case Expr::ConceptSpecializationExprClass:
1406 case Expr::RequiresExprClass:
1410 case Expr::MSPropertyRefExprClass:
1411 case Expr::MSPropertySubscriptExprClass:
1412 llvm_unreachable(
"Invalid class for expression");
1415 case Stmt::AttributedStmtClass:
1416 case Stmt::BreakStmtClass:
1417 case Stmt::CapturedStmtClass:
1418 case Stmt::CaseStmtClass:
1419 case Stmt::CompoundStmtClass:
1420 case Stmt::ContinueStmtClass:
1421 case Stmt::CoreturnStmtClass:
1422 case Stmt::CoroutineBodyStmtClass:
1423 case Stmt::CXXCatchStmtClass:
1424 case Stmt::CXXForRangeStmtClass:
1425 case Stmt::DefaultStmtClass:
1426 case Stmt::DoStmtClass:
1427 case Stmt::ForStmtClass:
1428 case Stmt::GCCAsmStmtClass:
1429 case Stmt::GotoStmtClass:
1430 case Stmt::IndirectGotoStmtClass:
1431 case Stmt::LabelStmtClass:
1432 case Stmt::MSAsmStmtClass:
1433 case Stmt::MSDependentExistsStmtClass:
1434 case Stmt::NullStmtClass:
1435 case Stmt::ObjCAtCatchStmtClass:
1436 case Stmt::ObjCAtFinallyStmtClass:
1437 case Stmt::ObjCAtSynchronizedStmtClass:
1438 case Stmt::ObjCAutoreleasePoolStmtClass:
1439 case Stmt::ObjCForCollectionStmtClass:
1440 case Stmt::OMPAtomicDirectiveClass:
1441 case Stmt::OMPBarrierDirectiveClass:
1442 case Stmt::OMPCancelDirectiveClass:
1443 case Stmt::OMPCancellationPointDirectiveClass:
1444 case Stmt::OMPCriticalDirectiveClass:
1445 case Stmt::OMPDistributeDirectiveClass:
1446 case Stmt::OMPDistributeParallelForDirectiveClass:
1447 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1448 case Stmt::OMPDistributeSimdDirectiveClass:
1449 case Stmt::OMPFlushDirectiveClass:
1450 case Stmt::OMPDepobjDirectiveClass:
1451 case Stmt::OMPScanDirectiveClass:
1452 case Stmt::OMPForDirectiveClass:
1453 case Stmt::OMPForSimdDirectiveClass:
1454 case Stmt::OMPMasterDirectiveClass:
1455 case Stmt::OMPMasterTaskLoopDirectiveClass:
1456 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1457 case Stmt::OMPOrderedDirectiveClass:
1458 case Stmt::OMPCanonicalLoopClass:
1459 case Stmt::OMPParallelDirectiveClass:
1460 case Stmt::OMPParallelForDirectiveClass:
1461 case Stmt::OMPParallelForSimdDirectiveClass:
1462 case Stmt::OMPParallelMasterDirectiveClass:
1463 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1464 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1465 case Stmt::OMPParallelSectionsDirectiveClass:
1466 case Stmt::OMPSectionDirectiveClass:
1467 case Stmt::OMPSectionsDirectiveClass:
1468 case Stmt::OMPSimdDirectiveClass:
1469 case Stmt::OMPTileDirectiveClass:
1470 case Stmt::OMPUnrollDirectiveClass:
1471 case Stmt::OMPSingleDirectiveClass:
1472 case Stmt::OMPTargetDataDirectiveClass:
1473 case Stmt::OMPTargetDirectiveClass:
1474 case Stmt::OMPTargetEnterDataDirectiveClass:
1475 case Stmt::OMPTargetExitDataDirectiveClass:
1476 case Stmt::OMPTargetParallelDirectiveClass:
1477 case Stmt::OMPTargetParallelForDirectiveClass:
1478 case Stmt::OMPTargetParallelForSimdDirectiveClass:
1479 case Stmt::OMPTargetSimdDirectiveClass:
1480 case Stmt::OMPTargetTeamsDirectiveClass:
1481 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1482 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1483 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1484 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1485 case Stmt::OMPTargetUpdateDirectiveClass:
1486 case Stmt::OMPTaskDirectiveClass:
1487 case Stmt::OMPTaskgroupDirectiveClass:
1488 case Stmt::OMPTaskLoopDirectiveClass:
1489 case Stmt::OMPTaskLoopSimdDirectiveClass:
1490 case Stmt::OMPTaskwaitDirectiveClass:
1491 case Stmt::OMPTaskyieldDirectiveClass:
1492 case Stmt::OMPTeamsDirectiveClass:
1493 case Stmt::OMPTeamsDistributeDirectiveClass:
1494 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1495 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1496 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1497 case Stmt::OMPInteropDirectiveClass:
1498 case Stmt::OMPDispatchDirectiveClass:
1499 case Stmt::OMPMaskedDirectiveClass:
1500 case Stmt::OMPMetaDirectiveClass:
1501 case Stmt::OMPGenericLoopDirectiveClass:
1502 case Stmt::OMPTeamsGenericLoopDirectiveClass:
1503 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
1504 case Stmt::OMPParallelGenericLoopDirectiveClass:
1505 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
1506 case Stmt::ReturnStmtClass:
1507 case Stmt::SEHExceptStmtClass:
1508 case Stmt::SEHFinallyStmtClass:
1509 case Stmt::SEHLeaveStmtClass:
1510 case Stmt::SEHTryStmtClass:
1511 case Stmt::SwitchStmtClass:
1512 case Stmt::WhileStmtClass:
1515 case Stmt::DeclStmtClass: {
1517 for (
const Decl *D : cast<DeclStmt>(S)->decls()) {
1518 if (
auto *VD = dyn_cast<VarDecl>(D))
1522 if (
auto *TND = dyn_cast<TypedefNameDecl>(D))
1523 if (TND->getUnderlyingType()->isVariablyModifiedType())
1525 if (
auto *VD = dyn_cast<ValueDecl>(D))
1526 if (VD->getType()->isVariablyModifiedType())
1532 case Stmt::IfStmtClass: {
1533 auto *IS = cast<IfStmt>(S);
1535 if (
const Stmt *Init = IS->getInit())
1537 if (
const Stmt *CondDS = IS->getConditionVariableDeclStmt())
1557 case Stmt::CXXTryStmtClass: {
1558 auto *TS = cast<CXXTryStmt>(S);
1561 const CXXCatchStmt *FinalHandler = TS->getHandler(TS->getNumHandlers() - 1);
1567 case Stmt::ObjCAtThrowStmtClass:
1570 case Stmt::ObjCAtTryStmtClass: {
1571 auto *TS = cast<ObjCAtTryStmt>(S);
1576 if (
const Stmt *Finally = TS->getFinallyStmt())
1578 for (
unsigned I = TS->getNumCatchStmts(); I != 0; --I) {
1590 case Stmt::SYCLUniqueStableNameExprClass:
1593 llvm_unreachable(
"Invalid class for statement");
1595 llvm_unreachable(
"Bogus StmtClass");