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