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