1 //===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides Sema routines for C++ exception specification testing.
12 //===----------------------------------------------------------------------===//
14 #include "clang/Sema/SemaInternal.h"
15 #include "clang/AST/ASTMutationListener.h"
16 #include "clang/AST/CXXInheritance.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/AST/ExprCXX.h"
19 #include "clang/AST/TypeLoc.h"
20 #include "clang/Basic/Diagnostic.h"
21 #include "clang/Basic/SourceManager.h"
22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/SmallString.h"
27 static const FunctionProtoType *GetUnderlyingFunction(QualType T)
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>();
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.
42 bool Sema::isLibstdcxxEagerExceptionSpecHack(const Declarator &D) {
43 auto *RD = dyn_cast<CXXRecordDecl>(CurContext);
45 // All the problem cases are member functions named "swap" within class
46 // templates declared directly within namespace std or std::__debug or
48 if (!RD || !RD->getIdentifier() || !RD->getDescribedClassTemplate() ||
49 !D.getIdentifier() || !D.getIdentifier()->isStr("swap"))
52 auto *ND = dyn_cast<NamespaceDecl>(RD->getDeclContext());
56 bool IsInStd = ND->isStdNamespace();
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())
66 // Only apply this hack within a system header.
67 if (!Context.getSourceManager().isInSystemHeader(D.getLocStart()))
70 return llvm::StringSwitch<bool>(RD->getIdentifier()->getName())
72 .Case("pair", IsInStd)
73 .Case("priority_queue", IsInStd)
74 .Case("stack", IsInStd)
75 .Case("queue", IsInStd)
79 /// CheckSpecifiedExceptionType - Check if the given type is valid in an
80 /// exception specification. Incomplete types, or pointers to incomplete types
81 /// other than void are not allowed.
83 /// \param[in,out] T The exception type. This will be decayed to a pointer type
84 /// when the input is an array or a function type.
85 bool Sema::CheckSpecifiedExceptionType(QualType &T, SourceRange Range) {
86 // C++11 [except.spec]p2:
87 // A type cv T, "array of T", or "function returning T" denoted
88 // in an exception-specification is adjusted to type T, "pointer to T", or
89 // "pointer to function returning T", respectively.
91 // We also apply this rule in C++98.
93 T = Context.getArrayDecayedType(T);
94 else if (T->isFunctionType())
95 T = Context.getPointerType(T);
98 QualType PointeeT = T;
99 if (const PointerType *PT = T->getAs<PointerType>()) {
100 PointeeT = PT->getPointeeType();
103 // cv void* is explicitly permitted, despite being a pointer to an
105 if (PointeeT->isVoidType())
107 } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
108 PointeeT = RT->getPointeeType();
111 if (RT->isRValueReferenceType()) {
112 // C++11 [except.spec]p2:
113 // A type denoted in an exception-specification shall not denote [...]
114 // an rvalue reference type.
115 Diag(Range.getBegin(), diag::err_rref_in_exception_spec)
121 // C++11 [except.spec]p2:
122 // A type denoted in an exception-specification shall not denote an
123 // incomplete type other than a class currently being defined [...].
124 // A type denoted in an exception-specification shall not denote a
125 // pointer or reference to an incomplete type, other than (cv) void* or a
126 // pointer or reference to a class currently being defined.
127 // In Microsoft mode, downgrade this to a warning.
128 unsigned DiagID = diag::err_incomplete_in_exception_spec;
129 bool ReturnValueOnError = true;
130 if (getLangOpts().MicrosoftExt) {
131 DiagID = diag::ext_incomplete_in_exception_spec;
132 ReturnValueOnError = false;
134 if (!(PointeeT->isRecordType() &&
135 PointeeT->getAs<RecordType>()->isBeingDefined()) &&
136 RequireCompleteType(Range.getBegin(), PointeeT, DiagID, Kind, Range))
137 return ReturnValueOnError;
142 /// CheckDistantExceptionSpec - Check if the given type is a pointer or pointer
143 /// to member to a function with an exception specification. This means that
144 /// it is invalid to add another level of indirection.
145 bool Sema::CheckDistantExceptionSpec(QualType T) {
146 // C++17 removes this rule in favor of putting exception specifications into
148 if (getLangOpts().CPlusPlus17)
151 if (const PointerType *PT = T->getAs<PointerType>())
152 T = PT->getPointeeType();
153 else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
154 T = PT->getPointeeType();
158 const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
162 return FnT->hasExceptionSpec();
165 const FunctionProtoType *
166 Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) {
167 if (FPT->getExceptionSpecType() == EST_Unparsed) {
168 Diag(Loc, diag::err_exception_spec_not_parsed);
172 if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
175 FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl();
176 const FunctionProtoType *SourceFPT =
177 SourceDecl->getType()->castAs<FunctionProtoType>();
179 // If the exception specification has already been resolved, just return it.
180 if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType()))
183 // Compute or instantiate the exception specification now.
184 if (SourceFPT->getExceptionSpecType() == EST_Unevaluated)
185 EvaluateImplicitExceptionSpec(Loc, cast<CXXMethodDecl>(SourceDecl));
187 InstantiateExceptionSpec(Loc, SourceDecl);
189 const FunctionProtoType *Proto =
190 SourceDecl->getType()->castAs<FunctionProtoType>();
191 if (Proto->getExceptionSpecType() == clang::EST_Unparsed) {
192 Diag(Loc, diag::err_exception_spec_not_parsed);
199 Sema::UpdateExceptionSpec(FunctionDecl *FD,
200 const FunctionProtoType::ExceptionSpecInfo &ESI) {
201 // If we've fully resolved the exception specification, notify listeners.
202 if (!isUnresolvedExceptionSpec(ESI.Type))
203 if (auto *Listener = getASTMutationListener())
204 Listener->ResolvedExceptionSpec(FD);
206 for (auto *Redecl : FD->redecls())
207 Context.adjustExceptionSpec(cast<FunctionDecl>(Redecl), ESI);
210 static bool CheckEquivalentExceptionSpecImpl(
211 Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID,
212 const FunctionProtoType *Old, SourceLocation OldLoc,
213 const FunctionProtoType *New, SourceLocation NewLoc,
214 bool *MissingExceptionSpecification = nullptr,
215 bool *MissingEmptyExceptionSpecification = nullptr,
216 bool AllowNoexceptAllMatchWithNoSpec = false, bool IsOperatorNew = false);
218 /// Determine whether a function has an implicitly-generated exception
220 static bool hasImplicitExceptionSpec(FunctionDecl *Decl) {
221 if (!isa<CXXDestructorDecl>(Decl) &&
222 Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete &&
223 Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
226 // For a function that the user didn't declare:
227 // - if this is a destructor, its exception specification is implicit.
228 // - if this is 'operator delete' or 'operator delete[]', the exception
229 // specification is as-if an explicit exception specification was given
230 // (per [basic.stc.dynamic]p2).
231 if (!Decl->getTypeSourceInfo())
232 return isa<CXXDestructorDecl>(Decl);
234 const FunctionProtoType *Ty =
235 Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>();
236 return !Ty->hasExceptionSpec();
239 bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
240 // Just completely ignore this under -fno-exceptions prior to C++17.
241 // In C++17 onwards, the exception specification is part of the type and
242 // we will diagnose mismatches anyway, so it's better to check for them here.
243 if (!getLangOpts().CXXExceptions && !getLangOpts().CPlusPlus17)
246 OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator();
247 bool IsOperatorNew = OO == OO_New || OO == OO_Array_New;
248 bool MissingExceptionSpecification = false;
249 bool MissingEmptyExceptionSpecification = false;
251 unsigned DiagID = diag::err_mismatched_exception_spec;
252 bool ReturnValueOnError = true;
253 if (getLangOpts().MicrosoftExt) {
254 DiagID = diag::ext_mismatched_exception_spec;
255 ReturnValueOnError = false;
258 // Check the types as written: they must match before any exception
259 // specification adjustment is applied.
260 if (!CheckEquivalentExceptionSpecImpl(
261 *this, PDiag(DiagID), PDiag(diag::note_previous_declaration),
262 Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(),
263 New->getType()->getAs<FunctionProtoType>(), New->getLocation(),
264 &MissingExceptionSpecification, &MissingEmptyExceptionSpecification,
265 /*AllowNoexceptAllMatchWithNoSpec=*/true, IsOperatorNew)) {
266 // C++11 [except.spec]p4 [DR1492]:
267 // If a declaration of a function has an implicit
268 // exception-specification, other declarations of the function shall
269 // not specify an exception-specification.
270 if (getLangOpts().CPlusPlus11 && getLangOpts().CXXExceptions &&
271 hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) {
272 Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch)
273 << hasImplicitExceptionSpec(Old);
274 if (Old->getLocation().isValid())
275 Diag(Old->getLocation(), diag::note_previous_declaration);
280 // The failure was something other than an missing exception
281 // specification; return an error, except in MS mode where this is a warning.
282 if (!MissingExceptionSpecification)
283 return ReturnValueOnError;
285 const FunctionProtoType *NewProto =
286 New->getType()->castAs<FunctionProtoType>();
288 // The new function declaration is only missing an empty exception
289 // specification "throw()". If the throw() specification came from a
290 // function in a system header that has C linkage, just add an empty
291 // exception specification to the "new" declaration. Note that C library
292 // implementations are permitted to add these nothrow exception
295 // Likewise if the old function is a builtin.
296 if (MissingEmptyExceptionSpecification && NewProto &&
297 (Old->getLocation().isInvalid() ||
298 Context.getSourceManager().isInSystemHeader(Old->getLocation()) ||
299 Old->getBuiltinID()) &&
301 New->setType(Context.getFunctionType(
302 NewProto->getReturnType(), NewProto->getParamTypes(),
303 NewProto->getExtProtoInfo().withExceptionSpec(EST_DynamicNone)));
307 const FunctionProtoType *OldProto =
308 Old->getType()->castAs<FunctionProtoType>();
310 FunctionProtoType::ExceptionSpecInfo ESI = OldProto->getExceptionSpecType();
311 if (ESI.Type == EST_Dynamic) {
312 ESI.Exceptions = OldProto->exceptions();
315 if (ESI.Type == EST_ComputedNoexcept) {
316 // For computed noexcept, we can't just take the expression from the old
317 // prototype. It likely contains references to the old prototype's
319 New->setInvalidDecl();
321 // Update the type of the function with the appropriate exception
323 New->setType(Context.getFunctionType(
324 NewProto->getReturnType(), NewProto->getParamTypes(),
325 NewProto->getExtProtoInfo().withExceptionSpec(ESI)));
328 if (getLangOpts().MicrosoftExt && ESI.Type != EST_ComputedNoexcept) {
329 // Allow missing exception specifications in redeclarations as an extension.
330 DiagID = diag::ext_ms_missing_exception_specification;
331 ReturnValueOnError = false;
332 } else if (New->isReplaceableGlobalAllocationFunction() &&
333 ESI.Type != EST_ComputedNoexcept) {
334 // Allow missing exception specifications in redeclarations as an extension,
335 // when declaring a replaceable global allocation function.
336 DiagID = diag::ext_missing_exception_specification;
337 ReturnValueOnError = false;
339 DiagID = diag::err_missing_exception_specification;
340 ReturnValueOnError = true;
343 // Warn about the lack of exception specification.
344 SmallString<128> ExceptionSpecString;
345 llvm::raw_svector_ostream OS(ExceptionSpecString);
346 switch (OldProto->getExceptionSpecType()) {
347 case EST_DynamicNone:
353 bool OnFirstException = true;
354 for (const auto &E : OldProto->exceptions()) {
355 if (OnFirstException)
356 OnFirstException = false;
360 OS << E.getAsString(getPrintingPolicy());
366 case EST_BasicNoexcept:
370 case EST_ComputedNoexcept:
372 assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr");
373 OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy());
378 llvm_unreachable("This spec type is compatible with none.");
381 SourceLocation FixItLoc;
382 if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) {
383 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
384 // FIXME: Preserve enough information so that we can produce a correct fixit
385 // location when there is a trailing return type.
386 if (auto FTLoc = TL.getAs<FunctionProtoTypeLoc>())
387 if (!FTLoc.getTypePtr()->hasTrailingReturn())
388 FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd());
391 if (FixItLoc.isInvalid())
392 Diag(New->getLocation(), DiagID)
395 Diag(New->getLocation(), DiagID)
397 << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str());
400 if (Old->getLocation().isValid())
401 Diag(Old->getLocation(), diag::note_previous_declaration);
403 return ReturnValueOnError;
406 /// CheckEquivalentExceptionSpec - Check if the two types have equivalent
407 /// exception specifications. Exception specifications are equivalent if
408 /// they allow exactly the same set of exception types. It does not matter how
409 /// that is achieved. See C++ [except.spec]p2.
410 bool Sema::CheckEquivalentExceptionSpec(
411 const FunctionProtoType *Old, SourceLocation OldLoc,
412 const FunctionProtoType *New, SourceLocation NewLoc) {
413 if (!getLangOpts().CXXExceptions)
416 unsigned DiagID = diag::err_mismatched_exception_spec;
417 if (getLangOpts().MicrosoftExt)
418 DiagID = diag::ext_mismatched_exception_spec;
419 bool Result = CheckEquivalentExceptionSpecImpl(
420 *this, PDiag(DiagID), PDiag(diag::note_previous_declaration),
421 Old, OldLoc, New, NewLoc);
423 // In Microsoft mode, mismatching exception specifications just cause a warning.
424 if (getLangOpts().MicrosoftExt)
429 /// CheckEquivalentExceptionSpec - Check if the two types have compatible
430 /// exception specifications. See C++ [except.spec]p3.
432 /// \return \c false if the exception specifications match, \c true if there is
433 /// a problem. If \c true is returned, either a diagnostic has already been
434 /// produced or \c *MissingExceptionSpecification is set to \c true.
435 static bool CheckEquivalentExceptionSpecImpl(
436 Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID,
437 const FunctionProtoType *Old, SourceLocation OldLoc,
438 const FunctionProtoType *New, SourceLocation NewLoc,
439 bool *MissingExceptionSpecification,
440 bool *MissingEmptyExceptionSpecification,
441 bool AllowNoexceptAllMatchWithNoSpec, bool IsOperatorNew) {
442 if (MissingExceptionSpecification)
443 *MissingExceptionSpecification = false;
445 if (MissingEmptyExceptionSpecification)
446 *MissingEmptyExceptionSpecification = false;
448 Old = S.ResolveExceptionSpec(NewLoc, Old);
451 New = S.ResolveExceptionSpec(NewLoc, New);
455 // C++0x [except.spec]p3: Two exception-specifications are compatible if:
456 // - both are non-throwing, regardless of their form,
457 // - both have the form noexcept(constant-expression) and the constant-
458 // expressions are equivalent,
459 // - both are dynamic-exception-specifications that have the same set of
462 // C++0x [except.spec]p12: An exception-specification is non-throwing if it is
463 // of the form throw(), noexcept, or noexcept(constant-expression) where the
464 // constant-expression yields true.
466 // C++0x [except.spec]p4: If any declaration of a function has an exception-
467 // specifier that is not a noexcept-specification allowing all exceptions,
468 // all declarations [...] of that function shall have a compatible
469 // exception-specification.
471 // That last point basically means that noexcept(false) matches no spec.
472 // It's considered when AllowNoexceptAllMatchWithNoSpec is true.
474 ExceptionSpecificationType OldEST = Old->getExceptionSpecType();
475 ExceptionSpecificationType NewEST = New->getExceptionSpecType();
477 assert(!isUnresolvedExceptionSpec(OldEST) &&
478 !isUnresolvedExceptionSpec(NewEST) &&
479 "Shouldn't see unknown exception specifications here");
481 // Shortcut the case where both have no spec.
482 if (OldEST == EST_None && NewEST == EST_None)
485 FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(S.Context);
486 FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(S.Context);
487 if (OldNR == FunctionProtoType::NR_BadNoexcept ||
488 NewNR == FunctionProtoType::NR_BadNoexcept)
491 // Dependent noexcept specifiers are compatible with each other, but nothing
493 // One noexcept is compatible with another if the argument is the same
494 if (OldNR == NewNR &&
495 OldNR != FunctionProtoType::NR_NoNoexcept &&
496 NewNR != FunctionProtoType::NR_NoNoexcept)
498 if (OldNR != NewNR &&
499 OldNR != FunctionProtoType::NR_NoNoexcept &&
500 NewNR != FunctionProtoType::NR_NoNoexcept) {
501 S.Diag(NewLoc, DiagID);
502 if (NoteID.getDiagID() != 0 && OldLoc.isValid())
503 S.Diag(OldLoc, NoteID);
507 // The MS extension throw(...) is compatible with itself.
508 if (OldEST == EST_MSAny && NewEST == EST_MSAny)
511 // It's also compatible with no spec.
512 if ((OldEST == EST_None && NewEST == EST_MSAny) ||
513 (OldEST == EST_MSAny && NewEST == EST_None))
516 // It's also compatible with noexcept(false).
517 if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw)
519 if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw)
522 // As described above, noexcept(false) matches no spec only for functions.
523 if (AllowNoexceptAllMatchWithNoSpec) {
524 if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw)
526 if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw)
530 // Any non-throwing specifications are compatible.
531 bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow ||
532 OldEST == EST_DynamicNone;
533 bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow ||
534 NewEST == EST_DynamicNone;
535 if (OldNonThrowing && NewNonThrowing)
538 // As a special compatibility feature, under C++0x we accept no spec and
539 // throw(std::bad_alloc) as equivalent for operator new and operator new[].
540 // This is because the implicit declaration changed, but old code would break.
541 if (S.getLangOpts().CPlusPlus11 && IsOperatorNew) {
542 const FunctionProtoType *WithExceptions = nullptr;
543 if (OldEST == EST_None && NewEST == EST_Dynamic)
544 WithExceptions = New;
545 else if (OldEST == EST_Dynamic && NewEST == EST_None)
546 WithExceptions = Old;
547 if (WithExceptions && WithExceptions->getNumExceptions() == 1) {
548 // One has no spec, the other throw(something). If that something is
549 // std::bad_alloc, all conditions are met.
550 QualType Exception = *WithExceptions->exception_begin();
551 if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) {
552 IdentifierInfo* Name = ExRecord->getIdentifier();
553 if (Name && Name->getName() == "bad_alloc") {
554 // It's called bad_alloc, but is it in std?
555 if (ExRecord->isInStdNamespace()) {
563 // At this point, the only remaining valid case is two matching dynamic
564 // specifications. We return here unless both specifications are dynamic.
565 if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) {
566 if (MissingExceptionSpecification && Old->hasExceptionSpec() &&
567 !New->hasExceptionSpec()) {
568 // The old type has an exception specification of some sort, but
569 // the new type does not.
570 *MissingExceptionSpecification = true;
572 if (MissingEmptyExceptionSpecification && OldNonThrowing) {
573 // The old type has a throw() or noexcept(true) exception specification
574 // and the new type has no exception specification, and the caller asked
575 // to handle this itself.
576 *MissingEmptyExceptionSpecification = true;
582 S.Diag(NewLoc, DiagID);
583 if (NoteID.getDiagID() != 0 && OldLoc.isValid())
584 S.Diag(OldLoc, NoteID);
588 assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic &&
589 "Exception compatibility logic error: non-dynamic spec slipped through.");
592 // Both have a dynamic exception spec. Collect the first set, then compare
594 llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
595 for (const auto &I : Old->exceptions())
596 OldTypes.insert(S.Context.getCanonicalType(I).getUnqualifiedType());
598 for (const auto &I : New->exceptions()) {
599 CanQualType TypePtr = S.Context.getCanonicalType(I).getUnqualifiedType();
600 if (OldTypes.count(TypePtr))
601 NewTypes.insert(TypePtr);
606 Success = Success && OldTypes.size() == NewTypes.size();
611 S.Diag(NewLoc, DiagID);
612 if (NoteID.getDiagID() != 0 && OldLoc.isValid())
613 S.Diag(OldLoc, NoteID);
617 bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID,
618 const PartialDiagnostic &NoteID,
619 const FunctionProtoType *Old,
620 SourceLocation OldLoc,
621 const FunctionProtoType *New,
622 SourceLocation NewLoc) {
623 if (!getLangOpts().CXXExceptions)
625 return CheckEquivalentExceptionSpecImpl(*this, DiagID, NoteID, Old, OldLoc,
629 /// CheckExceptionSpecSubset - Check whether the second function type's
630 /// exception specification is a subset (or equivalent) of the first function
631 /// type. This is used by override and pointer assignment checks.
632 bool Sema::CheckExceptionSpecSubset(const PartialDiagnostic &DiagID,
633 const PartialDiagnostic &NestedDiagID,
634 const PartialDiagnostic &NoteID,
635 const FunctionProtoType *Superset,
636 SourceLocation SuperLoc,
637 const FunctionProtoType *Subset,
638 SourceLocation SubLoc) {
640 // Just auto-succeed under -fno-exceptions.
641 if (!getLangOpts().CXXExceptions)
644 // FIXME: As usual, we could be more specific in our error messages, but
645 // that better waits until we've got types with source locations.
647 if (!SubLoc.isValid())
650 // Resolve the exception specifications, if needed.
651 Superset = ResolveExceptionSpec(SuperLoc, Superset);
654 Subset = ResolveExceptionSpec(SubLoc, Subset);
658 ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType();
660 // If superset contains everything, we're done.
661 if (SuperEST == EST_None || SuperEST == EST_MSAny)
662 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
665 // If there are dependent noexcept specs, assume everything is fine. Unlike
666 // with the equivalency check, this is safe in this case, because we don't
667 // want to merge declarations. Checks after instantiation will catch any
668 // omissions we make here.
669 // We also shortcut checking if a noexcept expression was bad.
671 FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context);
672 if (SuperNR == FunctionProtoType::NR_BadNoexcept ||
673 SuperNR == FunctionProtoType::NR_Dependent)
676 // Another case of the superset containing everything.
677 if (SuperNR == FunctionProtoType::NR_Throw)
678 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
681 ExceptionSpecificationType SubEST = Subset->getExceptionSpecType();
683 assert(!isUnresolvedExceptionSpec(SuperEST) &&
684 !isUnresolvedExceptionSpec(SubEST) &&
685 "Shouldn't see unknown exception specifications here");
687 // It does not. If the subset contains everything, we've failed.
688 if (SubEST == EST_None || SubEST == EST_MSAny) {
689 Diag(SubLoc, DiagID);
690 if (NoteID.getDiagID() != 0)
691 Diag(SuperLoc, NoteID);
695 FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context);
696 if (SubNR == FunctionProtoType::NR_BadNoexcept ||
697 SubNR == FunctionProtoType::NR_Dependent)
700 // Another case of the subset containing everything.
701 if (SubNR == FunctionProtoType::NR_Throw) {
702 Diag(SubLoc, DiagID);
703 if (NoteID.getDiagID() != 0)
704 Diag(SuperLoc, NoteID);
708 // If the subset contains nothing, we're done.
709 if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow)
710 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
713 // Otherwise, if the superset contains nothing, we've failed.
714 if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) {
715 Diag(SubLoc, DiagID);
716 if (NoteID.getDiagID() != 0)
717 Diag(SuperLoc, NoteID);
721 assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic &&
722 "Exception spec subset: non-dynamic case slipped through.");
724 // Neither contains everything or nothing. Do a proper comparison.
725 for (const auto &SubI : Subset->exceptions()) {
726 // Take one type from the subset.
727 QualType CanonicalSubT = Context.getCanonicalType(SubI);
728 // Unwrap pointers and references so that we can do checks within a class
729 // hierarchy. Don't unwrap member pointers; they don't have hierarchy
730 // conversions on the pointee.
731 bool SubIsPointer = false;
732 if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>())
733 CanonicalSubT = RefTy->getPointeeType();
734 if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) {
735 CanonicalSubT = PtrTy->getPointeeType();
738 bool SubIsClass = CanonicalSubT->isRecordType();
739 CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
741 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
742 /*DetectVirtual=*/false);
744 bool Contained = false;
745 // Make sure it's in the superset.
746 for (const auto &SuperI : Superset->exceptions()) {
747 QualType CanonicalSuperT = Context.getCanonicalType(SuperI);
748 // SubT must be SuperT or derived from it, or pointer or reference to
750 if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>())
751 CanonicalSuperT = RefTy->getPointeeType();
753 if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>())
754 CanonicalSuperT = PtrTy->getPointeeType();
759 CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType();
760 // If the types are the same, move on to the next type in the subset.
761 if (CanonicalSubT == CanonicalSuperT) {
766 // Otherwise we need to check the inheritance.
767 if (!SubIsClass || !CanonicalSuperT->isRecordType())
771 if (!IsDerivedFrom(SubLoc, CanonicalSubT, CanonicalSuperT, Paths))
774 if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT)))
777 // Do this check from a context without privileges.
778 switch (CheckBaseClassAccess(SourceLocation(),
779 CanonicalSuperT, CanonicalSubT,
783 /*ForceUnprivileged*/ true)) {
784 case AR_accessible: break;
785 case AR_inaccessible: continue;
787 llvm_unreachable("access check dependent for unprivileged context");
789 llvm_unreachable("access check delayed in non-declaration");
796 Diag(SubLoc, DiagID);
797 if (NoteID.getDiagID() != 0)
798 Diag(SuperLoc, NoteID);
802 // We've run half the gauntlet.
803 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
808 CheckSpecForTypesEquivalent(Sema &S, const PartialDiagnostic &DiagID,
809 const PartialDiagnostic &NoteID, QualType Target,
810 SourceLocation TargetLoc, QualType Source,
811 SourceLocation SourceLoc) {
812 const FunctionProtoType *TFunc = GetUnderlyingFunction(Target);
815 const FunctionProtoType *SFunc = GetUnderlyingFunction(Source);
819 return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc,
823 /// CheckParamExceptionSpec - Check if the parameter and return types of the
824 /// two functions have equivalent exception specs. This is part of the
825 /// assignment and override compatibility check. We do not check the parameters
826 /// of parameter function pointers recursively, as no sane programmer would
827 /// even be able to write such a function type.
828 bool Sema::CheckParamExceptionSpec(const PartialDiagnostic &DiagID,
829 const PartialDiagnostic &NoteID,
830 const FunctionProtoType *Target,
831 SourceLocation TargetLoc,
832 const FunctionProtoType *Source,
833 SourceLocation SourceLoc) {
834 auto RetDiag = DiagID;
836 if (CheckSpecForTypesEquivalent(
837 *this, RetDiag, PDiag(),
838 Target->getReturnType(), TargetLoc, Source->getReturnType(),
842 // We shouldn't even be testing this unless the arguments are otherwise
844 assert(Target->getNumParams() == Source->getNumParams() &&
845 "Functions have different argument counts.");
846 for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) {
847 auto ParamDiag = DiagID;
849 if (CheckSpecForTypesEquivalent(
850 *this, ParamDiag, PDiag(),
851 Target->getParamType(i), TargetLoc, Source->getParamType(i),
858 bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) {
859 // First we check for applicability.
860 // Target type must be a function, function pointer or function reference.
861 const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
862 if (!ToFunc || ToFunc->hasDependentExceptionSpec())
865 // SourceType must be a function or function pointer.
866 const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
867 if (!FromFunc || FromFunc->hasDependentExceptionSpec())
870 unsigned DiagID = diag::err_incompatible_exception_specs;
871 unsigned NestedDiagID = diag::err_deep_exception_specs_differ;
872 // This is not an error in C++17 onwards, unless the noexceptness doesn't
873 // match, but in that case we have a full-on type mismatch, not just a
874 // type sugar mismatch.
875 if (getLangOpts().CPlusPlus17) {
876 DiagID = diag::warn_incompatible_exception_specs;
877 NestedDiagID = diag::warn_deep_exception_specs_differ;
880 // Now we've got the correct types on both sides, check their compatibility.
881 // This means that the source of the conversion can only throw a subset of
882 // the exceptions of the target, and any exception specs on arguments or
883 // return types must be equivalent.
885 // FIXME: If there is a nested dependent exception specification, we should
886 // not be checking it here. This is fine:
887 // template<typename T> void f() {
888 // void (*p)(void (*) throw(T));
889 // void (*q)(void (*) throw(int)) = p;
891 // ... because it might be instantiated with T=int.
892 return CheckExceptionSpecSubset(PDiag(DiagID), PDiag(NestedDiagID), PDiag(),
893 ToFunc, From->getSourceRange().getBegin(),
894 FromFunc, SourceLocation()) &&
895 !getLangOpts().CPlusPlus17;
898 bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
899 const CXXMethodDecl *Old) {
900 // If the new exception specification hasn't been parsed yet, skip the check.
901 // We'll get called again once it's been parsed.
902 if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() ==
905 if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) {
906 // Don't check uninstantiated template destructors at all. We can only
907 // synthesize correct specs after the template is instantiated.
908 if (New->getParent()->isDependentType())
910 if (New->getParent()->isBeingDefined()) {
911 // The destructor might be updated once the definition is finished. So
912 // remember it and check later.
913 DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old));
917 // If the old exception specification hasn't been parsed yet, remember that
918 // we need to perform this check when we get to the end of the outermost
919 // lexically-surrounding class.
920 if (Old->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() ==
922 DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old));
925 unsigned DiagID = diag::err_override_exception_spec;
926 if (getLangOpts().MicrosoftExt)
927 DiagID = diag::ext_override_exception_spec;
928 return CheckExceptionSpecSubset(PDiag(DiagID),
929 PDiag(diag::err_deep_exception_specs_differ),
930 PDiag(diag::note_overridden_virtual_function),
931 Old->getType()->getAs<FunctionProtoType>(),
933 New->getType()->getAs<FunctionProtoType>(),
937 static CanThrowResult canSubExprsThrow(Sema &S, const Expr *E) {
938 CanThrowResult R = CT_Cannot;
939 for (const Stmt *SubStmt : E->children()) {
940 R = mergeCanThrow(R, S.canThrow(cast<Expr>(SubStmt)));
947 static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D) {
948 // As an extension, we assume that __attribute__((nothrow)) functions don't
950 if (D && isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>())
955 // In C++1z, just look at the function type of the callee.
956 if (S.getLangOpts().CPlusPlus17 && isa<CallExpr>(E)) {
957 E = cast<CallExpr>(E)->getCallee();
959 if (T->isSpecificPlaceholderType(BuiltinType::BoundMember)) {
960 // Sadly we don't preserve the actual type as part of the "bound member"
961 // placeholder, so we need to reconstruct it.
962 E = E->IgnoreParenImpCasts();
964 // Could be a call to a pointer-to-member or a plain member access.
965 if (auto *Op = dyn_cast<BinaryOperator>(E)) {
966 assert(Op->getOpcode() == BO_PtrMemD || Op->getOpcode() == BO_PtrMemI);
967 T = Op->getRHS()->getType()
968 ->castAs<MemberPointerType>()->getPointeeType();
970 T = cast<MemberExpr>(E)->getMemberDecl()->getType();
973 } else if (const ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D))
976 // If we have no clue what we're calling, assume the worst.
979 const FunctionProtoType *FT;
980 if ((FT = T->getAs<FunctionProtoType>())) {
981 } else if (const PointerType *PT = T->getAs<PointerType>())
982 FT = PT->getPointeeType()->getAs<FunctionProtoType>();
983 else if (const ReferenceType *RT = T->getAs<ReferenceType>())
984 FT = RT->getPointeeType()->getAs<FunctionProtoType>();
985 else if (const MemberPointerType *MT = T->getAs<MemberPointerType>())
986 FT = MT->getPointeeType()->getAs<FunctionProtoType>();
987 else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
988 FT = BT->getPointeeType()->getAs<FunctionProtoType>();
993 FT = S.ResolveExceptionSpec(E->getLocStart(), FT);
997 return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can;
1000 static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) {
1001 if (DC->isTypeDependent())
1002 return CT_Dependent;
1004 if (!DC->getTypeAsWritten()->isReferenceType())
1007 if (DC->getSubExpr()->isTypeDependent())
1008 return CT_Dependent;
1010 return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot;
1013 static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) {
1014 if (DC->isTypeOperand())
1017 Expr *Op = DC->getExprOperand();
1018 if (Op->isTypeDependent())
1019 return CT_Dependent;
1021 const RecordType *RT = Op->getType()->getAs<RecordType>();
1025 if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic())
1028 if (Op->Classify(S.Context).isPRValue())
1034 CanThrowResult Sema::canThrow(const Expr *E) {
1035 // C++ [expr.unary.noexcept]p3:
1036 // [Can throw] if in a potentially-evaluated context the expression would
1038 switch (E->getStmtClass()) {
1039 case Expr::CXXThrowExprClass:
1040 // - a potentially evaluated throw-expression
1043 case Expr::CXXDynamicCastExprClass: {
1044 // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
1045 // where T is a reference type, that requires a run-time check
1046 CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E));
1049 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1052 case Expr::CXXTypeidExprClass:
1053 // - a potentially evaluated typeid expression applied to a glvalue
1054 // expression whose type is a polymorphic class type
1055 return canTypeidThrow(*this, cast<CXXTypeidExpr>(E));
1057 // - a potentially evaluated call to a function, member function, function
1058 // pointer, or member function pointer that does not have a non-throwing
1059 // exception-specification
1060 case Expr::CallExprClass:
1061 case Expr::CXXMemberCallExprClass:
1062 case Expr::CXXOperatorCallExprClass:
1063 case Expr::UserDefinedLiteralClass: {
1064 const CallExpr *CE = cast<CallExpr>(E);
1066 if (E->isTypeDependent())
1068 else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens()))
1071 CT = canCalleeThrow(*this, E, CE->getCalleeDecl());
1074 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1077 case Expr::CXXConstructExprClass:
1078 case Expr::CXXTemporaryObjectExprClass: {
1079 CanThrowResult CT = canCalleeThrow(*this, E,
1080 cast<CXXConstructExpr>(E)->getConstructor());
1083 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1086 case Expr::CXXInheritedCtorInitExprClass:
1087 return canCalleeThrow(*this, E,
1088 cast<CXXInheritedCtorInitExpr>(E)->getConstructor());
1090 case Expr::LambdaExprClass: {
1091 const LambdaExpr *Lambda = cast<LambdaExpr>(E);
1092 CanThrowResult CT = CT_Cannot;
1093 for (LambdaExpr::const_capture_init_iterator
1094 Cap = Lambda->capture_init_begin(),
1095 CapEnd = Lambda->capture_init_end();
1096 Cap != CapEnd; ++Cap)
1097 CT = mergeCanThrow(CT, canThrow(*Cap));
1101 case Expr::CXXNewExprClass: {
1103 if (E->isTypeDependent())
1106 CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew());
1109 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1112 case Expr::CXXDeleteExprClass: {
1114 QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType();
1115 if (DTy.isNull() || DTy->isDependentType()) {
1118 CT = canCalleeThrow(*this, E,
1119 cast<CXXDeleteExpr>(E)->getOperatorDelete());
1120 if (const RecordType *RT = DTy->getAs<RecordType>()) {
1121 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
1122 const CXXDestructorDecl *DD = RD->getDestructor();
1124 CT = mergeCanThrow(CT, canCalleeThrow(*this, E, DD));
1129 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1132 case Expr::CXXBindTemporaryExprClass: {
1133 // The bound temporary has to be destroyed again, which might throw.
1134 CanThrowResult CT = canCalleeThrow(*this, E,
1135 cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor());
1138 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1141 // ObjC message sends are like function calls, but never have exception
1143 case Expr::ObjCMessageExprClass:
1144 case Expr::ObjCPropertyRefExprClass:
1145 case Expr::ObjCSubscriptRefExprClass:
1148 // All the ObjC literals that are implemented as calls are
1149 // potentially throwing unless we decide to close off that
1151 case Expr::ObjCArrayLiteralClass:
1152 case Expr::ObjCDictionaryLiteralClass:
1153 case Expr::ObjCBoxedExprClass:
1156 // Many other things have subexpressions, so we have to test those.
1158 case Expr::CoawaitExprClass:
1159 case Expr::ConditionalOperatorClass:
1160 case Expr::CompoundLiteralExprClass:
1161 case Expr::CoyieldExprClass:
1162 case Expr::CXXConstCastExprClass:
1163 case Expr::CXXReinterpretCastExprClass:
1164 case Expr::CXXStdInitializerListExprClass:
1165 case Expr::DesignatedInitExprClass:
1166 case Expr::DesignatedInitUpdateExprClass:
1167 case Expr::ExprWithCleanupsClass:
1168 case Expr::ExtVectorElementExprClass:
1169 case Expr::InitListExprClass:
1170 case Expr::ArrayInitLoopExprClass:
1171 case Expr::MemberExprClass:
1172 case Expr::ObjCIsaExprClass:
1173 case Expr::ObjCIvarRefExprClass:
1174 case Expr::ParenExprClass:
1175 case Expr::ParenListExprClass:
1176 case Expr::ShuffleVectorExprClass:
1177 case Expr::ConvertVectorExprClass:
1178 case Expr::VAArgExprClass:
1179 return canSubExprsThrow(*this, E);
1181 // Some might be dependent for other reasons.
1182 case Expr::ArraySubscriptExprClass:
1183 case Expr::OMPArraySectionExprClass:
1184 case Expr::BinaryOperatorClass:
1185 case Expr::DependentCoawaitExprClass:
1186 case Expr::CompoundAssignOperatorClass:
1187 case Expr::CStyleCastExprClass:
1188 case Expr::CXXStaticCastExprClass:
1189 case Expr::CXXFunctionalCastExprClass:
1190 case Expr::ImplicitCastExprClass:
1191 case Expr::MaterializeTemporaryExprClass:
1192 case Expr::UnaryOperatorClass: {
1193 CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot;
1194 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1197 // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms.
1198 case Expr::StmtExprClass:
1201 case Expr::CXXDefaultArgExprClass:
1202 return canThrow(cast<CXXDefaultArgExpr>(E)->getExpr());
1204 case Expr::CXXDefaultInitExprClass:
1205 return canThrow(cast<CXXDefaultInitExpr>(E)->getExpr());
1207 case Expr::ChooseExprClass:
1208 if (E->isTypeDependent() || E->isValueDependent())
1209 return CT_Dependent;
1210 return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr());
1212 case Expr::GenericSelectionExprClass:
1213 if (cast<GenericSelectionExpr>(E)->isResultDependent())
1214 return CT_Dependent;
1215 return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr());
1217 // Some expressions are always dependent.
1218 case Expr::CXXDependentScopeMemberExprClass:
1219 case Expr::CXXUnresolvedConstructExprClass:
1220 case Expr::DependentScopeDeclRefExprClass:
1221 case Expr::CXXFoldExprClass:
1222 return CT_Dependent;
1224 case Expr::AsTypeExprClass:
1225 case Expr::BinaryConditionalOperatorClass:
1226 case Expr::BlockExprClass:
1227 case Expr::CUDAKernelCallExprClass:
1228 case Expr::DeclRefExprClass:
1229 case Expr::ObjCBridgedCastExprClass:
1230 case Expr::ObjCIndirectCopyRestoreExprClass:
1231 case Expr::ObjCProtocolExprClass:
1232 case Expr::ObjCSelectorExprClass:
1233 case Expr::ObjCAvailabilityCheckExprClass:
1234 case Expr::OffsetOfExprClass:
1235 case Expr::PackExpansionExprClass:
1236 case Expr::PseudoObjectExprClass:
1237 case Expr::SubstNonTypeTemplateParmExprClass:
1238 case Expr::SubstNonTypeTemplateParmPackExprClass:
1239 case Expr::FunctionParmPackExprClass:
1240 case Expr::UnaryExprOrTypeTraitExprClass:
1241 case Expr::UnresolvedLookupExprClass:
1242 case Expr::UnresolvedMemberExprClass:
1243 case Expr::TypoExprClass:
1244 // FIXME: Can any of the above throw? If so, when?
1247 case Expr::AddrLabelExprClass:
1248 case Expr::ArrayTypeTraitExprClass:
1249 case Expr::AtomicExprClass:
1250 case Expr::TypeTraitExprClass:
1251 case Expr::CXXBoolLiteralExprClass:
1252 case Expr::CXXNoexceptExprClass:
1253 case Expr::CXXNullPtrLiteralExprClass:
1254 case Expr::CXXPseudoDestructorExprClass:
1255 case Expr::CXXScalarValueInitExprClass:
1256 case Expr::CXXThisExprClass:
1257 case Expr::CXXUuidofExprClass:
1258 case Expr::CharacterLiteralClass:
1259 case Expr::ExpressionTraitExprClass:
1260 case Expr::FloatingLiteralClass:
1261 case Expr::GNUNullExprClass:
1262 case Expr::ImaginaryLiteralClass:
1263 case Expr::ImplicitValueInitExprClass:
1264 case Expr::IntegerLiteralClass:
1265 case Expr::ArrayInitIndexExprClass:
1266 case Expr::NoInitExprClass:
1267 case Expr::ObjCEncodeExprClass:
1268 case Expr::ObjCStringLiteralClass:
1269 case Expr::ObjCBoolLiteralExprClass:
1270 case Expr::OpaqueValueExprClass:
1271 case Expr::PredefinedExprClass:
1272 case Expr::SizeOfPackExprClass:
1273 case Expr::StringLiteralClass:
1274 // These expressions can never throw.
1277 case Expr::MSPropertyRefExprClass:
1278 case Expr::MSPropertySubscriptExprClass:
1279 llvm_unreachable("Invalid class for expression");
1281 #define STMT(CLASS, PARENT) case Expr::CLASS##Class:
1282 #define STMT_RANGE(Base, First, Last)
1283 #define LAST_STMT_RANGE(BASE, FIRST, LAST)
1284 #define EXPR(CLASS, PARENT)
1285 #define ABSTRACT_STMT(STMT)
1286 #include "clang/AST/StmtNodes.inc"
1287 case Expr::NoStmtClass:
1288 llvm_unreachable("Invalid class for expression");
1290 llvm_unreachable("Bogus StmtClass");
1293 } // end namespace clang