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