clang  16.0.0git
SemaExceptionSpec.cpp
Go to the documentation of this file.
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 
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"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/SmallString.h"
24 
25 namespace clang {
26 
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).
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.
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 
83 
84  if (NoexceptExpr->isTypeDependent() ||
85  NoexceptExpr->containsUnexpandedParameterPack()) {
87  return NoexceptExpr;
88  }
89 
90  llvm::APSInt Result;
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());
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.
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())
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.
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 *
210  if (FPT->getExceptionSpecType() == EST_Unparsed) {
211  Diag(Loc, diag::err_exception_spec_not_parsed);
212  return nullptr;
213  }
214 
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.
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
244  // If we've fully resolved the exception specification, notify listeners.
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 
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.
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 
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 
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.
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.
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 &&
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() ||
358  Old->getBuiltinID()) &&
359  Old->isExternC()) {
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.
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 
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.
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.
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 
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()) {
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 
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.
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();
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
871  const PartialDiagnostic &NoteID, QualType Target,
872  SourceLocation TargetLoc, QualType Source,
873  SourceLocation SourceLoc) {
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.
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;
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;
912  *this, ParamDiag, PDiag(),
913  Target->getParamType(i), TargetLoc, Source->getParamType(i),
914  SourceLoc))
915  return true;
916  }
917  return false;
918 }
919 
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.
955  PDiag(DiagID), PDiag(NestedDiagID), PDiag(), PDiag(), ToFunc,
956  From->getSourceRange().getBegin(), FromFunc, SourceLocation()) &&
957  !getLangOpts().CPlusPlus17;
958 }
959 
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.
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.
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) {
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 
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) {
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.
1072  if (auto *RD =
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 
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 
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 
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;
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);
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);
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::OMPErrorDirectiveClass:
1498  case Stmt::OMPTeamsDirectiveClass:
1499  case Stmt::OMPTeamsDistributeDirectiveClass:
1500  case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1501  case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1502  case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1503  case Stmt::OMPInteropDirectiveClass:
1504  case Stmt::OMPDispatchDirectiveClass:
1505  case Stmt::OMPMaskedDirectiveClass:
1506  case Stmt::OMPMetaDirectiveClass:
1507  case Stmt::OMPGenericLoopDirectiveClass:
1508  case Stmt::OMPTeamsGenericLoopDirectiveClass:
1509  case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
1510  case Stmt::OMPParallelGenericLoopDirectiveClass:
1511  case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
1512  case Stmt::ReturnStmtClass:
1513  case Stmt::SEHExceptStmtClass:
1514  case Stmt::SEHFinallyStmtClass:
1515  case Stmt::SEHLeaveStmtClass:
1516  case Stmt::SEHTryStmtClass:
1517  case Stmt::SwitchStmtClass:
1518  case Stmt::WhileStmtClass:
1519  return canSubStmtsThrow(*this, S);
1520 
1521  case Stmt::DeclStmtClass: {
1523  for (const Decl *D : cast<DeclStmt>(S)->decls()) {
1524  if (auto *VD = dyn_cast<VarDecl>(D))
1525  CT = mergeCanThrow(CT, canVarDeclThrow(*this, VD));
1526 
1527  // FIXME: Properly determine whether a variably-modified type can throw.
1528  if (auto *TND = dyn_cast<TypedefNameDecl>(D))
1529  if (TND->getUnderlyingType()->isVariablyModifiedType())
1530  return CT_Can;
1531  if (auto *VD = dyn_cast<ValueDecl>(D))
1532  if (VD->getType()->isVariablyModifiedType())
1533  return CT_Can;
1534  }
1535  return CT;
1536  }
1537 
1538  case Stmt::IfStmtClass: {
1539  auto *IS = cast<IfStmt>(S);
1541  if (const Stmt *Init = IS->getInit())
1542  CT = mergeCanThrow(CT, canThrow(Init));
1543  if (const Stmt *CondDS = IS->getConditionVariableDeclStmt())
1544  CT = mergeCanThrow(CT, canThrow(CondDS));
1545  CT = mergeCanThrow(CT, canThrow(IS->getCond()));
1546 
1547  // For 'if constexpr', consider only the non-discarded case.
1548  // FIXME: We should add a DiscardedStmt marker to the AST.
1549  if (Optional<const Stmt *> Case = IS->getNondiscardedCase(Context))
1550  return *Case ? mergeCanThrow(CT, canThrow(*Case)) : CT;
1551 
1552  CanThrowResult Then = canThrow(IS->getThen());
1553  CanThrowResult Else = IS->getElse() ? canThrow(IS->getElse()) : CT_Cannot;
1554  if (Then == Else)
1555  return mergeCanThrow(CT, Then);
1556 
1557  // For a dependent 'if constexpr', the result is dependent if it depends on
1558  // the value of the condition.
1559  return mergeCanThrow(CT, IS->isConstexpr() ? CT_Dependent
1560  : mergeCanThrow(Then, Else));
1561  }
1562 
1563  case Stmt::CXXTryStmtClass: {
1564  auto *TS = cast<CXXTryStmt>(S);
1565  // try /*...*/ catch (...) { H } can throw only if H can throw.
1566  // Any other try-catch can throw if any substatement can throw.
1567  const CXXCatchStmt *FinalHandler = TS->getHandler(TS->getNumHandlers() - 1);
1568  if (!FinalHandler->getExceptionDecl())
1569  return canThrow(FinalHandler->getHandlerBlock());
1570  return canSubStmtsThrow(*this, S);
1571  }
1572 
1573  case Stmt::ObjCAtThrowStmtClass:
1574  return CT_Can;
1575 
1576  case Stmt::ObjCAtTryStmtClass: {
1577  auto *TS = cast<ObjCAtTryStmt>(S);
1578 
1579  // @catch(...) need not be last in Objective-C. Walk backwards until we
1580  // see one or hit the @try.
1582  if (const Stmt *Finally = TS->getFinallyStmt())
1583  CT = mergeCanThrow(CT, canThrow(Finally));
1584  for (unsigned I = TS->getNumCatchStmts(); I != 0; --I) {
1585  const ObjCAtCatchStmt *Catch = TS->getCatchStmt(I - 1);
1586  CT = mergeCanThrow(CT, canThrow(Catch));
1587  // If we reach a @catch(...), no earlier exceptions can escape.
1588  if (Catch->hasEllipsis())
1589  return CT;
1590  }
1591 
1592  // Didn't find an @catch(...). Exceptions from the @try body can escape.
1593  return mergeCanThrow(CT, canThrow(TS->getTryBody()));
1594  }
1595 
1596  case Stmt::SYCLUniqueStableNameExprClass:
1597  return CT_Cannot;
1598  case Stmt::NoStmtClass:
1599  llvm_unreachable("Invalid class for statement");
1600  }
1601  llvm_unreachable("Bogus StmtClass");
1602 }
1603 
1604 } // end namespace clang
clang::Sema::CurContext
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:421
clang::Type::isRecordType
bool isRecordType() const
Definition: Type.h:6973
clang::canDynamicCastThrow
static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC)
Definition: SemaExceptionSpec.cpp:1090
clang::CXXBoolLiteralExpr
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition: ExprCXX.h:721
clang::FunctionProtoType::getExceptionSpecType
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:4252
clang::FunctionProtoType::hasDependentExceptionSpec
bool hasDependentExceptionSpec() const
Return whether this function has a dependent exception spec.
Definition: Type.cpp:3284
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:210
clang::Decl::hasAttr
bool hasAttr() const
Definition: DeclBase.h:560
clang::FixItHint::CreateInsertion
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
Definition: Diagnostic.h:97
clang::QualType::isConstQualified
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6694
SemaInternal.h
clang::Sema::CheckOverridingFunctionExceptionSpec
bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, const CXXMethodDecl *Old)
CheckOverridingFunctionExceptionSpec - Checks whether the exception spec is a subset of base spec.
Definition: SemaExceptionSpec.cpp:960
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:86
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:219
clang::MultiVersionKind::Target
@ Target
clang::CastExpr::getSubExpr
Expr * getSubExpr()
Definition: Expr.h:3530
CXXInheritance.h
clang::Stmt::getSourceRange
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:324
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:737
clang::ObjCAtCatchStmt::hasEllipsis
bool hasEllipsis() const
Definition: StmtObjC.h:113
clang::Declarator::getIdentifier
IdentifierInfo * getIdentifier() const
Definition: DeclSpec.h:2251
clang::Sema::AR_accessible
@ AR_accessible
Definition: Sema.h:7794
clang::EST_None
@ EST_None
no exception specification
Definition: ExceptionSpecificationType.h:21
clang::CXXTypeidExpr
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition: ExprCXX.h:846
clang::EST_Dynamic
@ EST_Dynamic
throw(T1, T2)
Definition: ExceptionSpecificationType.h:23
clang::Qualifiers
The collection of all-type qualifiers we support.
Definition: Type.h:147
clang::FunctionProtoType::hasExceptionSpec
bool hasExceptionSpec() const
Return whether this function has any kind of exception spec.
Definition: Type.h:4258
clang::isUnresolvedExceptionSpec
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
Definition: ExceptionSpecificationType.h:49
clang::Sema::Diag
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1881
clang::ASTContext::getFunctionType
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1561
clang::Sema::AR_dependent
@ AR_dependent
Definition: Sema.h:7796
clang::mergeCanThrow
CanThrowResult mergeCanThrow(CanThrowResult CT1, CanThrowResult CT2)
Definition: ExceptionSpecificationType.h:60
clang::CT_Cannot
@ CT_Cannot
Definition: ExceptionSpecificationType.h:55
llvm::Optional
Definition: LLVM.h:40
llvm::SmallPtrSet
Definition: ASTContext.h:82
SourceManager.h
clang::Type::isVoidType
bool isVoidType() const
Definition: Type.h:7180
clang::QualType::isVolatileQualified
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Definition: Type.h:6705
clang::EST_Unparsed
@ EST_Unparsed
not parsed yet
Definition: ExceptionSpecificationType.h:32
clang::CallExpr::getCalleeDecl
Decl * getCalleeDecl()
Definition: Expr.h:2974
clang::Expr::containsUnexpandedParameterPack
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates).
Definition: Expr.h:232
clang::Qualifiers::compatiblyIncludes
bool compatiblyIncludes(Qualifiers other) const
Determines if these qualifiers compatibly include another set.
Definition: Type.h:532
clang::CXXTypeidExpr::getExprOperand
Expr * getExprOperand() const
Definition: ExprCXX.h:893
clang::ASTContext::getSourceManager
SourceManager & getSourceManager()
Definition: ASTContext.h:721
clang::Sema::AR_delayed
@ AR_delayed
Definition: Sema.h:7797
clang::Sema::CheckDistantExceptionSpec
bool CheckDistantExceptionSpec(QualType T)
CheckDistantExceptionSpec - Check if the given type is a pointer or pointer to member to a function w...
Definition: SemaExceptionSpec.cpp:188
clang::Sema::Context
ASTContext & Context
Definition: Sema.h:409
clang::hasImplicitExceptionSpec
static bool hasImplicitExceptionSpec(FunctionDecl *Decl)
Determine whether a function has an implicitly-generated exception specification.
Definition: SemaExceptionSpec.cpp:273
clang::Stmt::NoStmtClass
@ NoStmtClass
Definition: Stmt.h:74
clang::CXXCatchStmt::getHandlerBlock
Stmt * getHandlerBlock() const
Definition: StmtCXX.h:51
clang::CPlusPlus17
@ CPlusPlus17
Definition: LangStandard.h:56
clang::Sema::getLangOpts
const LangOptions & getLangOpts() const
Definition: Sema.h:1630
clang::EST_DependentNoexcept
@ EST_DependentNoexcept
noexcept(expression), value-dependent
Definition: ExceptionSpecificationType.h:27
clang::ReferenceType::getPointeeType
QualType getPointeeType() const
Definition: Type.h:2898
clang::EST_Unevaluated
@ EST_Unevaluated
not evaluated yet, for special member function
Definition: ExceptionSpecificationType.h:30
clang::TagType::isBeingDefined
bool isBeingDefined() const
Determines whether this type is in the process of being defined.
Definition: Type.cpp:3541
clang::canVarDeclThrow
static CanThrowResult canVarDeclThrow(Sema &Self, const VarDecl *VD)
Definition: SemaExceptionSpec.cpp:1062
APSInt
llvm::APSInt APSInt
Definition: ByteCodeEmitter.cpp:19
clang::EST_NoexceptTrue
@ EST_NoexceptTrue
noexcept(expression), evals to 'true'
Definition: ExceptionSpecificationType.h:29
clang::IdentifierInfo::isStr
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Definition: IdentifierTable.h:177
clang::QualType::DK_cxx_destructor
@ DK_cxx_destructor
Definition: Type.h:1277
clang::Sema::RequireCompleteType
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:8699
clang::isDynamicExceptionSpec
bool isDynamicExceptionSpec(ExceptionSpecificationType ESpecType)
Definition: ExceptionSpecificationType.h:35
clang::Type::isReferenceType
bool isReferenceType() const
Definition: Type.h:6895
clang::CallExpr::getCallee
Expr * getCallee()
Definition: Expr.h:2960
clang::ObjCAtCatchStmt
Represents Objective-C's @catch statement.
Definition: StmtObjC.h:77
clang::Expr::isTypeDependent
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:185
clang::Sema::DelayedOverridingExceptionSpecChecks
SmallVector< std::pair< const CXXMethodDecl *, const CXXMethodDecl * >, 2 > DelayedOverridingExceptionSpecChecks
All the overriding functions seen during a class definition that had their exception spec checks dela...
Definition: Sema.h:901
clang::GetUnderlyingFunction
static const FunctionProtoType * GetUnderlyingFunction(QualType T)
Definition: SemaExceptionSpec.cpp:27
clang::RecordType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4816
clang::DeclarationName::getCXXOverloadedOperator
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
Definition: DeclarationName.h:471
clang::Declarator::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclSpec.h:2005
clang::Sema::UpdateExceptionSpec
void UpdateExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI)
Definition: SemaExceptionSpec.cpp:242
clang::ExceptionSpecificationType
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
Definition: ExceptionSpecificationType.h:20
clang::Sema::canCalleeThrow
static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, SourceLocation Loc=SourceLocation())
Determine whether the callee of a particular function call can throw.
Definition: SemaExceptionSpec.cpp:1007
clang::Sema::InstantiateExceptionSpec
void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Function)
Definition: SemaTemplateInstantiateDecl.cpp:4572
clang::FunctionProtoType::ExceptionSpecInfo
Holds information about the various types of exception specification.
Definition: Type.h:4073
clang::Type::isNullPtrType
bool isNullPtrType() const
Definition: Type.h:7205
clang::LambdaExpr
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1872
clang::CanThrowResult
CanThrowResult
Possible results from evaluation of a noexcept expression.
Definition: ExceptionSpecificationType.h:54
clang::CT_Dependent
@ CT_Dependent
Definition: ExceptionSpecificationType.h:56
Diagnostic.h
clang::canSubStmtsThrow
static CanThrowResult canSubStmtsThrow(Sema &Self, const Stmt *S)
Definition: SemaExceptionSpec.cpp:995
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7386
clang::FunctionProtoType::ExceptionSpecInfo::Exceptions
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Definition: Type.h:4078
clang::EST_DynamicNone
@ EST_DynamicNone
throw()
Definition: ExceptionSpecificationType.h:22
clang::Sema::CCEK_Noexcept
@ CCEK_Noexcept
Condition in a noexcept(bool) specifier.
Definition: Sema.h:3813
clang::Sema::CheckSpecifiedExceptionType
bool CheckSpecifiedExceptionType(QualType &T, SourceRange Range)
CheckSpecifiedExceptionType - Check if the given type is valid in an exception specification.
Definition: SemaExceptionSpec.cpp:120
clang::FunctionProtoType::getParamType
QualType getParamType(unsigned i) const
Definition: Type.h:4229
clang::Sema::PDiag
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition: SemaInternal.h:24
clang::CXXDestructorDecl
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2703
clang::Type::isFunctionType
bool isFunctionType() const
Definition: Type.h:6879
clang::Type::isSizelessType
bool isSizelessType() const
As an extension, we classify types as one of "sized" or "sizeless"; every type is one or the other.
Definition: Type.cpp:2322
clang::LambdaExpr::const_capture_init_iterator
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
Definition: ExprCXX.h:1985
Expr.h
llvm::SmallString< 128 >
clang::ASTContext::adjustExceptionSpec
void adjustExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI, bool AsWritten=false)
Change the exception specification on a function once it is delay-parsed, instantiated,...
Definition: ASTContext.cpp:3283
clang::Redeclarable::redecls
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:296
clang::Sema::IsFunctionConversion
bool IsFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy)
Determine whether the conversion from FromType to ToType is a valid conversion that strips "noexcept"...
Definition: SemaOverload.cpp:1633
clang::FunctionProtoType::canThrow
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition: Type.cpp:3305
clang::CXXDynamicCastExpr
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition: ExprCXX.h:477
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:906
clang::exceptionSpecNotKnownYet
static bool exceptionSpecNotKnownYet(const FunctionDecl *FD)
Definition: SemaExceptionSpec.cpp:253
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:625
clang::ASTContext::getCanonicalType
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2528
clang::Type::getAsCXXRecordDecl
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1760
clang::Sema::getLocForEndOfToken
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:56
clang::Stmt::Profile
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
Definition: StmtProfile.cpp:2369
clang::CanQual< Type >
ExprCXX.h
clang::Sema::canThrow
CanThrowResult canThrow(const Stmt *E)
Definition: SemaExceptionSpec.cpp:1124
clang::Sema::ResolveExceptionSpec
const FunctionProtoType * ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT)
Definition: SemaExceptionSpec.cpp:209
clang::Sema::ActOnNoexceptSpec
ExprResult ActOnNoexceptSpec(Expr *NoexceptExpr, ExceptionSpecificationType &EST)
Check the given noexcept-specifier, convert its expression, and compute the appropriate ExceptionSpec...
Definition: SemaExceptionSpec.cpp:81
clang::BlockPointerType
Pointer to a block type.
Definition: Type.h:2849
clang::Sema::getASTMutationListener
ASTMutationListener * getASTMutationListener() const
Definition: Sema.cpp:532
clang::CastExpr::getCastKind
CastKind getCastKind() const
Definition: Expr.h:3524
clang::OverloadedOperatorKind
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
StmtObjC.h
clang::CheckEquivalentExceptionSpecImpl
static bool CheckEquivalentExceptionSpecImpl(Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, const FunctionProtoType *Old, SourceLocation OldLoc, const FunctionProtoType *New, SourceLocation NewLoc, bool *MissingExceptionSpecification=nullptr, bool *MissingEmptyExceptionSpecification=nullptr, bool AllowNoexceptAllMatchWithNoSpec=false, bool IsOperatorNew=false)
CheckEquivalentExceptionSpec - Check if the two types have compatible exception specifications.
Definition: SemaExceptionSpec.cpp:515
clang::Type::castAs
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7453
clang::Sema::CheckParamExceptionSpec
bool CheckParamExceptionSpec(const PartialDiagnostic &NestedDiagID, const PartialDiagnostic &NoteID, const FunctionProtoType *Target, SourceLocation TargetLoc, const FunctionProtoType *Source, SourceLocation SourceLoc)
CheckParamExceptionSpec - Check if the parameter and return types of the two functions have equivalen...
Definition: SemaExceptionSpec.cpp:890
clang::Sema::IsQualificationConversion
bool IsQualificationConversion(QualType FromType, QualType ToType, bool CStyle, bool &ObjCLifetimeConversion)
IsQualificationConversion - Determines whether the conversion from an rvalue of type FromType to ToTy...
Definition: SemaOverload.cpp:3393
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
clang::CT_Can
@ CT_Can
Definition: ExceptionSpecificationType.h:57
clang::EST_Uninstantiated
@ EST_Uninstantiated
not instantiated yet
Definition: ExceptionSpecificationType.h:31
clang::Type::isDependentType
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2304
clang::Sema::IsDerivedFrom
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
Definition: SemaDeclCXX.cpp:2862
clang::Type::isMemberPointerType
bool isMemberPointerType() const
Definition: Type.h:6931
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6883
clang::LambdaExpr::capture_init_end
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression.
Definition: ExprCXX.h:2011
clang::ConstantExpr::Create
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Definition: Expr.cpp:402
clang::ActionResult::get
PtrTy get() const
Definition: Ownership.h:169
clang::ValueDecl
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:701
clang::ASTContext::getUnqualifiedArrayType
QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals)
Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.
Definition: ASTContext.cpp:6016
clang::FunctionProtoType
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4016
clang::FunctionProtoType::exception_begin
exception_iterator exception_begin() const
Definition: Type.h:4399
clang::TypeLoc::getAs
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:88
clang::Type::isSpecificPlaceholderType
bool isSpecificPlaceholderType(unsigned K) const
Test for a specific placeholder type.
Definition: Type.h:7169
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:802
clang::FunctionProtoType::getNoexceptExpr
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:4310
clang::Sema::AR_inaccessible
@ AR_inaccessible
Definition: Sema.h:7795
Value
Value
Definition: UninitializedValues.cpp:103
clang::Sema::CheckExceptionSpecSubset
bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID, const PartialDiagnostic &NestedDiagID, const PartialDiagnostic &NoteID, const PartialDiagnostic &NoThrowDiagID, const FunctionProtoType *Superset, SourceLocation SuperLoc, const FunctionProtoType *Subset, SourceLocation SubLoc)
CheckExceptionSpecSubset - Check whether the second function type's exception specification is a subs...
Definition: SemaExceptionSpec.cpp:765
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
clang::CXXTypeidExpr::isTypeOperand
bool isTypeOperand() const
Definition: ExprCXX.h:882
clang::TypeLoc
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
clang::Expr::IgnoreParenImpCasts
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:3035
clang::Sema::isLibstdcxxEagerExceptionSpecHack
bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D)
Determine if we're in a case where we need to (incorrectly) eagerly parse an exception specification ...
Definition: SemaExceptionSpec.cpp:44
clang::FunctionDecl::isReplaceableGlobalAllocationFunction
bool isReplaceableGlobalAllocationFunction(Optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
Definition: Decl.cpp:3206
ASTMutationListener.h
clang::Sema
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:358
clang::ActionResult::isInvalid
bool isInvalid() const
Definition: Ownership.h:165
clang::Sema::handlerCanCatch
bool handlerCanCatch(QualType HandlerType, QualType ExceptionType)
Definition: SemaExceptionSpec.cpp:678
clang::EST_MSAny
@ EST_MSAny
Microsoft throw(...) extension.
Definition: ExceptionSpecificationType.h:24
clang::FunctionProtoType::getNumParams
unsigned getNumParams() const
Definition: Type.h:4227
clang::CheckSpecForTypesEquivalent
static bool CheckSpecForTypesEquivalent(Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, QualType Target, SourceLocation TargetLoc, QualType Source, SourceLocation SourceLoc)
Definition: SemaExceptionSpec.cpp:870
clang::FunctionProtoType::getExceptionSpecDecl
FunctionDecl * getExceptionSpecDecl() const
If this function type has an exception specification which hasn't been determined yet (either because...
Definition: Type.h:4320
clang::VarDecl::getInit
const Expr * getInit() const
Definition: Decl.h:1315
clang::Expr::isValueDependent
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:168
clang::EST_NoThrow
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
Definition: ExceptionSpecificationType.h:25
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:85
clang::canTypeidThrow
static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC)
Definition: SemaExceptionSpec.cpp:1103
clang::Sema::CheckEquivalentExceptionSpec
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New)
Definition: SemaExceptionSpec.cpp:291
clang::PartialDiagnostic::getDiagID
unsigned getDiagID() const
Definition: PartialDiagnostic.h:141
clang::CXXRecordDecl::getDestructor
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition: DeclCXX.cpp:1917
clang::PartialDiagnostic
Definition: PartialDiagnostic.h:31
clang::FunctionDecl::isExternC
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition: Decl.cpp:3303
clang::MemberPointerType
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:2960
clang::ObjCPropertyAttribute::Kind
Kind
Definition: DeclObjCCommon.h:22
clang::ActionResult< Expr * >
clang::FunctionProtoType::ExceptionSpecInfo::Type
ExceptionSpecificationType Type
The kind of exception specification this is.
Definition: Type.h:4075
clang::VarDecl::isUsableInConstantExpressions
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
Definition: Decl.cpp:2426
clang::TypeLoc::IgnoreParens
TypeLoc IgnoreParens() const
Definition: TypeLoc.h:1183
clang::PointerType
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2769
clang::FunctionProtoType::exceptions
ArrayRef< QualType > exceptions() const
Definition: Type.h:4395
clang::Type::getBaseElementTypeUnsafe
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition: Type.h:7336
clang::CanQual::getUnqualifiedType
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
Definition: CanonicalType.h:619
clang::interp::NE
bool NE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:490
clang::Expr::Classify
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
Definition: Expr.h:398
clang::SourceLocation::isInvalid
bool isInvalid() const
Definition: SourceLocation.h:111
clang::Expr::IgnoreParens
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3031
clang
Definition: CalledOnceCheck.h:17
clang::Type::isArrayType
bool isArrayType() const
Definition: Type.h:6949
clang::Sema::CheckConvertedConstantExpression
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE)
Definition: SemaOverload.cpp:5968
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:71
clang::EST_BasicNoexcept
@ EST_BasicNoexcept
noexcept
Definition: ExceptionSpecificationType.h:26
clang::CXXCatchStmt
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:28
clang::Declarator
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1834
clang::SourceManager::isInSystemHeader
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
Definition: SourceManager.h:1504
clang::Type::isObjectType
bool isObjectType() const
Determine whether this type is an object type.
Definition: Type.h:2058
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::SourceLocation::isValid
bool isValid() const
Return true if this is a valid SourceLocation object.
Definition: SourceLocation.h:110
clang::TypeSourceInfo
A container of type source information.
Definition: Type.h:6593
clang::FunctionType::getReturnType
QualType getReturnType() const
Definition: Type.h:3940
clang::NamedDecl::getDeclName
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
clang::Sema::EvaluateImplicitExceptionSpec
void EvaluateImplicitExceptionSpec(SourceLocation Loc, FunctionDecl *FD)
Evaluate the implicit exception specification for a defaulted special member function.
Definition: SemaDeclCXX.cpp:7412
clang::Stmt::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:336
clang::CXXBasePaths
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Definition: CXXInheritance.h:117
clang::RecordType::getDecl
RecordDecl * getDecl() const
Definition: Type.h:4826
clang::VarDecl::needsDestruction
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
Definition: Decl.cpp:2736
clang::ASTContext::getPointerType
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Definition: ASTContext.cpp:3341
clang::CPlusPlus11
@ CPlusPlus11
Definition: LangStandard.h:54
clang::ReferenceType
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2880
clang::FunctionProtoTypeLoc
Definition: TypeLoc.h:1498
clang::Decl::setInvalidDecl
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
clang::ASTContext::getArrayDecayedType
QualType getArrayDecayedType(QualType T) const
Return the properly qualified result of decaying the specified array type to a pointer.
Definition: ASTContext.cpp:6962
clang::APValue
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Definition: APValue.h:122
clang::TagDecl::isDependentType
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
Definition: Decl.h:3579
clang::EST_NoexceptFalse
@ EST_NoexceptFalse
noexcept(expression), evals to 'false'
Definition: ExceptionSpecificationType.h:28
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:712
clang::FunctionDecl::getBuiltinID
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition: Decl.cpp:3406
clang::Sema::getPrintingPolicy
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition: Sema.h:3223
clang::ASTContext::hasSameUnqualifiedType
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2571
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::CXXCatchStmt::getExceptionDecl
VarDecl * getExceptionDecl() const
Definition: StmtCXX.h:49
clang::Sema::CheckExceptionSpecCompatibility
bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
Definition: SemaExceptionSpec.cpp:920
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:432
clang::ASTContext::BoolTy
CanQualType BoolTy
Definition: ASTContext.h:1108
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1904
clang::Expr::Classification::isPRValue
bool isPRValue() const
Definition: Expr.h:376
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2810
clang::DeclaratorDecl::getTypeSourceInfo
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:787
clang::ExplicitCastExpr::getTypeAsWritten
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Definition: Expr.h:3729
clang::Sema::CheckBaseClassAccess
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
Definition: SemaAccess.cpp:1861
TypeLoc.h
clang::LambdaExpr::capture_init_begin
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition: ExprCXX.h:1999
clang::ValueDecl::setType
void setType(QualType newType)
Definition: Decl.h:713
clang::CXXMethodDecl::getParent
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Definition: DeclCXX.h:2098
clang::FunctionProtoType::getNumExceptions
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4295
clang::CXXMethodDecl
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1983
clang::Sema::DelayedEquivalentExceptionSpecChecks
SmallVector< std::pair< FunctionDecl *, FunctionDecl * >, 2 > DelayedEquivalentExceptionSpecChecks
All the function redeclarations seen during a class definition that had their exception spec checks d...
Definition: Sema.h:909