Coverage Report

Created: 2021-09-21 08:58

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