clang 20.0.0git
SemaFunctionEffects.cpp
Go to the documentation of this file.
1//=== SemaFunctionEffects.cpp - Sema handling of function effects ---------===//
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 implements Sema handling of function effects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/Decl.h"
14#include "clang/AST/DeclCXX.h"
16#include "clang/AST/ExprObjC.h"
17#include "clang/AST/Stmt.h"
18#include "clang/AST/StmtObjC.h"
19#include "clang/AST/Type.h"
22
23#define DEBUG_TYPE "effectanalysis"
24
25using namespace clang;
26
27namespace {
28
29enum class ViolationID : uint8_t {
30 None = 0, // Sentinel for an empty Violation.
31 // These first 5 map to a %select{} in one of several FunctionEffects
32 // diagnostics, e.g. warn_func_effect_violation.
33 BaseDiagnosticIndex,
34 AllocatesMemory = BaseDiagnosticIndex,
35 ThrowsOrCatchesExceptions,
36 HasStaticLocalVariable,
37 AccessesThreadLocalVariable,
38 AccessesObjCMethodOrProperty,
39
40 // These only apply to callees, where the analysis stops at the Decl.
41 DeclDisallowsInference,
42
43 // These both apply to indirect calls. The difference is that sometimes
44 // we have an actual Decl (generally a variable) which is the function
45 // pointer being called, and sometimes, typically due to a cast, we only
46 // have an expression.
47 CallsDeclWithoutEffect,
48 CallsExprWithoutEffect,
49};
50
51// Information about the AST context in which a violation was found, so
52// that diagnostics can point to the correct source.
53class ViolationSite {
54public:
55 enum class Kind : uint8_t {
56 Default, // Function body.
57 MemberInitializer,
58 DefaultArgExpr
59 };
60
61private:
62 llvm::PointerIntPair<CXXDefaultArgExpr *, 2, Kind> Impl;
63
64public:
65 ViolationSite() = default;
66
67 explicit ViolationSite(CXXDefaultArgExpr *E)
68 : Impl(E, Kind::DefaultArgExpr) {}
69
70 Kind kind() const { return static_cast<Kind>(Impl.getInt()); }
71 CXXDefaultArgExpr *defaultArgExpr() const { return Impl.getPointer(); }
72
73 void setKind(Kind K) { Impl.setPointerAndInt(nullptr, K); }
74};
75
76// Represents a violation of the rules, potentially for the entire duration of
77// the analysis phase, in order to refer to it when explaining why a caller has
78// been made unsafe by a callee. Can be transformed into either a Diagnostic
79// (warning or a note), depending on whether the violation pertains to a
80// function failing to be verifed as holding an effect vs. a function failing to
81// be inferred as holding that effect.
82struct Violation {
83 FunctionEffect Effect;
84 std::optional<FunctionEffect>
85 CalleeEffectPreventingInference; // Only for certain IDs; can be nullopt.
86 ViolationID ID = ViolationID::None;
87 ViolationSite Site;
89 const Decl *Callee =
90 nullptr; // Only valid for ViolationIDs Calls{Decl,Expr}WithoutEffect.
91
92 Violation(FunctionEffect Effect, ViolationID ID, ViolationSite VS,
93 SourceLocation Loc, const Decl *Callee = nullptr,
94 std::optional<FunctionEffect> CalleeEffect = std::nullopt)
95 : Effect(Effect), CalleeEffectPreventingInference(CalleeEffect), ID(ID),
96 Site(VS), Loc(Loc), Callee(Callee) {}
97
98 unsigned diagnosticSelectIndex() const {
99 return unsigned(ID) - unsigned(ViolationID::BaseDiagnosticIndex);
100 }
101};
102
103enum class SpecialFuncType : uint8_t { None, OperatorNew, OperatorDelete };
104enum class CallableType : uint8_t {
105 // Unknown: probably function pointer.
106 Unknown,
107 Function,
108 Virtual,
109 Block
110};
111
112// Return whether a function's effects CAN be verified.
113// The question of whether it SHOULD be verified is independent.
114static bool functionIsVerifiable(const FunctionDecl *FD) {
115 if (FD->isTrivial()) {
116 // Otherwise `struct x { int a; };` would have an unverifiable default
117 // constructor.
118 return true;
119 }
120 return FD->hasBody();
121}
122
123static bool isNoexcept(const FunctionDecl *FD) {
124 const auto *FPT = FD->getType()->getAs<FunctionProtoType>();
125 return FPT && (FPT->isNothrow() || FD->hasAttr<NoThrowAttr>());
126}
127
128// This list is probably incomplete.
129// FIXME: Investigate:
130// __builtin_eh_return?
131// __builtin_allow_runtime_check?
132// __builtin_unwind_init and other similar things that sound exception-related.
133// va_copy?
134// coroutines?
135static FunctionEffectKindSet getBuiltinFunctionEffects(unsigned BuiltinID) {
137
138 switch (BuiltinID) {
139 case 0: // Not builtin.
140 default: // By default, builtins have no known effects.
141 break;
142
143 // These allocate/deallocate heap memory.
144 case Builtin::ID::BI__builtin_calloc:
145 case Builtin::ID::BI__builtin_malloc:
146 case Builtin::ID::BI__builtin_realloc:
147 case Builtin::ID::BI__builtin_free:
148 case Builtin::ID::BI__builtin_operator_delete:
149 case Builtin::ID::BI__builtin_operator_new:
150 case Builtin::ID::BIaligned_alloc:
151 case Builtin::ID::BIcalloc:
152 case Builtin::ID::BImalloc:
153 case Builtin::ID::BImemalign:
154 case Builtin::ID::BIrealloc:
155 case Builtin::ID::BIfree:
156
157 case Builtin::ID::BIfopen:
158 case Builtin::ID::BIpthread_create:
159 case Builtin::ID::BI_Block_object_dispose:
160 Result.insert(FunctionEffect(FunctionEffect::Kind::Allocating));
161 break;
162
163 // These block in some other way than allocating memory.
164 // longjmp() and friends are presumed unsafe because they are the moral
165 // equivalent of throwing a C++ exception, which is unsafe.
166 case Builtin::ID::BIlongjmp:
167 case Builtin::ID::BI_longjmp:
168 case Builtin::ID::BIsiglongjmp:
169 case Builtin::ID::BI__builtin_longjmp:
170 case Builtin::ID::BIobjc_exception_throw:
171
172 // Objective-C runtime.
173 case Builtin::ID::BIobjc_msgSend:
174 case Builtin::ID::BIobjc_msgSend_fpret:
175 case Builtin::ID::BIobjc_msgSend_fp2ret:
176 case Builtin::ID::BIobjc_msgSend_stret:
177 case Builtin::ID::BIobjc_msgSendSuper:
178 case Builtin::ID::BIobjc_getClass:
179 case Builtin::ID::BIobjc_getMetaClass:
180 case Builtin::ID::BIobjc_enumerationMutation:
181 case Builtin::ID::BIobjc_assign_ivar:
182 case Builtin::ID::BIobjc_assign_global:
183 case Builtin::ID::BIobjc_sync_enter:
184 case Builtin::ID::BIobjc_sync_exit:
185 case Builtin::ID::BINSLog:
186 case Builtin::ID::BINSLogv:
187
188 // stdio.h
189 case Builtin::ID::BIfread:
190 case Builtin::ID::BIfwrite:
191
192 // stdio.h: printf family.
193 case Builtin::ID::BIprintf:
194 case Builtin::ID::BI__builtin_printf:
195 case Builtin::ID::BIfprintf:
196 case Builtin::ID::BIsnprintf:
197 case Builtin::ID::BIsprintf:
198 case Builtin::ID::BIvprintf:
199 case Builtin::ID::BIvfprintf:
200 case Builtin::ID::BIvsnprintf:
201 case Builtin::ID::BIvsprintf:
202
203 // stdio.h: scanf family.
204 case Builtin::ID::BIscanf:
205 case Builtin::ID::BIfscanf:
206 case Builtin::ID::BIsscanf:
207 case Builtin::ID::BIvscanf:
208 case Builtin::ID::BIvfscanf:
209 case Builtin::ID::BIvsscanf:
210 Result.insert(FunctionEffect(FunctionEffect::Kind::Blocking));
211 break;
212 }
213
214 return Result;
215}
216
217// Transitory, more extended information about a callable, which can be a
218// function, block, or function pointer.
219struct CallableInfo {
220 // CDecl holds the function's definition, if any.
221 // FunctionDecl if CallableType::Function or Virtual
222 // BlockDecl if CallableType::Block
223 const Decl *CDecl;
224
225 // Remember whether the callable is a function, block, virtual method,
226 // or (presumed) function pointer.
227 CallableType CType = CallableType::Unknown;
228
229 // Remember whether the callable is an operator new or delete function,
230 // so that calls to them are reported more meaningfully, as memory
231 // allocations.
232 SpecialFuncType FuncType = SpecialFuncType::None;
233
234 // We inevitably want to know the callable's declared effects, so cache them.
235 FunctionEffectKindSet Effects;
236
237 CallableInfo(const Decl &CD, SpecialFuncType FT = SpecialFuncType::None)
238 : CDecl(&CD), FuncType(FT) {
239 FunctionEffectsRef DeclEffects;
240 if (auto *FD = dyn_cast<FunctionDecl>(CDecl)) {
241 // Use the function's definition, if any.
242 if (const FunctionDecl *Def = FD->getDefinition())
243 CDecl = FD = Def;
244 CType = CallableType::Function;
245 if (auto *Method = dyn_cast<CXXMethodDecl>(FD);
246 Method && Method->isVirtual())
247 CType = CallableType::Virtual;
248 DeclEffects = FD->getFunctionEffects();
249 } else if (auto *BD = dyn_cast<BlockDecl>(CDecl)) {
250 CType = CallableType::Block;
251 DeclEffects = BD->getFunctionEffects();
252 } else if (auto *VD = dyn_cast<ValueDecl>(CDecl)) {
253 // ValueDecl is function, enum, or variable, so just look at its type.
254 DeclEffects = FunctionEffectsRef::get(VD->getType());
255 }
256 Effects = FunctionEffectKindSet(DeclEffects);
257 }
258
259 CallableType type() const { return CType; }
260
261 bool isCalledDirectly() const {
262 return CType == CallableType::Function || CType == CallableType::Block;
263 }
264
265 bool isVerifiable() const {
266 switch (CType) {
267 case CallableType::Unknown:
268 case CallableType::Virtual:
269 return false;
270 case CallableType::Block:
271 return true;
272 case CallableType::Function:
273 return functionIsVerifiable(dyn_cast<FunctionDecl>(CDecl));
274 }
275 llvm_unreachable("undefined CallableType");
276 }
277
278 /// Generate a name for logging and diagnostics.
279 std::string getNameForDiagnostic(Sema &S) const {
280 std::string Name;
281 llvm::raw_string_ostream OS(Name);
282
283 if (auto *FD = dyn_cast<FunctionDecl>(CDecl))
285 /*Qualified=*/true);
286 else if (auto *BD = dyn_cast<BlockDecl>(CDecl))
287 OS << "(block " << BD->getBlockManglingNumber() << ")";
288 else if (auto *VD = dyn_cast<NamedDecl>(CDecl))
289 VD->printQualifiedName(OS);
290 return Name;
291 }
292};
293
294// ----------
295// Map effects to single Violations, to hold the first (of potentially many)
296// violations pertaining to an effect, per function.
297class EffectToViolationMap {
298 // Since we currently only have a tiny number of effects (typically no more
299 // than 1), use a SmallVector with an inline capacity of 1. Since it
300 // is often empty, use a unique_ptr to the SmallVector.
301 // Note that Violation itself contains a FunctionEffect which is the key.
302 // FIXME: Is there a way to simplify this using existing data structures?
303 using ImplVec = llvm::SmallVector<Violation, 1>;
304 std::unique_ptr<ImplVec> Impl;
305
306public:
307 // Insert a new Violation if we do not already have one for its effect.
308 void maybeInsert(const Violation &Viol) {
309 if (Impl == nullptr)
310 Impl = std::make_unique<ImplVec>();
311 else if (lookup(Viol.Effect) != nullptr)
312 return;
313
314 Impl->push_back(Viol);
315 }
316
317 const Violation *lookup(FunctionEffect Key) {
318 if (Impl == nullptr)
319 return nullptr;
320
321 auto *Iter = llvm::find_if(
322 *Impl, [&](const auto &Item) { return Item.Effect == Key; });
323 return Iter != Impl->end() ? &*Iter : nullptr;
324 }
325
326 size_t size() const { return Impl ? Impl->size() : 0; }
327};
328
329// ----------
330// State pertaining to a function whose AST is walked and whose effect analysis
331// is dependent on a subsequent analysis of other functions.
332class PendingFunctionAnalysis {
333 friend class CompleteFunctionAnalysis;
334
335public:
336 struct DirectCall {
337 const Decl *Callee;
338 SourceLocation CallLoc;
339 // Not all recursive calls are detected, just enough
340 // to break cycles.
341 bool Recursed = false;
342 ViolationSite VSite;
343
344 DirectCall(const Decl *D, SourceLocation CallLoc, ViolationSite VSite)
345 : Callee(D), CallLoc(CallLoc), VSite(VSite) {}
346 };
347
348 // We always have two disjoint sets of effects to verify:
349 // 1. Effects declared explicitly by this function.
350 // 2. All other inferrable effects needing verification.
351 FunctionEffectKindSet DeclaredVerifiableEffects;
352 FunctionEffectKindSet EffectsToInfer;
353
354private:
355 // Violations pertaining to the function's explicit effects.
356 SmallVector<Violation, 0> ViolationsForExplicitEffects;
357
358 // Violations pertaining to other, non-explicit, inferrable effects.
359 EffectToViolationMap InferrableEffectToFirstViolation;
360
361 // These unverified direct calls are what keeps the analysis "pending",
362 // until the callees can be verified.
363 SmallVector<DirectCall, 0> UnverifiedDirectCalls;
364
365public:
366 PendingFunctionAnalysis(Sema &S, const CallableInfo &CInfo,
367 FunctionEffectKindSet AllInferrableEffectsToVerify)
368 : DeclaredVerifiableEffects(CInfo.Effects) {
369 // Check for effects we are not allowed to infer.
370 FunctionEffectKindSet InferrableEffects;
371
372 for (FunctionEffect effect : AllInferrableEffectsToVerify) {
373 std::optional<FunctionEffect> ProblemCalleeEffect =
374 effect.effectProhibitingInference(*CInfo.CDecl, CInfo.Effects);
375 if (!ProblemCalleeEffect)
376 InferrableEffects.insert(effect);
377 else {
378 // Add a Violation for this effect if a caller were to
379 // try to infer it.
380 InferrableEffectToFirstViolation.maybeInsert(Violation(
381 effect, ViolationID::DeclDisallowsInference, ViolationSite{},
382 CInfo.CDecl->getLocation(), nullptr, ProblemCalleeEffect));
383 }
384 }
385 // InferrableEffects is now the set of inferrable effects which are not
386 // prohibited.
387 EffectsToInfer = FunctionEffectKindSet::difference(
388 InferrableEffects, DeclaredVerifiableEffects);
389 }
390
391 // Hide the way that Violations for explicitly required effects vs. inferred
392 // ones are handled differently.
393 void checkAddViolation(bool Inferring, const Violation &NewViol) {
394 if (!Inferring)
395 ViolationsForExplicitEffects.push_back(NewViol);
396 else
397 InferrableEffectToFirstViolation.maybeInsert(NewViol);
398 }
399
400 void addUnverifiedDirectCall(const Decl *D, SourceLocation CallLoc,
401 ViolationSite VSite) {
402 UnverifiedDirectCalls.emplace_back(D, CallLoc, VSite);
403 }
404
405 // Analysis is complete when there are no unverified direct calls.
406 bool isComplete() const { return UnverifiedDirectCalls.empty(); }
407
408 const Violation *violationForInferrableEffect(FunctionEffect effect) {
409 return InferrableEffectToFirstViolation.lookup(effect);
410 }
411
412 // Mutable because caller may need to set a DirectCall's Recursing flag.
413 MutableArrayRef<DirectCall> unverifiedCalls() {
414 assert(!isComplete());
415 return UnverifiedDirectCalls;
416 }
417
418 ArrayRef<Violation> getSortedViolationsForExplicitEffects(SourceManager &SM) {
419 if (!ViolationsForExplicitEffects.empty())
420 llvm::sort(ViolationsForExplicitEffects,
421 [&SM](const Violation &LHS, const Violation &RHS) {
422 return SM.isBeforeInTranslationUnit(LHS.Loc, RHS.Loc);
423 });
424 return ViolationsForExplicitEffects;
425 }
426
427 void dump(Sema &SemaRef, llvm::raw_ostream &OS) const {
428 OS << "Pending: Declared ";
429 DeclaredVerifiableEffects.dump(OS);
430 OS << ", " << ViolationsForExplicitEffects.size() << " violations; ";
431 OS << " Infer ";
432 EffectsToInfer.dump(OS);
433 OS << ", " << InferrableEffectToFirstViolation.size() << " violations";
434 if (!UnverifiedDirectCalls.empty()) {
435 OS << "; Calls: ";
436 for (const DirectCall &Call : UnverifiedDirectCalls) {
437 CallableInfo CI(*Call.Callee);
438 OS << " " << CI.getNameForDiagnostic(SemaRef);
439 }
440 }
441 OS << "\n";
442 }
443};
444
445// ----------
446class CompleteFunctionAnalysis {
447 // Current size: 2 pointers
448public:
449 // Has effects which are both the declared ones -- not to be inferred -- plus
450 // ones which have been successfully inferred. These are all considered
451 // "verified" for the purposes of callers; any issue with verifying declared
452 // effects has already been reported and is not the problem of any caller.
453 FunctionEffectKindSet VerifiedEffects;
454
455private:
456 // This is used to generate notes about failed inference.
457 EffectToViolationMap InferrableEffectToFirstViolation;
458
459public:
460 // The incoming Pending analysis is consumed (member(s) are moved-from).
461 CompleteFunctionAnalysis(ASTContext &Ctx, PendingFunctionAnalysis &&Pending,
462 FunctionEffectKindSet DeclaredEffects,
463 FunctionEffectKindSet AllInferrableEffectsToVerify)
464 : VerifiedEffects(DeclaredEffects) {
465 for (FunctionEffect effect : AllInferrableEffectsToVerify)
466 if (Pending.violationForInferrableEffect(effect) == nullptr)
467 VerifiedEffects.insert(effect);
468
469 InferrableEffectToFirstViolation =
470 std::move(Pending.InferrableEffectToFirstViolation);
471 }
472
473 const Violation *firstViolationForEffect(FunctionEffect Effect) {
474 return InferrableEffectToFirstViolation.lookup(Effect);
475 }
476
477 void dump(llvm::raw_ostream &OS) const {
478 OS << "Complete: Verified ";
479 VerifiedEffects.dump(OS);
480 OS << "; Infer ";
481 OS << InferrableEffectToFirstViolation.size() << " violations\n";
482 }
483};
484
485// ==========
486class Analyzer {
487 Sema &S;
488
489 // Subset of Sema.AllEffectsToVerify
490 FunctionEffectKindSet AllInferrableEffectsToVerify;
491
492 using FuncAnalysisPtr =
493 llvm::PointerUnion<PendingFunctionAnalysis *, CompleteFunctionAnalysis *>;
494
495 // Map all Decls analyzed to FuncAnalysisPtr. Pending state is larger
496 // than complete state, so use different objects to represent them.
497 // The state pointers are owned by the container.
498 class AnalysisMap : llvm::DenseMap<const Decl *, FuncAnalysisPtr> {
499 using Base = llvm::DenseMap<const Decl *, FuncAnalysisPtr>;
500
501 public:
502 ~AnalysisMap();
503
504 // Use non-public inheritance in order to maintain the invariant
505 // that lookups and insertions are via the canonical Decls.
506
507 FuncAnalysisPtr lookup(const Decl *Key) const {
508 return Base::lookup(Key->getCanonicalDecl());
509 }
510
511 FuncAnalysisPtr &operator[](const Decl *Key) {
512 return Base::operator[](Key->getCanonicalDecl());
513 }
514
515 /// Shortcut for the case where we only care about completed analysis.
516 CompleteFunctionAnalysis *completedAnalysisForDecl(const Decl *D) const {
517 if (FuncAnalysisPtr AP = lookup(D);
518 isa_and_nonnull<CompleteFunctionAnalysis *>(AP))
519 return cast<CompleteFunctionAnalysis *>(AP);
520 return nullptr;
521 }
522
523 void dump(Sema &SemaRef, llvm::raw_ostream &OS) {
524 OS << "\nAnalysisMap:\n";
525 for (const auto &item : *this) {
526 CallableInfo CI(*item.first);
527 const auto AP = item.second;
528 OS << item.first << " " << CI.getNameForDiagnostic(SemaRef) << " : ";
529 if (AP.isNull()) {
530 OS << "null\n";
531 } else if (auto *CFA = dyn_cast<CompleteFunctionAnalysis *>(AP)) {
532 OS << CFA << " ";
533 CFA->dump(OS);
534 } else if (auto *PFA = dyn_cast<PendingFunctionAnalysis *>(AP)) {
535 OS << PFA << " ";
536 PFA->dump(SemaRef, OS);
537 } else
538 llvm_unreachable("never");
539 }
540 OS << "---\n";
541 }
542 };
543 AnalysisMap DeclAnalysis;
544
545public:
546 Analyzer(Sema &S) : S(S) {}
547
548 void run(const TranslationUnitDecl &TU) {
549 // Gather all of the effects to be verified to see what operations need to
550 // be checked, and to see which ones are inferrable.
551 for (FunctionEffect Effect : S.AllEffectsToVerify) {
552 const FunctionEffect::Flags Flags = Effect.flags();
554 AllInferrableEffectsToVerify.insert(Effect);
555 }
556 LLVM_DEBUG(llvm::dbgs() << "AllInferrableEffectsToVerify: ";
557 AllInferrableEffectsToVerify.dump(llvm::dbgs());
558 llvm::dbgs() << "\n";);
559
560 // We can use DeclsWithEffectsToVerify as a stack for a
561 // depth-first traversal; there's no need for a second container. But first,
562 // reverse it, so when working from the end, Decls are verified in the order
563 // they are declared.
565 std::reverse(VerificationQueue.begin(), VerificationQueue.end());
566
567 while (!VerificationQueue.empty()) {
568 const Decl *D = VerificationQueue.back();
569 if (FuncAnalysisPtr AP = DeclAnalysis.lookup(D)) {
570 if (auto *Pending = AP.dyn_cast<PendingFunctionAnalysis *>()) {
571 // All children have been traversed; finish analysis.
572 finishPendingAnalysis(D, Pending);
573 }
574 VerificationQueue.pop_back();
575 continue;
576 }
577
578 // Not previously visited; begin a new analysis for this Decl.
579 PendingFunctionAnalysis *Pending = verifyDecl(D);
580 if (Pending == nullptr) {
581 // Completed now.
582 VerificationQueue.pop_back();
583 continue;
584 }
585
586 // Analysis remains pending because there are direct callees to be
587 // verified first. Push them onto the queue.
588 for (PendingFunctionAnalysis::DirectCall &Call :
589 Pending->unverifiedCalls()) {
590 FuncAnalysisPtr AP = DeclAnalysis.lookup(Call.Callee);
591 if (AP.isNull()) {
592 VerificationQueue.push_back(Call.Callee);
593 continue;
594 }
595
596 // This indicates recursion (not necessarily direct). For the
597 // purposes of effect analysis, we can just ignore it since
598 // no effects forbid recursion.
599 assert(isa<PendingFunctionAnalysis *>(AP));
600 Call.Recursed = true;
601 }
602 }
603 }
604
605private:
606 // Verify a single Decl. Return the pending structure if that was the result,
607 // else null. This method must not recurse.
608 PendingFunctionAnalysis *verifyDecl(const Decl *D) {
609 CallableInfo CInfo(*D);
610 bool isExternC = false;
611
612 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
614
615 // For C++, with non-extern "C" linkage only - if any of the Decl's declared
616 // effects forbid throwing (e.g. nonblocking) then the function should also
617 // be declared noexcept.
618 if (S.getLangOpts().CPlusPlus && !isExternC) {
619 for (FunctionEffect Effect : CInfo.Effects) {
620 if (!(Effect.flags() & FunctionEffect::FE_ExcludeThrow))
621 continue;
622
623 bool IsNoexcept = false;
624 if (auto *FD = D->getAsFunction()) {
625 IsNoexcept = isNoexcept(FD);
626 } else if (auto *BD = dyn_cast<BlockDecl>(D)) {
627 if (auto *TSI = BD->getSignatureAsWritten()) {
628 auto *FPT = TSI->getType()->castAs<FunctionProtoType>();
629 IsNoexcept = FPT->isNothrow() || BD->hasAttr<NoThrowAttr>();
630 }
631 }
632 if (!IsNoexcept)
633 S.Diag(D->getBeginLoc(), diag::warn_perf_constraint_implies_noexcept)
634 << GetCallableDeclKind(D, nullptr) << Effect.name();
635 break;
636 }
637 }
638
639 // Build a PendingFunctionAnalysis on the stack. If it turns out to be
640 // complete, we'll have avoided a heap allocation; if it's incomplete, it's
641 // a fairly trivial move to a heap-allocated object.
642 PendingFunctionAnalysis FAnalysis(S, CInfo, AllInferrableEffectsToVerify);
643
644 LLVM_DEBUG(llvm::dbgs()
645 << "\nVerifying " << CInfo.getNameForDiagnostic(S) << " ";
646 FAnalysis.dump(S, llvm::dbgs()););
647
648 FunctionBodyASTVisitor Visitor(*this, FAnalysis, CInfo);
649
650 Visitor.run();
651 if (FAnalysis.isComplete()) {
652 completeAnalysis(CInfo, std::move(FAnalysis));
653 return nullptr;
654 }
655 // Move the pending analysis to the heap and save it in the map.
656 PendingFunctionAnalysis *PendingPtr =
657 new PendingFunctionAnalysis(std::move(FAnalysis));
658 DeclAnalysis[D] = PendingPtr;
659 LLVM_DEBUG(llvm::dbgs() << "inserted pending " << PendingPtr << "\n";
660 DeclAnalysis.dump(S, llvm::dbgs()););
661 return PendingPtr;
662 }
663
664 // Consume PendingFunctionAnalysis, create with it a CompleteFunctionAnalysis,
665 // inserted in the container.
666 void completeAnalysis(const CallableInfo &CInfo,
667 PendingFunctionAnalysis &&Pending) {
668 if (ArrayRef<Violation> Viols =
669 Pending.getSortedViolationsForExplicitEffects(S.getSourceManager());
670 !Viols.empty())
671 emitDiagnostics(Viols, CInfo);
672
673 CompleteFunctionAnalysis *CompletePtr = new CompleteFunctionAnalysis(
674 S.getASTContext(), std::move(Pending), CInfo.Effects,
675 AllInferrableEffectsToVerify);
676 DeclAnalysis[CInfo.CDecl] = CompletePtr;
677 LLVM_DEBUG(llvm::dbgs() << "inserted complete " << CompletePtr << "\n";
678 DeclAnalysis.dump(S, llvm::dbgs()););
679 }
680
681 // Called after all direct calls requiring inference have been found -- or
682 // not. Repeats calls to FunctionBodyASTVisitor::followCall() but without
683 // the possibility of inference. Deletes Pending.
684 void finishPendingAnalysis(const Decl *D, PendingFunctionAnalysis *Pending) {
685 CallableInfo Caller(*D);
686 LLVM_DEBUG(llvm::dbgs() << "finishPendingAnalysis for "
687 << Caller.getNameForDiagnostic(S) << " : ";
688 Pending->dump(S, llvm::dbgs()); llvm::dbgs() << "\n";);
689 for (const PendingFunctionAnalysis::DirectCall &Call :
690 Pending->unverifiedCalls()) {
691 if (Call.Recursed)
692 continue;
693
694 CallableInfo Callee(*Call.Callee);
695 followCall(Caller, *Pending, Callee, Call.CallLoc,
696 /*AssertNoFurtherInference=*/true, Call.VSite);
697 }
698 completeAnalysis(Caller, std::move(*Pending));
699 delete Pending;
700 }
701
702 // Here we have a call to a Decl, either explicitly via a CallExpr or some
703 // other AST construct. PFA pertains to the caller.
704 void followCall(const CallableInfo &Caller, PendingFunctionAnalysis &PFA,
705 const CallableInfo &Callee, SourceLocation CallLoc,
706 bool AssertNoFurtherInference, ViolationSite VSite) {
707 const bool DirectCall = Callee.isCalledDirectly();
708
709 // Initially, the declared effects; inferred effects will be added.
710 FunctionEffectKindSet CalleeEffects = Callee.Effects;
711
712 bool IsInferencePossible = DirectCall;
713
714 if (DirectCall)
715 if (CompleteFunctionAnalysis *CFA =
716 DeclAnalysis.completedAnalysisForDecl(Callee.CDecl)) {
717 // Combine declared effects with those which may have been inferred.
718 CalleeEffects.insert(CFA->VerifiedEffects);
719 IsInferencePossible = false; // We've already traversed it.
720 }
721
722 if (AssertNoFurtherInference) {
723 assert(!IsInferencePossible);
724 }
725
726 if (!Callee.isVerifiable())
727 IsInferencePossible = false;
728
729 LLVM_DEBUG(llvm::dbgs()
730 << "followCall from " << Caller.getNameForDiagnostic(S)
731 << " to " << Callee.getNameForDiagnostic(S)
732 << "; verifiable: " << Callee.isVerifiable() << "; callee ";
733 CalleeEffects.dump(llvm::dbgs()); llvm::dbgs() << "\n";
734 llvm::dbgs() << " callee " << Callee.CDecl << " canonical "
735 << Callee.CDecl->getCanonicalDecl() << "\n";);
736
737 auto Check1Effect = [&](FunctionEffect Effect, bool Inferring) {
738 if (!Effect.shouldDiagnoseFunctionCall(DirectCall, CalleeEffects))
739 return;
740
741 // If inference is not allowed, or the target is indirect (virtual
742 // method/function ptr?), generate a Violation now.
743 if (!IsInferencePossible ||
745 if (Callee.FuncType == SpecialFuncType::None)
746 PFA.checkAddViolation(Inferring,
747 {Effect, ViolationID::CallsDeclWithoutEffect,
748 VSite, CallLoc, Callee.CDecl});
749 else
750 PFA.checkAddViolation(
751 Inferring,
752 {Effect, ViolationID::AllocatesMemory, VSite, CallLoc});
753 } else {
754 // Inference is allowed and necessary; defer it.
755 PFA.addUnverifiedDirectCall(Callee.CDecl, CallLoc, VSite);
756 }
757 };
758
759 for (FunctionEffect Effect : PFA.DeclaredVerifiableEffects)
760 Check1Effect(Effect, false);
761
762 for (FunctionEffect Effect : PFA.EffectsToInfer)
763 Check1Effect(Effect, true);
764 }
765
766 // Describe a callable Decl for a diagnostic.
767 // (Not an enum class because the value is always converted to an integer for
768 // use in a diagnostic.)
769 enum CallableDeclKind {
770 CDK_Function,
771 CDK_Constructor,
772 CDK_Destructor,
773 CDK_Lambda,
774 CDK_Block,
775 CDK_MemberInitializer,
776 };
777
778 // Describe a call site or target using an enum mapping to a %select{}
779 // in a diagnostic, e.g. warn_func_effect_violation,
780 // warn_perf_constraint_implies_noexcept, and others.
781 static CallableDeclKind GetCallableDeclKind(const Decl *D,
782 const Violation *V) {
783 if (V != nullptr &&
784 V->Site.kind() == ViolationSite::Kind::MemberInitializer)
785 return CDK_MemberInitializer;
786 if (isa<BlockDecl>(D))
787 return CDK_Block;
788 if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
789 if (isa<CXXConstructorDecl>(D))
790 return CDK_Constructor;
791 if (isa<CXXDestructorDecl>(D))
792 return CDK_Destructor;
793 const CXXRecordDecl *Rec = Method->getParent();
794 if (Rec->isLambda())
795 return CDK_Lambda;
796 }
797 return CDK_Function;
798 };
799
800 // Should only be called when function's analysis is determined to be
801 // complete.
802 void emitDiagnostics(ArrayRef<Violation> Viols, const CallableInfo &CInfo) {
803 if (Viols.empty())
804 return;
805
806 auto MaybeAddTemplateNote = [&](const Decl *D) {
807 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
808 while (FD != nullptr && FD->isTemplateInstantiation() &&
811 diag::note_func_effect_from_template);
813 }
814 }
815 };
816
817 // For note_func_effect_call_indirect.
818 enum { Indirect_VirtualMethod, Indirect_FunctionPtr };
819
820 auto MaybeAddSiteContext = [&](const Decl *D, const Violation &V) {
821 // If a violation site is a member initializer, add a note pointing to
822 // the constructor which invoked it.
823 if (V.Site.kind() == ViolationSite::Kind::MemberInitializer) {
824 unsigned ImplicitCtor = 0;
825 if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D);
826 Ctor && Ctor->isImplicit())
827 ImplicitCtor = 1;
828 S.Diag(D->getLocation(), diag::note_func_effect_in_constructor)
829 << ImplicitCtor;
830 }
831
832 // If a violation site is a default argument expression, add a note
833 // pointing to the call site using the default argument.
834 else if (V.Site.kind() == ViolationSite::Kind::DefaultArgExpr)
835 S.Diag(V.Site.defaultArgExpr()->getUsedLocation(),
836 diag::note_in_evaluating_default_argument);
837 };
838
839 // Top-level violations are warnings.
840 for (const Violation &Viol1 : Viols) {
841 StringRef effectName = Viol1.Effect.name();
842 switch (Viol1.ID) {
843 case ViolationID::None:
844 case ViolationID::DeclDisallowsInference: // Shouldn't happen
845 // here.
846 llvm_unreachable("Unexpected violation kind");
847 break;
848 case ViolationID::AllocatesMemory:
849 case ViolationID::ThrowsOrCatchesExceptions:
850 case ViolationID::HasStaticLocalVariable:
851 case ViolationID::AccessesThreadLocalVariable:
852 case ViolationID::AccessesObjCMethodOrProperty:
853 S.Diag(Viol1.Loc, diag::warn_func_effect_violation)
854 << GetCallableDeclKind(CInfo.CDecl, &Viol1) << effectName
855 << Viol1.diagnosticSelectIndex();
856 MaybeAddSiteContext(CInfo.CDecl, Viol1);
857 MaybeAddTemplateNote(CInfo.CDecl);
858 break;
859 case ViolationID::CallsExprWithoutEffect:
860 S.Diag(Viol1.Loc, diag::warn_func_effect_calls_expr_without_effect)
861 << GetCallableDeclKind(CInfo.CDecl, &Viol1) << effectName;
862 MaybeAddSiteContext(CInfo.CDecl, Viol1);
863 MaybeAddTemplateNote(CInfo.CDecl);
864 break;
865
866 case ViolationID::CallsDeclWithoutEffect: {
867 CallableInfo CalleeInfo(*Viol1.Callee);
868 std::string CalleeName = CalleeInfo.getNameForDiagnostic(S);
869
870 S.Diag(Viol1.Loc, diag::warn_func_effect_calls_func_without_effect)
871 << GetCallableDeclKind(CInfo.CDecl, &Viol1) << effectName
872 << GetCallableDeclKind(CalleeInfo.CDecl, nullptr) << CalleeName;
873 MaybeAddSiteContext(CInfo.CDecl, Viol1);
874 MaybeAddTemplateNote(CInfo.CDecl);
875
876 // Emit notes explaining the transitive chain of inferences: Why isn't
877 // the callee safe?
878 for (const Decl *Callee = Viol1.Callee; Callee != nullptr;) {
879 std::optional<CallableInfo> MaybeNextCallee;
880 CompleteFunctionAnalysis *Completed =
881 DeclAnalysis.completedAnalysisForDecl(CalleeInfo.CDecl);
882 if (Completed == nullptr) {
883 // No result - could be
884 // - non-inline and extern
885 // - indirect (virtual or through function pointer)
886 // - effect has been explicitly disclaimed (e.g. "blocking")
887
888 CallableType CType = CalleeInfo.type();
889 if (CType == CallableType::Virtual)
890 S.Diag(Callee->getLocation(),
891 diag::note_func_effect_call_indirect)
892 << Indirect_VirtualMethod << effectName;
893 else if (CType == CallableType::Unknown)
894 S.Diag(Callee->getLocation(),
895 diag::note_func_effect_call_indirect)
896 << Indirect_FunctionPtr << effectName;
897 else if (CalleeInfo.Effects.contains(Viol1.Effect.oppositeKind()))
898 S.Diag(Callee->getLocation(),
899 diag::note_func_effect_call_disallows_inference)
900 << GetCallableDeclKind(CInfo.CDecl, nullptr) << effectName
901 << FunctionEffect(Viol1.Effect.oppositeKind()).name();
902 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Callee);
903 FD == nullptr || FD->getBuiltinID() == 0) {
904 // A builtin callee generally doesn't have a useful source
905 // location at which to insert a note.
906 S.Diag(Callee->getLocation(), diag::note_func_effect_call_extern)
907 << effectName;
908 }
909 break;
910 }
911 const Violation *PtrViol2 =
912 Completed->firstViolationForEffect(Viol1.Effect);
913 if (PtrViol2 == nullptr)
914 break;
915
916 const Violation &Viol2 = *PtrViol2;
917 switch (Viol2.ID) {
918 case ViolationID::None:
919 llvm_unreachable("Unexpected violation kind");
920 break;
921 case ViolationID::DeclDisallowsInference:
922 S.Diag(Viol2.Loc, diag::note_func_effect_call_disallows_inference)
923 << GetCallableDeclKind(CalleeInfo.CDecl, nullptr) << effectName
924 << Viol2.CalleeEffectPreventingInference->name();
925 break;
926 case ViolationID::CallsExprWithoutEffect:
927 S.Diag(Viol2.Loc, diag::note_func_effect_call_indirect)
928 << Indirect_FunctionPtr << effectName;
929 break;
930 case ViolationID::AllocatesMemory:
931 case ViolationID::ThrowsOrCatchesExceptions:
932 case ViolationID::HasStaticLocalVariable:
933 case ViolationID::AccessesThreadLocalVariable:
934 case ViolationID::AccessesObjCMethodOrProperty:
935 S.Diag(Viol2.Loc, diag::note_func_effect_violation)
936 << GetCallableDeclKind(CalleeInfo.CDecl, &Viol2) << effectName
937 << Viol2.diagnosticSelectIndex();
938 MaybeAddSiteContext(CalleeInfo.CDecl, Viol2);
939 break;
940 case ViolationID::CallsDeclWithoutEffect:
941 MaybeNextCallee.emplace(*Viol2.Callee);
942 S.Diag(Viol2.Loc, diag::note_func_effect_calls_func_without_effect)
943 << GetCallableDeclKind(CalleeInfo.CDecl, &Viol2) << effectName
944 << GetCallableDeclKind(Viol2.Callee, nullptr)
945 << MaybeNextCallee->getNameForDiagnostic(S);
946 break;
947 }
948 MaybeAddTemplateNote(Callee);
949 Callee = Viol2.Callee;
950 if (MaybeNextCallee) {
951 CalleeInfo = *MaybeNextCallee;
952 CalleeName = CalleeInfo.getNameForDiagnostic(S);
953 }
954 }
955 } break;
956 }
957 }
958 }
959
960 // ----------
961 // This AST visitor is used to traverse the body of a function during effect
962 // verification. This happens in 2 situations:
963 // [1] The function has declared effects which need to be validated.
964 // [2] The function has not explicitly declared an effect in question, and is
965 // being checked for implicit conformance.
966 //
967 // Violations are always routed to a PendingFunctionAnalysis.
968 struct FunctionBodyASTVisitor : DynamicRecursiveASTVisitor {
969 Analyzer &Outer;
970 PendingFunctionAnalysis &CurrentFunction;
971 CallableInfo &CurrentCaller;
972 ViolationSite VSite;
973 const Expr *TrailingRequiresClause = nullptr;
974 const Expr *NoexceptExpr = nullptr;
975
976 FunctionBodyASTVisitor(Analyzer &Outer,
977 PendingFunctionAnalysis &CurrentFunction,
978 CallableInfo &CurrentCaller)
979 : Outer(Outer), CurrentFunction(CurrentFunction),
980 CurrentCaller(CurrentCaller) {
981 ShouldVisitImplicitCode = true;
982 ShouldWalkTypesOfTypeLocs = false;
983 }
984
985 // -- Entry point --
986 void run() {
987 // The target function may have implicit code paths beyond the
988 // body: member and base destructors. Visit these first.
989 if (auto *Dtor = dyn_cast<CXXDestructorDecl>(CurrentCaller.CDecl))
990 followDestructor(dyn_cast<CXXRecordDecl>(Dtor->getParent()), Dtor);
991
992 if (auto *FD = dyn_cast<FunctionDecl>(CurrentCaller.CDecl)) {
993 TrailingRequiresClause = FD->getTrailingRequiresClause();
994
995 // Note that FD->getType->getAs<FunctionProtoType>() can yield a
996 // noexcept Expr which has been boiled down to a constant expression.
997 // Going through the TypeSourceInfo obtains the actual expression which
998 // will be traversed as part of the function -- unless we capture it
999 // here and have TraverseStmt skip it.
1000 if (TypeSourceInfo *TSI = FD->getTypeSourceInfo()) {
1001 if (FunctionProtoTypeLoc TL =
1002 TSI->getTypeLoc().getAs<FunctionProtoTypeLoc>())
1003 if (const FunctionProtoType *FPT = TL.getTypePtr())
1004 NoexceptExpr = FPT->getNoexceptExpr();
1005 }
1006 }
1007
1008 // Do an AST traversal of the function/block body
1009 TraverseDecl(const_cast<Decl *>(CurrentCaller.CDecl));
1010 }
1011
1012 // -- Methods implementing common logic --
1013
1014 // Handle a language construct forbidden by some effects. Only effects whose
1015 // flags include the specified flag receive a violation. \p Flag describes
1016 // the construct.
1017 void diagnoseLanguageConstruct(FunctionEffect::FlagBit Flag,
1018 ViolationID VID, SourceLocation Loc,
1019 const Decl *Callee = nullptr) {
1020 // If there are any declared verifiable effects which forbid the construct
1021 // represented by the flag, store just one violation.
1022 for (FunctionEffect Effect : CurrentFunction.DeclaredVerifiableEffects) {
1023 if (Effect.flags() & Flag) {
1024 addViolation(/*inferring=*/false, Effect, VID, Loc, Callee);
1025 break;
1026 }
1027 }
1028 // For each inferred effect which forbids the construct, store a
1029 // violation, if we don't already have a violation for that effect.
1030 for (FunctionEffect Effect : CurrentFunction.EffectsToInfer)
1031 if (Effect.flags() & Flag)
1032 addViolation(/*inferring=*/true, Effect, VID, Loc, Callee);
1033 }
1034
1035 void addViolation(bool Inferring, FunctionEffect Effect, ViolationID VID,
1036 SourceLocation Loc, const Decl *Callee = nullptr) {
1037 CurrentFunction.checkAddViolation(
1038 Inferring, Violation(Effect, VID, VSite, Loc, Callee));
1039 }
1040
1041 // Here we have a call to a Decl, either explicitly via a CallExpr or some
1042 // other AST construct. CallableInfo pertains to the callee.
1043 void followCall(CallableInfo &CI, SourceLocation CallLoc) {
1044 // Check for a call to a builtin function, whose effects are
1045 // handled specially.
1046 if (const auto *FD = dyn_cast<FunctionDecl>(CI.CDecl)) {
1047 if (unsigned BuiltinID = FD->getBuiltinID()) {
1048 CI.Effects = getBuiltinFunctionEffects(BuiltinID);
1049 if (CI.Effects.empty()) {
1050 // A builtin with no known effects is assumed safe.
1051 return;
1052 }
1053 // A builtin WITH effects doesn't get any special treatment for
1054 // being noreturn/noexcept, e.g. longjmp(), so we skip the check
1055 // below.
1056 } else {
1057 // If the callee is both `noreturn` and `noexcept`, it presumably
1058 // terminates. Ignore it for the purposes of effect analysis.
1059 // If not C++, `noreturn` alone is sufficient.
1060 if (FD->isNoReturn() &&
1061 (!Outer.S.getLangOpts().CPlusPlus || isNoexcept(FD)))
1062 return;
1063 }
1064 }
1065
1066 Outer.followCall(CurrentCaller, CurrentFunction, CI, CallLoc,
1067 /*AssertNoFurtherInference=*/false, VSite);
1068 }
1069
1070 void checkIndirectCall(CallExpr *Call, QualType CalleeType) {
1071 FunctionEffectKindSet CalleeEffects;
1072 if (FunctionEffectsRef Effects = FunctionEffectsRef::get(CalleeType);
1073 !Effects.empty())
1074 CalleeEffects.insert(Effects);
1075
1076 auto Check1Effect = [&](FunctionEffect Effect, bool Inferring) {
1077 if (Effect.shouldDiagnoseFunctionCall(
1078 /*direct=*/false, CalleeEffects))
1079 addViolation(Inferring, Effect, ViolationID::CallsExprWithoutEffect,
1080 Call->getBeginLoc());
1081 };
1082
1083 for (FunctionEffect Effect : CurrentFunction.DeclaredVerifiableEffects)
1084 Check1Effect(Effect, false);
1085
1086 for (FunctionEffect Effect : CurrentFunction.EffectsToInfer)
1087 Check1Effect(Effect, true);
1088 }
1089
1090 // This destructor's body should be followed by the caller, but here we
1091 // follow the field and base destructors.
1092 void followDestructor(const CXXRecordDecl *Rec,
1093 const CXXDestructorDecl *Dtor) {
1094 SourceLocation DtorLoc = Dtor->getLocation();
1095 for (const FieldDecl *Field : Rec->fields())
1096 followTypeDtor(Field->getType(), DtorLoc);
1097
1098 if (const auto *Class = dyn_cast<CXXRecordDecl>(Rec))
1099 for (const CXXBaseSpecifier &Base : Class->bases())
1100 followTypeDtor(Base.getType(), DtorLoc);
1101 }
1102
1103 void followTypeDtor(QualType QT, SourceLocation CallSite) {
1104 const Type *Ty = QT.getTypePtr();
1105 while (Ty->isArrayType()) {
1106 const ArrayType *Arr = Ty->getAsArrayTypeUnsafe();
1107 QT = Arr->getElementType();
1108 Ty = QT.getTypePtr();
1109 }
1110
1111 if (Ty->isRecordType()) {
1112 if (const CXXRecordDecl *Class = Ty->getAsCXXRecordDecl()) {
1113 if (CXXDestructorDecl *Dtor = Class->getDestructor();
1114 Dtor && !Dtor->isDeleted()) {
1115 CallableInfo CI(*Dtor);
1116 followCall(CI, CallSite);
1117 }
1118 }
1119 }
1120 }
1121
1122 // -- Methods for use of RecursiveASTVisitor --
1123
1124 bool VisitCXXThrowExpr(CXXThrowExpr *Throw) override {
1125 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow,
1126 ViolationID::ThrowsOrCatchesExceptions,
1127 Throw->getThrowLoc());
1128 return true;
1129 }
1130
1131 bool VisitCXXCatchStmt(CXXCatchStmt *Catch) override {
1132 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1133 ViolationID::ThrowsOrCatchesExceptions,
1134 Catch->getCatchLoc());
1135 return true;
1136 }
1137
1138 bool VisitObjCAtThrowStmt(ObjCAtThrowStmt *Throw) override {
1139 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow,
1140 ViolationID::ThrowsOrCatchesExceptions,
1141 Throw->getThrowLoc());
1142 return true;
1143 }
1144
1145 bool VisitObjCAtCatchStmt(ObjCAtCatchStmt *Catch) override {
1146 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1147 ViolationID::ThrowsOrCatchesExceptions,
1148 Catch->getAtCatchLoc());
1149 return true;
1150 }
1151
1152 bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Finally) override {
1153 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1154 ViolationID::ThrowsOrCatchesExceptions,
1155 Finally->getAtFinallyLoc());
1156 return true;
1157 }
1158
1159 bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) override {
1160 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1161 ViolationID::AccessesObjCMethodOrProperty,
1162 Msg->getBeginLoc());
1163 return true;
1164 }
1165
1166 bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *ARP) override {
1167 // Under the hood, @autorelease (potentially?) allocates memory and
1168 // invokes ObjC methods. We don't currently have memory allocation as
1169 // a "language construct" but we do have ObjC messaging, so diagnose that.
1170 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1171 ViolationID::AccessesObjCMethodOrProperty,
1172 ARP->getBeginLoc());
1173 return true;
1174 }
1175
1176 bool VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Sync) override {
1177 // Under the hood, this calls objc_sync_enter and objc_sync_exit, wrapped
1178 // in a @try/@finally block. Diagnose this generically as "ObjC
1179 // messaging".
1180 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1181 ViolationID::AccessesObjCMethodOrProperty,
1182 Sync->getBeginLoc());
1183 return true;
1184 }
1185
1186 bool VisitSEHExceptStmt(SEHExceptStmt *Exc) override {
1187 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1188 ViolationID::ThrowsOrCatchesExceptions,
1189 Exc->getExceptLoc());
1190 return true;
1191 }
1192
1193 bool VisitCallExpr(CallExpr *Call) override {
1194 LLVM_DEBUG(llvm::dbgs()
1195 << "VisitCallExpr : "
1196 << Call->getBeginLoc().printToString(Outer.S.SourceMgr)
1197 << "\n";);
1198
1199 Expr *CalleeExpr = Call->getCallee();
1200 if (const Decl *Callee = CalleeExpr->getReferencedDeclOfCallee()) {
1201 CallableInfo CI(*Callee);
1202 followCall(CI, Call->getBeginLoc());
1203 return true;
1204 }
1205
1206 if (isa<CXXPseudoDestructorExpr>(CalleeExpr)) {
1207 // Just destroying a scalar, fine.
1208 return true;
1209 }
1210
1211 // No Decl, just an Expr. Just check based on its type.
1212 checkIndirectCall(Call, CalleeExpr->getType());
1213
1214 return true;
1215 }
1216
1217 bool VisitVarDecl(VarDecl *Var) override {
1218 LLVM_DEBUG(llvm::dbgs()
1219 << "VisitVarDecl : "
1220 << Var->getBeginLoc().printToString(Outer.S.SourceMgr)
1221 << "\n";);
1222
1223 if (Var->isStaticLocal())
1224 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeStaticLocalVars,
1225 ViolationID::HasStaticLocalVariable,
1226 Var->getLocation());
1227
1228 const QualType::DestructionKind DK =
1229 Var->needsDestruction(Outer.S.getASTContext());
1231 followTypeDtor(Var->getType(), Var->getLocation());
1232 return true;
1233 }
1234
1235 bool VisitCXXNewExpr(CXXNewExpr *New) override {
1236 // RecursiveASTVisitor does not visit the implicit call to operator new.
1237 if (FunctionDecl *FD = New->getOperatorNew()) {
1238 CallableInfo CI(*FD, SpecialFuncType::OperatorNew);
1239 followCall(CI, New->getBeginLoc());
1240 }
1241
1242 // It's a bit excessive to check operator delete here, since it's
1243 // just a fallback for operator new followed by a failed constructor.
1244 // We could check it via New->getOperatorDelete().
1245
1246 // It DOES however visit the called constructor
1247 return true;
1248 }
1249
1250 bool VisitCXXDeleteExpr(CXXDeleteExpr *Delete) override {
1251 // RecursiveASTVisitor does not visit the implicit call to operator
1252 // delete.
1253 if (FunctionDecl *FD = Delete->getOperatorDelete()) {
1254 CallableInfo CI(*FD, SpecialFuncType::OperatorDelete);
1255 followCall(CI, Delete->getBeginLoc());
1256 }
1257
1258 // It DOES however visit the called destructor
1259
1260 return true;
1261 }
1262
1263 bool VisitCXXConstructExpr(CXXConstructExpr *Construct) override {
1264 LLVM_DEBUG(llvm::dbgs() << "VisitCXXConstructExpr : "
1265 << Construct->getBeginLoc().printToString(
1266 Outer.S.SourceMgr)
1267 << "\n";);
1268
1269 // RecursiveASTVisitor does not visit the implicit call to the
1270 // constructor.
1271 const CXXConstructorDecl *Ctor = Construct->getConstructor();
1272 CallableInfo CI(*Ctor);
1273 followCall(CI, Construct->getLocation());
1274
1275 return true;
1276 }
1277
1278 bool TraverseStmt(Stmt *Statement) override {
1279 // If this statement is a `requires` clause from the top-level function
1280 // being traversed, ignore it, since it's not generating runtime code.
1281 // We skip the traversal of lambdas (beyond their captures, see
1282 // TraverseLambdaExpr below), so just caching this from our constructor
1283 // should suffice.
1284 if (Statement != TrailingRequiresClause && Statement != NoexceptExpr)
1286 return true;
1287 }
1288
1289 bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
1290 ViolationSite PrevVS = VSite;
1291 if (Init->isAnyMemberInitializer())
1292 VSite.setKind(ViolationSite::Kind::MemberInitializer);
1293 bool Result =
1295 VSite = PrevVS;
1296 return Result;
1297 }
1298
1299 bool TraverseCXXDefaultArgExpr(CXXDefaultArgExpr *E) override {
1300 LLVM_DEBUG(llvm::dbgs()
1301 << "TraverseCXXDefaultArgExpr : "
1302 << E->getUsedLocation().printToString(Outer.S.SourceMgr)
1303 << "\n";);
1304
1305 ViolationSite PrevVS = VSite;
1306 if (VSite.kind() == ViolationSite::Kind::Default)
1307 VSite = ViolationSite{E};
1308
1309 bool Result = DynamicRecursiveASTVisitor::TraverseCXXDefaultArgExpr(E);
1310 VSite = PrevVS;
1311 return Result;
1312 }
1313
1314 bool TraverseLambdaExpr(LambdaExpr *Lambda) override {
1315 // We override this so as to be able to skip traversal of the lambda's
1316 // body. We have to explicitly traverse the captures. Why not return
1317 // false from shouldVisitLambdaBody()? Because we need to visit a lambda's
1318 // body when we are verifying the lambda itself; we only want to skip it
1319 // in the context of the outer function.
1320 for (unsigned I = 0, N = Lambda->capture_size(); I < N; ++I)
1321 TraverseLambdaCapture(Lambda, Lambda->capture_begin() + I,
1322 Lambda->capture_init_begin()[I]);
1323
1324 return true;
1325 }
1326
1327 bool TraverseBlockExpr(BlockExpr * /*unused*/) override {
1328 // As with lambdas, don't traverse the block's body.
1329 // TODO: are the capture expressions (ctor call?) safe?
1330 return true;
1331 }
1332
1333 bool VisitDeclRefExpr(DeclRefExpr *E) override {
1334 const ValueDecl *Val = E->getDecl();
1335 if (const auto *Var = dyn_cast<VarDecl>(Val)) {
1336 if (Var->getTLSKind() != VarDecl::TLS_None) {
1337 // At least on macOS, thread-local variables are initialized on
1338 // first access, including a heap allocation.
1339 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThreadLocalVars,
1340 ViolationID::AccessesThreadLocalVariable,
1341 E->getLocation());
1342 }
1343 }
1344 return true;
1345 }
1346
1347 bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) override {
1348 return TraverseStmt(Node->getResultExpr());
1349 }
1350 bool
1351 TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override {
1352 return true;
1353 }
1354
1355 bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) override {
1356 return true;
1357 }
1358
1359 bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) override { return true; }
1360
1361 bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override {
1362 return true;
1363 }
1364
1365 bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) override { return true; }
1366
1367 // Skip concept requirements since they don't generate code.
1368 bool TraverseConceptRequirement(concepts::Requirement *R) override {
1369 return true;
1370 }
1371 };
1372};
1373
1374Analyzer::AnalysisMap::~AnalysisMap() {
1375 for (const auto &Item : *this) {
1376 FuncAnalysisPtr AP = Item.second;
1377 if (auto *PFA = dyn_cast<PendingFunctionAnalysis *>(AP))
1378 delete PFA;
1379 else
1380 delete cast<CompleteFunctionAnalysis *>(AP);
1381 }
1382}
1383
1384} // anonymous namespace
1385
1386namespace clang {
1387
1389 const FunctionEffectsRef &FX, const FunctionEffectWithCondition &NewEC,
1390 SourceLocation NewAttrLoc) {
1391 // If the new effect has a condition, we can't detect conflicts until the
1392 // condition is resolved.
1393 if (NewEC.Cond.getCondition() != nullptr)
1394 return false;
1395
1396 // Diagnose the new attribute as incompatible with a previous one.
1397 auto Incompatible = [&](const FunctionEffectWithCondition &PrevEC) {
1398 Diag(NewAttrLoc, diag::err_attributes_are_not_compatible)
1399 << ("'" + NewEC.description() + "'")
1400 << ("'" + PrevEC.description() + "'") << false;
1401 // We don't necessarily have the location of the previous attribute,
1402 // so no note.
1403 return true;
1404 };
1405
1406 // Compare against previous attributes.
1407 FunctionEffect::Kind NewKind = NewEC.Effect.kind();
1408
1409 for (const FunctionEffectWithCondition &PrevEC : FX) {
1410 // Again, can't check yet when the effect is conditional.
1411 if (PrevEC.Cond.getCondition() != nullptr)
1412 continue;
1413
1414 FunctionEffect::Kind PrevKind = PrevEC.Effect.kind();
1415 // Note that we allow PrevKind == NewKind; it's redundant and ignored.
1416
1417 if (PrevEC.Effect.oppositeKind() == NewKind)
1418 return Incompatible(PrevEC);
1419
1420 // A new allocating is incompatible with a previous nonblocking.
1421 if (PrevKind == FunctionEffect::Kind::NonBlocking &&
1423 return Incompatible(PrevEC);
1424
1425 // A new nonblocking is incompatible with a previous allocating.
1426 if (PrevKind == FunctionEffect::Kind::Allocating &&
1428 return Incompatible(PrevEC);
1429 }
1430
1431 return false;
1432}
1433
1435 const FunctionEffectSet::Conflicts &Errs, SourceLocation NewLoc,
1436 SourceLocation OldLoc) {
1437 for (const FunctionEffectSet::Conflict &Conflict : Errs) {
1438 Diag(NewLoc, diag::warn_conflicting_func_effects)
1439 << Conflict.Kept.description() << Conflict.Rejected.description();
1440 Diag(OldLoc, diag::note_previous_declaration);
1441 }
1442}
1443
1444// Decl should be a FunctionDecl or BlockDecl.
1446 const FunctionEffectsRef &FX) {
1447 if (!D->hasBody()) {
1448 if (const auto *FD = D->getAsFunction(); FD && !FD->willHaveBody())
1449 return;
1450 }
1451
1455 return;
1456
1458 return;
1459
1460 // For code in dependent contexts, we'll do this at instantiation time.
1461 // Without this check, we would analyze the function based on placeholder
1462 // template parameters, and potentially generate spurious diagnostics.
1463 if (cast<DeclContext>(D)->isDependentContext())
1464 return;
1465
1466 addDeclWithEffects(D, FX);
1467}
1468
1470 // To avoid the possibility of conflict, don't add effects which are
1471 // not FE_InferrableOnCallees and therefore not verified; this removes
1472 // blocking/allocating but keeps nonblocking/nonallocating.
1473 // Also, ignore any conditions when building the list of effects.
1474 bool AnyVerifiable = false;
1475 for (const FunctionEffectWithCondition &EC : FX)
1476 if (EC.Effect.flags() & FunctionEffect::FE_InferrableOnCallees) {
1477 AllEffectsToVerify.insert(EC.Effect);
1478 AnyVerifiable = true;
1479 }
1480
1481 // Record the declaration for later analysis.
1482 if (AnyVerifiable)
1483 DeclsWithEffectsToVerify.push_back(D);
1484}
1485
1488 return;
1489 if (TU == nullptr)
1490 return;
1491 Analyzer{*this}.run(*TU);
1492}
1493
1495 const FunctionEffectsRef &Old, const FunctionEffectsRef &New) {
1496
1498 FunctionEffectsRef::iterator OldEnd = Old.end();
1500 FunctionEffectsRef::iterator NewEnd = New.end();
1501
1502 while (true) {
1503 int cmp = 0;
1504 if (POld == OldEnd) {
1505 if (PNew == NewEnd)
1506 break;
1507 cmp = 1;
1508 } else if (PNew == NewEnd)
1509 cmp = -1;
1510 else {
1511 FunctionEffectWithCondition Old = *POld;
1512 FunctionEffectWithCondition New = *PNew;
1513 if (Old.Effect.kind() < New.Effect.kind())
1514 cmp = -1;
1515 else if (New.Effect.kind() < Old.Effect.kind())
1516 cmp = 1;
1517 else {
1518 cmp = 0;
1519 if (Old.Cond.getCondition() != New.Cond.getCondition()) {
1520 // FIXME: Cases where the expressions are equivalent but
1521 // don't have the same identity.
1522 push_back(FunctionEffectDiff{
1524 Old, New});
1525 }
1526 }
1527 }
1528
1529 if (cmp < 0) {
1530 // removal
1531 FunctionEffectWithCondition Old = *POld;
1532 push_back(FunctionEffectDiff{Old.Effect.kind(),
1534 std::nullopt});
1535 ++POld;
1536 } else if (cmp > 0) {
1537 // addition
1538 FunctionEffectWithCondition New = *PNew;
1539 push_back(FunctionEffectDiff{New.Effect.kind(),
1541 std::nullopt, New});
1542 ++PNew;
1543 } else {
1544 ++POld;
1545 ++PNew;
1546 }
1547 }
1548}
1549
1551 QualType SrcType, const FunctionEffectsRef &SrcFX, QualType DstType,
1552 const FunctionEffectsRef &DstFX) const {
1553
1554 switch (EffectKind) {
1556 // nonallocating can't be added (spoofed) during a conversion, unless we
1557 // have nonblocking.
1558 if (DiffKind == Kind::Added) {
1559 for (const auto &CFE : SrcFX) {
1560 if (CFE.Effect.kind() == FunctionEffect::Kind::NonBlocking)
1561 return false;
1562 }
1563 }
1564 [[fallthrough]];
1566 // nonblocking can't be added (spoofed) during a conversion.
1567 switch (DiffKind) {
1568 case Kind::Added:
1569 return true;
1570 case Kind::Removed:
1571 return false;
1572 case Kind::ConditionMismatch:
1573 // FIXME: Condition mismatches are too coarse right now -- expressions
1574 // which are equivalent but don't have the same identity are detected as
1575 // mismatches. We're going to diagnose those anyhow until expression
1576 // matching is better.
1577 return true;
1578 }
1579 break;
1582 return false;
1583 }
1584 llvm_unreachable("unknown effect kind");
1585}
1586
1588 const FunctionDecl &OldFunction, const FunctionEffectsRef &OldFX,
1589 const FunctionDecl &NewFunction, const FunctionEffectsRef &NewFX) const {
1590 switch (EffectKind) {
1593 // nonblocking/nonallocating can't be removed in a redeclaration.
1594 switch (DiffKind) {
1595 case Kind::Added:
1596 return false; // No diagnostic.
1597 case Kind::Removed:
1598 return true; // Issue diagnostic.
1599 case Kind::ConditionMismatch:
1600 // All these forms of mismatches are diagnosed.
1601 return true;
1602 }
1603 break;
1606 return false;
1607 }
1608 llvm_unreachable("unknown effect kind");
1609}
1610
1613 const CXXMethodDecl &OldMethod, const FunctionEffectsRef &OldFX,
1614 const CXXMethodDecl &NewMethod, const FunctionEffectsRef &NewFX) const {
1615 switch (EffectKind) {
1618 switch (DiffKind) {
1619
1620 // If added on an override, that's fine and not diagnosed.
1621 case Kind::Added:
1622 return OverrideResult::NoAction;
1623
1624 // If missing from an override (removed), propagate from base to derived.
1625 case Kind::Removed:
1626 return OverrideResult::Merge;
1627
1628 // If there's a mismatch involving the effect's polarity or condition,
1629 // issue a warning.
1630 case Kind::ConditionMismatch:
1631 return OverrideResult::Warn;
1632 }
1633 break;
1636 return OverrideResult::NoAction;
1637 }
1638 llvm_unreachable("unknown effect kind");
1639}
1640
1641} // namespace clang
#define V(N, I)
Definition: ASTContext.h:3443
DynTypedNode Node
static bool isNoexcept(const FunctionDecl *FD)
#define SM(sm)
Definition: Cuda.cpp:84
const Decl * D
Expr * E
static void dump(llvm::raw_ostream &OS, StringRef FunctionName, ArrayRef< CounterExpression > Expressions, ArrayRef< CounterMappingRegion > Regions)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
const CFGBlock * Block
Definition: HTMLLogger.cpp:152
unsigned Iter
Definition: HTMLLogger.cpp:153
static bool isExternC(const NamedDecl *ND)
Definition: Mangle.cpp:57
static void emitDiagnostics(BoundNodes &Match, const Decl *D, BugReporter &BR, AnalysisManager &AM, const ObjCAutoreleaseWriteChecker *Checker)
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines the SourceManager interface.
Defines the Objective-C statement AST node classes.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3577
QualType getElementType() const
Definition: Type.h:3589
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6414
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:28
SourceLocation getCatchLoc() const
Definition: StmtCXX.h:48
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1546
SourceLocation getLocation() const
Definition: ExprCXX.h:1611
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.cpp:562
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition: ExprCXX.h:1609
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2553
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2318
A default argument (C++ [dcl.fct.default]).
Definition: ExprCXX.h:1268
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2498
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2817
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2078
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2241
SourceLocation getBeginLoc() const
Definition: ExprCXX.h:2478
FunctionDecl * getOperatorNew() const
Definition: ExprCXX.h:2344
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition: ExprCXX.h:4126
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition: DeclCXX.h:1030
A C++ throw-expression (C++ [except.throw]).
Definition: ExprCXX.h:1206
SourceLocation getThrowLoc() const
Definition: ExprCXX.h:1229
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition: ExprCXX.h:845
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2874
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2089
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1385
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1265
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition: DeclBase.cpp:246
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
Definition: DeclBase.h:1082
SourceLocation getLocation() const
Definition: DeclBase.h:442
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:434
bool hasAttr() const
Definition: DeclBase.h:580
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:967
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Decl.h:786
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition: Decl.h:810
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:764
bool getIgnoreAllWarnings() const
Definition: Diagnostic.h:676
bool getSuppressSystemWarnings() const
Definition: Diagnostic.h:713
Recursive AST visitor that supports extension via dynamic dispatch.
virtual bool TraverseStmt(Stmt *S)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
virtual bool TraverseConstructorInitializer(CXXCtorInitializer *Init)
Recursively visit a constructor initializer.
Expr * getCondition() const
Definition: Type.h:4830
This represents one expression.
Definition: Expr.h:110
Decl * getReferencedDeclOfCallee()
Definition: Expr.cpp:1543
QualType getType() const
Definition: Expr.h:142
Represents a member of a struct/union/class.
Definition: Decl.h:3033
Represents a function declaration or definition.
Definition: Decl.h:1935
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition: Decl.cpp:3638
SourceLocation getPointOfInstantiation() const
Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...
Definition: Decl.cpp:4370
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
Definition: Decl.cpp:3531
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
Definition: Decl.cpp:4123
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition: Decl.h:2305
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:3623
bool isDeleted() const
Whether this function has been deleted.
Definition: Decl.h:2468
FunctionEffectsRef getFunctionEffects() const
Definition: Decl.h:3009
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
Definition: Decl.cpp:4116
FunctionDecl * getDefinition()
Get the definition for this declaration.
Definition: Decl.h:2217
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition: Decl.cpp:3163
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override
Appends a human-readable name for this declaration into the given stream.
Definition: Decl.cpp:3088
bool willHaveBody() const
True if this function will eventually have a body, once it's fully parsed.
Definition: Decl.h:2561
Support iteration in parallel through a pair of FunctionEffect and EffectConditionExpr containers.
Definition: Type.h:4856
A mutable set of FunctionEffect::Kind.
Definition: Type.h:4957
static FunctionEffectKindSet difference(FunctionEffectKindSet LHS, FunctionEffectKindSet RHS)
Definition: Type.h:5029
void dump(llvm::raw_ostream &OS) const
Definition: Type.cpp:5410
void insert(FunctionEffect Effect)
Definition: Type.h:5016
Represents an abstract function effect, using just an enumeration describing its kind.
Definition: Type.h:4716
Kind kind() const
The kind of the effect.
Definition: Type.h:4755
Kind
Identifies the particular effect.
Definition: Type.h:4719
Flags flags() const
Flags describing some behaviors of the effect.
Definition: Type.h:4767
bool shouldDiagnoseFunctionCall(bool Direct, FunctionEffectKindSet CalleeFX) const
Definition: Type.cpp:5261
StringRef name() const
The description printed in diagnostics, e.g. 'nonblocking'.
Definition: Type.cpp:5223
An immutable set of FunctionEffects and possibly conditions attached to them.
Definition: Type.h:4903
iterator begin() const
Definition: Type.h:4941
iterator end() const
Definition: Type.h:4942
static FunctionEffectsRef get(QualType QT)
Extract the effects from a Type if it is a function, block, or member function pointer,...
Definition: Type.h:8838
bool empty() const
Definition: Type.h:4933
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5102
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
Definition: Type.h:5474
Represents a C11 generic selection.
Definition: Expr.h:5966
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1954
capture_iterator capture_begin() const
Retrieve an iterator pointing to the first lambda capture.
Definition: ExprCXX.cpp:1344
unsigned capture_size() const
Determine the number of captures in this lambda.
Definition: ExprCXX.h:2035
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition: ExprCXX.h:2080
Represents Objective-C's @catch statement.
Definition: StmtObjC.h:77
SourceLocation getAtCatchLoc() const
Definition: StmtObjC.h:105
Represents Objective-C's @finally statement.
Definition: StmtObjC.h:127
SourceLocation getAtFinallyLoc() const
Definition: StmtObjC.h:148
Represents Objective-C's @synchronized statement.
Definition: StmtObjC.h:303
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: StmtObjC.h:339
Represents Objective-C's @throw statement.
Definition: StmtObjC.h:358
SourceLocation getThrowLoc() const LLVM_READONLY
Definition: StmtObjC.h:374
Represents Objective-C's @autoreleasepool Statement.
Definition: StmtObjC.h:394
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: StmtObjC.h:409
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:941
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprObjC.h:1447
A (possibly-)qualified type.
Definition: Type.h:929
@ DK_cxx_destructor
Definition: Type.h:1521
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7931
field_range fields() const
Definition: Decl.h:4354
SourceLocation getExceptLoc() const
Definition: Stmt.h:3643
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:60
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:463
void addDeclWithEffects(const Decl *D, const FunctionEffectsRef &FX)
Unconditionally add a Decl to DeclsWithEfffectsToVerify.
FunctionEffectKindSet AllEffectsToVerify
The union of all effects present on DeclsWithEffectsToVerify.
Definition: Sema.h:15134
ASTContext & getASTContext() const
Definition: Sema.h:531
SmallVector< const Decl * > DeclsWithEffectsToVerify
All functions/lambdas/blocks which have bodies and which have a non-empty FunctionEffectsRef to be ve...
Definition: Sema.h:15130
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition: Sema.h:816
const LangOptions & getLangOpts() const
Definition: Sema.h:524
void maybeAddDeclWithEffects(FuncOrBlockDecl *D)
Inline checks from the start of maybeAddDeclWithEffects, to minimize performance impact on code not u...
Definition: Sema.h:15153
void performFunctionEffectAnalysis(TranslationUnitDecl *TU)
@ Incompatible
Incompatible - We reject this conversion outright, it is invalid to represent it in the AST.
Definition: Sema.h:7654
SourceManager & getSourceManager() const
Definition: Sema.h:529
void diagnoseFunctionEffectMergeConflicts(const FunctionEffectSet::Conflicts &Errs, SourceLocation NewLoc, SourceLocation OldLoc)
bool diagnoseConflictingFunctionEffect(const FunctionEffectsRef &FX, const FunctionEffectWithCondition &EC, SourceLocation NewAttrLoc)
Warn and return true if adding a function effect to a set would create a conflict.
bool hasUncompilableErrorOccurred() const
Whether uncompilable error has occurred.
Definition: Sema.cpp:1684
SourceManager & SourceMgr
Definition: Sema.h:911
DiagnosticsEngine & Diags
Definition: Sema.h:910
Encodes a location in the source.
std::string printToString(const SourceManager &SM) const
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
Stmt - This represents one statement.
Definition: Stmt.h:84
The top declaration context.
Definition: Decl.h:84
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:89
A container of type source information.
Definition: Type.h:7902
The base class of the type hierarchy.
Definition: Type.h:1828
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1916
bool isArrayType() const
Definition: Type.h:8258
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:8786
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8731
bool isRecordType() const
Definition: Type.h:8286
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition: Expr.h:2622
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
QualType getType() const
Definition: Decl.h:682
Represents a variable declaration or definition.
Definition: Decl.h:882
TLSKind getTLSKind() const
Definition: Decl.cpp:2157
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1159
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
Definition: Decl.cpp:2827
@ TLS_None
Not a TLS variable.
Definition: Decl.h:902
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:168
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
@ None
The alignment was not explicit in code.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
A FunctionEffect plus a potential boolean expression determining whether the effect is declared (e....
Definition: Type.h:4840
EffectConditionExpr Cond
Definition: Type.h:4842
std::string description() const
Return a textual description of the effect, and its condition, if any.
Definition: Type.cpp:5425
FunctionEffectDiffVector(const FunctionEffectsRef &Old, const FunctionEffectsRef &New)
Caller should short-circuit by checking for equality first.
bool shouldDiagnoseConversion(QualType SrcType, const FunctionEffectsRef &SrcFX, QualType DstType, const FunctionEffectsRef &DstFX) const
Return true if adding or removing the effect as part of a type conversion should generate a diagnosti...
bool shouldDiagnoseRedeclaration(const FunctionDecl &OldFunction, const FunctionEffectsRef &OldFX, const FunctionDecl &NewFunction, const FunctionEffectsRef &NewFX) const
Return true if adding or removing the effect in a redeclaration should generate a diagnostic.
OverrideResult shouldDiagnoseMethodOverride(const CXXMethodDecl &OldMethod, const FunctionEffectsRef &OldFX, const CXXMethodDecl &NewMethod, const FunctionEffectsRef &NewFX) const
Return true if adding or removing the effect in a C++ virtual method override should generate a diagn...
OverrideResult
Describes the result of effects differing between a base class's virtual method and an overriding met...
Definition: Sema.h:15095