blob: 3561bd02b9551dde7f6d756301b96af99963dc49 [file] [log] [blame]
Sebastian Redl4915e632009-10-11 09:03:14 +00001//===--- SemaExceptionSpec.cpp - C++ Exception Specifications ---*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides Sema routines for C++ exception specification testing.
11//
12//===----------------------------------------------------------------------===//
13
John McCall83024632010-08-25 22:03:47 +000014#include "clang/Sema/SemaInternal.h"
Richard Smith564417a2014-03-20 21:47:22 +000015#include "clang/AST/ASTMutationListener.h"
Sebastian Redl4915e632009-10-11 09:03:14 +000016#include "clang/AST/CXXInheritance.h"
17#include "clang/AST/Expr.h"
18#include "clang/AST/ExprCXX.h"
Douglas Gregord6bc5e62010-03-24 07:14:45 +000019#include "clang/AST/TypeLoc.h"
Douglas Gregorf40863c2010-02-12 07:32:17 +000020#include "clang/Basic/Diagnostic.h"
21#include "clang/Basic/SourceManager.h"
Sebastian Redl4915e632009-10-11 09:03:14 +000022#include "llvm/ADT/SmallPtrSet.h"
Benjamin Kramer49038022012-02-04 13:45:25 +000023#include "llvm/ADT/SmallString.h"
Sebastian Redl4915e632009-10-11 09:03:14 +000024
25namespace clang {
26
27static const FunctionProtoType *GetUnderlyingFunction(QualType T)
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();
Sebastian Redl075b21d2009-10-14 14:38:54 +000033 else if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
34 T = MPTy->getPointeeType();
Sebastian Redl4915e632009-10-11 09:03:14 +000035 return T->getAs<FunctionProtoType>();
36}
37
Richard Smith6403e932014-11-14 00:37:55 +000038/// 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.
42bool Sema::isLibstdcxxEagerExceptionSpecHack(const Declarator &D) {
43 auto *RD = dyn_cast<CXXRecordDecl>(CurContext);
44
45 // All the problem cases are member functions named "swap" within class
Richard Smith62895462016-10-19 23:47:37 +000046 // templates declared directly within namespace std or std::__debug or
47 // std::__profile.
48 if (!RD || !RD->getIdentifier() || !RD->getDescribedClassTemplate() ||
Richard Smith6403e932014-11-14 00:37:55 +000049 !D.getIdentifier() || !D.getIdentifier()->isStr("swap"))
50 return false;
51
Richard Smith62895462016-10-19 23:47:37 +000052 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
Richard Smith6403e932014-11-14 00:37:55 +000066 // Only apply this hack within a system header.
67 if (!Context.getSourceManager().isInSystemHeader(D.getLocStart()))
68 return false;
69
70 return llvm::StringSwitch<bool>(RD->getIdentifier()->getName())
71 .Case("array", true)
Richard Smith62895462016-10-19 23:47:37 +000072 .Case("pair", IsInStd)
73 .Case("priority_queue", IsInStd)
74 .Case("stack", IsInStd)
75 .Case("queue", IsInStd)
Richard Smith6403e932014-11-14 00:37:55 +000076 .Default(false);
77}
78
Sebastian Redl4915e632009-10-11 09:03:14 +000079/// 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.
Richard Smith8606d752012-11-28 22:33:28 +000082///
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.
Craig Toppere335f252015-10-04 04:53:55 +000085bool Sema::CheckSpecifiedExceptionType(QualType &T, SourceRange Range) {
Richard Smitha118c6a2012-11-28 22:52:42 +000086 // C++11 [except.spec]p2:
87 // A type cv T, "array of T", or "function returning T" denoted
Richard Smith8606d752012-11-28 22:33:28 +000088 // in an exception-specification is adjusted to type T, "pointer to T", or
89 // "pointer to function returning T", respectively.
Richard Smitha118c6a2012-11-28 22:52:42 +000090 //
91 // We also apply this rule in C++98.
Richard Smith8606d752012-11-28 22:33:28 +000092 if (T->isArrayType())
93 T = Context.getArrayDecayedType(T);
94 else if (T->isFunctionType())
95 T = Context.getPointerType(T);
Sebastian Redl4915e632009-10-11 09:03:14 +000096
Richard Smitha118c6a2012-11-28 22:52:42 +000097 int Kind = 0;
Richard Smith8606d752012-11-28 22:33:28 +000098 QualType PointeeT = T;
Richard Smitha118c6a2012-11-28 22:52:42 +000099 if (const PointerType *PT = T->getAs<PointerType>()) {
100 PointeeT = PT->getPointeeType();
101 Kind = 1;
Sebastian Redl4915e632009-10-11 09:03:14 +0000102
Richard Smitha118c6a2012-11-28 22:52:42 +0000103 // cv void* is explicitly permitted, despite being a pointer to an
104 // incomplete type.
105 if (PointeeT->isVoidType())
106 return false;
107 } else if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
108 PointeeT = RT->getPointeeType();
109 Kind = 2;
Richard Smith8606d752012-11-28 22:33:28 +0000110
Richard Smitha118c6a2012-11-28 22:52:42 +0000111 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)
116 << T << Range;
117 return true;
118 }
119 }
120
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.
David Majnemerb2b0da42016-06-10 18:24:41 +0000127 // In Microsoft mode, downgrade this to a warning.
128 unsigned DiagID = diag::err_incomplete_in_exception_spec;
David Majnemer5d321e62016-06-11 01:25:04 +0000129 bool ReturnValueOnError = true;
130 if (getLangOpts().MicrosoftExt) {
David Majnemerb2b0da42016-06-10 18:24:41 +0000131 DiagID = diag::ext_incomplete_in_exception_spec;
David Majnemer5d321e62016-06-11 01:25:04 +0000132 ReturnValueOnError = false;
133 }
Richard Smitha118c6a2012-11-28 22:52:42 +0000134 if (!(PointeeT->isRecordType() &&
135 PointeeT->getAs<RecordType>()->isBeingDefined()) &&
David Majnemerb2b0da42016-06-10 18:24:41 +0000136 RequireCompleteType(Range.getBegin(), PointeeT, DiagID, Kind, Range))
David Majnemer5d321e62016-06-11 01:25:04 +0000137 return ReturnValueOnError;
Sebastian Redl4915e632009-10-11 09:03:14 +0000138
139 return false;
140}
141
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.
145bool Sema::CheckDistantExceptionSpec(QualType T) {
Richard Smith3c4f8d22016-10-16 17:54:23 +0000146 // C++17 removes this rule in favor of putting exception specifications into
147 // the type system.
148 if (getLangOpts().CPlusPlus1z)
149 return false;
150
Sebastian Redl4915e632009-10-11 09:03:14 +0000151 if (const PointerType *PT = T->getAs<PointerType>())
152 T = PT->getPointeeType();
153 else if (const MemberPointerType *PT = T->getAs<MemberPointerType>())
154 T = PT->getPointeeType();
155 else
156 return false;
157
158 const FunctionProtoType *FnT = T->getAs<FunctionProtoType>();
159 if (!FnT)
160 return false;
161
162 return FnT->hasExceptionSpec();
163}
164
Richard Smithf623c962012-04-17 00:58:00 +0000165const FunctionProtoType *
166Sema::ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT) {
Richard Smith0b3a4622014-11-13 20:01:57 +0000167 if (FPT->getExceptionSpecType() == EST_Unparsed) {
168 Diag(Loc, diag::err_exception_spec_not_parsed);
169 return nullptr;
170 }
171
Richard Smithd3b5c9082012-07-27 04:22:15 +0000172 if (!isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
Richard Smithf623c962012-04-17 00:58:00 +0000173 return FPT;
174
175 FunctionDecl *SourceDecl = FPT->getExceptionSpecDecl();
176 const FunctionProtoType *SourceFPT =
177 SourceDecl->getType()->castAs<FunctionProtoType>();
178
Richard Smithd3b5c9082012-07-27 04:22:15 +0000179 // If the exception specification has already been resolved, just return it.
180 if (!isUnresolvedExceptionSpec(SourceFPT->getExceptionSpecType()))
Richard Smithf623c962012-04-17 00:58:00 +0000181 return SourceFPT;
182
Richard Smithd3b5c9082012-07-27 04:22:15 +0000183 // Compute or instantiate the exception specification now.
Richard Smith3901dfe2013-03-27 00:22:47 +0000184 if (SourceFPT->getExceptionSpecType() == EST_Unevaluated)
Richard Smithd3b5c9082012-07-27 04:22:15 +0000185 EvaluateImplicitExceptionSpec(Loc, cast<CXXMethodDecl>(SourceDecl));
186 else
187 InstantiateExceptionSpec(Loc, SourceDecl);
Richard Smithf623c962012-04-17 00:58:00 +0000188
Davide Italiano922b7022015-07-25 01:19:32 +0000189 const FunctionProtoType *Proto =
190 SourceDecl->getType()->castAs<FunctionProtoType>();
191 if (Proto->getExceptionSpecType() == clang::EST_Unparsed) {
192 Diag(Loc, diag::err_exception_spec_not_parsed);
193 Proto = nullptr;
194 }
195 return Proto;
Richard Smithf623c962012-04-17 00:58:00 +0000196}
197
Richard Smith8acb4282014-07-31 21:57:55 +0000198void
199Sema::UpdateExceptionSpec(FunctionDecl *FD,
200 const FunctionProtoType::ExceptionSpecInfo &ESI) {
Richard Smith564417a2014-03-20 21:47:22 +0000201 // If we've fully resolved the exception specification, notify listeners.
Richard Smith8acb4282014-07-31 21:57:55 +0000202 if (!isUnresolvedExceptionSpec(ESI.Type))
Richard Smith564417a2014-03-20 21:47:22 +0000203 if (auto *Listener = getASTMutationListener())
204 Listener->ResolvedExceptionSpec(FD);
Richard Smith9e2341d2015-03-23 03:25:59 +0000205
206 for (auto *Redecl : FD->redecls())
207 Context.adjustExceptionSpec(cast<FunctionDecl>(Redecl), ESI);
Richard Smith564417a2014-03-20 21:47:22 +0000208}
209
Richard Smith13b40bc2016-11-30 00:13:55 +0000210static 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);
217
Richard Smith66f3ac92012-10-20 08:26:51 +0000218/// Determine whether a function has an implicitly-generated exception
Richard Smith1ee63522012-10-16 23:30:16 +0000219/// specification.
Richard Smith66f3ac92012-10-20 08:26:51 +0000220static bool hasImplicitExceptionSpec(FunctionDecl *Decl) {
221 if (!isa<CXXDestructorDecl>(Decl) &&
222 Decl->getDeclName().getCXXOverloadedOperator() != OO_Delete &&
223 Decl->getDeclName().getCXXOverloadedOperator() != OO_Array_Delete)
224 return false;
Richard Smith1ee63522012-10-16 23:30:16 +0000225
Richard Smithc7fb2252014-02-07 22:51:16 +0000226 // 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).
Richard Smith66f3ac92012-10-20 08:26:51 +0000231 if (!Decl->getTypeSourceInfo())
Richard Smithc7fb2252014-02-07 22:51:16 +0000232 return isa<CXXDestructorDecl>(Decl);
Richard Smith66f3ac92012-10-20 08:26:51 +0000233
234 const FunctionProtoType *Ty =
235 Decl->getTypeSourceInfo()->getType()->getAs<FunctionProtoType>();
236 return !Ty->hasExceptionSpec();
Richard Smith1ee63522012-10-16 23:30:16 +0000237}
238
Douglas Gregorf40863c2010-02-12 07:32:17 +0000239bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
Richard Smith13b40bc2016-11-30 00:13:55 +0000240 // Just completely ignore this under -fno-exceptions prior to C++1z.
241 // In C++1z 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().CPlusPlus1z)
244 return false;
245
Sebastian Redlcb5dd002011-03-15 19:52:30 +0000246 OverloadedOperatorKind OO = New->getDeclName().getCXXOverloadedOperator();
247 bool IsOperatorNew = OO == OO_New || OO == OO_Array_New;
Douglas Gregord6bc5e62010-03-24 07:14:45 +0000248 bool MissingExceptionSpecification = false;
Douglas Gregorf40863c2010-02-12 07:32:17 +0000249 bool MissingEmptyExceptionSpecification = false;
Hans Wennborg39a509a2014-02-05 02:37:58 +0000250
Francois Pichet13b4e682011-03-19 23:05:18 +0000251 unsigned DiagID = diag::err_mismatched_exception_spec;
Hans Wennborg39a509a2014-02-05 02:37:58 +0000252 bool ReturnValueOnError = true;
253 if (getLangOpts().MicrosoftExt) {
Richard Smith1b98ccc2014-07-19 01:39:17 +0000254 DiagID = diag::ext_mismatched_exception_spec;
Hans Wennborg39a509a2014-02-05 02:37:58 +0000255 ReturnValueOnError = false;
256 }
Richard Smithf623c962012-04-17 00:58:00 +0000257
Richard Smith1ee63522012-10-16 23:30:16 +0000258 // Check the types as written: they must match before any exception
259 // specification adjustment is applied.
Richard Smith13b40bc2016-11-30 00:13:55 +0000260 if (!CheckEquivalentExceptionSpecImpl(
261 *this, PDiag(DiagID), PDiag(diag::note_previous_declaration),
Richard Smith66f3ac92012-10-20 08:26:51 +0000262 Old->getType()->getAs<FunctionProtoType>(), Old->getLocation(),
263 New->getType()->getAs<FunctionProtoType>(), New->getLocation(),
Richard Smith1ee63522012-10-16 23:30:16 +0000264 &MissingExceptionSpecification, &MissingEmptyExceptionSpecification,
Richard Smith66f3ac92012-10-20 08:26:51 +0000265 /*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.
Richard Smithe3ea0012016-08-31 20:38:32 +0000270 if (getLangOpts().CPlusPlus11 && getLangOpts().CXXExceptions &&
Richard Smith66f3ac92012-10-20 08:26:51 +0000271 hasImplicitExceptionSpec(Old) != hasImplicitExceptionSpec(New)) {
272 Diag(New->getLocation(), diag::ext_implicit_exception_spec_mismatch)
273 << hasImplicitExceptionSpec(Old);
Yaron Keren8b563662015-10-03 10:46:20 +0000274 if (Old->getLocation().isValid())
Richard Smith66f3ac92012-10-20 08:26:51 +0000275 Diag(Old->getLocation(), diag::note_previous_declaration);
276 }
Douglas Gregorf40863c2010-02-12 07:32:17 +0000277 return false;
Richard Smith66f3ac92012-10-20 08:26:51 +0000278 }
Douglas Gregorf40863c2010-02-12 07:32:17 +0000279
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000280 // The failure was something other than an missing exception
Hans Wennborg39a509a2014-02-05 02:37:58 +0000281 // specification; return an error, except in MS mode where this is a warning.
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000282 if (!MissingExceptionSpecification)
Hans Wennborg39a509a2014-02-05 02:37:58 +0000283 return ReturnValueOnError;
Douglas Gregorf40863c2010-02-12 07:32:17 +0000284
Richard Smith66f3ac92012-10-20 08:26:51 +0000285 const FunctionProtoType *NewProto =
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000286 New->getType()->castAs<FunctionProtoType>();
John McCalldb40c7f2010-12-14 08:05:40 +0000287
Douglas Gregorf40863c2010-02-12 07:32:17 +0000288 // 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. This is an
292 // egregious workaround for glibc, which adds throw() specifications
293 // to many libc functions as an optimization. Unfortunately, that
294 // optimization isn't permitted by the C++ standard, so we're forced
295 // to work around it here.
John McCalldb40c7f2010-12-14 08:05:40 +0000296 if (MissingEmptyExceptionSpecification && NewProto &&
Douglas Gregord6bc5e62010-03-24 07:14:45 +0000297 (Old->getLocation().isInvalid() ||
298 Context.getSourceManager().isInSystemHeader(Old->getLocation())) &&
Douglas Gregorf40863c2010-02-12 07:32:17 +0000299 Old->isExternC()) {
Richard Smith8acb4282014-07-31 21:57:55 +0000300 New->setType(Context.getFunctionType(
301 NewProto->getReturnType(), NewProto->getParamTypes(),
302 NewProto->getExtProtoInfo().withExceptionSpec(EST_DynamicNone)));
Douglas Gregorf40863c2010-02-12 07:32:17 +0000303 return false;
304 }
305
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000306 const FunctionProtoType *OldProto =
307 Old->getType()->castAs<FunctionProtoType>();
Douglas Gregord6bc5e62010-03-24 07:14:45 +0000308
Richard Smith8acb4282014-07-31 21:57:55 +0000309 FunctionProtoType::ExceptionSpecInfo ESI = OldProto->getExceptionSpecType();
310 if (ESI.Type == EST_Dynamic) {
311 ESI.Exceptions = OldProto->exceptions();
Douglas Gregord6bc5e62010-03-24 07:14:45 +0000312 }
313
Richard Smitha91de372015-09-30 00:48:50 +0000314 if (ESI.Type == EST_ComputedNoexcept) {
315 // For computed noexcept, we can't just take the expression from the old
316 // prototype. It likely contains references to the old prototype's
317 // parameters.
318 New->setInvalidDecl();
319 } else {
320 // Update the type of the function with the appropriate exception
321 // specification.
322 New->setType(Context.getFunctionType(
323 NewProto->getReturnType(), NewProto->getParamTypes(),
324 NewProto->getExtProtoInfo().withExceptionSpec(ESI)));
325 }
326
David Majnemer06ce8a42015-10-20 20:49:21 +0000327 if (getLangOpts().MicrosoftExt && ESI.Type != EST_ComputedNoexcept) {
328 // Allow missing exception specifications in redeclarations as an extension.
329 DiagID = diag::ext_ms_missing_exception_specification;
330 ReturnValueOnError = false;
331 } else if (New->isReplaceableGlobalAllocationFunction() &&
332 ESI.Type != EST_ComputedNoexcept) {
333 // Allow missing exception specifications in redeclarations as an extension,
334 // when declaring a replaceable global allocation function.
Richard Smitha91de372015-09-30 00:48:50 +0000335 DiagID = diag::ext_missing_exception_specification;
336 ReturnValueOnError = false;
337 } else {
338 DiagID = diag::err_missing_exception_specification;
339 ReturnValueOnError = true;
340 }
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000341
342 // Warn about the lack of exception specification.
343 SmallString<128> ExceptionSpecString;
344 llvm::raw_svector_ostream OS(ExceptionSpecString);
345 switch (OldProto->getExceptionSpecType()) {
346 case EST_DynamicNone:
347 OS << "throw()";
348 break;
349
350 case EST_Dynamic: {
351 OS << "throw(";
352 bool OnFirstException = true;
Aaron Ballmanb088fbe2014-03-17 15:38:09 +0000353 for (const auto &E : OldProto->exceptions()) {
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000354 if (OnFirstException)
355 OnFirstException = false;
356 else
357 OS << ", ";
358
Aaron Ballmanb088fbe2014-03-17 15:38:09 +0000359 OS << E.getAsString(getPrintingPolicy());
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000360 }
361 OS << ")";
362 break;
363 }
364
365 case EST_BasicNoexcept:
366 OS << "noexcept";
367 break;
368
369 case EST_ComputedNoexcept:
370 OS << "noexcept(";
Richard Trieuddd01ce2014-06-09 22:53:25 +0000371 assert(OldProto->getNoexceptExpr() != nullptr && "Expected non-null Expr");
Craig Topperc3ec1492014-05-26 06:22:03 +0000372 OldProto->getNoexceptExpr()->printPretty(OS, nullptr, getPrintingPolicy());
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000373 OS << ")";
374 break;
375
376 default:
377 llvm_unreachable("This spec type is compatible with none.");
378 }
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000379
380 SourceLocation FixItLoc;
381 if (TypeSourceInfo *TSInfo = New->getTypeSourceInfo()) {
382 TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
Richard Smitha91de372015-09-30 00:48:50 +0000383 // FIXME: Preserve enough information so that we can produce a correct fixit
384 // location when there is a trailing return type.
385 if (auto FTLoc = TL.getAs<FunctionProtoTypeLoc>())
386 if (!FTLoc.getTypePtr()->hasTrailingReturn())
387 FixItLoc = getLocForEndOfToken(FTLoc.getLocalRangeEnd());
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000388 }
389
390 if (FixItLoc.isInvalid())
Richard Smitha91de372015-09-30 00:48:50 +0000391 Diag(New->getLocation(), DiagID)
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000392 << New << OS.str();
393 else {
Richard Smitha91de372015-09-30 00:48:50 +0000394 Diag(New->getLocation(), DiagID)
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000395 << New << OS.str()
396 << FixItHint::CreateInsertion(FixItLoc, " " + OS.str().str());
397 }
398
Yaron Keren8b563662015-10-03 10:46:20 +0000399 if (Old->getLocation().isValid())
Eli Friedman96dbf6f2013-06-25 00:46:32 +0000400 Diag(Old->getLocation(), diag::note_previous_declaration);
401
Richard Smitha91de372015-09-30 00:48:50 +0000402 return ReturnValueOnError;
Douglas Gregorf40863c2010-02-12 07:32:17 +0000403}
404
Sebastian Redl4915e632009-10-11 09:03:14 +0000405/// CheckEquivalentExceptionSpec - Check if the two types have equivalent
406/// exception specifications. Exception specifications are equivalent if
407/// they allow exactly the same set of exception types. It does not matter how
408/// that is achieved. See C++ [except.spec]p2.
409bool Sema::CheckEquivalentExceptionSpec(
410 const FunctionProtoType *Old, SourceLocation OldLoc,
411 const FunctionProtoType *New, SourceLocation NewLoc) {
Richard Smith13b40bc2016-11-30 00:13:55 +0000412 if (!getLangOpts().CXXExceptions)
413 return false;
414
Francois Pichet13b4e682011-03-19 23:05:18 +0000415 unsigned DiagID = diag::err_mismatched_exception_spec;
David Blaikiebbafb8a2012-03-11 07:00:24 +0000416 if (getLangOpts().MicrosoftExt)
Richard Smith1b98ccc2014-07-19 01:39:17 +0000417 DiagID = diag::ext_mismatched_exception_spec;
Richard Smith13b40bc2016-11-30 00:13:55 +0000418 bool Result = CheckEquivalentExceptionSpecImpl(
419 *this, PDiag(DiagID), PDiag(diag::note_previous_declaration),
420 Old, OldLoc, New, NewLoc);
Hans Wennborg39a509a2014-02-05 02:37:58 +0000421
422 // In Microsoft mode, mismatching exception specifications just cause a warning.
423 if (getLangOpts().MicrosoftExt)
424 return false;
425 return Result;
Sebastian Redl4915e632009-10-11 09:03:14 +0000426}
427
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000428/// CheckEquivalentExceptionSpec - Check if the two types have compatible
429/// exception specifications. See C++ [except.spec]p3.
Richard Smith66f3ac92012-10-20 08:26:51 +0000430///
431/// \return \c false if the exception specifications match, \c true if there is
432/// a problem. If \c true is returned, either a diagnostic has already been
433/// produced or \c *MissingExceptionSpecification is set to \c true.
Richard Smith13b40bc2016-11-30 00:13:55 +0000434static bool CheckEquivalentExceptionSpecImpl(
435 Sema &S, const PartialDiagnostic &DiagID, const PartialDiagnostic &NoteID,
436 const FunctionProtoType *Old, SourceLocation OldLoc,
437 const FunctionProtoType *New, SourceLocation NewLoc,
438 bool *MissingExceptionSpecification,
439 bool *MissingEmptyExceptionSpecification,
440 bool AllowNoexceptAllMatchWithNoSpec, bool IsOperatorNew) {
Douglas Gregord6bc5e62010-03-24 07:14:45 +0000441 if (MissingExceptionSpecification)
442 *MissingExceptionSpecification = false;
443
Douglas Gregorf40863c2010-02-12 07:32:17 +0000444 if (MissingEmptyExceptionSpecification)
445 *MissingEmptyExceptionSpecification = false;
446
Richard Smith13b40bc2016-11-30 00:13:55 +0000447 Old = S.ResolveExceptionSpec(NewLoc, Old);
Richard Smithf623c962012-04-17 00:58:00 +0000448 if (!Old)
449 return false;
Richard Smith13b40bc2016-11-30 00:13:55 +0000450 New = S.ResolveExceptionSpec(NewLoc, New);
Richard Smithf623c962012-04-17 00:58:00 +0000451 if (!New)
452 return false;
453
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000454 // C++0x [except.spec]p3: Two exception-specifications are compatible if:
455 // - both are non-throwing, regardless of their form,
456 // - both have the form noexcept(constant-expression) and the constant-
457 // expressions are equivalent,
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000458 // - both are dynamic-exception-specifications that have the same set of
459 // adjusted types.
460 //
Eric Christophere6b7cf42015-07-10 18:25:52 +0000461 // C++0x [except.spec]p12: An exception-specification is non-throwing if it is
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000462 // of the form throw(), noexcept, or noexcept(constant-expression) where the
463 // constant-expression yields true.
464 //
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000465 // C++0x [except.spec]p4: If any declaration of a function has an exception-
466 // specifier that is not a noexcept-specification allowing all exceptions,
467 // all declarations [...] of that function shall have a compatible
468 // exception-specification.
469 //
470 // That last point basically means that noexcept(false) matches no spec.
471 // It's considered when AllowNoexceptAllMatchWithNoSpec is true.
472
473 ExceptionSpecificationType OldEST = Old->getExceptionSpecType();
474 ExceptionSpecificationType NewEST = New->getExceptionSpecType();
475
Richard Smithd3b5c9082012-07-27 04:22:15 +0000476 assert(!isUnresolvedExceptionSpec(OldEST) &&
477 !isUnresolvedExceptionSpec(NewEST) &&
Richard Smith938f40b2011-06-11 17:19:42 +0000478 "Shouldn't see unknown exception specifications here");
479
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000480 // Shortcut the case where both have no spec.
481 if (OldEST == EST_None && NewEST == EST_None)
482 return false;
483
Richard Smith13b40bc2016-11-30 00:13:55 +0000484 FunctionProtoType::NoexceptResult OldNR = Old->getNoexceptSpec(S.Context);
485 FunctionProtoType::NoexceptResult NewNR = New->getNoexceptSpec(S.Context);
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000486 if (OldNR == FunctionProtoType::NR_BadNoexcept ||
487 NewNR == FunctionProtoType::NR_BadNoexcept)
488 return false;
489
490 // Dependent noexcept specifiers are compatible with each other, but nothing
491 // else.
492 // One noexcept is compatible with another if the argument is the same
493 if (OldNR == NewNR &&
494 OldNR != FunctionProtoType::NR_NoNoexcept &&
495 NewNR != FunctionProtoType::NR_NoNoexcept)
496 return false;
497 if (OldNR != NewNR &&
498 OldNR != FunctionProtoType::NR_NoNoexcept &&
499 NewNR != FunctionProtoType::NR_NoNoexcept) {
Richard Smith13b40bc2016-11-30 00:13:55 +0000500 S.Diag(NewLoc, DiagID);
David Majnemer7da23022015-02-19 07:28:55 +0000501 if (NoteID.getDiagID() != 0 && OldLoc.isValid())
Richard Smith13b40bc2016-11-30 00:13:55 +0000502 S.Diag(OldLoc, NoteID);
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000503 return true;
Douglas Gregorf62c5292010-08-30 15:04:51 +0000504 }
505
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000506 // The MS extension throw(...) is compatible with itself.
507 if (OldEST == EST_MSAny && NewEST == EST_MSAny)
Sebastian Redl4915e632009-10-11 09:03:14 +0000508 return false;
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000509
510 // It's also compatible with no spec.
511 if ((OldEST == EST_None && NewEST == EST_MSAny) ||
512 (OldEST == EST_MSAny && NewEST == EST_None))
513 return false;
514
515 // It's also compatible with noexcept(false).
516 if (OldEST == EST_MSAny && NewNR == FunctionProtoType::NR_Throw)
517 return false;
518 if (NewEST == EST_MSAny && OldNR == FunctionProtoType::NR_Throw)
519 return false;
520
521 // As described above, noexcept(false) matches no spec only for functions.
522 if (AllowNoexceptAllMatchWithNoSpec) {
523 if (OldEST == EST_None && NewNR == FunctionProtoType::NR_Throw)
524 return false;
525 if (NewEST == EST_None && OldNR == FunctionProtoType::NR_Throw)
526 return false;
527 }
528
529 // Any non-throwing specifications are compatible.
530 bool OldNonThrowing = OldNR == FunctionProtoType::NR_Nothrow ||
531 OldEST == EST_DynamicNone;
532 bool NewNonThrowing = NewNR == FunctionProtoType::NR_Nothrow ||
533 NewEST == EST_DynamicNone;
534 if (OldNonThrowing && NewNonThrowing)
535 return false;
536
Sebastian Redlcb5dd002011-03-15 19:52:30 +0000537 // As a special compatibility feature, under C++0x we accept no spec and
538 // throw(std::bad_alloc) as equivalent for operator new and operator new[].
539 // This is because the implicit declaration changed, but old code would break.
Richard Smith13b40bc2016-11-30 00:13:55 +0000540 if (S.getLangOpts().CPlusPlus11 && IsOperatorNew) {
Craig Topperc3ec1492014-05-26 06:22:03 +0000541 const FunctionProtoType *WithExceptions = nullptr;
Sebastian Redlcb5dd002011-03-15 19:52:30 +0000542 if (OldEST == EST_None && NewEST == EST_Dynamic)
543 WithExceptions = New;
544 else if (OldEST == EST_Dynamic && NewEST == EST_None)
545 WithExceptions = Old;
546 if (WithExceptions && WithExceptions->getNumExceptions() == 1) {
547 // One has no spec, the other throw(something). If that something is
548 // std::bad_alloc, all conditions are met.
549 QualType Exception = *WithExceptions->exception_begin();
550 if (CXXRecordDecl *ExRecord = Exception->getAsCXXRecordDecl()) {
551 IdentifierInfo* Name = ExRecord->getIdentifier();
552 if (Name && Name->getName() == "bad_alloc") {
553 // It's called bad_alloc, but is it in std?
Richard Trieuc771d5d2014-05-28 02:16:01 +0000554 if (ExRecord->isInStdNamespace()) {
555 return false;
Sebastian Redlcb5dd002011-03-15 19:52:30 +0000556 }
557 }
558 }
559 }
560 }
561
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000562 // At this point, the only remaining valid case is two matching dynamic
563 // specifications. We return here unless both specifications are dynamic.
564 if (OldEST != EST_Dynamic || NewEST != EST_Dynamic) {
Douglas Gregord6bc5e62010-03-24 07:14:45 +0000565 if (MissingExceptionSpecification && Old->hasExceptionSpec() &&
Douglas Gregorf40863c2010-02-12 07:32:17 +0000566 !New->hasExceptionSpec()) {
Douglas Gregord6bc5e62010-03-24 07:14:45 +0000567 // The old type has an exception specification of some sort, but
568 // the new type does not.
569 *MissingExceptionSpecification = true;
570
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000571 if (MissingEmptyExceptionSpecification && OldNonThrowing) {
572 // The old type has a throw() or noexcept(true) exception specification
573 // and the new type has no exception specification, and the caller asked
Douglas Gregord6bc5e62010-03-24 07:14:45 +0000574 // to handle this itself.
575 *MissingEmptyExceptionSpecification = true;
576 }
577
Douglas Gregorf40863c2010-02-12 07:32:17 +0000578 return true;
579 }
580
Richard Smith13b40bc2016-11-30 00:13:55 +0000581 S.Diag(NewLoc, DiagID);
David Majnemer7da23022015-02-19 07:28:55 +0000582 if (NoteID.getDiagID() != 0 && OldLoc.isValid())
Richard Smith13b40bc2016-11-30 00:13:55 +0000583 S.Diag(OldLoc, NoteID);
Sebastian Redl4915e632009-10-11 09:03:14 +0000584 return true;
585 }
586
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000587 assert(OldEST == EST_Dynamic && NewEST == EST_Dynamic &&
588 "Exception compatibility logic error: non-dynamic spec slipped through.");
589
Sebastian Redl4915e632009-10-11 09:03:14 +0000590 bool Success = true;
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000591 // Both have a dynamic exception spec. Collect the first set, then compare
Sebastian Redl4915e632009-10-11 09:03:14 +0000592 // to the second.
Sebastian Redl184edca2009-10-14 15:06:25 +0000593 llvm::SmallPtrSet<CanQualType, 8> OldTypes, NewTypes;
Aaron Ballmanb088fbe2014-03-17 15:38:09 +0000594 for (const auto &I : Old->exceptions())
Richard Smith13b40bc2016-11-30 00:13:55 +0000595 OldTypes.insert(S.Context.getCanonicalType(I).getUnqualifiedType());
Sebastian Redl4915e632009-10-11 09:03:14 +0000596
Aaron Ballmanb088fbe2014-03-17 15:38:09 +0000597 for (const auto &I : New->exceptions()) {
Richard Smith13b40bc2016-11-30 00:13:55 +0000598 CanQualType TypePtr = S.Context.getCanonicalType(I).getUnqualifiedType();
599 if (OldTypes.count(TypePtr))
Sebastian Redl6e4c8712009-10-11 09:11:23 +0000600 NewTypes.insert(TypePtr);
601 else
602 Success = false;
603 }
Sebastian Redl4915e632009-10-11 09:03:14 +0000604
Sebastian Redl6e4c8712009-10-11 09:11:23 +0000605 Success = Success && OldTypes.size() == NewTypes.size();
Sebastian Redl4915e632009-10-11 09:03:14 +0000606
607 if (Success) {
608 return false;
609 }
Richard Smith13b40bc2016-11-30 00:13:55 +0000610 S.Diag(NewLoc, DiagID);
David Majnemer7da23022015-02-19 07:28:55 +0000611 if (NoteID.getDiagID() != 0 && OldLoc.isValid())
Richard Smith13b40bc2016-11-30 00:13:55 +0000612 S.Diag(OldLoc, NoteID);
Sebastian Redl4915e632009-10-11 09:03:14 +0000613 return true;
614}
615
Richard Smith13b40bc2016-11-30 00:13:55 +0000616bool Sema::CheckEquivalentExceptionSpec(const PartialDiagnostic &DiagID,
617 const PartialDiagnostic &NoteID,
618 const FunctionProtoType *Old,
619 SourceLocation OldLoc,
620 const FunctionProtoType *New,
621 SourceLocation NewLoc) {
622 if (!getLangOpts().CXXExceptions)
623 return false;
624 return CheckEquivalentExceptionSpecImpl(*this, DiagID, NoteID, Old, OldLoc,
625 New, NewLoc);
626}
627
Sebastian Redl4915e632009-10-11 09:03:14 +0000628/// CheckExceptionSpecSubset - Check whether the second function type's
629/// exception specification is a subset (or equivalent) of the first function
630/// type. This is used by override and pointer assignment checks.
Richard Smith1be59c52016-10-22 01:32:19 +0000631bool Sema::CheckExceptionSpecSubset(const PartialDiagnostic &DiagID,
632 const PartialDiagnostic &NestedDiagID,
633 const PartialDiagnostic &NoteID,
634 const FunctionProtoType *Superset,
635 SourceLocation SuperLoc,
636 const FunctionProtoType *Subset,
637 SourceLocation SubLoc) {
John McCallf9c94092010-05-28 08:37:35 +0000638
639 // Just auto-succeed under -fno-exceptions.
David Blaikiebbafb8a2012-03-11 07:00:24 +0000640 if (!getLangOpts().CXXExceptions)
John McCallf9c94092010-05-28 08:37:35 +0000641 return false;
642
Sebastian Redl4915e632009-10-11 09:03:14 +0000643 // FIXME: As usual, we could be more specific in our error messages, but
644 // that better waits until we've got types with source locations.
645
646 if (!SubLoc.isValid())
647 SubLoc = SuperLoc;
648
Richard Smithf623c962012-04-17 00:58:00 +0000649 // Resolve the exception specifications, if needed.
650 Superset = ResolveExceptionSpec(SuperLoc, Superset);
651 if (!Superset)
652 return false;
653 Subset = ResolveExceptionSpec(SubLoc, Subset);
654 if (!Subset)
655 return false;
656
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000657 ExceptionSpecificationType SuperEST = Superset->getExceptionSpecType();
658
Sebastian Redl4915e632009-10-11 09:03:14 +0000659 // If superset contains everything, we're done.
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000660 if (SuperEST == EST_None || SuperEST == EST_MSAny)
Richard Smith1be59c52016-10-22 01:32:19 +0000661 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
662 Subset, SubLoc);
Sebastian Redl4915e632009-10-11 09:03:14 +0000663
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000664 // If there are dependent noexcept specs, assume everything is fine. Unlike
665 // with the equivalency check, this is safe in this case, because we don't
666 // want to merge declarations. Checks after instantiation will catch any
667 // omissions we make here.
668 // We also shortcut checking if a noexcept expression was bad.
669
Sebastian Redl31ad7542011-03-13 17:09:40 +0000670 FunctionProtoType::NoexceptResult SuperNR =Superset->getNoexceptSpec(Context);
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000671 if (SuperNR == FunctionProtoType::NR_BadNoexcept ||
672 SuperNR == FunctionProtoType::NR_Dependent)
673 return false;
674
675 // Another case of the superset containing everything.
676 if (SuperNR == FunctionProtoType::NR_Throw)
Richard Smith1be59c52016-10-22 01:32:19 +0000677 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
678 Subset, SubLoc);
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000679
680 ExceptionSpecificationType SubEST = Subset->getExceptionSpecType();
681
Richard Smithd3b5c9082012-07-27 04:22:15 +0000682 assert(!isUnresolvedExceptionSpec(SuperEST) &&
683 !isUnresolvedExceptionSpec(SubEST) &&
Richard Smith938f40b2011-06-11 17:19:42 +0000684 "Shouldn't see unknown exception specifications here");
685
Sebastian Redl4915e632009-10-11 09:03:14 +0000686 // It does not. If the subset contains everything, we've failed.
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000687 if (SubEST == EST_None || SubEST == EST_MSAny) {
Sebastian Redl4915e632009-10-11 09:03:14 +0000688 Diag(SubLoc, DiagID);
Sebastian Redla44822f2009-10-14 16:09:29 +0000689 if (NoteID.getDiagID() != 0)
Sebastian Redl4915e632009-10-11 09:03:14 +0000690 Diag(SuperLoc, NoteID);
691 return true;
692 }
693
Sebastian Redl31ad7542011-03-13 17:09:40 +0000694 FunctionProtoType::NoexceptResult SubNR = Subset->getNoexceptSpec(Context);
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000695 if (SubNR == FunctionProtoType::NR_BadNoexcept ||
696 SubNR == FunctionProtoType::NR_Dependent)
697 return false;
698
699 // Another case of the subset containing everything.
700 if (SubNR == FunctionProtoType::NR_Throw) {
701 Diag(SubLoc, DiagID);
702 if (NoteID.getDiagID() != 0)
703 Diag(SuperLoc, NoteID);
704 return true;
705 }
706
707 // If the subset contains nothing, we're done.
708 if (SubEST == EST_DynamicNone || SubNR == FunctionProtoType::NR_Nothrow)
Richard Smith1be59c52016-10-22 01:32:19 +0000709 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
710 Subset, SubLoc);
Sebastian Redlfa453cf2011-03-12 11:50:43 +0000711
712 // Otherwise, if the superset contains nothing, we've failed.
713 if (SuperEST == EST_DynamicNone || SuperNR == FunctionProtoType::NR_Nothrow) {
714 Diag(SubLoc, DiagID);
715 if (NoteID.getDiagID() != 0)
716 Diag(SuperLoc, NoteID);
717 return true;
718 }
719
720 assert(SuperEST == EST_Dynamic && SubEST == EST_Dynamic &&
721 "Exception spec subset: non-dynamic case slipped through.");
722
723 // Neither contains everything or nothing. Do a proper comparison.
Aaron Ballmanb088fbe2014-03-17 15:38:09 +0000724 for (const auto &SubI : Subset->exceptions()) {
Sebastian Redl4915e632009-10-11 09:03:14 +0000725 // Take one type from the subset.
Aaron Ballmanb088fbe2014-03-17 15:38:09 +0000726 QualType CanonicalSubT = Context.getCanonicalType(SubI);
Sebastian Redl075b21d2009-10-14 14:38:54 +0000727 // Unwrap pointers and references so that we can do checks within a class
728 // hierarchy. Don't unwrap member pointers; they don't have hierarchy
729 // conversions on the pointee.
Sebastian Redl4915e632009-10-11 09:03:14 +0000730 bool SubIsPointer = false;
731 if (const ReferenceType *RefTy = CanonicalSubT->getAs<ReferenceType>())
732 CanonicalSubT = RefTy->getPointeeType();
733 if (const PointerType *PtrTy = CanonicalSubT->getAs<PointerType>()) {
734 CanonicalSubT = PtrTy->getPointeeType();
735 SubIsPointer = true;
736 }
737 bool SubIsClass = CanonicalSubT->isRecordType();
Douglas Gregor1b8fe5b72009-11-16 21:35:15 +0000738 CanonicalSubT = CanonicalSubT.getLocalUnqualifiedType();
Sebastian Redl4915e632009-10-11 09:03:14 +0000739
740 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
741 /*DetectVirtual=*/false);
742
743 bool Contained = false;
744 // Make sure it's in the superset.
Aaron Ballmanb088fbe2014-03-17 15:38:09 +0000745 for (const auto &SuperI : Superset->exceptions()) {
746 QualType CanonicalSuperT = Context.getCanonicalType(SuperI);
Sebastian Redl4915e632009-10-11 09:03:14 +0000747 // SubT must be SuperT or derived from it, or pointer or reference to
748 // such types.
749 if (const ReferenceType *RefTy = CanonicalSuperT->getAs<ReferenceType>())
750 CanonicalSuperT = RefTy->getPointeeType();
751 if (SubIsPointer) {
752 if (const PointerType *PtrTy = CanonicalSuperT->getAs<PointerType>())
753 CanonicalSuperT = PtrTy->getPointeeType();
754 else {
755 continue;
756 }
757 }
Douglas Gregor1b8fe5b72009-11-16 21:35:15 +0000758 CanonicalSuperT = CanonicalSuperT.getLocalUnqualifiedType();
Sebastian Redl4915e632009-10-11 09:03:14 +0000759 // If the types are the same, move on to the next type in the subset.
760 if (CanonicalSubT == CanonicalSuperT) {
761 Contained = true;
762 break;
763 }
764
765 // Otherwise we need to check the inheritance.
766 if (!SubIsClass || !CanonicalSuperT->isRecordType())
767 continue;
768
769 Paths.clear();
Richard Smith0f59cb32015-12-18 21:45:41 +0000770 if (!IsDerivedFrom(SubLoc, CanonicalSubT, CanonicalSuperT, Paths))
Sebastian Redl4915e632009-10-11 09:03:14 +0000771 continue;
772
Douglas Gregor27ac4292010-05-21 20:29:55 +0000773 if (Paths.isAmbiguous(Context.getCanonicalType(CanonicalSuperT)))
Sebastian Redl4915e632009-10-11 09:03:14 +0000774 continue;
775
John McCall5b0829a2010-02-10 09:31:12 +0000776 // Do this check from a context without privileges.
John McCall1064d7e2010-03-16 05:22:47 +0000777 switch (CheckBaseClassAccess(SourceLocation(),
John McCall5b0829a2010-02-10 09:31:12 +0000778 CanonicalSuperT, CanonicalSubT,
779 Paths.front(),
John McCall1064d7e2010-03-16 05:22:47 +0000780 /*Diagnostic*/ 0,
John McCall5b0829a2010-02-10 09:31:12 +0000781 /*ForceCheck*/ true,
John McCall1064d7e2010-03-16 05:22:47 +0000782 /*ForceUnprivileged*/ true)) {
John McCall5b0829a2010-02-10 09:31:12 +0000783 case AR_accessible: break;
784 case AR_inaccessible: continue;
785 case AR_dependent:
786 llvm_unreachable("access check dependent for unprivileged context");
John McCall5b0829a2010-02-10 09:31:12 +0000787 case AR_delayed:
788 llvm_unreachable("access check delayed in non-declaration");
John McCall5b0829a2010-02-10 09:31:12 +0000789 }
Sebastian Redl4915e632009-10-11 09:03:14 +0000790
791 Contained = true;
792 break;
793 }
794 if (!Contained) {
795 Diag(SubLoc, DiagID);
Sebastian Redla44822f2009-10-14 16:09:29 +0000796 if (NoteID.getDiagID() != 0)
Sebastian Redl4915e632009-10-11 09:03:14 +0000797 Diag(SuperLoc, NoteID);
798 return true;
799 }
800 }
801 // We've run half the gauntlet.
Richard Smith1be59c52016-10-22 01:32:19 +0000802 return CheckParamExceptionSpec(NestedDiagID, NoteID, Superset, SuperLoc,
803 Subset, SubLoc);
Sebastian Redl4915e632009-10-11 09:03:14 +0000804}
805
Richard Smith1be59c52016-10-22 01:32:19 +0000806static bool
807CheckSpecForTypesEquivalent(Sema &S, const PartialDiagnostic &DiagID,
808 const PartialDiagnostic &NoteID, QualType Target,
809 SourceLocation TargetLoc, QualType Source,
810 SourceLocation SourceLoc) {
Sebastian Redl4915e632009-10-11 09:03:14 +0000811 const FunctionProtoType *TFunc = GetUnderlyingFunction(Target);
812 if (!TFunc)
813 return false;
814 const FunctionProtoType *SFunc = GetUnderlyingFunction(Source);
815 if (!SFunc)
816 return false;
817
818 return S.CheckEquivalentExceptionSpec(DiagID, NoteID, TFunc, TargetLoc,
819 SFunc, SourceLoc);
820}
821
822/// CheckParamExceptionSpec - Check if the parameter and return types of the
823/// two functions have equivalent exception specs. This is part of the
824/// assignment and override compatibility check. We do not check the parameters
825/// of parameter function pointers recursively, as no sane programmer would
826/// even be able to write such a function type.
Richard Smith1be59c52016-10-22 01:32:19 +0000827bool Sema::CheckParamExceptionSpec(const PartialDiagnostic &DiagID,
828 const PartialDiagnostic &NoteID,
Richard Smith2e321552014-11-12 02:00:47 +0000829 const FunctionProtoType *Target,
830 SourceLocation TargetLoc,
831 const FunctionProtoType *Source,
832 SourceLocation SourceLoc) {
Richard Smith1be59c52016-10-22 01:32:19 +0000833 auto RetDiag = DiagID;
834 RetDiag << 0;
Alp Toker314cc812014-01-25 16:55:45 +0000835 if (CheckSpecForTypesEquivalent(
Richard Smith1be59c52016-10-22 01:32:19 +0000836 *this, RetDiag, PDiag(),
Alp Toker314cc812014-01-25 16:55:45 +0000837 Target->getReturnType(), TargetLoc, Source->getReturnType(),
838 SourceLoc))
Sebastian Redl4915e632009-10-11 09:03:14 +0000839 return true;
840
Sebastian Redla44822f2009-10-14 16:09:29 +0000841 // We shouldn't even be testing this unless the arguments are otherwise
Sebastian Redl4915e632009-10-11 09:03:14 +0000842 // compatible.
Alp Toker9cacbab2014-01-20 20:26:09 +0000843 assert(Target->getNumParams() == Source->getNumParams() &&
Sebastian Redl4915e632009-10-11 09:03:14 +0000844 "Functions have different argument counts.");
Alp Toker9cacbab2014-01-20 20:26:09 +0000845 for (unsigned i = 0, E = Target->getNumParams(); i != E; ++i) {
Richard Smith1be59c52016-10-22 01:32:19 +0000846 auto ParamDiag = DiagID;
847 ParamDiag << 1;
Alp Toker9cacbab2014-01-20 20:26:09 +0000848 if (CheckSpecForTypesEquivalent(
Richard Smith1be59c52016-10-22 01:32:19 +0000849 *this, ParamDiag, PDiag(),
Alp Toker9cacbab2014-01-20 20:26:09 +0000850 Target->getParamType(i), TargetLoc, Source->getParamType(i),
851 SourceLoc))
Sebastian Redl4915e632009-10-11 09:03:14 +0000852 return true;
853 }
854 return false;
855}
856
Richard Smith2e321552014-11-12 02:00:47 +0000857bool Sema::CheckExceptionSpecCompatibility(Expr *From, QualType ToType) {
Sebastian Redl4915e632009-10-11 09:03:14 +0000858 // First we check for applicability.
859 // Target type must be a function, function pointer or function reference.
860 const FunctionProtoType *ToFunc = GetUnderlyingFunction(ToType);
Richard Smith2e321552014-11-12 02:00:47 +0000861 if (!ToFunc || ToFunc->hasDependentExceptionSpec())
Sebastian Redl4915e632009-10-11 09:03:14 +0000862 return false;
863
864 // SourceType must be a function or function pointer.
865 const FunctionProtoType *FromFunc = GetUnderlyingFunction(From->getType());
Richard Smith2e321552014-11-12 02:00:47 +0000866 if (!FromFunc || FromFunc->hasDependentExceptionSpec())
Sebastian Redl4915e632009-10-11 09:03:14 +0000867 return false;
868
Richard Smith1be59c52016-10-22 01:32:19 +0000869 unsigned DiagID = diag::err_incompatible_exception_specs;
870 unsigned NestedDiagID = diag::err_deep_exception_specs_differ;
871 // This is not an error in C++17 onwards, unless the noexceptness doesn't
872 // match, but in that case we have a full-on type mismatch, not just a
873 // type sugar mismatch.
874 if (getLangOpts().CPlusPlus1z) {
875 DiagID = diag::warn_incompatible_exception_specs;
876 NestedDiagID = diag::warn_deep_exception_specs_differ;
877 }
878
Sebastian Redl4915e632009-10-11 09:03:14 +0000879 // Now we've got the correct types on both sides, check their compatibility.
880 // This means that the source of the conversion can only throw a subset of
881 // the exceptions of the target, and any exception specs on arguments or
882 // return types must be equivalent.
Richard Smith2e321552014-11-12 02:00:47 +0000883 //
884 // FIXME: If there is a nested dependent exception specification, we should
885 // not be checking it here. This is fine:
886 // template<typename T> void f() {
887 // void (*p)(void (*) throw(T));
888 // void (*q)(void (*) throw(int)) = p;
889 // }
890 // ... because it might be instantiated with T=int.
Richard Smith1be59c52016-10-22 01:32:19 +0000891 return CheckExceptionSpecSubset(PDiag(DiagID), PDiag(NestedDiagID), PDiag(),
892 ToFunc, From->getSourceRange().getBegin(),
893 FromFunc, SourceLocation()) &&
894 !getLangOpts().CPlusPlus1z;
Sebastian Redl4915e632009-10-11 09:03:14 +0000895}
896
897bool Sema::CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New,
898 const CXXMethodDecl *Old) {
Richard Smith88f45492014-11-22 03:09:05 +0000899 // If the new exception specification hasn't been parsed yet, skip the check.
900 // We'll get called again once it's been parsed.
901 if (New->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() ==
902 EST_Unparsed)
903 return false;
Richard Smith2bf7fdb2013-01-02 11:42:31 +0000904 if (getLangOpts().CPlusPlus11 && isa<CXXDestructorDecl>(New)) {
Sebastian Redl645d9582011-05-20 05:57:18 +0000905 // Don't check uninstantiated template destructors at all. We can only
906 // synthesize correct specs after the template is instantiated.
907 if (New->getParent()->isDependentType())
908 return false;
909 if (New->getParent()->isBeingDefined()) {
910 // The destructor might be updated once the definition is finished. So
911 // remember it and check later.
Richard Smith88f45492014-11-22 03:09:05 +0000912 DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old));
Sebastian Redl645d9582011-05-20 05:57:18 +0000913 return false;
914 }
Sebastian Redl623ea822011-05-19 05:13:44 +0000915 }
Richard Smith88f45492014-11-22 03:09:05 +0000916 // If the old exception specification hasn't been parsed yet, remember that
917 // we need to perform this check when we get to the end of the outermost
918 // lexically-surrounding class.
919 if (Old->getType()->castAs<FunctionProtoType>()->getExceptionSpecType() ==
920 EST_Unparsed) {
921 DelayedExceptionSpecChecks.push_back(std::make_pair(New, Old));
Richard Smith0b3a4622014-11-13 20:01:57 +0000922 return false;
Richard Smith88f45492014-11-22 03:09:05 +0000923 }
Francois Picheta8032e92011-05-24 02:11:43 +0000924 unsigned DiagID = diag::err_override_exception_spec;
David Blaikiebbafb8a2012-03-11 07:00:24 +0000925 if (getLangOpts().MicrosoftExt)
Richard Smith1b98ccc2014-07-19 01:39:17 +0000926 DiagID = diag::ext_override_exception_spec;
Francois Picheta8032e92011-05-24 02:11:43 +0000927 return CheckExceptionSpecSubset(PDiag(DiagID),
Richard Smith1be59c52016-10-22 01:32:19 +0000928 PDiag(diag::err_deep_exception_specs_differ),
Douglas Gregor89336232010-03-29 23:34:08 +0000929 PDiag(diag::note_overridden_virtual_function),
Sebastian Redl4915e632009-10-11 09:03:14 +0000930 Old->getType()->getAs<FunctionProtoType>(),
931 Old->getLocation(),
932 New->getType()->getAs<FunctionProtoType>(),
933 New->getLocation());
934}
935
Benjamin Kramer642f1732015-07-02 21:03:14 +0000936static CanThrowResult canSubExprsThrow(Sema &S, const Expr *E) {
Richard Smithf623c962012-04-17 00:58:00 +0000937 CanThrowResult R = CT_Cannot;
Benjamin Kramer642f1732015-07-02 21:03:14 +0000938 for (const Stmt *SubStmt : E->children()) {
939 R = mergeCanThrow(R, S.canThrow(cast<Expr>(SubStmt)));
940 if (R == CT_Can)
941 break;
942 }
Richard Smithf623c962012-04-17 00:58:00 +0000943 return R;
944}
945
Eli Friedman0423b762013-06-25 01:24:22 +0000946static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D) {
Richard Smithf623c962012-04-17 00:58:00 +0000947 // As an extension, we assume that __attribute__((nothrow)) functions don't
948 // throw.
Richard Smith3a8f13a2016-12-03 00:29:06 +0000949 if (D && isa<FunctionDecl>(D) && D->hasAttr<NoThrowAttr>())
Richard Smithf623c962012-04-17 00:58:00 +0000950 return CT_Cannot;
951
Richard Smith3a8f13a2016-12-03 00:29:06 +0000952 QualType T;
953
954 // In C++1z, just look at the function type of the callee.
955 if (S.getLangOpts().CPlusPlus1z && isa<CallExpr>(E)) {
956 E = cast<CallExpr>(E)->getCallee();
957 T = E->getType();
958 if (T->isSpecificPlaceholderType(BuiltinType::BoundMember)) {
959 // Sadly we don't preserve the actual type as part of the "bound member"
960 // placeholder, so we need to reconstruct it.
961 E = E->IgnoreParenImpCasts();
962
963 // Could be a call to a pointer-to-member or a plain member access.
964 if (auto *Op = dyn_cast<BinaryOperator>(E)) {
965 assert(Op->getOpcode() == BO_PtrMemD || Op->getOpcode() == BO_PtrMemI);
966 T = Op->getRHS()->getType()
967 ->castAs<MemberPointerType>()->getPointeeType();
968 } else {
969 T = cast<MemberExpr>(E)->getMemberDecl()->getType();
970 }
971 }
972 } else if (const ValueDecl *VD = dyn_cast_or_null<ValueDecl>(D))
973 T = VD->getType();
974 else
975 // If we have no clue what we're calling, assume the worst.
976 return CT_Can;
977
Richard Smithf623c962012-04-17 00:58:00 +0000978 const FunctionProtoType *FT;
979 if ((FT = T->getAs<FunctionProtoType>())) {
980 } else if (const PointerType *PT = T->getAs<PointerType>())
981 FT = PT->getPointeeType()->getAs<FunctionProtoType>();
982 else if (const ReferenceType *RT = T->getAs<ReferenceType>())
983 FT = RT->getPointeeType()->getAs<FunctionProtoType>();
984 else if (const MemberPointerType *MT = T->getAs<MemberPointerType>())
985 FT = MT->getPointeeType()->getAs<FunctionProtoType>();
986 else if (const BlockPointerType *BT = T->getAs<BlockPointerType>())
987 FT = BT->getPointeeType()->getAs<FunctionProtoType>();
988
989 if (!FT)
990 return CT_Can;
991
992 FT = S.ResolveExceptionSpec(E->getLocStart(), FT);
993 if (!FT)
994 return CT_Can;
995
Richard Smithf623c962012-04-17 00:58:00 +0000996 return FT->isNothrow(S.Context) ? CT_Cannot : CT_Can;
997}
998
999static CanThrowResult canDynamicCastThrow(const CXXDynamicCastExpr *DC) {
1000 if (DC->isTypeDependent())
1001 return CT_Dependent;
1002
1003 if (!DC->getTypeAsWritten()->isReferenceType())
1004 return CT_Cannot;
1005
1006 if (DC->getSubExpr()->isTypeDependent())
1007 return CT_Dependent;
1008
1009 return DC->getCastKind() == clang::CK_Dynamic? CT_Can : CT_Cannot;
1010}
1011
1012static CanThrowResult canTypeidThrow(Sema &S, const CXXTypeidExpr *DC) {
1013 if (DC->isTypeOperand())
1014 return CT_Cannot;
1015
1016 Expr *Op = DC->getExprOperand();
1017 if (Op->isTypeDependent())
1018 return CT_Dependent;
1019
1020 const RecordType *RT = Op->getType()->getAs<RecordType>();
1021 if (!RT)
1022 return CT_Cannot;
1023
1024 if (!cast<CXXRecordDecl>(RT->getDecl())->isPolymorphic())
1025 return CT_Cannot;
1026
1027 if (Op->Classify(S.Context).isPRValue())
1028 return CT_Cannot;
1029
1030 return CT_Can;
1031}
1032
1033CanThrowResult Sema::canThrow(const Expr *E) {
1034 // C++ [expr.unary.noexcept]p3:
1035 // [Can throw] if in a potentially-evaluated context the expression would
1036 // contain:
1037 switch (E->getStmtClass()) {
1038 case Expr::CXXThrowExprClass:
1039 // - a potentially evaluated throw-expression
1040 return CT_Can;
1041
1042 case Expr::CXXDynamicCastExprClass: {
1043 // - a potentially evaluated dynamic_cast expression dynamic_cast<T>(v),
1044 // where T is a reference type, that requires a run-time check
1045 CanThrowResult CT = canDynamicCastThrow(cast<CXXDynamicCastExpr>(E));
1046 if (CT == CT_Can)
1047 return CT;
1048 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1049 }
1050
1051 case Expr::CXXTypeidExprClass:
1052 // - a potentially evaluated typeid expression applied to a glvalue
1053 // expression whose type is a polymorphic class type
1054 return canTypeidThrow(*this, cast<CXXTypeidExpr>(E));
1055
1056 // - a potentially evaluated call to a function, member function, function
1057 // pointer, or member function pointer that does not have a non-throwing
1058 // exception-specification
1059 case Expr::CallExprClass:
1060 case Expr::CXXMemberCallExprClass:
1061 case Expr::CXXOperatorCallExprClass:
1062 case Expr::UserDefinedLiteralClass: {
1063 const CallExpr *CE = cast<CallExpr>(E);
1064 CanThrowResult CT;
1065 if (E->isTypeDependent())
1066 CT = CT_Dependent;
1067 else if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens()))
1068 CT = CT_Cannot;
Eli Friedman5a8738f2013-06-25 01:55:41 +00001069 else
Richard Smith3a8f13a2016-12-03 00:29:06 +00001070 CT = canCalleeThrow(*this, E, CE->getCalleeDecl());
Richard Smithf623c962012-04-17 00:58:00 +00001071 if (CT == CT_Can)
1072 return CT;
1073 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1074 }
1075
1076 case Expr::CXXConstructExprClass:
1077 case Expr::CXXTemporaryObjectExprClass: {
1078 CanThrowResult CT = canCalleeThrow(*this, E,
1079 cast<CXXConstructExpr>(E)->getConstructor());
1080 if (CT == CT_Can)
1081 return CT;
1082 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1083 }
1084
Richard Smith5179eb72016-06-28 19:03:57 +00001085 case Expr::CXXInheritedCtorInitExprClass:
1086 return canCalleeThrow(*this, E,
1087 cast<CXXInheritedCtorInitExpr>(E)->getConstructor());
1088
Richard Smithf623c962012-04-17 00:58:00 +00001089 case Expr::LambdaExprClass: {
1090 const LambdaExpr *Lambda = cast<LambdaExpr>(E);
1091 CanThrowResult CT = CT_Cannot;
James Y Knight53c76162015-07-17 18:21:37 +00001092 for (LambdaExpr::const_capture_init_iterator
1093 Cap = Lambda->capture_init_begin(),
1094 CapEnd = Lambda->capture_init_end();
Richard Smithf623c962012-04-17 00:58:00 +00001095 Cap != CapEnd; ++Cap)
1096 CT = mergeCanThrow(CT, canThrow(*Cap));
1097 return CT;
1098 }
1099
1100 case Expr::CXXNewExprClass: {
1101 CanThrowResult CT;
1102 if (E->isTypeDependent())
1103 CT = CT_Dependent;
1104 else
1105 CT = canCalleeThrow(*this, E, cast<CXXNewExpr>(E)->getOperatorNew());
1106 if (CT == CT_Can)
1107 return CT;
1108 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1109 }
1110
1111 case Expr::CXXDeleteExprClass: {
1112 CanThrowResult CT;
1113 QualType DTy = cast<CXXDeleteExpr>(E)->getDestroyedType();
1114 if (DTy.isNull() || DTy->isDependentType()) {
1115 CT = CT_Dependent;
1116 } else {
1117 CT = canCalleeThrow(*this, E,
1118 cast<CXXDeleteExpr>(E)->getOperatorDelete());
1119 if (const RecordType *RT = DTy->getAs<RecordType>()) {
1120 const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
Eli Friedman0423b762013-06-25 01:24:22 +00001121 const CXXDestructorDecl *DD = RD->getDestructor();
1122 if (DD)
1123 CT = mergeCanThrow(CT, canCalleeThrow(*this, E, DD));
Richard Smithf623c962012-04-17 00:58:00 +00001124 }
1125 if (CT == CT_Can)
1126 return CT;
1127 }
1128 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1129 }
1130
1131 case Expr::CXXBindTemporaryExprClass: {
1132 // The bound temporary has to be destroyed again, which might throw.
1133 CanThrowResult CT = canCalleeThrow(*this, E,
1134 cast<CXXBindTemporaryExpr>(E)->getTemporary()->getDestructor());
1135 if (CT == CT_Can)
1136 return CT;
1137 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1138 }
1139
1140 // ObjC message sends are like function calls, but never have exception
1141 // specs.
1142 case Expr::ObjCMessageExprClass:
1143 case Expr::ObjCPropertyRefExprClass:
1144 case Expr::ObjCSubscriptRefExprClass:
1145 return CT_Can;
1146
1147 // All the ObjC literals that are implemented as calls are
1148 // potentially throwing unless we decide to close off that
1149 // possibility.
1150 case Expr::ObjCArrayLiteralClass:
1151 case Expr::ObjCDictionaryLiteralClass:
Patrick Beard0caa3942012-04-19 00:25:12 +00001152 case Expr::ObjCBoxedExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001153 return CT_Can;
1154
1155 // Many other things have subexpressions, so we have to test those.
1156 // Some are simple:
Richard Smith9f690bd2015-10-27 06:02:45 +00001157 case Expr::CoawaitExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001158 case Expr::ConditionalOperatorClass:
1159 case Expr::CompoundLiteralExprClass:
Richard Smith9f690bd2015-10-27 06:02:45 +00001160 case Expr::CoyieldExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001161 case Expr::CXXConstCastExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001162 case Expr::CXXReinterpretCastExprClass:
Richard Smithcc1b96d2013-06-12 22:31:48 +00001163 case Expr::CXXStdInitializerListExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001164 case Expr::DesignatedInitExprClass:
Yunzhong Gaocb779302015-06-10 00:27:52 +00001165 case Expr::DesignatedInitUpdateExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001166 case Expr::ExprWithCleanupsClass:
1167 case Expr::ExtVectorElementExprClass:
1168 case Expr::InitListExprClass:
1169 case Expr::MemberExprClass:
1170 case Expr::ObjCIsaExprClass:
1171 case Expr::ObjCIvarRefExprClass:
1172 case Expr::ParenExprClass:
1173 case Expr::ParenListExprClass:
1174 case Expr::ShuffleVectorExprClass:
Hal Finkelc4d7c822013-09-18 03:29:45 +00001175 case Expr::ConvertVectorExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001176 case Expr::VAArgExprClass:
1177 return canSubExprsThrow(*this, E);
1178
1179 // Some might be dependent for other reasons.
1180 case Expr::ArraySubscriptExprClass:
Alexey Bataev1a3320e2015-08-25 14:24:04 +00001181 case Expr::OMPArraySectionExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001182 case Expr::BinaryOperatorClass:
1183 case Expr::CompoundAssignOperatorClass:
1184 case Expr::CStyleCastExprClass:
1185 case Expr::CXXStaticCastExprClass:
1186 case Expr::CXXFunctionalCastExprClass:
1187 case Expr::ImplicitCastExprClass:
1188 case Expr::MaterializeTemporaryExprClass:
1189 case Expr::UnaryOperatorClass: {
1190 CanThrowResult CT = E->isTypeDependent() ? CT_Dependent : CT_Cannot;
1191 return mergeCanThrow(CT, canSubExprsThrow(*this, E));
1192 }
1193
1194 // FIXME: We should handle StmtExpr, but that opens a MASSIVE can of worms.
1195 case Expr::StmtExprClass:
1196 return CT_Can;
1197
Richard Smith852c9db2013-04-20 22:23:05 +00001198 case Expr::CXXDefaultArgExprClass:
1199 return canThrow(cast<CXXDefaultArgExpr>(E)->getExpr());
1200
1201 case Expr::CXXDefaultInitExprClass:
1202 return canThrow(cast<CXXDefaultInitExpr>(E)->getExpr());
1203
Richard Smithf623c962012-04-17 00:58:00 +00001204 case Expr::ChooseExprClass:
1205 if (E->isTypeDependent() || E->isValueDependent())
1206 return CT_Dependent;
Eli Friedman75807f22013-07-20 00:40:58 +00001207 return canThrow(cast<ChooseExpr>(E)->getChosenSubExpr());
Richard Smithf623c962012-04-17 00:58:00 +00001208
1209 case Expr::GenericSelectionExprClass:
1210 if (cast<GenericSelectionExpr>(E)->isResultDependent())
1211 return CT_Dependent;
1212 return canThrow(cast<GenericSelectionExpr>(E)->getResultExpr());
1213
1214 // Some expressions are always dependent.
1215 case Expr::CXXDependentScopeMemberExprClass:
1216 case Expr::CXXUnresolvedConstructExprClass:
1217 case Expr::DependentScopeDeclRefExprClass:
Richard Smith0f0af192014-11-08 05:07:16 +00001218 case Expr::CXXFoldExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001219 return CT_Dependent;
1220
1221 case Expr::AsTypeExprClass:
1222 case Expr::BinaryConditionalOperatorClass:
1223 case Expr::BlockExprClass:
1224 case Expr::CUDAKernelCallExprClass:
1225 case Expr::DeclRefExprClass:
1226 case Expr::ObjCBridgedCastExprClass:
1227 case Expr::ObjCIndirectCopyRestoreExprClass:
1228 case Expr::ObjCProtocolExprClass:
1229 case Expr::ObjCSelectorExprClass:
Erik Pilkington29099de2016-07-16 00:35:23 +00001230 case Expr::ObjCAvailabilityCheckExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001231 case Expr::OffsetOfExprClass:
1232 case Expr::PackExpansionExprClass:
1233 case Expr::PseudoObjectExprClass:
1234 case Expr::SubstNonTypeTemplateParmExprClass:
1235 case Expr::SubstNonTypeTemplateParmPackExprClass:
Richard Smithb15fe3a2012-09-12 00:56:43 +00001236 case Expr::FunctionParmPackExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001237 case Expr::UnaryExprOrTypeTraitExprClass:
1238 case Expr::UnresolvedLookupExprClass:
1239 case Expr::UnresolvedMemberExprClass:
Kaelyn Takatae1f49d52014-10-27 18:07:20 +00001240 case Expr::TypoExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001241 // FIXME: Can any of the above throw? If so, when?
1242 return CT_Cannot;
1243
1244 case Expr::AddrLabelExprClass:
1245 case Expr::ArrayTypeTraitExprClass:
1246 case Expr::AtomicExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001247 case Expr::TypeTraitExprClass:
1248 case Expr::CXXBoolLiteralExprClass:
1249 case Expr::CXXNoexceptExprClass:
1250 case Expr::CXXNullPtrLiteralExprClass:
1251 case Expr::CXXPseudoDestructorExprClass:
1252 case Expr::CXXScalarValueInitExprClass:
1253 case Expr::CXXThisExprClass:
1254 case Expr::CXXUuidofExprClass:
1255 case Expr::CharacterLiteralClass:
1256 case Expr::ExpressionTraitExprClass:
1257 case Expr::FloatingLiteralClass:
1258 case Expr::GNUNullExprClass:
1259 case Expr::ImaginaryLiteralClass:
1260 case Expr::ImplicitValueInitExprClass:
1261 case Expr::IntegerLiteralClass:
Yunzhong Gaocb779302015-06-10 00:27:52 +00001262 case Expr::NoInitExprClass:
Richard Smithf623c962012-04-17 00:58:00 +00001263 case Expr::ObjCEncodeExprClass:
1264 case Expr::ObjCStringLiteralClass:
1265 case Expr::ObjCBoolLiteralExprClass:
1266 case Expr::OpaqueValueExprClass:
1267 case Expr::PredefinedExprClass:
1268 case Expr::SizeOfPackExprClass:
1269 case Expr::StringLiteralClass:
Richard Smithf623c962012-04-17 00:58:00 +00001270 // These expressions can never throw.
1271 return CT_Cannot;
1272
John McCall5e77d762013-04-16 07:28:30 +00001273 case Expr::MSPropertyRefExprClass:
Alexey Bataevf7630272015-11-25 12:01:00 +00001274 case Expr::MSPropertySubscriptExprClass:
John McCall5e77d762013-04-16 07:28:30 +00001275 llvm_unreachable("Invalid class for expression");
1276
Richard Smithf623c962012-04-17 00:58:00 +00001277#define STMT(CLASS, PARENT) case Expr::CLASS##Class:
1278#define STMT_RANGE(Base, First, Last)
1279#define LAST_STMT_RANGE(BASE, FIRST, LAST)
1280#define EXPR(CLASS, PARENT)
1281#define ABSTRACT_STMT(STMT)
1282#include "clang/AST/StmtNodes.inc"
1283 case Expr::NoStmtClass:
1284 llvm_unreachable("Invalid class for expression");
1285 }
1286 llvm_unreachable("Bogus StmtClass");
1287}
1288
Sebastian Redl4915e632009-10-11 09:03:14 +00001289} // end namespace clang