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