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