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