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