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