clang API Documentation

SemaExceptionSpec.cpp
Go to the documentation of this file.
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