22 #include "llvm/ADT/SmallPtrSet.h"
23 #include "llvm/ADT/SmallString.h"
56 return llvm::StringSwitch<bool>(RD->getIdentifier()->getName())
59 .Case(
"priority_queue",
true)
97 if (RT->isRValueReferenceType()) {
101 Diag(Range.
getBegin(), diag::err_rref_in_exception_spec)
116 diag::err_incomplete_in_exception_spec,
Kind, Range))
143 Diag(Loc, diag::err_exception_spec_not_parsed);
167 Diag(Loc, diag::err_exception_spec_not_parsed);
179 Listener->ResolvedExceptionSpec(FD);
181 for (
auto *Redecl : FD->
redecls())
188 if (!isa<CXXDestructorDecl>(Decl) &&
199 return isa<CXXDestructorDecl>(Decl);
208 bool IsOperatorNew = OO == OO_New || OO == OO_Array_New;
209 bool MissingExceptionSpecification =
false;
210 bool MissingEmptyExceptionSpecification =
false;
212 unsigned DiagID = diag::err_mismatched_exception_spec;
213 bool ReturnValueOnError =
true;
215 DiagID = diag::ext_mismatched_exception_spec;
216 ReturnValueOnError =
false;
222 PDiag(DiagID),
PDiag(diag::note_previous_declaration),
225 &MissingExceptionSpecification, &MissingEmptyExceptionSpecification,
226 true, IsOperatorNew)) {
243 if (!MissingExceptionSpecification)
244 return ReturnValueOnError;
257 if (MissingEmptyExceptionSpecification && NewProto &&
286 llvm::raw_svector_ostream OS(ExceptionSpecString);
294 bool OnFirstException =
true;
295 for (
const auto &E : OldProto->
exceptions()) {
296 if (OnFirstException)
297 OnFirstException =
false;
313 assert(OldProto->
getNoexceptExpr() !=
nullptr &&
"Expected non-null Expr");
319 llvm_unreachable(
"This spec type is compatible with none.");
354 unsigned DiagID = diag::err_mismatched_exception_spec;
356 DiagID = diag::ext_mismatched_exception_spec;
358 PDiag(diag::note_previous_declaration), Old, OldLoc, New, NewLoc);
378 bool *MissingExceptionSpecification,
379 bool*MissingEmptyExceptionSpecification,
380 bool AllowNoexceptAllMatchWithNoSpec,
381 bool IsOperatorNew) {
386 if (MissingExceptionSpecification)
387 *MissingExceptionSpecification =
false;
389 if (MissingEmptyExceptionSpecification)
390 *MissingEmptyExceptionSpecification =
false;
423 "Shouldn't see unknown exception specifications here");
438 if (OldNR == NewNR &&
442 if (OldNR != NewNR &&
445 Diag(NewLoc, DiagID);
447 Diag(OldLoc, NoteID);
467 if (AllowNoexceptAllMatchWithNoSpec) {
479 if (OldNonThrowing && NewNonThrowing)
488 WithExceptions = New;
490 WithExceptions = Old;
497 if (Name && Name->
getName() ==
"bad_alloc") {
499 if (ExRecord->isInStdNamespace()) {
514 *MissingExceptionSpecification =
true;
516 if (MissingEmptyExceptionSpecification && OldNonThrowing) {
520 *MissingEmptyExceptionSpecification =
true;
526 Diag(NewLoc, DiagID);
528 Diag(OldLoc, NoteID);
533 "Exception compatibility logic error: non-dynamic spec slipped through.");
538 llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
544 if(OldTypes.count(TypePtr))
545 NewTypes.insert(TypePtr);
550 Success = Success && OldTypes.size() == NewTypes.size();
555 Diag(NewLoc, DiagID);
557 Diag(OldLoc, NoteID);
612 "Shouldn't see unknown exception specifications here");
616 Diag(SubLoc, DiagID);
618 Diag(SuperLoc, NoteID);
629 Diag(SubLoc, DiagID);
631 Diag(SuperLoc, NoteID);
641 Diag(SubLoc, DiagID);
643 Diag(SuperLoc, NoteID);
648 "Exception spec subset: non-dynamic case slipped through.");
651 for (
const auto &SubI : Subset->
exceptions()) {
657 bool SubIsPointer =
false;
670 bool Contained =
false;
672 for (
const auto &SuperI : Superset->
exceptions()) {
687 if (CanonicalSubT == CanonicalSuperT) {
705 CanonicalSuperT, CanonicalSubT,
713 llvm_unreachable(
"access check dependent for unprivileged context");
715 llvm_unreachable(
"access check delayed in non-declaration");
722 Diag(SubLoc, DiagID);
724 Diag(SuperLoc, NoteID);
759 *
this,
PDiag(diag::err_deep_exception_specs_differ) << 0,
PDiag(),
767 "Functions have different argument counts.");
768 for (
unsigned i = 0, E = Target->
getNumParams(); i != E; ++i) {
770 *
this,
PDiag(diag::err_deep_exception_specs_differ) << 1,
PDiag(),
804 From->getSourceRange().getBegin(),
815 if (
getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) {
835 unsigned DiagID = diag::err_override_exception_spec;
837 DiagID = diag::ext_override_exception_spec;
839 PDiag(diag::note_overridden_virtual_function),
848 for (
const Stmt *SubStmt : E->children()) {
857 assert(D &&
"Expected decl");
866 if (isa<FunctionDecl>(D) && D->
hasAttr<NoThrowAttr>())
916 if (!cast<CXXRecordDecl>(RT->
getDecl())->isPolymorphic())
929 switch (E->getStmtClass()) {
930 case Expr::CXXThrowExprClass:
934 case Expr::CXXDynamicCastExprClass: {
943 case Expr::CXXTypeidExprClass:
951 case Expr::CallExprClass:
952 case Expr::CXXMemberCallExprClass:
953 case Expr::CXXOperatorCallExprClass:
954 case Expr::UserDefinedLiteralClass: {
955 const CallExpr *CE = cast<CallExpr>(E);
970 case Expr::CXXConstructExprClass:
971 case Expr::CXXTemporaryObjectExprClass: {
973 cast<CXXConstructExpr>(E)->getConstructor());
979 case Expr::LambdaExprClass: {
980 const LambdaExpr *Lambda = cast<LambdaExpr>(E);
984 Cap != CapEnd; ++Cap)
989 case Expr::CXXNewExprClass: {
994 CT =
canCalleeThrow(*
this, E, cast<CXXNewExpr>(E)->getOperatorNew());
1000 case Expr::CXXDeleteExprClass: {
1002 QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType();
1007 cast<CXXDeleteExpr>(E)->getOperatorDelete());
1009 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
1020 case Expr::CXXBindTemporaryExprClass: {
1023 cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor());
1031 case Expr::ObjCMessageExprClass:
1032 case Expr::ObjCPropertyRefExprClass:
1033 case Expr::ObjCSubscriptRefExprClass:
1039 case Expr::ObjCArrayLiteralClass:
1040 case Expr::ObjCDictionaryLiteralClass:
1041 case Expr::ObjCBoxedExprClass:
1046 case Expr::ConditionalOperatorClass:
1047 case Expr::CompoundLiteralExprClass:
1048 case Expr::CXXConstCastExprClass:
1049 case Expr::CXXReinterpretCastExprClass:
1050 case Expr::CXXStdInitializerListExprClass:
1051 case Expr::DesignatedInitExprClass:
1052 case Expr::DesignatedInitUpdateExprClass:
1053 case Expr::ExprWithCleanupsClass:
1054 case Expr::ExtVectorElementExprClass:
1055 case Expr::InitListExprClass:
1056 case Expr::MemberExprClass:
1057 case Expr::ObjCIsaExprClass:
1058 case Expr::ObjCIvarRefExprClass:
1059 case Expr::ParenExprClass:
1060 case Expr::ParenListExprClass:
1061 case Expr::ShuffleVectorExprClass:
1062 case Expr::ConvertVectorExprClass:
1063 case Expr::VAArgExprClass:
1067 case Expr::ArraySubscriptExprClass:
1068 case Expr::BinaryOperatorClass:
1069 case Expr::CompoundAssignOperatorClass:
1070 case Expr::CStyleCastExprClass:
1071 case Expr::CXXStaticCastExprClass:
1072 case Expr::CXXFunctionalCastExprClass:
1073 case Expr::ImplicitCastExprClass:
1074 case Expr::MaterializeTemporaryExprClass:
1075 case Expr::UnaryOperatorClass: {
1081 case Expr::StmtExprClass:
1084 case Expr::CXXDefaultArgExprClass:
1085 return canThrow(cast<CXXDefaultArgExpr>(E)->getExpr());
1087 case Expr::CXXDefaultInitExprClass:
1088 return canThrow(cast<CXXDefaultInitExpr>(E)->getExpr());
1090 case Expr::ChooseExprClass:
1093 return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr());
1095 case Expr::GenericSelectionExprClass:
1096 if (cast<GenericSelectionExpr>(E)->isResultDependent())
1098 return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr());
1101 case Expr::CXXDependentScopeMemberExprClass:
1102 case Expr::CXXUnresolvedConstructExprClass:
1103 case Expr::DependentScopeDeclRefExprClass:
1104 case Expr::CXXFoldExprClass:
1107 case Expr::AsTypeExprClass:
1108 case Expr::BinaryConditionalOperatorClass:
1109 case Expr::BlockExprClass:
1110 case Expr::CUDAKernelCallExprClass:
1111 case Expr::DeclRefExprClass:
1112 case Expr::ObjCBridgedCastExprClass:
1113 case Expr::ObjCIndirectCopyRestoreExprClass:
1114 case Expr::ObjCProtocolExprClass:
1115 case Expr::ObjCSelectorExprClass:
1116 case Expr::OffsetOfExprClass:
1117 case Expr::PackExpansionExprClass:
1118 case Expr::PseudoObjectExprClass:
1119 case Expr::SubstNonTypeTemplateParmExprClass:
1120 case Expr::SubstNonTypeTemplateParmPackExprClass:
1121 case Expr::FunctionParmPackExprClass:
1122 case Expr::UnaryExprOrTypeTraitExprClass:
1123 case Expr::UnresolvedLookupExprClass:
1124 case Expr::UnresolvedMemberExprClass:
1125 case Expr::TypoExprClass:
1129 case Expr::AddrLabelExprClass:
1130 case Expr::ArrayTypeTraitExprClass:
1131 case Expr::AtomicExprClass:
1132 case Expr::TypeTraitExprClass:
1133 case Expr::CXXBoolLiteralExprClass:
1134 case Expr::CXXNoexceptExprClass:
1135 case Expr::CXXNullPtrLiteralExprClass:
1136 case Expr::CXXPseudoDestructorExprClass:
1137 case Expr::CXXScalarValueInitExprClass:
1138 case Expr::CXXThisExprClass:
1139 case Expr::CXXUuidofExprClass:
1140 case Expr::CharacterLiteralClass:
1141 case Expr::ExpressionTraitExprClass:
1142 case Expr::FloatingLiteralClass:
1143 case Expr::GNUNullExprClass:
1144 case Expr::ImaginaryLiteralClass:
1145 case Expr::ImplicitValueInitExprClass:
1146 case Expr::IntegerLiteralClass:
1147 case Expr::NoInitExprClass:
1148 case Expr::ObjCEncodeExprClass:
1149 case Expr::ObjCStringLiteralClass:
1150 case Expr::ObjCBoolLiteralExprClass:
1151 case Expr::OpaqueValueExprClass:
1152 case Expr::PredefinedExprClass:
1153 case Expr::SizeOfPackExprClass:
1154 case Expr::StringLiteralClass:
1158 case Expr::MSPropertyRefExprClass:
1159 llvm_unreachable(
"Invalid class for expression");
1161 #define STMT(CLASS, PARENT) case Expr::CLASS##Class:
1162 #define STMT_RANGE(Base, First, Last)
1163 #define LAST_STMT_RANGE(BASE, FIRST, LAST)
1164 #define EXPR(CLASS, PARENT)
1165 #define ABSTRACT_STMT(STMT)
1166 #include "clang/AST/StmtNodes.inc"
1167 case Expr::NoStmtClass:
1168 llvm_unreachable(
"Invalid class for expression");
1170 llvm_unreachable(
"Bogus StmtClass");
CanThrowResult canThrow(const Expr *E)
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
CastKind getCastKind() const
no exception specification
bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
void UpdateExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI)
void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Function)
FunctionDecl * getExceptionSpecDecl() const
If this function type has an exception specification which hasn't been determined yet (either because...
const FunctionProtoType * ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT)
IdentifierInfo * getIdentifier() const
const LangOptions & getLangOpts() const
CanQual< T > getUnqualifiedType() const
Retrieve the unqualified form of this type.
Defines the SourceManager interface.
bool isRecordType() const
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
void EvaluateImplicitExceptionSpec(SourceLocation Loc, CXXMethodDecl *MD)
Evaluate the implicit exception specification for a defaulted special member function.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
A container of type source information.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
The noexcept specifier has a bad expression.
Information about one declarator, including the parsed type information and the identifier.
const Expr * getCallee() const
void clear()
Clear the base-paths results.
CK_Dynamic - A C++ dynamic_cast.
Defines the clang::Expr interface and subclasses for C++ expressions.
QualType getArrayDecayedType(QualType T) const
Return the properly qualified result of decaying the specified array type to a pointer.
Base wrapper for a particular "section" of type source info.
unsigned getNumParams() const
bool isExternC() const
Determines whether this function is a function with external, C linkage.
ArrayRef< QualType > getParamTypes() const
bool isReferenceType() const
NoexceptResult
Result type of getNoexceptSpec().
SourceLocation getLocStart() const LLVM_READONLY
Microsoft throw(...) extension.
unsigned getDiagID() const
QualType getReturnType() const
Wrapper for source info for functions.
const CXXRecordDecl * getParent() const
bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, const CXXMethodDecl *Old)
capture_init_iterator capture_init_end() const
Retrieve the iterator pointing one past the last initialization argument for this lambda expression...
Expr * getExprOperand() const
Expr * getNoexceptExpr() const
bool isValueDependent() const
RecordDecl * getDecl() const
static bool CheckSpecForTypesEquivalent(Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, QualType Target, SourceLocation TargetLoc, QualType Source, SourceLocation SourceLoc)
QualType getTypeAsWritten() const
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Sema - This implements semantic analysis and AST building for C.
QualType getParamType(unsigned i) const
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
capture_init_iterator capture_init_begin() const
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
CanThrowResult mergeCanThrow(CanThrowResult CT1, CanThrowResult CT2)
QualType getPointeeType() const
StringRef getName() const
Return the actual identifier string.
Represents a C++ destructor within a class.
ExtProtoInfo getExtProtoInfo() const
ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O)
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Defines the clang::TypeLoc interface and its subclasses.
There is no noexcept specifier.
ASTMutationListener * getASTMutationListener() const
bool isDependentType() const
bool IsDerivedFrom(QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
DeclarationName getDeclName() const
The result type of a method or function.
TypeSourceInfo * getTypeSourceInfo() const
static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC)
bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification. If this depends on t...
CanThrowResult
Possible results from evaluation of a noexcept expression.
exception_iterator exception_begin() const
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl. It will iterate at least once ...
ExceptionSpecificationType Type
The kind of exception specification this is.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
bool CheckDistantExceptionSpec(QualType T)
bool CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range)
bool isValid() const
Return true if this is a valid SourceLocation object.
OverloadedOperatorKind getCXXOverloadedOperator() const
Represents a static or instance method of a struct/union/class.
static bool hasImplicitExceptionSpec(FunctionDecl *Decl)
The noexcept specifier evaluates to true.
static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC)
bool hasDependentExceptionSpec() const
Return whether this function has a dependent exception spec.
SourceLocation getBegin() const
bool isTypeDependent() const
NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const
Get the meaning of the noexcept spec on this function, if any.
bool isLibstdcxxEagerExceptionSpecHack(const Declarator &D)
Determine if we're in a case where we need to (incorrectly) eagerly parse an exception specification ...
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
QualType getType() const
Return the type wrapped by this type source info.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
not evaluated yet, for special member function
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
TypeLoc IgnoreParens() const
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Defines the Diagnostic-related interfaces.
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy.
bool CheckExceptionSpecSubset(const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID, const FunctionProtoType *Superset, SourceLocation SuperLoc, const FunctionProtoType *Subset, SourceLocation SubLoc)
bool isFunctionType() const
The noexcept specifier evaluates to false.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
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.
SourceManager & getSourceManager()
IdentifierInfo * getIdentifier() const
bool CheckParamExceptionSpec(const PartialDiagnostic &NoteID, const FunctionProtoType *Target, SourceLocation TargetLoc, const FunctionProtoType *Source, SourceLocation SourceLoc)
Represents a C++ struct/union/class.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
void adjustExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI, bool AsWritten=false)
Change the exception specification on a function once it is delay-parsed, instantiated, or computed.
static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D)
bool hasExceptionSpec() const
Return whether this function has any kind of exception spec.
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
A trivial tuple used to represent a source range.
SourceLocation getLocation() const
static CanThrowResult canSubExprsThrow(Sema &S, const Expr *E)
SmallVector< std::pair< const CXXMethodDecl *, const CXXMethodDecl * >, 2 > DelayedExceptionSpecChecks
All the overriding functions seen during a class definition that had their exception spec checks dela...
bool isNull() const
isNull - Return true if this QualType doesn't point to a type yet.
bool isTypeOperand() const
The noexcept specifier is dependent.
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New)
NamespaceDecl * getStdNamespace() const
void setType(QualType newType)
ArrayRef< QualType > exceptions() const
bool isBeingDefined() const
isBeingDefined - Return true if this decl is currently being defined.
static const FunctionProtoType * GetUnderlyingFunction(QualType T)
Expr * IgnoreParens() LLVM_READONLY
unsigned getNumExceptions() const