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