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