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