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