Coverage Report

Created: 2021-01-26 06:56

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