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