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