clang API Documentation
00001 //===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides Sema routines for C++ exception specification testing. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/Sema/SemaInternal.h" 00015 #include "clang/AST/CXXInheritance.h" 00016 #include "clang/AST/Expr.h" 00017 #include "clang/AST/ExprCXX.h" 00018 #include "clang/AST/TypeLoc.h" 00019 #include "clang/Lex/Preprocessor.h" 00020 #include "clang/Basic/Diagnostic.h" 00021 #include "clang/Basic/SourceManager.h" 00022 #include "llvm/ADT/SmallPtrSet.h" 00023 #include "llvm/ADT/SmallString.h" 00024 00025 namespace clang { 00026 00027 static const FunctionProtoType *GetUnderlyingFunction(QualType T) 00028 { 00029 if (const PointerType *PtrTy = T->getAs<PointerType>()) 00030 T = PtrTy->getPointeeType(); 00031 else if (const ReferenceType *RefTy = T->getAs<ReferenceType>()) 00032 T = RefTy->getPointeeType(); 00033 else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) 00034 T = MPTy->getPointeeType(); 00035 return T->getAs<FunctionProtoType>(); 00036 } 00037 00038 /// CheckSpecifiedExceptionType - Check if the given type is valid in an 00039 /// exception specification. Incomplete types, or pointers to incomplete types 00040 /// other than void are not allowed. 00041 bool Sema::CheckSpecifiedExceptionType(QualType T, const SourceRange &Range) { 00042 00043 // This check (and the similar one below) deals with issue 437, that changes 00044 // C++ 9.2p2 this way: 00045 // Within the class member-specification, the class is regarded as complete 00046 // within function bodies, default arguments, exception-specifications, and 00047 // constructor ctor-initializers (including such things in nested classes). 00048 if (T->isRecordType() && T->getAs<RecordType>()->isBeingDefined()) 00049 return false; 00050 00051 // C++ 15.4p2: A type denoted in an exception-specification shall not denote 00052 // an incomplete type. 00053 if (RequireCompleteType(Range.getBegin(), T, 00054 diag::err_incomplete_in_exception_spec, 00055 /*direct*/0, Range)) 00056 return true; 00057 00058 // C++ 15.4p2: A type denoted in an exception-specification shall not denote 00059 // an incomplete type a pointer or reference to an incomplete type, other 00060 // than (cv) void*. 00061 int kind; 00062 if (const PointerType* IT = T->getAs<PointerType>()) { 00063 T = IT->getPointeeType(); 00064 kind = 1; 00065 } else if (const ReferenceType* IT = T->getAs<ReferenceType>()) { 00066 T = IT->getPointeeType(); 00067 kind = 2; 00068 } else 00069 return false; 00070 00071 // Again as before 00072 if (T->isRecordType() && T->getAs<RecordType>()->isBeingDefined()) 00073 return false; 00074 00075 if (!T->isVoidType() && 00076 RequireCompleteType(Range.getBegin(), T, 00077 diag::err_incomplete_in_exception_spec, kind, Range)) 00078 return true; 00079 00080 return false; 00081 } 00082 00083 /// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer 00084 /// to member to a function with an exception specification. This means that 00085 /// it is invalid to add another level of indirection. 00086 bool Sema::CheckDistantExceptionSpec(QualType T) { 00087 if (const PointerType *PT = T->getAs<PointerType>()) 00088 T = PT->getPointeeType(); 00089 else if (const MemberPointerType *PT = T->getAs<MemberPointerType>()) 00090 T = PT->getPointeeType(); 00091 else 00092 return false; 00093 00094 const FunctionProtoType *FnT = T->getAs<FunctionProtoType>(); 00095 if (!FnT) 00096 return false; 00097 00098 return FnT->hasExceptionSpec(); 00099 } 00100 00101 const FunctionProtoType * 00102 Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) { 00103 // FIXME: If FD is a special member, we should delay computing its exception 00104 // specification until this point. 00105 if (FPT->getExceptionSpecType() != EST_Uninstantiated) 00106 return FPT; 00107 00108 FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl(); 00109 const FunctionProtoType *SourceFPT = 00110 SourceDecl->getType()->castAs<FunctionProtoType>(); 00111 00112 if (SourceFPT->getExceptionSpecType() != EST_Uninstantiated) 00113 return SourceFPT; 00114 00115 // Instantiate the exception specification now. 00116 InstantiateExceptionSpec(Loc, SourceDecl); 00117 00118 return SourceDecl->getType()->castAs<FunctionProtoType>(); 00119 } 00120 00121 bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { 00122 OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator(); 00123 bool IsOperatorNew = OO == OO_New || OO == OO_Array_New; 00124 bool MissingExceptionSpecification = false; 00125 bool MissingEmptyExceptionSpecification = false; 00126 unsigned DiagID = diag::err_mismatched_exception_spec; 00127 if (getLangOpts().MicrosoftExt) 00128 DiagID = diag::warn_mismatched_exception_spec; 00129 00130 if (!CheckEquivalentExceptionSpec(PDiag(DiagID), 00131 PDiag(diag::note_previous_declaration), 00132 Old->getType()->getAs<FunctionProtoType>(), 00133 Old->getLocation(), 00134 New->getType()->getAs<FunctionProtoType>(), 00135 New->getLocation(), 00136 &MissingExceptionSpecification, 00137 &MissingEmptyExceptionSpecification, 00138 /*AllowNoexceptAllMatchWithNoSpec=*/true, 00139 IsOperatorNew)) 00140 return false; 00141 00142 // The failure was something other than an empty exception 00143 // specification; return an error. 00144 if (!MissingExceptionSpecification && !MissingEmptyExceptionSpecification) 00145 return true; 00146 00147 const FunctionProtoType *NewProto 00148 = New->getType()->getAs<FunctionProtoType>(); 00149 00150 // The new function declaration is only missing an empty exception 00151 // specification "throw()". If the throw() specification came from a 00152 // function in a system header that has C linkage, just add an empty 00153 // exception specification to the "new" declaration. This is an 00154 // egregious workaround for glibc, which adds throw() specifications 00155 // to many libc functions as an optimization. Unfortunately, that 00156 // optimization isn't permitted by the C++ standard, so we're forced 00157 // to work around it here. 00158 if (MissingEmptyExceptionSpecification && NewProto && 00159 (Old->getLocation().isInvalid() || 00160 Context.getSourceManager().isInSystemHeader(Old->getLocation())) && 00161 Old->isExternC()) { 00162 FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); 00163 EPI.ExceptionSpecType = EST_DynamicNone; 00164 QualType NewType = Context.getFunctionType(NewProto->getResultType(), 00165 NewProto->arg_type_begin(), 00166 NewProto->getNumArgs(), 00167 EPI); 00168 New->setType(NewType); 00169 return false; 00170 } 00171 00172 if (MissingExceptionSpecification && NewProto) { 00173 const FunctionProtoType *OldProto 00174 = Old->getType()->getAs<FunctionProtoType>(); 00175 00176 FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); 00177 EPI.ExceptionSpecType = OldProto->getExceptionSpecType(); 00178 if (EPI.ExceptionSpecType == EST_Dynamic) { 00179 EPI.NumExceptions = OldProto->getNumExceptions(); 00180 EPI.Exceptions = OldProto->exception_begin(); 00181 } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { 00182 // FIXME: We can't just take the expression from the old prototype. It 00183 // likely contains references to the old prototype's parameters. 00184 } 00185 00186 // Update the type of the function with the appropriate exception 00187 // specification. 00188 QualType NewType = Context.getFunctionType(NewProto->getResultType(), 00189 NewProto->arg_type_begin(), 00190 NewProto->getNumArgs(), 00191 EPI); 00192 New->setType(NewType); 00193 00194 // If exceptions are disabled, suppress the warning about missing 00195 // exception specifications for new and delete operators. 00196 if (!getLangOpts().CXXExceptions) { 00197 switch (New->getDeclName().getCXXOverloadedOperator()) { 00198 case OO_New: 00199 case OO_Array_New: 00200 case OO_Delete: 00201 case OO_Array_Delete: 00202 if (New->getDeclContext()->isTranslationUnit()) 00203 return false; 00204 break; 00205 00206 default: 00207 break; 00208 } 00209 } 00210 00211 // Warn about the lack of exception specification. 00212 SmallString<128> ExceptionSpecString; 00213 llvm::raw_svector_ostream OS(ExceptionSpecString); 00214 switch (OldProto->getExceptionSpecType()) { 00215 case EST_DynamicNone: 00216 OS << "throw()"; 00217 break; 00218 00219 case EST_Dynamic: { 00220 OS << "throw("; 00221 bool OnFirstException = true; 00222 for (FunctionProtoType::exception_iterator E = OldProto->exception_begin(), 00223 EEnd = OldProto->exception_end(); 00224 E != EEnd; 00225 ++E) { 00226 if (OnFirstException) 00227 OnFirstException = false; 00228 else 00229 OS << ", "; 00230 00231 OS << E->getAsString(getPrintingPolicy()); 00232 } 00233 OS << ")"; 00234 break; 00235 } 00236 00237 case EST_BasicNoexcept: 00238 OS << "noexcept"; 00239 break; 00240 00241 case EST_ComputedNoexcept: 00242 OS << "noexcept("; 00243 OldProto->getNoexceptExpr()->printPretty(OS, Context, 0, 00244 getPrintingPolicy()); 00245 OS << ")"; 00246 break; 00247 00248 default: 00249 llvm_unreachable("This spec type is compatible with none."); 00250 } 00251 OS.flush(); 00252 00253 SourceLocation FixItLoc; 00254 if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) { 00255 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); 00256 if (const FunctionTypeLoc *FTLoc = dyn_cast<FunctionTypeLoc>(&TL)) 00257 FixItLoc = PP.getLocForEndOfToken(FTLoc->getLocalRangeEnd()); 00258 } 00259 00260 if (FixItLoc.isInvalid()) 00261 Diag(New->getLocation(), diag::warn_missing_exception_specification) 00262 << New << OS.str(); 00263 else { 00264 // FIXME: This will get more complicated with C++0x 00265 // late-specified return types. 00266 Diag(New->getLocation(), diag::warn_missing_exception_specification) 00267 << New << OS.str() 00268 << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str()); 00269 } 00270 00271 if (!Old->getLocation().isInvalid()) 00272 Diag(Old->getLocation(), diag::note_previous_declaration); 00273 00274 return false; 00275 } 00276 00277 Diag(New->getLocation(), DiagID); 00278 Diag(Old->getLocation(), diag::note_previous_declaration); 00279 return true; 00280 } 00281 00282 /// CheckEquivalentExceptionSpec - Check if the two types have equivalent 00283 /// exception specifications. Exception specifications are equivalent if 00284 /// they allow exactly the same set of exception types. It does not matter how 00285 /// that is achieved. See C++ [except.spec]p2. 00286 bool Sema::CheckEquivalentExceptionSpec( 00287 const FunctionProtoType *Old, SourceLocation OldLoc, 00288 const FunctionProtoType *New, SourceLocation NewLoc) { 00289 unsigned DiagID = diag::err_mismatched_exception_spec; 00290 if (getLangOpts().MicrosoftExt) 00291 DiagID = diag::warn_mismatched_exception_spec; 00292 return CheckEquivalentExceptionSpec( 00293 PDiag(DiagID), 00294 PDiag(diag::note_previous_declaration), 00295 Old, OldLoc, New, NewLoc); 00296 } 00297 00298 /// CheckEquivalentExceptionSpec - Check if the two types have compatible 00299 /// exception specifications. See C++ [except.spec]p3. 00300 bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, 00301 const PartialDiagnostic & NoteID, 00302 const FunctionProtoType *Old, 00303 SourceLocation OldLoc, 00304 const FunctionProtoType *New, 00305 SourceLocation NewLoc, 00306 bool *MissingExceptionSpecification, 00307 bool*MissingEmptyExceptionSpecification, 00308 bool AllowNoexceptAllMatchWithNoSpec, 00309 bool IsOperatorNew) { 00310 // Just completely ignore this under -fno-exceptions. 00311 if (!getLangOpts().CXXExceptions) 00312 return false; 00313 00314 if (MissingExceptionSpecification) 00315 *MissingExceptionSpecification = false; 00316 00317 if (MissingEmptyExceptionSpecification) 00318 *MissingEmptyExceptionSpecification = false; 00319 00320 Old = ResolveExceptionSpec(NewLoc, Old); 00321 if (!Old) 00322 return false; 00323 New = ResolveExceptionSpec(NewLoc, New); 00324 if (!New) 00325 return false; 00326 00327 // C++0x [except.spec]p3: Two exception-specifications are compatible if: 00328 // - both are non-throwing, regardless of their form, 00329 // - both have the form noexcept(constant-expression) and the constant- 00330 // expressions are equivalent, 00331 // - both are dynamic-exception-specifications that have the same set of 00332 // adjusted types. 00333 // 00334 // C++0x [except.spec]p12: An exception-specifcation is non-throwing if it is 00335 // of the form throw(), noexcept, or noexcept(constant-expression) where the 00336 // constant-expression yields true. 00337 // 00338 // C++0x [except.spec]p4: If any declaration of a function has an exception- 00339 // specifier that is not a noexcept-specification allowing all exceptions, 00340 // all declarations [...] of that function shall have a compatible 00341 // exception-specification. 00342 // 00343 // That last point basically means that noexcept(false) matches no spec. 00344 // It's considered when AllowNoexceptAllMatchWithNoSpec is true. 00345 00346 ExceptionSpecificationType OldEST = Old->getExceptionSpecType(); 00347 ExceptionSpecificationType NewEST = New->getExceptionSpecType(); 00348 00349 assert(OldEST != EST_Delayed && NewEST != EST_Delayed && 00350 OldEST != EST_Uninstantiated && NewEST != EST_Uninstantiated && 00351 "Shouldn't see unknown exception specifications here"); 00352 00353 // Shortcut the case where both have no spec. 00354 if (OldEST == EST_None && NewEST == EST_None) 00355 return false; 00356 00357 FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(Context); 00358 FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(Context); 00359 if (OldNR == FunctionProtoType::NR_BadNoexcept || 00360 NewNR == FunctionProtoType::NR_BadNoexcept) 00361 return false; 00362 00363 // Dependent noexcept specifiers are compatible with each other, but nothing 00364 // else. 00365 // One noexcept is compatible with another if the argument is the same 00366 if (OldNR == NewNR && 00367 OldNR != FunctionProtoType::NR_NoNoexcept && 00368 NewNR != FunctionProtoType::NR_NoNoexcept) 00369 return false; 00370 if (OldNR != NewNR && 00371 OldNR != FunctionProtoType::NR_NoNoexcept && 00372 NewNR != FunctionProtoType::NR_NoNoexcept) { 00373 Diag(NewLoc, DiagID); 00374 if (NoteID.getDiagID() != 0) 00375 Diag(OldLoc, NoteID); 00376 return true; 00377 } 00378 00379 // The MS extension throw(...) is compatible with itself. 00380 if (OldEST == EST_MSAny && NewEST == EST_MSAny) 00381 return false; 00382 00383 // It's also compatible with no spec. 00384 if ((OldEST == EST_None && NewEST == EST_MSAny) || 00385 (OldEST == EST_MSAny && NewEST == EST_None)) 00386 return false; 00387 00388 // It's also compatible with noexcept(false). 00389 if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw) 00390 return false; 00391 if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw) 00392 return false; 00393 00394 // As described above, noexcept(false) matches no spec only for functions. 00395 if (AllowNoexceptAllMatchWithNoSpec) { 00396 if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw) 00397 return false; 00398 if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw) 00399 return false; 00400 } 00401 00402 // Any non-throwing specifications are compatible. 00403 bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow || 00404 OldEST == EST_DynamicNone; 00405 bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow || 00406 NewEST == EST_DynamicNone; 00407 if (OldNonThrowing && NewNonThrowing) 00408 return false; 00409 00410 // As a special compatibility feature, under C++0x we accept no spec and 00411 // throw(std::bad_alloc) as equivalent for operator new and operator new[]. 00412 // This is because the implicit declaration changed, but old code would break. 00413 if (getLangOpts().CPlusPlus0x && IsOperatorNew) { 00414 const FunctionProtoType *WithExceptions = 0; 00415 if (OldEST == EST_None && NewEST == EST_Dynamic) 00416 WithExceptions = New; 00417 else if (OldEST == EST_Dynamic && NewEST == EST_None) 00418 WithExceptions = Old; 00419 if (WithExceptions && WithExceptions->getNumExceptions() == 1) { 00420 // One has no spec, the other throw(something). If that something is 00421 // std::bad_alloc, all conditions are met. 00422 QualType Exception = *WithExceptions->exception_begin(); 00423 if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) { 00424 IdentifierInfo* Name = ExRecord->getIdentifier(); 00425 if (Name && Name->getName() == "bad_alloc") { 00426 // It's called bad_alloc, but is it in std? 00427 DeclContext* DC = ExRecord->getDeclContext(); 00428 DC = DC->getEnclosingNamespaceContext(); 00429 if (NamespaceDecl* NS = dyn_cast<NamespaceDecl>(DC)) { 00430 IdentifierInfo* NSName = NS->getIdentifier(); 00431 DC = DC->getParent(); 00432 if (NSName && NSName->getName() == "std" && 00433 DC->getEnclosingNamespaceContext()->isTranslationUnit()) { 00434 return false; 00435 } 00436 } 00437 } 00438 } 00439 } 00440 } 00441 00442 // At this point, the only remaining valid case is two matching dynamic 00443 // specifications. We return here unless both specifications are dynamic. 00444 if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) { 00445 if (MissingExceptionSpecification && Old->hasExceptionSpec() && 00446 !New->hasExceptionSpec()) { 00447 // The old type has an exception specification of some sort, but 00448 // the new type does not. 00449 *MissingExceptionSpecification = true; 00450 00451 if (MissingEmptyExceptionSpecification && OldNonThrowing) { 00452 // The old type has a throw() or noexcept(true) exception specification 00453 // and the new type has no exception specification, and the caller asked 00454 // to handle this itself. 00455 *MissingEmptyExceptionSpecification = true; 00456 } 00457 00458 return true; 00459 } 00460 00461 Diag(NewLoc, DiagID); 00462 if (NoteID.getDiagID() != 0) 00463 Diag(OldLoc, NoteID); 00464 return true; 00465 } 00466 00467 assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic && 00468 "Exception compatibility logic error: non-dynamic spec slipped through."); 00469 00470 bool Success = true; 00471 // Both have a dynamic exception spec. Collect the first set, then compare 00472 // to the second. 00473 llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes; 00474 for (FunctionProtoType::exception_iterator I = Old->exception_begin(), 00475 E = Old->exception_end(); I != E; ++I) 00476 OldTypes.insert(Context.getCanonicalType(*I).getUnqualifiedType()); 00477 00478 for (FunctionProtoType::exception_iterator I = New->exception_begin(), 00479 E = New->exception_end(); I != E && Success; ++I) { 00480 CanQualType TypePtr = Context.getCanonicalType(*I).getUnqualifiedType(); 00481 if(OldTypes.count(TypePtr)) 00482 NewTypes.insert(TypePtr); 00483 else 00484 Success = false; 00485 } 00486 00487 Success = Success && OldTypes.size() == NewTypes.size(); 00488 00489 if (Success) { 00490 return false; 00491 } 00492 Diag(NewLoc, DiagID); 00493 if (NoteID.getDiagID() != 0) 00494 Diag(OldLoc, NoteID); 00495 return true; 00496 } 00497 00498 /// CheckExceptionSpecSubset - Check whether the second function type's 00499 /// exception specification is a subset (or equivalent) of the first function 00500 /// type. This is used by override and pointer assignment checks. 00501 bool Sema::CheckExceptionSpecSubset( 00502 const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, 00503 const FunctionProtoType *Superset, SourceLocation SuperLoc, 00504 const FunctionProtoType *Subset, SourceLocation SubLoc) { 00505 00506 // Just auto-succeed under -fno-exceptions. 00507 if (!getLangOpts().CXXExceptions) 00508 return false; 00509 00510 // FIXME: As usual, we could be more specific in our error messages, but 00511 // that better waits until we've got types with source locations. 00512 00513 if (!SubLoc.isValid()) 00514 SubLoc = SuperLoc; 00515 00516 // Resolve the exception specifications, if needed. 00517 Superset = ResolveExceptionSpec(SuperLoc, Superset); 00518 if (!Superset) 00519 return false; 00520 Subset = ResolveExceptionSpec(SubLoc, Subset); 00521 if (!Subset) 00522 return false; 00523 00524 ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType(); 00525 00526 // If superset contains everything, we're done. 00527 if (SuperEST == EST_None || SuperEST == EST_MSAny) 00528 return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 00529 00530 // If there are dependent noexcept specs, assume everything is fine. Unlike 00531 // with the equivalency check, this is safe in this case, because we don't 00532 // want to merge declarations. Checks after instantiation will catch any 00533 // omissions we make here. 00534 // We also shortcut checking if a noexcept expression was bad. 00535 00536 FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context); 00537 if (SuperNR == FunctionProtoType::NR_BadNoexcept || 00538 SuperNR == FunctionProtoType::NR_Dependent) 00539 return false; 00540 00541 // Another case of the superset containing everything. 00542 if (SuperNR == FunctionProtoType::NR_Throw) 00543 return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 00544 00545 ExceptionSpecificationType SubEST = Subset->getExceptionSpecType(); 00546 00547 assert(SuperEST != EST_Delayed && SubEST != EST_Delayed && 00548 SuperEST != EST_Uninstantiated && SubEST != EST_Uninstantiated && 00549 "Shouldn't see unknown exception specifications here"); 00550 00551 // It does not. If the subset contains everything, we've failed. 00552 if (SubEST == EST_None || SubEST == EST_MSAny) { 00553 Diag(SubLoc, DiagID); 00554 if (NoteID.getDiagID() != 0) 00555 Diag(SuperLoc, NoteID); 00556 return true; 00557 } 00558 00559 FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context); 00560 if (SubNR == FunctionProtoType::NR_BadNoexcept || 00561 SubNR == FunctionProtoType::NR_Dependent) 00562 return false; 00563 00564 // Another case of the subset containing everything. 00565 if (SubNR == FunctionProtoType::NR_Throw) { 00566 Diag(SubLoc, DiagID); 00567 if (NoteID.getDiagID() != 0) 00568 Diag(SuperLoc, NoteID); 00569 return true; 00570 } 00571 00572 // If the subset contains nothing, we're done. 00573 if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow) 00574 return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 00575 00576 // Otherwise, if the superset contains nothing, we've failed. 00577 if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) { 00578 Diag(SubLoc, DiagID); 00579 if (NoteID.getDiagID() != 0) 00580 Diag(SuperLoc, NoteID); 00581 return true; 00582 } 00583 00584 assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic && 00585 "Exception spec subset: non-dynamic case slipped through."); 00586 00587 // Neither contains everything or nothing. Do a proper comparison. 00588 for (FunctionProtoType::exception_iterator SubI = Subset->exception_begin(), 00589 SubE = Subset->exception_end(); SubI != SubE; ++SubI) { 00590 // Take one type from the subset. 00591 QualType CanonicalSubT = Context.getCanonicalType(*SubI); 00592 // Unwrap pointers and references so that we can do checks within a class 00593 // hierarchy. Don't unwrap member pointers; they don't have hierarchy 00594 // conversions on the pointee. 00595 bool SubIsPointer = false; 00596 if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>()) 00597 CanonicalSubT = RefTy->getPointeeType(); 00598 if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) { 00599 CanonicalSubT = PtrTy->getPointeeType(); 00600 SubIsPointer = true; 00601 } 00602 bool SubIsClass = CanonicalSubT->isRecordType(); 00603 CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType(); 00604 00605 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 00606 /*DetectVirtual=*/false); 00607 00608 bool Contained = false; 00609 // Make sure it's in the superset. 00610 for (FunctionProtoType::exception_iterator SuperI = 00611 Superset->exception_begin(), SuperE = Superset->exception_end(); 00612 SuperI != SuperE; ++SuperI) { 00613 QualType CanonicalSuperT = Context.getCanonicalType(*SuperI); 00614 // SubT must be SuperT or derived from it, or pointer or reference to 00615 // such types. 00616 if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>()) 00617 CanonicalSuperT = RefTy->getPointeeType(); 00618 if (SubIsPointer) { 00619 if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>()) 00620 CanonicalSuperT = PtrTy->getPointeeType(); 00621 else { 00622 continue; 00623 } 00624 } 00625 CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType(); 00626 // If the types are the same, move on to the next type in the subset. 00627 if (CanonicalSubT == CanonicalSuperT) { 00628 Contained = true; 00629 break; 00630 } 00631 00632 // Otherwise we need to check the inheritance. 00633 if (!SubIsClass || !CanonicalSuperT->isRecordType()) 00634 continue; 00635 00636 Paths.clear(); 00637 if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths)) 00638 continue; 00639 00640 if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT))) 00641 continue; 00642 00643 // Do this check from a context without privileges. 00644 switch (CheckBaseClassAccess(SourceLocation(), 00645 CanonicalSuperT, CanonicalSubT, 00646 Paths.front(), 00647 /*Diagnostic*/ 0, 00648 /*ForceCheck*/ true, 00649 /*ForceUnprivileged*/ true)) { 00650 case AR_accessible: break; 00651 case AR_inaccessible: continue; 00652 case AR_dependent: 00653 llvm_unreachable("access check dependent for unprivileged context"); 00654 case AR_delayed: 00655 llvm_unreachable("access check delayed in non-declaration"); 00656 } 00657 00658 Contained = true; 00659 break; 00660 } 00661 if (!Contained) { 00662 Diag(SubLoc, DiagID); 00663 if (NoteID.getDiagID() != 0) 00664 Diag(SuperLoc, NoteID); 00665 return true; 00666 } 00667 } 00668 // We've run half the gauntlet. 00669 return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 00670 } 00671 00672 static bool CheckSpecForTypesEquivalent(Sema &S, 00673 const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, 00674 QualType Target, SourceLocation TargetLoc, 00675 QualType Source, SourceLocation SourceLoc) 00676 { 00677 const FunctionProtoType *TFunc = GetUnderlyingFunction(Target); 00678 if (!TFunc) 00679 return false; 00680 const FunctionProtoType *SFunc = GetUnderlyingFunction(Source); 00681 if (!SFunc) 00682 return false; 00683 00684 return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc, 00685 SFunc, SourceLoc); 00686 } 00687 00688 /// CheckParamExceptionSpec - Check if the parameter and return types of the 00689 /// two functions have equivalent exception specs. This is part of the 00690 /// assignment and override compatibility check. We do not check the parameters 00691 /// of parameter function pointers recursively, as no sane programmer would 00692 /// even be able to write such a function type. 00693 bool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID, 00694 const FunctionProtoType *Target, SourceLocation TargetLoc, 00695 const FunctionProtoType *Source, SourceLocation SourceLoc) 00696 { 00697 if (CheckSpecForTypesEquivalent(*this, 00698 PDiag(diag::err_deep_exception_specs_differ) << 0, 00699 PDiag(), 00700 Target->getResultType(), TargetLoc, 00701 Source->getResultType(), SourceLoc)) 00702 return true; 00703 00704 // We shouldn't even be testing this unless the arguments are otherwise 00705 // compatible. 00706 assert(Target->getNumArgs() == Source->getNumArgs() && 00707 "Functions have different argument counts."); 00708 for (unsigned i = 0, E = Target->getNumArgs(); i != E; ++i) { 00709 if (CheckSpecForTypesEquivalent(*this, 00710 PDiag(diag::err_deep_exception_specs_differ) << 1, 00711 PDiag(), 00712 Target->getArgType(i), TargetLoc, 00713 Source->getArgType(i), SourceLoc)) 00714 return true; 00715 } 00716 return false; 00717 } 00718 00719 bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) 00720 { 00721 // First we check for applicability. 00722 // Target type must be a function, function pointer or function reference. 00723 const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType); 00724 if (!ToFunc) 00725 return false; 00726 00727 // SourceType must be a function or function pointer. 00728 const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType()); 00729 if (!FromFunc) 00730 return false; 00731 00732 // Now we've got the correct types on both sides, check their compatibility. 00733 // This means that the source of the conversion can only throw a subset of 00734 // the exceptions of the target, and any exception specs on arguments or 00735 // return types must be equivalent. 00736 return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs), 00737 PDiag(), ToFunc, 00738 From->getSourceRange().getBegin(), 00739 FromFunc, SourceLocation()); 00740 } 00741 00742 bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, 00743 const CXXMethodDecl *Old) { 00744 if (getLangOpts().CPlusPlus0x && isa<CXXDestructorDecl>(New)) { 00745 // Don't check uninstantiated template destructors at all. We can only 00746 // synthesize correct specs after the template is instantiated. 00747 if (New->getParent()->isDependentType()) 00748 return false; 00749 if (New->getParent()->isBeingDefined()) { 00750 // The destructor might be updated once the definition is finished. So 00751 // remember it and check later. 00752 DelayedDestructorExceptionSpecChecks.push_back(std::make_pair( 00753 cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old))); 00754 return false; 00755 } 00756 } 00757 unsigned DiagID = diag::err_override_exception_spec; 00758 if (getLangOpts().MicrosoftExt) 00759 DiagID = diag::warn_override_exception_spec; 00760 return CheckExceptionSpecSubset(PDiag(DiagID), 00761 PDiag(diag::note_overridden_virtual_function), 00762 Old->getType()->getAs<FunctionProtoType>(), 00763 Old->getLocation(), 00764 New->getType()->getAs<FunctionProtoType>(), 00765 New->getLocation()); 00766 } 00767 00768 static CanThrowResult canSubExprsThrow(Sema &S, const Expr *CE) { 00769 Expr *E = const_cast<Expr*>(CE); 00770 CanThrowResult R = CT_Cannot; 00771 for (Expr::child_range I = E->children(); I && R != CT_Can; ++I) 00772 R = mergeCanThrow(R, S.canThrow(cast<Expr>(*I))); 00773 return R; 00774 } 00775 00776 static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, 00777 const Decl *D, 00778 bool NullThrows = true) { 00779 if (!D) 00780 return NullThrows ? CT_Can : CT_Cannot; 00781 00782 // See if we can get a function type from the decl somehow. 00783 const ValueDecl *VD = dyn_cast<ValueDecl>(D); 00784 if (!VD) // If we have no clue what we're calling, assume the worst. 00785 return CT_Can; 00786 00787 // As an extension, we assume that __attribute__((nothrow)) functions don't 00788 // throw. 00789 if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) 00790 return CT_Cannot; 00791 00792 QualType T = VD->getType(); 00793 const FunctionProtoType *FT; 00794 if ((FT = T->getAs<FunctionProtoType>())) { 00795 } else if (const PointerType *PT = T->getAs<PointerType>()) 00796 FT = PT->getPointeeType()->getAs<FunctionProtoType>(); 00797 else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 00798 FT = RT->getPointeeType()->getAs<FunctionProtoType>(); 00799 else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) 00800 FT = MT->getPointeeType()->getAs<FunctionProtoType>(); 00801 else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) 00802 FT = BT->getPointeeType()->getAs<FunctionProtoType>(); 00803 00804 if (!FT) 00805 return CT_Can; 00806 00807 FT = S.ResolveExceptionSpec(E->getLocStart(), FT); 00808 if (!FT) 00809 return CT_Can; 00810 00811 if (FT->getExceptionSpecType() == EST_Delayed) { 00812 // FIXME: Try to resolve a delayed exception spec in ResolveExceptionSpec. 00813 assert(isa<CXXConstructorDecl>(D) && 00814 "only constructor exception specs can be unknown"); 00815 S.Diag(E->getLocStart(), diag::err_exception_spec_unknown) 00816 << E->getSourceRange(); 00817 return CT_Can; 00818 } 00819 00820 return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can; 00821 } 00822 00823 static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { 00824 if (DC->isTypeDependent()) 00825 return CT_Dependent; 00826 00827 if (!DC->getTypeAsWritten()->isReferenceType()) 00828 return CT_Cannot; 00829 00830 if (DC->getSubExpr()->isTypeDependent()) 00831 return CT_Dependent; 00832 00833 return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot; 00834 } 00835 00836 static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { 00837 if (DC->isTypeOperand()) 00838 return CT_Cannot; 00839 00840 Expr *Op = DC->getExprOperand(); 00841 if (Op->isTypeDependent()) 00842 return CT_Dependent; 00843 00844 const RecordType *RT = Op->getType()->getAs<RecordType>(); 00845 if (!RT) 00846 return CT_Cannot; 00847 00848 if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) 00849 return CT_Cannot; 00850 00851 if (Op->Classify(S.Context).isPRValue()) 00852 return CT_Cannot; 00853 00854 return CT_Can; 00855 } 00856 00857 CanThrowResult Sema::canThrow(const Expr *E) { 00858 // C++ [expr.unary.noexcept]p3: 00859 // [Can throw] if in a potentially-evaluated context the expression would 00860 // contain: 00861 switch (E->getStmtClass()) { 00862 case Expr::CXXThrowExprClass: 00863 // - a potentially evaluated throw-expression 00864 return CT_Can; 00865 00866 case Expr::CXXDynamicCastExprClass: { 00867 // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), 00868 // where T is a reference type, that requires a run-time check 00869 CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E)); 00870 if (CT == CT_Can) 00871 return CT; 00872 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 00873 } 00874 00875 case Expr::CXXTypeidExprClass: 00876 // - a potentially evaluated typeid expression applied to a glvalue 00877 // expression whose type is a polymorphic class type 00878 return canTypeidThrow(*this, cast<CXXTypeidExpr>(E)); 00879 00880 // - a potentially evaluated call to a function, member function, function 00881 // pointer, or member function pointer that does not have a non-throwing 00882 // exception-specification 00883 case Expr::CallExprClass: 00884 case Expr::CXXMemberCallExprClass: 00885 case Expr::CXXOperatorCallExprClass: 00886 case Expr::UserDefinedLiteralClass: { 00887 const CallExpr *CE = cast<CallExpr>(E); 00888 CanThrowResult CT; 00889 if (E->isTypeDependent()) 00890 CT = CT_Dependent; 00891 else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) 00892 CT = CT_Cannot; 00893 else 00894 CT = canCalleeThrow(*this, E, CE->getCalleeDecl()); 00895 if (CT == CT_Can) 00896 return CT; 00897 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 00898 } 00899 00900 case Expr::CXXConstructExprClass: 00901 case Expr::CXXTemporaryObjectExprClass: { 00902 CanThrowResult CT = canCalleeThrow(*this, E, 00903 cast<CXXConstructExpr>(E)->getConstructor()); 00904 if (CT == CT_Can) 00905 return CT; 00906 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 00907 } 00908 00909 case Expr::LambdaExprClass: { 00910 const LambdaExpr *Lambda = cast<LambdaExpr>(E); 00911 CanThrowResult CT = CT_Cannot; 00912 for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(), 00913 CapEnd = Lambda->capture_init_end(); 00914 Cap != CapEnd; ++Cap) 00915 CT = mergeCanThrow(CT, canThrow(*Cap)); 00916 return CT; 00917 } 00918 00919 case Expr::CXXNewExprClass: { 00920 CanThrowResult CT; 00921 if (E->isTypeDependent()) 00922 CT = CT_Dependent; 00923 else 00924 CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew()); 00925 if (CT == CT_Can) 00926 return CT; 00927 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 00928 } 00929 00930 case Expr::CXXDeleteExprClass: { 00931 CanThrowResult CT; 00932 QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType(); 00933 if (DTy.isNull() || DTy->isDependentType()) { 00934 CT = CT_Dependent; 00935 } else { 00936 CT = canCalleeThrow(*this, E, 00937 cast<CXXDeleteExpr>(E)->getOperatorDelete()); 00938 if (const RecordType *RT = DTy->getAs<RecordType>()) { 00939 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 00940 CT = mergeCanThrow(CT, canCalleeThrow(*this, E, RD->getDestructor())); 00941 } 00942 if (CT == CT_Can) 00943 return CT; 00944 } 00945 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 00946 } 00947 00948 case Expr::CXXBindTemporaryExprClass: { 00949 // The bound temporary has to be destroyed again, which might throw. 00950 CanThrowResult CT = canCalleeThrow(*this, E, 00951 cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor()); 00952 if (CT == CT_Can) 00953 return CT; 00954 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 00955 } 00956 00957 // ObjC message sends are like function calls, but never have exception 00958 // specs. 00959 case Expr::ObjCMessageExprClass: 00960 case Expr::ObjCPropertyRefExprClass: 00961 case Expr::ObjCSubscriptRefExprClass: 00962 return CT_Can; 00963 00964 // All the ObjC literals that are implemented as calls are 00965 // potentially throwing unless we decide to close off that 00966 // possibility. 00967 case Expr::ObjCArrayLiteralClass: 00968 case Expr::ObjCDictionaryLiteralClass: 00969 case Expr::ObjCBoxedExprClass: 00970 return CT_Can; 00971 00972 // Many other things have subexpressions, so we have to test those. 00973 // Some are simple: 00974 case Expr::ConditionalOperatorClass: 00975 case Expr::CompoundLiteralExprClass: 00976 case Expr::CXXConstCastExprClass: 00977 case Expr::CXXDefaultArgExprClass: 00978 case Expr::CXXReinterpretCastExprClass: 00979 case Expr::DesignatedInitExprClass: 00980 case Expr::ExprWithCleanupsClass: 00981 case Expr::ExtVectorElementExprClass: 00982 case Expr::InitListExprClass: 00983 case Expr::MemberExprClass: 00984 case Expr::ObjCIsaExprClass: 00985 case Expr::ObjCIvarRefExprClass: 00986 case Expr::ParenExprClass: 00987 case Expr::ParenListExprClass: 00988 case Expr::ShuffleVectorExprClass: 00989 case Expr::VAArgExprClass: 00990 return canSubExprsThrow(*this, E); 00991 00992 // Some might be dependent for other reasons. 00993 case Expr::ArraySubscriptExprClass: 00994 case Expr::BinaryOperatorClass: 00995 case Expr::CompoundAssignOperatorClass: 00996 case Expr::CStyleCastExprClass: 00997 case Expr::CXXStaticCastExprClass: 00998 case Expr::CXXFunctionalCastExprClass: 00999 case Expr::ImplicitCastExprClass: 01000 case Expr::MaterializeTemporaryExprClass: 01001 case Expr::UnaryOperatorClass: { 01002 CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot; 01003 return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 01004 } 01005 01006 // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms. 01007 case Expr::StmtExprClass: 01008 return CT_Can; 01009 01010 case Expr::ChooseExprClass: 01011 if (E->isTypeDependent() || E->isValueDependent()) 01012 return CT_Dependent; 01013 return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr(Context)); 01014 01015 case Expr::GenericSelectionExprClass: 01016 if (cast<GenericSelectionExpr>(E)->isResultDependent()) 01017 return CT_Dependent; 01018 return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr()); 01019 01020 // Some expressions are always dependent. 01021 case Expr::CXXDependentScopeMemberExprClass: 01022 case Expr::CXXUnresolvedConstructExprClass: 01023 case Expr::DependentScopeDeclRefExprClass: 01024 return CT_Dependent; 01025 01026 case Expr::AsTypeExprClass: 01027 case Expr::BinaryConditionalOperatorClass: 01028 case Expr::BlockExprClass: 01029 case Expr::CUDAKernelCallExprClass: 01030 case Expr::DeclRefExprClass: 01031 case Expr::ObjCBridgedCastExprClass: 01032 case Expr::ObjCIndirectCopyRestoreExprClass: 01033 case Expr::ObjCProtocolExprClass: 01034 case Expr::ObjCSelectorExprClass: 01035 case Expr::OffsetOfExprClass: 01036 case Expr::PackExpansionExprClass: 01037 case Expr::PseudoObjectExprClass: 01038 case Expr::SubstNonTypeTemplateParmExprClass: 01039 case Expr::SubstNonTypeTemplateParmPackExprClass: 01040 case Expr::UnaryExprOrTypeTraitExprClass: 01041 case Expr::UnresolvedLookupExprClass: 01042 case Expr::UnresolvedMemberExprClass: 01043 // FIXME: Can any of the above throw? If so, when? 01044 return CT_Cannot; 01045 01046 case Expr::AddrLabelExprClass: 01047 case Expr::ArrayTypeTraitExprClass: 01048 case Expr::AtomicExprClass: 01049 case Expr::BinaryTypeTraitExprClass: 01050 case Expr::TypeTraitExprClass: 01051 case Expr::CXXBoolLiteralExprClass: 01052 case Expr::CXXNoexceptExprClass: 01053 case Expr::CXXNullPtrLiteralExprClass: 01054 case Expr::CXXPseudoDestructorExprClass: 01055 case Expr::CXXScalarValueInitExprClass: 01056 case Expr::CXXThisExprClass: 01057 case Expr::CXXUuidofExprClass: 01058 case Expr::CharacterLiteralClass: 01059 case Expr::ExpressionTraitExprClass: 01060 case Expr::FloatingLiteralClass: 01061 case Expr::GNUNullExprClass: 01062 case Expr::ImaginaryLiteralClass: 01063 case Expr::ImplicitValueInitExprClass: 01064 case Expr::IntegerLiteralClass: 01065 case Expr::ObjCEncodeExprClass: 01066 case Expr::ObjCStringLiteralClass: 01067 case Expr::ObjCBoolLiteralExprClass: 01068 case Expr::OpaqueValueExprClass: 01069 case Expr::PredefinedExprClass: 01070 case Expr::SizeOfPackExprClass: 01071 case Expr::StringLiteralClass: 01072 case Expr::UnaryTypeTraitExprClass: 01073 // These expressions can never throw. 01074 return CT_Cannot; 01075 01076 #define STMT(CLASS, PARENT) case Expr::CLASS##Class: 01077 #define STMT_RANGE(Base, First, Last) 01078 #define LAST_STMT_RANGE(BASE, FIRST, LAST) 01079 #define EXPR(CLASS, PARENT) 01080 #define ABSTRACT_STMT(STMT) 01081 #include "clang/AST/StmtNodes.inc" 01082 case Expr::NoStmtClass: 01083 llvm_unreachable("Invalid class for expression"); 01084 } 01085 llvm_unreachable("Bogus StmtClass"); 01086 } 01087 01088 } // end namespace clang