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