1//===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides Sema routines for C++ exception specification testing.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/Sema/SemaInternal.h"
14#include "clang/AST/ASTMutationListener.h"
15#include "clang/AST/CXXInheritance.h"
16#include "clang/AST/Expr.h"
17#include "clang/AST/ExprCXX.h"
18#include "clang/AST/StmtObjC.h"
19#include "clang/AST/TypeLoc.h"
20#include "clang/Basic/Diagnostic.h"
21#include "clang/Basic/SourceManager.h"
22#include "llvm/ADT/SmallPtrSet.h"
23#include "llvm/ADT/SmallString.h"
24
25namespace clang {
26
27static const FunctionProtoType *GetUnderlyingFunction(QualType T)
28{
29  if (const PointerType *PtrTy = T->getAs<PointerType>())
30    T = PtrTy->getPointeeType();
31  else if (const ReferenceType *RefTy = T->getAs<ReferenceType>())
32    T = RefTy->getPointeeType();
33  else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
34    T = MPTy->getPointeeType();
35  return T->getAs<FunctionProtoType>();
36}
37
38/// HACK: 2014-11-14 libstdc++ had a bug where it shadows std::swap with a
39/// member swap function then tries to call std::swap unqualified from the
40/// exception specification of that function. This function detects whether
41/// we're in such a case and turns off delay-parsing of exception
42/// specifications. Libstdc++ 6.1 (released 2016-04-27) appears to have
43/// resolved it as side-effect of commit ddb63209a8d (2015-06-05).
44bool Sema::isLibstdcxxEagerExceptionSpecHack(const Declarator &D) {
45  auto *RD = dyn_cast<CXXRecordDecl>(CurContext);
46
47  // All the problem cases are member functions named "swap" within class
48  // templates declared directly within namespace std or std::__debug or
49  // std::__profile.
50  if (!RD || !RD->getIdentifier() || !RD->getDescribedClassTemplate() ||
51      !D.getIdentifier() || !D.getIdentifier()->isStr("swap"))
52    return false;
53
54  auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext());
55  if (!ND)
56    return false;
57
58  bool IsInStd = ND->isStdNamespace();
59  if (!IsInStd) {
60    // This isn't a direct member of namespace std, but it might still be
61    // libstdc++'s std::__debug::array or std::__profile::array.
62    IdentifierInfo *II = ND->getIdentifier();
63    if (!II || !(II->isStr("__debug") || II->isStr("__profile")) ||
64        !ND->isInStdNamespace())
65      return false;
66  }
67
68  // Only apply this hack within a system header.
69  if (!Context.getSourceManager().isInSystemHeader(D.getBeginLoc()))
70    return false;
71
72  return llvm::StringSwitch<bool>(RD->getIdentifier()->getName())
73      .Case("array", true)
74      .Case("pair", IsInStd)
75      .Case("priority_queue", IsInStd)
76      .Case("stack", IsInStd)
77      .Case("queue", IsInStd)
78      .Default(false);
79}
80
81ExprResult Sema::ActOnNoexceptSpec(SourceLocation NoexceptLoc,
82                                   Expr *NoexceptExpr,
83                                   ExceptionSpecificationType &EST) {
84  // FIXME: This is bogus, a noexcept expression is not a condition.
85  ExprResult Converted = CheckBooleanCondition(NoexceptLoc, NoexceptExpr);
86  if (Converted.isInvalid()) {
87    EST = EST_NoexceptFalse;
88
89    // Fill in an expression of 'false' as a fixup.
90    auto *BoolExpr = new (Context)
91        CXXBoolLiteralExpr(false, Context.BoolTy, NoexceptExpr->getBeginLoc());
92    llvm::APSInt Value{1};
93    Value = 0;
94    return ConstantExpr::Create(Context, BoolExpr, APValue{Value});
95  }
96
97  if (Converted.get()->isValueDependent()) {
98    EST = EST_DependentNoexcept;
99    return Converted;
100  }
101
102  llvm::APSInt Result;
103  Converted = VerifyIntegerConstantExpression(
104      Converted.get(), &Result, diag::err_noexcept_needs_constant_expression);
105  if (!Converted.isInvalid())
106    EST = !Result ? EST_NoexceptFalse : EST_NoexceptTrue;
107  return Converted;
108}
109
110/// CheckSpecifiedExceptionType - Check if the given type is valid in an
111/// exception specification. Incomplete types, or pointers to incomplete types
112/// other than void are not allowed.
113///
114/// \param[in,out] T  The exception type. This will be decayed to a pointer type
115///                   when the input is an array or a function type.
116bool Sema::CheckSpecifiedExceptionType(QualType &T, SourceRange Range) {
117  // C++11 [except.spec]p2:
118  //   A type cv T, "array of T", or "function returning T" denoted
119  //   in an exception-specification is adjusted to type T, "pointer to T", or
120  //   "pointer to function returning T", respectively.
121  //
122  // We also apply this rule in C++98.
123  if (T->isArrayType())
124    T = Context.getArrayDecayedType(T);
125  else if (T->isFunctionType())
126    T = Context.getPointerType(T);
127
128  int Kind = 0;
129  QualType PointeeT = T;
130  if (const PointerType *PT = T->getAs<PointerType>()) {
131    PointeeT = PT->getPointeeType();
132    Kind = 1;
133
134    // cv void* is explicitly permitted, despite being a pointer to an
135    // incomplete type.
136    if (PointeeT->isVoidType())
137      return false;
138  } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
139    PointeeT = RT->getPointeeType();
140    Kind = 2;
141
142    if (RT->isRValueReferenceType()) {
143      // C++11 [except.spec]p2:
144      //   A type denoted in an exception-specification shall not denote [...]
145      //   an rvalue reference type.
146      Diag(Range.getBegin(), diag::err_rref_in_exception_spec)
147        << T << Range;
148      return true;
149    }
150  }
151
152  // C++11 [except.spec]p2:
153  //   A type denoted in an exception-specification shall not denote an
154  //   incomplete type other than a class currently being defined [...].
155  //   A type denoted in an exception-specification shall not denote a
156  //   pointer or reference to an incomplete type, other than (cv) void* or a
157  //   pointer or reference to a class currently being defined.
158  // In Microsoft mode, downgrade this to a warning.
159  unsigned DiagID = diag::err_incomplete_in_exception_spec;
160  bool ReturnValueOnError = true;
161  if (getLangOpts().MSVCCompat) {
162    DiagID = diag::ext_incomplete_in_exception_spec;
163    ReturnValueOnError = false;
164  }
165  if (!(PointeeT->isRecordType() &&
166        PointeeT->castAs<RecordType>()->isBeingDefined()) &&
167      RequireCompleteType(Range.getBegin(), PointeeT, DiagID, Kind, Range))
168    return ReturnValueOnError;
169
170  // The MSVC compatibility mode doesn't extend to sizeless types,
171  // so diagnose them separately.
172  if (PointeeT->isSizelessType() && Kind != 1) {
173    Diag(Range.getBegin(), diag::err_sizeless_in_exception_spec)
174        << (Kind == 2 ? 1 : 0) << PointeeT << Range;
175    return true;
176  }
177
178  return false;
179}
180
181/// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer
182/// to member to a function with an exception specification. This means that
183/// it is invalid to add another level of indirection.
184bool Sema::CheckDistantExceptionSpec(QualType T) {
185  // C++17 removes this rule in favor of putting exception specifications into
186  // the type system.
187  if (getLangOpts().CPlusPlus17)
188    return false;
189
190  if (const PointerType *PT = T->getAs<PointerType>())
191    T = PT->getPointeeType();
192  else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
193    T = PT->getPointeeType();
194  else
195    return false;
196
197  const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
198  if (!FnT)
199    return false;
200
201  return FnT->hasExceptionSpec();
202}
203
204const FunctionProtoType *
205Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) {
206  if (FPT->getExceptionSpecType() == EST_Unparsed) {
207    Diag(Loc, diag::err_exception_spec_not_parsed);
208    return nullptr;
209  }
210
211  if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
212    return FPT;
213
214  FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl();
215  const FunctionProtoType *SourceFPT =
216      SourceDecl->getType()->castAs<FunctionProtoType>();
217
218  // If the exception specification has already been resolved, just return it.
219  if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType()))
220    return SourceFPT;
221
222  // Compute or instantiate the exception specification now.
223  if (SourceFPT->getExceptionSpecType() == EST_Unevaluated)
224    EvaluateImplicitExceptionSpec(Loc, SourceDecl);
225  else
226    InstantiateExceptionSpec(Loc, SourceDecl);
227
228  const FunctionProtoType *Proto =
229    SourceDecl->getType()->castAs<FunctionProtoType>();
230  if (Proto->getExceptionSpecType() == clang::EST_Unparsed) {
231    Diag(Loc, diag::err_exception_spec_not_parsed);
232    Proto = nullptr;
233  }
234  return Proto;
235}
236
237void
238Sema::UpdateExceptionSpec(FunctionDecl *FD,
239                          const FunctionProtoType::ExceptionSpecInfo &ESI) {
240  // If we've fully resolved the exception specification, notify listeners.
241  if (!isUnresolvedExceptionSpec(ESI.Type))
242    if (auto *Listener = getASTMutationListener())
243      Listener->ResolvedExceptionSpec(FD);
244
245  for (FunctionDecl *Redecl : FD->redecls())
246    Context.adjustExceptionSpec(Redecl, ESI);
247}
248
249static bool exceptionSpecNotKnownYet(const FunctionDecl *FD) {
250  auto *MD = dyn_cast<CXXMethodDecl>(FD);
251  if (!MD)
252    return false;
253
254  auto EST = MD->getType()->castAs<FunctionProtoType>()->getExceptionSpecType();
255  return EST == EST_Unparsed ||
256         (EST == EST_Unevaluated && MD->getParent()->isBeingDefined());
257}
258
259static bool CheckEquivalentExceptionSpecImpl(
260    Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID,
261    const FunctionProtoType *Old, SourceLocation OldLoc,
262    const FunctionProtoType *New, SourceLocation NewLoc,
263    bool *MissingExceptionSpecification = nullptr,
264    bool *MissingEmptyExceptionSpecification = nullptr,
265    bool AllowNoexceptAllMatchWithNoSpec = false, bool IsOperatorNew = false);
266
267/// Determine whether a function has an implicitly-generated exception
268/// specification.
269static bool hasImplicitExceptionSpec(FunctionDecl *Decl) {
270  if (!isa<CXXDestructorDecl>(Decl) &&
271      Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete &&
272      Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
273    return false;
274
275  // For a function that the user didn't declare:
276  //  - if this is a destructor, its exception specification is implicit.
277  //  - if this is 'operator delete' or 'operator delete[]', the exception
278  //    specification is as-if an explicit exception specification was given
279  //    (per [basic.stc.dynamic]p2).
280  if (!Decl->getTypeSourceInfo())
281    return isa<CXXDestructorDecl>(Decl);
282
283  auto *Ty = Decl->getTypeSourceInfo()->getType()->castAs<FunctionProtoType>();
284  return !Ty->hasExceptionSpec();
285}
286
287bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
288  // Just completely ignore this under -fno-exceptions prior to C++17.
289  // In C++17 onwards, the exception specification is part of the type and
290  // we will diagnose mismatches anyway, so it's better to check for them here.
291  if (!getLangOpts().CXXExceptions && !getLangOpts().CPlusPlus17)
292    return false;
293
294  OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator();
295  bool IsOperatorNew = OO == OO_New || OO == OO_Array_New;
296  bool MissingExceptionSpecification = false;
297  bool MissingEmptyExceptionSpecification = false;
298
299  unsigned DiagID = diag::err_mismatched_exception_spec;
300  bool ReturnValueOnError = true;
301  if (getLangOpts().MSVCCompat) {
302    DiagID = diag::ext_mismatched_exception_spec;
303    ReturnValueOnError = false;
304  }
305
306  // If we're befriending a member function of a class that's currently being
307  // defined, we might not be able to work out its exception specification yet.
308  // If not, defer the check until later.
309  if (exceptionSpecNotKnownYet(Old) || exceptionSpecNotKnownYet(New)) {
310    DelayedEquivalentExceptionSpecChecks.push_back({New, Old});
311    return false;
312  }
313
314  // Check the types as written: they must match before any exception
315  // specification adjustment is applied.
316  if (!CheckEquivalentExceptionSpecImpl(
317        *this, PDiag(DiagID), PDiag(diag::note_previous_declaration),
318        Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(),
319        New->getType()->getAs<FunctionProtoType>(), New->getLocation(),
320        &MissingExceptionSpecification, &MissingEmptyExceptionSpecification,
321        /*AllowNoexceptAllMatchWithNoSpec=*/true, IsOperatorNew)) {
322    // C++11 [except.spec]p4 [DR1492]:
323    //   If a declaration of a function has an implicit
324    //   exception-specification, other declarations of the function shall
325    //   not specify an exception-specification.
326    if (getLangOpts().CPlusPlus11 && getLangOpts().CXXExceptions &&
327        hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) {
328      Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch)
329        << hasImplicitExceptionSpec(Old);
330      if (Old->getLocation().isValid())
331        Diag(Old->getLocation(), diag::note_previous_declaration);
332    }
333    return false;
334  }
335
336  // The failure was something other than an missing exception
337  // specification; return an error, except in MS mode where this is a warning.
338  if (!MissingExceptionSpecification)
339    return ReturnValueOnError;
340
341  const FunctionProtoType *NewProto =
342    New->getType()->castAs<FunctionProtoType>();
343
344  // The new function declaration is only missing an empty exception
345  // specification "throw()". If the throw() specification came from a
346  // function in a system header that has C linkage, just add an empty
347  // exception specification to the "new" declaration. Note that C library
348  // implementations are permitted to add these nothrow exception
349  // specifications.
350  //
351  // Likewise if the old function is a builtin.
352  if (MissingEmptyExceptionSpecification && NewProto &&
353      (Old->getLocation().isInvalid() ||
354       Context.getSourceManager().isInSystemHeader(Old->getLocation()) ||
355       Old->getBuiltinID()) &&
356      Old->isExternC()) {
357    New->setType(Context.getFunctionType(
358        NewProto->getReturnType(), NewProto->getParamTypes(),
359        NewProto->getExtProtoInfo().withExceptionSpec(EST_DynamicNone)));
360    return false;
361  }
362
363  const FunctionProtoType *OldProto =
364    Old->getType()->castAs<FunctionProtoType>();
365
366  FunctionProtoType::ExceptionSpecInfo ESI = OldProto->getExceptionSpecType();
367  if (ESI.Type == EST_Dynamic) {
368    // FIXME: What if the exceptions are described in terms of the old
369    // prototype's parameters?
370    ESI.Exceptions = OldProto->exceptions();
371  }
372
373  if (ESI.Type == EST_NoexceptFalse)
374    ESI.Type = EST_None;
375  if (ESI.Type == EST_NoexceptTrue)
376    ESI.Type = EST_BasicNoexcept;
377
378  // For dependent noexcept, we can't just take the expression from the old
379  // prototype. It likely contains references to the old prototype's parameters.
380  if (ESI.Type == EST_DependentNoexcept) {
381    New->setInvalidDecl();
382  } else {
383    // Update the type of the function with the appropriate exception
384    // specification.
385    New->setType(Context.getFunctionType(
386        NewProto->getReturnType(), NewProto->getParamTypes(),
387        NewProto->getExtProtoInfo().withExceptionSpec(ESI)));
388  }
389
390  if (getLangOpts().MSVCCompat && ESI.Type != EST_DependentNoexcept) {
391    // Allow missing exception specifications in redeclarations as an extension.
392    DiagID = diag::ext_ms_missing_exception_specification;
393    ReturnValueOnError = false;
394  } else if (New->isReplaceableGlobalAllocationFunction() &&
395             ESI.Type != EST_DependentNoexcept) {
396    // Allow missing exception specifications in redeclarations as an extension,
397    // when declaring a replaceable global allocation function.
398    DiagID = diag::ext_missing_exception_specification;
399    ReturnValueOnError = false;
400  } else if (ESI.Type == EST_NoThrow) {
401    // Allow missing attribute 'nothrow' in redeclarations, since this is a very
402    // common omission.
403    DiagID = diag::ext_missing_exception_specification;
404    ReturnValueOnError = false;
405  } else {
406    DiagID = diag::err_missing_exception_specification;
407    ReturnValueOnError = true;
408  }
409
410  // Warn about the lack of exception specification.
411  SmallString<128> ExceptionSpecString;
412  llvm::raw_svector_ostream OS(ExceptionSpecString);
413  switch (OldProto->getExceptionSpecType()) {
414  case EST_DynamicNone:
415    OS << "throw()";
416    break;
417
418  case EST_Dynamic: {
419    OS << "throw(";
420    bool OnFirstException = true;
421    for (const auto &E : OldProto->exceptions()) {
422      if (OnFirstException)
423        OnFirstException = false;
424      else
425        OS << ", ";
426
427      OS << E.getAsString(getPrintingPolicy());
428    }
429    OS << ")";
430    break;
431  }
432
433  case EST_BasicNoexcept:
434    OS << "noexcept";
435    break;
436
437  case EST_DependentNoexcept:
438  case EST_NoexceptFalse:
439  case EST_NoexceptTrue:
440    OS << "noexcept(";
441    assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr");
442    OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy());
443    OS << ")";
444    break;
445  case EST_NoThrow:
446    OS <<"__attribute__((nothrow))";
447    break;
448  case EST_None:
449  case EST_MSAny:
450  case EST_Unevaluated:
451  case EST_Uninstantiated:
452  case EST_Unparsed:
453    llvm_unreachable("This spec type is compatible with none.");
454  }
455
456  SourceLocation FixItLoc;
457  if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) {
458    TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
459    // FIXME: Preserve enough information so that we can produce a correct fixit
460    // location when there is a trailing return type.
461    if (auto FTLoc = TL.getAs<FunctionProtoTypeLoc>())
462      if (!FTLoc.getTypePtr()->hasTrailingReturn())
463        FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd());
464  }
465
466  if (FixItLoc.isInvalid())
467    Diag(New->getLocation(), DiagID)
468      << New << OS.str();
469  else {
470    Diag(New->getLocation(), DiagID)
471      << New << OS.str()
472      << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str());
473  }
474
475  if (Old->getLocation().isValid())
476    Diag(Old->getLocation(), diag::note_previous_declaration);
477
478  return ReturnValueOnError;
479}
480
481/// CheckEquivalentExceptionSpec - Check if the two types have equivalent
482/// exception specifications. Exception specifications are equivalent if
483/// they allow exactly the same set of exception types. It does not matter how
484/// that is achieved. See C++ [except.spec]p2.
485bool Sema::CheckEquivalentExceptionSpec(
486    const FunctionProtoType *Old, SourceLocation OldLoc,
487    const FunctionProtoType *New, SourceLocation NewLoc) {
488  if (!getLangOpts().CXXExceptions)
489    return false;
490
491  unsigned DiagID = diag::err_mismatched_exception_spec;
492  if (getLangOpts().MSVCCompat)
493    DiagID = diag::ext_mismatched_exception_spec;
494  bool Result = CheckEquivalentExceptionSpecImpl(
495      *this, PDiag(DiagID), PDiag(diag::note_previous_declaration),
496      Old, OldLoc, New, NewLoc);
497
498  // In Microsoft mode, mismatching exception specifications just cause a warning.
499  if (getLangOpts().MSVCCompat)
500    return false;
501  return Result;
502}
503
504/// CheckEquivalentExceptionSpec - Check if the two types have compatible
505/// exception specifications. See C++ [except.spec]p3.
506///
507/// \return \c false if the exception specifications match, \c true if there is
508/// a problem. If \c true is returned, either a diagnostic has already been
509/// produced or \c *MissingExceptionSpecification is set to \c true.
510static bool CheckEquivalentExceptionSpecImpl(
511    Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID,
512    const FunctionProtoType *Old, SourceLocation OldLoc,
513    const FunctionProtoType *New, SourceLocation NewLoc,
514    bool *MissingExceptionSpecification,
515    bool *MissingEmptyExceptionSpecification,
516    bool AllowNoexceptAllMatchWithNoSpec, bool IsOperatorNew) {
517  if (MissingExceptionSpecification)
518    *MissingExceptionSpecification = false;
519
520  if (MissingEmptyExceptionSpecification)
521    *MissingEmptyExceptionSpecification = false;
522
523  Old = S.ResolveExceptionSpec(NewLoc, Old);
524  if (!Old)
525    return false;
526  New = S.ResolveExceptionSpec(NewLoc, New);
527  if (!New)
528    return false;
529
530  // C++0x [except.spec]p3: Two exception-specifications are compatible if:
531  //   - both are non-throwing, regardless of their form,
532  //   - both have the form noexcept(constant-expression) and the constant-
533  //     expressions are equivalent,
534  //   - both are dynamic-exception-specifications that have the same set of
535  //     adjusted types.
536  //
537  // C++0x [except.spec]p12: An exception-specification is non-throwing if it is
538  //   of the form throw(), noexcept, or noexcept(constant-expression) where the
539  //   constant-expression yields true.
540  //
541  // C++0x [except.spec]p4: If any declaration of a function has an exception-
542  //   specifier that is not a noexcept-specification allowing all exceptions,
543  //   all declarations [...] of that function shall have a compatible
544  //   exception-specification.
545  //
546  // That last point basically means that noexcept(false) matches no spec.
547  // It's considered when AllowNoexceptAllMatchWithNoSpec is true.
548
549  ExceptionSpecificationType OldEST = Old->getExceptionSpecType();
550  ExceptionSpecificationType NewEST = New->getExceptionSpecType();
551
552  assert(!isUnresolvedExceptionSpec(OldEST) &&
553         !isUnresolvedExceptionSpec(NewEST) &&
554         "Shouldn't see unknown exception specifications here");
555
556  CanThrowResult OldCanThrow = Old->canThrow();
557  CanThrowResult NewCanThrow = New->canThrow();
558
559  // Any non-throwing specifications are compatible.
560  if (OldCanThrow == CT_Cannot && NewCanThrow == CT_Cannot)
561    return false;
562
563  // Any throws-anything specifications are usually compatible.
564  if (OldCanThrow == CT_Can && OldEST != EST_Dynamic &&
565      NewCanThrow == CT_Can && NewEST != EST_Dynamic) {
566    // The exception is that the absence of an exception specification only
567    // matches noexcept(false) for functions, as described above.
568    if (!AllowNoexceptAllMatchWithNoSpec &&
569        ((OldEST == EST_None && NewEST == EST_NoexceptFalse) ||
570         (OldEST == EST_NoexceptFalse && NewEST == EST_None))) {
571      // This is the disallowed case.
572    } else {
573      return false;
574    }
575  }
576
577  // C++14 [except.spec]p3:
578  //   Two exception-specifications are compatible if [...] both have the form
579  //   noexcept(constant-expression) and the constant-expressions are equivalent
580  if (OldEST == EST_DependentNoexcept && NewEST == EST_DependentNoexcept) {
581    llvm::FoldingSetNodeID OldFSN, NewFSN;
582    Old->getNoexceptExpr()->Profile(OldFSN, S.Context, true);
583    New->getNoexceptExpr()->Profile(NewFSN, S.Context, true);
584    if (OldFSN == NewFSN)
585      return false;
586  }
587
588  // Dynamic exception specifications with the same set of adjusted types
589  // are compatible.
590  if (OldEST == EST_Dynamic && NewEST == EST_Dynamic) {
591    bool Success = true;
592    // Both have a dynamic exception spec. Collect the first set, then compare
593    // to the second.
594    llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
595    for (const auto &I : Old->exceptions())
596      OldTypes.insert(S.Context.getCanonicalType(I).getUnqualifiedType());
597
598    for (const auto &I : New->exceptions()) {
599      CanQualType TypePtr = S.Context.getCanonicalType(I).getUnqualifiedType();
600      if (OldTypes.count(TypePtr))
601        NewTypes.insert(TypePtr);
602      else {
603        Success = false;
604        break;
605      }
606    }
607
608    if (Success && OldTypes.size() == NewTypes.size())
609      return false;
610  }
611
612  // As a special compatibility feature, under C++0x we accept no spec and
613  // throw(std::bad_alloc) as equivalent for operator new and operator new[].
614  // This is because the implicit declaration changed, but old code would break.
615  if (S.getLangOpts().CPlusPlus11 && IsOperatorNew) {
616    const FunctionProtoType *WithExceptions = nullptr;
617    if (OldEST == EST_None && NewEST == EST_Dynamic)
618      WithExceptions = New;
619    else if (OldEST == EST_Dynamic && NewEST == EST_None)
620      WithExceptions = Old;
621    if (WithExceptions && WithExceptions->getNumExceptions() == 1) {
622      // One has no spec, the other throw(something). If that something is
623      // std::bad_alloc, all conditions are met.
624      QualType Exception = *WithExceptions->exception_begin();
625      if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) {
626        IdentifierInfo* Name = ExRecord->getIdentifier();
627        if (Name && Name->getName() == "bad_alloc") {
628          // It's called bad_alloc, but is it in std?
629          if (ExRecord->isInStdNamespace()) {
630            return false;
631          }
632        }
633      }
634    }
635  }
636
637  // If the caller wants to handle the case that the new function is
638  // incompatible due to a missing exception specification, let it.
639  if (MissingExceptionSpecification && OldEST != EST_None &&
640      NewEST == EST_None) {
641    // The old type has an exception specification of some sort, but
642    // the new type does not.
643    *MissingExceptionSpecification = true;
644
645    if (MissingEmptyExceptionSpecification && OldCanThrow == CT_Cannot) {
646      // The old type has a throw() or noexcept(true) exception specification
647      // and the new type has no exception specification, and the caller asked
648      // to handle this itself.
649      *MissingEmptyExceptionSpecification = true;
650    }
651
652    return true;
653  }
654
655  S.Diag(NewLoc, DiagID);
656  if (NoteID.getDiagID() != 0 && OldLoc.isValid())
657    S.Diag(OldLoc, NoteID);
658  return true;
659}
660
661bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID,
662                                        const PartialDiagnostic &NoteID,
663                                        const FunctionProtoType *Old,
664                                        SourceLocation OldLoc,
665                                        const FunctionProtoType *New,
666                                        SourceLocation NewLoc) {
667  if (!getLangOpts().CXXExceptions)
668    return false;
669  return CheckEquivalentExceptionSpecImpl(*this, DiagID, NoteID, Old, OldLoc,
670                                          New, NewLoc);
671}
672
673bool Sema::handlerCanCatch(QualType HandlerType, QualType ExceptionType) {
674  // [except.handle]p3:
675  //   A handler is a match for an exception object of type E if:
676
677  // HandlerType must be ExceptionType or derived from it, or pointer or
678  // reference to such types.
679  const ReferenceType *RefTy = HandlerType->getAs<ReferenceType>();
680  if (RefTy)
681    HandlerType = RefTy->getPointeeType();
682
683  //   -- the handler is of type cv T or cv T& and E and T are the same type
684  if (Context.hasSameUnqualifiedType(ExceptionType, HandlerType))
685    return true;
686
687  // FIXME: ObjC pointer types?
688  if (HandlerType->isPointerType() || HandlerType->isMemberPointerType()) {
689    if (RefTy && (!HandlerType.isConstQualified() ||
690                  HandlerType.isVolatileQualified()))
691      return false;
692
693    // -- the handler is of type cv T or const T& where T is a pointer or
694    //    pointer to member type and E is std::nullptr_t
695    if (ExceptionType->isNullPtrType())
696      return true;
697
698    // -- the handler is of type cv T or const T& where T is a pointer or
699    //    pointer to member type and E is a pointer or pointer to member type
700    //    that can be converted to T by one or more of
701    //    -- a qualification conversion
702    //    -- a function pointer conversion
703    bool LifetimeConv;
704    QualType Result;
705    // FIXME: Should we treat the exception as catchable if a lifetime
706    // conversion is required?
707    if (IsQualificationConversion(ExceptionType, HandlerType, false,
708                                  LifetimeConv) ||
709        IsFunctionConversion(ExceptionType, HandlerType, Result))
710      return true;
711
712    //    -- a standard pointer conversion [...]
713    if (!ExceptionType->isPointerType() || !HandlerType->isPointerType())
714      return false;
715
716    // Handle the "qualification conversion" portion.
717    Qualifiers EQuals, HQuals;
718    ExceptionType = Context.getUnqualifiedArrayType(
719        ExceptionType->getPointeeType(), EQuals);
720    HandlerType = Context.getUnqualifiedArrayType(
721        HandlerType->getPointeeType(), HQuals);
722    if (!HQuals.compatiblyIncludes(EQuals))
723      return false;
724
725    if (HandlerType->isVoidType() && ExceptionType->isObjectType())
726      return true;
727
728    // The only remaining case is a derived-to-base conversion.
729  }
730
731  //   -- the handler is of type cg T or cv T& and T is an unambiguous public
732  //      base class of E
733  if (!ExceptionType->isRecordType() || !HandlerType->isRecordType())
734    return false;
735  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
736                     /*DetectVirtual=*/false);
737  if (!IsDerivedFrom(SourceLocation(), ExceptionType, HandlerType, Paths) ||
738      Paths.isAmbiguous(Context.getCanonicalType(HandlerType)))
739    return false;
740
741  // Do this check from a context without privileges.
742  switch (CheckBaseClassAccess(SourceLocation(), HandlerType, ExceptionType,
743                               Paths.front(),
744                               /*Diagnostic*/ 0,
745                               /*ForceCheck*/ true,
746                               /*ForceUnprivileged*/ true)) {
747  case AR_accessible: return true;
748  case AR_inaccessible: return false;
749  case AR_dependent:
750    llvm_unreachable("access check dependent for unprivileged context");
751  case AR_delayed:
752    llvm_unreachable("access check delayed in non-declaration");
753  }
754  llvm_unreachable("unexpected access check result");
755}
756
757/// CheckExceptionSpecSubset - Check whether the second function type's
758/// exception specification is a subset (or equivalent) of the first function
759/// type. This is used by override and pointer assignment checks.
760bool Sema::CheckExceptionSpecSubset(const PartialDiagnostic &DiagID,
761                                    const PartialDiagnostic &NestedDiagID,
762                                    const PartialDiagnostic &NoteID,
763                                    const PartialDiagnostic &NoThrowDiagID,
764                                    const FunctionProtoType *Superset,
765                                    SourceLocation SuperLoc,
766                                    const FunctionProtoType *Subset,
767                                    SourceLocation SubLoc) {
768
769  // Just auto-succeed under -fno-exceptions.
770  if (!getLangOpts().CXXExceptions)
771    return false;
772
773  // FIXME: As usual, we could be more specific in our error messages, but
774  // that better waits until we've got types with source locations.
775
776  if (!SubLoc.isValid())
777    SubLoc = SuperLoc;
778
779  // Resolve the exception specifications, if needed.
780  Superset = ResolveExceptionSpec(SuperLoc, Superset);
781  if (!Superset)
782    return false;
783  Subset = ResolveExceptionSpec(SubLoc, Subset);
784  if (!Subset)
785    return false;
786
787  ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType();
788  ExceptionSpecificationType SubEST = Subset->getExceptionSpecType();
789  assert(!isUnresolvedExceptionSpec(SuperEST) &&
790         !isUnresolvedExceptionSpec(SubEST) &&
791         "Shouldn't see unknown exception specifications here");
792
793  // If there are dependent noexcept specs, assume everything is fine. Unlike
794  // with the equivalency check, this is safe in this case, because we don't
795  // want to merge declarations. Checks after instantiation will catch any
796  // omissions we make here.
797  if (SuperEST == EST_DependentNoexcept || SubEST == EST_DependentNoexcept)
798    return false;
799
800  CanThrowResult SuperCanThrow = Superset->canThrow();
801  CanThrowResult SubCanThrow = Subset->canThrow();
802
803  // If the superset contains everything or the subset contains nothing, we're
804  // done.
805  if ((SuperCanThrow == CT_Can && SuperEST != EST_Dynamic) ||
806      SubCanThrow == CT_Cannot)
807    return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
808                                   Subset, SubLoc);
809
810  // Allow __declspec(nothrow) to be missing on redeclaration as an extension in
811  // some cases.
812  if (NoThrowDiagID.getDiagID() != 0 && SubCanThrow == CT_Can &&
813      SuperCanThrow == CT_Cannot && SuperEST == EST_NoThrow) {
814    Diag(SubLoc, NoThrowDiagID);
815    if (NoteID.getDiagID() != 0)
816      Diag(SuperLoc, NoteID);
817    return true;
818  }
819
820  // If the subset contains everything or the superset contains nothing, we've
821  // failed.
822  if ((SubCanThrow == CT_Can && SubEST != EST_Dynamic) ||
823      SuperCanThrow == CT_Cannot) {
824    Diag(SubLoc, DiagID);
825    if (NoteID.getDiagID() != 0)
826      Diag(SuperLoc, NoteID);
827    return true;
828  }
829
830  assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic &&
831         "Exception spec subset: non-dynamic case slipped through.");
832
833  // Neither contains everything or nothing. Do a proper comparison.
834  for (QualType SubI : Subset->exceptions()) {
835    if (const ReferenceType *RefTy = SubI->getAs<ReferenceType>())
836      SubI = RefTy->getPointeeType();
837
838    // Make sure it's in the superset.
839    bool Contained = false;
840    for (QualType SuperI : Superset->exceptions()) {
841      // [except.spec]p5:
842      //   the target entity shall allow at least the exceptions allowed by the
843      //   source
844      //
845      // We interpret this as meaning that a handler for some target type would
846      // catch an exception of each source type.
847      if (handlerCanCatch(SuperI, SubI)) {
848        Contained = true;
849        break;
850      }
851    }
852    if (!Contained) {
853      Diag(SubLoc, DiagID);
854      if (NoteID.getDiagID() != 0)
855        Diag(SuperLoc, NoteID);
856      return true;
857    }
858  }
859  // We've run half the gauntlet.
860  return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
861                                 Subset, SubLoc);
862}
863
864static bool
865CheckSpecForTypesEquivalent(Sema &S, const PartialDiagnostic &DiagID,
866                            const PartialDiagnostic &NoteID, QualType Target,
867                            SourceLocation TargetLoc, QualType Source,
868                            SourceLocation SourceLoc) {
869  const FunctionProtoType *TFunc = GetUnderlyingFunction(Target);
870  if (!TFunc)
871    return false;
872  const FunctionProtoType *SFunc = GetUnderlyingFunction(Source);
873  if (!SFunc)
874    return false;
875
876  return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc,
877                                        SFunc, SourceLoc);
878}
879
880/// CheckParamExceptionSpec - Check if the parameter and return types of the
881/// two functions have equivalent exception specs. This is part of the
882/// assignment and override compatibility check. We do not check the parameters
883/// of parameter function pointers recursively, as no sane programmer would
884/// even be able to write such a function type.
885bool Sema::CheckParamExceptionSpec(const PartialDiagnostic &DiagID,
886                                   const PartialDiagnostic &NoteID,
887                                   const FunctionProtoType *Target,
888                                   SourceLocation TargetLoc,
889                                   const FunctionProtoType *Source,
890                                   SourceLocation SourceLoc) {
891  auto RetDiag = DiagID;
892  RetDiag << 0;
893  if (CheckSpecForTypesEquivalent(
894          *this, RetDiag, PDiag(),
895          Target->getReturnType(), TargetLoc, Source->getReturnType(),
896          SourceLoc))
897    return true;
898
899  // We shouldn't even be testing this unless the arguments are otherwise
900  // compatible.
901  assert(Target->getNumParams() == Source->getNumParams() &&
902         "Functions have different argument counts.");
903  for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) {
904    auto ParamDiag = DiagID;
905    ParamDiag << 1;
906    if (CheckSpecForTypesEquivalent(
907            *this, ParamDiag, PDiag(),
908            Target->getParamType(i), TargetLoc, Source->getParamType(i),
909            SourceLoc))
910      return true;
911  }
912  return false;
913}
914
915bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) {
916  // First we check for applicability.
917  // Target type must be a function, function pointer or function reference.
918  const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
919  if (!ToFunc || ToFunc->hasDependentExceptionSpec())
920    return false;
921
922  // SourceType must be a function or function pointer.
923  const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
924  if (!FromFunc || FromFunc->hasDependentExceptionSpec())
925    return false;
926
927  unsigned DiagID = diag::err_incompatible_exception_specs;
928  unsigned NestedDiagID = diag::err_deep_exception_specs_differ;
929  // This is not an error in C++17 onwards, unless the noexceptness doesn't
930  // match, but in that case we have a full-on type mismatch, not just a
931  // type sugar mismatch.
932  if (getLangOpts().CPlusPlus17) {
933    DiagID = diag::warn_incompatible_exception_specs;
934    NestedDiagID = diag::warn_deep_exception_specs_differ;
935  }
936
937  // Now we've got the correct types on both sides, check their compatibility.
938  // This means that the source of the conversion can only throw a subset of
939  // the exceptions of the target, and any exception specs on arguments or
940  // return types must be equivalent.
941  //
942  // FIXME: If there is a nested dependent exception specification, we should
943  // not be checking it here. This is fine:
944  //   template<typename T> void f() {
945  //     void (*p)(void (*) throw(T));
946  //     void (*q)(void (*) throw(int)) = p;
947  //   }
948  // ... because it might be instantiated with T=int.
949  return CheckExceptionSpecSubset(
950             PDiag(DiagID), PDiag(NestedDiagID), PDiag(), PDiag(), ToFunc,
951             From->getSourceRange().getBegin(), FromFunc, SourceLocation()) &&
952         !getLangOpts().CPlusPlus17;
953}
954
955bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
956                                                const CXXMethodDecl *Old) {
957  // If the new exception specification hasn't been parsed yet, skip the check.
958  // We'll get called again once it's been parsed.
959  if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() ==
960      EST_Unparsed)
961    return false;
962
963  // Don't check uninstantiated template destructors at all. We can only
964  // synthesize correct specs after the template is instantiated.
965  if (isa<CXXDestructorDecl>(New) && New->getParent()->isDependentType())
966    return false;
967
968  // If the old exception specification hasn't been parsed yet, or the new
969  // exception specification can't be computed yet, remember that we need to
970  // perform this check when we get to the end of the outermost
971  // lexically-surrounding class.
972  if (exceptionSpecNotKnownYet(Old) || exceptionSpecNotKnownYet(New)) {
973    DelayedOverridingExceptionSpecChecks.push_back({New, Old});
974    return false;
975  }
976
977  unsigned DiagID = diag::err_override_exception_spec;
978  if (getLangOpts().MSVCCompat)
979    DiagID = diag::ext_override_exception_spec;
980  return CheckExceptionSpecSubset(PDiag(DiagID),
981                                  PDiag(diag::err_deep_exception_specs_differ),
982                                  PDiag(diag::note_overridden_virtual_function),
983                                  PDiag(diag::ext_override_exception_spec),
984                                  Old->getType()->castAs<FunctionProtoType>(),
985                                  Old->getLocation(),
986                                  New->getType()->castAs<FunctionProtoType>(),
987                                  New->getLocation());
988}
989
990static CanThrowResult canSubStmtsThrow(Sema &Self, const Stmt *S) {
991  CanThrowResult R = CT_Cannot;
992  for (const Stmt *SubStmt : S->children()) {
993    if (!SubStmt)
994      continue;
995    R = mergeCanThrow(R, Self.canThrow(SubStmt));
996    if (R == CT_Can)
997      break;
998  }
999  return R;
1000}
1001
1002CanThrowResult Sema::canCalleeThrow(Sema &S, const Expr *E, const Decl *D,
1003                                    SourceLocation Loc) {
1004  // As an extension, we assume that __attribute__((nothrow)) functions don't
1005  // throw.
1006  if (D && isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>())
1007    return CT_Cannot;
1008
1009  QualType T;
1010
1011  // In C++1z, just look at the function type of the callee.
1012  if (S.getLangOpts().CPlusPlus17 && E && isa<CallExpr>(E)) {
1013    E = cast<CallExpr>(E)->getCallee();
1014    T = E->getType();
1015    if (T->isSpecificPlaceholderType(BuiltinType::BoundMember)) {
1016      // Sadly we don't preserve the actual type as part of the "bound member"
1017      // placeholder, so we need to reconstruct it.
1018      E = E->IgnoreParenImpCasts();
1019
1020      // Could be a call to a pointer-to-member or a plain member access.
1021      if (auto *Op = dyn_cast<BinaryOperator>(E)) {
1022        assert(Op->getOpcode() == BO_PtrMemD || Op->getOpcode() == BO_PtrMemI);
1023        T = Op->getRHS()->getType()
1024              ->castAs<MemberPointerType>()->getPointeeType();
1025      } else {
1026        T = cast<MemberExpr>(E)->getMemberDecl()->getType();
1027      }
1028    }
1029  } else if (const ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D))
1030    T = VD->getType();
1031  else
1032    // If we have no clue what we're calling, assume the worst.
1033    return CT_Can;
1034
1035  const FunctionProtoType *FT;
1036  if ((FT = T->getAs<FunctionProtoType>())) {
1037  } else if (const PointerType *PT = T->getAs<PointerType>())
1038    FT = PT->getPointeeType()->getAs<FunctionProtoType>();
1039  else if (const ReferenceType *RT = T->getAs<ReferenceType>())
1040    FT = RT->getPointeeType()->getAs<FunctionProtoType>();
1041  else if (const MemberPointerType *MT = T->getAs<MemberPointerType>())
1042    FT = MT->getPointeeType()->getAs<FunctionProtoType>();
1043  else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
1044    FT = BT->getPointeeType()->getAs<FunctionProtoType>();
1045
1046  if (!FT)
1047    return CT_Can;
1048
1049  if (Loc.isValid() || (Loc.isInvalid() && E))
1050    FT = S.ResolveExceptionSpec(Loc.isInvalid() ? E->getBeginLoc() : Loc, FT);
1051  if (!FT)
1052    return CT_Can;
1053
1054  return FT->canThrow();
1055}
1056
1057static CanThrowResult canVarDeclThrow(Sema &Self, const VarDecl *VD) {
1058  CanThrowResult CT = CT_Cannot;
1059
1060  // Initialization might throw.
1061  if (!VD->isUsableInConstantExpressions(Self.Context))
1062    if (const Expr *Init = VD->getInit())
1063      CT = mergeCanThrow(CT, Self.canThrow(Init));
1064
1065  // Destructor might throw.
1066  if (VD->needsDestruction(Self.Context) == QualType::DK_cxx_destructor) {
1067    if (auto *RD =
1068            VD->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl()) {
1069      if (auto *Dtor = RD->getDestructor()) {
1070        CT = mergeCanThrow(
1071            CT, Sema::canCalleeThrow(Self, nullptr, Dtor, VD->getLocation()));
1072      }
1073    }
1074  }
1075
1076  // If this is a decomposition declaration, bindings might throw.
1077  if (auto *DD = dyn_cast<DecompositionDecl>(VD))
1078    for (auto *B : DD->bindings())
1079      if (auto *HD = B->getHoldingVar())
1080        CT = mergeCanThrow(CT, canVarDeclThrow(Self, HD));
1081
1082  return CT;
1083}
1084
1085static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) {
1086  if (DC->isTypeDependent())
1087    return CT_Dependent;
1088
1089  if (!DC->getTypeAsWritten()->isReferenceType())
1090    return CT_Cannot;
1091
1092  if (DC->getSubExpr()->isTypeDependent())
1093    return CT_Dependent;
1094
1095  return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot;
1096}
1097
1098static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) {
1099  if (DC->isTypeOperand())
1100    return CT_Cannot;
1101
1102  Expr *Op = DC->getExprOperand();
1103  if (Op->isTypeDependent())
1104    return CT_Dependent;
1105
1106  const RecordType *RT = Op->getType()->getAs<RecordType>();
1107  if (!RT)
1108    return CT_Cannot;
1109
1110  if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic())
1111    return CT_Cannot;
1112
1113  if (Op->Classify(S.Context).isPRValue())
1114    return CT_Cannot;
1115
1116  return CT_Can;
1117}
1118
1119CanThrowResult Sema::canThrow(const Stmt *S) {
1120  // C++ [expr.unary.noexcept]p3:
1121  //   [Can throw] if in a potentially-evaluated context the expression would
1122  //   contain:
1123  switch (S->getStmtClass()) {
1124  case Expr::ConstantExprClass:
1125    return canThrow(cast<ConstantExpr>(S)->getSubExpr());
1126
1127  case Expr::CXXThrowExprClass:
1128    //   - a potentially evaluated throw-expression
1129    return CT_Can;
1130
1131  case Expr::CXXDynamicCastExprClass: {
1132    //   - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
1133    //     where T is a reference type, that requires a run-time check
1134    auto *CE = cast<CXXDynamicCastExpr>(S);
1135    // FIXME: Properly determine whether a variably-modified type can throw.
1136    if (CE->getType()->isVariablyModifiedType())
1137      return CT_Can;
1138    CanThrowResult CT = canDynamicCastThrow(CE);
1139    if (CT == CT_Can)
1140      return CT;
1141    return mergeCanThrow(CT, canSubStmtsThrow(*this, CE));
1142  }
1143
1144  case Expr::CXXTypeidExprClass:
1145    //   - a potentially evaluated typeid expression applied to a glvalue
1146    //     expression whose type is a polymorphic class type
1147    return canTypeidThrow(*this, cast<CXXTypeidExpr>(S));
1148
1149    //   - a potentially evaluated call to a function, member function, function
1150    //     pointer, or member function pointer that does not have a non-throwing
1151    //     exception-specification
1152  case Expr::CallExprClass:
1153  case Expr::CXXMemberCallExprClass:
1154  case Expr::CXXOperatorCallExprClass:
1155  case Expr::UserDefinedLiteralClass: {
1156    const CallExpr *CE = cast<CallExpr>(S);
1157    CanThrowResult CT;
1158    if (CE->isTypeDependent())
1159      CT = CT_Dependent;
1160    else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens()))
1161      CT = CT_Cannot;
1162    else
1163      CT = canCalleeThrow(*this, CE, CE->getCalleeDecl());
1164    if (CT == CT_Can)
1165      return CT;
1166    return mergeCanThrow(CT, canSubStmtsThrow(*this, CE));
1167  }
1168
1169  case Expr::CXXConstructExprClass:
1170  case Expr::CXXTemporaryObjectExprClass: {
1171    auto *CE = cast<CXXConstructExpr>(S);
1172    // FIXME: Properly determine whether a variably-modified type can throw.
1173    if (CE->getType()->isVariablyModifiedType())
1174      return CT_Can;
1175    CanThrowResult CT = canCalleeThrow(*this, CE, CE->getConstructor());
1176    if (CT == CT_Can)
1177      return CT;
1178    return mergeCanThrow(CT, canSubStmtsThrow(*this, CE));
1179  }
1180
1181  case Expr::CXXInheritedCtorInitExprClass: {
1182    auto *ICIE = cast<CXXInheritedCtorInitExpr>(S);
1183    return canCalleeThrow(*this, ICIE, ICIE->getConstructor());
1184  }
1185
1186  case Expr::LambdaExprClass: {
1187    const LambdaExpr *Lambda = cast<LambdaExpr>(S);
1188    CanThrowResult CT = CT_Cannot;
1189    for (LambdaExpr::const_capture_init_iterator
1190             Cap = Lambda->capture_init_begin(),
1191             CapEnd = Lambda->capture_init_end();
1192         Cap != CapEnd; ++Cap)
1193      CT = mergeCanThrow(CT, canThrow(*Cap));
1194    return CT;
1195  }
1196
1197  case Expr::CXXNewExprClass: {
1198    auto *NE = cast<CXXNewExpr>(S);
1199    CanThrowResult CT;
1200    if (NE->isTypeDependent())
1201      CT = CT_Dependent;
1202    else
1203      CT = canCalleeThrow(*this, NE, NE->getOperatorNew());
1204    if (CT == CT_Can)
1205      return CT;
1206    return mergeCanThrow(CT, canSubStmtsThrow(*this, NE));
1207  }
1208
1209  case Expr::CXXDeleteExprClass: {
1210    auto *DE = cast<CXXDeleteExpr>(S);
1211    CanThrowResult CT;
1212    QualType DTy = DE->getDestroyedType();
1213    if (DTy.isNull() || DTy->isDependentType()) {
1214      CT = CT_Dependent;
1215    } else {
1216      CT = canCalleeThrow(*this, DE, DE->getOperatorDelete());
1217      if (const RecordType *RT = DTy->getAs<RecordType>()) {
1218        const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
1219        const CXXDestructorDecl *DD = RD->getDestructor();
1220        if (DD)
1221          CT = mergeCanThrow(CT, canCalleeThrow(*this, DE, DD));
1222      }
1223      if (CT == CT_Can)
1224        return CT;
1225    }
1226    return mergeCanThrow(CT, canSubStmtsThrow(*this, DE));
1227  }
1228
1229  case Expr::CXXBindTemporaryExprClass: {
1230    auto *BTE = cast<CXXBindTemporaryExpr>(S);
1231    // The bound temporary has to be destroyed again, which might throw.
1232    CanThrowResult CT =
1233        canCalleeThrow(*this, BTE, BTE->getTemporary()->getDestructor());
1234    if (CT == CT_Can)
1235      return CT;
1236    return mergeCanThrow(CT, canSubStmtsThrow(*this, BTE));
1237  }
1238
1239  case Expr::PseudoObjectExprClass: {
1240    auto *POE = cast<PseudoObjectExpr>(S);
1241    CanThrowResult CT = CT_Cannot;
1242    for (const Expr *E : POE->semantics()) {
1243      CT = mergeCanThrow(CT, canThrow(E));
1244      if (CT == CT_Can)
1245        break;
1246    }
1247    return CT;
1248  }
1249
1250    // ObjC message sends are like function calls, but never have exception
1251    // specs.
1252  case Expr::ObjCMessageExprClass:
1253  case Expr::ObjCPropertyRefExprClass:
1254  case Expr::ObjCSubscriptRefExprClass:
1255    return CT_Can;
1256
1257    // All the ObjC literals that are implemented as calls are
1258    // potentially throwing unless we decide to close off that
1259    // possibility.
1260  case Expr::ObjCArrayLiteralClass:
1261  case Expr::ObjCDictionaryLiteralClass:
1262  case Expr::ObjCBoxedExprClass:
1263    return CT_Can;
1264
1265    // Many other things have subexpressions, so we have to test those.
1266    // Some are simple:
1267  case Expr::CoawaitExprClass:
1268  case Expr::ConditionalOperatorClass:
1269  case Expr::CoyieldExprClass:
1270  case Expr::CXXRewrittenBinaryOperatorClass:
1271  case Expr::CXXStdInitializerListExprClass:
1272  case Expr::DesignatedInitExprClass:
1273  case Expr::DesignatedInitUpdateExprClass:
1274  case Expr::ExprWithCleanupsClass:
1275  case Expr::ExtVectorElementExprClass:
1276  case Expr::InitListExprClass:
1277  case Expr::ArrayInitLoopExprClass:
1278  case Expr::MemberExprClass:
1279  case Expr::ObjCIsaExprClass:
1280  case Expr::ObjCIvarRefExprClass:
1281  case Expr::ParenExprClass:
1282  case Expr::ParenListExprClass:
1283  case Expr::ShuffleVectorExprClass:
1284  case Expr::StmtExprClass:
1285  case Expr::ConvertVectorExprClass:
1286  case Expr::VAArgExprClass:
1287    return canSubStmtsThrow(*this, S);
1288
1289  case Expr::CompoundLiteralExprClass:
1290  case Expr::CXXConstCastExprClass:
1291  case Expr::CXXAddrspaceCastExprClass:
1292  case Expr::CXXReinterpretCastExprClass:
1293  case Expr::BuiltinBitCastExprClass:
1294      // FIXME: Properly determine whether a variably-modified type can throw.
1295    if (cast<Expr>(S)->getType()->isVariablyModifiedType())
1296      return CT_Can;
1297    return canSubStmtsThrow(*this, S);
1298
1299    // Some might be dependent for other reasons.
1300  case Expr::ArraySubscriptExprClass:
1301  case Expr::MatrixSubscriptExprClass:
1302  case Expr::OMPArraySectionExprClass:
1303  case Expr::OMPArrayShapingExprClass:
1304  case Expr::OMPIteratorExprClass:
1305  case Expr::BinaryOperatorClass:
1306  case Expr::DependentCoawaitExprClass:
1307  case Expr::CompoundAssignOperatorClass:
1308  case Expr::CStyleCastExprClass:
1309  case Expr::CXXStaticCastExprClass:
1310  case Expr::CXXFunctionalCastExprClass:
1311  case Expr::ImplicitCastExprClass:
1312  case Expr::MaterializeTemporaryExprClass:
1313  case Expr::UnaryOperatorClass: {
1314    // FIXME: Properly determine whether a variably-modified type can throw.
1315    if (auto *CE = dyn_cast<CastExpr>(S))
1316      if (CE->getType()->isVariablyModifiedType())
1317        return CT_Can;
1318    CanThrowResult CT =
1319        cast<Expr>(S)->isTypeDependent() ? CT_Dependent : CT_Cannot;
1320    return mergeCanThrow(CT, canSubStmtsThrow(*this, S));
1321  }
1322
1323  case Expr::CXXDefaultArgExprClass:
1324    return canThrow(cast<CXXDefaultArgExpr>(S)->getExpr());
1325
1326  case Expr::CXXDefaultInitExprClass:
1327    return canThrow(cast<CXXDefaultInitExpr>(S)->getExpr());
1328
1329  case Expr::ChooseExprClass: {
1330    auto *CE = cast<ChooseExpr>(S);
1331    if (CE->isTypeDependent() || CE->isValueDependent())
1332      return CT_Dependent;
1333    return canThrow(CE->getChosenSubExpr());
1334  }
1335
1336  case Expr::GenericSelectionExprClass:
1337    if (cast<GenericSelectionExpr>(S)->isResultDependent())
1338      return CT_Dependent;
1339    return canThrow(cast<GenericSelectionExpr>(S)->getResultExpr());
1340
1341    // Some expressions are always dependent.
1342  case Expr::CXXDependentScopeMemberExprClass:
1343  case Expr::CXXUnresolvedConstructExprClass:
1344  case Expr::DependentScopeDeclRefExprClass:
1345  case Expr::CXXFoldExprClass:
1346  case Expr::RecoveryExprClass:
1347    return CT_Dependent;
1348
1349  case Expr::AsTypeExprClass:
1350  case Expr::BinaryConditionalOperatorClass:
1351  case Expr::BlockExprClass:
1352  case Expr::CUDAKernelCallExprClass:
1353  case Expr::DeclRefExprClass:
1354  case Expr::ObjCBridgedCastExprClass:
1355  case Expr::ObjCIndirectCopyRestoreExprClass:
1356  case Expr::ObjCProtocolExprClass:
1357  case Expr::ObjCSelectorExprClass:
1358  case Expr::ObjCAvailabilityCheckExprClass:
1359  case Expr::OffsetOfExprClass:
1360  case Expr::PackExpansionExprClass:
1361  case Expr::SubstNonTypeTemplateParmExprClass:
1362  case Expr::SubstNonTypeTemplateParmPackExprClass:
1363  case Expr::FunctionParmPackExprClass:
1364  case Expr::UnaryExprOrTypeTraitExprClass:
1365  case Expr::UnresolvedLookupExprClass:
1366  case Expr::UnresolvedMemberExprClass:
1367  case Expr::TypoExprClass:
1368    // FIXME: Many of the above can throw.
1369    return CT_Cannot;
1370
1371  case Expr::AddrLabelExprClass:
1372  case Expr::ArrayTypeTraitExprClass:
1373  case Expr::AtomicExprClass:
1374  case Expr::TypeTraitExprClass:
1375  case Expr::CXXBoolLiteralExprClass:
1376  case Expr::CXXNoexceptExprClass:
1377  case Expr::CXXNullPtrLiteralExprClass:
1378  case Expr::CXXPseudoDestructorExprClass:
1379  case Expr::CXXScalarValueInitExprClass:
1380  case Expr::CXXThisExprClass:
1381  case Expr::CXXUuidofExprClass:
1382  case Expr::CharacterLiteralClass:
1383  case Expr::ExpressionTraitExprClass:
1384  case Expr::FloatingLiteralClass:
1385  case Expr::GNUNullExprClass:
1386  case Expr::ImaginaryLiteralClass:
1387  case Expr::ImplicitValueInitExprClass:
1388  case Expr::IntegerLiteralClass:
1389  case Expr::FixedPointLiteralClass:
1390  case Expr::ArrayInitIndexExprClass:
1391  case Expr::NoInitExprClass:
1392  case Expr::ObjCEncodeExprClass:
1393  case Expr::ObjCStringLiteralClass:
1394  case Expr::ObjCBoolLiteralExprClass:
1395  case Expr::OpaqueValueExprClass:
1396  case Expr::PredefinedExprClass:
1397  case Expr::SizeOfPackExprClass:
1398  case Expr::StringLiteralClass:
1399  case Expr::SourceLocExprClass:
1400  case Expr::ConceptSpecializationExprClass:
1401  case Expr::RequiresExprClass:
1402    // These expressions can never throw.
1403    return CT_Cannot;
1404
1405  case Expr::MSPropertyRefExprClass:
1406  case Expr::MSPropertySubscriptExprClass:
1407    llvm_unreachable("Invalid class for expression");
1408
1409    // Most statements can throw if any substatement can throw.
1410  case Stmt::AttributedStmtClass:
1411  case Stmt::BreakStmtClass:
1412  case Stmt::CapturedStmtClass:
1413  case Stmt::CaseStmtClass:
1414  case Stmt::CompoundStmtClass:
1415  case Stmt::ContinueStmtClass:
1416  case Stmt::CoreturnStmtClass:
1417  case Stmt::CoroutineBodyStmtClass:
1418  case Stmt::CXXCatchStmtClass:
1419  case Stmt::CXXForRangeStmtClass:
1420  case Stmt::DefaultStmtClass:
1421  case Stmt::DoStmtClass:
1422  case Stmt::ForStmtClass:
1423  case Stmt::GCCAsmStmtClass:
1424  case Stmt::GotoStmtClass:
1425  case Stmt::IndirectGotoStmtClass:
1426  case Stmt::LabelStmtClass:
1427  case Stmt::MSAsmStmtClass:
1428  case Stmt::MSDependentExistsStmtClass:
1429  case Stmt::NullStmtClass:
1430  case Stmt::ObjCAtCatchStmtClass:
1431  case Stmt::ObjCAtFinallyStmtClass:
1432  case Stmt::ObjCAtSynchronizedStmtClass:
1433  case Stmt::ObjCAutoreleasePoolStmtClass:
1434  case Stmt::ObjCForCollectionStmtClass:
1435  case Stmt::OMPAtomicDirectiveClass:
1436  case Stmt::OMPBarrierDirectiveClass:
1437  case Stmt::OMPCancelDirectiveClass:
1438  case Stmt::OMPCancellationPointDirectiveClass:
1439  case Stmt::OMPCriticalDirectiveClass:
1440  case Stmt::OMPDistributeDirectiveClass:
1441  case Stmt::OMPDistributeParallelForDirectiveClass:
1442  case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1443  case Stmt::OMPDistributeSimdDirectiveClass:
1444  case Stmt::OMPFlushDirectiveClass:
1445  case Stmt::OMPDepobjDirectiveClass:
1446  case Stmt::OMPScanDirectiveClass:
1447  case Stmt::OMPForDirectiveClass:
1448  case Stmt::OMPForSimdDirectiveClass:
1449  case Stmt::OMPMasterDirectiveClass:
1450  case Stmt::OMPMasterTaskLoopDirectiveClass:
1451  case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1452  case Stmt::OMPOrderedDirectiveClass:
1453  case Stmt::OMPCanonicalLoopClass:
1454  case Stmt::OMPParallelDirectiveClass:
1455  case Stmt::OMPParallelForDirectiveClass:
1456  case Stmt::OMPParallelForSimdDirectiveClass:
1457  case Stmt::OMPParallelMasterDirectiveClass:
1458  case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1459  case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1460  case Stmt::OMPParallelSectionsDirectiveClass:
1461  case Stmt::OMPSectionDirectiveClass:
1462  case Stmt::OMPSectionsDirectiveClass:
1463  case Stmt::OMPSimdDirectiveClass:
1464  case Stmt::OMPTileDirectiveClass:
1465  case Stmt::OMPSingleDirectiveClass:
1466  case Stmt::OMPTargetDataDirectiveClass:
1467  case Stmt::OMPTargetDirectiveClass:
1468  case Stmt::OMPTargetEnterDataDirectiveClass:
1469  case Stmt::OMPTargetExitDataDirectiveClass:
1470  case Stmt::OMPTargetParallelDirectiveClass:
1471  case Stmt::OMPTargetParallelForDirectiveClass:
1472  case Stmt::OMPTargetParallelForSimdDirectiveClass:
1473  case Stmt::OMPTargetSimdDirectiveClass:
1474  case Stmt::OMPTargetTeamsDirectiveClass:
1475  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1476  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1477  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1478  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1479  case Stmt::OMPTargetUpdateDirectiveClass:
1480  case Stmt::OMPTaskDirectiveClass:
1481  case Stmt::OMPTaskgroupDirectiveClass:
1482  case Stmt::OMPTaskLoopDirectiveClass:
1483  case Stmt::OMPTaskLoopSimdDirectiveClass:
1484  case Stmt::OMPTaskwaitDirectiveClass:
1485  case Stmt::OMPTaskyieldDirectiveClass:
1486  case Stmt::OMPTeamsDirectiveClass:
1487  case Stmt::OMPTeamsDistributeDirectiveClass:
1488  case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1489  case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1490  case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1491  case Stmt::OMPInteropDirectiveClass:
1492  case Stmt::OMPDispatchDirectiveClass:
1493  case Stmt::OMPMaskedDirectiveClass:
1494  case Stmt::ReturnStmtClass:
1495  case Stmt::SEHExceptStmtClass:
1496  case Stmt::SEHFinallyStmtClass:
1497  case Stmt::SEHLeaveStmtClass:
1498  case Stmt::SEHTryStmtClass:
1499  case Stmt::SwitchStmtClass:
1500  case Stmt::WhileStmtClass:
1501    return canSubStmtsThrow(*this, S);
1502
1503  case Stmt::DeclStmtClass: {
1504    CanThrowResult CT = CT_Cannot;
1505    for (const Decl *D : cast<DeclStmt>(S)->decls()) {
1506      if (auto *VD = dyn_cast<VarDecl>(D))
1507        CT = mergeCanThrow(CT, canVarDeclThrow(*this, VD));
1508
1509      // FIXME: Properly determine whether a variably-modified type can throw.
1510      if (auto *TND = dyn_cast<TypedefNameDecl>(D))
1511        if (TND->getUnderlyingType()->isVariablyModifiedType())
1512          return CT_Can;
1513      if (auto *VD = dyn_cast<ValueDecl>(D))
1514        if (VD->getType()->isVariablyModifiedType())
1515          return CT_Can;
1516    }
1517    return CT;
1518  }
1519
1520  case Stmt::IfStmtClass: {
1521    auto *IS = cast<IfStmt>(S);
1522    CanThrowResult CT = CT_Cannot;
1523    if (const Stmt *Init = IS->getInit())
1524      CT = mergeCanThrow(CT, canThrow(Init));
1525    if (const Stmt *CondDS = IS->getConditionVariableDeclStmt())
1526      CT = mergeCanThrow(CT, canThrow(CondDS));
1527    CT = mergeCanThrow(CT, canThrow(IS->getCond()));
1528
1529    // For 'if constexpr', consider only the non-discarded case.
1530    // FIXME: We should add a DiscardedStmt marker to the AST.
1531    if (Optional<const Stmt *> Case = IS->getNondiscardedCase(Context))
1532      return *Case ? mergeCanThrow(CT, canThrow(*Case)) : CT;
1533
1534    CanThrowResult Then = canThrow(IS->getThen());
1535    CanThrowResult Else = IS->getElse() ? canThrow(IS->getElse()) : CT_Cannot;
1536    if (Then == Else)
1537      return mergeCanThrow(CT, Then);
1538
1539    // For a dependent 'if constexpr', the result is dependent if it depends on
1540    // the value of the condition.
1541    return mergeCanThrow(CT, IS->isConstexpr() ? CT_Dependent
1542                                               : mergeCanThrow(Then, Else));
1543  }
1544
1545  case Stmt::CXXTryStmtClass: {
1546    auto *TS = cast<CXXTryStmt>(S);
1547    // try /*...*/ catch (...) { H } can throw only if H can throw.
1548    // Any other try-catch can throw if any substatement can throw.
1549    const CXXCatchStmt *FinalHandler = TS->getHandler(TS->getNumHandlers() - 1);
1550    if (!FinalHandler->getExceptionDecl())
1551      return canThrow(FinalHandler->getHandlerBlock());
1552    return canSubStmtsThrow(*this, S);
1553  }
1554
1555  case Stmt::ObjCAtThrowStmtClass:
1556    return CT_Can;
1557
1558  case Stmt::ObjCAtTryStmtClass: {
1559    auto *TS = cast<ObjCAtTryStmt>(S);
1560
1561    // @catch(...) need not be last in Objective-C. Walk backwards until we
1562    // see one or hit the @try.
1563    CanThrowResult CT = CT_Cannot;
1564    if (const Stmt *Finally = TS->getFinallyStmt())
1565      CT = mergeCanThrow(CT, canThrow(Finally));
1566    for (unsigned I = TS->getNumCatchStmts(); I != 0; --I) {
1567      const ObjCAtCatchStmt *Catch = TS->getCatchStmt(I - 1);
1568      CT = mergeCanThrow(CT, canThrow(Catch));
1569      // If we reach a @catch(...), no earlier exceptions can escape.
1570      if (Catch->hasEllipsis())
1571        return CT;
1572    }
1573
1574    // Didn't find an @catch(...). Exceptions from the @try body can escape.
1575    return mergeCanThrow(CT, canThrow(TS->getTryBody()));
1576  }
1577
1578  case Stmt::NoStmtClass:
1579    llvm_unreachable("Invalid class for statement");
1580  }
1581  llvm_unreachable("Bogus StmtClass");
1582}
1583
1584} // end namespace clang
1585