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/Basic/Diagnostic.h" 20 #include "clang/Basic/SourceManager.h" 21 #include "clang/Lex/Preprocessor.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 /// Determine whether a function has an implicitly-generated exception 136 /// specification. 137 static bool hasImplicitExceptionSpec(FunctionDecl *Decl) { 138 if (!isa<CXXDestructorDecl>(Decl) && 139 Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete && 140 Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) 141 return false; 142 143 // If the user didn't declare the function, its exception specification must 144 // be implicit. 145 if (!Decl->getTypeSourceInfo()) 146 return true; 147 148 const FunctionProtoType *Ty = 149 Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>(); 150 return !Ty->hasExceptionSpec(); 151 } 152 153 bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { 154 OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator(); 155 bool IsOperatorNew = OO == OO_New || OO == OO_Array_New; 156 bool MissingExceptionSpecification = false; 157 bool MissingEmptyExceptionSpecification = false; 158 unsigned DiagID = diag::err_mismatched_exception_spec; 159 if (getLangOpts().MicrosoftExt) 160 DiagID = diag::warn_mismatched_exception_spec; 161 162 // Check the types as written: they must match before any exception 163 // specification adjustment is applied. 164 if (!CheckEquivalentExceptionSpec( 165 PDiag(DiagID), PDiag(diag::note_previous_declaration), 166 Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(), 167 New->getType()->getAs<FunctionProtoType>(), New->getLocation(), 168 &MissingExceptionSpecification, &MissingEmptyExceptionSpecification, 169 /*AllowNoexceptAllMatchWithNoSpec=*/true, IsOperatorNew)) { 170 // C++11 [except.spec]p4 [DR1492]: 171 // If a declaration of a function has an implicit 172 // exception-specification, other declarations of the function shall 173 // not specify an exception-specification. 174 if (getLangOpts().CPlusPlus11 && 175 hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) { 176 Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch) 177 << hasImplicitExceptionSpec(Old); 178 if (!Old->getLocation().isInvalid()) 179 Diag(Old->getLocation(), diag::note_previous_declaration); 180 } 181 return false; 182 } 183 184 // The failure was something other than an empty exception 185 // specification; return an error. 186 if (!MissingExceptionSpecification && !MissingEmptyExceptionSpecification) 187 return true; 188 189 const FunctionProtoType *NewProto = 190 New->getType()->getAs<FunctionProtoType>(); 191 192 // The new function declaration is only missing an empty exception 193 // specification "throw()". If the throw() specification came from a 194 // function in a system header that has C linkage, just add an empty 195 // exception specification to the "new" declaration. This is an 196 // egregious workaround for glibc, which adds throw() specifications 197 // to many libc functions as an optimization. Unfortunately, that 198 // optimization isn't permitted by the C++ standard, so we're forced 199 // to work around it here. 200 if (MissingEmptyExceptionSpecification && NewProto && 201 (Old->getLocation().isInvalid() || 202 Context.getSourceManager().isInSystemHeader(Old->getLocation())) && 203 Old->isExternC()) { 204 FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); 205 EPI.ExceptionSpecType = EST_DynamicNone; 206 QualType NewType = Context.getFunctionType(NewProto->getResultType(), 207 NewProto->getArgTypes(), EPI); 208 New->setType(NewType); 209 return false; 210 } 211 212 if (MissingExceptionSpecification && NewProto) { 213 const FunctionProtoType *OldProto = 214 Old->getType()->getAs<FunctionProtoType>(); 215 216 FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); 217 EPI.ExceptionSpecType = OldProto->getExceptionSpecType(); 218 if (EPI.ExceptionSpecType == EST_Dynamic) { 219 EPI.NumExceptions = OldProto->getNumExceptions(); 220 EPI.Exceptions = OldProto->exception_begin(); 221 } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { 222 // FIXME: We can't just take the expression from the old prototype. It 223 // likely contains references to the old prototype's parameters. 224 } 225 226 // Update the type of the function with the appropriate exception 227 // specification. 228 QualType NewType = Context.getFunctionType(NewProto->getResultType(), 229 NewProto->getArgTypes(), EPI); 230 New->setType(NewType); 231 232 // If exceptions are disabled, suppress the warning about missing 233 // exception specifications for new and delete operators. 234 if (!getLangOpts().CXXExceptions) { 235 switch (New->getDeclName().getCXXOverloadedOperator()) { 236 case OO_New: 237 case OO_Array_New: 238 case OO_Delete: 239 case OO_Array_Delete: 240 if (New->getDeclContext()->isTranslationUnit()) 241 return false; 242 break; 243 244 default: 245 break; 246 } 247 } 248 249 // Warn about the lack of exception specification. 250 SmallString<128> ExceptionSpecString; 251 llvm::raw_svector_ostream OS(ExceptionSpecString); 252 switch (OldProto->getExceptionSpecType()) { 253 case EST_DynamicNone: 254 OS << "throw()"; 255 break; 256 257 case EST_Dynamic: { 258 OS << "throw("; 259 bool OnFirstException = true; 260 for (FunctionProtoType::exception_iterator E = OldProto->exception_begin(), 261 EEnd = OldProto->exception_end(); 262 E != EEnd; 263 ++E) { 264 if (OnFirstException) 265 OnFirstException = false; 266 else 267 OS << ", "; 268 269 OS << E->getAsString(getPrintingPolicy()); 270 } 271 OS << ")"; 272 break; 273 } 274 275 case EST_BasicNoexcept: 276 OS << "noexcept"; 277 break; 278 279 case EST_ComputedNoexcept: 280 OS << "noexcept("; 281 OldProto->getNoexceptExpr()->printPretty(OS, 0, getPrintingPolicy()); 282 OS << ")"; 283 break; 284 285 default: 286 llvm_unreachable("This spec type is compatible with none."); 287 } 288 OS.flush(); 289 290 SourceLocation FixItLoc; 291 if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) { 292 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); 293 if (FunctionTypeLoc FTLoc = TL.getAs<FunctionTypeLoc>()) 294 FixItLoc = PP.getLocForEndOfToken(FTLoc.getLocalRangeEnd()); 295 } 296 297 if (FixItLoc.isInvalid()) 298 Diag(New->getLocation(), diag::warn_missing_exception_specification) 299 << New << OS.str(); 300 else { 301 // FIXME: This will get more complicated with C++0x 302 // late-specified return types. 303 Diag(New->getLocation(), diag::warn_missing_exception_specification) 304 << New << OS.str() 305 << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str()); 306 } 307 308 if (!Old->getLocation().isInvalid()) 309 Diag(Old->getLocation(), diag::note_previous_declaration); 310 311 return false; 312 } 313 314 Diag(New->getLocation(), DiagID); 315 Diag(Old->getLocation(), diag::note_previous_declaration); 316 return true; 317 } 318 319 /// CheckEquivalentExceptionSpec - Check if the two types have equivalent 320 /// exception specifications. Exception specifications are equivalent if 321 /// they allow exactly the same set of exception types. It does not matter how 322 /// that is achieved. See C++ [except.spec]p2. 323 bool Sema::CheckEquivalentExceptionSpec( 324 const FunctionProtoType *Old, SourceLocation OldLoc, 325 const FunctionProtoType *New, SourceLocation NewLoc) { 326 unsigned DiagID = diag::err_mismatched_exception_spec; 327 if (getLangOpts().MicrosoftExt) 328 DiagID = diag::warn_mismatched_exception_spec; 329 return CheckEquivalentExceptionSpec(PDiag(DiagID), 330 PDiag(diag::note_previous_declaration), 331 Old, OldLoc, New, NewLoc); 332 } 333 334 /// CheckEquivalentExceptionSpec - Check if the two types have compatible 335 /// exception specifications. See C++ [except.spec]p3. 336 /// 337 /// \return \c false if the exception specifications match, \c true if there is 338 /// a problem. If \c true is returned, either a diagnostic has already been 339 /// produced or \c *MissingExceptionSpecification is set to \c true. 340 bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, 341 const PartialDiagnostic & NoteID, 342 const FunctionProtoType *Old, 343 SourceLocation OldLoc, 344 const FunctionProtoType *New, 345 SourceLocation NewLoc, 346 bool *MissingExceptionSpecification, 347 bool*MissingEmptyExceptionSpecification, 348 bool AllowNoexceptAllMatchWithNoSpec, 349 bool IsOperatorNew) { 350 // Just completely ignore this under -fno-exceptions. 351 if (!getLangOpts().CXXExceptions) 352 return false; 353 354 if (MissingExceptionSpecification) 355 *MissingExceptionSpecification = false; 356 357 if (MissingEmptyExceptionSpecification) 358 *MissingEmptyExceptionSpecification = false; 359 360 Old = ResolveExceptionSpec(NewLoc, Old); 361 if (!Old) 362 return false; 363 New = ResolveExceptionSpec(NewLoc, New); 364 if (!New) 365 return false; 366 367 // C++0x [except.spec]p3: Two exception-specifications are compatible if: 368 // - both are non-throwing, regardless of their form, 369 // - both have the form noexcept(constant-expression) and the constant- 370 // expressions are equivalent, 371 // - both are dynamic-exception-specifications that have the same set of 372 // adjusted types. 373 // 374 // C++0x [except.spec]p12: An exception-specifcation is non-throwing if it is 375 // of the form throw(), noexcept, or noexcept(constant-expression) where the 376 // constant-expression yields true. 377 // 378 // C++0x [except.spec]p4: If any declaration of a function has an exception- 379 // specifier that is not a noexcept-specification allowing all exceptions, 380 // all declarations [...] of that function shall have a compatible 381 // exception-specification. 382 // 383 // That last point basically means that noexcept(false) matches no spec. 384 // It's considered when AllowNoexceptAllMatchWithNoSpec is true. 385 386 ExceptionSpecificationType OldEST = Old->getExceptionSpecType(); 387 ExceptionSpecificationType NewEST = New->getExceptionSpecType(); 388 389 assert(!isUnresolvedExceptionSpec(OldEST) && 390 !isUnresolvedExceptionSpec(NewEST) && 391 "Shouldn't see unknown exception specifications here"); 392 393 // Shortcut the case where both have no spec. 394 if (OldEST == EST_None && NewEST == EST_None) 395 return false; 396 397 FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(Context); 398 FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(Context); 399 if (OldNR == FunctionProtoType::NR_BadNoexcept || 400 NewNR == FunctionProtoType::NR_BadNoexcept) 401 return false; 402 403 // Dependent noexcept specifiers are compatible with each other, but nothing 404 // else. 405 // One noexcept is compatible with another if the argument is the same 406 if (OldNR == NewNR && 407 OldNR != FunctionProtoType::NR_NoNoexcept && 408 NewNR != FunctionProtoType::NR_NoNoexcept) 409 return false; 410 if (OldNR != NewNR && 411 OldNR != FunctionProtoType::NR_NoNoexcept && 412 NewNR != FunctionProtoType::NR_NoNoexcept) { 413 Diag(NewLoc, DiagID); 414 if (NoteID.getDiagID() != 0) 415 Diag(OldLoc, NoteID); 416 return true; 417 } 418 419 // The MS extension throw(...) is compatible with itself. 420 if (OldEST == EST_MSAny && NewEST == EST_MSAny) 421 return false; 422 423 // It's also compatible with no spec. 424 if ((OldEST == EST_None && NewEST == EST_MSAny) || 425 (OldEST == EST_MSAny && NewEST == EST_None)) 426 return false; 427 428 // It's also compatible with noexcept(false). 429 if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw) 430 return false; 431 if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw) 432 return false; 433 434 // As described above, noexcept(false) matches no spec only for functions. 435 if (AllowNoexceptAllMatchWithNoSpec) { 436 if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw) 437 return false; 438 if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw) 439 return false; 440 } 441 442 // Any non-throwing specifications are compatible. 443 bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow || 444 OldEST == EST_DynamicNone; 445 bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow || 446 NewEST == EST_DynamicNone; 447 if (OldNonThrowing && NewNonThrowing) 448 return false; 449 450 // As a special compatibility feature, under C++0x we accept no spec and 451 // throw(std::bad_alloc) as equivalent for operator new and operator new[]. 452 // This is because the implicit declaration changed, but old code would break. 453 if (getLangOpts().CPlusPlus11 && IsOperatorNew) { 454 const FunctionProtoType *WithExceptions = 0; 455 if (OldEST == EST_None && NewEST == EST_Dynamic) 456 WithExceptions = New; 457 else if (OldEST == EST_Dynamic && NewEST == EST_None) 458 WithExceptions = Old; 459 if (WithExceptions && WithExceptions->getNumExceptions() == 1) { 460 // One has no spec, the other throw(something). If that something is 461 // std::bad_alloc, all conditions are met. 462 QualType Exception = *WithExceptions->exception_begin(); 463 if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) { 464 IdentifierInfo* Name = ExRecord->getIdentifier(); 465 if (Name && Name->getName() == "bad_alloc") { 466 // It's called bad_alloc, but is it in std? 467 DeclContext* DC = ExRecord->getDeclContext(); 468 DC = DC->getEnclosingNamespaceContext(); 469 if (NamespaceDecl* NS = dyn_cast<NamespaceDecl>(DC)) { 470 IdentifierInfo* NSName = NS->getIdentifier(); 471 DC = DC->getParent(); 472 if (NSName && NSName->getName() == "std" && 473 DC->getEnclosingNamespaceContext()->isTranslationUnit()) { 474 return false; 475 } 476 } 477 } 478 } 479 } 480 } 481 482 // At this point, the only remaining valid case is two matching dynamic 483 // specifications. We return here unless both specifications are dynamic. 484 if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) { 485 if (MissingExceptionSpecification && Old->hasExceptionSpec() && 486 !New->hasExceptionSpec()) { 487 // The old type has an exception specification of some sort, but 488 // the new type does not. 489 *MissingExceptionSpecification = true; 490 491 if (MissingEmptyExceptionSpecification && OldNonThrowing) { 492 // The old type has a throw() or noexcept(true) exception specification 493 // and the new type has no exception specification, and the caller asked 494 // to handle this itself. 495 *MissingEmptyExceptionSpecification = true; 496 } 497 498 return true; 499 } 500 501 Diag(NewLoc, DiagID); 502 if (NoteID.getDiagID() != 0) 503 Diag(OldLoc, NoteID); 504 return true; 505 } 506 507 assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic && 508 "Exception compatibility logic error: non-dynamic spec slipped through."); 509 510 bool Success = true; 511 // Both have a dynamic exception spec. Collect the first set, then compare 512 // to the second. 513 llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes; 514 for (FunctionProtoType::exception_iterator I = Old->exception_begin(), 515 E = Old->exception_end(); I != E; ++I) 516 OldTypes.insert(Context.getCanonicalType(*I).getUnqualifiedType()); 517 518 for (FunctionProtoType::exception_iterator I = New->exception_begin(), 519 E = New->exception_end(); I != E && Success; ++I) { 520 CanQualType TypePtr = Context.getCanonicalType(*I).getUnqualifiedType(); 521 if(OldTypes.count(TypePtr)) 522 NewTypes.insert(TypePtr); 523 else 524 Success = false; 525 } 526 527 Success = Success && OldTypes.size() == NewTypes.size(); 528 529 if (Success) { 530 return false; 531 } 532 Diag(NewLoc, DiagID); 533 if (NoteID.getDiagID() != 0) 534 Diag(OldLoc, NoteID); 535 return true; 536 } 537 538 /// CheckExceptionSpecSubset - Check whether the second function type's 539 /// exception specification is a subset (or equivalent) of the first function 540 /// type. This is used by override and pointer assignment checks. 541 bool Sema::CheckExceptionSpecSubset( 542 const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, 543 const FunctionProtoType *Superset, SourceLocation SuperLoc, 544 const FunctionProtoType *Subset, SourceLocation SubLoc) { 545 546 // Just auto-succeed under -fno-exceptions. 547 if (!getLangOpts().CXXExceptions) 548 return false; 549 550 // FIXME: As usual, we could be more specific in our error messages, but 551 // that better waits until we've got types with source locations. 552 553 if (!SubLoc.isValid()) 554 SubLoc = SuperLoc; 555 556 // Resolve the exception specifications, if needed. 557 Superset = ResolveExceptionSpec(SuperLoc, Superset); 558 if (!Superset) 559 return false; 560 Subset = ResolveExceptionSpec(SubLoc, Subset); 561 if (!Subset) 562 return false; 563 564 ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType(); 565 566 // If superset contains everything, we're done. 567 if (SuperEST == EST_None || SuperEST == EST_MSAny) 568 return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 569 570 // If there are dependent noexcept specs, assume everything is fine. Unlike 571 // with the equivalency check, this is safe in this case, because we don't 572 // want to merge declarations. Checks after instantiation will catch any 573 // omissions we make here. 574 // We also shortcut checking if a noexcept expression was bad. 575 576 FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context); 577 if (SuperNR == FunctionProtoType::NR_BadNoexcept || 578 SuperNR == FunctionProtoType::NR_Dependent) 579 return false; 580 581 // Another case of the superset containing everything. 582 if (SuperNR == FunctionProtoType::NR_Throw) 583 return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 584 585 ExceptionSpecificationType SubEST = Subset->getExceptionSpecType(); 586 587 assert(!isUnresolvedExceptionSpec(SuperEST) && 588 !isUnresolvedExceptionSpec(SubEST) && 589 "Shouldn't see unknown exception specifications here"); 590 591 // It does not. If the subset contains everything, we've failed. 592 if (SubEST == EST_None || SubEST == EST_MSAny) { 593 Diag(SubLoc, DiagID); 594 if (NoteID.getDiagID() != 0) 595 Diag(SuperLoc, NoteID); 596 return true; 597 } 598 599 FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context); 600 if (SubNR == FunctionProtoType::NR_BadNoexcept || 601 SubNR == FunctionProtoType::NR_Dependent) 602 return false; 603 604 // Another case of the subset containing everything. 605 if (SubNR == FunctionProtoType::NR_Throw) { 606 Diag(SubLoc, DiagID); 607 if (NoteID.getDiagID() != 0) 608 Diag(SuperLoc, NoteID); 609 return true; 610 } 611 612 // If the subset contains nothing, we're done. 613 if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow) 614 return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 615 616 // Otherwise, if the superset contains nothing, we've failed. 617 if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) { 618 Diag(SubLoc, DiagID); 619 if (NoteID.getDiagID() != 0) 620 Diag(SuperLoc, NoteID); 621 return true; 622 } 623 624 assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic && 625 "Exception spec subset: non-dynamic case slipped through."); 626 627 // Neither contains everything or nothing. Do a proper comparison. 628 for (FunctionProtoType::exception_iterator SubI = Subset->exception_begin(), 629 SubE = Subset->exception_end(); SubI != SubE; ++SubI) { 630 // Take one type from the subset. 631 QualType CanonicalSubT = Context.getCanonicalType(*SubI); 632 // Unwrap pointers and references so that we can do checks within a class 633 // hierarchy. Don't unwrap member pointers; they don't have hierarchy 634 // conversions on the pointee. 635 bool SubIsPointer = false; 636 if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>()) 637 CanonicalSubT = RefTy->getPointeeType(); 638 if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) { 639 CanonicalSubT = PtrTy->getPointeeType(); 640 SubIsPointer = true; 641 } 642 bool SubIsClass = CanonicalSubT->isRecordType(); 643 CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType(); 644 645 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 646 /*DetectVirtual=*/false); 647 648 bool Contained = false; 649 // Make sure it's in the superset. 650 for (FunctionProtoType::exception_iterator SuperI = 651 Superset->exception_begin(), SuperE = Superset->exception_end(); 652 SuperI != SuperE; ++SuperI) { 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(*this, 738 PDiag(diag::err_deep_exception_specs_differ) << 0, 739 PDiag(), 740 Target->getResultType(), TargetLoc, 741 Source->getResultType(), SourceLoc)) 742 return true; 743 744 // We shouldn't even be testing this unless the arguments are otherwise 745 // compatible. 746 assert(Target->getNumArgs() == Source->getNumArgs() && 747 "Functions have different argument counts."); 748 for (unsigned i = 0, E = Target->getNumArgs(); i != E; ++i) { 749 if (CheckSpecForTypesEquivalent(*this, 750 PDiag(diag::err_deep_exception_specs_differ) << 1, 751 PDiag(), 752 Target->getArgType(i), TargetLoc, 753 Source->getArgType(i), SourceLoc)) 754 return true; 755 } 756 return false; 757 } 758 759 bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) 760 { 761 // First we check for applicability. 762 // Target type must be a function, function pointer or function reference. 763 const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType); 764 if (!ToFunc) 765 return false; 766 767 // SourceType must be a function or function pointer. 768 const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType()); 769 if (!FromFunc) 770 return false; 771 772 // Now we've got the correct types on both sides, check their compatibility. 773 // This means that the source of the conversion can only throw a subset of 774 // the exceptions of the target, and any exception specs on arguments or 775 // return types must be equivalent. 776 return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs), 777 PDiag(), ToFunc, 778 From->getSourceRange().getBegin(), 779 FromFunc, SourceLocation()); 780 } 781 782 bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, 783 const CXXMethodDecl *Old) { 784 if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) { 785 // Don't check uninstantiated template destructors at all. We can only 786 // synthesize correct specs after the template is instantiated. 787 if (New->getParent()->isDependentType()) 788 return false; 789 if (New->getParent()->isBeingDefined()) { 790 // The destructor might be updated once the definition is finished. So 791 // remember it and check later. 792 DelayedDestructorExceptionSpecChecks.push_back(std::make_pair( 793 cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old))); 794 return false; 795 } 796 } 797 unsigned DiagID = diag::err_override_exception_spec; 798 if (getLangOpts().MicrosoftExt) 799 DiagID = diag::warn_override_exception_spec; 800 return CheckExceptionSpecSubset(PDiag(DiagID), 801 PDiag(diag::note_overridden_virtual_function), 802 Old->getType()->getAs<FunctionProtoType>(), 803 Old->getLocation(), 804 New->getType()->getAs<FunctionProtoType>(), 805 New->getLocation()); 806 } 807 808 static CanThrowResult canSubExprsThrow(Sema &S, const Expr *CE) { 809 Expr *E = const_cast<Expr*>(CE); 810 CanThrowResult R = CT_Cannot; 811 for (Expr::child_range I = E->children(); I && R != CT_Can; ++I) 812 R = mergeCanThrow(R, S.canThrow(cast<Expr>(*I))); 813 return R; 814 } 815 816 static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, 817 const Decl *D, 818 bool NullThrows = true) { 819 if (!D) 820 return NullThrows ? CT_Can : CT_Cannot; 821 822 // See if we can get a function type from the decl somehow. 823 const ValueDecl *VD = dyn_cast<ValueDecl>(D); 824 if (!VD) // If we have no clue what we're calling, assume the worst. 825 return CT_Can; 826 827 // As an extension, we assume that __attribute__((nothrow)) functions don't 828 // throw. 829 if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) 830 return CT_Cannot; 831 832 QualType T = VD->getType(); 833 const FunctionProtoType *FT; 834 if ((FT = T->getAs<FunctionProtoType>())) { 835 } else if (const PointerType *PT = T->getAs<PointerType>()) 836 FT = PT->getPointeeType()->getAs<FunctionProtoType>(); 837 else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 838 FT = RT->getPointeeType()->getAs<FunctionProtoType>(); 839 else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) 840 FT = MT->getPointeeType()->getAs<FunctionProtoType>(); 841 else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) 842 FT = BT->getPointeeType()->getAs<FunctionProtoType>(); 843 844 if (!FT) 845 return CT_Can; 846 847 FT = S.ResolveExceptionSpec(E->getLocStart(), FT); 848 if (!FT) 849 return CT_Can; 850 851 return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can; 852 } 853 854 static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { 855 if (DC->isTypeDependent()) 856 return CT_Dependent; 857 858 if (!DC->getTypeAsWritten()->isReferenceType()) 859 return CT_Cannot; 860 861 if (DC->getSubExpr()->isTypeDependent()) 862 return CT_Dependent; 863 864 return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot; 865 } 866 867 static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { 868 if (DC->isTypeOperand()) 869 return CT_Cannot; 870 871 Expr *Op = DC->getExprOperand(); 872 if (Op->isTypeDependent()) 873 return CT_Dependent; 874 875 const RecordType *RT = Op->getType()->getAs<RecordType>(); 876 if (!RT) 877 return CT_Cannot; 878 879 if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) 880 return CT_Cannot; 881 882 if (Op->Classify(S.Context).isPRValue()) 883 return CT_Cannot; 884 885 return CT_Can; 886 } 887 888 CanThrowResult Sema::canThrow(const Expr *E) { 889 // C++ [expr.unary.noexcept]p3: 890 // [Can throw] if in a potentially-evaluated context the expression would 891 // contain: 892 switch (E->getStmtClass()) { 893 case Expr::CXXThrowExprClass: 894 // - a potentially evaluated throw-expression 895 return CT_Can; 896 897 case Expr::CXXDynamicCastExprClass: { 898 // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), 899 // where T is a reference type, that requires a run-time check 900 CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E)); 901 if (CT == CT_Can) 902 return CT; 903 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 904 } 905 906 case Expr::CXXTypeidExprClass: 907 // - a potentially evaluated typeid expression applied to a glvalue 908 // expression whose type is a polymorphic class type 909 return canTypeidThrow(*this, cast<CXXTypeidExpr>(E)); 910 911 // - a potentially evaluated call to a function, member function, function 912 // pointer, or member function pointer that does not have a non-throwing 913 // exception-specification 914 case Expr::CallExprClass: 915 case Expr::CXXMemberCallExprClass: 916 case Expr::CXXOperatorCallExprClass: 917 case Expr::UserDefinedLiteralClass: { 918 const CallExpr *CE = cast<CallExpr>(E); 919 CanThrowResult CT; 920 if (E->isTypeDependent()) 921 CT = CT_Dependent; 922 else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) 923 CT = CT_Cannot; 924 else 925 CT = canCalleeThrow(*this, E, CE->getCalleeDecl()); 926 if (CT == CT_Can) 927 return CT; 928 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 929 } 930 931 case Expr::CXXConstructExprClass: 932 case Expr::CXXTemporaryObjectExprClass: { 933 CanThrowResult CT = canCalleeThrow(*this, E, 934 cast<CXXConstructExpr>(E)->getConstructor()); 935 if (CT == CT_Can) 936 return CT; 937 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 938 } 939 940 case Expr::LambdaExprClass: { 941 const LambdaExpr *Lambda = cast<LambdaExpr>(E); 942 CanThrowResult CT = CT_Cannot; 943 for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(), 944 CapEnd = Lambda->capture_init_end(); 945 Cap != CapEnd; ++Cap) 946 CT = mergeCanThrow(CT, canThrow(*Cap)); 947 return CT; 948 } 949 950 case Expr::CXXNewExprClass: { 951 CanThrowResult CT; 952 if (E->isTypeDependent()) 953 CT = CT_Dependent; 954 else 955 CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew()); 956 if (CT == CT_Can) 957 return CT; 958 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 959 } 960 961 case Expr::CXXDeleteExprClass: { 962 CanThrowResult CT; 963 QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType(); 964 if (DTy.isNull() || DTy->isDependentType()) { 965 CT = CT_Dependent; 966 } else { 967 CT = canCalleeThrow(*this, E, 968 cast<CXXDeleteExpr>(E)->getOperatorDelete()); 969 if (const RecordType *RT = DTy->getAs<RecordType>()) { 970 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 971 CT = mergeCanThrow(CT, canCalleeThrow(*this, E, RD->getDestructor())); 972 } 973 if (CT == CT_Can) 974 return CT; 975 } 976 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 977 } 978 979 case Expr::CXXBindTemporaryExprClass: { 980 // The bound temporary has to be destroyed again, which might throw. 981 CanThrowResult CT = canCalleeThrow(*this, E, 982 cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor()); 983 if (CT == CT_Can) 984 return CT; 985 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 986 } 987 988 // ObjC message sends are like function calls, but never have exception 989 // specs. 990 case Expr::ObjCMessageExprClass: 991 case Expr::ObjCPropertyRefExprClass: 992 case Expr::ObjCSubscriptRefExprClass: 993 return CT_Can; 994 995 // All the ObjC literals that are implemented as calls are 996 // potentially throwing unless we decide to close off that 997 // possibility. 998 case Expr::ObjCArrayLiteralClass: 999 case Expr::ObjCDictionaryLiteralClass: 1000 case Expr::ObjCBoxedExprClass: 1001 return CT_Can; 1002 1003 // Many other things have subexpressions, so we have to test those. 1004 // Some are simple: 1005 case Expr::ConditionalOperatorClass: 1006 case Expr::CompoundLiteralExprClass: 1007 case Expr::CXXConstCastExprClass: 1008 case Expr::CXXReinterpretCastExprClass: 1009 case Expr::CXXStdInitializerListExprClass: 1010 case Expr::DesignatedInitExprClass: 1011 case Expr::ExprWithCleanupsClass: 1012 case Expr::ExtVectorElementExprClass: 1013 case Expr::InitListExprClass: 1014 case Expr::MemberExprClass: 1015 case Expr::ObjCIsaExprClass: 1016 case Expr::ObjCIvarRefExprClass: 1017 case Expr::ParenExprClass: 1018 case Expr::ParenListExprClass: 1019 case Expr::ShuffleVectorExprClass: 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(Context)); 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::BinaryTypeTraitExprClass: 1088 case Expr::TypeTraitExprClass: 1089 case Expr::CXXBoolLiteralExprClass: 1090 case Expr::CXXNoexceptExprClass: 1091 case Expr::CXXNullPtrLiteralExprClass: 1092 case Expr::CXXPseudoDestructorExprClass: 1093 case Expr::CXXScalarValueInitExprClass: 1094 case Expr::CXXThisExprClass: 1095 case Expr::CXXUuidofExprClass: 1096 case Expr::CharacterLiteralClass: 1097 case Expr::ExpressionTraitExprClass: 1098 case Expr::FloatingLiteralClass: 1099 case Expr::GNUNullExprClass: 1100 case Expr::ImaginaryLiteralClass: 1101 case Expr::ImplicitValueInitExprClass: 1102 case Expr::IntegerLiteralClass: 1103 case Expr::ObjCEncodeExprClass: 1104 case Expr::ObjCStringLiteralClass: 1105 case Expr::ObjCBoolLiteralExprClass: 1106 case Expr::OpaqueValueExprClass: 1107 case Expr::PredefinedExprClass: 1108 case Expr::SizeOfPackExprClass: 1109 case Expr::StringLiteralClass: 1110 case Expr::UnaryTypeTraitExprClass: 1111 // These expressions can never throw. 1112 return CT_Cannot; 1113 1114 case Expr::MSPropertyRefExprClass: 1115 llvm_unreachable("Invalid class for expression"); 1116 1117 #define STMT(CLASS, PARENT) case Expr::CLASS##Class: 1118 #define STMT_RANGE(Base, First, Last) 1119 #define LAST_STMT_RANGE(BASE, FIRST, LAST) 1120 #define EXPR(CLASS, PARENT) 1121 #define ABSTRACT_STMT(STMT) 1122 #include "clang/AST/StmtNodes.inc" 1123 case Expr::NoStmtClass: 1124 llvm_unreachable("Invalid class for expression"); 1125 } 1126 llvm_unreachable("Bogus StmtClass"); 1127 } 1128 1129 } // end namespace clang 1130