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