1 //===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file provides Sema routines for C++ exception specification testing. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/Sema/SemaInternal.h" 14 #include "clang/AST/ASTMutationListener.h" 15 #include "clang/AST/CXXInheritance.h" 16 #include "clang/AST/Expr.h" 17 #include "clang/AST/ExprCXX.h" 18 #include "clang/AST/StmtObjC.h" 19 #include "clang/AST/TypeLoc.h" 20 #include "clang/Basic/Diagnostic.h" 21 #include "clang/Basic/SourceManager.h" 22 #include "llvm/ADT/SmallPtrSet.h" 23 #include "llvm/ADT/SmallString.h" 24 25 namespace clang { 26 27 static const FunctionProtoType *GetUnderlyingFunction(QualType T) 28 { 29 if (const PointerType *PtrTy = T->getAs<PointerType>()) 30 T = PtrTy->getPointeeType(); 31 else if (const ReferenceType *RefTy = T->getAs<ReferenceType>()) 32 T = RefTy->getPointeeType(); 33 else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) 34 T = MPTy->getPointeeType(); 35 return T->getAs<FunctionProtoType>(); 36 } 37 38 /// HACK: libstdc++ has a bug where it shadows std::swap with a member 39 /// swap function then tries to call std::swap unqualified from the exception 40 /// specification of that function. This function detects whether we're in 41 /// such a case and turns off delay-parsing of exception specifications. 42 bool Sema::isLibstdcxxEagerExceptionSpecHack(const Declarator &D) { 43 auto *RD = dyn_cast<CXXRecordDecl>(CurContext); 44 45 // All the problem cases are member functions named "swap" within class 46 // templates declared directly within namespace std or std::__debug or 47 // std::__profile. 48 if (!RD || !RD->getIdentifier() || !RD->getDescribedClassTemplate() || 49 !D.getIdentifier() || !D.getIdentifier()->isStr("swap")) 50 return false; 51 52 auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext()); 53 if (!ND) 54 return false; 55 56 bool IsInStd = ND->isStdNamespace(); 57 if (!IsInStd) { 58 // This isn't a direct member of namespace std, but it might still be 59 // libstdc++'s std::__debug::array or std::__profile::array. 60 IdentifierInfo *II = ND->getIdentifier(); 61 if (!II || !(II->isStr("__debug") || II->isStr("__profile")) || 62 !ND->isInStdNamespace()) 63 return false; 64 } 65 66 // Only apply this hack within a system header. 67 if (!Context.getSourceManager().isInSystemHeader(D.getBeginLoc())) 68 return false; 69 70 return llvm::StringSwitch<bool>(RD->getIdentifier()->getName()) 71 .Case("array", true) 72 .Case("pair", IsInStd) 73 .Case("priority_queue", IsInStd) 74 .Case("stack", IsInStd) 75 .Case("queue", IsInStd) 76 .Default(false); 77 } 78 79 ExprResult Sema::ActOnNoexceptSpec(SourceLocation NoexceptLoc, 80 Expr *NoexceptExpr, 81 ExceptionSpecificationType &EST) { 82 // FIXME: This is bogus, a noexcept expression is not a condition. 83 ExprResult Converted = CheckBooleanCondition(NoexceptLoc, NoexceptExpr); 84 if (Converted.isInvalid()) 85 return Converted; 86 87 if (Converted.get()->isValueDependent()) { 88 EST = EST_DependentNoexcept; 89 return Converted; 90 } 91 92 llvm::APSInt Result; 93 Converted = VerifyIntegerConstantExpression( 94 Converted.get(), &Result, 95 diag::err_noexcept_needs_constant_expression, 96 /*AllowFold*/ false); 97 if (!Converted.isInvalid()) 98 EST = !Result ? EST_NoexceptFalse : EST_NoexceptTrue; 99 return Converted; 100 } 101 102 /// CheckSpecifiedExceptionType - Check if the given type is valid in an 103 /// exception specification. Incomplete types, or pointers to incomplete types 104 /// other than void are not allowed. 105 /// 106 /// \param[in,out] T The exception type. This will be decayed to a pointer type 107 /// when the input is an array or a function type. 108 bool Sema::CheckSpecifiedExceptionType(QualType &T, SourceRange Range) { 109 // C++11 [except.spec]p2: 110 // A type cv T, "array of T", or "function returning T" denoted 111 // in an exception-specification is adjusted to type T, "pointer to T", or 112 // "pointer to function returning T", respectively. 113 // 114 // We also apply this rule in C++98. 115 if (T->isArrayType()) 116 T = Context.getArrayDecayedType(T); 117 else if (T->isFunctionType()) 118 T = Context.getPointerType(T); 119 120 int Kind = 0; 121 QualType PointeeT = T; 122 if (const PointerType *PT = T->getAs<PointerType>()) { 123 PointeeT = PT->getPointeeType(); 124 Kind = 1; 125 126 // cv void* is explicitly permitted, despite being a pointer to an 127 // incomplete type. 128 if (PointeeT->isVoidType()) 129 return false; 130 } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) { 131 PointeeT = RT->getPointeeType(); 132 Kind = 2; 133 134 if (RT->isRValueReferenceType()) { 135 // C++11 [except.spec]p2: 136 // A type denoted in an exception-specification shall not denote [...] 137 // an rvalue reference type. 138 Diag(Range.getBegin(), diag::err_rref_in_exception_spec) 139 << T << Range; 140 return true; 141 } 142 } 143 144 // C++11 [except.spec]p2: 145 // A type denoted in an exception-specification shall not denote an 146 // incomplete type other than a class currently being defined [...]. 147 // A type denoted in an exception-specification shall not denote a 148 // pointer or reference to an incomplete type, other than (cv) void* or a 149 // pointer or reference to a class currently being defined. 150 // In Microsoft mode, downgrade this to a warning. 151 unsigned DiagID = diag::err_incomplete_in_exception_spec; 152 bool ReturnValueOnError = true; 153 if (getLangOpts().MSVCCompat) { 154 DiagID = diag::ext_incomplete_in_exception_spec; 155 ReturnValueOnError = false; 156 } 157 if (!(PointeeT->isRecordType() && 158 PointeeT->castAs<RecordType>()->isBeingDefined()) && 159 RequireCompleteType(Range.getBegin(), PointeeT, DiagID, Kind, Range)) 160 return ReturnValueOnError; 161 162 return false; 163 } 164 165 /// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer 166 /// to member to a function with an exception specification. This means that 167 /// it is invalid to add another level of indirection. 168 bool Sema::CheckDistantExceptionSpec(QualType T) { 169 // C++17 removes this rule in favor of putting exception specifications into 170 // the type system. 171 if (getLangOpts().CPlusPlus17) 172 return false; 173 174 if (const PointerType *PT = T->getAs<PointerType>()) 175 T = PT->getPointeeType(); 176 else if (const MemberPointerType *PT = T->getAs<MemberPointerType>()) 177 T = PT->getPointeeType(); 178 else 179 return false; 180 181 const FunctionProtoType *FnT = T->getAs<FunctionProtoType>(); 182 if (!FnT) 183 return false; 184 185 return FnT->hasExceptionSpec(); 186 } 187 188 const FunctionProtoType * 189 Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) { 190 if (FPT->getExceptionSpecType() == EST_Unparsed) { 191 Diag(Loc, diag::err_exception_spec_not_parsed); 192 return nullptr; 193 } 194 195 if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) 196 return FPT; 197 198 FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl(); 199 const FunctionProtoType *SourceFPT = 200 SourceDecl->getType()->castAs<FunctionProtoType>(); 201 202 // If the exception specification has already been resolved, just return it. 203 if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType())) 204 return SourceFPT; 205 206 // Compute or instantiate the exception specification now. 207 if (SourceFPT->getExceptionSpecType() == EST_Unevaluated) 208 EvaluateImplicitExceptionSpec(Loc, SourceDecl); 209 else 210 InstantiateExceptionSpec(Loc, SourceDecl); 211 212 const FunctionProtoType *Proto = 213 SourceDecl->getType()->castAs<FunctionProtoType>(); 214 if (Proto->getExceptionSpecType() == clang::EST_Unparsed) { 215 Diag(Loc, diag::err_exception_spec_not_parsed); 216 Proto = nullptr; 217 } 218 return Proto; 219 } 220 221 void 222 Sema::UpdateExceptionSpec(FunctionDecl *FD, 223 const FunctionProtoType::ExceptionSpecInfo &ESI) { 224 // If we've fully resolved the exception specification, notify listeners. 225 if (!isUnresolvedExceptionSpec(ESI.Type)) 226 if (auto *Listener = getASTMutationListener()) 227 Listener->ResolvedExceptionSpec(FD); 228 229 for (FunctionDecl *Redecl : FD->redecls()) 230 Context.adjustExceptionSpec(Redecl, ESI); 231 } 232 233 static bool exceptionSpecNotKnownYet(const FunctionDecl *FD) { 234 auto *MD = dyn_cast<CXXMethodDecl>(FD); 235 if (!MD) 236 return false; 237 238 auto EST = MD->getType()->castAs<FunctionProtoType>()->getExceptionSpecType(); 239 return EST == EST_Unparsed || 240 (EST == EST_Unevaluated && MD->getParent()->isBeingDefined()); 241 } 242 243 static bool CheckEquivalentExceptionSpecImpl( 244 Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, 245 const FunctionProtoType *Old, SourceLocation OldLoc, 246 const FunctionProtoType *New, SourceLocation NewLoc, 247 bool *MissingExceptionSpecification = nullptr, 248 bool *MissingEmptyExceptionSpecification = nullptr, 249 bool AllowNoexceptAllMatchWithNoSpec = false, bool IsOperatorNew = false); 250 251 /// Determine whether a function has an implicitly-generated exception 252 /// specification. 253 static bool hasImplicitExceptionSpec(FunctionDecl *Decl) { 254 if (!isa<CXXDestructorDecl>(Decl) && 255 Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete && 256 Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) 257 return false; 258 259 // For a function that the user didn't declare: 260 // - if this is a destructor, its exception specification is implicit. 261 // - if this is 'operator delete' or 'operator delete[]', the exception 262 // specification is as-if an explicit exception specification was given 263 // (per [basic.stc.dynamic]p2). 264 if (!Decl->getTypeSourceInfo()) 265 return isa<CXXDestructorDecl>(Decl); 266 267 auto *Ty = Decl->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>(); 268 return !Ty->hasExceptionSpec(); 269 } 270 271 bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { 272 // Just completely ignore this under -fno-exceptions prior to C++17. 273 // In C++17 onwards, the exception specification is part of the type and 274 // we will diagnose mismatches anyway, so it's better to check for them here. 275 if (!getLangOpts().CXXExceptions && !getLangOpts().CPlusPlus17) 276 return false; 277 278 OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator(); 279 bool IsOperatorNew = OO == OO_New || OO == OO_Array_New; 280 bool MissingExceptionSpecification = false; 281 bool MissingEmptyExceptionSpecification = false; 282 283 unsigned DiagID = diag::err_mismatched_exception_spec; 284 bool ReturnValueOnError = true; 285 if (getLangOpts().MSVCCompat) { 286 DiagID = diag::ext_mismatched_exception_spec; 287 ReturnValueOnError = false; 288 } 289 290 // If we're befriending a member function of a class that's currently being 291 // defined, we might not be able to work out its exception specification yet. 292 // If not, defer the check until later. 293 if (exceptionSpecNotKnownYet(Old) || exceptionSpecNotKnownYet(New)) { 294 DelayedEquivalentExceptionSpecChecks.push_back({New, Old}); 295 return false; 296 } 297 298 // Check the types as written: they must match before any exception 299 // specification adjustment is applied. 300 if (!CheckEquivalentExceptionSpecImpl( 301 *this, PDiag(DiagID), PDiag(diag::note_previous_declaration), 302 Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(), 303 New->getType()->getAs<FunctionProtoType>(), New->getLocation(), 304 &MissingExceptionSpecification, &MissingEmptyExceptionSpecification, 305 /*AllowNoexceptAllMatchWithNoSpec=*/true, IsOperatorNew)) { 306 // C++11 [except.spec]p4 [DR1492]: 307 // If a declaration of a function has an implicit 308 // exception-specification, other declarations of the function shall 309 // not specify an exception-specification. 310 if (getLangOpts().CPlusPlus11 && getLangOpts().CXXExceptions && 311 hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) { 312 Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch) 313 << hasImplicitExceptionSpec(Old); 314 if (Old->getLocation().isValid()) 315 Diag(Old->getLocation(), diag::note_previous_declaration); 316 } 317 return false; 318 } 319 320 // The failure was something other than an missing exception 321 // specification; return an error, except in MS mode where this is a warning. 322 if (!MissingExceptionSpecification) 323 return ReturnValueOnError; 324 325 const FunctionProtoType *NewProto = 326 New->getType()->castAs<FunctionProtoType>(); 327 328 // The new function declaration is only missing an empty exception 329 // specification "throw()". If the throw() specification came from a 330 // function in a system header that has C linkage, just add an empty 331 // exception specification to the "new" declaration. Note that C library 332 // implementations are permitted to add these nothrow exception 333 // specifications. 334 // 335 // Likewise if the old function is a builtin. 336 if (MissingEmptyExceptionSpecification && NewProto && 337 (Old->getLocation().isInvalid() || 338 Context.getSourceManager().isInSystemHeader(Old->getLocation()) || 339 Old->getBuiltinID()) && 340 Old->isExternC()) { 341 New->setType(Context.getFunctionType( 342 NewProto->getReturnType(), NewProto->getParamTypes(), 343 NewProto->getExtProtoInfo().withExceptionSpec(EST_DynamicNone))); 344 return false; 345 } 346 347 const FunctionProtoType *OldProto = 348 Old->getType()->castAs<FunctionProtoType>(); 349 350 FunctionProtoType::ExceptionSpecInfo ESI = OldProto->getExceptionSpecType(); 351 if (ESI.Type == EST_Dynamic) { 352 // FIXME: What if the exceptions are described in terms of the old 353 // prototype's parameters? 354 ESI.Exceptions = OldProto->exceptions(); 355 } 356 357 if (ESI.Type == EST_NoexceptFalse) 358 ESI.Type = EST_None; 359 if (ESI.Type == EST_NoexceptTrue) 360 ESI.Type = EST_BasicNoexcept; 361 362 // For dependent noexcept, we can't just take the expression from the old 363 // prototype. It likely contains references to the old prototype's parameters. 364 if (ESI.Type == EST_DependentNoexcept) { 365 New->setInvalidDecl(); 366 } else { 367 // Update the type of the function with the appropriate exception 368 // specification. 369 New->setType(Context.getFunctionType( 370 NewProto->getReturnType(), NewProto->getParamTypes(), 371 NewProto->getExtProtoInfo().withExceptionSpec(ESI))); 372 } 373 374 if (getLangOpts().MSVCCompat && ESI.Type != EST_DependentNoexcept) { 375 // Allow missing exception specifications in redeclarations as an extension. 376 DiagID = diag::ext_ms_missing_exception_specification; 377 ReturnValueOnError = false; 378 } else if (New->isReplaceableGlobalAllocationFunction() && 379 ESI.Type != EST_DependentNoexcept) { 380 // Allow missing exception specifications in redeclarations as an extension, 381 // when declaring a replaceable global allocation function. 382 DiagID = diag::ext_missing_exception_specification; 383 ReturnValueOnError = false; 384 } else if (ESI.Type == EST_NoThrow) { 385 // Allow missing attribute 'nothrow' in redeclarations, since this is a very 386 // common omission. 387 DiagID = diag::ext_missing_exception_specification; 388 ReturnValueOnError = false; 389 } else { 390 DiagID = diag::err_missing_exception_specification; 391 ReturnValueOnError = true; 392 } 393 394 // Warn about the lack of exception specification. 395 SmallString<128> ExceptionSpecString; 396 llvm::raw_svector_ostream OS(ExceptionSpecString); 397 switch (OldProto->getExceptionSpecType()) { 398 case EST_DynamicNone: 399 OS << "throw()"; 400 break; 401 402 case EST_Dynamic: { 403 OS << "throw("; 404 bool OnFirstException = true; 405 for (const auto &E : OldProto->exceptions()) { 406 if (OnFirstException) 407 OnFirstException = false; 408 else 409 OS << ", "; 410 411 OS << E.getAsString(getPrintingPolicy()); 412 } 413 OS << ")"; 414 break; 415 } 416 417 case EST_BasicNoexcept: 418 OS << "noexcept"; 419 break; 420 421 case EST_DependentNoexcept: 422 case EST_NoexceptFalse: 423 case EST_NoexceptTrue: 424 OS << "noexcept("; 425 assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr"); 426 OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy()); 427 OS << ")"; 428 break; 429 case EST_NoThrow: 430 OS <<"__attribute__((nothrow))"; 431 break; 432 case EST_None: 433 case EST_MSAny: 434 case EST_Unevaluated: 435 case EST_Uninstantiated: 436 case EST_Unparsed: 437 llvm_unreachable("This spec type is compatible with none."); 438 } 439 440 SourceLocation FixItLoc; 441 if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) { 442 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); 443 // FIXME: Preserve enough information so that we can produce a correct fixit 444 // location when there is a trailing return type. 445 if (auto FTLoc = TL.getAs<FunctionProtoTypeLoc>()) 446 if (!FTLoc.getTypePtr()->hasTrailingReturn()) 447 FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd()); 448 } 449 450 if (FixItLoc.isInvalid()) 451 Diag(New->getLocation(), DiagID) 452 << New << OS.str(); 453 else { 454 Diag(New->getLocation(), DiagID) 455 << New << OS.str() 456 << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str()); 457 } 458 459 if (Old->getLocation().isValid()) 460 Diag(Old->getLocation(), diag::note_previous_declaration); 461 462 return ReturnValueOnError; 463 } 464 465 /// CheckEquivalentExceptionSpec - Check if the two types have equivalent 466 /// exception specifications. Exception specifications are equivalent if 467 /// they allow exactly the same set of exception types. It does not matter how 468 /// that is achieved. See C++ [except.spec]p2. 469 bool Sema::CheckEquivalentExceptionSpec( 470 const FunctionProtoType *Old, SourceLocation OldLoc, 471 const FunctionProtoType *New, SourceLocation NewLoc) { 472 if (!getLangOpts().CXXExceptions) 473 return false; 474 475 unsigned DiagID = diag::err_mismatched_exception_spec; 476 if (getLangOpts().MSVCCompat) 477 DiagID = diag::ext_mismatched_exception_spec; 478 bool Result = CheckEquivalentExceptionSpecImpl( 479 *this, PDiag(DiagID), PDiag(diag::note_previous_declaration), 480 Old, OldLoc, New, NewLoc); 481 482 // In Microsoft mode, mismatching exception specifications just cause a warning. 483 if (getLangOpts().MSVCCompat) 484 return false; 485 return Result; 486 } 487 488 /// CheckEquivalentExceptionSpec - Check if the two types have compatible 489 /// exception specifications. See C++ [except.spec]p3. 490 /// 491 /// \return \c false if the exception specifications match, \c true if there is 492 /// a problem. If \c true is returned, either a diagnostic has already been 493 /// produced or \c *MissingExceptionSpecification is set to \c true. 494 static bool CheckEquivalentExceptionSpecImpl( 495 Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, 496 const FunctionProtoType *Old, SourceLocation OldLoc, 497 const FunctionProtoType *New, SourceLocation NewLoc, 498 bool *MissingExceptionSpecification, 499 bool *MissingEmptyExceptionSpecification, 500 bool AllowNoexceptAllMatchWithNoSpec, bool IsOperatorNew) { 501 if (MissingExceptionSpecification) 502 *MissingExceptionSpecification = false; 503 504 if (MissingEmptyExceptionSpecification) 505 *MissingEmptyExceptionSpecification = false; 506 507 Old = S.ResolveExceptionSpec(NewLoc, Old); 508 if (!Old) 509 return false; 510 New = S.ResolveExceptionSpec(NewLoc, New); 511 if (!New) 512 return false; 513 514 // C++0x [except.spec]p3: Two exception-specifications are compatible if: 515 // - both are non-throwing, regardless of their form, 516 // - both have the form noexcept(constant-expression) and the constant- 517 // expressions are equivalent, 518 // - both are dynamic-exception-specifications that have the same set of 519 // adjusted types. 520 // 521 // C++0x [except.spec]p12: An exception-specification is non-throwing if it is 522 // of the form throw(), noexcept, or noexcept(constant-expression) where the 523 // constant-expression yields true. 524 // 525 // C++0x [except.spec]p4: If any declaration of a function has an exception- 526 // specifier that is not a noexcept-specification allowing all exceptions, 527 // all declarations [...] of that function shall have a compatible 528 // exception-specification. 529 // 530 // That last point basically means that noexcept(false) matches no spec. 531 // It's considered when AllowNoexceptAllMatchWithNoSpec is true. 532 533 ExceptionSpecificationType OldEST = Old->getExceptionSpecType(); 534 ExceptionSpecificationType NewEST = New->getExceptionSpecType(); 535 536 assert(!isUnresolvedExceptionSpec(OldEST) && 537 !isUnresolvedExceptionSpec(NewEST) && 538 "Shouldn't see unknown exception specifications here"); 539 540 CanThrowResult OldCanThrow = Old->canThrow(); 541 CanThrowResult NewCanThrow = New->canThrow(); 542 543 // Any non-throwing specifications are compatible. 544 if (OldCanThrow == CT_Cannot && NewCanThrow == CT_Cannot) 545 return false; 546 547 // Any throws-anything specifications are usually compatible. 548 if (OldCanThrow == CT_Can && OldEST != EST_Dynamic && 549 NewCanThrow == CT_Can && NewEST != EST_Dynamic) { 550 // The exception is that the absence of an exception specification only 551 // matches noexcept(false) for functions, as described above. 552 if (!AllowNoexceptAllMatchWithNoSpec && 553 ((OldEST == EST_None && NewEST == EST_NoexceptFalse) || 554 (OldEST == EST_NoexceptFalse && NewEST == EST_None))) { 555 // This is the disallowed case. 556 } else { 557 return false; 558 } 559 } 560 561 // C++14 [except.spec]p3: 562 // Two exception-specifications are compatible if [...] both have the form 563 // noexcept(constant-expression) and the constant-expressions are equivalent 564 if (OldEST == EST_DependentNoexcept && NewEST == EST_DependentNoexcept) { 565 llvm::FoldingSetNodeID OldFSN, NewFSN; 566 Old->getNoexceptExpr()->Profile(OldFSN, S.Context, true); 567 New->getNoexceptExpr()->Profile(NewFSN, S.Context, true); 568 if (OldFSN == NewFSN) 569 return false; 570 } 571 572 // Dynamic exception specifications with the same set of adjusted types 573 // are compatible. 574 if (OldEST == EST_Dynamic && NewEST == EST_Dynamic) { 575 bool Success = true; 576 // Both have a dynamic exception spec. Collect the first set, then compare 577 // to the second. 578 llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes; 579 for (const auto &I : Old->exceptions()) 580 OldTypes.insert(S.Context.getCanonicalType(I).getUnqualifiedType()); 581 582 for (const auto &I : New->exceptions()) { 583 CanQualType TypePtr = S.Context.getCanonicalType(I).getUnqualifiedType(); 584 if (OldTypes.count(TypePtr)) 585 NewTypes.insert(TypePtr); 586 else { 587 Success = false; 588 break; 589 } 590 } 591 592 if (Success && OldTypes.size() == NewTypes.size()) 593 return false; 594 } 595 596 // As a special compatibility feature, under C++0x we accept no spec and 597 // throw(std::bad_alloc) as equivalent for operator new and operator new[]. 598 // This is because the implicit declaration changed, but old code would break. 599 if (S.getLangOpts().CPlusPlus11 && IsOperatorNew) { 600 const FunctionProtoType *WithExceptions = nullptr; 601 if (OldEST == EST_None && NewEST == EST_Dynamic) 602 WithExceptions = New; 603 else if (OldEST == EST_Dynamic && NewEST == EST_None) 604 WithExceptions = Old; 605 if (WithExceptions && WithExceptions->getNumExceptions() == 1) { 606 // One has no spec, the other throw(something). If that something is 607 // std::bad_alloc, all conditions are met. 608 QualType Exception = *WithExceptions->exception_begin(); 609 if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) { 610 IdentifierInfo* Name = ExRecord->getIdentifier(); 611 if (Name && Name->getName() == "bad_alloc") { 612 // It's called bad_alloc, but is it in std? 613 if (ExRecord->isInStdNamespace()) { 614 return false; 615 } 616 } 617 } 618 } 619 } 620 621 // If the caller wants to handle the case that the new function is 622 // incompatible due to a missing exception specification, let it. 623 if (MissingExceptionSpecification && OldEST != EST_None && 624 NewEST == EST_None) { 625 // The old type has an exception specification of some sort, but 626 // the new type does not. 627 *MissingExceptionSpecification = true; 628 629 if (MissingEmptyExceptionSpecification && OldCanThrow == CT_Cannot) { 630 // The old type has a throw() or noexcept(true) exception specification 631 // and the new type has no exception specification, and the caller asked 632 // to handle this itself. 633 *MissingEmptyExceptionSpecification = true; 634 } 635 636 return true; 637 } 638 639 S.Diag(NewLoc, DiagID); 640 if (NoteID.getDiagID() != 0 && OldLoc.isValid()) 641 S.Diag(OldLoc, NoteID); 642 return true; 643 } 644 645 bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, 646 const PartialDiagnostic &NoteID, 647 const FunctionProtoType *Old, 648 SourceLocation OldLoc, 649 const FunctionProtoType *New, 650 SourceLocation NewLoc) { 651 if (!getLangOpts().CXXExceptions) 652 return false; 653 return CheckEquivalentExceptionSpecImpl(*this, DiagID, NoteID, Old, OldLoc, 654 New, NewLoc); 655 } 656 657 bool Sema::handlerCanCatch(QualType HandlerType, QualType ExceptionType) { 658 // [except.handle]p3: 659 // A handler is a match for an exception object of type E if: 660 661 // HandlerType must be ExceptionType or derived from it, or pointer or 662 // reference to such types. 663 const ReferenceType *RefTy = HandlerType->getAs<ReferenceType>(); 664 if (RefTy) 665 HandlerType = RefTy->getPointeeType(); 666 667 // -- the handler is of type cv T or cv T& and E and T are the same type 668 if (Context.hasSameUnqualifiedType(ExceptionType, HandlerType)) 669 return true; 670 671 // FIXME: ObjC pointer types? 672 if (HandlerType->isPointerType() || HandlerType->isMemberPointerType()) { 673 if (RefTy && (!HandlerType.isConstQualified() || 674 HandlerType.isVolatileQualified())) 675 return false; 676 677 // -- the handler is of type cv T or const T& where T is a pointer or 678 // pointer to member type and E is std::nullptr_t 679 if (ExceptionType->isNullPtrType()) 680 return true; 681 682 // -- the handler is of type cv T or const T& where T is a pointer or 683 // pointer to member type and E is a pointer or pointer to member type 684 // that can be converted to T by one or more of 685 // -- a qualification conversion 686 // -- a function pointer conversion 687 bool LifetimeConv; 688 QualType Result; 689 // FIXME: Should we treat the exception as catchable if a lifetime 690 // conversion is required? 691 if (IsQualificationConversion(ExceptionType, HandlerType, false, 692 LifetimeConv) || 693 IsFunctionConversion(ExceptionType, HandlerType, Result)) 694 return true; 695 696 // -- a standard pointer conversion [...] 697 if (!ExceptionType->isPointerType() || !HandlerType->isPointerType()) 698 return false; 699 700 // Handle the "qualification conversion" portion. 701 Qualifiers EQuals, HQuals; 702 ExceptionType = Context.getUnqualifiedArrayType( 703 ExceptionType->getPointeeType(), EQuals); 704 HandlerType = Context.getUnqualifiedArrayType( 705 HandlerType->getPointeeType(), HQuals); 706 if (!HQuals.compatiblyIncludes(EQuals)) 707 return false; 708 709 if (HandlerType->isVoidType() && ExceptionType->isObjectType()) 710 return true; 711 712 // The only remaining case is a derived-to-base conversion. 713 } 714 715 // -- the handler is of type cg T or cv T& and T is an unambiguous public 716 // base class of E 717 if (!ExceptionType->isRecordType() || !HandlerType->isRecordType()) 718 return false; 719 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 720 /*DetectVirtual=*/false); 721 if (!IsDerivedFrom(SourceLocation(), ExceptionType, HandlerType, Paths) || 722 Paths.isAmbiguous(Context.getCanonicalType(HandlerType))) 723 return false; 724 725 // Do this check from a context without privileges. 726 switch (CheckBaseClassAccess(SourceLocation(), HandlerType, ExceptionType, 727 Paths.front(), 728 /*Diagnostic*/ 0, 729 /*ForceCheck*/ true, 730 /*ForceUnprivileged*/ true)) { 731 case AR_accessible: return true; 732 case AR_inaccessible: return false; 733 case AR_dependent: 734 llvm_unreachable("access check dependent for unprivileged context"); 735 case AR_delayed: 736 llvm_unreachable("access check delayed in non-declaration"); 737 } 738 llvm_unreachable("unexpected access check result"); 739 } 740 741 /// CheckExceptionSpecSubset - Check whether the second function type's 742 /// exception specification is a subset (or equivalent) of the first function 743 /// type. This is used by override and pointer assignment checks. 744 bool Sema::CheckExceptionSpecSubset(const PartialDiagnostic &DiagID, 745 const PartialDiagnostic &NestedDiagID, 746 const PartialDiagnostic &NoteID, 747 const PartialDiagnostic &NoThrowDiagID, 748 const FunctionProtoType *Superset, 749 SourceLocation SuperLoc, 750 const FunctionProtoType *Subset, 751 SourceLocation SubLoc) { 752 753 // Just auto-succeed under -fno-exceptions. 754 if (!getLangOpts().CXXExceptions) 755 return false; 756 757 // FIXME: As usual, we could be more specific in our error messages, but 758 // that better waits until we've got types with source locations. 759 760 if (!SubLoc.isValid()) 761 SubLoc = SuperLoc; 762 763 // Resolve the exception specifications, if needed. 764 Superset = ResolveExceptionSpec(SuperLoc, Superset); 765 if (!Superset) 766 return false; 767 Subset = ResolveExceptionSpec(SubLoc, Subset); 768 if (!Subset) 769 return false; 770 771 ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType(); 772 ExceptionSpecificationType SubEST = Subset->getExceptionSpecType(); 773 assert(!isUnresolvedExceptionSpec(SuperEST) && 774 !isUnresolvedExceptionSpec(SubEST) && 775 "Shouldn't see unknown exception specifications here"); 776 777 // If there are dependent noexcept specs, assume everything is fine. Unlike 778 // with the equivalency check, this is safe in this case, because we don't 779 // want to merge declarations. Checks after instantiation will catch any 780 // omissions we make here. 781 if (SuperEST == EST_DependentNoexcept || SubEST == EST_DependentNoexcept) 782 return false; 783 784 CanThrowResult SuperCanThrow = Superset->canThrow(); 785 CanThrowResult SubCanThrow = Subset->canThrow(); 786 787 // If the superset contains everything or the subset contains nothing, we're 788 // done. 789 if ((SuperCanThrow == CT_Can && SuperEST != EST_Dynamic) || 790 SubCanThrow == CT_Cannot) 791 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc, 792 Subset, SubLoc); 793 794 // Allow __declspec(nothrow) to be missing on redeclaration as an extension in 795 // some cases. 796 if (NoThrowDiagID.getDiagID() != 0 && SubCanThrow == CT_Can && 797 SuperCanThrow == CT_Cannot && SuperEST == EST_NoThrow) { 798 Diag(SubLoc, NoThrowDiagID); 799 if (NoteID.getDiagID() != 0) 800 Diag(SuperLoc, NoteID); 801 return true; 802 } 803 804 // If the subset contains everything or the superset contains nothing, we've 805 // failed. 806 if ((SubCanThrow == CT_Can && SubEST != EST_Dynamic) || 807 SuperCanThrow == CT_Cannot) { 808 Diag(SubLoc, DiagID); 809 if (NoteID.getDiagID() != 0) 810 Diag(SuperLoc, NoteID); 811 return true; 812 } 813 814 assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic && 815 "Exception spec subset: non-dynamic case slipped through."); 816 817 // Neither contains everything or nothing. Do a proper comparison. 818 for (QualType SubI : Subset->exceptions()) { 819 if (const ReferenceType *RefTy = SubI->getAs<ReferenceType>()) 820 SubI = RefTy->getPointeeType(); 821 822 // Make sure it's in the superset. 823 bool Contained = false; 824 for (QualType SuperI : Superset->exceptions()) { 825 // [except.spec]p5: 826 // the target entity shall allow at least the exceptions allowed by the 827 // source 828 // 829 // We interpret this as meaning that a handler for some target type would 830 // catch an exception of each source type. 831 if (handlerCanCatch(SuperI, SubI)) { 832 Contained = true; 833 break; 834 } 835 } 836 if (!Contained) { 837 Diag(SubLoc, DiagID); 838 if (NoteID.getDiagID() != 0) 839 Diag(SuperLoc, NoteID); 840 return true; 841 } 842 } 843 // We've run half the gauntlet. 844 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc, 845 Subset, SubLoc); 846 } 847 848 static bool 849 CheckSpecForTypesEquivalent(Sema &S, const PartialDiagnostic &DiagID, 850 const PartialDiagnostic &NoteID, QualType Target, 851 SourceLocation TargetLoc, QualType Source, 852 SourceLocation SourceLoc) { 853 const FunctionProtoType *TFunc = GetUnderlyingFunction(Target); 854 if (!TFunc) 855 return false; 856 const FunctionProtoType *SFunc = GetUnderlyingFunction(Source); 857 if (!SFunc) 858 return false; 859 860 return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc, 861 SFunc, SourceLoc); 862 } 863 864 /// CheckParamExceptionSpec - Check if the parameter and return types of the 865 /// two functions have equivalent exception specs. This is part of the 866 /// assignment and override compatibility check. We do not check the parameters 867 /// of parameter function pointers recursively, as no sane programmer would 868 /// even be able to write such a function type. 869 bool Sema::CheckParamExceptionSpec(const PartialDiagnostic &DiagID, 870 const PartialDiagnostic &NoteID, 871 const FunctionProtoType *Target, 872 SourceLocation TargetLoc, 873 const FunctionProtoType *Source, 874 SourceLocation SourceLoc) { 875 auto RetDiag = DiagID; 876 RetDiag << 0; 877 if (CheckSpecForTypesEquivalent( 878 *this, RetDiag, PDiag(), 879 Target->getReturnType(), TargetLoc, Source->getReturnType(), 880 SourceLoc)) 881 return true; 882 883 // We shouldn't even be testing this unless the arguments are otherwise 884 // compatible. 885 assert(Target->getNumParams() == Source->getNumParams() && 886 "Functions have different argument counts."); 887 for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) { 888 auto ParamDiag = DiagID; 889 ParamDiag << 1; 890 if (CheckSpecForTypesEquivalent( 891 *this, ParamDiag, PDiag(), 892 Target->getParamType(i), TargetLoc, Source->getParamType(i), 893 SourceLoc)) 894 return true; 895 } 896 return false; 897 } 898 899 bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) { 900 // First we check for applicability. 901 // Target type must be a function, function pointer or function reference. 902 const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType); 903 if (!ToFunc || ToFunc->hasDependentExceptionSpec()) 904 return false; 905 906 // SourceType must be a function or function pointer. 907 const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType()); 908 if (!FromFunc || FromFunc->hasDependentExceptionSpec()) 909 return false; 910 911 unsigned DiagID = diag::err_incompatible_exception_specs; 912 unsigned NestedDiagID = diag::err_deep_exception_specs_differ; 913 // This is not an error in C++17 onwards, unless the noexceptness doesn't 914 // match, but in that case we have a full-on type mismatch, not just a 915 // type sugar mismatch. 916 if (getLangOpts().CPlusPlus17) { 917 DiagID = diag::warn_incompatible_exception_specs; 918 NestedDiagID = diag::warn_deep_exception_specs_differ; 919 } 920 921 // Now we've got the correct types on both sides, check their compatibility. 922 // This means that the source of the conversion can only throw a subset of 923 // the exceptions of the target, and any exception specs on arguments or 924 // return types must be equivalent. 925 // 926 // FIXME: If there is a nested dependent exception specification, we should 927 // not be checking it here. This is fine: 928 // template<typename T> void f() { 929 // void (*p)(void (*) throw(T)); 930 // void (*q)(void (*) throw(int)) = p; 931 // } 932 // ... because it might be instantiated with T=int. 933 return CheckExceptionSpecSubset( 934 PDiag(DiagID), PDiag(NestedDiagID), PDiag(), PDiag(), ToFunc, 935 From->getSourceRange().getBegin(), FromFunc, SourceLocation()) && 936 !getLangOpts().CPlusPlus17; 937 } 938 939 bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, 940 const CXXMethodDecl *Old) { 941 // If the new exception specification hasn't been parsed yet, skip the check. 942 // We'll get called again once it's been parsed. 943 if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == 944 EST_Unparsed) 945 return false; 946 947 // Don't check uninstantiated template destructors at all. We can only 948 // synthesize correct specs after the template is instantiated. 949 if (isa<CXXDestructorDecl>(New) && New->getParent()->isDependentType()) 950 return false; 951 952 // If the old exception specification hasn't been parsed yet, or the new 953 // exception specification can't be computed yet, remember that we need to 954 // perform this check when we get to the end of the outermost 955 // lexically-surrounding class. 956 if (exceptionSpecNotKnownYet(Old) || exceptionSpecNotKnownYet(New)) { 957 DelayedOverridingExceptionSpecChecks.push_back({New, Old}); 958 return false; 959 } 960 961 unsigned DiagID = diag::err_override_exception_spec; 962 if (getLangOpts().MSVCCompat) 963 DiagID = diag::ext_override_exception_spec; 964 return CheckExceptionSpecSubset(PDiag(DiagID), 965 PDiag(diag::err_deep_exception_specs_differ), 966 PDiag(diag::note_overridden_virtual_function), 967 PDiag(diag::ext_override_exception_spec), 968 Old->getType()->castAs<FunctionProtoType>(), 969 Old->getLocation(), 970 New->getType()->castAs<FunctionProtoType>(), 971 New->getLocation()); 972 } 973 974 static CanThrowResult canSubStmtsThrow(Sema &Self, const Stmt *S) { 975 CanThrowResult R = CT_Cannot; 976 for (const Stmt *SubStmt : S->children()) { 977 if (!SubStmt) 978 continue; 979 R = mergeCanThrow(R, Self.canThrow(SubStmt)); 980 if (R == CT_Can) 981 break; 982 } 983 return R; 984 } 985 986 /// Determine whether the callee of a particular function call can throw. 987 /// E and D are both optional, but at least one of E and Loc must be specified. 988 static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, 989 SourceLocation Loc = SourceLocation()) { 990 // As an extension, we assume that __attribute__((nothrow)) functions don't 991 // throw. 992 if (D && isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) 993 return CT_Cannot; 994 995 QualType T; 996 997 // In C++1z, just look at the function type of the callee. 998 if (S.getLangOpts().CPlusPlus17 && E && isa<CallExpr>(E)) { 999 E = cast<CallExpr>(E)->getCallee(); 1000 T = E->getType(); 1001 if (T->isSpecificPlaceholderType(BuiltinType::BoundMember)) { 1002 // Sadly we don't preserve the actual type as part of the "bound member" 1003 // placeholder, so we need to reconstruct it. 1004 E = E->IgnoreParenImpCasts(); 1005 1006 // Could be a call to a pointer-to-member or a plain member access. 1007 if (auto *Op = dyn_cast<BinaryOperator>(E)) { 1008 assert(Op->getOpcode() == BO_PtrMemD || Op->getOpcode() == BO_PtrMemI); 1009 T = Op->getRHS()->getType() 1010 ->castAs<MemberPointerType>()->getPointeeType(); 1011 } else { 1012 T = cast<MemberExpr>(E)->getMemberDecl()->getType(); 1013 } 1014 } 1015 } else if (const ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D)) 1016 T = VD->getType(); 1017 else 1018 // If we have no clue what we're calling, assume the worst. 1019 return CT_Can; 1020 1021 const FunctionProtoType *FT; 1022 if ((FT = T->getAs<FunctionProtoType>())) { 1023 } else if (const PointerType *PT = T->getAs<PointerType>()) 1024 FT = PT->getPointeeType()->getAs<FunctionProtoType>(); 1025 else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 1026 FT = RT->getPointeeType()->getAs<FunctionProtoType>(); 1027 else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) 1028 FT = MT->getPointeeType()->getAs<FunctionProtoType>(); 1029 else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) 1030 FT = BT->getPointeeType()->getAs<FunctionProtoType>(); 1031 1032 if (!FT) 1033 return CT_Can; 1034 1035 FT = S.ResolveExceptionSpec(Loc.isInvalid() ? E->getBeginLoc() : Loc, FT); 1036 if (!FT) 1037 return CT_Can; 1038 1039 return FT->canThrow(); 1040 } 1041 1042 static CanThrowResult canVarDeclThrow(Sema &Self, const VarDecl *VD) { 1043 CanThrowResult CT = CT_Cannot; 1044 1045 // Initialization might throw. 1046 if (!VD->isUsableInConstantExpressions(Self.Context)) 1047 if (const Expr *Init = VD->getInit()) 1048 CT = mergeCanThrow(CT, Self.canThrow(Init)); 1049 1050 // Destructor might throw. 1051 if (VD->needsDestruction(Self.Context) == QualType::DK_cxx_destructor) { 1052 if (auto *RD = 1053 VD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) { 1054 if (auto *Dtor = RD->getDestructor()) { 1055 CT = mergeCanThrow( 1056 CT, canCalleeThrow(Self, nullptr, Dtor, VD->getLocation())); 1057 } 1058 } 1059 } 1060 1061 // If this is a decomposition declaration, bindings might throw. 1062 if (auto *DD = dyn_cast<DecompositionDecl>(VD)) 1063 for (auto *B : DD->bindings()) 1064 if (auto *HD = B->getHoldingVar()) 1065 CT = mergeCanThrow(CT, canVarDeclThrow(Self, HD)); 1066 1067 return CT; 1068 } 1069 1070 static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { 1071 if (DC->isTypeDependent()) 1072 return CT_Dependent; 1073 1074 if (!DC->getTypeAsWritten()->isReferenceType()) 1075 return CT_Cannot; 1076 1077 if (DC->getSubExpr()->isTypeDependent()) 1078 return CT_Dependent; 1079 1080 return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot; 1081 } 1082 1083 static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { 1084 if (DC->isTypeOperand()) 1085 return CT_Cannot; 1086 1087 Expr *Op = DC->getExprOperand(); 1088 if (Op->isTypeDependent()) 1089 return CT_Dependent; 1090 1091 const RecordType *RT = Op->getType()->getAs<RecordType>(); 1092 if (!RT) 1093 return CT_Cannot; 1094 1095 if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) 1096 return CT_Cannot; 1097 1098 if (Op->Classify(S.Context).isPRValue()) 1099 return CT_Cannot; 1100 1101 return CT_Can; 1102 } 1103 1104 CanThrowResult Sema::canThrow(const Stmt *S) { 1105 // C++ [expr.unary.noexcept]p3: 1106 // [Can throw] if in a potentially-evaluated context the expression would 1107 // contain: 1108 switch (S->getStmtClass()) { 1109 case Expr::ConstantExprClass: 1110 return canThrow(cast<ConstantExpr>(S)->getSubExpr()); 1111 1112 case Expr::CXXThrowExprClass: 1113 // - a potentially evaluated throw-expression 1114 return CT_Can; 1115 1116 case Expr::CXXDynamicCastExprClass: { 1117 // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), 1118 // where T is a reference type, that requires a run-time check 1119 auto *CE = cast<CXXDynamicCastExpr>(S); 1120 // FIXME: Properly determine whether a variably-modified type can throw. 1121 if (CE->getType()->isVariablyModifiedType()) 1122 return CT_Can; 1123 CanThrowResult CT = canDynamicCastThrow(CE); 1124 if (CT == CT_Can) 1125 return CT; 1126 return mergeCanThrow(CT, canSubStmtsThrow(*this, CE)); 1127 } 1128 1129 case Expr::CXXTypeidExprClass: 1130 // - a potentially evaluated typeid expression applied to a glvalue 1131 // expression whose type is a polymorphic class type 1132 return canTypeidThrow(*this, cast<CXXTypeidExpr>(S)); 1133 1134 // - a potentially evaluated call to a function, member function, function 1135 // pointer, or member function pointer that does not have a non-throwing 1136 // exception-specification 1137 case Expr::CallExprClass: 1138 case Expr::CXXMemberCallExprClass: 1139 case Expr::CXXOperatorCallExprClass: 1140 case Expr::UserDefinedLiteralClass: { 1141 const CallExpr *CE = cast<CallExpr>(S); 1142 CanThrowResult CT; 1143 if (CE->isTypeDependent()) 1144 CT = CT_Dependent; 1145 else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) 1146 CT = CT_Cannot; 1147 else 1148 CT = canCalleeThrow(*this, CE, CE->getCalleeDecl()); 1149 if (CT == CT_Can) 1150 return CT; 1151 return mergeCanThrow(CT, canSubStmtsThrow(*this, CE)); 1152 } 1153 1154 case Expr::CXXConstructExprClass: 1155 case Expr::CXXTemporaryObjectExprClass: { 1156 auto *CE = cast<CXXConstructExpr>(S); 1157 // FIXME: Properly determine whether a variably-modified type can throw. 1158 if (CE->getType()->isVariablyModifiedType()) 1159 return CT_Can; 1160 CanThrowResult CT = canCalleeThrow(*this, CE, CE->getConstructor()); 1161 if (CT == CT_Can) 1162 return CT; 1163 return mergeCanThrow(CT, canSubStmtsThrow(*this, CE)); 1164 } 1165 1166 case Expr::CXXInheritedCtorInitExprClass: { 1167 auto *ICIE = cast<CXXInheritedCtorInitExpr>(S); 1168 return canCalleeThrow(*this, ICIE, ICIE->getConstructor()); 1169 } 1170 1171 case Expr::LambdaExprClass: { 1172 const LambdaExpr *Lambda = cast<LambdaExpr>(S); 1173 CanThrowResult CT = CT_Cannot; 1174 for (LambdaExpr::const_capture_init_iterator 1175 Cap = Lambda->capture_init_begin(), 1176 CapEnd = Lambda->capture_init_end(); 1177 Cap != CapEnd; ++Cap) 1178 CT = mergeCanThrow(CT, canThrow(*Cap)); 1179 return CT; 1180 } 1181 1182 case Expr::CXXNewExprClass: { 1183 auto *NE = cast<CXXNewExpr>(S); 1184 CanThrowResult CT; 1185 if (NE->isTypeDependent()) 1186 CT = CT_Dependent; 1187 else 1188 CT = canCalleeThrow(*this, NE, NE->getOperatorNew()); 1189 if (CT == CT_Can) 1190 return CT; 1191 return mergeCanThrow(CT, canSubStmtsThrow(*this, NE)); 1192 } 1193 1194 case Expr::CXXDeleteExprClass: { 1195 auto *DE = cast<CXXDeleteExpr>(S); 1196 CanThrowResult CT; 1197 QualType DTy = DE->getDestroyedType(); 1198 if (DTy.isNull() || DTy->isDependentType()) { 1199 CT = CT_Dependent; 1200 } else { 1201 CT = canCalleeThrow(*this, DE, DE->getOperatorDelete()); 1202 if (const RecordType *RT = DTy->getAs<RecordType>()) { 1203 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 1204 const CXXDestructorDecl *DD = RD->getDestructor(); 1205 if (DD) 1206 CT = mergeCanThrow(CT, canCalleeThrow(*this, DE, DD)); 1207 } 1208 if (CT == CT_Can) 1209 return CT; 1210 } 1211 return mergeCanThrow(CT, canSubStmtsThrow(*this, DE)); 1212 } 1213 1214 case Expr::CXXBindTemporaryExprClass: { 1215 auto *BTE = cast<CXXBindTemporaryExpr>(S); 1216 // The bound temporary has to be destroyed again, which might throw. 1217 CanThrowResult CT = 1218 canCalleeThrow(*this, BTE, BTE->getTemporary()->getDestructor()); 1219 if (CT == CT_Can) 1220 return CT; 1221 return mergeCanThrow(CT, canSubStmtsThrow(*this, BTE)); 1222 } 1223 1224 case Expr::PseudoObjectExprClass: { 1225 auto *POE = cast<PseudoObjectExpr>(S); 1226 CanThrowResult CT = CT_Cannot; 1227 for (const Expr *E : POE->semantics()) { 1228 CT = mergeCanThrow(CT, canThrow(E)); 1229 if (CT == CT_Can) 1230 break; 1231 } 1232 return CT; 1233 } 1234 1235 // ObjC message sends are like function calls, but never have exception 1236 // specs. 1237 case Expr::ObjCMessageExprClass: 1238 case Expr::ObjCPropertyRefExprClass: 1239 case Expr::ObjCSubscriptRefExprClass: 1240 return CT_Can; 1241 1242 // All the ObjC literals that are implemented as calls are 1243 // potentially throwing unless we decide to close off that 1244 // possibility. 1245 case Expr::ObjCArrayLiteralClass: 1246 case Expr::ObjCDictionaryLiteralClass: 1247 case Expr::ObjCBoxedExprClass: 1248 return CT_Can; 1249 1250 // Many other things have subexpressions, so we have to test those. 1251 // Some are simple: 1252 case Expr::CoawaitExprClass: 1253 case Expr::ConditionalOperatorClass: 1254 case Expr::CoyieldExprClass: 1255 case Expr::CXXRewrittenBinaryOperatorClass: 1256 case Expr::CXXStdInitializerListExprClass: 1257 case Expr::DesignatedInitExprClass: 1258 case Expr::DesignatedInitUpdateExprClass: 1259 case Expr::ExprWithCleanupsClass: 1260 case Expr::ExtVectorElementExprClass: 1261 case Expr::InitListExprClass: 1262 case Expr::ArrayInitLoopExprClass: 1263 case Expr::MemberExprClass: 1264 case Expr::ObjCIsaExprClass: 1265 case Expr::ObjCIvarRefExprClass: 1266 case Expr::ParenExprClass: 1267 case Expr::ParenListExprClass: 1268 case Expr::ShuffleVectorExprClass: 1269 case Expr::StmtExprClass: 1270 case Expr::ConvertVectorExprClass: 1271 case Expr::VAArgExprClass: 1272 return canSubStmtsThrow(*this, S); 1273 1274 case Expr::CompoundLiteralExprClass: 1275 case Expr::CXXConstCastExprClass: 1276 case Expr::CXXReinterpretCastExprClass: 1277 case Expr::BuiltinBitCastExprClass: 1278 // FIXME: Properly determine whether a variably-modified type can throw. 1279 if (cast<Expr>(S)->getType()->isVariablyModifiedType()) 1280 return CT_Can; 1281 return canSubStmtsThrow(*this, S); 1282 1283 // Some might be dependent for other reasons. 1284 case Expr::ArraySubscriptExprClass: 1285 case Expr::OMPArraySectionExprClass: 1286 case Expr::BinaryOperatorClass: 1287 case Expr::DependentCoawaitExprClass: 1288 case Expr::CompoundAssignOperatorClass: 1289 case Expr::CStyleCastExprClass: 1290 case Expr::CXXStaticCastExprClass: 1291 case Expr::CXXFunctionalCastExprClass: 1292 case Expr::ImplicitCastExprClass: 1293 case Expr::MaterializeTemporaryExprClass: 1294 case Expr::UnaryOperatorClass: { 1295 // FIXME: Properly determine whether a variably-modified type can throw. 1296 if (auto *CE = dyn_cast<CastExpr>(S)) 1297 if (CE->getType()->isVariablyModifiedType()) 1298 return CT_Can; 1299 CanThrowResult CT = 1300 cast<Expr>(S)->isTypeDependent() ? CT_Dependent : CT_Cannot; 1301 return mergeCanThrow(CT, canSubStmtsThrow(*this, S)); 1302 } 1303 1304 case Expr::CXXDefaultArgExprClass: 1305 return canThrow(cast<CXXDefaultArgExpr>(S)->getExpr()); 1306 1307 case Expr::CXXDefaultInitExprClass: 1308 return canThrow(cast<CXXDefaultInitExpr>(S)->getExpr()); 1309 1310 case Expr::ChooseExprClass: { 1311 auto *CE = cast<ChooseExpr>(S); 1312 if (CE->isTypeDependent() || CE->isValueDependent()) 1313 return CT_Dependent; 1314 return canThrow(CE->getChosenSubExpr()); 1315 } 1316 1317 case Expr::GenericSelectionExprClass: 1318 if (cast<GenericSelectionExpr>(S)->isResultDependent()) 1319 return CT_Dependent; 1320 return canThrow(cast<GenericSelectionExpr>(S)->getResultExpr()); 1321 1322 // Some expressions are always dependent. 1323 case Expr::CXXDependentScopeMemberExprClass: 1324 case Expr::CXXUnresolvedConstructExprClass: 1325 case Expr::DependentScopeDeclRefExprClass: 1326 case Expr::CXXFoldExprClass: 1327 return CT_Dependent; 1328 1329 case Expr::AsTypeExprClass: 1330 case Expr::BinaryConditionalOperatorClass: 1331 case Expr::BlockExprClass: 1332 case Expr::CUDAKernelCallExprClass: 1333 case Expr::DeclRefExprClass: 1334 case Expr::ObjCBridgedCastExprClass: 1335 case Expr::ObjCIndirectCopyRestoreExprClass: 1336 case Expr::ObjCProtocolExprClass: 1337 case Expr::ObjCSelectorExprClass: 1338 case Expr::ObjCAvailabilityCheckExprClass: 1339 case Expr::OffsetOfExprClass: 1340 case Expr::PackExpansionExprClass: 1341 case Expr::SubstNonTypeTemplateParmExprClass: 1342 case Expr::SubstNonTypeTemplateParmPackExprClass: 1343 case Expr::FunctionParmPackExprClass: 1344 case Expr::UnaryExprOrTypeTraitExprClass: 1345 case Expr::UnresolvedLookupExprClass: 1346 case Expr::UnresolvedMemberExprClass: 1347 case Expr::TypoExprClass: 1348 // FIXME: Many of the above can throw. 1349 return CT_Cannot; 1350 1351 case Expr::AddrLabelExprClass: 1352 case Expr::ArrayTypeTraitExprClass: 1353 case Expr::AtomicExprClass: 1354 case Expr::TypeTraitExprClass: 1355 case Expr::CXXBoolLiteralExprClass: 1356 case Expr::CXXNoexceptExprClass: 1357 case Expr::CXXNullPtrLiteralExprClass: 1358 case Expr::CXXPseudoDestructorExprClass: 1359 case Expr::CXXScalarValueInitExprClass: 1360 case Expr::CXXThisExprClass: 1361 case Expr::CXXUuidofExprClass: 1362 case Expr::CharacterLiteralClass: 1363 case Expr::ExpressionTraitExprClass: 1364 case Expr::FloatingLiteralClass: 1365 case Expr::GNUNullExprClass: 1366 case Expr::ImaginaryLiteralClass: 1367 case Expr::ImplicitValueInitExprClass: 1368 case Expr::IntegerLiteralClass: 1369 case Expr::FixedPointLiteralClass: 1370 case Expr::ArrayInitIndexExprClass: 1371 case Expr::NoInitExprClass: 1372 case Expr::ObjCEncodeExprClass: 1373 case Expr::ObjCStringLiteralClass: 1374 case Expr::ObjCBoolLiteralExprClass: 1375 case Expr::OpaqueValueExprClass: 1376 case Expr::PredefinedExprClass: 1377 case Expr::SizeOfPackExprClass: 1378 case Expr::StringLiteralClass: 1379 case Expr::SourceLocExprClass: 1380 case Expr::ConceptSpecializationExprClass: 1381 // These expressions can never throw. 1382 return CT_Cannot; 1383 1384 case Expr::MSPropertyRefExprClass: 1385 case Expr::MSPropertySubscriptExprClass: 1386 llvm_unreachable("Invalid class for expression"); 1387 1388 // Most statements can throw if any substatement can throw. 1389 case Stmt::AttributedStmtClass: 1390 case Stmt::BreakStmtClass: 1391 case Stmt::CapturedStmtClass: 1392 case Stmt::CaseStmtClass: 1393 case Stmt::CompoundStmtClass: 1394 case Stmt::ContinueStmtClass: 1395 case Stmt::CoreturnStmtClass: 1396 case Stmt::CoroutineBodyStmtClass: 1397 case Stmt::CXXCatchStmtClass: 1398 case Stmt::CXXForRangeStmtClass: 1399 case Stmt::DefaultStmtClass: 1400 case Stmt::DoStmtClass: 1401 case Stmt::ForStmtClass: 1402 case Stmt::GCCAsmStmtClass: 1403 case Stmt::GotoStmtClass: 1404 case Stmt::IndirectGotoStmtClass: 1405 case Stmt::LabelStmtClass: 1406 case Stmt::MSAsmStmtClass: 1407 case Stmt::MSDependentExistsStmtClass: 1408 case Stmt::NullStmtClass: 1409 case Stmt::ObjCAtCatchStmtClass: 1410 case Stmt::ObjCAtFinallyStmtClass: 1411 case Stmt::ObjCAtSynchronizedStmtClass: 1412 case Stmt::ObjCAutoreleasePoolStmtClass: 1413 case Stmt::ObjCForCollectionStmtClass: 1414 case Stmt::OMPAtomicDirectiveClass: 1415 case Stmt::OMPBarrierDirectiveClass: 1416 case Stmt::OMPCancelDirectiveClass: 1417 case Stmt::OMPCancellationPointDirectiveClass: 1418 case Stmt::OMPCriticalDirectiveClass: 1419 case Stmt::OMPDistributeDirectiveClass: 1420 case Stmt::OMPDistributeParallelForDirectiveClass: 1421 case Stmt::OMPDistributeParallelForSimdDirectiveClass: 1422 case Stmt::OMPDistributeSimdDirectiveClass: 1423 case Stmt::OMPFlushDirectiveClass: 1424 case Stmt::OMPForDirectiveClass: 1425 case Stmt::OMPForSimdDirectiveClass: 1426 case Stmt::OMPMasterDirectiveClass: 1427 case Stmt::OMPMasterTaskLoopDirectiveClass: 1428 case Stmt::OMPMasterTaskLoopSimdDirectiveClass: 1429 case Stmt::OMPOrderedDirectiveClass: 1430 case Stmt::OMPParallelDirectiveClass: 1431 case Stmt::OMPParallelForDirectiveClass: 1432 case Stmt::OMPParallelForSimdDirectiveClass: 1433 case Stmt::OMPParallelMasterDirectiveClass: 1434 case Stmt::OMPParallelMasterTaskLoopDirectiveClass: 1435 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass: 1436 case Stmt::OMPParallelSectionsDirectiveClass: 1437 case Stmt::OMPSectionDirectiveClass: 1438 case Stmt::OMPSectionsDirectiveClass: 1439 case Stmt::OMPSimdDirectiveClass: 1440 case Stmt::OMPSingleDirectiveClass: 1441 case Stmt::OMPTargetDataDirectiveClass: 1442 case Stmt::OMPTargetDirectiveClass: 1443 case Stmt::OMPTargetEnterDataDirectiveClass: 1444 case Stmt::OMPTargetExitDataDirectiveClass: 1445 case Stmt::OMPTargetParallelDirectiveClass: 1446 case Stmt::OMPTargetParallelForDirectiveClass: 1447 case Stmt::OMPTargetParallelForSimdDirectiveClass: 1448 case Stmt::OMPTargetSimdDirectiveClass: 1449 case Stmt::OMPTargetTeamsDirectiveClass: 1450 case Stmt::OMPTargetTeamsDistributeDirectiveClass: 1451 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass: 1452 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass: 1453 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass: 1454 case Stmt::OMPTargetUpdateDirectiveClass: 1455 case Stmt::OMPTaskDirectiveClass: 1456 case Stmt::OMPTaskgroupDirectiveClass: 1457 case Stmt::OMPTaskLoopDirectiveClass: 1458 case Stmt::OMPTaskLoopSimdDirectiveClass: 1459 case Stmt::OMPTaskwaitDirectiveClass: 1460 case Stmt::OMPTaskyieldDirectiveClass: 1461 case Stmt::OMPTeamsDirectiveClass: 1462 case Stmt::OMPTeamsDistributeDirectiveClass: 1463 case Stmt::OMPTeamsDistributeParallelForDirectiveClass: 1464 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass: 1465 case Stmt::OMPTeamsDistributeSimdDirectiveClass: 1466 case Stmt::ReturnStmtClass: 1467 case Stmt::SEHExceptStmtClass: 1468 case Stmt::SEHFinallyStmtClass: 1469 case Stmt::SEHLeaveStmtClass: 1470 case Stmt::SEHTryStmtClass: 1471 case Stmt::SwitchStmtClass: 1472 case Stmt::WhileStmtClass: 1473 return canSubStmtsThrow(*this, S); 1474 1475 case Stmt::DeclStmtClass: { 1476 CanThrowResult CT = CT_Cannot; 1477 for (const Decl *D : cast<DeclStmt>(S)->decls()) { 1478 if (auto *VD = dyn_cast<VarDecl>(D)) 1479 CT = mergeCanThrow(CT, canVarDeclThrow(*this, VD)); 1480 1481 // FIXME: Properly determine whether a variably-modified type can throw. 1482 if (auto *TND = dyn_cast<TypedefNameDecl>(D)) 1483 if (TND->getUnderlyingType()->isVariablyModifiedType()) 1484 return CT_Can; 1485 if (auto *VD = dyn_cast<ValueDecl>(D)) 1486 if (VD->getType()->isVariablyModifiedType()) 1487 return CT_Can; 1488 } 1489 return CT; 1490 } 1491 1492 case Stmt::IfStmtClass: { 1493 auto *IS = cast<IfStmt>(S); 1494 CanThrowResult CT = CT_Cannot; 1495 if (const Stmt *Init = IS->getInit()) 1496 CT = mergeCanThrow(CT, canThrow(Init)); 1497 if (const Stmt *CondDS = IS->getConditionVariableDeclStmt()) 1498 CT = mergeCanThrow(CT, canThrow(CondDS)); 1499 CT = mergeCanThrow(CT, canThrow(IS->getCond())); 1500 1501 // For 'if constexpr', consider only the non-discarded case. 1502 // FIXME: We should add a DiscardedStmt marker to the AST. 1503 if (Optional<const Stmt *> Case = IS->getNondiscardedCase(Context)) 1504 return *Case ? mergeCanThrow(CT, canThrow(*Case)) : CT; 1505 1506 CanThrowResult Then = canThrow(IS->getThen()); 1507 CanThrowResult Else = IS->getElse() ? canThrow(IS->getElse()) : CT_Cannot; 1508 if (Then == Else) 1509 return mergeCanThrow(CT, Then); 1510 1511 // For a dependent 'if constexpr', the result is dependent if it depends on 1512 // the value of the condition. 1513 return mergeCanThrow(CT, IS->isConstexpr() ? CT_Dependent 1514 : mergeCanThrow(Then, Else)); 1515 } 1516 1517 case Stmt::CXXTryStmtClass: { 1518 auto *TS = cast<CXXTryStmt>(S); 1519 // try /*...*/ catch (...) { H } can throw only if H can throw. 1520 // Any other try-catch can throw if any substatement can throw. 1521 const CXXCatchStmt *FinalHandler = TS->getHandler(TS->getNumHandlers() - 1); 1522 if (!FinalHandler->getExceptionDecl()) 1523 return canThrow(FinalHandler->getHandlerBlock()); 1524 return canSubStmtsThrow(*this, S); 1525 } 1526 1527 case Stmt::ObjCAtThrowStmtClass: 1528 return CT_Can; 1529 1530 case Stmt::ObjCAtTryStmtClass: { 1531 auto *TS = cast<ObjCAtTryStmt>(S); 1532 1533 // @catch(...) need not be last in Objective-C. Walk backwards until we 1534 // see one or hit the @try. 1535 CanThrowResult CT = CT_Cannot; 1536 if (const Stmt *Finally = TS->getFinallyStmt()) 1537 CT = mergeCanThrow(CT, canThrow(Finally)); 1538 for (unsigned I = TS->getNumCatchStmts(); I != 0; --I) { 1539 const ObjCAtCatchStmt *Catch = TS->getCatchStmt(I - 1); 1540 CT = mergeCanThrow(CT, canThrow(Catch)); 1541 // If we reach a @catch(...), no earlier exceptions can escape. 1542 if (Catch->hasEllipsis()) 1543 return CT; 1544 } 1545 1546 // Didn't find an @catch(...). Exceptions from the @try body can escape. 1547 return mergeCanThrow(CT, canThrow(TS->getTryBody())); 1548 } 1549 1550 case Stmt::NoStmtClass: 1551 llvm_unreachable("Invalid class for statement"); 1552 } 1553 llvm_unreachable("Bogus StmtClass"); 1554 } 1555 1556 } // end namespace clang 1557