1 //===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file provides Sema routines for C++ exception specification testing. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Sema/SemaInternal.h" 15 #include "clang/AST/ASTMutationListener.h" 16 #include "clang/AST/CXXInheritance.h" 17 #include "clang/AST/Expr.h" 18 #include "clang/AST/ExprCXX.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.getLocStart())) 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 /// CheckSpecifiedExceptionType - Check if the given type is valid in an 80 /// exception specification. Incomplete types, or pointers to incomplete types 81 /// other than void are not allowed. 82 /// 83 /// \param[in,out] T The exception type. This will be decayed to a pointer type 84 /// when the input is an array or a function type. 85 bool Sema::CheckSpecifiedExceptionType(QualType &T, SourceRange Range) { 86 // C++11 [except.spec]p2: 87 // A type cv T, "array of T", or "function returning T" denoted 88 // in an exception-specification is adjusted to type T, "pointer to T", or 89 // "pointer to function returning T", respectively. 90 // 91 // We also apply this rule in C++98. 92 if (T->isArrayType()) 93 T = Context.getArrayDecayedType(T); 94 else if (T->isFunctionType()) 95 T = Context.getPointerType(T); 96 97 int Kind = 0; 98 QualType PointeeT = T; 99 if (const PointerType *PT = T->getAs<PointerType>()) { 100 PointeeT = PT->getPointeeType(); 101 Kind = 1; 102 103 // cv void* is explicitly permitted, despite being a pointer to an 104 // incomplete type. 105 if (PointeeT->isVoidType()) 106 return false; 107 } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) { 108 PointeeT = RT->getPointeeType(); 109 Kind = 2; 110 111 if (RT->isRValueReferenceType()) { 112 // C++11 [except.spec]p2: 113 // A type denoted in an exception-specification shall not denote [...] 114 // an rvalue reference type. 115 Diag(Range.getBegin(), diag::err_rref_in_exception_spec) 116 << T << Range; 117 return true; 118 } 119 } 120 121 // C++11 [except.spec]p2: 122 // A type denoted in an exception-specification shall not denote an 123 // incomplete type other than a class currently being defined [...]. 124 // A type denoted in an exception-specification shall not denote a 125 // pointer or reference to an incomplete type, other than (cv) void* or a 126 // pointer or reference to a class currently being defined. 127 // In Microsoft mode, downgrade this to a warning. 128 unsigned DiagID = diag::err_incomplete_in_exception_spec; 129 bool ReturnValueOnError = true; 130 if (getLangOpts().MicrosoftExt) { 131 DiagID = diag::ext_incomplete_in_exception_spec; 132 ReturnValueOnError = false; 133 } 134 if (!(PointeeT->isRecordType() && 135 PointeeT->getAs<RecordType>()->isBeingDefined()) && 136 RequireCompleteType(Range.getBegin(), PointeeT, DiagID, Kind, Range)) 137 return ReturnValueOnError; 138 139 return false; 140 } 141 142 /// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer 143 /// to member to a function with an exception specification. This means that 144 /// it is invalid to add another level of indirection. 145 bool Sema::CheckDistantExceptionSpec(QualType T) { 146 // C++17 removes this rule in favor of putting exception specifications into 147 // the type system. 148 if (getLangOpts().CPlusPlus17) 149 return false; 150 151 if (const PointerType *PT = T->getAs<PointerType>()) 152 T = PT->getPointeeType(); 153 else if (const MemberPointerType *PT = T->getAs<MemberPointerType>()) 154 T = PT->getPointeeType(); 155 else 156 return false; 157 158 const FunctionProtoType *FnT = T->getAs<FunctionProtoType>(); 159 if (!FnT) 160 return false; 161 162 return FnT->hasExceptionSpec(); 163 } 164 165 const FunctionProtoType * 166 Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) { 167 if (FPT->getExceptionSpecType() == EST_Unparsed) { 168 Diag(Loc, diag::err_exception_spec_not_parsed); 169 return nullptr; 170 } 171 172 if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) 173 return FPT; 174 175 FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl(); 176 const FunctionProtoType *SourceFPT = 177 SourceDecl->getType()->castAs<FunctionProtoType>(); 178 179 // If the exception specification has already been resolved, just return it. 180 if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType())) 181 return SourceFPT; 182 183 // Compute or instantiate the exception specification now. 184 if (SourceFPT->getExceptionSpecType() == EST_Unevaluated) 185 EvaluateImplicitExceptionSpec(Loc, cast<CXXMethodDecl>(SourceDecl)); 186 else 187 InstantiateExceptionSpec(Loc, SourceDecl); 188 189 const FunctionProtoType *Proto = 190 SourceDecl->getType()->castAs<FunctionProtoType>(); 191 if (Proto->getExceptionSpecType() == clang::EST_Unparsed) { 192 Diag(Loc, diag::err_exception_spec_not_parsed); 193 Proto = nullptr; 194 } 195 return Proto; 196 } 197 198 void 199 Sema::UpdateExceptionSpec(FunctionDecl *FD, 200 const FunctionProtoType::ExceptionSpecInfo &ESI) { 201 // If we've fully resolved the exception specification, notify listeners. 202 if (!isUnresolvedExceptionSpec(ESI.Type)) 203 if (auto *Listener = getASTMutationListener()) 204 Listener->ResolvedExceptionSpec(FD); 205 206 for (FunctionDecl *Redecl : FD->redecls()) 207 Context.adjustExceptionSpec(Redecl, ESI); 208 } 209 210 static bool CheckEquivalentExceptionSpecImpl( 211 Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, 212 const FunctionProtoType *Old, SourceLocation OldLoc, 213 const FunctionProtoType *New, SourceLocation NewLoc, 214 bool *MissingExceptionSpecification = nullptr, 215 bool *MissingEmptyExceptionSpecification = nullptr, 216 bool AllowNoexceptAllMatchWithNoSpec = false, bool IsOperatorNew = false); 217 218 /// Determine whether a function has an implicitly-generated exception 219 /// specification. 220 static bool hasImplicitExceptionSpec(FunctionDecl *Decl) { 221 if (!isa<CXXDestructorDecl>(Decl) && 222 Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete && 223 Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) 224 return false; 225 226 // For a function that the user didn't declare: 227 // - if this is a destructor, its exception specification is implicit. 228 // - if this is 'operator delete' or 'operator delete[]', the exception 229 // specification is as-if an explicit exception specification was given 230 // (per [basic.stc.dynamic]p2). 231 if (!Decl->getTypeSourceInfo()) 232 return isa<CXXDestructorDecl>(Decl); 233 234 const FunctionProtoType *Ty = 235 Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>(); 236 return !Ty->hasExceptionSpec(); 237 } 238 239 bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { 240 // Just completely ignore this under -fno-exceptions prior to C++17. 241 // In C++17 onwards, the exception specification is part of the type and 242 // we will diagnose mismatches anyway, so it's better to check for them here. 243 if (!getLangOpts().CXXExceptions && !getLangOpts().CPlusPlus17) 244 return false; 245 246 OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator(); 247 bool IsOperatorNew = OO == OO_New || OO == OO_Array_New; 248 bool MissingExceptionSpecification = false; 249 bool MissingEmptyExceptionSpecification = false; 250 251 unsigned DiagID = diag::err_mismatched_exception_spec; 252 bool ReturnValueOnError = true; 253 if (getLangOpts().MicrosoftExt) { 254 DiagID = diag::ext_mismatched_exception_spec; 255 ReturnValueOnError = false; 256 } 257 258 // Check the types as written: they must match before any exception 259 // specification adjustment is applied. 260 if (!CheckEquivalentExceptionSpecImpl( 261 *this, PDiag(DiagID), PDiag(diag::note_previous_declaration), 262 Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(), 263 New->getType()->getAs<FunctionProtoType>(), New->getLocation(), 264 &MissingExceptionSpecification, &MissingEmptyExceptionSpecification, 265 /*AllowNoexceptAllMatchWithNoSpec=*/true, IsOperatorNew)) { 266 // C++11 [except.spec]p4 [DR1492]: 267 // If a declaration of a function has an implicit 268 // exception-specification, other declarations of the function shall 269 // not specify an exception-specification. 270 if (getLangOpts().CPlusPlus11 && getLangOpts().CXXExceptions && 271 hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) { 272 Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch) 273 << hasImplicitExceptionSpec(Old); 274 if (Old->getLocation().isValid()) 275 Diag(Old->getLocation(), diag::note_previous_declaration); 276 } 277 return false; 278 } 279 280 // The failure was something other than an missing exception 281 // specification; return an error, except in MS mode where this is a warning. 282 if (!MissingExceptionSpecification) 283 return ReturnValueOnError; 284 285 const FunctionProtoType *NewProto = 286 New->getType()->castAs<FunctionProtoType>(); 287 288 // The new function declaration is only missing an empty exception 289 // specification "throw()". If the throw() specification came from a 290 // function in a system header that has C linkage, just add an empty 291 // exception specification to the "new" declaration. Note that C library 292 // implementations are permitted to add these nothrow exception 293 // specifications. 294 // 295 // Likewise if the old function is a builtin. 296 if (MissingEmptyExceptionSpecification && NewProto && 297 (Old->getLocation().isInvalid() || 298 Context.getSourceManager().isInSystemHeader(Old->getLocation()) || 299 Old->getBuiltinID()) && 300 Old->isExternC()) { 301 New->setType(Context.getFunctionType( 302 NewProto->getReturnType(), NewProto->getParamTypes(), 303 NewProto->getExtProtoInfo().withExceptionSpec(EST_DynamicNone))); 304 return false; 305 } 306 307 const FunctionProtoType *OldProto = 308 Old->getType()->castAs<FunctionProtoType>(); 309 310 FunctionProtoType::ExceptionSpecInfo ESI = OldProto->getExceptionSpecType(); 311 if (ESI.Type == EST_Dynamic) { 312 ESI.Exceptions = OldProto->exceptions(); 313 } 314 315 if (ESI.Type == EST_ComputedNoexcept) { 316 // For computed noexcept, we can't just take the expression from the old 317 // prototype. It likely contains references to the old prototype's 318 // parameters. 319 New->setInvalidDecl(); 320 } else { 321 // Update the type of the function with the appropriate exception 322 // specification. 323 New->setType(Context.getFunctionType( 324 NewProto->getReturnType(), NewProto->getParamTypes(), 325 NewProto->getExtProtoInfo().withExceptionSpec(ESI))); 326 } 327 328 if (getLangOpts().MicrosoftExt && ESI.Type != EST_ComputedNoexcept) { 329 // Allow missing exception specifications in redeclarations as an extension. 330 DiagID = diag::ext_ms_missing_exception_specification; 331 ReturnValueOnError = false; 332 } else if (New->isReplaceableGlobalAllocationFunction() && 333 ESI.Type != EST_ComputedNoexcept) { 334 // Allow missing exception specifications in redeclarations as an extension, 335 // when declaring a replaceable global allocation function. 336 DiagID = diag::ext_missing_exception_specification; 337 ReturnValueOnError = false; 338 } else { 339 DiagID = diag::err_missing_exception_specification; 340 ReturnValueOnError = true; 341 } 342 343 // Warn about the lack of exception specification. 344 SmallString<128> ExceptionSpecString; 345 llvm::raw_svector_ostream OS(ExceptionSpecString); 346 switch (OldProto->getExceptionSpecType()) { 347 case EST_DynamicNone: 348 OS << "throw()"; 349 break; 350 351 case EST_Dynamic: { 352 OS << "throw("; 353 bool OnFirstException = true; 354 for (const auto &E : OldProto->exceptions()) { 355 if (OnFirstException) 356 OnFirstException = false; 357 else 358 OS << ", "; 359 360 OS << E.getAsString(getPrintingPolicy()); 361 } 362 OS << ")"; 363 break; 364 } 365 366 case EST_BasicNoexcept: 367 OS << "noexcept"; 368 break; 369 370 case EST_ComputedNoexcept: 371 OS << "noexcept("; 372 assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr"); 373 OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy()); 374 OS << ")"; 375 break; 376 377 default: 378 llvm_unreachable("This spec type is compatible with none."); 379 } 380 381 SourceLocation FixItLoc; 382 if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) { 383 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); 384 // FIXME: Preserve enough information so that we can produce a correct fixit 385 // location when there is a trailing return type. 386 if (auto FTLoc = TL.getAs<FunctionProtoTypeLoc>()) 387 if (!FTLoc.getTypePtr()->hasTrailingReturn()) 388 FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd()); 389 } 390 391 if (FixItLoc.isInvalid()) 392 Diag(New->getLocation(), DiagID) 393 << New << OS.str(); 394 else { 395 Diag(New->getLocation(), DiagID) 396 << New << OS.str() 397 << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str()); 398 } 399 400 if (Old->getLocation().isValid()) 401 Diag(Old->getLocation(), diag::note_previous_declaration); 402 403 return ReturnValueOnError; 404 } 405 406 /// CheckEquivalentExceptionSpec - Check if the two types have equivalent 407 /// exception specifications. Exception specifications are equivalent if 408 /// they allow exactly the same set of exception types. It does not matter how 409 /// that is achieved. See C++ [except.spec]p2. 410 bool Sema::CheckEquivalentExceptionSpec( 411 const FunctionProtoType *Old, SourceLocation OldLoc, 412 const FunctionProtoType *New, SourceLocation NewLoc) { 413 if (!getLangOpts().CXXExceptions) 414 return false; 415 416 unsigned DiagID = diag::err_mismatched_exception_spec; 417 if (getLangOpts().MicrosoftExt) 418 DiagID = diag::ext_mismatched_exception_spec; 419 bool Result = CheckEquivalentExceptionSpecImpl( 420 *this, PDiag(DiagID), PDiag(diag::note_previous_declaration), 421 Old, OldLoc, New, NewLoc); 422 423 // In Microsoft mode, mismatching exception specifications just cause a warning. 424 if (getLangOpts().MicrosoftExt) 425 return false; 426 return Result; 427 } 428 429 /// CheckEquivalentExceptionSpec - Check if the two types have compatible 430 /// exception specifications. See C++ [except.spec]p3. 431 /// 432 /// \return \c false if the exception specifications match, \c true if there is 433 /// a problem. If \c true is returned, either a diagnostic has already been 434 /// produced or \c *MissingExceptionSpecification is set to \c true. 435 static bool CheckEquivalentExceptionSpecImpl( 436 Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, 437 const FunctionProtoType *Old, SourceLocation OldLoc, 438 const FunctionProtoType *New, SourceLocation NewLoc, 439 bool *MissingExceptionSpecification, 440 bool *MissingEmptyExceptionSpecification, 441 bool AllowNoexceptAllMatchWithNoSpec, bool IsOperatorNew) { 442 if (MissingExceptionSpecification) 443 *MissingExceptionSpecification = false; 444 445 if (MissingEmptyExceptionSpecification) 446 *MissingEmptyExceptionSpecification = false; 447 448 Old = S.ResolveExceptionSpec(NewLoc, Old); 449 if (!Old) 450 return false; 451 New = S.ResolveExceptionSpec(NewLoc, New); 452 if (!New) 453 return false; 454 455 // C++0x [except.spec]p3: Two exception-specifications are compatible if: 456 // - both are non-throwing, regardless of their form, 457 // - both have the form noexcept(constant-expression) and the constant- 458 // expressions are equivalent, 459 // - both are dynamic-exception-specifications that have the same set of 460 // adjusted types. 461 // 462 // C++0x [except.spec]p12: An exception-specification is non-throwing if it is 463 // of the form throw(), noexcept, or noexcept(constant-expression) where the 464 // constant-expression yields true. 465 // 466 // C++0x [except.spec]p4: If any declaration of a function has an exception- 467 // specifier that is not a noexcept-specification allowing all exceptions, 468 // all declarations [...] of that function shall have a compatible 469 // exception-specification. 470 // 471 // That last point basically means that noexcept(false) matches no spec. 472 // It's considered when AllowNoexceptAllMatchWithNoSpec is true. 473 474 ExceptionSpecificationType OldEST = Old->getExceptionSpecType(); 475 ExceptionSpecificationType NewEST = New->getExceptionSpecType(); 476 477 assert(!isUnresolvedExceptionSpec(OldEST) && 478 !isUnresolvedExceptionSpec(NewEST) && 479 "Shouldn't see unknown exception specifications here"); 480 481 // Shortcut the case where both have no spec. 482 if (OldEST == EST_None && NewEST == EST_None) 483 return false; 484 485 FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(S.Context); 486 FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(S.Context); 487 if (OldNR == FunctionProtoType::NR_BadNoexcept || 488 NewNR == FunctionProtoType::NR_BadNoexcept) 489 return false; 490 491 // Dependent noexcept specifiers are compatible with each other, but nothing 492 // else. 493 // One noexcept is compatible with another if the argument is the same 494 if (OldNR == NewNR && 495 OldNR != FunctionProtoType::NR_NoNoexcept && 496 NewNR != FunctionProtoType::NR_NoNoexcept) 497 return false; 498 if (OldNR != NewNR && 499 OldNR != FunctionProtoType::NR_NoNoexcept && 500 NewNR != FunctionProtoType::NR_NoNoexcept) { 501 S.Diag(NewLoc, DiagID); 502 if (NoteID.getDiagID() != 0 && OldLoc.isValid()) 503 S.Diag(OldLoc, NoteID); 504 return true; 505 } 506 507 // The MS extension throw(...) is compatible with itself. 508 if (OldEST == EST_MSAny && NewEST == EST_MSAny) 509 return false; 510 511 // It's also compatible with no spec. 512 if ((OldEST == EST_None && NewEST == EST_MSAny) || 513 (OldEST == EST_MSAny && NewEST == EST_None)) 514 return false; 515 516 // It's also compatible with noexcept(false). 517 if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw) 518 return false; 519 if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw) 520 return false; 521 522 // As described above, noexcept(false) matches no spec only for functions. 523 if (AllowNoexceptAllMatchWithNoSpec) { 524 if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw) 525 return false; 526 if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw) 527 return false; 528 } 529 530 // Any non-throwing specifications are compatible. 531 bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow || 532 OldEST == EST_DynamicNone; 533 bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow || 534 NewEST == EST_DynamicNone; 535 if (OldNonThrowing && NewNonThrowing) 536 return false; 537 538 // As a special compatibility feature, under C++0x we accept no spec and 539 // throw(std::bad_alloc) as equivalent for operator new and operator new[]. 540 // This is because the implicit declaration changed, but old code would break. 541 if (S.getLangOpts().CPlusPlus11 && IsOperatorNew) { 542 const FunctionProtoType *WithExceptions = nullptr; 543 if (OldEST == EST_None && NewEST == EST_Dynamic) 544 WithExceptions = New; 545 else if (OldEST == EST_Dynamic && NewEST == EST_None) 546 WithExceptions = Old; 547 if (WithExceptions && WithExceptions->getNumExceptions() == 1) { 548 // One has no spec, the other throw(something). If that something is 549 // std::bad_alloc, all conditions are met. 550 QualType Exception = *WithExceptions->exception_begin(); 551 if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) { 552 IdentifierInfo* Name = ExRecord->getIdentifier(); 553 if (Name && Name->getName() == "bad_alloc") { 554 // It's called bad_alloc, but is it in std? 555 if (ExRecord->isInStdNamespace()) { 556 return false; 557 } 558 } 559 } 560 } 561 } 562 563 // At this point, the only remaining valid case is two matching dynamic 564 // specifications. We return here unless both specifications are dynamic. 565 if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) { 566 if (MissingExceptionSpecification && Old->hasExceptionSpec() && 567 !New->hasExceptionSpec()) { 568 // The old type has an exception specification of some sort, but 569 // the new type does not. 570 *MissingExceptionSpecification = true; 571 572 if (MissingEmptyExceptionSpecification && OldNonThrowing) { 573 // The old type has a throw() or noexcept(true) exception specification 574 // and the new type has no exception specification, and the caller asked 575 // to handle this itself. 576 *MissingEmptyExceptionSpecification = true; 577 } 578 579 return true; 580 } 581 582 S.Diag(NewLoc, DiagID); 583 if (NoteID.getDiagID() != 0 && OldLoc.isValid()) 584 S.Diag(OldLoc, NoteID); 585 return true; 586 } 587 588 assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic && 589 "Exception compatibility logic error: non-dynamic spec slipped through."); 590 591 bool Success = true; 592 // Both have a dynamic exception spec. Collect the first set, then compare 593 // to the second. 594 llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes; 595 for (const auto &I : Old->exceptions()) 596 OldTypes.insert(S.Context.getCanonicalType(I).getUnqualifiedType()); 597 598 for (const auto &I : New->exceptions()) { 599 CanQualType TypePtr = S.Context.getCanonicalType(I).getUnqualifiedType(); 600 if (OldTypes.count(TypePtr)) 601 NewTypes.insert(TypePtr); 602 else 603 Success = false; 604 } 605 606 Success = Success && OldTypes.size() == NewTypes.size(); 607 608 if (Success) { 609 return false; 610 } 611 S.Diag(NewLoc, DiagID); 612 if (NoteID.getDiagID() != 0 && OldLoc.isValid()) 613 S.Diag(OldLoc, NoteID); 614 return true; 615 } 616 617 bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, 618 const PartialDiagnostic &NoteID, 619 const FunctionProtoType *Old, 620 SourceLocation OldLoc, 621 const FunctionProtoType *New, 622 SourceLocation NewLoc) { 623 if (!getLangOpts().CXXExceptions) 624 return false; 625 return CheckEquivalentExceptionSpecImpl(*this, DiagID, NoteID, Old, OldLoc, 626 New, NewLoc); 627 } 628 629 bool Sema::handlerCanCatch(QualType HandlerType, QualType ExceptionType) { 630 // [except.handle]p3: 631 // A handler is a match for an exception object of type E if: 632 633 // HandlerType must be ExceptionType or derived from it, or pointer or 634 // reference to such types. 635 const ReferenceType *RefTy = HandlerType->getAs<ReferenceType>(); 636 if (RefTy) 637 HandlerType = RefTy->getPointeeType(); 638 639 // -- the handler is of type cv T or cv T& and E and T are the same type 640 if (Context.hasSameUnqualifiedType(ExceptionType, HandlerType)) 641 return true; 642 643 // FIXME: ObjC pointer types? 644 if (HandlerType->isPointerType() || HandlerType->isMemberPointerType()) { 645 if (RefTy && (!HandlerType.isConstQualified() || 646 HandlerType.isVolatileQualified())) 647 return false; 648 649 // -- the handler is of type cv T or const T& where T is a pointer or 650 // pointer to member type and E is std::nullptr_t 651 if (ExceptionType->isNullPtrType()) 652 return true; 653 654 // -- the handler is of type cv T or const T& where T is a pointer or 655 // pointer to member type and E is a pointer or pointer to member type 656 // that can be converted to T by one or more of 657 // -- a qualification conversion 658 // -- a function pointer conversion 659 bool LifetimeConv; 660 QualType Result; 661 // FIXME: Should we treat the exception as catchable if a lifetime 662 // conversion is required? 663 if (IsQualificationConversion(ExceptionType, HandlerType, false, 664 LifetimeConv) || 665 IsFunctionConversion(ExceptionType, HandlerType, Result)) 666 return true; 667 668 // -- a standard pointer conversion [...] 669 if (!ExceptionType->isPointerType() || !HandlerType->isPointerType()) 670 return false; 671 672 // Handle the "qualification conversion" portion. 673 Qualifiers EQuals, HQuals; 674 ExceptionType = Context.getUnqualifiedArrayType( 675 ExceptionType->getPointeeType(), EQuals); 676 HandlerType = Context.getUnqualifiedArrayType( 677 HandlerType->getPointeeType(), HQuals); 678 if (!HQuals.compatiblyIncludes(EQuals)) 679 return false; 680 681 if (HandlerType->isVoidType() && ExceptionType->isObjectType()) 682 return true; 683 684 // The only remaining case is a derived-to-base conversion. 685 } 686 687 // -- the handler is of type cg T or cv T& and T is an unambiguous public 688 // base class of E 689 if (!ExceptionType->isRecordType() || !HandlerType->isRecordType()) 690 return false; 691 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 692 /*DetectVirtual=*/false); 693 if (!IsDerivedFrom(SourceLocation(), ExceptionType, HandlerType, Paths) || 694 Paths.isAmbiguous(Context.getCanonicalType(HandlerType))) 695 return false; 696 697 // Do this check from a context without privileges. 698 switch (CheckBaseClassAccess(SourceLocation(), HandlerType, ExceptionType, 699 Paths.front(), 700 /*Diagnostic*/ 0, 701 /*ForceCheck*/ true, 702 /*ForceUnprivileged*/ true)) { 703 case AR_accessible: return true; 704 case AR_inaccessible: return false; 705 case AR_dependent: 706 llvm_unreachable("access check dependent for unprivileged context"); 707 case AR_delayed: 708 llvm_unreachable("access check delayed in non-declaration"); 709 } 710 llvm_unreachable("unexpected access check result"); 711 } 712 713 /// CheckExceptionSpecSubset - Check whether the second function type's 714 /// exception specification is a subset (or equivalent) of the first function 715 /// type. This is used by override and pointer assignment checks. 716 bool Sema::CheckExceptionSpecSubset(const PartialDiagnostic &DiagID, 717 const PartialDiagnostic &NestedDiagID, 718 const PartialDiagnostic &NoteID, 719 const FunctionProtoType *Superset, 720 SourceLocation SuperLoc, 721 const FunctionProtoType *Subset, 722 SourceLocation SubLoc) { 723 724 // Just auto-succeed under -fno-exceptions. 725 if (!getLangOpts().CXXExceptions) 726 return false; 727 728 // FIXME: As usual, we could be more specific in our error messages, but 729 // that better waits until we've got types with source locations. 730 731 if (!SubLoc.isValid()) 732 SubLoc = SuperLoc; 733 734 // Resolve the exception specifications, if needed. 735 Superset = ResolveExceptionSpec(SuperLoc, Superset); 736 if (!Superset) 737 return false; 738 Subset = ResolveExceptionSpec(SubLoc, Subset); 739 if (!Subset) 740 return false; 741 742 ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType(); 743 744 // If superset contains everything, we're done. 745 if (SuperEST == EST_None || SuperEST == EST_MSAny) 746 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc, 747 Subset, SubLoc); 748 749 // If there are dependent noexcept specs, assume everything is fine. Unlike 750 // with the equivalency check, this is safe in this case, because we don't 751 // want to merge declarations. Checks after instantiation will catch any 752 // omissions we make here. 753 // We also shortcut checking if a noexcept expression was bad. 754 755 FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context); 756 if (SuperNR == FunctionProtoType::NR_BadNoexcept || 757 SuperNR == FunctionProtoType::NR_Dependent) 758 return false; 759 760 // Another case of the superset containing everything. 761 if (SuperNR == FunctionProtoType::NR_Throw) 762 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc, 763 Subset, SubLoc); 764 765 ExceptionSpecificationType SubEST = Subset->getExceptionSpecType(); 766 767 assert(!isUnresolvedExceptionSpec(SuperEST) && 768 !isUnresolvedExceptionSpec(SubEST) && 769 "Shouldn't see unknown exception specifications here"); 770 771 // It does not. If the subset contains everything, we've failed. 772 if (SubEST == EST_None || SubEST == EST_MSAny) { 773 Diag(SubLoc, DiagID); 774 if (NoteID.getDiagID() != 0) 775 Diag(SuperLoc, NoteID); 776 return true; 777 } 778 779 FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context); 780 if (SubNR == FunctionProtoType::NR_BadNoexcept || 781 SubNR == FunctionProtoType::NR_Dependent) 782 return false; 783 784 // Another case of the subset containing everything. 785 if (SubNR == FunctionProtoType::NR_Throw) { 786 Diag(SubLoc, DiagID); 787 if (NoteID.getDiagID() != 0) 788 Diag(SuperLoc, NoteID); 789 return true; 790 } 791 792 // If the subset contains nothing, we're done. 793 if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow) 794 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc, 795 Subset, SubLoc); 796 797 // Otherwise, if the superset contains nothing, we've failed. 798 if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) { 799 Diag(SubLoc, DiagID); 800 if (NoteID.getDiagID() != 0) 801 Diag(SuperLoc, NoteID); 802 return true; 803 } 804 805 assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic && 806 "Exception spec subset: non-dynamic case slipped through."); 807 808 // Neither contains everything or nothing. Do a proper comparison. 809 for (QualType SubI : Subset->exceptions()) { 810 if (const ReferenceType *RefTy = SubI->getAs<ReferenceType>()) 811 SubI = RefTy->getPointeeType(); 812 813 // Make sure it's in the superset. 814 bool Contained = false; 815 for (QualType SuperI : Superset->exceptions()) { 816 // [except.spec]p5: 817 // the target entity shall allow at least the exceptions allowed by the 818 // source 819 // 820 // We interpret this as meaning that a handler for some target type would 821 // catch an exception of each source type. 822 if (handlerCanCatch(SuperI, SubI)) { 823 Contained = true; 824 break; 825 } 826 } 827 if (!Contained) { 828 Diag(SubLoc, DiagID); 829 if (NoteID.getDiagID() != 0) 830 Diag(SuperLoc, NoteID); 831 return true; 832 } 833 } 834 // We've run half the gauntlet. 835 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc, 836 Subset, SubLoc); 837 } 838 839 static bool 840 CheckSpecForTypesEquivalent(Sema &S, const PartialDiagnostic &DiagID, 841 const PartialDiagnostic &NoteID, QualType Target, 842 SourceLocation TargetLoc, QualType Source, 843 SourceLocation SourceLoc) { 844 const FunctionProtoType *TFunc = GetUnderlyingFunction(Target); 845 if (!TFunc) 846 return false; 847 const FunctionProtoType *SFunc = GetUnderlyingFunction(Source); 848 if (!SFunc) 849 return false; 850 851 return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc, 852 SFunc, SourceLoc); 853 } 854 855 /// CheckParamExceptionSpec - Check if the parameter and return types of the 856 /// two functions have equivalent exception specs. This is part of the 857 /// assignment and override compatibility check. We do not check the parameters 858 /// of parameter function pointers recursively, as no sane programmer would 859 /// even be able to write such a function type. 860 bool Sema::CheckParamExceptionSpec(const PartialDiagnostic &DiagID, 861 const PartialDiagnostic &NoteID, 862 const FunctionProtoType *Target, 863 SourceLocation TargetLoc, 864 const FunctionProtoType *Source, 865 SourceLocation SourceLoc) { 866 auto RetDiag = DiagID; 867 RetDiag << 0; 868 if (CheckSpecForTypesEquivalent( 869 *this, RetDiag, PDiag(), 870 Target->getReturnType(), TargetLoc, Source->getReturnType(), 871 SourceLoc)) 872 return true; 873 874 // We shouldn't even be testing this unless the arguments are otherwise 875 // compatible. 876 assert(Target->getNumParams() == Source->getNumParams() && 877 "Functions have different argument counts."); 878 for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) { 879 auto ParamDiag = DiagID; 880 ParamDiag << 1; 881 if (CheckSpecForTypesEquivalent( 882 *this, ParamDiag, PDiag(), 883 Target->getParamType(i), TargetLoc, Source->getParamType(i), 884 SourceLoc)) 885 return true; 886 } 887 return false; 888 } 889 890 bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) { 891 // First we check for applicability. 892 // Target type must be a function, function pointer or function reference. 893 const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType); 894 if (!ToFunc || ToFunc->hasDependentExceptionSpec()) 895 return false; 896 897 // SourceType must be a function or function pointer. 898 const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType()); 899 if (!FromFunc || FromFunc->hasDependentExceptionSpec()) 900 return false; 901 902 unsigned DiagID = diag::err_incompatible_exception_specs; 903 unsigned NestedDiagID = diag::err_deep_exception_specs_differ; 904 // This is not an error in C++17 onwards, unless the noexceptness doesn't 905 // match, but in that case we have a full-on type mismatch, not just a 906 // type sugar mismatch. 907 if (getLangOpts().CPlusPlus17) { 908 DiagID = diag::warn_incompatible_exception_specs; 909 NestedDiagID = diag::warn_deep_exception_specs_differ; 910 } 911 912 // Now we've got the correct types on both sides, check their compatibility. 913 // This means that the source of the conversion can only throw a subset of 914 // the exceptions of the target, and any exception specs on arguments or 915 // return types must be equivalent. 916 // 917 // FIXME: If there is a nested dependent exception specification, we should 918 // not be checking it here. This is fine: 919 // template<typename T> void f() { 920 // void (*p)(void (*) throw(T)); 921 // void (*q)(void (*) throw(int)) = p; 922 // } 923 // ... because it might be instantiated with T=int. 924 return CheckExceptionSpecSubset(PDiag(DiagID), PDiag(NestedDiagID), PDiag(), 925 ToFunc, From->getSourceRange().getBegin(), 926 FromFunc, SourceLocation()) && 927 !getLangOpts().CPlusPlus17; 928 } 929 930 bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, 931 const CXXMethodDecl *Old) { 932 // If the new exception specification hasn't been parsed yet, skip the check. 933 // We'll get called again once it's been parsed. 934 if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == 935 EST_Unparsed) 936 return false; 937 if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) { 938 // Don't check uninstantiated template destructors at all. We can only 939 // synthesize correct specs after the template is instantiated. 940 if (New->getParent()->isDependentType()) 941 return false; 942 if (New->getParent()->isBeingDefined()) { 943 // The destructor might be updated once the definition is finished. So 944 // remember it and check later. 945 DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old)); 946 return false; 947 } 948 } 949 // If the old exception specification hasn't been parsed yet, remember that 950 // we need to perform this check when we get to the end of the outermost 951 // lexically-surrounding class. 952 if (Old->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() == 953 EST_Unparsed) { 954 DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old)); 955 return false; 956 } 957 unsigned DiagID = diag::err_override_exception_spec; 958 if (getLangOpts().MicrosoftExt) 959 DiagID = diag::ext_override_exception_spec; 960 return CheckExceptionSpecSubset(PDiag(DiagID), 961 PDiag(diag::err_deep_exception_specs_differ), 962 PDiag(diag::note_overridden_virtual_function), 963 Old->getType()->getAs<FunctionProtoType>(), 964 Old->getLocation(), 965 New->getType()->getAs<FunctionProtoType>(), 966 New->getLocation()); 967 } 968 969 static CanThrowResult canSubExprsThrow(Sema &S, const Expr *E) { 970 CanThrowResult R = CT_Cannot; 971 for (const Stmt *SubStmt : E->children()) { 972 R = mergeCanThrow(R, S.canThrow(cast<Expr>(SubStmt))); 973 if (R == CT_Can) 974 break; 975 } 976 return R; 977 } 978 979 static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D) { 980 // As an extension, we assume that __attribute__((nothrow)) functions don't 981 // throw. 982 if (D && isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) 983 return CT_Cannot; 984 985 QualType T; 986 987 // In C++1z, just look at the function type of the callee. 988 if (S.getLangOpts().CPlusPlus17 && isa<CallExpr>(E)) { 989 E = cast<CallExpr>(E)->getCallee(); 990 T = E->getType(); 991 if (T->isSpecificPlaceholderType(BuiltinType::BoundMember)) { 992 // Sadly we don't preserve the actual type as part of the "bound member" 993 // placeholder, so we need to reconstruct it. 994 E = E->IgnoreParenImpCasts(); 995 996 // Could be a call to a pointer-to-member or a plain member access. 997 if (auto *Op = dyn_cast<BinaryOperator>(E)) { 998 assert(Op->getOpcode() == BO_PtrMemD || Op->getOpcode() == BO_PtrMemI); 999 T = Op->getRHS()->getType() 1000 ->castAs<MemberPointerType>()->getPointeeType(); 1001 } else { 1002 T = cast<MemberExpr>(E)->getMemberDecl()->getType(); 1003 } 1004 } 1005 } else if (const ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D)) 1006 T = VD->getType(); 1007 else 1008 // If we have no clue what we're calling, assume the worst. 1009 return CT_Can; 1010 1011 const FunctionProtoType *FT; 1012 if ((FT = T->getAs<FunctionProtoType>())) { 1013 } else if (const PointerType *PT = T->getAs<PointerType>()) 1014 FT = PT->getPointeeType()->getAs<FunctionProtoType>(); 1015 else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 1016 FT = RT->getPointeeType()->getAs<FunctionProtoType>(); 1017 else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) 1018 FT = MT->getPointeeType()->getAs<FunctionProtoType>(); 1019 else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) 1020 FT = BT->getPointeeType()->getAs<FunctionProtoType>(); 1021 1022 if (!FT) 1023 return CT_Can; 1024 1025 FT = S.ResolveExceptionSpec(E->getLocStart(), FT); 1026 if (!FT) 1027 return CT_Can; 1028 1029 return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can; 1030 } 1031 1032 static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { 1033 if (DC->isTypeDependent()) 1034 return CT_Dependent; 1035 1036 if (!DC->getTypeAsWritten()->isReferenceType()) 1037 return CT_Cannot; 1038 1039 if (DC->getSubExpr()->isTypeDependent()) 1040 return CT_Dependent; 1041 1042 return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot; 1043 } 1044 1045 static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { 1046 if (DC->isTypeOperand()) 1047 return CT_Cannot; 1048 1049 Expr *Op = DC->getExprOperand(); 1050 if (Op->isTypeDependent()) 1051 return CT_Dependent; 1052 1053 const RecordType *RT = Op->getType()->getAs<RecordType>(); 1054 if (!RT) 1055 return CT_Cannot; 1056 1057 if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) 1058 return CT_Cannot; 1059 1060 if (Op->Classify(S.Context).isPRValue()) 1061 return CT_Cannot; 1062 1063 return CT_Can; 1064 } 1065 1066 CanThrowResult Sema::canThrow(const Expr *E) { 1067 // C++ [expr.unary.noexcept]p3: 1068 // [Can throw] if in a potentially-evaluated context the expression would 1069 // contain: 1070 switch (E->getStmtClass()) { 1071 case Expr::CXXThrowExprClass: 1072 // - a potentially evaluated throw-expression 1073 return CT_Can; 1074 1075 case Expr::CXXDynamicCastExprClass: { 1076 // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), 1077 // where T is a reference type, that requires a run-time check 1078 CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E)); 1079 if (CT == CT_Can) 1080 return CT; 1081 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1082 } 1083 1084 case Expr::CXXTypeidExprClass: 1085 // - a potentially evaluated typeid expression applied to a glvalue 1086 // expression whose type is a polymorphic class type 1087 return canTypeidThrow(*this, cast<CXXTypeidExpr>(E)); 1088 1089 // - a potentially evaluated call to a function, member function, function 1090 // pointer, or member function pointer that does not have a non-throwing 1091 // exception-specification 1092 case Expr::CallExprClass: 1093 case Expr::CXXMemberCallExprClass: 1094 case Expr::CXXOperatorCallExprClass: 1095 case Expr::UserDefinedLiteralClass: { 1096 const CallExpr *CE = cast<CallExpr>(E); 1097 CanThrowResult CT; 1098 if (E->isTypeDependent()) 1099 CT = CT_Dependent; 1100 else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) 1101 CT = CT_Cannot; 1102 else 1103 CT = canCalleeThrow(*this, E, CE->getCalleeDecl()); 1104 if (CT == CT_Can) 1105 return CT; 1106 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1107 } 1108 1109 case Expr::CXXConstructExprClass: 1110 case Expr::CXXTemporaryObjectExprClass: { 1111 CanThrowResult CT = canCalleeThrow(*this, E, 1112 cast<CXXConstructExpr>(E)->getConstructor()); 1113 if (CT == CT_Can) 1114 return CT; 1115 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1116 } 1117 1118 case Expr::CXXInheritedCtorInitExprClass: 1119 return canCalleeThrow(*this, E, 1120 cast<CXXInheritedCtorInitExpr>(E)->getConstructor()); 1121 1122 case Expr::LambdaExprClass: { 1123 const LambdaExpr *Lambda = cast<LambdaExpr>(E); 1124 CanThrowResult CT = CT_Cannot; 1125 for (LambdaExpr::const_capture_init_iterator 1126 Cap = Lambda->capture_init_begin(), 1127 CapEnd = Lambda->capture_init_end(); 1128 Cap != CapEnd; ++Cap) 1129 CT = mergeCanThrow(CT, canThrow(*Cap)); 1130 return CT; 1131 } 1132 1133 case Expr::CXXNewExprClass: { 1134 CanThrowResult CT; 1135 if (E->isTypeDependent()) 1136 CT = CT_Dependent; 1137 else 1138 CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew()); 1139 if (CT == CT_Can) 1140 return CT; 1141 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1142 } 1143 1144 case Expr::CXXDeleteExprClass: { 1145 CanThrowResult CT; 1146 QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType(); 1147 if (DTy.isNull() || DTy->isDependentType()) { 1148 CT = CT_Dependent; 1149 } else { 1150 CT = canCalleeThrow(*this, E, 1151 cast<CXXDeleteExpr>(E)->getOperatorDelete()); 1152 if (const RecordType *RT = DTy->getAs<RecordType>()) { 1153 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 1154 const CXXDestructorDecl *DD = RD->getDestructor(); 1155 if (DD) 1156 CT = mergeCanThrow(CT, canCalleeThrow(*this, E, DD)); 1157 } 1158 if (CT == CT_Can) 1159 return CT; 1160 } 1161 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1162 } 1163 1164 case Expr::CXXBindTemporaryExprClass: { 1165 // The bound temporary has to be destroyed again, which might throw. 1166 CanThrowResult CT = canCalleeThrow(*this, E, 1167 cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor()); 1168 if (CT == CT_Can) 1169 return CT; 1170 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1171 } 1172 1173 // ObjC message sends are like function calls, but never have exception 1174 // specs. 1175 case Expr::ObjCMessageExprClass: 1176 case Expr::ObjCPropertyRefExprClass: 1177 case Expr::ObjCSubscriptRefExprClass: 1178 return CT_Can; 1179 1180 // All the ObjC literals that are implemented as calls are 1181 // potentially throwing unless we decide to close off that 1182 // possibility. 1183 case Expr::ObjCArrayLiteralClass: 1184 case Expr::ObjCDictionaryLiteralClass: 1185 case Expr::ObjCBoxedExprClass: 1186 return CT_Can; 1187 1188 // Many other things have subexpressions, so we have to test those. 1189 // Some are simple: 1190 case Expr::CoawaitExprClass: 1191 case Expr::ConditionalOperatorClass: 1192 case Expr::CompoundLiteralExprClass: 1193 case Expr::CoyieldExprClass: 1194 case Expr::CXXConstCastExprClass: 1195 case Expr::CXXReinterpretCastExprClass: 1196 case Expr::CXXStdInitializerListExprClass: 1197 case Expr::DesignatedInitExprClass: 1198 case Expr::DesignatedInitUpdateExprClass: 1199 case Expr::ExprWithCleanupsClass: 1200 case Expr::ExtVectorElementExprClass: 1201 case Expr::InitListExprClass: 1202 case Expr::ArrayInitLoopExprClass: 1203 case Expr::MemberExprClass: 1204 case Expr::ObjCIsaExprClass: 1205 case Expr::ObjCIvarRefExprClass: 1206 case Expr::ParenExprClass: 1207 case Expr::ParenListExprClass: 1208 case Expr::ShuffleVectorExprClass: 1209 case Expr::ConvertVectorExprClass: 1210 case Expr::VAArgExprClass: 1211 return canSubExprsThrow(*this, E); 1212 1213 // Some might be dependent for other reasons. 1214 case Expr::ArraySubscriptExprClass: 1215 case Expr::OMPArraySectionExprClass: 1216 case Expr::BinaryOperatorClass: 1217 case Expr::DependentCoawaitExprClass: 1218 case Expr::CompoundAssignOperatorClass: 1219 case Expr::CStyleCastExprClass: 1220 case Expr::CXXStaticCastExprClass: 1221 case Expr::CXXFunctionalCastExprClass: 1222 case Expr::ImplicitCastExprClass: 1223 case Expr::MaterializeTemporaryExprClass: 1224 case Expr::UnaryOperatorClass: { 1225 CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot; 1226 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1227 } 1228 1229 // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms. 1230 case Expr::StmtExprClass: 1231 return CT_Can; 1232 1233 case Expr::CXXDefaultArgExprClass: 1234 return canThrow(cast<CXXDefaultArgExpr>(E)->getExpr()); 1235 1236 case Expr::CXXDefaultInitExprClass: 1237 return canThrow(cast<CXXDefaultInitExpr>(E)->getExpr()); 1238 1239 case Expr::ChooseExprClass: 1240 if (E->isTypeDependent() || E->isValueDependent()) 1241 return CT_Dependent; 1242 return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr()); 1243 1244 case Expr::GenericSelectionExprClass: 1245 if (cast<GenericSelectionExpr>(E)->isResultDependent()) 1246 return CT_Dependent; 1247 return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr()); 1248 1249 // Some expressions are always dependent. 1250 case Expr::CXXDependentScopeMemberExprClass: 1251 case Expr::CXXUnresolvedConstructExprClass: 1252 case Expr::DependentScopeDeclRefExprClass: 1253 case Expr::CXXFoldExprClass: 1254 return CT_Dependent; 1255 1256 case Expr::AsTypeExprClass: 1257 case Expr::BinaryConditionalOperatorClass: 1258 case Expr::BlockExprClass: 1259 case Expr::CUDAKernelCallExprClass: 1260 case Expr::DeclRefExprClass: 1261 case Expr::ObjCBridgedCastExprClass: 1262 case Expr::ObjCIndirectCopyRestoreExprClass: 1263 case Expr::ObjCProtocolExprClass: 1264 case Expr::ObjCSelectorExprClass: 1265 case Expr::ObjCAvailabilityCheckExprClass: 1266 case Expr::OffsetOfExprClass: 1267 case Expr::PackExpansionExprClass: 1268 case Expr::PseudoObjectExprClass: 1269 case Expr::SubstNonTypeTemplateParmExprClass: 1270 case Expr::SubstNonTypeTemplateParmPackExprClass: 1271 case Expr::FunctionParmPackExprClass: 1272 case Expr::UnaryExprOrTypeTraitExprClass: 1273 case Expr::UnresolvedLookupExprClass: 1274 case Expr::UnresolvedMemberExprClass: 1275 case Expr::TypoExprClass: 1276 // FIXME: Can any of the above throw? If so, when? 1277 return CT_Cannot; 1278 1279 case Expr::AddrLabelExprClass: 1280 case Expr::ArrayTypeTraitExprClass: 1281 case Expr::AtomicExprClass: 1282 case Expr::TypeTraitExprClass: 1283 case Expr::CXXBoolLiteralExprClass: 1284 case Expr::CXXNoexceptExprClass: 1285 case Expr::CXXNullPtrLiteralExprClass: 1286 case Expr::CXXPseudoDestructorExprClass: 1287 case Expr::CXXScalarValueInitExprClass: 1288 case Expr::CXXThisExprClass: 1289 case Expr::CXXUuidofExprClass: 1290 case Expr::CharacterLiteralClass: 1291 case Expr::ExpressionTraitExprClass: 1292 case Expr::FloatingLiteralClass: 1293 case Expr::GNUNullExprClass: 1294 case Expr::ImaginaryLiteralClass: 1295 case Expr::ImplicitValueInitExprClass: 1296 case Expr::IntegerLiteralClass: 1297 case Expr::ArrayInitIndexExprClass: 1298 case Expr::NoInitExprClass: 1299 case Expr::ObjCEncodeExprClass: 1300 case Expr::ObjCStringLiteralClass: 1301 case Expr::ObjCBoolLiteralExprClass: 1302 case Expr::OpaqueValueExprClass: 1303 case Expr::PredefinedExprClass: 1304 case Expr::SizeOfPackExprClass: 1305 case Expr::StringLiteralClass: 1306 // These expressions can never throw. 1307 return CT_Cannot; 1308 1309 case Expr::MSPropertyRefExprClass: 1310 case Expr::MSPropertySubscriptExprClass: 1311 llvm_unreachable("Invalid class for expression"); 1312 1313 #define STMT(CLASS, PARENT) case Expr::CLASS##Class: 1314 #define STMT_RANGE(Base, First, Last) 1315 #define LAST_STMT_RANGE(BASE, FIRST, LAST) 1316 #define EXPR(CLASS, PARENT) 1317 #define ABSTRACT_STMT(STMT) 1318 #include "clang/AST/StmtNodes.inc" 1319 case Expr::NoStmtClass: 1320 llvm_unreachable("Invalid class for expression"); 1321 } 1322 llvm_unreachable("Bogus StmtClass"); 1323 } 1324 1325 } // end namespace clang 1326