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