Bug Summary

File:clang/lib/Sema/SemaExceptionSpec.cpp
Warning:line 1043, column 49
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaExceptionSpec.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaExceptionSpec.cpp

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/lib/Sema/SemaExceptionSpec.cpp

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

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h

1//===- SourceLocation.h - Compact identifier for Source Files ---*- 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/// \file
10/// Defines the clang::SourceLocation class and associated facilities.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_BASIC_SOURCELOCATION_H
15#define LLVM_CLANG_BASIC_SOURCELOCATION_H
16
17#include "clang/Basic/LLVM.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Support/PointerLikeTypeTraits.h"
20#include <cassert>
21#include <cstdint>
22#include <string>
23#include <utility>
24
25namespace llvm {
26
27template <typename T> struct DenseMapInfo;
28
29} // namespace llvm
30
31namespace clang {
32
33class SourceManager;
34
35/// An opaque identifier used by SourceManager which refers to a
36/// source file (MemoryBuffer) along with its \#include path and \#line data.
37///
38class FileID {
39 /// A mostly-opaque identifier, where 0 is "invalid", >0 is
40 /// this module, and <-1 is something loaded from another module.
41 int ID = 0;
42
43public:
44 bool isValid() const { return ID != 0; }
45 bool isInvalid() const { return ID == 0; }
46
47 bool operator==(const FileID &RHS) const { return ID == RHS.ID; }
48 bool operator<(const FileID &RHS) const { return ID < RHS.ID; }
49 bool operator<=(const FileID &RHS) const { return ID <= RHS.ID; }
50 bool operator!=(const FileID &RHS) const { return !(*this == RHS); }
51 bool operator>(const FileID &RHS) const { return RHS < *this; }
52 bool operator>=(const FileID &RHS) const { return RHS <= *this; }
53
54 static FileID getSentinel() { return get(-1); }
55 unsigned getHashValue() const { return static_cast<unsigned>(ID); }
56
57private:
58 friend class ASTWriter;
59 friend class ASTReader;
60 friend class SourceManager;
61
62 static FileID get(int V) {
63 FileID F;
64 F.ID = V;
65 return F;
66 }
67
68 int getOpaqueValue() const { return ID; }
69};
70
71/// Encodes a location in the source. The SourceManager can decode this
72/// to get at the full include stack, line and column information.
73///
74/// Technically, a source location is simply an offset into the manager's view
75/// of the input source, which is all input buffers (including macro
76/// expansions) concatenated in an effectively arbitrary order. The manager
77/// actually maintains two blocks of input buffers. One, starting at offset
78/// 0 and growing upwards, contains all buffers from this module. The other,
79/// starting at the highest possible offset and growing downwards, contains
80/// buffers of loaded modules.
81///
82/// In addition, one bit of SourceLocation is used for quick access to the
83/// information whether the location is in a file or a macro expansion.
84///
85/// It is important that this type remains small. It is currently 32 bits wide.
86class SourceLocation {
87 friend class ASTReader;
88 friend class ASTWriter;
89 friend class SourceManager;
90
91 unsigned ID = 0;
92
93 enum : unsigned {
94 MacroIDBit = 1U << 31
95 };
96
97public:
98 bool isFileID() const { return (ID & MacroIDBit) == 0; }
99 bool isMacroID() const { return (ID & MacroIDBit) != 0; }
100
101 /// Return true if this is a valid SourceLocation object.
102 ///
103 /// Invalid SourceLocations are often used when events have no corresponding
104 /// location in the source (e.g. a diagnostic is required for a command line
105 /// option).
106 bool isValid() const { return ID != 0; }
107 bool isInvalid() const { return ID == 0; }
55
Assuming field 'ID' is equal to 0
56
Returning the value 1, which participates in a condition later
108
109private:
110 /// Return the offset into the manager's global input view.
111 unsigned getOffset() const {
112 return ID & ~MacroIDBit;
113 }
114
115 static SourceLocation getFileLoc(unsigned ID) {
116 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!")(((ID & MacroIDBit) == 0 && "Ran out of source locations!"
) ? static_cast<void> (0) : __assert_fail ("(ID & MacroIDBit) == 0 && \"Ran out of source locations!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 116, __PRETTY_FUNCTION__))
;
117 SourceLocation L;
118 L.ID = ID;
119 return L;
120 }
121
122 static SourceLocation getMacroLoc(unsigned ID) {
123 assert((ID & MacroIDBit) == 0 && "Ran out of source locations!")(((ID & MacroIDBit) == 0 && "Ran out of source locations!"
) ? static_cast<void> (0) : __assert_fail ("(ID & MacroIDBit) == 0 && \"Ran out of source locations!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 123, __PRETTY_FUNCTION__))
;
124 SourceLocation L;
125 L.ID = MacroIDBit | ID;
126 return L;
127 }
128
129public:
130 /// Return a source location with the specified offset from this
131 /// SourceLocation.
132 SourceLocation getLocWithOffset(int Offset) const {
133 assert(((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow")((((getOffset()+Offset) & MacroIDBit) == 0 && "offset overflow"
) ? static_cast<void> (0) : __assert_fail ("((getOffset()+Offset) & MacroIDBit) == 0 && \"offset overflow\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 133, __PRETTY_FUNCTION__))
;
134 SourceLocation L;
135 L.ID = ID+Offset;
136 return L;
137 }
138
139 /// When a SourceLocation itself cannot be used, this returns
140 /// an (opaque) 32-bit integer encoding for it.
141 ///
142 /// This should only be passed to SourceLocation::getFromRawEncoding, it
143 /// should not be inspected directly.
144 unsigned getRawEncoding() const { return ID; }
145
146 /// Turn a raw encoding of a SourceLocation object into
147 /// a real SourceLocation.
148 ///
149 /// \see getRawEncoding.
150 static SourceLocation getFromRawEncoding(unsigned Encoding) {
151 SourceLocation X;
152 X.ID = Encoding;
153 return X;
154 }
155
156 /// When a SourceLocation itself cannot be used, this returns
157 /// an (opaque) pointer encoding for it.
158 ///
159 /// This should only be passed to SourceLocation::getFromPtrEncoding, it
160 /// should not be inspected directly.
161 void* getPtrEncoding() const {
162 // Double cast to avoid a warning "cast to pointer from integer of different
163 // size".
164 return (void*)(uintptr_t)getRawEncoding();
165 }
166
167 /// Turn a pointer encoding of a SourceLocation object back
168 /// into a real SourceLocation.
169 static SourceLocation getFromPtrEncoding(const void *Encoding) {
170 return getFromRawEncoding((unsigned)(uintptr_t)Encoding);
171 }
172
173 static bool isPairOfFileLocations(SourceLocation Start, SourceLocation End) {
174 return Start.isValid() && Start.isFileID() && End.isValid() &&
175 End.isFileID();
176 }
177
178 void print(raw_ostream &OS, const SourceManager &SM) const;
179 std::string printToString(const SourceManager &SM) const;
180 void dump(const SourceManager &SM) const;
181};
182
183inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) {
184 return LHS.getRawEncoding() == RHS.getRawEncoding();
185}
186
187inline bool operator!=(const SourceLocation &LHS, const SourceLocation &RHS) {
188 return !(LHS == RHS);
189}
190
191// Ordering is meaningful only if LHS and RHS have the same FileID!
192// Otherwise use SourceManager::isBeforeInTranslationUnit().
193inline bool operator<(const SourceLocation &LHS, const SourceLocation &RHS) {
194 return LHS.getRawEncoding() < RHS.getRawEncoding();
195}
196inline bool operator>(const SourceLocation &LHS, const SourceLocation &RHS) {
197 return LHS.getRawEncoding() > RHS.getRawEncoding();
198}
199inline bool operator<=(const SourceLocation &LHS, const SourceLocation &RHS) {
200 return LHS.getRawEncoding() <= RHS.getRawEncoding();
201}
202inline bool operator>=(const SourceLocation &LHS, const SourceLocation &RHS) {
203 return LHS.getRawEncoding() >= RHS.getRawEncoding();
204}
205
206/// A trivial tuple used to represent a source range.
207class SourceRange {
208 SourceLocation B;
209 SourceLocation E;
210
211public:
212 SourceRange() = default;
213 SourceRange(SourceLocation loc) : B(loc), E(loc) {}
214 SourceRange(SourceLocation begin, SourceLocation end) : B(begin), E(end) {}
215
216 SourceLocation getBegin() const { return B; }
217 SourceLocation getEnd() const { return E; }
218
219 void setBegin(SourceLocation b) { B = b; }
220 void setEnd(SourceLocation e) { E = e; }
221
222 bool isValid() const { return B.isValid() && E.isValid(); }
223 bool isInvalid() const { return !isValid(); }
224
225 bool operator==(const SourceRange &X) const {
226 return B == X.B && E == X.E;
227 }
228
229 bool operator!=(const SourceRange &X) const {
230 return B != X.B || E != X.E;
231 }
232
233 // Returns true iff other is wholly contained within this range.
234 bool fullyContains(const SourceRange &other) const {
235 return B <= other.B && E >= other.E;
236 }
237
238 void print(raw_ostream &OS, const SourceManager &SM) const;
239 std::string printToString(const SourceManager &SM) const;
240 void dump(const SourceManager &SM) const;
241};
242
243/// Represents a character-granular source range.
244///
245/// The underlying SourceRange can either specify the starting/ending character
246/// of the range, or it can specify the start of the range and the start of the
247/// last token of the range (a "token range"). In the token range case, the
248/// size of the last token must be measured to determine the actual end of the
249/// range.
250class CharSourceRange {
251 SourceRange Range;
252 bool IsTokenRange = false;
253
254public:
255 CharSourceRange() = default;
256 CharSourceRange(SourceRange R, bool ITR) : Range(R), IsTokenRange(ITR) {}
257
258 static CharSourceRange getTokenRange(SourceRange R) {
259 return CharSourceRange(R, true);
260 }
261
262 static CharSourceRange getCharRange(SourceRange R) {
263 return CharSourceRange(R, false);
264 }
265
266 static CharSourceRange getTokenRange(SourceLocation B, SourceLocation E) {
267 return getTokenRange(SourceRange(B, E));
268 }
269
270 static CharSourceRange getCharRange(SourceLocation B, SourceLocation E) {
271 return getCharRange(SourceRange(B, E));
272 }
273
274 /// Return true if the end of this range specifies the start of
275 /// the last token. Return false if the end of this range specifies the last
276 /// character in the range.
277 bool isTokenRange() const { return IsTokenRange; }
278 bool isCharRange() const { return !IsTokenRange; }
279
280 SourceLocation getBegin() const { return Range.getBegin(); }
281 SourceLocation getEnd() const { return Range.getEnd(); }
282 SourceRange getAsRange() const { return Range; }
283
284 void setBegin(SourceLocation b) { Range.setBegin(b); }
285 void setEnd(SourceLocation e) { Range.setEnd(e); }
286 void setTokenRange(bool TR) { IsTokenRange = TR; }
287
288 bool isValid() const { return Range.isValid(); }
289 bool isInvalid() const { return !isValid(); }
290};
291
292/// Represents an unpacked "presumed" location which can be presented
293/// to the user.
294///
295/// A 'presumed' location can be modified by \#line and GNU line marker
296/// directives and is always the expansion point of a normal location.
297///
298/// You can get a PresumedLoc from a SourceLocation with SourceManager.
299class PresumedLoc {
300 const char *Filename = nullptr;
301 FileID ID;
302 unsigned Line, Col;
303 SourceLocation IncludeLoc;
304
305public:
306 PresumedLoc() = default;
307 PresumedLoc(const char *FN, FileID FID, unsigned Ln, unsigned Co,
308 SourceLocation IL)
309 : Filename(FN), ID(FID), Line(Ln), Col(Co), IncludeLoc(IL) {}
310
311 /// Return true if this object is invalid or uninitialized.
312 ///
313 /// This occurs when created with invalid source locations or when walking
314 /// off the top of a \#include stack.
315 bool isInvalid() const { return Filename == nullptr; }
316 bool isValid() const { return Filename != nullptr; }
317
318 /// Return the presumed filename of this location.
319 ///
320 /// This can be affected by \#line etc.
321 const char *getFilename() const {
322 assert(isValid())((isValid()) ? static_cast<void> (0) : __assert_fail ("isValid()"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 322, __PRETTY_FUNCTION__))
;
323 return Filename;
324 }
325
326 FileID getFileID() const {
327 assert(isValid())((isValid()) ? static_cast<void> (0) : __assert_fail ("isValid()"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 327, __PRETTY_FUNCTION__))
;
328 return ID;
329 }
330
331 /// Return the presumed line number of this location.
332 ///
333 /// This can be affected by \#line etc.
334 unsigned getLine() const {
335 assert(isValid())((isValid()) ? static_cast<void> (0) : __assert_fail ("isValid()"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 335, __PRETTY_FUNCTION__))
;
336 return Line;
337 }
338
339 /// Return the presumed column number of this location.
340 ///
341 /// This cannot be affected by \#line, but is packaged here for convenience.
342 unsigned getColumn() const {
343 assert(isValid())((isValid()) ? static_cast<void> (0) : __assert_fail ("isValid()"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 343, __PRETTY_FUNCTION__))
;
344 return Col;
345 }
346
347 /// Return the presumed include location of this location.
348 ///
349 /// This can be affected by GNU linemarker directives.
350 SourceLocation getIncludeLoc() const {
351 assert(isValid())((isValid()) ? static_cast<void> (0) : __assert_fail ("isValid()"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 351, __PRETTY_FUNCTION__))
;
352 return IncludeLoc;
353 }
354};
355
356class FileEntry;
357
358/// A SourceLocation and its associated SourceManager.
359///
360/// This is useful for argument passing to functions that expect both objects.
361class FullSourceLoc : public SourceLocation {
362 const SourceManager *SrcMgr = nullptr;
363
364public:
365 /// Creates a FullSourceLoc where isValid() returns \c false.
366 FullSourceLoc() = default;
367
368 explicit FullSourceLoc(SourceLocation Loc, const SourceManager &SM)
369 : SourceLocation(Loc), SrcMgr(&SM) {}
370
371 bool hasManager() const {
372 bool hasSrcMgr = SrcMgr != nullptr;
373 assert(hasSrcMgr == isValid() && "FullSourceLoc has location but no manager")((hasSrcMgr == isValid() && "FullSourceLoc has location but no manager"
) ? static_cast<void> (0) : __assert_fail ("hasSrcMgr == isValid() && \"FullSourceLoc has location but no manager\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 373, __PRETTY_FUNCTION__))
;
374 return hasSrcMgr;
375 }
376
377 /// \pre This FullSourceLoc has an associated SourceManager.
378 const SourceManager &getManager() const {
379 assert(SrcMgr && "SourceManager is NULL.")((SrcMgr && "SourceManager is NULL.") ? static_cast<
void> (0) : __assert_fail ("SrcMgr && \"SourceManager is NULL.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 379, __PRETTY_FUNCTION__))
;
380 return *SrcMgr;
381 }
382
383 FileID getFileID() const;
384
385 FullSourceLoc getExpansionLoc() const;
386 FullSourceLoc getSpellingLoc() const;
387 FullSourceLoc getFileLoc() const;
388 PresumedLoc getPresumedLoc(bool UseLineDirectives = true) const;
389 bool isMacroArgExpansion(FullSourceLoc *StartLoc = nullptr) const;
390 FullSourceLoc getImmediateMacroCallerLoc() const;
391 std::pair<FullSourceLoc, StringRef> getModuleImportLoc() const;
392 unsigned getFileOffset() const;
393
394 unsigned getExpansionLineNumber(bool *Invalid = nullptr) const;
395 unsigned getExpansionColumnNumber(bool *Invalid = nullptr) const;
396
397 unsigned getSpellingLineNumber(bool *Invalid = nullptr) const;
398 unsigned getSpellingColumnNumber(bool *Invalid = nullptr) const;
399
400 const char *getCharacterData(bool *Invalid = nullptr) const;
401
402 unsigned getLineNumber(bool *Invalid = nullptr) const;
403 unsigned getColumnNumber(bool *Invalid = nullptr) const;
404
405 const FileEntry *getFileEntry() const;
406
407 /// Return a StringRef to the source buffer data for the
408 /// specified FileID.
409 StringRef getBufferData(bool *Invalid = nullptr) const;
410
411 /// Decompose the specified location into a raw FileID + Offset pair.
412 ///
413 /// The first element is the FileID, the second is the offset from the
414 /// start of the buffer of the location.
415 std::pair<FileID, unsigned> getDecomposedLoc() const;
416
417 bool isInSystemHeader() const;
418
419 /// Determines the order of 2 source locations in the translation unit.
420 ///
421 /// \returns true if this source location comes before 'Loc', false otherwise.
422 bool isBeforeInTranslationUnitThan(SourceLocation Loc) const;
423
424 /// Determines the order of 2 source locations in the translation unit.
425 ///
426 /// \returns true if this source location comes before 'Loc', false otherwise.
427 bool isBeforeInTranslationUnitThan(FullSourceLoc Loc) const {
428 assert(Loc.isValid())((Loc.isValid()) ? static_cast<void> (0) : __assert_fail
("Loc.isValid()", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 428, __PRETTY_FUNCTION__))
;
429 assert(SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!")((SrcMgr == Loc.SrcMgr && "Loc comes from another SourceManager!"
) ? static_cast<void> (0) : __assert_fail ("SrcMgr == Loc.SrcMgr && \"Loc comes from another SourceManager!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/clang/include/clang/Basic/SourceLocation.h"
, 429, __PRETTY_FUNCTION__))
;
430 return isBeforeInTranslationUnitThan((SourceLocation)Loc);
431 }
432
433 /// Comparison function class, useful for sorting FullSourceLocs.
434 struct BeforeThanCompare {
435 bool operator()(const FullSourceLoc& lhs, const FullSourceLoc& rhs) const {
436 return lhs.isBeforeInTranslationUnitThan(rhs);
437 }
438 };
439
440 /// Prints information about this FullSourceLoc to stderr.
441 ///
442 /// This is useful for debugging.
443 void dump() const;
444
445 friend bool
446 operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
447 return LHS.getRawEncoding() == RHS.getRawEncoding() &&
448 LHS.SrcMgr == RHS.SrcMgr;
449 }
450
451 friend bool
452 operator!=(const FullSourceLoc &LHS, const FullSourceLoc &RHS) {
453 return !(LHS == RHS);
454 }
455};
456
457} // namespace clang
458
459namespace llvm {
460
461 /// Define DenseMapInfo so that FileID's can be used as keys in DenseMap and
462 /// DenseSets.
463 template <>
464 struct DenseMapInfo<clang::FileID> {
465 static clang::FileID getEmptyKey() {
466 return {};
467 }
468
469 static clang::FileID getTombstoneKey() {
470 return clang::FileID::getSentinel();
471 }
472
473 static unsigned getHashValue(clang::FileID S) {
474 return S.getHashValue();
475 }
476
477 static bool isEqual(clang::FileID LHS, clang::FileID RHS) {
478 return LHS == RHS;
479 }
480 };
481
482 // Teach SmallPtrSet how to handle SourceLocation.
483 template<>
484 struct PointerLikeTypeTraits<clang::SourceLocation> {
485 static constexpr int NumLowBitsAvailable = 0;
486
487 static void *getAsVoidPointer(clang::SourceLocation L) {
488 return L.getPtrEncoding();
489 }
490
491 static clang::SourceLocation getFromVoidPointer(void *P) {
492 return clang::SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)P);
493 }
494 };
495
496} // namespace llvm
497
498#endif // LLVM_CLANG_BASIC_SOURCELOCATION_H