Coverage Report

Created: 2022-07-16 07:03

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