1dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl//===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===// 2dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// 3dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// The LLVM Compiler Infrastructure 4dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// 5dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// This file is distributed under the University of Illinois Open Source 6dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// License. See LICENSE.TXT for details. 7dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// 8dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl//===----------------------------------------------------------------------===// 9dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// 10dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// This file provides Sema routines for C++ exception specification testing. 11dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl// 12dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl//===----------------------------------------------------------------------===// 13dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 142d88708cbe4e4ec5e04e4acb6bd7f5be68557379John McCall#include "clang/Sema/SemaInternal.h" 15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/AST/ASTMutationListener.h" 16dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl#include "clang/AST/CXXInheritance.h" 17dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl#include "clang/AST/Expr.h" 18dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl#include "clang/AST/ExprCXX.h" 192eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor#include "clang/AST/TypeLoc.h" 20e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor#include "clang/Basic/Diagnostic.h" 21e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor#include "clang/Basic/SourceManager.h" 22dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl#include "llvm/ADT/SmallPtrSet.h" 238fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h" 24dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 25dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlnamespace clang { 26dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 27dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlstatic const FunctionProtoType *GetUnderlyingFunction(QualType T) 28dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl{ 29dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const PointerType *PtrTy = T->getAs<PointerType>()) 30dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl T = PtrTy->getPointeeType(); 31dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl else if (const ReferenceType *RefTy = T->getAs<ReferenceType>()) 32dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl T = RefTy->getPointeeType(); 33c3a3b7b38440384944614ea6e93cf8d238d3d5f2Sebastian Redl else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) 34c3a3b7b38440384944614ea6e93cf8d238d3d5f2Sebastian Redl T = MPTy->getPointeeType(); 35dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return T->getAs<FunctionProtoType>(); 36dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 37dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 38dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// CheckSpecifiedExceptionType - Check if the given type is valid in an 39dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// exception specification. Incomplete types, or pointers to incomplete types 40dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// other than void are not allowed. 4121173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith/// 4221173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith/// \param[in,out] T The exception type. This will be decayed to a pointer type 4321173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith/// when the input is an array or a function type. 4421173b1080abaa2738f9e700a9d4b0d04f928930Richard Smithbool Sema::CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range) { 45a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // C++11 [except.spec]p2: 46a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // A type cv T, "array of T", or "function returning T" denoted 4721173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith // in an exception-specification is adjusted to type T, "pointer to T", or 4821173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith // "pointer to function returning T", respectively. 49a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // 50a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // We also apply this rule in C++98. 5121173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith if (T->isArrayType()) 5221173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith T = Context.getArrayDecayedType(T); 5321173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith else if (T->isFunctionType()) 5421173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith T = Context.getPointerType(T); 5521173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith 56a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith int Kind = 0; 5721173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith QualType PointeeT = T; 58a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith if (const PointerType *PT = T->getAs<PointerType>()) { 59a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith PointeeT = PT->getPointeeType(); 60a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith Kind = 1; 61dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 62a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // cv void* is explicitly permitted, despite being a pointer to an 63a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // incomplete type. 64a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith if (PointeeT->isVoidType()) 65a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith return false; 66a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) { 67a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith PointeeT = RT->getPointeeType(); 68a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith Kind = 2; 69a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith 70a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith if (RT->isRValueReferenceType()) { 71a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // C++11 [except.spec]p2: 72a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // A type denoted in an exception-specification shall not denote [...] 73a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // an rvalue reference type. 74a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith Diag(Range.getBegin(), diag::err_rref_in_exception_spec) 75a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith << T << Range; 76a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith return true; 77a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith } 78a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith } 7921173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith 80a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // C++11 [except.spec]p2: 81a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // A type denoted in an exception-specification shall not denote an 82a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // incomplete type other than a class currently being defined [...]. 83a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // A type denoted in an exception-specification shall not denote a 84a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // pointer or reference to an incomplete type, other than (cv) void* or a 85a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith // pointer or reference to a class currently being defined. 86a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith if (!(PointeeT->isRecordType() && 87a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith PointeeT->getAs<RecordType>()->isBeingDefined()) && 8821173b1080abaa2738f9e700a9d4b0d04f928930Richard Smith RequireCompleteType(Range.getBegin(), PointeeT, 89a70c3f8738cc123ded68c183cedd6e93df670c2fRichard Smith diag::err_incomplete_in_exception_spec, Kind, Range)) 90491b84c062ead1c69911a8d5f0d57826afacc099Sebastian Redl return true; 91dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 92dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 93dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 94dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 95dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer 96dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// to member to a function with an exception specification. This means that 97dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// it is invalid to add another level of indirection. 98dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlbool Sema::CheckDistantExceptionSpec(QualType T) { 99dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const PointerType *PT = T->getAs<PointerType>()) 100dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl T = PT->getPointeeType(); 101dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl else if (const MemberPointerType *PT = T->getAs<MemberPointerType>()) 102dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl T = PT->getPointeeType(); 103dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl else 104dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 105dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 106dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *FnT = T->getAs<FunctionProtoType>(); 107dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!FnT) 108dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 109dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 110dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return FnT->hasExceptionSpec(); 111dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 112dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 113e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smithconst FunctionProtoType * 114e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard SmithSema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) { 115b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) 116e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return FPT; 117e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 118e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl(); 119e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const FunctionProtoType *SourceFPT = 120e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith SourceDecl->getType()->castAs<FunctionProtoType>(); 121e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 122b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith // If the exception specification has already been resolved, just return it. 123b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType())) 124e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return SourceFPT; 125e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 126b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith // Compute or instantiate the exception specification now. 12712fef490dce56bf8abc1bad7fec798eb882aabf7Richard Smith if (SourceFPT->getExceptionSpecType() == EST_Unevaluated) 128b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith EvaluateImplicitExceptionSpec(Loc, cast<CXXMethodDecl>(SourceDecl)); 129b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith else 130b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith InstantiateExceptionSpec(Loc, SourceDecl); 131e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 132e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return SourceDecl->getType()->castAs<FunctionProtoType>(); 133e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 134e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Sema::UpdateExceptionSpec(FunctionDecl *FD, 136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FunctionProtoType::ExtProtoInfo &EPI) { 137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines const FunctionProtoType *Proto = FD->getType()->castAs<FunctionProtoType>(); 138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Overwrite the exception spec and rebuild the function type. 140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FunctionProtoType::ExtProtoInfo NewEPI = Proto->getExtProtoInfo(); 141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NewEPI.ExceptionSpecType = EPI.ExceptionSpecType; 142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NewEPI.NumExceptions = EPI.NumExceptions; 143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NewEPI.Exceptions = EPI.Exceptions; 144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NewEPI.NoexceptExpr = EPI.NoexceptExpr; 145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines FD->setType(Context.getFunctionType(Proto->getReturnType(), 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Proto->getParamTypes(), NewEPI)); 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // If we've fully resolved the exception specification, notify listeners. 149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (!isUnresolvedExceptionSpec(EPI.ExceptionSpecType)) 150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (auto *Listener = getASTMutationListener()) 151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Listener->ResolvedExceptionSpec(FD); 152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 154444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// Determine whether a function has an implicitly-generated exception 155708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith/// specification. 156444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smithstatic bool hasImplicitExceptionSpec(FunctionDecl *Decl) { 157444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith if (!isa<CXXDestructorDecl>(Decl) && 158444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete && 159444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) 160444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith return false; 161444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith 162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // For a function that the user didn't declare: 163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // - if this is a destructor, its exception specification is implicit. 164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // - if this is 'operator delete' or 'operator delete[]', the exception 165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // specification is as-if an explicit exception specification was given 166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // (per [basic.stc.dynamic]p2). 167444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith if (!Decl->getTypeSourceInfo()) 168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return isa<CXXDestructorDecl>(Decl); 169708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith 170444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith const FunctionProtoType *Ty = 171444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>(); 172444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith return !Ty->hasExceptionSpec(); 173708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith} 174708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith 175e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregorbool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { 17699439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator(); 17799439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl bool IsOperatorNew = OO == OO_New || OO == OO_Array_New; 1782eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor bool MissingExceptionSpecification = false; 179e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor bool MissingEmptyExceptionSpecification = false; 180651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 181eedd4670b2eb7e4d67d11b2f26ed1ad304b70596Francois Pichet unsigned DiagID = diag::err_mismatched_exception_spec; 182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool ReturnValueOnError = true; 183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (getLangOpts().MicrosoftExt) { 184cf320c6388c90f1938c264e87d77a0e43946e2c3Francois Pichet DiagID = diag::warn_mismatched_exception_spec; 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines ReturnValueOnError = false; 186651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines } 187e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 188708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith // Check the types as written: they must match before any exception 189708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith // specification adjustment is applied. 190708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith if (!CheckEquivalentExceptionSpec( 191708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith PDiag(DiagID), PDiag(diag::note_previous_declaration), 192444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(), 193444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith New->getType()->getAs<FunctionProtoType>(), New->getLocation(), 194708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith &MissingExceptionSpecification, &MissingEmptyExceptionSpecification, 195444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith /*AllowNoexceptAllMatchWithNoSpec=*/true, IsOperatorNew)) { 196444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // C++11 [except.spec]p4 [DR1492]: 197444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // If a declaration of a function has an implicit 198444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // exception-specification, other declarations of the function shall 199444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // not specify an exception-specification. 20080ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (getLangOpts().CPlusPlus11 && 201444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) { 202444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch) 203444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith << hasImplicitExceptionSpec(Old); 204444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith if (!Old->getLocation().isInvalid()) 205444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Diag(Old->getLocation(), diag::note_previous_declaration); 206444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith } 207e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor return false; 208444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith } 209e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 2106e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // The failure was something other than an missing exception 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // specification; return an error, except in MS mode where this is a warning. 2126e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (!MissingExceptionSpecification) 213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return ReturnValueOnError; 214e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 215444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith const FunctionProtoType *NewProto = 2166e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman New->getType()->castAs<FunctionProtoType>(); 217e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall 218e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // The new function declaration is only missing an empty exception 219e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // specification "throw()". If the throw() specification came from a 220e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // function in a system header that has C linkage, just add an empty 221e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // exception specification to the "new" declaration. This is an 222e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // egregious workaround for glibc, which adds throw() specifications 223e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // to many libc functions as an optimization. Unfortunately, that 224e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // optimization isn't permitted by the C++ standard, so we're forced 225e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // to work around it here. 226e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall if (MissingEmptyExceptionSpecification && NewProto && 2272eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor (Old->getLocation().isInvalid() || 2282eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor Context.getSourceManager().isInSystemHeader(Old->getLocation())) && 229e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor Old->isExternC()) { 230e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); 23160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl EPI.ExceptionSpecType = EST_DynamicNone; 232651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType NewType = Context.getFunctionType(NewProto->getReturnType(), 233651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NewProto->getParamTypes(), EPI); 234e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor New->setType(NewType); 235e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor return false; 236e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor } 237e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 2386e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman const FunctionProtoType *OldProto = 2396e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman Old->getType()->castAs<FunctionProtoType>(); 2406e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 2416e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); 2426e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman EPI.ExceptionSpecType = OldProto->getExceptionSpecType(); 2436e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (EPI.ExceptionSpecType == EST_Dynamic) { 2446e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman EPI.NumExceptions = OldProto->getNumExceptions(); 2456e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman EPI.Exceptions = OldProto->exception_begin(); 2466e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { 2476e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // FIXME: We can't just take the expression from the old prototype. It 2486e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // likely contains references to the old prototype's parameters. 2496e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } 2502eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 2516e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // Update the type of the function with the appropriate exception 2526e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // specification. 253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType NewType = Context.getFunctionType(NewProto->getReturnType(), 254651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NewProto->getParamTypes(), EPI); 2556e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman New->setType(NewType); 2566e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 2576e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // Warn about the lack of exception specification. 2586e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman SmallString<128> ExceptionSpecString; 2596e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman llvm::raw_svector_ostream OS(ExceptionSpecString); 2606e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman switch (OldProto->getExceptionSpecType()) { 2616e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman case EST_DynamicNone: 2626e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << "throw()"; 2636e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman break; 2646e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 2656e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman case EST_Dynamic: { 2666e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << "throw("; 2676e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman bool OnFirstException = true; 268651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &E : OldProto->exceptions()) { 2696e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (OnFirstException) 2706e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OnFirstException = false; 2716e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman else 2726e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << ", "; 2736e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 274651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << E.getAsString(getPrintingPolicy()); 27560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 2766e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << ")"; 2776e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman break; 2786e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } 27960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 2806e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman case EST_BasicNoexcept: 2816e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << "noexcept"; 2826e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman break; 28360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 2846e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman case EST_ComputedNoexcept: 2856e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << "noexcept("; 286ef8225444452a1486bd721f3285301fe84643b00Stephen Hines assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr"); 2876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy()); 2886e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << ")"; 2896e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman break; 2902eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 2916e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman default: 2926e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman llvm_unreachable("This spec type is compatible with none."); 2936e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } 2946e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS.flush(); 2952eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 2966e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman SourceLocation FixItLoc; 2976e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) { 2986e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); 2996e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (FunctionTypeLoc FTLoc = TL.getAs<FunctionTypeLoc>()) 3006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd()); 3016e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } 3022eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 3036e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (FixItLoc.isInvalid()) 3046e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman Diag(New->getLocation(), diag::warn_missing_exception_specification) 3056e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman << New << OS.str(); 3066e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman else { 3076e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // FIXME: This will get more complicated with C++0x 3086e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // late-specified return types. 3096e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman Diag(New->getLocation(), diag::warn_missing_exception_specification) 3106e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman << New << OS.str() 3116e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str()); 3122eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor } 3132eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 3146e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (!Old->getLocation().isInvalid()) 3156e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman Diag(Old->getLocation(), diag::note_previous_declaration); 3166e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 3176e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman return false; 318e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor} 319e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 320dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// CheckEquivalentExceptionSpec - Check if the two types have equivalent 321dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// exception specifications. Exception specifications are equivalent if 322dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// they allow exactly the same set of exception types. It does not matter how 323dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// that is achieved. See C++ [except.spec]p2. 324dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlbool Sema::CheckEquivalentExceptionSpec( 325dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Old, SourceLocation OldLoc, 326dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *New, SourceLocation NewLoc) { 327eedd4670b2eb7e4d67d11b2f26ed1ad304b70596Francois Pichet unsigned DiagID = diag::err_mismatched_exception_spec; 3284e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt) 329651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines DiagID = diag::warn_mismatched_exception_spec; 330651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool Result = CheckEquivalentExceptionSpec(PDiag(DiagID), 331651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines PDiag(diag::note_previous_declaration), Old, OldLoc, New, NewLoc); 332651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 333651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // In Microsoft mode, mismatching exception specifications just cause a warning. 334651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (getLangOpts().MicrosoftExt) 335651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return false; 336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return Result; 337dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 338dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 33960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl/// CheckEquivalentExceptionSpec - Check if the two types have compatible 34060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl/// exception specifications. See C++ [except.spec]p3. 341444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// 342444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// \return \c false if the exception specifications match, \c true if there is 343444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// a problem. If \c true is returned, either a diagnostic has already been 344444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// produced or \c *MissingExceptionSpecification is set to \c true. 34560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redlbool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, 3462eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor const PartialDiagnostic & NoteID, 34760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl const FunctionProtoType *Old, 3482eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor SourceLocation OldLoc, 34960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl const FunctionProtoType *New, 3502eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor SourceLocation NewLoc, 3512eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor bool *MissingExceptionSpecification, 35260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl bool*MissingEmptyExceptionSpecification, 35399439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl bool AllowNoexceptAllMatchWithNoSpec, 35499439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl bool IsOperatorNew) { 355811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall // Just completely ignore this under -fno-exceptions. 3564e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CXXExceptions) 357811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall return false; 358811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall 3592eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor if (MissingExceptionSpecification) 3602eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor *MissingExceptionSpecification = false; 3612eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 362e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor if (MissingEmptyExceptionSpecification) 363e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor *MissingEmptyExceptionSpecification = false; 364e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 365e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Old = ResolveExceptionSpec(NewLoc, Old); 366e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!Old) 367e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return false; 368e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith New = ResolveExceptionSpec(NewLoc, New); 369e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!New) 370e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return false; 371e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 37260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // C++0x [except.spec]p3: Two exception-specifications are compatible if: 37360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // - both are non-throwing, regardless of their form, 37460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // - both have the form noexcept(constant-expression) and the constant- 37560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // expressions are equivalent, 37660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // - both are dynamic-exception-specifications that have the same set of 37760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // adjusted types. 37860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // 37960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // C++0x [except.spec]p12: An exception-specifcation is non-throwing if it is 38060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // of the form throw(), noexcept, or noexcept(constant-expression) where the 38160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // constant-expression yields true. 38260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // 38360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // C++0x [except.spec]p4: If any declaration of a function has an exception- 38460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // specifier that is not a noexcept-specification allowing all exceptions, 38560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // all declarations [...] of that function shall have a compatible 38660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // exception-specification. 38760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // 38860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // That last point basically means that noexcept(false) matches no spec. 38960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // It's considered when AllowNoexceptAllMatchWithNoSpec is true. 39060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 39160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ExceptionSpecificationType OldEST = Old->getExceptionSpecType(); 39260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ExceptionSpecificationType NewEST = New->getExceptionSpecType(); 39360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 394b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith assert(!isUnresolvedExceptionSpec(OldEST) && 395b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith !isUnresolvedExceptionSpec(NewEST) && 3967a614d8380297fcd2bc23986241905d97222948cRichard Smith "Shouldn't see unknown exception specifications here"); 3977a614d8380297fcd2bc23986241905d97222948cRichard Smith 39860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Shortcut the case where both have no spec. 39960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST == EST_None && NewEST == EST_None) 40060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 40160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 4028026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(Context); 4038026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(Context); 40460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldNR == FunctionProtoType::NR_BadNoexcept || 40560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NewNR == FunctionProtoType::NR_BadNoexcept) 40660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 40760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 40860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Dependent noexcept specifiers are compatible with each other, but nothing 40960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // else. 41060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // One noexcept is compatible with another if the argument is the same 41160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldNR == NewNR && 41260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl OldNR != FunctionProtoType::NR_NoNoexcept && 41360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NewNR != FunctionProtoType::NR_NoNoexcept) 41460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 41560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldNR != NewNR && 41660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl OldNR != FunctionProtoType::NR_NoNoexcept && 41760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NewNR != FunctionProtoType::NR_NoNoexcept) { 41860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(NewLoc, DiagID); 41960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NoteID.getDiagID() != 0) 42060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(OldLoc, NoteID); 42160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return true; 42260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 42360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 42460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // The MS extension throw(...) is compatible with itself. 42560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST == EST_MSAny && NewEST == EST_MSAny) 42660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 42760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 42860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // It's also compatible with no spec. 42960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if ((OldEST == EST_None && NewEST == EST_MSAny) || 43060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl (OldEST == EST_MSAny && NewEST == EST_None)) 43160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 43260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 43360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // It's also compatible with noexcept(false). 43460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw) 43560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 43660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw) 43760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 43860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 43960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // As described above, noexcept(false) matches no spec only for functions. 44060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (AllowNoexceptAllMatchWithNoSpec) { 44160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw) 44260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 44360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw) 44460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 4455b6f769a6abda4da44186cc8e6a2d6ed37dc9344Douglas Gregor } 4465b6f769a6abda4da44186cc8e6a2d6ed37dc9344Douglas Gregor 44760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Any non-throwing specifications are compatible. 44860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow || 44960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl OldEST == EST_DynamicNone; 45060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow || 45160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NewEST == EST_DynamicNone; 45260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldNonThrowing && NewNonThrowing) 453dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 45460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 45599439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // As a special compatibility feature, under C++0x we accept no spec and 45699439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // throw(std::bad_alloc) as equivalent for operator new and operator new[]. 45799439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // This is because the implicit declaration changed, but old code would break. 45880ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (getLangOpts().CPlusPlus11 && IsOperatorNew) { 4596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const FunctionProtoType *WithExceptions = nullptr; 46099439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (OldEST == EST_None && NewEST == EST_Dynamic) 46199439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl WithExceptions = New; 46299439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl else if (OldEST == EST_Dynamic && NewEST == EST_None) 46399439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl WithExceptions = Old; 46499439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (WithExceptions && WithExceptions->getNumExceptions() == 1) { 46599439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // One has no spec, the other throw(something). If that something is 46699439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // std::bad_alloc, all conditions are met. 46799439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl QualType Exception = *WithExceptions->exception_begin(); 46899439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) { 46999439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl IdentifierInfo* Name = ExRecord->getIdentifier(); 47099439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (Name && Name->getName() == "bad_alloc") { 47199439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // It's called bad_alloc, but is it in std? 4726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines if (ExRecord->isInStdNamespace()) { 4736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return false; 47499439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 47599439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 47699439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 47799439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 47899439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 47999439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl 48060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // At this point, the only remaining valid case is two matching dynamic 48160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // specifications. We return here unless both specifications are dynamic. 48260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) { 4832eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor if (MissingExceptionSpecification && Old->hasExceptionSpec() && 484e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor !New->hasExceptionSpec()) { 4852eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor // The old type has an exception specification of some sort, but 4862eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor // the new type does not. 4872eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor *MissingExceptionSpecification = true; 4882eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 48960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (MissingEmptyExceptionSpecification && OldNonThrowing) { 49060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // The old type has a throw() or noexcept(true) exception specification 49160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // and the new type has no exception specification, and the caller asked 4922eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor // to handle this itself. 4932eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor *MissingEmptyExceptionSpecification = true; 4942eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor } 4952eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 496e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor return true; 497e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor } 498e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 499dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(NewLoc, DiagID); 50037c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (NoteID.getDiagID() != 0) 501dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(OldLoc, NoteID); 502dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 503dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 504dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 50560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic && 50660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl "Exception compatibility logic error: non-dynamic spec slipped through."); 50760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 508dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl bool Success = true; 50960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Both have a dynamic exception spec. Collect the first set, then compare 510dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // to the second. 5111219d150aff23d19ba988e12602db5f3b70e404dSebastian Redl llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes; 512651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : Old->exceptions()) 513651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OldTypes.insert(Context.getCanonicalType(I).getUnqualifiedType()); 514dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 515651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &I : New->exceptions()) { 516651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines CanQualType TypePtr = Context.getCanonicalType(I).getUnqualifiedType(); 5175db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl if(OldTypes.count(TypePtr)) 5185db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl NewTypes.insert(TypePtr); 5195db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl else 5205db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl Success = false; 5215db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl } 522dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 5235db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl Success = Success && OldTypes.size() == NewTypes.size(); 524dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 525dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (Success) { 526dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 527dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 528dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(NewLoc, DiagID); 52937c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (NoteID.getDiagID() != 0) 530dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(OldLoc, NoteID); 531dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 532dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 533dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 534dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// CheckExceptionSpecSubset - Check whether the second function type's 535dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// exception specification is a subset (or equivalent) of the first function 536dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// type. This is used by override and pointer assignment checks. 53737c38ec5f1c155886929739338110a0b70ac3362Sebastian Redlbool Sema::CheckExceptionSpecSubset( 53837c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, 539dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Superset, SourceLocation SuperLoc, 540dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Subset, SourceLocation SubLoc) { 541811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall 542811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall // Just auto-succeed under -fno-exceptions. 5434e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CXXExceptions) 544811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall return false; 545811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall 546dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // FIXME: As usual, we could be more specific in our error messages, but 547dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // that better waits until we've got types with source locations. 548dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 549dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!SubLoc.isValid()) 550dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl SubLoc = SuperLoc; 551dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 552e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Resolve the exception specifications, if needed. 553e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Superset = ResolveExceptionSpec(SuperLoc, Superset); 554e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!Superset) 555e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return false; 556e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Subset = ResolveExceptionSpec(SubLoc, Subset); 557e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!Subset) 558e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return false; 559e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 56060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType(); 56160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 562dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // If superset contains everything, we're done. 56360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SuperEST == EST_None || SuperEST == EST_MSAny) 56460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 56560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 56660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // If there are dependent noexcept specs, assume everything is fine. Unlike 56760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // with the equivalency check, this is safe in this case, because we don't 56860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // want to merge declarations. Checks after instantiation will catch any 56960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // omissions we make here. 57060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // We also shortcut checking if a noexcept expression was bad. 57160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 5728026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context); 57360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SuperNR == FunctionProtoType::NR_BadNoexcept || 57460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl SuperNR == FunctionProtoType::NR_Dependent) 57560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 57660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 57760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Another case of the superset containing everything. 57860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SuperNR == FunctionProtoType::NR_Throw) 579dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 580dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 58160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ExceptionSpecificationType SubEST = Subset->getExceptionSpecType(); 58260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 583b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith assert(!isUnresolvedExceptionSpec(SuperEST) && 584b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith !isUnresolvedExceptionSpec(SubEST) && 5857a614d8380297fcd2bc23986241905d97222948cRichard Smith "Shouldn't see unknown exception specifications here"); 5867a614d8380297fcd2bc23986241905d97222948cRichard Smith 587dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // It does not. If the subset contains everything, we've failed. 58860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SubEST == EST_None || SubEST == EST_MSAny) { 58960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(SubLoc, DiagID); 59060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NoteID.getDiagID() != 0) 59160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(SuperLoc, NoteID); 59260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return true; 59360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 59460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 5958026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context); 59660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SubNR == FunctionProtoType::NR_BadNoexcept || 59760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl SubNR == FunctionProtoType::NR_Dependent) 59860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 59960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 60060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Another case of the subset containing everything. 60160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SubNR == FunctionProtoType::NR_Throw) { 60260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(SubLoc, DiagID); 60360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NoteID.getDiagID() != 0) 60460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(SuperLoc, NoteID); 60560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return true; 60660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 60760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 60860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // If the subset contains nothing, we're done. 60960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow) 61060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 61160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 61260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Otherwise, if the superset contains nothing, we've failed. 61360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) { 614dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(SubLoc, DiagID); 61537c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (NoteID.getDiagID() != 0) 616dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(SuperLoc, NoteID); 617dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 618dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 619dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 62060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic && 62160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl "Exception spec subset: non-dynamic case slipped through."); 62260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 62360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Neither contains everything or nothing. Do a proper comparison. 624651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &SubI : Subset->exceptions()) { 625dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Take one type from the subset. 626651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType CanonicalSubT = Context.getCanonicalType(SubI); 627c3a3b7b38440384944614ea6e93cf8d238d3d5f2Sebastian Redl // Unwrap pointers and references so that we can do checks within a class 628c3a3b7b38440384944614ea6e93cf8d238d3d5f2Sebastian Redl // hierarchy. Don't unwrap member pointers; they don't have hierarchy 629c3a3b7b38440384944614ea6e93cf8d238d3d5f2Sebastian Redl // conversions on the pointee. 630dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl bool SubIsPointer = false; 631dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>()) 632dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CanonicalSubT = RefTy->getPointeeType(); 633dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) { 634dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CanonicalSubT = PtrTy->getPointeeType(); 635dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl SubIsPointer = true; 636dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 637dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl bool SubIsClass = CanonicalSubT->isRecordType(); 638a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType(); 639dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 640dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 641dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl /*DetectVirtual=*/false); 642dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 643dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl bool Contained = false; 644dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Make sure it's in the superset. 645651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (const auto &SuperI : Superset->exceptions()) { 646651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines QualType CanonicalSuperT = Context.getCanonicalType(SuperI); 647dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // SubT must be SuperT or derived from it, or pointer or reference to 648dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // such types. 649dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>()) 650dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CanonicalSuperT = RefTy->getPointeeType(); 651dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (SubIsPointer) { 652dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>()) 653dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CanonicalSuperT = PtrTy->getPointeeType(); 654dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl else { 655dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl continue; 656dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 657dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 658a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType(); 659dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // If the types are the same, move on to the next type in the subset. 660dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (CanonicalSubT == CanonicalSuperT) { 661dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Contained = true; 662dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl break; 663dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 664dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 665dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Otherwise we need to check the inheritance. 666dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!SubIsClass || !CanonicalSuperT->isRecordType()) 667dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl continue; 668dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 669dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Paths.clear(); 670dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths)) 671dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl continue; 672dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 673e0d5fe2a417b84ac8b51927ebeb8f1c9ae492760Douglas Gregor if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT))) 674dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl continue; 675dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 6766b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall // Do this check from a context without privileges. 67758e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall switch (CheckBaseClassAccess(SourceLocation(), 6786b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall CanonicalSuperT, CanonicalSubT, 6796b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall Paths.front(), 68058e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall /*Diagnostic*/ 0, 6816b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall /*ForceCheck*/ true, 68258e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall /*ForceUnprivileged*/ true)) { 6836b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall case AR_accessible: break; 6846b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall case AR_inaccessible: continue; 6856b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall case AR_dependent: 6866b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall llvm_unreachable("access check dependent for unprivileged context"); 6876b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall case AR_delayed: 6886b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall llvm_unreachable("access check delayed in non-declaration"); 6896b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall } 690dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 691dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Contained = true; 692dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl break; 693dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 694dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!Contained) { 695dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(SubLoc, DiagID); 69637c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (NoteID.getDiagID() != 0) 697dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(SuperLoc, NoteID); 698dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 699dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 700dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 701dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // We've run half the gauntlet. 702dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 703dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 704dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 705dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlstatic bool CheckSpecForTypesEquivalent(Sema &S, 70637c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, 707dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl QualType Target, SourceLocation TargetLoc, 708dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl QualType Source, SourceLocation SourceLoc) 709dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl{ 710dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *TFunc = GetUnderlyingFunction(Target); 711dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!TFunc) 712dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 713dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *SFunc = GetUnderlyingFunction(Source); 714dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!SFunc) 715dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 716dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 717dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc, 718dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl SFunc, SourceLoc); 719dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 720dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 721dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// CheckParamExceptionSpec - Check if the parameter and return types of the 722dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// two functions have equivalent exception specs. This is part of the 723dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// assignment and override compatibility check. We do not check the parameters 724dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// of parameter function pointers recursively, as no sane programmer would 725dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// even be able to write such a function type. 72637c38ec5f1c155886929739338110a0b70ac3362Sebastian Redlbool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID, 727dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Target, SourceLocation TargetLoc, 728dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Source, SourceLocation SourceLoc) 729dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl{ 730651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CheckSpecForTypesEquivalent( 731651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *this, PDiag(diag::err_deep_exception_specs_differ) << 0, PDiag(), 732651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Target->getReturnType(), TargetLoc, Source->getReturnType(), 733651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLoc)) 734dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 735dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 73637c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl // We shouldn't even be testing this unless the arguments are otherwise 737dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // compatible. 738651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines assert(Target->getNumParams() == Source->getNumParams() && 739dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl "Functions have different argument counts."); 740651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) { 741651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (CheckSpecForTypesEquivalent( 742651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines *this, PDiag(diag::err_deep_exception_specs_differ) << 1, PDiag(), 743651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Target->getParamType(i), TargetLoc, Source->getParamType(i), 744651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines SourceLoc)) 745dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 746dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 747dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 748dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 749dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 750dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlbool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) 751dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl{ 752dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // First we check for applicability. 753dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Target type must be a function, function pointer or function reference. 754dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType); 755dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!ToFunc) 756dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 757dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 758dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // SourceType must be a function or function pointer. 759dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType()); 760dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!FromFunc) 761dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 762dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 763dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Now we've got the correct types on both sides, check their compatibility. 764dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // This means that the source of the conversion can only throw a subset of 765dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // the exceptions of the target, and any exception specs on arguments or 766dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // return types must be equivalent. 767fe6b2d481d91140923f4541f273b253291884214Douglas Gregor return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs), 768fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(), ToFunc, 769fe6b2d481d91140923f4541f273b253291884214Douglas Gregor From->getSourceRange().getBegin(), 770dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl FromFunc, SourceLocation()); 771dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 772dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 773dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlbool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, 774dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const CXXMethodDecl *Old) { 77580ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) { 776a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl // Don't check uninstantiated template destructors at all. We can only 777a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl // synthesize correct specs after the template is instantiated. 778a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl if (New->getParent()->isDependentType()) 779a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl return false; 780a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl if (New->getParent()->isBeingDefined()) { 781a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl // The destructor might be updated once the definition is finished. So 782a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl // remember it and check later. 783a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl DelayedDestructorExceptionSpecChecks.push_back(std::make_pair( 784a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old))); 785a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl return false; 786a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl } 7870ee33912f8ec3453856c8a32ed2c2e8007bed614Sebastian Redl } 7880f161593b36584ec447e5268dbed2953489854d8Francois Pichet unsigned DiagID = diag::err_override_exception_spec; 7894e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt) 7900f161593b36584ec447e5268dbed2953489854d8Francois Pichet DiagID = diag::warn_override_exception_spec; 7910f161593b36584ec447e5268dbed2953489854d8Francois Pichet return CheckExceptionSpecSubset(PDiag(DiagID), 792fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(diag::note_overridden_virtual_function), 793dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Old->getType()->getAs<FunctionProtoType>(), 794dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Old->getLocation(), 795dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl New->getType()->getAs<FunctionProtoType>(), 796dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl New->getLocation()); 797dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 798dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 799e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smithstatic CanThrowResult canSubExprsThrow(Sema &S, const Expr *CE) { 800e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Expr *E = const_cast<Expr*>(CE); 801e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult R = CT_Cannot; 802e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith for (Expr::child_range I = E->children(); I && R != CT_Can; ++I) 803e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith R = mergeCanThrow(R, S.canThrow(cast<Expr>(*I))); 804e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return R; 805e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 806e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 80772aa4c431b650800140457636c8481fd965f1534Eli Friedmanstatic CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D) { 80872aa4c431b650800140457636c8481fd965f1534Eli Friedman assert(D && "Expected decl"); 809e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 810e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // See if we can get a function type from the decl somehow. 811e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const ValueDecl *VD = dyn_cast<ValueDecl>(D); 812e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!VD) // If we have no clue what we're calling, assume the worst. 813e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 814e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 815e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // As an extension, we assume that __attribute__((nothrow)) functions don't 816e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // throw. 817e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) 818e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 819e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 820e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith QualType T = VD->getType(); 821e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const FunctionProtoType *FT; 822e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if ((FT = T->getAs<FunctionProtoType>())) { 823e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } else if (const PointerType *PT = T->getAs<PointerType>()) 824e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = PT->getPointeeType()->getAs<FunctionProtoType>(); 825e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 826e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = RT->getPointeeType()->getAs<FunctionProtoType>(); 827e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) 828e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = MT->getPointeeType()->getAs<FunctionProtoType>(); 829e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) 830e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = BT->getPointeeType()->getAs<FunctionProtoType>(); 831e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 832e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!FT) 833e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 834e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 835e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = S.ResolveExceptionSpec(E->getLocStart(), FT); 836e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!FT) 837e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 838e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 839e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can; 840e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 841e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 842e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smithstatic CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { 843e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (DC->isTypeDependent()) 844e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 845e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 846e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!DC->getTypeAsWritten()->isReferenceType()) 847e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 848e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 849e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (DC->getSubExpr()->isTypeDependent()) 850e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 851e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 852e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot; 853e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 854e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 855e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smithstatic CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { 856e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (DC->isTypeOperand()) 857e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 858e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 859e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Expr *Op = DC->getExprOperand(); 860e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (Op->isTypeDependent()) 861e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 862e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 863e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const RecordType *RT = Op->getType()->getAs<RecordType>(); 864e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!RT) 865e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 866e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 867e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) 868e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 869e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 870e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (Op->Classify(S.Context).isPRValue()) 871e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 872e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 873e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 874e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 875e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 876e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard SmithCanThrowResult Sema::canThrow(const Expr *E) { 877e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // C++ [expr.unary.noexcept]p3: 878e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // [Can throw] if in a potentially-evaluated context the expression would 879e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // contain: 880e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith switch (E->getStmtClass()) { 881e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXThrowExprClass: 882e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // - a potentially evaluated throw-expression 883e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 884e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 885e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXDynamicCastExprClass: { 886e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), 887e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // where T is a reference type, that requires a run-time check 888e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E)); 889e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 890e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 891e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 892e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 893e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 894e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXTypeidExprClass: 895e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // - a potentially evaluated typeid expression applied to a glvalue 896e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // expression whose type is a polymorphic class type 897e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return canTypeidThrow(*this, cast<CXXTypeidExpr>(E)); 898e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 899e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // - a potentially evaluated call to a function, member function, function 900e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // pointer, or member function pointer that does not have a non-throwing 901e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // exception-specification 902e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CallExprClass: 903e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXMemberCallExprClass: 904e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXOperatorCallExprClass: 905e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UserDefinedLiteralClass: { 906e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const CallExpr *CE = cast<CallExpr>(E); 907e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT; 908e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (E->isTypeDependent()) 909e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = CT_Dependent; 910e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) 911e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = CT_Cannot; 912f9b4fea4bf6cebe614e49ab4b582dcf4bf0a6806Eli Friedman else if (CE->getCalleeDecl()) 913e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = canCalleeThrow(*this, E, CE->getCalleeDecl()); 914f9b4fea4bf6cebe614e49ab4b582dcf4bf0a6806Eli Friedman else 915f9b4fea4bf6cebe614e49ab4b582dcf4bf0a6806Eli Friedman CT = CT_Can; 916e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 917e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 918e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 919e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 920e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 921e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXConstructExprClass: 922e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXTemporaryObjectExprClass: { 923e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = canCalleeThrow(*this, E, 924e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith cast<CXXConstructExpr>(E)->getConstructor()); 925e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 926e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 927e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 928e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 929e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 930e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::LambdaExprClass: { 931e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const LambdaExpr *Lambda = cast<LambdaExpr>(E); 932e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = CT_Cannot; 933e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(), 934e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CapEnd = Lambda->capture_init_end(); 935e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Cap != CapEnd; ++Cap) 936e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = mergeCanThrow(CT, canThrow(*Cap)); 937e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 938e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 939e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 940e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXNewExprClass: { 941e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT; 942e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (E->isTypeDependent()) 943e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = CT_Dependent; 944e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else 945e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew()); 946e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 947e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 948e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 949e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 950e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 951e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXDeleteExprClass: { 952e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT; 953e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType(); 954e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (DTy.isNull() || DTy->isDependentType()) { 955e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = CT_Dependent; 956e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } else { 957e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = canCalleeThrow(*this, E, 958e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith cast<CXXDeleteExpr>(E)->getOperatorDelete()); 959e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (const RecordType *RT = DTy->getAs<RecordType>()) { 960e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 96172aa4c431b650800140457636c8481fd965f1534Eli Friedman const CXXDestructorDecl *DD = RD->getDestructor(); 96272aa4c431b650800140457636c8481fd965f1534Eli Friedman if (DD) 96372aa4c431b650800140457636c8481fd965f1534Eli Friedman CT = mergeCanThrow(CT, canCalleeThrow(*this, E, DD)); 964e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 965e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 966e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 967e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 968e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 969e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 970e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 971e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXBindTemporaryExprClass: { 972e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // The bound temporary has to be destroyed again, which might throw. 973e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = canCalleeThrow(*this, E, 974e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor()); 975e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 976e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 977e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 978e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 979e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 980e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // ObjC message sends are like function calls, but never have exception 981e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // specs. 982e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCMessageExprClass: 983e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCPropertyRefExprClass: 984e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCSubscriptRefExprClass: 985e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 986e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 987e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // All the ObjC literals that are implemented as calls are 988e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // potentially throwing unless we decide to close off that 989e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // possibility. 990e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCArrayLiteralClass: 991e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCDictionaryLiteralClass: 992eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard case Expr::ObjCBoxedExprClass: 993e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 994e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 995e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Many other things have subexpressions, so we have to test those. 996e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Some are simple: 997e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ConditionalOperatorClass: 998e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CompoundLiteralExprClass: 999e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXConstCastExprClass: 1000e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXReinterpretCastExprClass: 10017c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith case Expr::CXXStdInitializerListExprClass: 1002e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::DesignatedInitExprClass: 1003e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ExprWithCleanupsClass: 1004e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ExtVectorElementExprClass: 1005e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::InitListExprClass: 1006e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::MemberExprClass: 1007e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCIsaExprClass: 1008e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCIvarRefExprClass: 1009e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ParenExprClass: 1010e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ParenListExprClass: 1011e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ShuffleVectorExprClass: 1012414a1bdbdaf250e0488589f12865c8961831b65dHal Finkel case Expr::ConvertVectorExprClass: 1013e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::VAArgExprClass: 1014e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return canSubExprsThrow(*this, E); 1015e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1016e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Some might be dependent for other reasons. 1017e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ArraySubscriptExprClass: 1018e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::BinaryOperatorClass: 1019e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CompoundAssignOperatorClass: 1020e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CStyleCastExprClass: 1021e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXStaticCastExprClass: 1022e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXFunctionalCastExprClass: 1023e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ImplicitCastExprClass: 1024e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::MaterializeTemporaryExprClass: 1025e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnaryOperatorClass: { 1026e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot; 1027e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1028e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 1029e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1030e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms. 1031e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::StmtExprClass: 1032e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 1033e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1034c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith case Expr::CXXDefaultArgExprClass: 1035c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith return canThrow(cast<CXXDefaultArgExpr>(E)->getExpr()); 1036c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith 1037c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith case Expr::CXXDefaultInitExprClass: 1038c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith return canThrow(cast<CXXDefaultInitExpr>(E)->getExpr()); 1039c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith 1040e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ChooseExprClass: 1041e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (E->isTypeDependent() || E->isValueDependent()) 1042e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 1043a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr()); 1044e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1045e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::GenericSelectionExprClass: 1046e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (cast<GenericSelectionExpr>(E)->isResultDependent()) 1047e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 1048e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr()); 1049e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1050e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Some expressions are always dependent. 1051e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXDependentScopeMemberExprClass: 1052e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXUnresolvedConstructExprClass: 1053e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::DependentScopeDeclRefExprClass: 1054e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 1055e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1056e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::AsTypeExprClass: 1057e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::BinaryConditionalOperatorClass: 1058e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::BlockExprClass: 1059e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CUDAKernelCallExprClass: 1060e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::DeclRefExprClass: 1061e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCBridgedCastExprClass: 1062e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCIndirectCopyRestoreExprClass: 1063e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCProtocolExprClass: 1064e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCSelectorExprClass: 1065e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::OffsetOfExprClass: 1066e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::PackExpansionExprClass: 1067e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::PseudoObjectExprClass: 1068e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::SubstNonTypeTemplateParmExprClass: 1069e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::SubstNonTypeTemplateParmPackExprClass: 10709a4db032ecd991626d236a502e770126db32bd31Richard Smith case Expr::FunctionParmPackExprClass: 1071e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnaryExprOrTypeTraitExprClass: 1072e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnresolvedLookupExprClass: 1073e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnresolvedMemberExprClass: 1074e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // FIXME: Can any of the above throw? If so, when? 1075e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 1076e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1077e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::AddrLabelExprClass: 1078e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ArrayTypeTraitExprClass: 1079e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::AtomicExprClass: 1080e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::TypeTraitExprClass: 1081e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXBoolLiteralExprClass: 1082e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXNoexceptExprClass: 1083e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXNullPtrLiteralExprClass: 1084e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXPseudoDestructorExprClass: 1085e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXScalarValueInitExprClass: 1086e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXThisExprClass: 1087e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXUuidofExprClass: 1088e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CharacterLiteralClass: 1089e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ExpressionTraitExprClass: 1090e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::FloatingLiteralClass: 1091e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::GNUNullExprClass: 1092e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ImaginaryLiteralClass: 1093e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ImplicitValueInitExprClass: 1094e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::IntegerLiteralClass: 1095e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCEncodeExprClass: 1096e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCStringLiteralClass: 1097e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCBoolLiteralExprClass: 1098e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::OpaqueValueExprClass: 1099e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::PredefinedExprClass: 1100e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::SizeOfPackExprClass: 1101e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::StringLiteralClass: 1102e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // These expressions can never throw. 1103e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 1104e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 110576da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall case Expr::MSPropertyRefExprClass: 110676da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall llvm_unreachable("Invalid class for expression"); 110776da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 1108e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define STMT(CLASS, PARENT) case Expr::CLASS##Class: 1109e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define STMT_RANGE(Base, First, Last) 1110e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define LAST_STMT_RANGE(BASE, FIRST, LAST) 1111e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define EXPR(CLASS, PARENT) 1112e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define ABSTRACT_STMT(STMT) 1113e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#include "clang/AST/StmtNodes.inc" 1114e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::NoStmtClass: 1115e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith llvm_unreachable("Invalid class for expression"); 1116e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 1117e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith llvm_unreachable("Bogus StmtClass"); 1118e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 1119e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1120dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} // end namespace clang 1121