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" 15dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl#include "clang/AST/CXXInheritance.h" 16dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl#include "clang/AST/Expr.h" 17dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl#include "clang/AST/ExprCXX.h" 182eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor#include "clang/AST/TypeLoc.h" 19e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor#include "clang/Basic/Diagnostic.h" 20e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor#include "clang/Basic/SourceManager.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Lex/Preprocessor.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 135444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// Determine whether a function has an implicitly-generated exception 136708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith/// specification. 137444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smithstatic bool hasImplicitExceptionSpec(FunctionDecl *Decl) { 138444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith if (!isa<CXXDestructorDecl>(Decl) && 139444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete && 140444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete) 141444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith return false; 142444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith 143444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // If the user didn't declare the function, its exception specification must 144444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // be implicit. 145444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith if (!Decl->getTypeSourceInfo()) 146444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith return true; 147708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith 148444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith const FunctionProtoType *Ty = 149444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>(); 150444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith return !Ty->hasExceptionSpec(); 151708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith} 152708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith 153e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregorbool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { 15499439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator(); 15599439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl bool IsOperatorNew = OO == OO_New || OO == OO_Array_New; 1562eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor bool MissingExceptionSpecification = false; 157e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor bool MissingEmptyExceptionSpecification = false; 158eedd4670b2eb7e4d67d11b2f26ed1ad304b70596Francois Pichet unsigned DiagID = diag::err_mismatched_exception_spec; 1594e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt) 160cf320c6388c90f1938c264e87d77a0e43946e2c3Francois Pichet DiagID = diag::warn_mismatched_exception_spec; 161e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 162708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith // Check the types as written: they must match before any exception 163708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith // specification adjustment is applied. 164708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith if (!CheckEquivalentExceptionSpec( 165708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith PDiag(DiagID), PDiag(diag::note_previous_declaration), 166444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(), 167444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith New->getType()->getAs<FunctionProtoType>(), New->getLocation(), 168708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith &MissingExceptionSpecification, &MissingEmptyExceptionSpecification, 169444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith /*AllowNoexceptAllMatchWithNoSpec=*/true, IsOperatorNew)) { 170444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // C++11 [except.spec]p4 [DR1492]: 171444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // If a declaration of a function has an implicit 172444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // exception-specification, other declarations of the function shall 173444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith // not specify an exception-specification. 17480ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (getLangOpts().CPlusPlus11 && 175444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) { 176444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch) 177444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith << hasImplicitExceptionSpec(Old); 178444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith if (!Old->getLocation().isInvalid()) 179444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith Diag(Old->getLocation(), diag::note_previous_declaration); 180444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith } 181e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor return false; 182444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith } 183e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 1846e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // The failure was something other than an missing exception 185e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // specification; return an error. 1866e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (!MissingExceptionSpecification) 187e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor return true; 188e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 189444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith const FunctionProtoType *NewProto = 1906e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman New->getType()->castAs<FunctionProtoType>(); 191e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall 192e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // The new function declaration is only missing an empty exception 193e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // specification "throw()". If the throw() specification came from a 194e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // function in a system header that has C linkage, just add an empty 195e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // exception specification to the "new" declaration. This is an 196e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // egregious workaround for glibc, which adds throw() specifications 197e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // to many libc functions as an optimization. Unfortunately, that 198e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // optimization isn't permitted by the C++ standard, so we're forced 199e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor // to work around it here. 200e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall if (MissingEmptyExceptionSpecification && NewProto && 2012eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor (Old->getLocation().isInvalid() || 2022eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor Context.getSourceManager().isInSystemHeader(Old->getLocation())) && 203e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor Old->isExternC()) { 204e23cf437fe76b1ed02d63c3f61b456fd48a915f5John McCall FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); 20560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl EPI.ExceptionSpecType = EST_DynamicNone; 2060567a79130a251bf464ce21ecf3f8b9fb5207900Reid Kleckner QualType NewType = Context.getFunctionType(NewProto->getResultType(), 2070567a79130a251bf464ce21ecf3f8b9fb5207900Reid Kleckner NewProto->getArgTypes(), EPI); 208e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor New->setType(NewType); 209e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor return false; 210e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor } 211e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 2126e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman const FunctionProtoType *OldProto = 2136e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman Old->getType()->castAs<FunctionProtoType>(); 2146e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 2156e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo(); 2166e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman EPI.ExceptionSpecType = OldProto->getExceptionSpecType(); 2176e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (EPI.ExceptionSpecType == EST_Dynamic) { 2186e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman EPI.NumExceptions = OldProto->getNumExceptions(); 2196e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman EPI.Exceptions = OldProto->exception_begin(); 2206e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } else if (EPI.ExceptionSpecType == EST_ComputedNoexcept) { 2216e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // FIXME: We can't just take the expression from the old prototype. It 2226e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // likely contains references to the old prototype's parameters. 2236e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } 2242eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 2256e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // Update the type of the function with the appropriate exception 2266e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // specification. 2276e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman QualType NewType = Context.getFunctionType(NewProto->getResultType(), 2286e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman NewProto->getArgTypes(), EPI); 2296e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman New->setType(NewType); 2306e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 2316e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // Warn about the lack of exception specification. 2326e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman SmallString<128> ExceptionSpecString; 2336e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman llvm::raw_svector_ostream OS(ExceptionSpecString); 2346e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman switch (OldProto->getExceptionSpecType()) { 2356e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman case EST_DynamicNone: 2366e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << "throw()"; 2376e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman break; 2386e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 2396e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman case EST_Dynamic: { 2406e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << "throw("; 2416e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman bool OnFirstException = true; 2426e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman for (FunctionProtoType::exception_iterator E = OldProto->exception_begin(), 2436e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman EEnd = OldProto->exception_end(); 2446e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman E != EEnd; 2456e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman ++E) { 2466e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (OnFirstException) 2476e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OnFirstException = false; 2486e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman else 2496e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << ", "; 2506e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 2516e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << E->getAsString(getPrintingPolicy()); 25260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 2536e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << ")"; 2546e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman break; 2556e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } 25660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 2576e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman case EST_BasicNoexcept: 2586e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << "noexcept"; 2596e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman break; 26060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 2616e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman case EST_ComputedNoexcept: 2626e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << "noexcept("; 2636e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OldProto->getNoexceptExpr()->printPretty(OS, 0, getPrintingPolicy()); 2646e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS << ")"; 2656e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman break; 2662eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 2676e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman default: 2686e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman llvm_unreachable("This spec type is compatible with none."); 2696e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } 2706e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman OS.flush(); 2712eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 2726e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman SourceLocation FixItLoc; 2736e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) { 2746e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens(); 2756e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (FunctionTypeLoc FTLoc = TL.getAs<FunctionTypeLoc>()) 2766e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman FixItLoc = PP.getLocForEndOfToken(FTLoc.getLocalRangeEnd()); 2776e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman } 2782eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 2796e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (FixItLoc.isInvalid()) 2806e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman Diag(New->getLocation(), diag::warn_missing_exception_specification) 2816e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman << New << OS.str(); 2826e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman else { 2836e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // FIXME: This will get more complicated with C++0x 2846e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman // late-specified return types. 2856e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman Diag(New->getLocation(), diag::warn_missing_exception_specification) 2866e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman << New << OS.str() 2876e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str()); 2882eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor } 2892eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 2906e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman if (!Old->getLocation().isInvalid()) 2916e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman Diag(Old->getLocation(), diag::note_previous_declaration); 2926e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman 2936e98678f638cfb47cd281ce9a89e0b7443b29487Eli Friedman return false; 294e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor} 295e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 296dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// CheckEquivalentExceptionSpec - Check if the two types have equivalent 297dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// exception specifications. Exception specifications are equivalent if 298dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// they allow exactly the same set of exception types. It does not matter how 299dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// that is achieved. See C++ [except.spec]p2. 300dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlbool Sema::CheckEquivalentExceptionSpec( 301dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Old, SourceLocation OldLoc, 302dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *New, SourceLocation NewLoc) { 303eedd4670b2eb7e4d67d11b2f26ed1ad304b70596Francois Pichet unsigned DiagID = diag::err_mismatched_exception_spec; 3044e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt) 305cf320c6388c90f1938c264e87d77a0e43946e2c3Francois Pichet DiagID = diag::warn_mismatched_exception_spec; 306708f69bcc1be715efd1e9f46266a9c1ead184be6Richard Smith return CheckEquivalentExceptionSpec(PDiag(DiagID), 307fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(diag::note_previous_declaration), 308dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Old, OldLoc, New, NewLoc); 309dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 310dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 31160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl/// CheckEquivalentExceptionSpec - Check if the two types have compatible 31260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl/// exception specifications. See C++ [except.spec]p3. 313444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// 314444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// \return \c false if the exception specifications match, \c true if there is 315444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// a problem. If \c true is returned, either a diagnostic has already been 316444d384a969ce05ae534bf8be3174e308dc8c58bRichard Smith/// produced or \c *MissingExceptionSpecification is set to \c true. 31760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redlbool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID, 3182eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor const PartialDiagnostic & NoteID, 31960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl const FunctionProtoType *Old, 3202eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor SourceLocation OldLoc, 32160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl const FunctionProtoType *New, 3222eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor SourceLocation NewLoc, 3232eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor bool *MissingExceptionSpecification, 32460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl bool*MissingEmptyExceptionSpecification, 32599439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl bool AllowNoexceptAllMatchWithNoSpec, 32699439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl bool IsOperatorNew) { 327811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall // Just completely ignore this under -fno-exceptions. 3284e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CXXExceptions) 329811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall return false; 330811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall 3312eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor if (MissingExceptionSpecification) 3322eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor *MissingExceptionSpecification = false; 3332eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 334e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor if (MissingEmptyExceptionSpecification) 335e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor *MissingEmptyExceptionSpecification = false; 336e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 337e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Old = ResolveExceptionSpec(NewLoc, Old); 338e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!Old) 339e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return false; 340e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith New = ResolveExceptionSpec(NewLoc, New); 341e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!New) 342e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return false; 343e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 34460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // C++0x [except.spec]p3: Two exception-specifications are compatible if: 34560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // - both are non-throwing, regardless of their form, 34660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // - both have the form noexcept(constant-expression) and the constant- 34760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // expressions are equivalent, 34860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // - both are dynamic-exception-specifications that have the same set of 34960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // adjusted types. 35060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // 35160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // C++0x [except.spec]p12: An exception-specifcation is non-throwing if it is 35260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // of the form throw(), noexcept, or noexcept(constant-expression) where the 35360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // constant-expression yields true. 35460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // 35560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // C++0x [except.spec]p4: If any declaration of a function has an exception- 35660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // specifier that is not a noexcept-specification allowing all exceptions, 35760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // all declarations [...] of that function shall have a compatible 35860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // exception-specification. 35960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // 36060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // That last point basically means that noexcept(false) matches no spec. 36160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // It's considered when AllowNoexceptAllMatchWithNoSpec is true. 36260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 36360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ExceptionSpecificationType OldEST = Old->getExceptionSpecType(); 36460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ExceptionSpecificationType NewEST = New->getExceptionSpecType(); 36560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 366b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith assert(!isUnresolvedExceptionSpec(OldEST) && 367b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith !isUnresolvedExceptionSpec(NewEST) && 3687a614d8380297fcd2bc23986241905d97222948cRichard Smith "Shouldn't see unknown exception specifications here"); 3697a614d8380297fcd2bc23986241905d97222948cRichard Smith 37060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Shortcut the case where both have no spec. 37160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST == EST_None && NewEST == EST_None) 37260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 37360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 3748026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(Context); 3758026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(Context); 37660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldNR == FunctionProtoType::NR_BadNoexcept || 37760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NewNR == FunctionProtoType::NR_BadNoexcept) 37860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 37960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 38060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Dependent noexcept specifiers are compatible with each other, but nothing 38160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // else. 38260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // One noexcept is compatible with another if the argument is the same 38360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldNR == NewNR && 38460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl OldNR != FunctionProtoType::NR_NoNoexcept && 38560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NewNR != FunctionProtoType::NR_NoNoexcept) 38660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 38760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldNR != NewNR && 38860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl OldNR != FunctionProtoType::NR_NoNoexcept && 38960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NewNR != FunctionProtoType::NR_NoNoexcept) { 39060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(NewLoc, DiagID); 39160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NoteID.getDiagID() != 0) 39260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(OldLoc, NoteID); 39360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return true; 39460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 39560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 39660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // The MS extension throw(...) is compatible with itself. 39760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST == EST_MSAny && NewEST == EST_MSAny) 39860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 39960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 40060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // It's also compatible with no spec. 40160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if ((OldEST == EST_None && NewEST == EST_MSAny) || 40260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl (OldEST == EST_MSAny && NewEST == EST_None)) 40360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 40460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 40560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // It's also compatible with noexcept(false). 40660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw) 40760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 40860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw) 40960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 41060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 41160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // As described above, noexcept(false) matches no spec only for functions. 41260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (AllowNoexceptAllMatchWithNoSpec) { 41360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw) 41460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 41560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw) 41660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 4175b6f769a6abda4da44186cc8e6a2d6ed37dc9344Douglas Gregor } 4185b6f769a6abda4da44186cc8e6a2d6ed37dc9344Douglas Gregor 41960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Any non-throwing specifications are compatible. 42060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow || 42160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl OldEST == EST_DynamicNone; 42260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow || 42360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl NewEST == EST_DynamicNone; 42460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldNonThrowing && NewNonThrowing) 425dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 42660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 42799439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // As a special compatibility feature, under C++0x we accept no spec and 42899439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // throw(std::bad_alloc) as equivalent for operator new and operator new[]. 42999439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // This is because the implicit declaration changed, but old code would break. 43080ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (getLangOpts().CPlusPlus11 && IsOperatorNew) { 43199439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl const FunctionProtoType *WithExceptions = 0; 43299439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (OldEST == EST_None && NewEST == EST_Dynamic) 43399439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl WithExceptions = New; 43499439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl else if (OldEST == EST_Dynamic && NewEST == EST_None) 43599439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl WithExceptions = Old; 43699439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (WithExceptions && WithExceptions->getNumExceptions() == 1) { 43799439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // One has no spec, the other throw(something). If that something is 43899439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // std::bad_alloc, all conditions are met. 43999439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl QualType Exception = *WithExceptions->exception_begin(); 44099439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) { 44199439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl IdentifierInfo* Name = ExRecord->getIdentifier(); 44299439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (Name && Name->getName() == "bad_alloc") { 44399439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl // It's called bad_alloc, but is it in std? 44499439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl DeclContext* DC = ExRecord->getDeclContext(); 445d8f2e8ed63072ec5a1a8329aa772ae940f1dc3bcSebastian Redl DC = DC->getEnclosingNamespaceContext(); 446d8f2e8ed63072ec5a1a8329aa772ae940f1dc3bcSebastian Redl if (NamespaceDecl* NS = dyn_cast<NamespaceDecl>(DC)) { 44799439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl IdentifierInfo* NSName = NS->getIdentifier(); 448d8f2e8ed63072ec5a1a8329aa772ae940f1dc3bcSebastian Redl DC = DC->getParent(); 44999439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl if (NSName && NSName->getName() == "std" && 450d8f2e8ed63072ec5a1a8329aa772ae940f1dc3bcSebastian Redl DC->getEnclosingNamespaceContext()->isTranslationUnit()) { 45199439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl return false; 452d8f2e8ed63072ec5a1a8329aa772ae940f1dc3bcSebastian Redl } 45399439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 45499439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 45599439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 45699439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 45799439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl } 45899439d474e7cb48497a2da4c35f70cdc1d5b153fSebastian Redl 45960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // At this point, the only remaining valid case is two matching dynamic 46060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // specifications. We return here unless both specifications are dynamic. 46160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) { 4622eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor if (MissingExceptionSpecification && Old->hasExceptionSpec() && 463e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor !New->hasExceptionSpec()) { 4642eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor // The old type has an exception specification of some sort, but 4652eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor // the new type does not. 4662eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor *MissingExceptionSpecification = true; 4672eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 46860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (MissingEmptyExceptionSpecification && OldNonThrowing) { 46960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // The old type has a throw() or noexcept(true) exception specification 47060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // and the new type has no exception specification, and the caller asked 4712eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor // to handle this itself. 4722eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor *MissingEmptyExceptionSpecification = true; 4732eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor } 4742eef829b19bdc59976a827fa39b409440e352bffDouglas Gregor 475e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor return true; 476e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor } 477e13ad837709cd7730e18d8af1cf6b7d35a56d6b7Douglas Gregor 478dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(NewLoc, DiagID); 47937c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (NoteID.getDiagID() != 0) 480dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(OldLoc, NoteID); 481dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 482dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 483dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 48460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic && 48560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl "Exception compatibility logic error: non-dynamic spec slipped through."); 48660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 487dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl bool Success = true; 48860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Both have a dynamic exception spec. Collect the first set, then compare 489dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // to the second. 4901219d150aff23d19ba988e12602db5f3b70e404dSebastian Redl llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes; 491dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl for (FunctionProtoType::exception_iterator I = Old->exception_begin(), 492dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl E = Old->exception_end(); I != E; ++I) 4931219d150aff23d19ba988e12602db5f3b70e404dSebastian Redl OldTypes.insert(Context.getCanonicalType(*I).getUnqualifiedType()); 494dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 495dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl for (FunctionProtoType::exception_iterator I = New->exception_begin(), 4965db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl E = New->exception_end(); I != E && Success; ++I) { 4971219d150aff23d19ba988e12602db5f3b70e404dSebastian Redl CanQualType TypePtr = Context.getCanonicalType(*I).getUnqualifiedType(); 4985db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl if(OldTypes.count(TypePtr)) 4995db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl NewTypes.insert(TypePtr); 5005db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl else 5015db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl Success = false; 5025db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl } 503dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 5045db4d908308576b0fc574138d4aa410c529785a6Sebastian Redl Success = Success && OldTypes.size() == NewTypes.size(); 505dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 506dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (Success) { 507dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 508dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 509dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(NewLoc, DiagID); 51037c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (NoteID.getDiagID() != 0) 511dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(OldLoc, NoteID); 512dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 513dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 514dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 515dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// CheckExceptionSpecSubset - Check whether the second function type's 516dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// exception specification is a subset (or equivalent) of the first function 517dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// type. This is used by override and pointer assignment checks. 51837c38ec5f1c155886929739338110a0b70ac3362Sebastian Redlbool Sema::CheckExceptionSpecSubset( 51937c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, 520dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Superset, SourceLocation SuperLoc, 521dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Subset, SourceLocation SubLoc) { 522811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall 523811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall // Just auto-succeed under -fno-exceptions. 5244e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (!getLangOpts().CXXExceptions) 525811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall return false; 526811d0bec4d4eb6a8ff373f97f98354d6e0e54ecbJohn McCall 527dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // FIXME: As usual, we could be more specific in our error messages, but 528dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // that better waits until we've got types with source locations. 529dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 530dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!SubLoc.isValid()) 531dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl SubLoc = SuperLoc; 532dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 533e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Resolve the exception specifications, if needed. 534e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Superset = ResolveExceptionSpec(SuperLoc, Superset); 535e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!Superset) 536e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return false; 537e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Subset = ResolveExceptionSpec(SubLoc, Subset); 538e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!Subset) 539e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return false; 540e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 54160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType(); 54260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 543dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // If superset contains everything, we're done. 54460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SuperEST == EST_None || SuperEST == EST_MSAny) 54560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 54660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 54760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // If there are dependent noexcept specs, assume everything is fine. Unlike 54860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // with the equivalency check, this is safe in this case, because we don't 54960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // want to merge declarations. Checks after instantiation will catch any 55060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // omissions we make here. 55160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // We also shortcut checking if a noexcept expression was bad. 55260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 5538026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context); 55460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SuperNR == FunctionProtoType::NR_BadNoexcept || 55560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl SuperNR == FunctionProtoType::NR_Dependent) 55660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 55760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 55860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Another case of the superset containing everything. 55960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SuperNR == FunctionProtoType::NR_Throw) 560dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 561dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 56260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl ExceptionSpecificationType SubEST = Subset->getExceptionSpecType(); 56360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 564b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith assert(!isUnresolvedExceptionSpec(SuperEST) && 565b9d0b76e42fd2d4cdfd135220302458d03ad09feRichard Smith !isUnresolvedExceptionSpec(SubEST) && 5667a614d8380297fcd2bc23986241905d97222948cRichard Smith "Shouldn't see unknown exception specifications here"); 5677a614d8380297fcd2bc23986241905d97222948cRichard Smith 568dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // It does not. If the subset contains everything, we've failed. 56960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SubEST == EST_None || SubEST == EST_MSAny) { 57060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(SubLoc, DiagID); 57160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NoteID.getDiagID() != 0) 57260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(SuperLoc, NoteID); 57360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return true; 57460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 57560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 5768026f6d82f7fa544bc0453714fe94bca62a1196eSebastian Redl FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context); 57760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SubNR == FunctionProtoType::NR_BadNoexcept || 57860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl SubNR == FunctionProtoType::NR_Dependent) 57960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return false; 58060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 58160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Another case of the subset containing everything. 58260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SubNR == FunctionProtoType::NR_Throw) { 58360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(SubLoc, DiagID); 58460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (NoteID.getDiagID() != 0) 58560618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl Diag(SuperLoc, NoteID); 58660618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return true; 58760618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl } 58860618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 58960618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // If the subset contains nothing, we're done. 59060618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow) 59160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 59260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 59360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Otherwise, if the superset contains nothing, we've failed. 59460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) { 595dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(SubLoc, DiagID); 59637c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (NoteID.getDiagID() != 0) 597dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(SuperLoc, NoteID); 598dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 599dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 600dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 60160618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic && 60260618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl "Exception spec subset: non-dynamic case slipped through."); 60360618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl 60460618fa7f88d5162bb5b40988b6b38d4d75d6fc6Sebastian Redl // Neither contains everything or nothing. Do a proper comparison. 605dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl for (FunctionProtoType::exception_iterator SubI = Subset->exception_begin(), 606dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl SubE = Subset->exception_end(); SubI != SubE; ++SubI) { 607dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Take one type from the subset. 608dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl QualType CanonicalSubT = Context.getCanonicalType(*SubI); 609c3a3b7b38440384944614ea6e93cf8d238d3d5f2Sebastian Redl // Unwrap pointers and references so that we can do checks within a class 610c3a3b7b38440384944614ea6e93cf8d238d3d5f2Sebastian Redl // hierarchy. Don't unwrap member pointers; they don't have hierarchy 611c3a3b7b38440384944614ea6e93cf8d238d3d5f2Sebastian Redl // conversions on the pointee. 612dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl bool SubIsPointer = false; 613dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>()) 614dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CanonicalSubT = RefTy->getPointeeType(); 615dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) { 616dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CanonicalSubT = PtrTy->getPointeeType(); 617dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl SubIsPointer = true; 618dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 619dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl bool SubIsClass = CanonicalSubT->isRecordType(); 620a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType(); 621dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 622dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 623dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl /*DetectVirtual=*/false); 624dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 625dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl bool Contained = false; 626dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Make sure it's in the superset. 627dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl for (FunctionProtoType::exception_iterator SuperI = 628dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Superset->exception_begin(), SuperE = Superset->exception_end(); 629dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl SuperI != SuperE; ++SuperI) { 630dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl QualType CanonicalSuperT = Context.getCanonicalType(*SuperI); 631dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // SubT must be SuperT or derived from it, or pointer or reference to 632dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // such types. 633dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>()) 634dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CanonicalSuperT = RefTy->getPointeeType(); 635dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (SubIsPointer) { 636dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>()) 637dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl CanonicalSuperT = PtrTy->getPointeeType(); 638dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl else { 639dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl continue; 640dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 641dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 642a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType(); 643dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // If the types are the same, move on to the next type in the subset. 644dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (CanonicalSubT == CanonicalSuperT) { 645dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Contained = true; 646dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl break; 647dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 648dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 649dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Otherwise we need to check the inheritance. 650dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!SubIsClass || !CanonicalSuperT->isRecordType()) 651dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl continue; 652dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 653dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Paths.clear(); 654dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!IsDerivedFrom(CanonicalSubT, CanonicalSuperT, Paths)) 655dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl continue; 656dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 657e0d5fe2a417b84ac8b51927ebeb8f1c9ae492760Douglas Gregor if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT))) 658dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl continue; 659dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 6606b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall // Do this check from a context without privileges. 66158e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall switch (CheckBaseClassAccess(SourceLocation(), 6626b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall CanonicalSuperT, CanonicalSubT, 6636b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall Paths.front(), 66458e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall /*Diagnostic*/ 0, 6656b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall /*ForceCheck*/ true, 66658e6f34e4d2c668562e1c391162ee9de7b05fbb2John McCall /*ForceUnprivileged*/ true)) { 6676b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall case AR_accessible: break; 6686b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall case AR_inaccessible: continue; 6696b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall case AR_dependent: 6706b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall llvm_unreachable("access check dependent for unprivileged context"); 6716b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall case AR_delayed: 6726b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall llvm_unreachable("access check delayed in non-declaration"); 6736b2accb4793e16b2e93a8c2589f5df702231f17aJohn McCall } 674dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 675dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Contained = true; 676dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl break; 677dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 678dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!Contained) { 679dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(SubLoc, DiagID); 68037c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (NoteID.getDiagID() != 0) 681dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Diag(SuperLoc, NoteID); 682dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 683dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 684dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 685dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // We've run half the gauntlet. 686dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return CheckParamExceptionSpec(NoteID, Superset, SuperLoc, Subset, SubLoc); 687dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 688dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 689dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlstatic bool CheckSpecForTypesEquivalent(Sema &S, 69037c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl const PartialDiagnostic &DiagID, const PartialDiagnostic & NoteID, 691dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl QualType Target, SourceLocation TargetLoc, 692dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl QualType Source, SourceLocation SourceLoc) 693dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl{ 694dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *TFunc = GetUnderlyingFunction(Target); 695dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!TFunc) 696dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 697dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *SFunc = GetUnderlyingFunction(Source); 698dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!SFunc) 699dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 700dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 701dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc, 702dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl SFunc, SourceLoc); 703dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 704dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 705dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// CheckParamExceptionSpec - Check if the parameter and return types of the 706dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// two functions have equivalent exception specs. This is part of the 707dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// assignment and override compatibility check. We do not check the parameters 708dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// of parameter function pointers recursively, as no sane programmer would 709dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl/// even be able to write such a function type. 71037c38ec5f1c155886929739338110a0b70ac3362Sebastian Redlbool Sema::CheckParamExceptionSpec(const PartialDiagnostic & NoteID, 711dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Target, SourceLocation TargetLoc, 712dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *Source, SourceLocation SourceLoc) 713dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl{ 71437c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (CheckSpecForTypesEquivalent(*this, 715fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(diag::err_deep_exception_specs_differ) << 0, 716fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(), 717dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Target->getResultType(), TargetLoc, 718dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Source->getResultType(), SourceLoc)) 719dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 720dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 72137c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl // We shouldn't even be testing this unless the arguments are otherwise 722dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // compatible. 723dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl assert(Target->getNumArgs() == Source->getNumArgs() && 724dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl "Functions have different argument counts."); 725dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl for (unsigned i = 0, E = Target->getNumArgs(); i != E; ++i) { 72637c38ec5f1c155886929739338110a0b70ac3362Sebastian Redl if (CheckSpecForTypesEquivalent(*this, 727fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(diag::err_deep_exception_specs_differ) << 1, 728fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(), 729dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Target->getArgType(i), TargetLoc, 730dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Source->getArgType(i), SourceLoc)) 731dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return true; 732dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl } 733dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 734dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 735dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 736dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlbool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) 737dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl{ 738dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // First we check for applicability. 739dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Target type must be a function, function pointer or function reference. 740dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType); 741dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!ToFunc) 742dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 743dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 744dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // SourceType must be a function or function pointer. 745dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType()); 746dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl if (!FromFunc) 747dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl return false; 748dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 749dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // Now we've got the correct types on both sides, check their compatibility. 750dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // This means that the source of the conversion can only throw a subset of 751dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // the exceptions of the target, and any exception specs on arguments or 752dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl // return types must be equivalent. 753fe6b2d481d91140923f4541f273b253291884214Douglas Gregor return CheckExceptionSpecSubset(PDiag(diag::err_incompatible_exception_specs), 754fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(), ToFunc, 755fe6b2d481d91140923f4541f273b253291884214Douglas Gregor From->getSourceRange().getBegin(), 756dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl FromFunc, SourceLocation()); 757dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 758dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 759dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redlbool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, 760dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl const CXXMethodDecl *Old) { 76180ad52f327b532bded5c5b0ee38779d841c6cd35Richard Smith if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) { 762a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl // Don't check uninstantiated template destructors at all. We can only 763a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl // synthesize correct specs after the template is instantiated. 764a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl if (New->getParent()->isDependentType()) 765a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl return false; 766a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl if (New->getParent()->isBeingDefined()) { 767a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl // The destructor might be updated once the definition is finished. So 768a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl // remember it and check later. 769a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl DelayedDestructorExceptionSpecChecks.push_back(std::make_pair( 770a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl cast<CXXDestructorDecl>(New), cast<CXXDestructorDecl>(Old))); 771a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl return false; 772a0448264c7da395ca9416c6570bc43a7f49e436bSebastian Redl } 7730ee33912f8ec3453856c8a32ed2c2e8007bed614Sebastian Redl } 7740f161593b36584ec447e5268dbed2953489854d8Francois Pichet unsigned DiagID = diag::err_override_exception_spec; 7754e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().MicrosoftExt) 7760f161593b36584ec447e5268dbed2953489854d8Francois Pichet DiagID = diag::warn_override_exception_spec; 7770f161593b36584ec447e5268dbed2953489854d8Francois Pichet return CheckExceptionSpecSubset(PDiag(DiagID), 778fe6b2d481d91140923f4541f273b253291884214Douglas Gregor PDiag(diag::note_overridden_virtual_function), 779dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Old->getType()->getAs<FunctionProtoType>(), 780dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl Old->getLocation(), 781dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl New->getType()->getAs<FunctionProtoType>(), 782dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl New->getLocation()); 783dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} 784dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl 785e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smithstatic CanThrowResult canSubExprsThrow(Sema &S, const Expr *CE) { 786e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Expr *E = const_cast<Expr*>(CE); 787e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult R = CT_Cannot; 788e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith for (Expr::child_range I = E->children(); I && R != CT_Can; ++I) 789e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith R = mergeCanThrow(R, S.canThrow(cast<Expr>(*I))); 790e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return R; 791e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 792e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 79372aa4c431b650800140457636c8481fd965f1534Eli Friedmanstatic CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D) { 79472aa4c431b650800140457636c8481fd965f1534Eli Friedman assert(D && "Expected decl"); 795e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 796e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // See if we can get a function type from the decl somehow. 797e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const ValueDecl *VD = dyn_cast<ValueDecl>(D); 798e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!VD) // If we have no clue what we're calling, assume the worst. 799e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 800e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 801e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // As an extension, we assume that __attribute__((nothrow)) functions don't 802e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // throw. 803e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>()) 804e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 805e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 806e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith QualType T = VD->getType(); 807e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const FunctionProtoType *FT; 808e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if ((FT = T->getAs<FunctionProtoType>())) { 809e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } else if (const PointerType *PT = T->getAs<PointerType>()) 810e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = PT->getPointeeType()->getAs<FunctionProtoType>(); 811e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else if (const ReferenceType *RT = T->getAs<ReferenceType>()) 812e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = RT->getPointeeType()->getAs<FunctionProtoType>(); 813e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else if (const MemberPointerType *MT = T->getAs<MemberPointerType>()) 814e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = MT->getPointeeType()->getAs<FunctionProtoType>(); 815e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) 816e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = BT->getPointeeType()->getAs<FunctionProtoType>(); 817e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 818e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!FT) 819e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 820e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 821e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith FT = S.ResolveExceptionSpec(E->getLocStart(), FT); 822e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!FT) 823e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 824e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 825e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can; 826e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 827e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 828e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smithstatic CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) { 829e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (DC->isTypeDependent()) 830e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 831e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 832e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!DC->getTypeAsWritten()->isReferenceType()) 833e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 834e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 835e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (DC->getSubExpr()->isTypeDependent()) 836e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 837e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 838e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot; 839e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 840e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 841e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smithstatic CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) { 842e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (DC->isTypeOperand()) 843e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 844e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 845e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Expr *Op = DC->getExprOperand(); 846e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (Op->isTypeDependent()) 847e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 848e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 849e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const RecordType *RT = Op->getType()->getAs<RecordType>(); 850e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!RT) 851e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 852e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 853e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic()) 854e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 855e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 856e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (Op->Classify(S.Context).isPRValue()) 857e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 858e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 859e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 860e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 861e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 862e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard SmithCanThrowResult Sema::canThrow(const Expr *E) { 863e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // C++ [expr.unary.noexcept]p3: 864e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // [Can throw] if in a potentially-evaluated context the expression would 865e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // contain: 866e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith switch (E->getStmtClass()) { 867e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXThrowExprClass: 868e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // - a potentially evaluated throw-expression 869e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 870e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 871e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXDynamicCastExprClass: { 872e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v), 873e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // where T is a reference type, that requires a run-time check 874e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E)); 875e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 876e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 877e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 878e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 879e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 880e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXTypeidExprClass: 881e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // - a potentially evaluated typeid expression applied to a glvalue 882e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // expression whose type is a polymorphic class type 883e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return canTypeidThrow(*this, cast<CXXTypeidExpr>(E)); 884e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 885e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // - a potentially evaluated call to a function, member function, function 886e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // pointer, or member function pointer that does not have a non-throwing 887e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // exception-specification 888e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CallExprClass: 889e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXMemberCallExprClass: 890e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXOperatorCallExprClass: 891e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UserDefinedLiteralClass: { 892e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const CallExpr *CE = cast<CallExpr>(E); 893e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT; 894e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (E->isTypeDependent()) 895e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = CT_Dependent; 896e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) 897e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = CT_Cannot; 898f9b4fea4bf6cebe614e49ab4b582dcf4bf0a6806Eli Friedman else if (CE->getCalleeDecl()) 899e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = canCalleeThrow(*this, E, CE->getCalleeDecl()); 900f9b4fea4bf6cebe614e49ab4b582dcf4bf0a6806Eli Friedman else 901f9b4fea4bf6cebe614e49ab4b582dcf4bf0a6806Eli Friedman CT = CT_Can; 902e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 903e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 904e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 905e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 906e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 907e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXConstructExprClass: 908e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXTemporaryObjectExprClass: { 909e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = canCalleeThrow(*this, E, 910e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith cast<CXXConstructExpr>(E)->getConstructor()); 911e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 912e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 913e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 914e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 915e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 916e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::LambdaExprClass: { 917e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const LambdaExpr *Lambda = cast<LambdaExpr>(E); 918e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = CT_Cannot; 919e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith for (LambdaExpr::capture_init_iterator Cap = Lambda->capture_init_begin(), 920e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CapEnd = Lambda->capture_init_end(); 921e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith Cap != CapEnd; ++Cap) 922e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = mergeCanThrow(CT, canThrow(*Cap)); 923e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 924e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 925e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 926e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXNewExprClass: { 927e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT; 928e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (E->isTypeDependent()) 929e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = CT_Dependent; 930e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith else 931e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew()); 932e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 933e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 934e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 935e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 936e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 937e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXDeleteExprClass: { 938e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT; 939e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType(); 940e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (DTy.isNull() || DTy->isDependentType()) { 941e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = CT_Dependent; 942e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } else { 943e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CT = canCalleeThrow(*this, E, 944e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith cast<CXXDeleteExpr>(E)->getOperatorDelete()); 945e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (const RecordType *RT = DTy->getAs<RecordType>()) { 946e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 94772aa4c431b650800140457636c8481fd965f1534Eli Friedman const CXXDestructorDecl *DD = RD->getDestructor(); 94872aa4c431b650800140457636c8481fd965f1534Eli Friedman if (DD) 94972aa4c431b650800140457636c8481fd965f1534Eli Friedman CT = mergeCanThrow(CT, canCalleeThrow(*this, E, DD)); 950e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 951e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 952e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 953e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 954e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 955e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 956e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 957e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXBindTemporaryExprClass: { 958e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // The bound temporary has to be destroyed again, which might throw. 959e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = canCalleeThrow(*this, E, 960e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor()); 961e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (CT == CT_Can) 962e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT; 963e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 964e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 965e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 966e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // ObjC message sends are like function calls, but never have exception 967e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // specs. 968e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCMessageExprClass: 969e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCPropertyRefExprClass: 970e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCSubscriptRefExprClass: 971e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 972e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 973e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // All the ObjC literals that are implemented as calls are 974e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // potentially throwing unless we decide to close off that 975e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // possibility. 976e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCArrayLiteralClass: 977e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCDictionaryLiteralClass: 978eb382ec1507cf2c8c12d7443d0b67c076223aec6Patrick Beard case Expr::ObjCBoxedExprClass: 979e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 980e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 981e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Many other things have subexpressions, so we have to test those. 982e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Some are simple: 983e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ConditionalOperatorClass: 984e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CompoundLiteralExprClass: 985e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXConstCastExprClass: 986e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXReinterpretCastExprClass: 9877c3e615f01e8f9f587315800fdaf2305ed824568Richard Smith case Expr::CXXStdInitializerListExprClass: 988e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::DesignatedInitExprClass: 989e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ExprWithCleanupsClass: 990e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ExtVectorElementExprClass: 991e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::InitListExprClass: 992e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::MemberExprClass: 993e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCIsaExprClass: 994e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCIvarRefExprClass: 995e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ParenExprClass: 996e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ParenListExprClass: 997e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ShuffleVectorExprClass: 998e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::VAArgExprClass: 999e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return canSubExprsThrow(*this, E); 1000e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1001e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Some might be dependent for other reasons. 1002e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ArraySubscriptExprClass: 1003e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::BinaryOperatorClass: 1004e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CompoundAssignOperatorClass: 1005e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CStyleCastExprClass: 1006e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXStaticCastExprClass: 1007e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXFunctionalCastExprClass: 1008e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ImplicitCastExprClass: 1009e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::MaterializeTemporaryExprClass: 1010e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnaryOperatorClass: { 1011e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot; 1012e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return mergeCanThrow(CT, canSubExprsThrow(*this, E)); 1013e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 1014e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1015e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms. 1016e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::StmtExprClass: 1017e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Can; 1018e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1019c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith case Expr::CXXDefaultArgExprClass: 1020c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith return canThrow(cast<CXXDefaultArgExpr>(E)->getExpr()); 1021c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith 1022c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith case Expr::CXXDefaultInitExprClass: 1023c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith return canThrow(cast<CXXDefaultInitExpr>(E)->getExpr()); 1024c3bf52ced9652f555aa0767bb822ec4c64546212Richard Smith 1025e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ChooseExprClass: 1026e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (E->isTypeDependent() || E->isValueDependent()) 1027e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 1028a5e660188a3c654cf0c88ed1093b28207e870b2bEli Friedman return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr()); 1029e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1030e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::GenericSelectionExprClass: 1031e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith if (cast<GenericSelectionExpr>(E)->isResultDependent()) 1032e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 1033e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr()); 1034e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1035e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // Some expressions are always dependent. 1036e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXDependentScopeMemberExprClass: 1037e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXUnresolvedConstructExprClass: 1038e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::DependentScopeDeclRefExprClass: 1039e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Dependent; 1040e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1041e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::AsTypeExprClass: 1042e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::BinaryConditionalOperatorClass: 1043e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::BlockExprClass: 1044e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CUDAKernelCallExprClass: 1045e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::DeclRefExprClass: 1046e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCBridgedCastExprClass: 1047e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCIndirectCopyRestoreExprClass: 1048e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCProtocolExprClass: 1049e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCSelectorExprClass: 1050e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::OffsetOfExprClass: 1051e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::PackExpansionExprClass: 1052e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::PseudoObjectExprClass: 1053e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::SubstNonTypeTemplateParmExprClass: 1054e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::SubstNonTypeTemplateParmPackExprClass: 10559a4db032ecd991626d236a502e770126db32bd31Richard Smith case Expr::FunctionParmPackExprClass: 1056e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnaryExprOrTypeTraitExprClass: 1057e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnresolvedLookupExprClass: 1058e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnresolvedMemberExprClass: 1059e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // FIXME: Can any of the above throw? If so, when? 1060e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 1061e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1062e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::AddrLabelExprClass: 1063e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ArrayTypeTraitExprClass: 1064e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::AtomicExprClass: 1065e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::BinaryTypeTraitExprClass: 1066e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::TypeTraitExprClass: 1067e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXBoolLiteralExprClass: 1068e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXNoexceptExprClass: 1069e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXNullPtrLiteralExprClass: 1070e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXPseudoDestructorExprClass: 1071e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXScalarValueInitExprClass: 1072e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXThisExprClass: 1073e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CXXUuidofExprClass: 1074e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::CharacterLiteralClass: 1075e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ExpressionTraitExprClass: 1076e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::FloatingLiteralClass: 1077e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::GNUNullExprClass: 1078e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ImaginaryLiteralClass: 1079e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ImplicitValueInitExprClass: 1080e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::IntegerLiteralClass: 1081e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCEncodeExprClass: 1082e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCStringLiteralClass: 1083e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::ObjCBoolLiteralExprClass: 1084e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::OpaqueValueExprClass: 1085e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::PredefinedExprClass: 1086e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::SizeOfPackExprClass: 1087e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::StringLiteralClass: 1088e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::UnaryTypeTraitExprClass: 1089e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith // These expressions can never throw. 1090e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith return CT_Cannot; 1091e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 109276da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall case Expr::MSPropertyRefExprClass: 109376da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall llvm_unreachable("Invalid class for expression"); 109476da55d3a49e1805f51b1ced7c5da5bcd7f759d8John McCall 1095e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define STMT(CLASS, PARENT) case Expr::CLASS##Class: 1096e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define STMT_RANGE(Base, First, Last) 1097e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define LAST_STMT_RANGE(BASE, FIRST, LAST) 1098e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define EXPR(CLASS, PARENT) 1099e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#define ABSTRACT_STMT(STMT) 1100e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith#include "clang/AST/StmtNodes.inc" 1101e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith case Expr::NoStmtClass: 1102e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith llvm_unreachable("Invalid class for expression"); 1103e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith } 1104e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith llvm_unreachable("Bogus StmtClass"); 1105e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith} 1106e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith 1107dced226e37f7c2c31c25d06c514f29b610fe2a54Sebastian Redl} // end namespace clang 1108