clang  14.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 FunctionProtoType *NewProto =
346  New->getType()->castAs<FunctionProtoType>();
347 
348  // The new function declaration is only missing an empty exception
349  // specification "throw()". If the throw() specification came from a
350  // function in a system header that has C linkage, just add an empty
351  // exception specification to the "new" declaration. Note that C library
352  // implementations are permitted to add these nothrow exception
353  // specifications.
354  //
355  // Likewise if the old function is a builtin.
356  if (MissingEmptyExceptionSpecification && NewProto &&
357  (Old->getLocation().isInvalid() ||
359  Old->getBuiltinID()) &&
360  Old->isExternC()) {
362  NewProto->getReturnType(), NewProto->getParamTypes(),
364  return false;
365  }
366 
367  const FunctionProtoType *OldProto =
368  Old->getType()->castAs<FunctionProtoType>();
369 
371  if (ESI.Type == EST_Dynamic) {
372  // FIXME: What if the exceptions are described in terms of the old
373  // prototype's parameters?
374  ESI.Exceptions = OldProto->exceptions();
375  }
376 
377  if (ESI.Type == EST_NoexceptFalse)
378  ESI.Type = EST_None;
379  if (ESI.Type == EST_NoexceptTrue)
380  ESI.Type = EST_BasicNoexcept;
381 
382  // For dependent noexcept, we can't just take the expression from the old
383  // prototype. It likely contains references to the old prototype's parameters.
384  if (ESI.Type == EST_DependentNoexcept) {
385  New->setInvalidDecl();
386  } else {
387  // Update the type of the function with the appropriate exception
388  // specification.
390  NewProto->getReturnType(), NewProto->getParamTypes(),
391  NewProto->getExtProtoInfo().withExceptionSpec(ESI)));
392  }
393 
394  if (getLangOpts().MSVCCompat && ESI.Type != EST_DependentNoexcept) {
395  // Allow missing exception specifications in redeclarations as an extension.
396  DiagID = diag::ext_ms_missing_exception_specification;
397  ReturnValueOnError = false;
398  } else if (New->isReplaceableGlobalAllocationFunction() &&
399  ESI.Type != EST_DependentNoexcept) {
400  // Allow missing exception specifications in redeclarations as an extension,
401  // when declaring a replaceable global allocation function.
402  DiagID = diag::ext_missing_exception_specification;
403  ReturnValueOnError = false;
404  } else if (ESI.Type == EST_NoThrow) {
405  // Allow missing attribute 'nothrow' in redeclarations, since this is a very
406  // common omission.
407  DiagID = diag::ext_missing_exception_specification;
408  ReturnValueOnError = false;
409  } else {
410  DiagID = diag::err_missing_exception_specification;
411  ReturnValueOnError = true;
412  }
413 
414  // Warn about the lack of exception specification.
415  SmallString<128> ExceptionSpecString;
416  llvm::raw_svector_ostream OS(ExceptionSpecString);
417  switch (OldProto->getExceptionSpecType()) {
418  case EST_DynamicNone:
419  OS << "throw()";
420  break;
421 
422  case EST_Dynamic: {
423  OS << "throw(";
424  bool OnFirstException = true;
425  for (const auto &E : OldProto->exceptions()) {
426  if (OnFirstException)
427  OnFirstException = false;
428  else
429  OS << ", ";
430 
431  OS << E.getAsString(getPrintingPolicy());
432  }
433  OS << ")";
434  break;
435  }
436 
437  case EST_BasicNoexcept:
438  OS << "noexcept";
439  break;
440 
442  case EST_NoexceptFalse:
443  case EST_NoexceptTrue:
444  OS << "noexcept(";
445  assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr");
446  OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy());
447  OS << ")";
448  break;
449  case EST_NoThrow:
450  OS <<"__attribute__((nothrow))";
451  break;
452  case EST_None:
453  case EST_MSAny:
454  case EST_Unevaluated:
455  case EST_Uninstantiated:
456  case EST_Unparsed:
457  llvm_unreachable("This spec type is compatible with none.");
458  }
459 
460  SourceLocation FixItLoc;
461  if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) {
462  TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
463  // FIXME: Preserve enough information so that we can produce a correct fixit
464  // location when there is a trailing return type.
465  if (auto FTLoc = TL.getAs<FunctionProtoTypeLoc>())
466  if (!FTLoc.getTypePtr()->hasTrailingReturn())
467  FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd());
468  }
469 
470  if (FixItLoc.isInvalid())
471  Diag(New->getLocation(), DiagID)
472  << New << OS.str();
473  else {
474  Diag(New->getLocation(), DiagID)
475  << New << OS.str()
476  << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str());
477  }
478 
479  if (Old->getLocation().isValid())
480  Diag(Old->getLocation(), diag::note_previous_declaration);
481 
482  return ReturnValueOnError;
483 }
484 
485 /// CheckEquivalentExceptionSpec - Check if the two types have equivalent
486 /// exception specifications. Exception specifications are equivalent if
487 /// they allow exactly the same set of exception types. It does not matter how
488 /// that is achieved. See C++ [except.spec]p2.
490  const FunctionProtoType *Old, SourceLocation OldLoc,
491  const FunctionProtoType *New, SourceLocation NewLoc) {
492  if (!getLangOpts().CXXExceptions)
493  return false;
494 
495  unsigned DiagID = diag::err_mismatched_exception_spec;
496  if (getLangOpts().MSVCCompat)
497  DiagID = diag::ext_mismatched_exception_spec;
498  bool Result = CheckEquivalentExceptionSpecImpl(
499  *this, PDiag(DiagID), PDiag(diag::note_previous_declaration),
500  Old, OldLoc, New, NewLoc);
501 
502  // In Microsoft mode, mismatching exception specifications just cause a warning.
503  if (getLangOpts().MSVCCompat)
504  return false;
505  return Result;
506 }
507 
508 /// CheckEquivalentExceptionSpec - Check if the two types have compatible
509 /// exception specifications. See C++ [except.spec]p3.
510 ///
511 /// \return \c false if the exception specifications match, \c true if there is
512 /// a problem. If \c true is returned, either a diagnostic has already been
513 /// produced or \c *MissingExceptionSpecification is set to \c true.
515  Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID,
516  const FunctionProtoType *Old, SourceLocation OldLoc,
517  const FunctionProtoType *New, SourceLocation NewLoc,
518  bool *MissingExceptionSpecification,
519  bool *MissingEmptyExceptionSpecification,
520  bool AllowNoexceptAllMatchWithNoSpec, bool IsOperatorNew) {
521  if (MissingExceptionSpecification)
522  *MissingExceptionSpecification = false;
523 
524  if (MissingEmptyExceptionSpecification)
525  *MissingEmptyExceptionSpecification = false;
526 
527  Old = S.ResolveExceptionSpec(NewLoc, Old);
528  if (!Old)
529  return false;
530  New = S.ResolveExceptionSpec(NewLoc, New);
531  if (!New)
532  return false;
533 
534  // C++0x [except.spec]p3: Two exception-specifications are compatible if:
535  // - both are non-throwing, regardless of their form,
536  // - both have the form noexcept(constant-expression) and the constant-
537  // expressions are equivalent,
538  // - both are dynamic-exception-specifications that have the same set of
539  // adjusted types.
540  //
541  // C++0x [except.spec]p12: An exception-specification is non-throwing if it is
542  // of the form throw(), noexcept, or noexcept(constant-expression) where the
543  // constant-expression yields true.
544  //
545  // C++0x [except.spec]p4: If any declaration of a function has an exception-
546  // specifier that is not a noexcept-specification allowing all exceptions,
547  // all declarations [...] of that function shall have a compatible
548  // exception-specification.
549  //
550  // That last point basically means that noexcept(false) matches no spec.
551  // It's considered when AllowNoexceptAllMatchWithNoSpec is true.
552 
555 
556  assert(!isUnresolvedExceptionSpec(OldEST) &&
557  !isUnresolvedExceptionSpec(NewEST) &&
558  "Shouldn't see unknown exception specifications here");
559 
560  CanThrowResult OldCanThrow = Old->canThrow();
561  CanThrowResult NewCanThrow = New->canThrow();
562 
563  // Any non-throwing specifications are compatible.
564  if (OldCanThrow == CT_Cannot && NewCanThrow == CT_Cannot)
565  return false;
566 
567  // Any throws-anything specifications are usually compatible.
568  if (OldCanThrow == CT_Can && OldEST != EST_Dynamic &&
569  NewCanThrow == CT_Can && NewEST != EST_Dynamic) {
570  // The exception is that the absence of an exception specification only
571  // matches noexcept(false) for functions, as described above.
572  if (!AllowNoexceptAllMatchWithNoSpec &&
573  ((OldEST == EST_None && NewEST == EST_NoexceptFalse) ||
574  (OldEST == EST_NoexceptFalse && NewEST == EST_None))) {
575  // This is the disallowed case.
576  } else {
577  return false;
578  }
579  }
580 
581  // C++14 [except.spec]p3:
582  // Two exception-specifications are compatible if [...] both have the form
583  // noexcept(constant-expression) and the constant-expressions are equivalent
584  if (OldEST == EST_DependentNoexcept && NewEST == EST_DependentNoexcept) {
585  llvm::FoldingSetNodeID OldFSN, NewFSN;
586  Old->getNoexceptExpr()->Profile(OldFSN, S.Context, true);
587  New->getNoexceptExpr()->Profile(NewFSN, S.Context, true);
588  if (OldFSN == NewFSN)
589  return false;
590  }
591 
592  // Dynamic exception specifications with the same set of adjusted types
593  // are compatible.
594  if (OldEST == EST_Dynamic && NewEST == EST_Dynamic) {
595  bool Success = true;
596  // Both have a dynamic exception spec. Collect the first set, then compare
597  // to the second.
598  llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
599  for (const auto &I : Old->exceptions())
600  OldTypes.insert(S.Context.getCanonicalType(I).getUnqualifiedType());
601 
602  for (const auto &I : New->exceptions()) {
604  if (OldTypes.count(TypePtr))
605  NewTypes.insert(TypePtr);
606  else {
607  Success = false;
608  break;
609  }
610  }
611 
612  if (Success && OldTypes.size() == NewTypes.size())
613  return false;
614  }
615 
616  // As a special compatibility feature, under C++0x we accept no spec and
617  // throw(std::bad_alloc) as equivalent for operator new and operator new[].
618  // This is because the implicit declaration changed, but old code would break.
619  if (S.getLangOpts().CPlusPlus11 && IsOperatorNew) {
620  const FunctionProtoType *WithExceptions = nullptr;
621  if (OldEST == EST_None && NewEST == EST_Dynamic)
622  WithExceptions = New;
623  else if (OldEST == EST_Dynamic && NewEST == EST_None)
624  WithExceptions = Old;
625  if (WithExceptions && WithExceptions->getNumExceptions() == 1) {
626  // One has no spec, the other throw(something). If that something is
627  // std::bad_alloc, all conditions are met.
628  QualType Exception = *WithExceptions->exception_begin();
629  if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) {
630  IdentifierInfo* Name = ExRecord->getIdentifier();
631  if (Name && Name->getName() == "bad_alloc") {
632  // It's called bad_alloc, but is it in std?
633  if (ExRecord->isInStdNamespace()) {
634  return false;
635  }
636  }
637  }
638  }
639  }
640 
641  // If the caller wants to handle the case that the new function is
642  // incompatible due to a missing exception specification, let it.
643  if (MissingExceptionSpecification && OldEST != EST_None &&
644  NewEST == EST_None) {
645  // The old type has an exception specification of some sort, but
646  // the new type does not.
647  *MissingExceptionSpecification = true;
648 
649  if (MissingEmptyExceptionSpecification && OldCanThrow == CT_Cannot) {
650  // The old type has a throw() or noexcept(true) exception specification
651  // and the new type has no exception specification, and the caller asked
652  // to handle this itself.
653  *MissingEmptyExceptionSpecification = true;
654  }
655 
656  return true;
657  }
658 
659  S.Diag(NewLoc, DiagID);
660  if (NoteID.getDiagID() != 0 && OldLoc.isValid())
661  S.Diag(OldLoc, NoteID);
662  return true;
663 }
664 
666  const PartialDiagnostic &NoteID,
667  const FunctionProtoType *Old,
668  SourceLocation OldLoc,
669  const FunctionProtoType *New,
670  SourceLocation NewLoc) {
671  if (!getLangOpts().CXXExceptions)
672  return false;
673  return CheckEquivalentExceptionSpecImpl(*this, DiagID, NoteID, Old, OldLoc,
674  New, NewLoc);
675 }
676 
677 bool Sema::handlerCanCatch(QualType HandlerType, QualType ExceptionType) {
678  // [except.handle]p3:
679  // A handler is a match for an exception object of type E if:
680 
681  // HandlerType must be ExceptionType or derived from it, or pointer or
682  // reference to such types.
683  const ReferenceType *RefTy = HandlerType->getAs<ReferenceType>();
684  if (RefTy)
685  HandlerType = RefTy->getPointeeType();
686 
687  // -- the handler is of type cv T or cv T& and E and T are the same type
688  if (Context.hasSameUnqualifiedType(ExceptionType, HandlerType))
689  return true;
690 
691  // FIXME: ObjC pointer types?
692  if (HandlerType->isPointerType() || HandlerType->isMemberPointerType()) {
693  if (RefTy && (!HandlerType.isConstQualified() ||
694  HandlerType.isVolatileQualified()))
695  return false;
696 
697  // -- the handler is of type cv T or const T& where T is a pointer or
698  // pointer to member type and E is std::nullptr_t
699  if (ExceptionType->isNullPtrType())
700  return true;
701 
702  // -- the handler is of type cv T or const T& where T is a pointer or
703  // pointer to member type and E is a pointer or pointer to member type
704  // that can be converted to T by one or more of
705  // -- a qualification conversion
706  // -- a function pointer conversion
707  bool LifetimeConv;
708  QualType Result;
709  // FIXME: Should we treat the exception as catchable if a lifetime
710  // conversion is required?
711  if (IsQualificationConversion(ExceptionType, HandlerType, false,
712  LifetimeConv) ||
713  IsFunctionConversion(ExceptionType, HandlerType, Result))
714  return true;
715 
716  // -- a standard pointer conversion [...]
717  if (!ExceptionType->isPointerType() || !HandlerType->isPointerType())
718  return false;
719 
720  // Handle the "qualification conversion" portion.
721  Qualifiers EQuals, HQuals;
722  ExceptionType = Context.getUnqualifiedArrayType(
723  ExceptionType->getPointeeType(), EQuals);
724  HandlerType = Context.getUnqualifiedArrayType(
725  HandlerType->getPointeeType(), HQuals);
726  if (!HQuals.compatiblyIncludes(EQuals))
727  return false;
728 
729  if (HandlerType->isVoidType() && ExceptionType->isObjectType())
730  return true;
731 
732  // The only remaining case is a derived-to-base conversion.
733  }
734 
735  // -- the handler is of type cg T or cv T& and T is an unambiguous public
736  // base class of E
737  if (!ExceptionType->isRecordType() || !HandlerType->isRecordType())
738  return false;
739  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
740  /*DetectVirtual=*/false);
741  if (!IsDerivedFrom(SourceLocation(), ExceptionType, HandlerType, Paths) ||
742  Paths.isAmbiguous(Context.getCanonicalType(HandlerType)))
743  return false;
744 
745  // Do this check from a context without privileges.
746  switch (CheckBaseClassAccess(SourceLocation(), HandlerType, ExceptionType,
747  Paths.front(),
748  /*Diagnostic*/ 0,
749  /*ForceCheck*/ true,
750  /*ForceUnprivileged*/ true)) {
751  case AR_accessible: return true;
752  case AR_inaccessible: return false;
753  case AR_dependent:
754  llvm_unreachable("access check dependent for unprivileged context");
755  case AR_delayed:
756  llvm_unreachable("access check delayed in non-declaration");
757  }
758  llvm_unreachable("unexpected access check result");
759 }
760 
761 /// CheckExceptionSpecSubset - Check whether the second function type's
762 /// exception specification is a subset (or equivalent) of the first function
763 /// type. This is used by override and pointer assignment checks.
765  const PartialDiagnostic &NestedDiagID,
766  const PartialDiagnostic &NoteID,
767  const PartialDiagnostic &NoThrowDiagID,
768  const FunctionProtoType *Superset,
769  SourceLocation SuperLoc,
770  const FunctionProtoType *Subset,
771  SourceLocation SubLoc) {
772 
773  // Just auto-succeed under -fno-exceptions.
774  if (!getLangOpts().CXXExceptions)
775  return false;
776 
777  // FIXME: As usual, we could be more specific in our error messages, but
778  // that better waits until we've got types with source locations.
779 
780  if (!SubLoc.isValid())
781  SubLoc = SuperLoc;
782 
783  // Resolve the exception specifications, if needed.
784  Superset = ResolveExceptionSpec(SuperLoc, Superset);
785  if (!Superset)
786  return false;
787  Subset = ResolveExceptionSpec(SubLoc, Subset);
788  if (!Subset)
789  return false;
790 
791  ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType();
793  assert(!isUnresolvedExceptionSpec(SuperEST) &&
794  !isUnresolvedExceptionSpec(SubEST) &&
795  "Shouldn't see unknown exception specifications here");
796 
797  // If there are dependent noexcept specs, assume everything is fine. Unlike
798  // with the equivalency check, this is safe in this case, because we don't
799  // want to merge declarations. Checks after instantiation will catch any
800  // omissions we make here.
801  if (SuperEST == EST_DependentNoexcept || SubEST == EST_DependentNoexcept)
802  return false;
803 
804  CanThrowResult SuperCanThrow = Superset->canThrow();
805  CanThrowResult SubCanThrow = Subset->canThrow();
806 
807  // If the superset contains everything or the subset contains nothing, we're
808  // done.
809  if ((SuperCanThrow == CT_Can && SuperEST != EST_Dynamic) ||
810  SubCanThrow == CT_Cannot)
811  return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
812  Subset, SubLoc);
813 
814  // Allow __declspec(nothrow) to be missing on redeclaration as an extension in
815  // some cases.
816  if (NoThrowDiagID.getDiagID() != 0 && SubCanThrow == CT_Can &&
817  SuperCanThrow == CT_Cannot && SuperEST == EST_NoThrow) {
818  Diag(SubLoc, NoThrowDiagID);
819  if (NoteID.getDiagID() != 0)
820  Diag(SuperLoc, NoteID);
821  return true;
822  }
823 
824  // If the subset contains everything or the superset contains nothing, we've
825  // failed.
826  if ((SubCanThrow == CT_Can && SubEST != EST_Dynamic) ||
827  SuperCanThrow == CT_Cannot) {
828  Diag(SubLoc, DiagID);
829  if (NoteID.getDiagID() != 0)
830  Diag(SuperLoc, NoteID);
831  return true;
832  }
833 
834  assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic &&
835  "Exception spec subset: non-dynamic case slipped through.");
836 
837  // Neither contains everything or nothing. Do a proper comparison.
838  for (QualType SubI : Subset->exceptions()) {
839  if (const ReferenceType *RefTy = SubI->getAs<ReferenceType>())
840  SubI = RefTy->getPointeeType();
841 
842  // Make sure it's in the superset.
843  bool Contained = false;
844  for (QualType SuperI : Superset->exceptions()) {
845  // [except.spec]p5:
846  // the target entity shall allow at least the exceptions allowed by the
847  // source
848  //
849  // We interpret this as meaning that a handler for some target type would
850  // catch an exception of each source type.
851  if (handlerCanCatch(SuperI, SubI)) {
852  Contained = true;
853  break;
854  }
855  }
856  if (!Contained) {
857  Diag(SubLoc, DiagID);
858  if (NoteID.getDiagID() != 0)
859  Diag(SuperLoc, NoteID);
860  return true;
861  }
862  }
863  // We've run half the gauntlet.
864  return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
865  Subset, SubLoc);
866 }
867 
868 static bool
870  const PartialDiagnostic &NoteID, QualType Target,
871  SourceLocation TargetLoc, QualType Source,
872  SourceLocation SourceLoc) {
874  if (!TFunc)
875  return false;
876  const FunctionProtoType *SFunc = GetUnderlyingFunction(Source);
877  if (!SFunc)
878  return false;
879 
880  return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc,
881  SFunc, SourceLoc);
882 }
883 
884 /// CheckParamExceptionSpec - Check if the parameter and return types of the
885 /// two functions have equivalent exception specs. This is part of the
886 /// assignment and override compatibility check. We do not check the parameters
887 /// of parameter function pointers recursively, as no sane programmer would
888 /// even be able to write such a function type.
890  const PartialDiagnostic &NoteID,
891  const FunctionProtoType *Target,
892  SourceLocation TargetLoc,
893  const FunctionProtoType *Source,
894  SourceLocation SourceLoc) {
895  auto RetDiag = DiagID;
896  RetDiag << 0;
898  *this, RetDiag, PDiag(),
899  Target->getReturnType(), TargetLoc, Source->getReturnType(),
900  SourceLoc))
901  return true;
902 
903  // We shouldn't even be testing this unless the arguments are otherwise
904  // compatible.
905  assert(Target->getNumParams() == Source->getNumParams() &&
906  "Functions have different argument counts.");
907  for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) {
908  auto ParamDiag = DiagID;
909  ParamDiag << 1;
911  *this, ParamDiag, PDiag(),
912  Target->getParamType(i), TargetLoc, Source->getParamType(i),
913  SourceLoc))
914  return true;
915  }
916  return false;
917 }
918 
920  // First we check for applicability.
921  // Target type must be a function, function pointer or function reference.
922  const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
923  if (!ToFunc || ToFunc->hasDependentExceptionSpec())
924  return false;
925 
926  // SourceType must be a function or function pointer.
927  const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
928  if (!FromFunc || FromFunc->hasDependentExceptionSpec())
929  return false;
930 
931  unsigned DiagID = diag::err_incompatible_exception_specs;
932  unsigned NestedDiagID = diag::err_deep_exception_specs_differ;
933  // This is not an error in C++17 onwards, unless the noexceptness doesn't
934  // match, but in that case we have a full-on type mismatch, not just a
935  // type sugar mismatch.
936  if (getLangOpts().CPlusPlus17) {
937  DiagID = diag::warn_incompatible_exception_specs;
938  NestedDiagID = diag::warn_deep_exception_specs_differ;
939  }
940 
941  // Now we've got the correct types on both sides, check their compatibility.
942  // This means that the source of the conversion can only throw a subset of
943  // the exceptions of the target, and any exception specs on arguments or
944  // return types must be equivalent.
945  //
946  // FIXME: If there is a nested dependent exception specification, we should
947  // not be checking it here. This is fine:
948  // template<typename T> void f() {
949  // void (*p)(void (*) throw(T));
950  // void (*q)(void (*) throw(int)) = p;
951  // }
952  // ... because it might be instantiated with T=int.
954  PDiag(DiagID), PDiag(NestedDiagID), PDiag(), PDiag(), ToFunc,
955  From->getSourceRange().getBegin(), FromFunc, SourceLocation()) &&
956  !getLangOpts().CPlusPlus17;
957 }
958 
960  const CXXMethodDecl *Old) {
961  // If the new exception specification hasn't been parsed yet, skip the check.
962  // We'll get called again once it's been parsed.
964  EST_Unparsed)
965  return false;
966 
967  // Don't check uninstantiated template destructors at all. We can only
968  // synthesize correct specs after the template is instantiated.
969  if (isa<CXXDestructorDecl>(New) && New->getParent()->isDependentType())
970  return false;
971 
972  // If the old exception specification hasn't been parsed yet, or the new
973  // exception specification can't be computed yet, remember that we need to
974  // perform this check when we get to the end of the outermost
975  // lexically-surrounding class.
977  DelayedOverridingExceptionSpecChecks.push_back({New, Old});
978  return false;
979  }
980 
981  unsigned DiagID = diag::err_override_exception_spec;
982  if (getLangOpts().MSVCCompat)
983  DiagID = diag::ext_override_exception_spec;
984  return CheckExceptionSpecSubset(PDiag(DiagID),
985  PDiag(diag::err_deep_exception_specs_differ),
986  PDiag(diag::note_overridden_virtual_function),
987  PDiag(diag::ext_override_exception_spec),
988  Old->getType()->castAs<FunctionProtoType>(),
989  Old->getLocation(),
990  New->getType()->castAs<FunctionProtoType>(),
991  New->getLocation());
992 }
993 
994 static CanThrowResult canSubStmtsThrow(Sema &Self, const Stmt *S) {
996  for (const Stmt *SubStmt : S->children()) {
997  if (!SubStmt)
998  continue;
999  R = mergeCanThrow(R, Self.canThrow(SubStmt));
1000  if (R == CT_Can)
1001  break;
1002  }
1003  return R;
1004 }
1005 
1007  SourceLocation Loc) {
1008  // As an extension, we assume that __attribute__((nothrow)) functions don't
1009  // throw.
1010  if (D && isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>())
1011  return CT_Cannot;
1012 
1013  QualType T;
1014 
1015  // In C++1z, just look at the function type of the callee.
1016  if (S.getLangOpts().CPlusPlus17 && E && isa<CallExpr>(E)) {
1017  E = cast<CallExpr>(E)->getCallee();
1018  T = E->getType();
1019  if (T->isSpecificPlaceholderType(BuiltinType::BoundMember)) {
1020  // Sadly we don't preserve the actual type as part of the "bound member"
1021  // placeholder, so we need to reconstruct it.
1022  E = E->IgnoreParenImpCasts();
1023 
1024  // Could be a call to a pointer-to-member or a plain member access.
1025  if (auto *Op = dyn_cast<BinaryOperator>(E)) {
1026  assert(Op->getOpcode() == BO_PtrMemD || Op->getOpcode() == BO_PtrMemI);
1027  T = Op->getRHS()->getType()
1028  ->castAs<MemberPointerType>()->getPointeeType();
1029  } else {
1030  T = cast<MemberExpr>(E)->getMemberDecl()->getType();
1031  }
1032  }
1033  } else if (const ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D))
1034  T = VD->getType();
1035  else
1036  // If we have no clue what we're calling, assume the worst.
1037  return CT_Can;
1038 
1039  const FunctionProtoType *FT;
1040  if ((FT = T->getAs<FunctionProtoType>())) {
1041  } else if (const PointerType *PT = T->getAs<PointerType>())
1042  FT = PT->getPointeeType()->getAs<FunctionProtoType>();
1043  else if (const ReferenceType *RT = T->getAs<ReferenceType>())
1044  FT = RT->getPointeeType()->getAs<FunctionProtoType>();
1045  else if (const MemberPointerType *MT = T->getAs<MemberPointerType>())
1046  FT = MT->getPointeeType()->getAs<FunctionProtoType>();
1047  else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
1048  FT = BT->getPointeeType()->getAs<FunctionProtoType>();
1049 
1050  if (!FT)
1051  return CT_Can;
1052 
1053  if (Loc.isValid() || (Loc.isInvalid() && E))
1054  FT = S.ResolveExceptionSpec(Loc.isInvalid() ? E->getBeginLoc() : Loc, FT);
1055  if (!FT)
1056  return CT_Can;
1057 
1058  return FT->canThrow();
1059 }
1060 
1061 static CanThrowResult canVarDeclThrow(Sema &Self, const VarDecl *VD) {
1063 
1064  // Initialization might throw.
1065  if (!VD->isUsableInConstantExpressions(Self.Context))
1066  if (const Expr *Init = VD->getInit())
1067  CT = mergeCanThrow(CT, Self.canThrow(Init));
1068 
1069  // Destructor might throw.
1071  if (auto *RD =
1073  if (auto *Dtor = RD->getDestructor()) {
1074  CT = mergeCanThrow(
1075  CT, Sema::canCalleeThrow(Self, nullptr, Dtor, VD->getLocation()));
1076  }
1077  }
1078  }
1079 
1080  // If this is a decomposition declaration, bindings might throw.
1081  if (auto *DD = dyn_cast<DecompositionDecl>(VD))
1082  for (auto *B : DD->bindings())
1083  if (auto *HD = B->getHoldingVar())
1084  CT = mergeCanThrow(CT, canVarDeclThrow(Self, HD));
1085 
1086  return CT;
1087 }
1088 
1090  if (DC->isTypeDependent())
1091  return CT_Dependent;
1092 
1093  if (!DC->getTypeAsWritten()->isReferenceType())
1094  return CT_Cannot;
1095 
1096  if (DC->getSubExpr()->isTypeDependent())
1097  return CT_Dependent;
1098 
1099  return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot;
1100 }
1101 
1103  if (DC->isTypeOperand())
1104  return CT_Cannot;
1105 
1106  Expr *Op = DC->getExprOperand();
1107  if (Op->isTypeDependent())
1108  return CT_Dependent;
1109 
1110  const RecordType *RT = Op->getType()->getAs<RecordType>();
1111  if (!RT)
1112  return CT_Cannot;
1113 
1114  if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic())
1115  return CT_Cannot;
1116 
1117  if (Op->Classify(S.Context).isPRValue())
1118  return CT_Cannot;
1119 
1120  return CT_Can;
1121 }
1122 
1124  // C++ [expr.unary.noexcept]p3:
1125  // [Can throw] if in a potentially-evaluated context the expression would
1126  // contain:
1127  switch (S->getStmtClass()) {
1128  case Expr::ConstantExprClass:
1129  return canThrow(cast<ConstantExpr>(S)->getSubExpr());
1130 
1131  case Expr::CXXThrowExprClass:
1132  // - a potentially evaluated throw-expression
1133  return CT_Can;
1134 
1135  case Expr::CXXDynamicCastExprClass: {
1136  // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
1137  // where T is a reference type, that requires a run-time check
1138  auto *CE = cast<CXXDynamicCastExpr>(S);
1139  // FIXME: Properly determine whether a variably-modified type can throw.
1140  if (CE->getType()->isVariablyModifiedType())
1141  return CT_Can;
1143  if (CT == CT_Can)
1144  return CT;
1145  return mergeCanThrow(CT, canSubStmtsThrow(*this, CE));
1146  }
1147 
1148  case Expr::CXXTypeidExprClass:
1149  // - a potentially evaluated typeid expression applied to a glvalue
1150  // expression whose type is a polymorphic class type
1151  return canTypeidThrow(*this, cast<CXXTypeidExpr>(S));
1152 
1153  // - a potentially evaluated call to a function, member function, function
1154  // pointer, or member function pointer that does not have a non-throwing
1155  // exception-specification
1156  case Expr::CallExprClass:
1157  case Expr::CXXMemberCallExprClass:
1158  case Expr::CXXOperatorCallExprClass:
1159  case Expr::UserDefinedLiteralClass: {
1160  const CallExpr *CE = cast<CallExpr>(S);
1161  CanThrowResult CT;
1162  if (CE->isTypeDependent())
1163  CT = CT_Dependent;
1164  else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens()))
1165  CT = CT_Cannot;
1166  else
1167  CT = canCalleeThrow(*this, CE, CE->getCalleeDecl());
1168  if (CT == CT_Can)
1169  return CT;
1170  return mergeCanThrow(CT, canSubStmtsThrow(*this, CE));
1171  }
1172 
1173  case Expr::CXXConstructExprClass:
1174  case Expr::CXXTemporaryObjectExprClass: {
1175  auto *CE = cast<CXXConstructExpr>(S);
1176  // FIXME: Properly determine whether a variably-modified type can throw.
1177  if (CE->getType()->isVariablyModifiedType())
1178  return CT_Can;
1179  CanThrowResult CT = canCalleeThrow(*this, CE, CE->getConstructor());
1180  if (CT == CT_Can)
1181  return CT;
1182  return mergeCanThrow(CT, canSubStmtsThrow(*this, CE));
1183  }
1184 
1185  case Expr::CXXInheritedCtorInitExprClass: {
1186  auto *ICIE = cast<CXXInheritedCtorInitExpr>(S);
1187  return canCalleeThrow(*this, ICIE, ICIE->getConstructor());
1188  }
1189 
1190  case Expr::LambdaExprClass: {
1191  const LambdaExpr *Lambda = cast<LambdaExpr>(S);
1194  Cap = Lambda->capture_init_begin(),
1195  CapEnd = Lambda->capture_init_end();
1196  Cap != CapEnd; ++Cap)
1197  CT = mergeCanThrow(CT, canThrow(*Cap));
1198  return CT;
1199  }
1200 
1201  case Expr::CXXNewExprClass: {
1202  auto *NE = cast<CXXNewExpr>(S);
1203  CanThrowResult CT;
1204  if (NE->isTypeDependent())
1205  CT = CT_Dependent;
1206  else
1207  CT = canCalleeThrow(*this, NE, NE->getOperatorNew());
1208  if (CT == CT_Can)
1209  return CT;
1210  return mergeCanThrow(CT, canSubStmtsThrow(*this, NE));
1211  }
1212 
1213  case Expr::CXXDeleteExprClass: {
1214  auto *DE = cast<CXXDeleteExpr>(S);
1215  CanThrowResult CT;
1216  QualType DTy = DE->getDestroyedType();
1217  if (DTy.isNull() || DTy->isDependentType()) {
1218  CT = CT_Dependent;
1219  } else {
1220  CT = canCalleeThrow(*this, DE, DE->getOperatorDelete());
1221  if (const RecordType *RT = DTy->getAs<RecordType>()) {
1222  const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
1223  const CXXDestructorDecl *DD = RD->getDestructor();
1224  if (DD)
1225  CT = mergeCanThrow(CT, canCalleeThrow(*this, DE, DD));
1226  }
1227  if (CT == CT_Can)
1228  return CT;
1229  }
1230  return mergeCanThrow(CT, canSubStmtsThrow(*this, DE));
1231  }
1232 
1233  case Expr::CXXBindTemporaryExprClass: {
1234  auto *BTE = cast<CXXBindTemporaryExpr>(S);
1235  // The bound temporary has to be destroyed again, which might throw.
1236  CanThrowResult CT =
1237  canCalleeThrow(*this, BTE, BTE->getTemporary()->getDestructor());
1238  if (CT == CT_Can)
1239  return CT;
1240  return mergeCanThrow(CT, canSubStmtsThrow(*this, BTE));
1241  }
1242 
1243  case Expr::PseudoObjectExprClass: {
1244  auto *POE = cast<PseudoObjectExpr>(S);
1246  for (const Expr *E : POE->semantics()) {
1247  CT = mergeCanThrow(CT, canThrow(E));
1248  if (CT == CT_Can)
1249  break;
1250  }
1251  return CT;
1252  }
1253 
1254  // ObjC message sends are like function calls, but never have exception
1255  // specs.
1256  case Expr::ObjCMessageExprClass:
1257  case Expr::ObjCPropertyRefExprClass:
1258  case Expr::ObjCSubscriptRefExprClass:
1259  return CT_Can;
1260 
1261  // All the ObjC literals that are implemented as calls are
1262  // potentially throwing unless we decide to close off that
1263  // possibility.
1264  case Expr::ObjCArrayLiteralClass:
1265  case Expr::ObjCDictionaryLiteralClass:
1266  case Expr::ObjCBoxedExprClass:
1267  return CT_Can;
1268 
1269  // Many other things have subexpressions, so we have to test those.
1270  // Some are simple:
1271  case Expr::CoawaitExprClass:
1272  case Expr::ConditionalOperatorClass:
1273  case Expr::CoyieldExprClass:
1274  case Expr::CXXRewrittenBinaryOperatorClass:
1275  case Expr::CXXStdInitializerListExprClass:
1276  case Expr::DesignatedInitExprClass:
1277  case Expr::DesignatedInitUpdateExprClass:
1278  case Expr::ExprWithCleanupsClass:
1279  case Expr::ExtVectorElementExprClass:
1280  case Expr::InitListExprClass:
1281  case Expr::ArrayInitLoopExprClass:
1282  case Expr::MemberExprClass:
1283  case Expr::ObjCIsaExprClass:
1284  case Expr::ObjCIvarRefExprClass:
1285  case Expr::ParenExprClass:
1286  case Expr::ParenListExprClass:
1287  case Expr::ShuffleVectorExprClass:
1288  case Expr::StmtExprClass:
1289  case Expr::ConvertVectorExprClass:
1290  case Expr::VAArgExprClass:
1291  return canSubStmtsThrow(*this, S);
1292 
1293  case Expr::CompoundLiteralExprClass:
1294  case Expr::CXXConstCastExprClass:
1295  case Expr::CXXAddrspaceCastExprClass:
1296  case Expr::CXXReinterpretCastExprClass:
1297  case Expr::BuiltinBitCastExprClass:
1298  // FIXME: Properly determine whether a variably-modified type can throw.
1299  if (cast<Expr>(S)->getType()->isVariablyModifiedType())
1300  return CT_Can;
1301  return canSubStmtsThrow(*this, S);
1302 
1303  // Some might be dependent for other reasons.
1304  case Expr::ArraySubscriptExprClass:
1305  case Expr::MatrixSubscriptExprClass:
1306  case Expr::OMPArraySectionExprClass:
1307  case Expr::OMPArrayShapingExprClass:
1308  case Expr::OMPIteratorExprClass:
1309  case Expr::BinaryOperatorClass:
1310  case Expr::DependentCoawaitExprClass:
1311  case Expr::CompoundAssignOperatorClass:
1312  case Expr::CStyleCastExprClass:
1313  case Expr::CXXStaticCastExprClass:
1314  case Expr::CXXFunctionalCastExprClass:
1315  case Expr::ImplicitCastExprClass:
1316  case Expr::MaterializeTemporaryExprClass:
1317  case Expr::UnaryOperatorClass: {
1318  // FIXME: Properly determine whether a variably-modified type can throw.
1319  if (auto *CE = dyn_cast<CastExpr>(S))
1320  if (CE->getType()->isVariablyModifiedType())
1321  return CT_Can;
1322  CanThrowResult CT =
1323  cast<Expr>(S)->isTypeDependent() ? CT_Dependent : CT_Cannot;
1324  return mergeCanThrow(CT, canSubStmtsThrow(*this, S));
1325  }
1326 
1327  case Expr::CXXDefaultArgExprClass:
1328  return canThrow(cast<CXXDefaultArgExpr>(S)->getExpr());
1329 
1330  case Expr::CXXDefaultInitExprClass:
1331  return canThrow(cast<CXXDefaultInitExpr>(S)->getExpr());
1332 
1333  case Expr::ChooseExprClass: {
1334  auto *CE = cast<ChooseExpr>(S);
1335  if (CE->isTypeDependent() || CE->isValueDependent())
1336  return CT_Dependent;
1337  return canThrow(CE->getChosenSubExpr());
1338  }
1339 
1340  case Expr::GenericSelectionExprClass:
1341  if (cast<GenericSelectionExpr>(S)->isResultDependent())
1342  return CT_Dependent;
1343  return canThrow(cast<GenericSelectionExpr>(S)->getResultExpr());
1344 
1345  // Some expressions are always dependent.
1346  case Expr::CXXDependentScopeMemberExprClass:
1347  case Expr::CXXUnresolvedConstructExprClass:
1348  case Expr::DependentScopeDeclRefExprClass:
1349  case Expr::CXXFoldExprClass:
1350  case Expr::RecoveryExprClass:
1351  return CT_Dependent;
1352 
1353  case Expr::AsTypeExprClass:
1354  case Expr::BinaryConditionalOperatorClass:
1355  case Expr::BlockExprClass:
1356  case Expr::CUDAKernelCallExprClass:
1357  case Expr::DeclRefExprClass:
1358  case Expr::ObjCBridgedCastExprClass:
1359  case Expr::ObjCIndirectCopyRestoreExprClass:
1360  case Expr::ObjCProtocolExprClass:
1361  case Expr::ObjCSelectorExprClass:
1362  case Expr::ObjCAvailabilityCheckExprClass:
1363  case Expr::OffsetOfExprClass:
1364  case Expr::PackExpansionExprClass:
1365  case Expr::SubstNonTypeTemplateParmExprClass:
1366  case Expr::SubstNonTypeTemplateParmPackExprClass:
1367  case Expr::FunctionParmPackExprClass:
1368  case Expr::UnaryExprOrTypeTraitExprClass:
1369  case Expr::UnresolvedLookupExprClass:
1370  case Expr::UnresolvedMemberExprClass:
1371  case Expr::TypoExprClass:
1372  // FIXME: Many of the above can throw.
1373  return CT_Cannot;
1374 
1375  case Expr::AddrLabelExprClass:
1376  case Expr::ArrayTypeTraitExprClass:
1377  case Expr::AtomicExprClass:
1378  case Expr::TypeTraitExprClass:
1379  case Expr::CXXBoolLiteralExprClass:
1380  case Expr::CXXNoexceptExprClass:
1381  case Expr::CXXNullPtrLiteralExprClass:
1382  case Expr::CXXPseudoDestructorExprClass:
1383  case Expr::CXXScalarValueInitExprClass:
1384  case Expr::CXXThisExprClass:
1385  case Expr::CXXUuidofExprClass:
1386  case Expr::CharacterLiteralClass:
1387  case Expr::ExpressionTraitExprClass:
1388  case Expr::FloatingLiteralClass:
1389  case Expr::GNUNullExprClass:
1390  case Expr::ImaginaryLiteralClass:
1391  case Expr::ImplicitValueInitExprClass:
1392  case Expr::IntegerLiteralClass:
1393  case Expr::FixedPointLiteralClass:
1394  case Expr::ArrayInitIndexExprClass:
1395  case Expr::NoInitExprClass:
1396  case Expr::ObjCEncodeExprClass:
1397  case Expr::ObjCStringLiteralClass:
1398  case Expr::ObjCBoolLiteralExprClass:
1399  case Expr::OpaqueValueExprClass:
1400  case Expr::PredefinedExprClass:
1401  case Expr::SizeOfPackExprClass:
1402  case Expr::StringLiteralClass:
1403  case Expr::SourceLocExprClass:
1404  case Expr::ConceptSpecializationExprClass:
1405  case Expr::RequiresExprClass:
1406  // These expressions can never throw.
1407  return CT_Cannot;
1408 
1409  case Expr::MSPropertyRefExprClass:
1410  case Expr::MSPropertySubscriptExprClass:
1411  llvm_unreachable("Invalid class for expression");
1412 
1413  // Most statements can throw if any substatement can throw.
1414  case Stmt::AttributedStmtClass:
1415  case Stmt::BreakStmtClass:
1416  case Stmt::CapturedStmtClass:
1417  case Stmt::CaseStmtClass:
1418  case Stmt::CompoundStmtClass:
1419  case Stmt::ContinueStmtClass:
1420  case Stmt::CoreturnStmtClass:
1421  case Stmt::CoroutineBodyStmtClass:
1422  case Stmt::CXXCatchStmtClass:
1423  case Stmt::CXXForRangeStmtClass:
1424  case Stmt::DefaultStmtClass:
1425  case Stmt::DoStmtClass:
1426  case Stmt::ForStmtClass:
1427  case Stmt::GCCAsmStmtClass:
1428  case Stmt::GotoStmtClass:
1429  case Stmt::IndirectGotoStmtClass:
1430  case Stmt::LabelStmtClass:
1431  case Stmt::MSAsmStmtClass:
1432  case Stmt::MSDependentExistsStmtClass:
1433  case Stmt::NullStmtClass:
1434  case Stmt::ObjCAtCatchStmtClass:
1435  case Stmt::ObjCAtFinallyStmtClass:
1436  case Stmt::ObjCAtSynchronizedStmtClass:
1437  case Stmt::ObjCAutoreleasePoolStmtClass:
1438  case Stmt::ObjCForCollectionStmtClass:
1439  case Stmt::OMPAtomicDirectiveClass:
1440  case Stmt::OMPBarrierDirectiveClass:
1441  case Stmt::OMPCancelDirectiveClass:
1442  case Stmt::OMPCancellationPointDirectiveClass:
1443  case Stmt::OMPCriticalDirectiveClass:
1444  case Stmt::OMPDistributeDirectiveClass:
1445  case Stmt::OMPDistributeParallelForDirectiveClass:
1446  case Stmt::OMPDistributeParallelForSimdDirectiveClass:
1447  case Stmt::OMPDistributeSimdDirectiveClass:
1448  case Stmt::OMPFlushDirectiveClass:
1449  case Stmt::OMPDepobjDirectiveClass:
1450  case Stmt::OMPScanDirectiveClass:
1451  case Stmt::OMPForDirectiveClass:
1452  case Stmt::OMPForSimdDirectiveClass:
1453  case Stmt::OMPMasterDirectiveClass:
1454  case Stmt::OMPMasterTaskLoopDirectiveClass:
1455  case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
1456  case Stmt::OMPOrderedDirectiveClass:
1457  case Stmt::OMPCanonicalLoopClass:
1458  case Stmt::OMPParallelDirectiveClass:
1459  case Stmt::OMPParallelForDirectiveClass:
1460  case Stmt::OMPParallelForSimdDirectiveClass:
1461  case Stmt::OMPParallelMasterDirectiveClass:
1462  case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
1463  case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
1464  case Stmt::OMPParallelSectionsDirectiveClass:
1465  case Stmt::OMPSectionDirectiveClass:
1466  case Stmt::OMPSectionsDirectiveClass:
1467  case Stmt::OMPSimdDirectiveClass:
1468  case Stmt::OMPTileDirectiveClass:
1469  case Stmt::OMPUnrollDirectiveClass:
1470  case Stmt::OMPSingleDirectiveClass:
1471  case Stmt::OMPTargetDataDirectiveClass:
1472  case Stmt::OMPTargetDirectiveClass:
1473  case Stmt::OMPTargetEnterDataDirectiveClass:
1474  case Stmt::OMPTargetExitDataDirectiveClass:
1475  case Stmt::OMPTargetParallelDirectiveClass:
1476  case Stmt::OMPTargetParallelForDirectiveClass:
1477  case Stmt::OMPTargetParallelForSimdDirectiveClass:
1478  case Stmt::OMPTargetSimdDirectiveClass:
1479  case Stmt::OMPTargetTeamsDirectiveClass:
1480  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
1481  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
1482  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
1483  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
1484  case Stmt::OMPTargetUpdateDirectiveClass:
1485  case Stmt::OMPTaskDirectiveClass:
1486  case Stmt::OMPTaskgroupDirectiveClass:
1487  case Stmt::OMPTaskLoopDirectiveClass:
1488  case Stmt::OMPTaskLoopSimdDirectiveClass:
1489  case Stmt::OMPTaskwaitDirectiveClass:
1490  case Stmt::OMPTaskyieldDirectiveClass:
1491  case Stmt::OMPTeamsDirectiveClass:
1492  case Stmt::OMPTeamsDistributeDirectiveClass:
1493  case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
1494  case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
1495  case Stmt::OMPTeamsDistributeSimdDirectiveClass:
1496  case Stmt::OMPInteropDirectiveClass:
1497  case Stmt::OMPDispatchDirectiveClass:
1498  case Stmt::OMPMaskedDirectiveClass:
1499  case Stmt::OMPMetaDirectiveClass:
1500  case Stmt::ReturnStmtClass:
1501  case Stmt::SEHExceptStmtClass:
1502  case Stmt::SEHFinallyStmtClass:
1503  case Stmt::SEHLeaveStmtClass:
1504  case Stmt::SEHTryStmtClass:
1505  case Stmt::SwitchStmtClass:
1506  case Stmt::WhileStmtClass:
1507  return canSubStmtsThrow(*this, S);
1508 
1509  case Stmt::DeclStmtClass: {
1511  for (const Decl *D : cast<DeclStmt>(S)->decls()) {
1512  if (auto *VD = dyn_cast<VarDecl>(D))
1513  CT = mergeCanThrow(CT, canVarDeclThrow(*this, VD));
1514 
1515  // FIXME: Properly determine whether a variably-modified type can throw.
1516  if (auto *TND = dyn_cast<TypedefNameDecl>(D))
1517  if (TND->getUnderlyingType()->isVariablyModifiedType())
1518  return CT_Can;
1519  if (auto *VD = dyn_cast<ValueDecl>(D))
1520  if (VD->getType()->isVariablyModifiedType())
1521  return CT_Can;
1522  }
1523  return CT;
1524  }
1525 
1526  case Stmt::IfStmtClass: {
1527  auto *IS = cast<IfStmt>(S);
1529  if (const Stmt *Init = IS->getInit())
1530  CT = mergeCanThrow(CT, canThrow(Init));
1531  if (const Stmt *CondDS = IS->getConditionVariableDeclStmt())
1532  CT = mergeCanThrow(CT, canThrow(CondDS));
1533  CT = mergeCanThrow(CT, canThrow(IS->getCond()));
1534 
1535  // For 'if constexpr', consider only the non-discarded case.
1536  // FIXME: We should add a DiscardedStmt marker to the AST.
1537  if (Optional<const Stmt *> Case = IS->getNondiscardedCase(Context))
1538  return *Case ? mergeCanThrow(CT, canThrow(*Case)) : CT;
1539 
1540  CanThrowResult Then = canThrow(IS->getThen());
1541  CanThrowResult Else = IS->getElse() ? canThrow(IS->getElse()) : CT_Cannot;
1542  if (Then == Else)
1543  return mergeCanThrow(CT, Then);
1544 
1545  // For a dependent 'if constexpr', the result is dependent if it depends on
1546  // the value of the condition.
1547  return mergeCanThrow(CT, IS->isConstexpr() ? CT_Dependent
1548  : mergeCanThrow(Then, Else));
1549  }
1550 
1551  case Stmt::CXXTryStmtClass: {
1552  auto *TS = cast<CXXTryStmt>(S);
1553  // try /*...*/ catch (...) { H } can throw only if H can throw.
1554  // Any other try-catch can throw if any substatement can throw.
1555  const CXXCatchStmt *FinalHandler = TS->getHandler(TS->getNumHandlers() - 1);
1556  if (!FinalHandler->getExceptionDecl())
1557  return canThrow(FinalHandler->getHandlerBlock());
1558  return canSubStmtsThrow(*this, S);
1559  }
1560 
1561  case Stmt::ObjCAtThrowStmtClass:
1562  return CT_Can;
1563 
1564  case Stmt::ObjCAtTryStmtClass: {
1565  auto *TS = cast<ObjCAtTryStmt>(S);
1566 
1567  // @catch(...) need not be last in Objective-C. Walk backwards until we
1568  // see one or hit the @try.
1570  if (const Stmt *Finally = TS->getFinallyStmt())
1571  CT = mergeCanThrow(CT, canThrow(Finally));
1572  for (unsigned I = TS->getNumCatchStmts(); I != 0; --I) {
1573  const ObjCAtCatchStmt *Catch = TS->getCatchStmt(I - 1);
1574  CT = mergeCanThrow(CT, canThrow(Catch));
1575  // If we reach a @catch(...), no earlier exceptions can escape.
1576  if (Catch->hasEllipsis())
1577  return CT;
1578  }
1579 
1580  // Didn't find an @catch(...). Exceptions from the @try body can escape.
1581  return mergeCanThrow(CT, canThrow(TS->getTryBody()));
1582  }
1583 
1584  case Stmt::SYCLUniqueStableNameExprClass:
1585  return CT_Cannot;
1586  case Stmt::NoStmtClass:
1587  llvm_unreachable("Invalid class for statement");
1588  }
1589  llvm_unreachable("Bogus StmtClass");
1590 }
1591 
1592 } // end namespace clang
clang::Sema::CurContext
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:423
clang::Type::isRecordType
bool isRecordType() const
Definition: Type.h:6763
clang::canDynamicCastThrow
static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC)
Definition: SemaExceptionSpec.cpp:1089
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:4120
clang::FunctionProtoType::hasDependentExceptionSpec
bool hasDependentExceptionSpec() const
Return whether this function has a dependent exception spec.
Definition: Type.cpp:3266
clang::SourceRange
A trivial tuple used to represent a source range.
Definition: SourceLocation.h:212
clang::Decl::hasAttr
bool hasAttr() const
Definition: DeclBase.h:547
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:96
clang::QualType::isConstQualified
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:6484
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:959
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:88
clang::SourceRange::getBegin
SourceLocation getBegin() const
Definition: SourceLocation.h:221
clang::MultiVersionKind::Target
@ Target
clang::CastExpr::getSubExpr
Expr * getSubExpr()
Definition: Expr.h:3524
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:673
clang::ObjCAtCatchStmt::hasEllipsis
bool hasEllipsis() const
Definition: StmtObjC.h:113
clang::Declarator::getIdentifier
IdentifierInfo * getIdentifier() const
Definition: DeclSpec.h:2189
clang::Sema::AR_accessible
@ AR_accessible
Definition: Sema.h:7330
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:839
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:145
clang::FunctionProtoType::hasExceptionSpec
bool hasExceptionSpec() const
Return whether this function has any kind of exception spec.
Definition: Type.h:4126
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:1832
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:1516
clang::Sema::AR_dependent
@ AR_dependent
Definition: Sema.h:7332
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:6956
clang::QualType::isVolatileQualified
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Definition: Type.h:6495
clang::EST_Unparsed
@ EST_Unparsed
not parsed yet
Definition: ExceptionSpecificationType.h:32
clang::CallExpr::getCalleeDecl
Decl * getCalleeDecl()
Definition: Expr.h:2959
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:515
clang::CXXTypeidExpr::getExprOperand
Expr * getExprOperand() const
Definition: ExprCXX.h:886
clang::ASTContext::getSourceManager
SourceManager & getSourceManager()
Definition: ASTContext.h:694
clang::Sema::AR_delayed
@ AR_delayed
Definition: Sema.h:7333
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:411
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:71
clang::CXXCatchStmt::getHandlerBlock
Stmt * getHandlerBlock() const
Definition: StmtCXX.h:51
clang::CPlusPlus17
@ CPlusPlus17
Definition: LangStandard.h:51
clang::Sema::getLangOpts
const LangOptions & getLangOpts() const
Definition: Sema.h:1562
clang::EST_DependentNoexcept
@ EST_DependentNoexcept
noexcept(expression), value-dependent
Definition: ExceptionSpecificationType.h:27
clang::ReferenceType::getPointeeType
QualType getPointeeType() const
Definition: Type.h:2769
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:3493
clang::canVarDeclThrow
static CanThrowResult canVarDeclThrow(Sema &Self, const VarDecl *VD)
Definition: SemaExceptionSpec.cpp:1061
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:156
clang::QualType::DK_cxx_destructor
@ DK_cxx_destructor
Definition: Type.h:1204
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:8422
clang::Type::isReferenceType
bool isReferenceType() const
Definition: Type.h:6685
clang::CallExpr::getCallee
Expr * getCallee()
Definition: Expr.h:2945
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:887
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:4613
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:462
clang::Declarator::getBeginLoc
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclSpec.h:1947
clang::Stmt::printPretty
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
Definition: StmtPrinter.cpp:2573
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:1006
clang::Sema::InstantiateExceptionSpec
void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Function)
Definition: SemaTemplateInstantiateDecl.cpp:4509
clang::FunctionProtoType::ExceptionSpecInfo
Holds information about the various types of exception specification.
Definition: Type.h:3942
clang::Type::isNullPtrType
bool isNullPtrType() const
Definition: Type.h:6981
clang::LambdaExpr
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1865
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:994
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7162
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:3528
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:4097
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:2668
clang::Type::isFunctionType
bool isFunctionType() const
Definition: Type.h:6669
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:2297
clang::LambdaExpr::const_capture_init_iterator
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
Definition: ExprCXX.h:1978
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:3193
clang::Redeclarable::redecls
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: Redeclarable.h:295
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:1523
clang::FunctionProtoType::canThrow
CanThrowResult canThrow() const
Determine whether this function type has a non-throwing exception specification.
Definition: Type.cpp:3287
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:876
clang::FunctionProtoType::getParamTypes
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:4102
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:2462
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:1753
clang::Sema::getLocForEndOfToken
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:54
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:2303
clang::CanQual< Type >
ExprCXX.h
clang::Sema::canThrow
CanThrowResult canThrow(const Stmt *E)
Definition: SemaExceptionSpec.cpp:1123
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:2720
clang::Sema::getASTMutationListener
ASTMutationListener * getASTMutationListener() const
Definition: Sema.cpp:514
clang::CastExpr::getCastKind
CastKind getCastKind() const
Definition: Expr.h:3518
clang::OverloadedOperatorKind
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
StmtObjC.h
clang::FunctionProtoType::ExtProtoInfo::withExceptionSpec
ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &ESI)
Definition: Type.h:3983
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:514
clang::Type::castAs
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7227
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:889
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:3264
clang::CXXRecordDecl
Represents a C++ struct/union/class.
Definition: DeclCXX.h:255
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:2174
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:2806
clang::Type::isMemberPointerType
bool isMemberPointerType() const
Definition: Type.h:6721
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6673
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:2004
clang::ConstantExpr::Create
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Definition: Expr.cpp:302
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:676
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:5797
clang::FunctionProtoType
Represents a prototype with parameter type info, e.g.
Definition: Type.h:3885
clang::FunctionProtoType::exception_begin
exception_iterator exception_begin() const
Definition: Type.h:4268
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:6945
clang::QualType::isNull
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:738
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:4178
clang::Sema::AR_inaccessible
@ AR_inaccessible
Definition: Sema.h:7331
Value
Value
Definition: UninitializedValues.cpp:102
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:764
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::CXXTypeidExpr::isTypeOperand
bool isTypeOperand() const
Definition: ExprCXX.h:875
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:2928
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:3105
ASTMutationListener.h
clang::Sema
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:355
clang::ActionResult::isInvalid
bool isInvalid() const
Definition: Ownership.h:165
clang::Sema::handlerCanCatch
bool handlerCanCatch(QualType HandlerType, QualType ExceptionType)
Definition: SemaExceptionSpec.cpp:677
clang::EST_MSAny
@ EST_MSAny
Microsoft throw(...) extension.
Definition: ExceptionSpecificationType.h:24
clang::FunctionProtoType::getNumParams
unsigned getNumParams() const
Definition: Type.h:4095
clang::CheckSpecForTypesEquivalent
static bool CheckSpecForTypesEquivalent(Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, QualType Target, SourceLocation TargetLoc, QualType Source, SourceLocation SourceLoc)
Definition: SemaExceptionSpec.cpp:869
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:4188
clang::VarDecl::getInit
const Expr * getInit() const
Definition: Decl.h:1285
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:67
clang::canTypeidThrow
static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC)
Definition: SemaExceptionSpec.cpp:1102
clang::Sema::CheckEquivalentExceptionSpec
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New)
Definition: SemaExceptionSpec.cpp:291
clang::PartialDiagnostic::getDiagID
unsigned getDiagID() const
Definition: PartialDiagnostic.h:144
clang::CXXRecordDecl::getDestructor
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
Definition: DeclCXX.cpp:1887
clang::PartialDiagnostic
Definition: PartialDiagnostic.h:34
clang::FunctionDecl::isExternC
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition: Decl.cpp:3200
clang::MemberPointerType
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition: Type.h:2831
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:3944
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:2368
clang::TypeLoc::IgnoreParens
TypeLoc IgnoreParens() const
Definition: TypeLoc.h:1150
clang::PointerType
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2640
clang::FunctionProtoType::exceptions
ArrayRef< QualType > exceptions() const
Definition: Type.h:4264
clang::Type::getBaseElementTypeUnsafe
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
Definition: Type.h:7112
clang::CanQual::getUnqualifiedType
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
Definition: CanonicalType.h:620
clang::interp::NE
bool NE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:225
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:113
clang::Expr::IgnoreParens
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:2924
clang
Definition: CalledOnceCheck.h:17
clang::Type::isArrayType
bool isArrayType() const
Definition: Type.h:6739
clang::Sema::CheckConvertedConstantExpression
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE)
Definition: SemaOverload.cpp:5864
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:68
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:1804
clang::SourceManager::isInSystemHeader
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
Definition: SourceManager.h:1488
clang::Type::isObjectType
bool isObjectType() const
Determine whether this type is an object type.
Definition: Type.h:1932
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:112
clang::TypeSourceInfo
A container of type source information.
Definition: Type.h:6396
clang::FunctionType::getReturnType
QualType getReturnType() const
Definition: Type.h:3809
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:7306
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:4623
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:2678
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:3251
clang::CPlusPlus11
@ CPlusPlus11
Definition: LangStandard.h:49
clang::ReferenceType
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2751
clang::FunctionProtoTypeLoc
Definition: TypeLoc.h:1465
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:6263
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:3484
clang::EST_NoexceptFalse
@ EST_NoexceptFalse
noexcept(expression), evals to 'false'
Definition: ExceptionSpecificationType.h:28
clang::ValueDecl::getType
QualType getType() const
Definition: Decl.h:687
clang::FunctionDecl::getBuiltinID
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition: Decl.cpp:3298
clang::Sema::getPrintingPolicy
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition: Sema.h:2988
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:2502
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::CXXCatchStmt::getExceptionDecl
VarDecl * getExceptionDecl() const
Definition: StmtCXX.h:49
clang::FunctionProtoType::getExtProtoInfo
ExtProtoInfo getExtProtoInfo() const
Definition: Type.h:4106
clang::Sema::CheckExceptionSpecCompatibility
bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
Definition: SemaExceptionSpec.cpp:919
clang::Decl::getLocation
SourceLocation getLocation() const
Definition: DeclBase.h:430
clang::ASTContext::BoolTy
CanQualType BoolTy
Definition: ASTContext.h:1068
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1856
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:2795
clang::DeclaratorDecl::getTypeSourceInfo
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:757
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:3720
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:1842
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:1992
clang::ValueDecl::setType
void setType(QualType newType)
Definition: Decl.h:688
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:2063
clang::FunctionProtoType::getNumExceptions
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4163
clang::CXXMethodDecl
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1948
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:895