clang 23.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:
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:
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))
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 = dyn_cast<PendingFunctionAnalysis *>(AP)) {
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.
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)) {
790 return CDK_Constructor;
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(Dtor->getParent(), Dtor);
991
992 if (auto *FD = dyn_cast<FunctionDecl>(CurrentCaller.CDecl)) {
993 TrailingRequiresClause = FD->getTrailingRequiresClause().ConstraintExpr;
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 for (const CXXBaseSpecifier &Base : Rec->bases())
1099 followTypeDtor(Base.getType(), DtorLoc);
1100 }
1101
1102 void followTypeDtor(QualType QT, SourceLocation CallSite) {
1103 const Type *Ty = QT.getTypePtr();
1104 while (Ty->isArrayType()) {
1105 const ArrayType *Arr = Ty->getAsArrayTypeUnsafe();
1106 QT = Arr->getElementType();
1107 Ty = QT.getTypePtr();
1108 }
1109
1110 if (Ty->isRecordType()) {
1111 if (const CXXRecordDecl *Class = Ty->getAsCXXRecordDecl()) {
1112 if (CXXDestructorDecl *Dtor = Class->getDestructor();
1113 Dtor && !Dtor->isDeleted()) {
1114 CallableInfo CI(*Dtor);
1115 followCall(CI, CallSite);
1116 }
1117 }
1118 }
1119 }
1120
1121 // -- Methods for use of RecursiveASTVisitor --
1122
1123 bool VisitCXXThrowExpr(CXXThrowExpr *Throw) override {
1124 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow,
1125 ViolationID::ThrowsOrCatchesExceptions,
1126 Throw->getThrowLoc());
1127 return true;
1128 }
1129
1130 bool VisitCXXCatchStmt(CXXCatchStmt *Catch) override {
1131 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1132 ViolationID::ThrowsOrCatchesExceptions,
1133 Catch->getCatchLoc());
1134 return true;
1135 }
1136
1137 bool VisitObjCAtThrowStmt(ObjCAtThrowStmt *Throw) override {
1138 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow,
1139 ViolationID::ThrowsOrCatchesExceptions,
1140 Throw->getThrowLoc());
1141 return true;
1142 }
1143
1144 bool VisitObjCAtCatchStmt(ObjCAtCatchStmt *Catch) override {
1145 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1146 ViolationID::ThrowsOrCatchesExceptions,
1147 Catch->getAtCatchLoc());
1148 return true;
1149 }
1150
1151 bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Finally) override {
1152 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1153 ViolationID::ThrowsOrCatchesExceptions,
1154 Finally->getAtFinallyLoc());
1155 return true;
1156 }
1157
1158 bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) override {
1159 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1160 ViolationID::AccessesObjCMethodOrProperty,
1161 Msg->getBeginLoc());
1162 return true;
1163 }
1164
1165 bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *ARP) override {
1166 // Under the hood, @autorelease (potentially?) allocates memory and
1167 // invokes ObjC methods. We don't currently have memory allocation as
1168 // a "language construct" but we do have ObjC messaging, so diagnose that.
1169 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1170 ViolationID::AccessesObjCMethodOrProperty,
1171 ARP->getBeginLoc());
1172 return true;
1173 }
1174
1175 bool VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Sync) override {
1176 // Under the hood, this calls objc_sync_enter and objc_sync_exit, wrapped
1177 // in a @try/@finally block. Diagnose this generically as "ObjC
1178 // messaging".
1179 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1180 ViolationID::AccessesObjCMethodOrProperty,
1181 Sync->getBeginLoc());
1182 return true;
1183 }
1184
1185 bool VisitSEHExceptStmt(SEHExceptStmt *Exc) override {
1186 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1187 ViolationID::ThrowsOrCatchesExceptions,
1188 Exc->getExceptLoc());
1189 return true;
1190 }
1191
1192 bool VisitCallExpr(CallExpr *Call) override {
1193 LLVM_DEBUG(llvm::dbgs()
1194 << "VisitCallExpr : "
1195 << Call->getBeginLoc().printToString(Outer.S.SourceMgr)
1196 << "\n";);
1197
1198 Expr *CalleeExpr = Call->getCallee();
1199 if (const Decl *Callee = CalleeExpr->getReferencedDeclOfCallee()) {
1200 CallableInfo CI(*Callee);
1201 followCall(CI, Call->getBeginLoc());
1202 return true;
1203 }
1204
1205 if (isa<CXXPseudoDestructorExpr>(CalleeExpr)) {
1206 // Just destroying a scalar, fine.
1207 return true;
1208 }
1209
1210 // No Decl, just an Expr. Just check based on its type. Bound member
1211 // functions are a special expression type and need to be specially
1212 // unpacked.
1213 QualType CalleeExprQT = CalleeExpr->getType();
1214 if (CalleeExpr->isBoundMemberFunction(Outer.S.getASTContext())) {
1215 QualType QT = Expr::findBoundMemberType(CalleeExpr);
1216 if (!QT.isNull())
1217 CalleeExprQT = QT;
1218 }
1219 checkIndirectCall(Call, CalleeExprQT);
1220
1221 return true;
1222 }
1223
1224 bool VisitVarDecl(VarDecl *Var) override {
1225 LLVM_DEBUG(llvm::dbgs()
1226 << "VisitVarDecl : "
1227 << Var->getBeginLoc().printToString(Outer.S.SourceMgr)
1228 << "\n";);
1229
1230 if (Var->isStaticLocal())
1231 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeStaticLocalVars,
1232 ViolationID::HasStaticLocalVariable,
1233 Var->getLocation());
1234
1235 const QualType::DestructionKind DK =
1236 Var->needsDestruction(Outer.S.getASTContext());
1238 followTypeDtor(Var->getType(), Var->getLocation());
1239 return true;
1240 }
1241
1242 bool VisitCXXNewExpr(CXXNewExpr *New) override {
1243 // RecursiveASTVisitor does not visit the implicit call to operator new.
1244 if (FunctionDecl *FD = New->getOperatorNew()) {
1245 CallableInfo CI(*FD, SpecialFuncType::OperatorNew);
1246 followCall(CI, New->getBeginLoc());
1247 }
1248
1249 // It's a bit excessive to check operator delete here, since it's
1250 // just a fallback for operator new followed by a failed constructor.
1251 // We could check it via New->getOperatorDelete().
1252
1253 // It DOES however visit the called constructor
1254 return true;
1255 }
1256
1257 bool VisitCXXDeleteExpr(CXXDeleteExpr *Delete) override {
1258 // RecursiveASTVisitor does not visit the implicit call to operator
1259 // delete.
1260 if (FunctionDecl *FD = Delete->getOperatorDelete()) {
1261 CallableInfo CI(*FD, SpecialFuncType::OperatorDelete);
1262 followCall(CI, Delete->getBeginLoc());
1263 }
1264
1265 // It DOES however visit the called destructor
1266
1267 return true;
1268 }
1269
1270 bool VisitCXXConstructExpr(CXXConstructExpr *Construct) override {
1271 LLVM_DEBUG(llvm::dbgs() << "VisitCXXConstructExpr : "
1272 << Construct->getBeginLoc().printToString(
1273 Outer.S.SourceMgr)
1274 << "\n";);
1275
1276 // RecursiveASTVisitor does not visit the implicit call to the
1277 // constructor.
1278 const CXXConstructorDecl *Ctor = Construct->getConstructor();
1279 CallableInfo CI(*Ctor);
1280 followCall(CI, Construct->getLocation());
1281 return true;
1282 }
1283
1284 bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *BTE) override {
1285 const CXXDestructorDecl *Dtor = BTE->getTemporary()->getDestructor();
1286 if (Dtor != nullptr) {
1287 CallableInfo CI(*Dtor);
1288 followCall(CI, BTE->getBeginLoc());
1289 }
1290 return true;
1291 }
1292
1293 bool TraverseStmt(Stmt *Statement) override {
1294 // If this statement is a `requires` clause from the top-level function
1295 // being traversed, ignore it, since it's not generating runtime code.
1296 // We skip the traversal of lambdas (beyond their captures, see
1297 // TraverseLambdaExpr below), so just caching this from our constructor
1298 // should suffice.
1299 if (Statement != TrailingRequiresClause && Statement != NoexceptExpr)
1301 return true;
1302 }
1303
1304 bool TraverseCXXRecordDecl(CXXRecordDecl *D) override {
1305 // Completely skip local struct/class/union declarations since their
1306 // methods would otherwise be incorrectly interpreted as part of the
1307 // function we are currently traversing. The initial Sema pass will have
1308 // already recorded any nonblocking methods needing analysis.
1309 return true;
1310 }
1311
1312 bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
1313 ViolationSite PrevVS = VSite;
1314 if (Init->isAnyMemberInitializer())
1315 VSite.setKind(ViolationSite::Kind::MemberInitializer);
1316 bool Result =
1318 VSite = PrevVS;
1319 return Result;
1320 }
1321
1322 bool TraverseCXXDefaultArgExpr(CXXDefaultArgExpr *E) override {
1323 LLVM_DEBUG(llvm::dbgs()
1324 << "TraverseCXXDefaultArgExpr : "
1325 << E->getUsedLocation().printToString(Outer.S.SourceMgr)
1326 << "\n";);
1327
1328 ViolationSite PrevVS = VSite;
1329 if (VSite.kind() == ViolationSite::Kind::Default)
1330 VSite = ViolationSite{E};
1331
1332 bool Result = DynamicRecursiveASTVisitor::TraverseCXXDefaultArgExpr(E);
1333 VSite = PrevVS;
1334 return Result;
1335 }
1336
1337 bool TraverseLambdaExpr(LambdaExpr *Lambda) override {
1338 // We override this so as to be able to skip traversal of the lambda's
1339 // body. We have to explicitly traverse the captures. Why not return
1340 // false from shouldVisitLambdaBody()? Because we need to visit a lambda's
1341 // body when we are verifying the lambda itself; we only want to skip it
1342 // in the context of the outer function.
1343 for (unsigned I = 0, N = Lambda->capture_size(); I < N; ++I)
1344 TraverseLambdaCapture(Lambda, Lambda->capture_begin() + I,
1345 Lambda->capture_init_begin()[I]);
1346
1347 return true;
1348 }
1349
1350 bool TraverseBlockExpr(BlockExpr * /*unused*/) override {
1351 // As with lambdas, don't traverse the block's body.
1352 // TODO: are the capture expressions (ctor call?) safe?
1353 return true;
1354 }
1355
1356 bool VisitDeclRefExpr(DeclRefExpr *E) override {
1357 const ValueDecl *Val = E->getDecl();
1358 if (const auto *Var = dyn_cast<VarDecl>(Val)) {
1359 if (Var->getTLSKind() != VarDecl::TLS_None) {
1360 // At least on macOS, thread-local variables are initialized on
1361 // first access, including a heap allocation.
1362 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThreadLocalVars,
1363 ViolationID::AccessesThreadLocalVariable,
1364 E->getLocation());
1365 }
1366 }
1367 return true;
1368 }
1369
1370 bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) override {
1371 return TraverseStmt(Node->getResultExpr());
1372 }
1373 bool
1374 TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override {
1375 return true;
1376 }
1377
1378 bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node,
1379 bool TraverseQualifier) override {
1380 return true;
1381 }
1382
1383 bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node,
1384 bool TraverseQualifier) override {
1385 return true;
1386 }
1387
1388 bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override {
1389 return true;
1390 }
1391
1392 bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) override { return true; }
1393
1394 // Skip concept requirements since they don't generate code.
1395 bool TraverseConceptRequirement(concepts::Requirement *R) override {
1396 return true;
1397 }
1398 };
1399};
1400
1401Analyzer::AnalysisMap::~AnalysisMap() {
1402 for (const auto &Item : *this) {
1403 FuncAnalysisPtr AP = Item.second;
1404 if (auto *PFA = dyn_cast<PendingFunctionAnalysis *>(AP))
1405 delete PFA;
1406 else
1408 }
1409}
1410
1411} // anonymous namespace
1412
1413namespace clang {
1414
1416 const FunctionEffectsRef &FX, const FunctionEffectWithCondition &NewEC,
1417 SourceLocation NewAttrLoc) {
1418 // If the new effect has a condition, we can't detect conflicts until the
1419 // condition is resolved.
1420 if (NewEC.Cond.getCondition() != nullptr)
1421 return false;
1422
1423 // Diagnose the new attribute as incompatible with a previous one.
1424 auto Incompatible = [&](const FunctionEffectWithCondition &PrevEC) {
1425 Diag(NewAttrLoc, diag::err_attributes_are_not_compatible)
1426 << ("'" + NewEC.description() + "'")
1427 << ("'" + PrevEC.description() + "'") << false;
1428 // We don't necessarily have the location of the previous attribute,
1429 // so no note.
1430 return true;
1431 };
1432
1433 // Compare against previous attributes.
1434 FunctionEffect::Kind NewKind = NewEC.Effect.kind();
1435
1436 for (const FunctionEffectWithCondition &PrevEC : FX) {
1437 // Again, can't check yet when the effect is conditional.
1438 if (PrevEC.Cond.getCondition() != nullptr)
1439 continue;
1440
1441 FunctionEffect::Kind PrevKind = PrevEC.Effect.kind();
1442 // Note that we allow PrevKind == NewKind; it's redundant and ignored.
1443
1444 if (PrevEC.Effect.oppositeKind() == NewKind)
1445 return Incompatible(PrevEC);
1446
1447 // A new allocating is incompatible with a previous nonblocking.
1448 if (PrevKind == FunctionEffect::Kind::NonBlocking &&
1450 return Incompatible(PrevEC);
1451
1452 // A new nonblocking is incompatible with a previous allocating.
1453 if (PrevKind == FunctionEffect::Kind::Allocating &&
1455 return Incompatible(PrevEC);
1456 }
1457
1458 return false;
1459}
1460
1462 const FunctionEffectSet::Conflicts &Errs, SourceLocation NewLoc,
1463 SourceLocation OldLoc) {
1464 for (const FunctionEffectSet::Conflict &Conflict : Errs) {
1465 Diag(NewLoc, diag::warn_conflicting_func_effects)
1466 << Conflict.Kept.description() << Conflict.Rejected.description();
1467 Diag(OldLoc, diag::note_previous_declaration);
1468 }
1469}
1470
1471// Decl should be a FunctionDecl or BlockDecl.
1473 const FunctionEffectsRef &FX) {
1474 if (!D->hasBody()) {
1475 if (const auto *FD = D->getAsFunction(); FD && !FD->willHaveBody())
1476 return;
1477 }
1478
1479 if (Diags.getIgnoreAllWarnings() ||
1480 (Diags.getSuppressSystemWarnings() &&
1481 SourceMgr.isInSystemHeader(D->getLocation())))
1482 return;
1483
1485 return;
1486
1487 // For code in dependent contexts, we'll do this at instantiation time.
1488 // Without this check, we would analyze the function based on placeholder
1489 // template parameters, and potentially generate spurious diagnostics.
1490 if (cast<DeclContext>(D)->isDependentContext())
1491 return;
1492
1493 addDeclWithEffects(D, FX);
1494}
1495
1497 // To avoid the possibility of conflict, don't add effects which are
1498 // not FE_InferrableOnCallees and therefore not verified; this removes
1499 // blocking/allocating but keeps nonblocking/nonallocating.
1500 // Also, ignore any conditions when building the list of effects.
1501 bool AnyVerifiable = false;
1502 for (const FunctionEffectWithCondition &EC : FX)
1503 if (EC.Effect.flags() & FunctionEffect::FE_InferrableOnCallees) {
1504 AllEffectsToVerify.insert(EC.Effect);
1505 AnyVerifiable = true;
1506 }
1507
1508 // Record the declaration for later analysis.
1509 if (AnyVerifiable)
1510 DeclsWithEffectsToVerify.push_back(D);
1511}
1512
1514 if (hasUncompilableErrorOccurred() || Diags.getIgnoreAllWarnings())
1515 return;
1516 if (TU == nullptr)
1517 return;
1518 Analyzer{*this}.run(*TU);
1519}
1520
1522 const FunctionEffectsRef &Old, const FunctionEffectsRef &New) {
1523
1525 FunctionEffectsRef::iterator OldEnd = Old.end();
1526 FunctionEffectsRef::iterator PNew = New.begin();
1527 FunctionEffectsRef::iterator NewEnd = New.end();
1528
1529 while (true) {
1530 int cmp = 0;
1531 if (POld == OldEnd) {
1532 if (PNew == NewEnd)
1533 break;
1534 cmp = 1;
1535 } else if (PNew == NewEnd)
1536 cmp = -1;
1537 else {
1538 FunctionEffectWithCondition Old = *POld;
1540 if (Old.Effect.kind() < New.Effect.kind())
1541 cmp = -1;
1542 else if (New.Effect.kind() < Old.Effect.kind())
1543 cmp = 1;
1544 else {
1545 cmp = 0;
1546 if (Old.Cond.getCondition() != New.Cond.getCondition()) {
1547 // FIXME: Cases where the expressions are equivalent but
1548 // don't have the same identity.
1549 push_back(FunctionEffectDiff{
1551 Old, New});
1552 }
1553 }
1554 }
1555
1556 if (cmp < 0) {
1557 // removal
1558 FunctionEffectWithCondition Old = *POld;
1559 push_back(FunctionEffectDiff{Old.Effect.kind(),
1561 std::nullopt});
1562 ++POld;
1563 } else if (cmp > 0) {
1564 // addition
1566 push_back(FunctionEffectDiff{New.Effect.kind(),
1568 std::nullopt, New});
1569 ++PNew;
1570 } else {
1571 ++POld;
1572 ++PNew;
1573 }
1574 }
1575}
1576
1578 QualType SrcType, const FunctionEffectsRef &SrcFX, QualType DstType,
1579 const FunctionEffectsRef &DstFX) const {
1580
1581 switch (EffectKind) {
1583 // nonallocating can't be added (spoofed) during a conversion, unless we
1584 // have nonblocking.
1585 if (DiffKind == Kind::Added) {
1586 for (const auto &CFE : SrcFX) {
1587 if (CFE.Effect.kind() == FunctionEffect::Kind::NonBlocking)
1588 return false;
1589 }
1590 }
1591 [[fallthrough]];
1593 // nonblocking can't be added (spoofed) during a conversion.
1594 switch (DiffKind) {
1595 case Kind::Added:
1596 return true;
1597 case Kind::Removed:
1598 return false;
1600 // FIXME: Condition mismatches are too coarse right now -- expressions
1601 // which are equivalent but don't have the same identity are detected as
1602 // mismatches. We're going to diagnose those anyhow until expression
1603 // matching is better.
1604 return true;
1605 }
1606 break;
1609 return false;
1610 }
1611 llvm_unreachable("unknown effect kind");
1612}
1613
1615 const FunctionDecl &OldFunction, const FunctionEffectsRef &OldFX,
1616 const FunctionDecl &NewFunction, const FunctionEffectsRef &NewFX) const {
1617 switch (EffectKind) {
1620 // nonblocking/nonallocating can't be removed in a redeclaration.
1621 switch (DiffKind) {
1622 case Kind::Added:
1623 return false; // No diagnostic.
1624 case Kind::Removed:
1625 return true; // Issue diagnostic.
1627 // All these forms of mismatches are diagnosed.
1628 return true;
1629 }
1630 break;
1633 return false;
1634 }
1635 llvm_unreachable("unknown effect kind");
1636}
1637
1640 const CXXMethodDecl &OldMethod, const FunctionEffectsRef &OldFX,
1641 const CXXMethodDecl &NewMethod, const FunctionEffectsRef &NewFX) const {
1642 switch (EffectKind) {
1645 switch (DiffKind) {
1646
1647 // If added on an override, that's fine and not diagnosed.
1648 case Kind::Added:
1650
1651 // If missing from an override (removed), propagate from base to derived.
1652 case Kind::Removed:
1653 return OverrideResult::Merge;
1654
1655 // If there's a mismatch involving the effect's polarity or condition,
1656 // issue a warning.
1658 return OverrideResult::Warn;
1659 }
1660 break;
1664 }
1665 llvm_unreachable("unknown effect kind");
1666}
1667
1668} // namespace clang
#define V(N, I)
static bool isNoexcept(const FunctionDecl *FD)
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....
static bool AllocatesMemory(QualType T)
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool isExternC(const NamedDecl *ND)
Definition Mangle.cpp:80
static void emitDiagnostics(BoundNodes &Match, const Decl *D, BugReporter &BR, AnalysisManager &AM, const ObjCAutoreleaseWriteChecker *Checker)
#define SM(sm)
*collection of selector each with an associated kind and an ordered *collection of selectors A selector has a kind
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:226
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3772
QualType getElementType() const
Definition TypeBase.h:3784
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6671
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1494
CXXTemporary * getTemporary()
Definition ExprCXX.h:1512
SourceLocation getBeginLoc() const LLVM_READONLY
Definition ExprCXX.h:1520
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:1549
SourceLocation getLocation() const
Definition ExprCXX.h:1614
SourceLocation getBeginLoc() const LLVM_READONLY
Definition ExprCXX.cpp:575
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1612
Represents a C++ constructor within a class.
Definition DeclCXX.h:2611
Represents a C++ base or member initializer.
Definition DeclCXX.h:2376
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1271
SourceLocation getUsedLocation() const
Retrieve the location where this default argument was actually used.
Definition ExprCXX.h:1345
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2627
Represents a C++ destructor within a class.
Definition DeclCXX.h:2876
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2356
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition ExprCXX.h:4310
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
base_class_range bases()
Definition DeclCXX.h:608
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition DeclCXX.h:1018
const CXXDestructorDecl * getDestructor() const
Definition ExprCXX.h:1471
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1209
SourceLocation getThrowLoc() const
Definition ExprCXX.h:1232
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:849
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1273
ValueDecl * getDecl()
Definition Expr.h:1341
SourceLocation getLocation() const
Definition Expr.h:1349
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:273
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:1093
SourceLocation getLocation() const
Definition DeclBase.h:439
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:431
bool hasAttr() const
Definition DeclBase.h:577
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:978
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:831
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition Decl.h:855
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:809
virtual bool TraverseConstructorInitializer(MaybeConst< CXXCtorInitializer > *Init)
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
Expr * getCondition() const
Definition TypeBase.h:5084
This represents one expression.
Definition Expr.h:112
static QualType findBoundMemberType(const Expr *expr)
Given an expression of bound-member type, find the type of the member.
Definition Expr.cpp:3046
Decl * getReferencedDeclOfCallee()
Definition Expr.cpp:1546
bool isBoundMemberFunction(ASTContext &Ctx) const
Returns true if this expression is a bound member function.
Definition Expr.cpp:3040
QualType getType() const
Definition Expr.h:144
Represents a member of a struct/union/class.
Definition Decl.h:3175
Represents a function declaration or definition.
Definition Decl.h:2015
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3763
SourceLocation getPointOfInstantiation() const
Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...
Definition Decl.cpp:4515
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
Definition Decl.cpp:3652
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:4265
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2392
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:3748
bool isDeleted() const
Whether this function has been deleted.
Definition Decl.h:2555
FunctionEffectsRef getFunctionEffects() const
Definition Decl.h:3149
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
Definition Decl.cpp:4258
FunctionDecl * getDefinition()
Get the definition for this declaration.
Definition Decl.h:2297
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3200
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:3126
bool willHaveBody() const
True if this function will eventually have a body, once it's fully parsed.
Definition Decl.h:2700
A mutable set of FunctionEffect::Kind.
Definition TypeBase.h:5211
static FunctionEffectKindSet difference(FunctionEffectKindSet LHS, FunctionEffectKindSet RHS)
Definition TypeBase.h:5283
bool contains(const FunctionEffect::Kind EK) const
Definition TypeBase.h:5278
void dump(llvm::raw_ostream &OS) const
Definition Type.cpp:5821
void insert(FunctionEffect Effect)
Definition TypeBase.h:5270
SmallVector< Conflict > Conflicts
Definition TypeBase.h:5325
Represents an abstract function effect, using just an enumeration describing its kind.
Definition TypeBase.h:4970
Kind kind() const
The kind of the effect.
Definition TypeBase.h:5009
unsigned Flags
Flags describing some behaviors of the effect.
Definition TypeBase.h:4983
Kind
Identifies the particular effect.
Definition TypeBase.h:4973
Flags flags() const
Flags describing some behaviors of the effect.
Definition TypeBase.h:5021
bool shouldDiagnoseFunctionCall(bool Direct, FunctionEffectKindSet CalleeFX) const
Definition Type.cpp:5672
StringRef name() const
The description printed in diagnostics, e.g. 'nonblocking'.
Definition Type.cpp:5634
An immutable set of FunctionEffects and possibly conditions attached to them.
Definition TypeBase.h:5157
iterator begin() const
Definition TypeBase.h:5195
iterator end() const
Definition TypeBase.h:5196
FunctionEffectIterator< FunctionEffectsRef > iterator
Definition TypeBase.h:5193
static FunctionEffectsRef get(QualType QT)
Extract the effects from a Type if it is a function, block, or member function pointer,...
Definition TypeBase.h:9366
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5357
Represents a C11 generic selection.
Definition Expr.h:6181
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition Expr.h:6467
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1969
capture_iterator capture_begin() const
Retrieve an iterator pointing to the first lambda capture.
Definition ExprCXX.cpp:1363
unsigned capture_size() const
Determine the number of captures in this lambda.
Definition ExprCXX.h:2050
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition ExprCXX.h:2095
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:971
SourceLocation getBeginLoc() const LLVM_READONLY
Definition ExprObjC.h:1489
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8431
field_range fields() const
Definition Decl.h:4545
SourceLocation getExceptLoc() const
Definition Stmt.h:3787
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
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:15764
ASTContext & getASTContext() const
Definition Sema.h:939
SmallVector< const Decl * > DeclsWithEffectsToVerify
All functions/lambdas/blocks which have bodies and which have a non-empty FunctionEffectsRef to be ve...
Definition Sema.h:15760
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition Sema.h:1212
const LangOptions & getLangOpts() const
Definition Sema.h:932
void maybeAddDeclWithEffects(FuncOrBlockDecl *D)
Inline checks from the start of maybeAddDeclWithEffects, to minimize performance impact on code not u...
Definition Sema.h:15783
void performFunctionEffectAnalysis(TranslationUnitDecl *TU)
SourceManager & getSourceManager() const
Definition Sema.h:937
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:1846
SourceManager & SourceMgr
Definition Sema.h:1311
DiagnosticsEngine & Diags
Definition Sema.h:1310
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.
Stmt - This represents one statement.
Definition Stmt.h:86
The top declaration context.
Definition Decl.h:105
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 TypeBase.h:8402
The base class of the type hierarchy.
Definition TypeBase.h:1866
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
bool isArrayType() const
Definition TypeBase.h:8767
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9314
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9261
bool isRecordType() const
Definition TypeBase.h:8795
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2628
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:712
QualType getType() const
Definition Decl.h:723
Represents a variable declaration or definition.
Definition Decl.h:926
TLSKind getTLSKind() const
Definition Decl.cpp:2180
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1208
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
Definition Decl.cpp:2863
@ TLS_None
Not a TLS variable.
Definition Decl.h:946
A static requirement that can be used in a requires-expression to check properties of types and expre...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ Delete
'delete' clause, allowed on the 'exit data' construct.
@ Incompatible
Incompatible - We reject this conversion outright, it is invalid to represent it in the AST.
Definition Sema.h:787
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
U cast(CodeGen::Address addr)
Definition Address.h:327
@ None
The alignment was not explicit in code.
Definition ASTContext.h:179
const Expr * ConstraintExpr
Definition Decl.h:88
A FunctionEffect plus a potential boolean expression determining whether the effect is declared (e....
Definition TypeBase.h:5094
std::string description() const
Return a textual description of the effect, and its condition, if any.
Definition Type.cpp:5836
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:15725
FunctionEffect::Kind EffectKind
Definition Sema.h:15710