clang 24.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 // Fortified printf family, used by _FORTIFY_SOURCE wrappers
204 case Builtin::ID::BI__builtin___fprintf_chk:
205 case Builtin::ID::BI__builtin___printf_chk:
206 case Builtin::ID::BI__builtin___snprintf_chk:
207 case Builtin::ID::BI__builtin___sprintf_chk:
208 case Builtin::ID::BI__builtin___vfprintf_chk:
209 case Builtin::ID::BI__builtin___vprintf_chk:
210 case Builtin::ID::BI__builtin___vsnprintf_chk:
211 case Builtin::ID::BI__builtin___vsprintf_chk:
212
213 // stdio.h: scanf family.
214 case Builtin::ID::BIscanf:
215 case Builtin::ID::BIfscanf:
216 case Builtin::ID::BIsscanf:
217 case Builtin::ID::BIvscanf:
218 case Builtin::ID::BIvfscanf:
219 case Builtin::ID::BIvsscanf:
221 break;
222 }
223
224 return Result;
225}
226
227// Transitory, more extended information about a callable, which can be a
228// function, block, or function pointer.
229struct CallableInfo {
230 // CDecl holds the function's definition, if any.
231 // FunctionDecl if CallableType::Function or Virtual
232 // BlockDecl if CallableType::Block
233 const Decl *CDecl;
234
235 // Remember whether the callable is a function, block, virtual method,
236 // or (presumed) function pointer.
237 CallableType CType = CallableType::Unknown;
238
239 // Remember whether the callable is an operator new or delete function,
240 // so that calls to them are reported more meaningfully, as memory
241 // allocations.
242 SpecialFuncType FuncType = SpecialFuncType::None;
243
244 // We inevitably want to know the callable's declared effects, so cache them.
245 FunctionEffectKindSet Effects;
246
247 CallableInfo(const Decl &CD, SpecialFuncType FT = SpecialFuncType::None)
248 : CDecl(&CD), FuncType(FT) {
249 FunctionEffectsRef DeclEffects;
250 if (auto *FD = dyn_cast<FunctionDecl>(CDecl)) {
251 // Use the function's definition, if any.
252 if (const FunctionDecl *Def = FD->getDefinition())
253 CDecl = FD = Def;
254 CType = CallableType::Function;
255 if (auto *Method = dyn_cast<CXXMethodDecl>(FD);
256 Method && Method->isVirtual())
257 CType = CallableType::Virtual;
258 DeclEffects = FD->getFunctionEffects();
259 } else if (auto *BD = dyn_cast<BlockDecl>(CDecl)) {
260 CType = CallableType::Block;
261 DeclEffects = BD->getFunctionEffects();
262 } else if (auto *VD = dyn_cast<ValueDecl>(CDecl)) {
263 // ValueDecl is function, enum, or variable, so just look at its type.
264 DeclEffects = FunctionEffectsRef::get(VD->getType());
265 }
266 Effects = FunctionEffectKindSet(DeclEffects);
267 }
268
269 CallableType type() const { return CType; }
270
271 bool isCalledDirectly() const {
272 return CType == CallableType::Function || CType == CallableType::Block;
273 }
274
275 bool isVerifiable() const {
276 switch (CType) {
277 case CallableType::Unknown:
278 case CallableType::Virtual:
279 return false;
280 case CallableType::Block:
281 return true;
282 case CallableType::Function:
283 return functionIsVerifiable(dyn_cast<FunctionDecl>(CDecl));
284 }
285 llvm_unreachable("undefined CallableType");
286 }
287
288 /// Generate a name for logging and diagnostics.
289 std::string getNameForDiagnostic(Sema &S) const {
290 std::string Name;
291 llvm::raw_string_ostream OS(Name);
292
293 if (auto *FD = dyn_cast<FunctionDecl>(CDecl))
295 /*Qualified=*/true);
296 else if (auto *BD = dyn_cast<BlockDecl>(CDecl))
297 OS << "(block " << BD->getBlockManglingNumber() << ")";
298 else if (auto *VD = dyn_cast<NamedDecl>(CDecl))
299 VD->printQualifiedName(OS);
300 return Name;
301 }
302};
303
304// ----------
305// Map effects to single Violations, to hold the first (of potentially many)
306// violations pertaining to an effect, per function.
307class EffectToViolationMap {
308 // Since we currently only have a tiny number of effects (typically no more
309 // than 1), use a SmallVector with an inline capacity of 1. Since it
310 // is often empty, use a unique_ptr to the SmallVector.
311 // Note that Violation itself contains a FunctionEffect which is the key.
312 // FIXME: Is there a way to simplify this using existing data structures?
313 using ImplVec = llvm::SmallVector<Violation, 1>;
314 std::unique_ptr<ImplVec> Impl;
315
316public:
317 // Insert a new Violation if we do not already have one for its effect.
318 void maybeInsert(const Violation &Viol) {
319 if (Impl == nullptr)
320 Impl = std::make_unique<ImplVec>();
321 else if (lookup(Viol.Effect) != nullptr)
322 return;
323
324 Impl->push_back(Viol);
325 }
326
327 const Violation *lookup(FunctionEffect Key) {
328 if (Impl == nullptr)
329 return nullptr;
330
331 auto *Iter = llvm::find_if(
332 *Impl, [&](const auto &Item) { return Item.Effect == Key; });
333 return Iter != Impl->end() ? &*Iter : nullptr;
334 }
335
336 size_t size() const { return Impl ? Impl->size() : 0; }
337};
338
339// ----------
340// State pertaining to a function whose AST is walked and whose effect analysis
341// is dependent on a subsequent analysis of other functions.
342class PendingFunctionAnalysis {
343 friend class CompleteFunctionAnalysis;
344
345public:
346 struct DirectCall {
347 const Decl *Callee;
348 SourceLocation CallLoc;
349 // Not all recursive calls are detected, just enough
350 // to break cycles.
351 bool Recursed = false;
352 ViolationSite VSite;
353
354 DirectCall(const Decl *D, SourceLocation CallLoc, ViolationSite VSite)
355 : Callee(D), CallLoc(CallLoc), VSite(VSite) {}
356 };
357
358 // We always have two disjoint sets of effects to verify:
359 // 1. Effects declared explicitly by this function.
360 // 2. All other inferrable effects needing verification.
361 FunctionEffectKindSet DeclaredVerifiableEffects;
362 FunctionEffectKindSet EffectsToInfer;
363
364private:
365 // Violations pertaining to the function's explicit effects.
366 SmallVector<Violation, 0> ViolationsForExplicitEffects;
367
368 // Violations pertaining to other, non-explicit, inferrable effects.
369 EffectToViolationMap InferrableEffectToFirstViolation;
370
371 // These unverified direct calls are what keeps the analysis "pending",
372 // until the callees can be verified.
373 SmallVector<DirectCall, 0> UnverifiedDirectCalls;
374
375public:
376 PendingFunctionAnalysis(Sema &S, const CallableInfo &CInfo,
377 FunctionEffectKindSet AllInferrableEffectsToVerify)
378 : DeclaredVerifiableEffects(CInfo.Effects) {
379 // Check for effects we are not allowed to infer.
380 FunctionEffectKindSet InferrableEffects;
381
382 for (FunctionEffect effect : AllInferrableEffectsToVerify) {
383 std::optional<FunctionEffect> ProblemCalleeEffect =
384 effect.effectProhibitingInference(*CInfo.CDecl, CInfo.Effects);
385 if (!ProblemCalleeEffect)
386 InferrableEffects.insert(effect);
387 else {
388 // Add a Violation for this effect if a caller were to
389 // try to infer it.
390 InferrableEffectToFirstViolation.maybeInsert(Violation(
391 effect, ViolationID::DeclDisallowsInference, ViolationSite{},
392 CInfo.CDecl->getLocation(), nullptr, ProblemCalleeEffect));
393 }
394 }
395 // InferrableEffects is now the set of inferrable effects which are not
396 // prohibited.
397 EffectsToInfer = FunctionEffectKindSet::difference(
398 InferrableEffects, DeclaredVerifiableEffects);
399 }
400
401 // Hide the way that Violations for explicitly required effects vs. inferred
402 // ones are handled differently.
403 void checkAddViolation(bool Inferring, const Violation &NewViol) {
404 if (!Inferring)
405 ViolationsForExplicitEffects.push_back(NewViol);
406 else
407 InferrableEffectToFirstViolation.maybeInsert(NewViol);
408 }
409
410 void addUnverifiedDirectCall(const Decl *D, SourceLocation CallLoc,
411 ViolationSite VSite) {
412 UnverifiedDirectCalls.emplace_back(D, CallLoc, VSite);
413 }
414
415 // Analysis is complete when there are no unverified direct calls.
416 bool isComplete() const { return UnverifiedDirectCalls.empty(); }
417
418 const Violation *violationForInferrableEffect(FunctionEffect effect) {
419 return InferrableEffectToFirstViolation.lookup(effect);
420 }
421
422 // Mutable because caller may need to set a DirectCall's Recursing flag.
423 MutableArrayRef<DirectCall> unverifiedCalls() {
424 assert(!isComplete());
425 return UnverifiedDirectCalls;
426 }
427
428 ArrayRef<Violation> getSortedViolationsForExplicitEffects(SourceManager &SM) {
429 if (!ViolationsForExplicitEffects.empty())
430 llvm::sort(ViolationsForExplicitEffects,
431 [&SM](const Violation &LHS, const Violation &RHS) {
432 return SM.isBeforeInTranslationUnit(LHS.Loc, RHS.Loc);
433 });
434 return ViolationsForExplicitEffects;
435 }
436
437 void dump(Sema &SemaRef, llvm::raw_ostream &OS) const {
438 OS << "Pending: Declared ";
439 DeclaredVerifiableEffects.dump(OS);
440 OS << ", " << ViolationsForExplicitEffects.size() << " violations; ";
441 OS << " Infer ";
442 EffectsToInfer.dump(OS);
443 OS << ", " << InferrableEffectToFirstViolation.size() << " violations";
444 if (!UnverifiedDirectCalls.empty()) {
445 OS << "; Calls: ";
446 for (const DirectCall &Call : UnverifiedDirectCalls) {
447 CallableInfo CI(*Call.Callee);
448 OS << " " << CI.getNameForDiagnostic(SemaRef);
449 }
450 }
451 OS << "\n";
452 }
453};
454
455// ----------
456class CompleteFunctionAnalysis {
457 // Current size: 2 pointers
458public:
459 // Has effects which are both the declared ones -- not to be inferred -- plus
460 // ones which have been successfully inferred. These are all considered
461 // "verified" for the purposes of callers; any issue with verifying declared
462 // effects has already been reported and is not the problem of any caller.
463 FunctionEffectKindSet VerifiedEffects;
464
465private:
466 // This is used to generate notes about failed inference.
467 EffectToViolationMap InferrableEffectToFirstViolation;
468
469public:
470 // The incoming Pending analysis is consumed (member(s) are moved-from).
471 CompleteFunctionAnalysis(ASTContext &Ctx, PendingFunctionAnalysis &&Pending,
472 FunctionEffectKindSet DeclaredEffects,
473 FunctionEffectKindSet AllInferrableEffectsToVerify)
474 : VerifiedEffects(DeclaredEffects) {
475 for (FunctionEffect effect : AllInferrableEffectsToVerify)
476 if (Pending.violationForInferrableEffect(effect) == nullptr)
477 VerifiedEffects.insert(effect);
478
479 InferrableEffectToFirstViolation =
480 std::move(Pending.InferrableEffectToFirstViolation);
481 }
482
483 const Violation *firstViolationForEffect(FunctionEffect Effect) {
484 return InferrableEffectToFirstViolation.lookup(Effect);
485 }
486
487 void dump(llvm::raw_ostream &OS) const {
488 OS << "Complete: Verified ";
489 VerifiedEffects.dump(OS);
490 OS << "; Infer ";
491 OS << InferrableEffectToFirstViolation.size() << " violations\n";
492 }
493};
494
495// ==========
496class Analyzer {
497 Sema &S;
498
499 // Subset of Sema.AllEffectsToVerify
500 FunctionEffectKindSet AllInferrableEffectsToVerify;
501
502 using FuncAnalysisPtr =
503 llvm::PointerUnion<PendingFunctionAnalysis *, CompleteFunctionAnalysis *>;
504
505 // Map all Decls analyzed to FuncAnalysisPtr. Pending state is larger
506 // than complete state, so use different objects to represent them.
507 // The state pointers are owned by the container.
508 class AnalysisMap : llvm::DenseMap<const Decl *, FuncAnalysisPtr> {
509 using Base = llvm::DenseMap<const Decl *, FuncAnalysisPtr>;
510
511 public:
512 ~AnalysisMap();
513
514 // Use non-public inheritance in order to maintain the invariant
515 // that lookups and insertions are via the canonical Decls.
516
517 FuncAnalysisPtr lookup(const Decl *Key) const {
518 return Base::lookup(Key->getCanonicalDecl());
519 }
520
521 FuncAnalysisPtr &operator[](const Decl *Key) {
522 return Base::operator[](Key->getCanonicalDecl());
523 }
524
525 /// Shortcut for the case where we only care about completed analysis.
526 CompleteFunctionAnalysis *completedAnalysisForDecl(const Decl *D) const {
527 if (FuncAnalysisPtr AP = lookup(D);
528 isa_and_nonnull<CompleteFunctionAnalysis *>(AP))
530 return nullptr;
531 }
532
533 void dump(Sema &SemaRef, llvm::raw_ostream &OS) {
534 OS << "\nAnalysisMap:\n";
535 for (const auto &item : *this) {
536 CallableInfo CI(*item.first);
537 const auto AP = item.second;
538 OS << item.first << " " << CI.getNameForDiagnostic(SemaRef) << " : ";
539 if (AP.isNull()) {
540 OS << "null\n";
541 } else if (auto *CFA = dyn_cast<CompleteFunctionAnalysis *>(AP)) {
542 OS << CFA << " ";
543 CFA->dump(OS);
544 } else if (auto *PFA = dyn_cast<PendingFunctionAnalysis *>(AP)) {
545 OS << PFA << " ";
546 PFA->dump(SemaRef, OS);
547 } else
548 llvm_unreachable("never");
549 }
550 OS << "---\n";
551 }
552 };
553 AnalysisMap DeclAnalysis;
554
555public:
556 Analyzer(Sema &S) : S(S) {}
557
558 void run(const TranslationUnitDecl &TU) {
559 // Gather all of the effects to be verified to see what operations need to
560 // be checked, and to see which ones are inferrable.
561 for (FunctionEffect Effect : S.AllEffectsToVerify) {
562 const FunctionEffect::Flags Flags = Effect.flags();
564 AllInferrableEffectsToVerify.insert(Effect);
565 }
566 LLVM_DEBUG(llvm::dbgs() << "AllInferrableEffectsToVerify: ";
567 AllInferrableEffectsToVerify.dump(llvm::dbgs());
568 llvm::dbgs() << "\n";);
569
570 // We can use DeclsWithEffectsToVerify as a stack for a
571 // depth-first traversal; there's no need for a second container. But first,
572 // reverse it, so when working from the end, Decls are verified in the order
573 // they are declared.
575 std::reverse(VerificationQueue.begin(), VerificationQueue.end());
576
577 while (!VerificationQueue.empty()) {
578 const Decl *D = VerificationQueue.back();
579 if (FuncAnalysisPtr AP = DeclAnalysis.lookup(D)) {
580 if (auto *Pending = dyn_cast<PendingFunctionAnalysis *>(AP)) {
581 // All children have been traversed; finish analysis.
582 finishPendingAnalysis(D, Pending);
583 }
584 VerificationQueue.pop_back();
585 continue;
586 }
587
588 // Not previously visited; begin a new analysis for this Decl.
589 PendingFunctionAnalysis *Pending = verifyDecl(D);
590 if (Pending == nullptr) {
591 // Completed now.
592 VerificationQueue.pop_back();
593 continue;
594 }
595
596 // Analysis remains pending because there are direct callees to be
597 // verified first. Push them onto the queue.
598 for (PendingFunctionAnalysis::DirectCall &Call :
599 Pending->unverifiedCalls()) {
600 FuncAnalysisPtr AP = DeclAnalysis.lookup(Call.Callee);
601 if (AP.isNull()) {
602 VerificationQueue.push_back(Call.Callee);
603 continue;
604 }
605
606 // This indicates recursion (not necessarily direct). For the
607 // purposes of effect analysis, we can just ignore it since
608 // no effects forbid recursion.
610 Call.Recursed = true;
611 }
612 }
613 }
614
615private:
616 // Verify a single Decl. Return the pending structure if that was the result,
617 // else null. This method must not recurse.
618 PendingFunctionAnalysis *verifyDecl(const Decl *D) {
619 CallableInfo CInfo(*D);
620 bool isExternC = false;
621
622 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
624
625 // For C++, with non-extern "C" linkage only - if any of the Decl's declared
626 // effects forbid throwing (e.g. nonblocking) then the function should also
627 // be declared noexcept.
628 if (S.getLangOpts().CPlusPlus && !isExternC) {
629 for (FunctionEffect Effect : CInfo.Effects) {
630 if (!(Effect.flags() & FunctionEffect::FE_ExcludeThrow))
631 continue;
632
633 bool IsNoexcept = false;
634 if (auto *FD = D->getAsFunction()) {
635 IsNoexcept = isNoexcept(FD);
636 } else if (auto *BD = dyn_cast<BlockDecl>(D)) {
637 if (auto *TSI = BD->getSignatureAsWritten()) {
638 auto *FPT = TSI->getType()->castAs<FunctionProtoType>();
639 IsNoexcept = FPT->isNothrow() || BD->hasAttr<NoThrowAttr>();
640 }
641 }
642 if (!IsNoexcept)
643 S.Diag(D->getBeginLoc(), diag::warn_perf_constraint_implies_noexcept)
644 << GetCallableDeclKind(D, nullptr) << Effect.name();
645 break;
646 }
647 }
648
649 // Build a PendingFunctionAnalysis on the stack. If it turns out to be
650 // complete, we'll have avoided a heap allocation; if it's incomplete, it's
651 // a fairly trivial move to a heap-allocated object.
652 PendingFunctionAnalysis FAnalysis(S, CInfo, AllInferrableEffectsToVerify);
653
654 LLVM_DEBUG(llvm::dbgs()
655 << "\nVerifying " << CInfo.getNameForDiagnostic(S) << " ";
656 FAnalysis.dump(S, llvm::dbgs()););
657
658 FunctionBodyASTVisitor Visitor(*this, FAnalysis, CInfo);
659
660 Visitor.run();
661 if (FAnalysis.isComplete()) {
662 completeAnalysis(CInfo, std::move(FAnalysis));
663 return nullptr;
664 }
665 // Move the pending analysis to the heap and save it in the map.
666 PendingFunctionAnalysis *PendingPtr =
667 new PendingFunctionAnalysis(std::move(FAnalysis));
668 DeclAnalysis[D] = PendingPtr;
669 LLVM_DEBUG(llvm::dbgs() << "inserted pending " << PendingPtr << "\n";
670 DeclAnalysis.dump(S, llvm::dbgs()););
671 return PendingPtr;
672 }
673
674 // Consume PendingFunctionAnalysis, create with it a CompleteFunctionAnalysis,
675 // inserted in the container.
676 void completeAnalysis(const CallableInfo &CInfo,
677 PendingFunctionAnalysis &&Pending) {
678 if (ArrayRef<Violation> Viols =
679 Pending.getSortedViolationsForExplicitEffects(S.getSourceManager());
680 !Viols.empty())
681 emitDiagnostics(Viols, CInfo);
682
683 CompleteFunctionAnalysis *CompletePtr = new CompleteFunctionAnalysis(
684 S.getASTContext(), std::move(Pending), CInfo.Effects,
685 AllInferrableEffectsToVerify);
686 DeclAnalysis[CInfo.CDecl] = CompletePtr;
687 LLVM_DEBUG(llvm::dbgs() << "inserted complete " << CompletePtr << "\n";
688 DeclAnalysis.dump(S, llvm::dbgs()););
689 }
690
691 // Called after all direct calls requiring inference have been found -- or
692 // not. Repeats calls to FunctionBodyASTVisitor::followCall() but without
693 // the possibility of inference. Deletes Pending.
694 void finishPendingAnalysis(const Decl *D, PendingFunctionAnalysis *Pending) {
695 CallableInfo Caller(*D);
696 LLVM_DEBUG(llvm::dbgs() << "finishPendingAnalysis for "
697 << Caller.getNameForDiagnostic(S) << " : ";
698 Pending->dump(S, llvm::dbgs()); llvm::dbgs() << "\n";);
699 for (const PendingFunctionAnalysis::DirectCall &Call :
700 Pending->unverifiedCalls()) {
701 if (Call.Recursed)
702 continue;
703
704 CallableInfo Callee(*Call.Callee);
705 followCall(Caller, *Pending, Callee, Call.CallLoc,
706 /*AssertNoFurtherInference=*/true, Call.VSite);
707 }
708 completeAnalysis(Caller, std::move(*Pending));
709 delete Pending;
710 }
711
712 // Here we have a call to a Decl, either explicitly via a CallExpr or some
713 // other AST construct. PFA pertains to the caller.
714 void followCall(const CallableInfo &Caller, PendingFunctionAnalysis &PFA,
715 const CallableInfo &Callee, SourceLocation CallLoc,
716 bool AssertNoFurtherInference, ViolationSite VSite) {
717 const bool DirectCall = Callee.isCalledDirectly();
718
719 // Initially, the declared effects; inferred effects will be added.
720 FunctionEffectKindSet CalleeEffects = Callee.Effects;
721
722 bool IsInferencePossible = DirectCall;
723
724 if (DirectCall)
725 if (CompleteFunctionAnalysis *CFA =
726 DeclAnalysis.completedAnalysisForDecl(Callee.CDecl)) {
727 // Combine declared effects with those which may have been inferred.
728 CalleeEffects.insert(CFA->VerifiedEffects);
729 IsInferencePossible = false; // We've already traversed it.
730 }
731
732 if (AssertNoFurtherInference) {
733 assert(!IsInferencePossible);
734 }
735
736 if (!Callee.isVerifiable())
737 IsInferencePossible = false;
738
739 LLVM_DEBUG(llvm::dbgs()
740 << "followCall from " << Caller.getNameForDiagnostic(S)
741 << " to " << Callee.getNameForDiagnostic(S)
742 << "; verifiable: " << Callee.isVerifiable() << "; callee ";
743 CalleeEffects.dump(llvm::dbgs()); llvm::dbgs() << "\n";
744 llvm::dbgs() << " callee " << Callee.CDecl << " canonical "
745 << Callee.CDecl->getCanonicalDecl() << "\n";);
746
747 auto Check1Effect = [&](FunctionEffect Effect, bool Inferring) {
748 if (!Effect.shouldDiagnoseFunctionCall(DirectCall, CalleeEffects))
749 return;
750
751 // If inference is not allowed, or the target is indirect (virtual
752 // method/function ptr?), generate a Violation now.
753 if (!IsInferencePossible ||
755 if (Callee.FuncType == SpecialFuncType::None)
756 PFA.checkAddViolation(Inferring,
757 {Effect, ViolationID::CallsDeclWithoutEffect,
758 VSite, CallLoc, Callee.CDecl});
759 else
760 PFA.checkAddViolation(
761 Inferring,
762 {Effect, ViolationID::AllocatesMemory, VSite, CallLoc});
763 } else {
764 // Inference is allowed and necessary; defer it.
765 PFA.addUnverifiedDirectCall(Callee.CDecl, CallLoc, VSite);
766 }
767 };
768
769 for (FunctionEffect Effect : PFA.DeclaredVerifiableEffects)
770 Check1Effect(Effect, false);
771
772 for (FunctionEffect Effect : PFA.EffectsToInfer)
773 Check1Effect(Effect, true);
774 }
775
776 // Describe a callable Decl for a diagnostic.
777 // (Not an enum class because the value is always converted to an integer for
778 // use in a diagnostic.)
779 enum CallableDeclKind {
780 CDK_Function,
781 CDK_Constructor,
782 CDK_Destructor,
783 CDK_Lambda,
784 CDK_Block,
785 CDK_MemberInitializer,
786 };
787
788 // Describe a call site or target using an enum mapping to a %select{}
789 // in a diagnostic, e.g. warn_func_effect_violation,
790 // warn_perf_constraint_implies_noexcept, and others.
791 static CallableDeclKind GetCallableDeclKind(const Decl *D,
792 const Violation *V) {
793 if (V != nullptr &&
794 V->Site.kind() == ViolationSite::Kind::MemberInitializer)
795 return CDK_MemberInitializer;
796 if (isa<BlockDecl>(D))
797 return CDK_Block;
798 if (auto *Method = dyn_cast<CXXMethodDecl>(D)) {
800 return CDK_Constructor;
802 return CDK_Destructor;
803 const CXXRecordDecl *Rec = Method->getParent();
804 if (Rec->isLambda())
805 return CDK_Lambda;
806 }
807 return CDK_Function;
808 };
809
810 // Should only be called when function's analysis is determined to be
811 // complete.
812 void emitDiagnostics(ArrayRef<Violation> Viols, const CallableInfo &CInfo) {
813 if (Viols.empty())
814 return;
815
816 auto MaybeAddTemplateNote = [&](const Decl *D) {
817 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
818 while (FD != nullptr && FD->isTemplateInstantiation() &&
821 diag::note_func_effect_from_template);
823 }
824 }
825 };
826
827 // For note_func_effect_call_indirect.
828 enum { Indirect_VirtualMethod, Indirect_FunctionPtr };
829
830 auto MaybeAddSiteContext = [&](const Decl *D, const Violation &V) {
831 // If a violation site is a member initializer, add a note pointing to
832 // the constructor which invoked it.
833 if (V.Site.kind() == ViolationSite::Kind::MemberInitializer) {
834 unsigned ImplicitCtor = 0;
835 if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D);
836 Ctor && Ctor->isImplicit())
837 ImplicitCtor = 1;
838 S.Diag(D->getLocation(), diag::note_func_effect_in_constructor)
839 << ImplicitCtor;
840 }
841
842 // If a violation site is a default argument expression, add a note
843 // pointing to the call site using the default argument.
844 else if (V.Site.kind() == ViolationSite::Kind::DefaultArgExpr)
845 S.Diag(V.Site.defaultArgExpr()->getUsedLocation(),
846 diag::note_in_evaluating_default_argument);
847 };
848
849 // Top-level violations are warnings.
850 for (const Violation &Viol1 : Viols) {
851 StringRef effectName = Viol1.Effect.name();
852 switch (Viol1.ID) {
853 case ViolationID::None:
854 case ViolationID::DeclDisallowsInference: // Shouldn't happen
855 // here.
856 llvm_unreachable("Unexpected violation kind");
857 break;
858 case ViolationID::AllocatesMemory:
859 case ViolationID::ThrowsOrCatchesExceptions:
860 case ViolationID::HasStaticLocalVariable:
861 case ViolationID::AccessesThreadLocalVariable:
862 case ViolationID::AccessesObjCMethodOrProperty:
863 S.Diag(Viol1.Loc, diag::warn_func_effect_violation)
864 << GetCallableDeclKind(CInfo.CDecl, &Viol1) << effectName
865 << Viol1.diagnosticSelectIndex();
866 MaybeAddSiteContext(CInfo.CDecl, Viol1);
867 MaybeAddTemplateNote(CInfo.CDecl);
868 break;
869 case ViolationID::CallsExprWithoutEffect:
870 S.Diag(Viol1.Loc, diag::warn_func_effect_calls_expr_without_effect)
871 << GetCallableDeclKind(CInfo.CDecl, &Viol1) << effectName;
872 MaybeAddSiteContext(CInfo.CDecl, Viol1);
873 MaybeAddTemplateNote(CInfo.CDecl);
874 break;
875
876 case ViolationID::CallsDeclWithoutEffect: {
877 CallableInfo CalleeInfo(*Viol1.Callee);
878 std::string CalleeName = CalleeInfo.getNameForDiagnostic(S);
879
880 S.Diag(Viol1.Loc, diag::warn_func_effect_calls_func_without_effect)
881 << GetCallableDeclKind(CInfo.CDecl, &Viol1) << effectName
882 << GetCallableDeclKind(CalleeInfo.CDecl, nullptr) << CalleeName;
883 MaybeAddSiteContext(CInfo.CDecl, Viol1);
884 MaybeAddTemplateNote(CInfo.CDecl);
885
886 // Emit notes explaining the transitive chain of inferences: Why isn't
887 // the callee safe?
888 for (const Decl *Callee = Viol1.Callee; Callee != nullptr;) {
889 std::optional<CallableInfo> MaybeNextCallee;
890 CompleteFunctionAnalysis *Completed =
891 DeclAnalysis.completedAnalysisForDecl(CalleeInfo.CDecl);
892 if (Completed == nullptr) {
893 // No result - could be
894 // - non-inline and extern
895 // - indirect (virtual or through function pointer)
896 // - effect has been explicitly disclaimed (e.g. "blocking")
897
898 CallableType CType = CalleeInfo.type();
899 if (CType == CallableType::Virtual)
900 S.Diag(Callee->getLocation(),
901 diag::note_func_effect_call_indirect)
902 << Indirect_VirtualMethod << effectName;
903 else if (CType == CallableType::Unknown)
904 S.Diag(Callee->getLocation(),
905 diag::note_func_effect_call_indirect)
906 << Indirect_FunctionPtr << effectName;
907 else if (CalleeInfo.Effects.contains(Viol1.Effect.oppositeKind()))
908 S.Diag(Callee->getLocation(),
909 diag::note_func_effect_call_disallows_inference)
910 << GetCallableDeclKind(CInfo.CDecl, nullptr) << effectName
911 << FunctionEffect(Viol1.Effect.oppositeKind()).name();
912 else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Callee);
913 FD == nullptr || FD->getBuiltinID() == 0) {
914 // A builtin callee generally doesn't have a useful source
915 // location at which to insert a note.
916 S.Diag(Callee->getLocation(), diag::note_func_effect_call_extern)
917 << effectName;
918 }
919 break;
920 }
921 const Violation *PtrViol2 =
922 Completed->firstViolationForEffect(Viol1.Effect);
923 if (PtrViol2 == nullptr)
924 break;
925
926 const Violation &Viol2 = *PtrViol2;
927 switch (Viol2.ID) {
928 case ViolationID::None:
929 llvm_unreachable("Unexpected violation kind");
930 break;
931 case ViolationID::DeclDisallowsInference:
932 S.Diag(Viol2.Loc, diag::note_func_effect_call_disallows_inference)
933 << GetCallableDeclKind(CalleeInfo.CDecl, nullptr) << effectName
934 << Viol2.CalleeEffectPreventingInference->name();
935 break;
936 case ViolationID::CallsExprWithoutEffect:
937 S.Diag(Viol2.Loc, diag::note_func_effect_call_indirect)
938 << Indirect_FunctionPtr << effectName;
939 break;
940 case ViolationID::AllocatesMemory:
941 case ViolationID::ThrowsOrCatchesExceptions:
942 case ViolationID::HasStaticLocalVariable:
943 case ViolationID::AccessesThreadLocalVariable:
944 case ViolationID::AccessesObjCMethodOrProperty:
945 S.Diag(Viol2.Loc, diag::note_func_effect_violation)
946 << GetCallableDeclKind(CalleeInfo.CDecl, &Viol2) << effectName
947 << Viol2.diagnosticSelectIndex();
948 MaybeAddSiteContext(CalleeInfo.CDecl, Viol2);
949 break;
950 case ViolationID::CallsDeclWithoutEffect:
951 MaybeNextCallee.emplace(*Viol2.Callee);
952 S.Diag(Viol2.Loc, diag::note_func_effect_calls_func_without_effect)
953 << GetCallableDeclKind(CalleeInfo.CDecl, &Viol2) << effectName
954 << GetCallableDeclKind(Viol2.Callee, nullptr)
955 << MaybeNextCallee->getNameForDiagnostic(S);
956 break;
957 }
958 MaybeAddTemplateNote(Callee);
959 Callee = Viol2.Callee;
960 if (MaybeNextCallee) {
961 CalleeInfo = *MaybeNextCallee;
962 CalleeName = CalleeInfo.getNameForDiagnostic(S);
963 }
964 }
965 } break;
966 }
967 }
968 }
969
970 // ----------
971 // This AST visitor is used to traverse the body of a function during effect
972 // verification. This happens in 2 situations:
973 // [1] The function has declared effects which need to be validated.
974 // [2] The function has not explicitly declared an effect in question, and is
975 // being checked for implicit conformance.
976 //
977 // Violations are always routed to a PendingFunctionAnalysis.
978 struct FunctionBodyASTVisitor : DynamicRecursiveASTVisitor {
979 Analyzer &Outer;
980 PendingFunctionAnalysis &CurrentFunction;
981 CallableInfo &CurrentCaller;
982 ViolationSite VSite;
983 const Expr *TrailingRequiresClause = nullptr;
984 const Expr *NoexceptExpr = nullptr;
985
986 FunctionBodyASTVisitor(Analyzer &Outer,
987 PendingFunctionAnalysis &CurrentFunction,
988 CallableInfo &CurrentCaller)
989 : Outer(Outer), CurrentFunction(CurrentFunction),
990 CurrentCaller(CurrentCaller) {
991 ShouldVisitImplicitCode = true;
992 ShouldWalkTypesOfTypeLocs = false;
993 }
994
995 // -- Entry point --
996 void run() {
997 // The target function may have implicit code paths beyond the
998 // body: member and base destructors. Visit these first.
999 if (auto *Dtor = dyn_cast<CXXDestructorDecl>(CurrentCaller.CDecl))
1000 followDestructor(Dtor->getParent(), Dtor);
1001
1002 if (auto *FD = dyn_cast<FunctionDecl>(CurrentCaller.CDecl)) {
1003 TrailingRequiresClause = FD->getTrailingRequiresClause().ConstraintExpr;
1004
1005 // Note that FD->getType->getAs<FunctionProtoType>() can yield a
1006 // noexcept Expr which has been boiled down to a constant expression.
1007 // Going through the TypeSourceInfo obtains the actual expression which
1008 // will be traversed as part of the function -- unless we capture it
1009 // here and have TraverseStmt skip it.
1010 if (TypeSourceInfo *TSI = FD->getTypeSourceInfo()) {
1011 if (FunctionProtoTypeLoc TL =
1012 TSI->getTypeLoc().getAs<FunctionProtoTypeLoc>())
1013 if (const FunctionProtoType *FPT = TL.getTypePtr())
1014 NoexceptExpr = FPT->getNoexceptExpr();
1015 }
1016 }
1017
1018 // Do an AST traversal of the function/block body
1019 TraverseDecl(const_cast<Decl *>(CurrentCaller.CDecl));
1020 }
1021
1022 // -- Methods implementing common logic --
1023
1024 // Handle a language construct forbidden by some effects. Only effects whose
1025 // flags include the specified flag receive a violation. \p Flag describes
1026 // the construct.
1027 void diagnoseLanguageConstruct(FunctionEffect::FlagBit Flag,
1028 ViolationID VID, SourceLocation Loc,
1029 const Decl *Callee = nullptr) {
1030 // If there are any declared verifiable effects which forbid the construct
1031 // represented by the flag, store just one violation.
1032 for (FunctionEffect Effect : CurrentFunction.DeclaredVerifiableEffects) {
1033 if (Effect.flags() & Flag) {
1034 addViolation(/*inferring=*/false, Effect, VID, Loc, Callee);
1035 break;
1036 }
1037 }
1038 // For each inferred effect which forbids the construct, store a
1039 // violation, if we don't already have a violation for that effect.
1040 for (FunctionEffect Effect : CurrentFunction.EffectsToInfer)
1041 if (Effect.flags() & Flag)
1042 addViolation(/*inferring=*/true, Effect, VID, Loc, Callee);
1043 }
1044
1045 void addViolation(bool Inferring, FunctionEffect Effect, ViolationID VID,
1046 SourceLocation Loc, const Decl *Callee = nullptr) {
1047 CurrentFunction.checkAddViolation(
1048 Inferring, Violation(Effect, VID, VSite, Loc, Callee));
1049 }
1050
1051 // Here we have a call to a Decl, either explicitly via a CallExpr or some
1052 // other AST construct. CallableInfo pertains to the callee.
1053 void followCall(CallableInfo &CI, SourceLocation CallLoc) {
1054 // Check for a call to a builtin function, whose effects are
1055 // handled specially.
1056 if (const auto *FD = dyn_cast<FunctionDecl>(CI.CDecl)) {
1057 if (unsigned BuiltinID = FD->getBuiltinID()) {
1058 CI.Effects = getBuiltinFunctionEffects(BuiltinID);
1059 if (CI.Effects.empty()) {
1060 // A builtin with no known effects is assumed safe.
1061 return;
1062 }
1063 // A builtin WITH effects doesn't get any special treatment for
1064 // being noreturn/noexcept, e.g. longjmp(), so we skip the check
1065 // below.
1066 } else {
1067 // If the callee is both `noreturn` and `noexcept`, it presumably
1068 // terminates. Ignore it for the purposes of effect analysis.
1069 // If not C++, `noreturn` alone is sufficient.
1070 if (FD->isNoReturn() &&
1071 (!Outer.S.getLangOpts().CPlusPlus || isNoexcept(FD)))
1072 return;
1073 }
1074 }
1075
1076 Outer.followCall(CurrentCaller, CurrentFunction, CI, CallLoc,
1077 /*AssertNoFurtherInference=*/false, VSite);
1078 }
1079
1080 void checkIndirectCall(CallExpr *Call, QualType CalleeType) {
1081 FunctionEffectKindSet CalleeEffects;
1082 if (FunctionEffectsRef Effects = FunctionEffectsRef::get(CalleeType);
1083 !Effects.empty())
1084 CalleeEffects.insert(Effects);
1085
1086 auto Check1Effect = [&](FunctionEffect Effect, bool Inferring) {
1087 if (Effect.shouldDiagnoseFunctionCall(
1088 /*direct=*/false, CalleeEffects))
1089 addViolation(Inferring, Effect, ViolationID::CallsExprWithoutEffect,
1090 Call->getBeginLoc());
1091 };
1092
1093 for (FunctionEffect Effect : CurrentFunction.DeclaredVerifiableEffects)
1094 Check1Effect(Effect, false);
1095
1096 for (FunctionEffect Effect : CurrentFunction.EffectsToInfer)
1097 Check1Effect(Effect, true);
1098 }
1099
1100 // This destructor's body should be followed by the caller, but here we
1101 // follow the field and base destructors.
1102 void followDestructor(const CXXRecordDecl *Rec,
1103 const CXXDestructorDecl *Dtor) {
1104 SourceLocation DtorLoc = Dtor->getLocation();
1105 for (const FieldDecl *Field : Rec->fields())
1106 followTypeDtor(Field->getType(), DtorLoc);
1107
1108 for (const CXXBaseSpecifier &Base : Rec->bases())
1109 followTypeDtor(Base.getType(), DtorLoc);
1110 }
1111
1112 void followTypeDtor(QualType QT, SourceLocation CallSite) {
1113 const Type *Ty = QT.getTypePtr();
1114 while (Ty->isArrayType()) {
1115 const ArrayType *Arr = Ty->getAsArrayTypeUnsafe();
1116 QT = Arr->getElementType();
1117 Ty = QT.getTypePtr();
1118 }
1119
1120 if (Ty->isRecordType()) {
1121 if (const CXXRecordDecl *Class = Ty->getAsCXXRecordDecl()) {
1122 if (CXXDestructorDecl *Dtor = Class->getDestructor();
1123 Dtor && !Dtor->isDeleted()) {
1124 CallableInfo CI(*Dtor);
1125 followCall(CI, CallSite);
1126 }
1127 }
1128 }
1129 }
1130
1131 // -- Methods for use of RecursiveASTVisitor --
1132
1133 bool VisitCXXThrowExpr(CXXThrowExpr *Throw) override {
1134 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow,
1135 ViolationID::ThrowsOrCatchesExceptions,
1136 Throw->getThrowLoc());
1137 return true;
1138 }
1139
1140 bool VisitCXXCatchStmt(CXXCatchStmt *Catch) override {
1141 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1142 ViolationID::ThrowsOrCatchesExceptions,
1143 Catch->getCatchLoc());
1144 return true;
1145 }
1146
1147 bool VisitObjCAtThrowStmt(ObjCAtThrowStmt *Throw) override {
1148 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThrow,
1149 ViolationID::ThrowsOrCatchesExceptions,
1150 Throw->getThrowLoc());
1151 return true;
1152 }
1153
1154 bool VisitObjCAtCatchStmt(ObjCAtCatchStmt *Catch) override {
1155 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1156 ViolationID::ThrowsOrCatchesExceptions,
1157 Catch->getAtCatchLoc());
1158 return true;
1159 }
1160
1161 bool VisitObjCAtFinallyStmt(ObjCAtFinallyStmt *Finally) override {
1162 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1163 ViolationID::ThrowsOrCatchesExceptions,
1164 Finally->getAtFinallyLoc());
1165 return true;
1166 }
1167
1168 bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) override {
1169 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1170 ViolationID::AccessesObjCMethodOrProperty,
1171 Msg->getBeginLoc());
1172 return true;
1173 }
1174
1175 bool VisitObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt *ARP) override {
1176 // Under the hood, @autorelease (potentially?) allocates memory and
1177 // invokes ObjC methods. We don't currently have memory allocation as
1178 // a "language construct" but we do have ObjC messaging, so diagnose that.
1179 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1180 ViolationID::AccessesObjCMethodOrProperty,
1181 ARP->getBeginLoc());
1182 return true;
1183 }
1184
1185 bool VisitObjCAtSynchronizedStmt(ObjCAtSynchronizedStmt *Sync) override {
1186 // Under the hood, this calls objc_sync_enter and objc_sync_exit, wrapped
1187 // in a @try/@finally block. Diagnose this generically as "ObjC
1188 // messaging".
1189 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeObjCMessageSend,
1190 ViolationID::AccessesObjCMethodOrProperty,
1191 Sync->getBeginLoc());
1192 return true;
1193 }
1194
1195 bool VisitSEHExceptStmt(SEHExceptStmt *Exc) override {
1196 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeCatch,
1197 ViolationID::ThrowsOrCatchesExceptions,
1198 Exc->getExceptLoc());
1199 return true;
1200 }
1201
1202 bool VisitCallExpr(CallExpr *Call) override {
1203 LLVM_DEBUG(llvm::dbgs()
1204 << "VisitCallExpr : "
1205 << Call->getBeginLoc().printToString(Outer.S.SourceMgr)
1206 << "\n";);
1207
1208 Expr *CalleeExpr = Call->getCallee();
1209 if (const Decl *Callee = CalleeExpr->getReferencedDeclOfCallee()) {
1210 CallableInfo CI(*Callee);
1211 followCall(CI, Call->getBeginLoc());
1212 return true;
1213 }
1214
1215 if (isa<CXXPseudoDestructorExpr>(CalleeExpr)) {
1216 // Just destroying a scalar, fine.
1217 return true;
1218 }
1219
1220 // No Decl, just an Expr. Just check based on its type. Bound member
1221 // functions are a special expression type and need to be specially
1222 // unpacked.
1223 QualType CalleeExprQT = CalleeExpr->getType();
1224 if (CalleeExpr->isBoundMemberFunction(Outer.S.getASTContext())) {
1225 QualType QT = Expr::findBoundMemberType(CalleeExpr);
1226 if (!QT.isNull())
1227 CalleeExprQT = QT;
1228 }
1229 checkIndirectCall(Call, CalleeExprQT);
1230
1231 return true;
1232 }
1233
1234 bool VisitVarDecl(VarDecl *Var) override {
1235 LLVM_DEBUG(llvm::dbgs()
1236 << "VisitVarDecl : "
1237 << Var->getBeginLoc().printToString(Outer.S.SourceMgr)
1238 << "\n";);
1239
1240 if (Var->isStaticLocal())
1241 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeStaticLocalVars,
1242 ViolationID::HasStaticLocalVariable,
1243 Var->getLocation());
1244
1245 const QualType::DestructionKind DK =
1246 Var->needsDestruction(Outer.S.getASTContext());
1248 followTypeDtor(Var->getType(), Var->getLocation());
1249 return true;
1250 }
1251
1252 bool VisitCXXNewExpr(CXXNewExpr *New) override {
1253 // RecursiveASTVisitor does not visit the implicit call to operator new.
1254 if (FunctionDecl *FD = New->getOperatorNew()) {
1255 CallableInfo CI(*FD, SpecialFuncType::OperatorNew);
1256 followCall(CI, New->getBeginLoc());
1257 }
1258
1259 // It's a bit excessive to check operator delete here, since it's
1260 // just a fallback for operator new followed by a failed constructor.
1261 // We could check it via New->getOperatorDelete().
1262
1263 // It DOES however visit the called constructor
1264 return true;
1265 }
1266
1267 bool VisitCXXDeleteExpr(CXXDeleteExpr *Delete) override {
1268 FunctionDecl *OpDelete = Delete->getOperatorDelete();
1269
1270 // RecursiveASTVisitor does not visit the called destructor.
1271 // But a destroying operator delete means that no destructor is called.
1272 if (OpDelete == nullptr || !OpDelete->isDestroyingOperatorDelete()) {
1273 if (QualType QT = Delete->getDestroyedType(); !QT.isNull()) {
1274 followTypeDtor(QT, Delete->getBeginLoc());
1275 }
1276 }
1277
1278 // RecursiveASTVisitor does not visit the implicit call to operator
1279 // delete.
1280 if (OpDelete != nullptr) {
1281 CallableInfo CI(*OpDelete, SpecialFuncType::OperatorDelete);
1282 followCall(CI, Delete->getBeginLoc());
1283 }
1284
1285 return true;
1286 }
1287
1288 bool VisitCXXConstructExpr(CXXConstructExpr *Construct) override {
1289 LLVM_DEBUG(llvm::dbgs() << "VisitCXXConstructExpr : "
1290 << Construct->getBeginLoc().printToString(
1291 Outer.S.SourceMgr)
1292 << "\n";);
1293
1294 // RecursiveASTVisitor does not visit the implicit call to the
1295 // constructor.
1296 const CXXConstructorDecl *Ctor = Construct->getConstructor();
1297 CallableInfo CI(*Ctor);
1298 followCall(CI, Construct->getLocation());
1299 return true;
1300 }
1301
1302 bool VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *BTE) override {
1303 const CXXDestructorDecl *Dtor = BTE->getTemporary()->getDestructor();
1304 if (Dtor != nullptr) {
1305 CallableInfo CI(*Dtor);
1306 followCall(CI, BTE->getBeginLoc());
1307 }
1308 return true;
1309 }
1310
1311 bool TraverseStmt(Stmt *Statement) override {
1312 // If this statement is a `requires` clause from the top-level function
1313 // being traversed, ignore it, since it's not generating runtime code.
1314 // We skip the traversal of lambdas (beyond their captures, see
1315 // TraverseLambdaExpr below), so just caching this from our constructor
1316 // should suffice.
1317 if (Statement != TrailingRequiresClause && Statement != NoexceptExpr)
1319 return true;
1320 }
1321
1322 bool TraverseCXXRecordDecl(CXXRecordDecl *D) override {
1323 // Completely skip local struct/class/union declarations since their
1324 // methods would otherwise be incorrectly interpreted as part of the
1325 // function we are currently traversing. The initial Sema pass will have
1326 // already recorded any nonblocking methods needing analysis.
1327 return true;
1328 }
1329
1330 bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
1331 ViolationSite PrevVS = VSite;
1332 if (Init->isAnyMemberInitializer())
1333 VSite.setKind(ViolationSite::Kind::MemberInitializer);
1334 bool Result =
1336 VSite = PrevVS;
1337 return Result;
1338 }
1339
1340 bool TraverseCXXDefaultArgExpr(CXXDefaultArgExpr *E) override {
1341 LLVM_DEBUG(llvm::dbgs()
1342 << "TraverseCXXDefaultArgExpr : "
1343 << E->getUsedLocation().printToString(Outer.S.SourceMgr)
1344 << "\n";);
1345
1346 ViolationSite PrevVS = VSite;
1347 if (VSite.kind() == ViolationSite::Kind::Default)
1348 VSite = ViolationSite{E};
1349
1350 bool Result = DynamicRecursiveASTVisitor::TraverseCXXDefaultArgExpr(E);
1351 VSite = PrevVS;
1352 return Result;
1353 }
1354
1355 bool TraverseLambdaExpr(LambdaExpr *Lambda) override {
1356 // We override this so as to be able to skip traversal of the lambda's
1357 // body. We have to explicitly traverse the captures. Why not return
1358 // false from shouldVisitLambdaBody()? Because we need to visit a lambda's
1359 // body when we are verifying the lambda itself; we only want to skip it
1360 // in the context of the outer function.
1361 for (unsigned I = 0, N = Lambda->capture_size(); I < N; ++I)
1362 TraverseLambdaCapture(Lambda, Lambda->capture_begin() + I,
1363 Lambda->capture_init_begin()[I]);
1364
1365 return true;
1366 }
1367
1368 bool TraverseBlockExpr(BlockExpr * /*unused*/) override {
1369 // As with lambdas, don't traverse the block's body.
1370 // TODO: are the capture expressions (ctor call?) safe?
1371 return true;
1372 }
1373
1374 bool VisitDeclRefExpr(DeclRefExpr *E) override {
1375 const ValueDecl *Val = E->getDecl();
1376 if (const auto *Var = dyn_cast<VarDecl>(Val)) {
1377 if (Var->getTLSKind() != VarDecl::TLS_None) {
1378 // At least on macOS, thread-local variables are initialized on
1379 // first access, including a heap allocation.
1380 diagnoseLanguageConstruct(FunctionEffect::FE_ExcludeThreadLocalVars,
1381 ViolationID::AccessesThreadLocalVariable,
1382 E->getLocation());
1383 }
1384 }
1385 return true;
1386 }
1387
1388 bool TraverseGenericSelectionExpr(GenericSelectionExpr *Node) override {
1389 return TraverseStmt(Node->getResultExpr());
1390 }
1391 bool
1392 TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) override {
1393 return true;
1394 }
1395
1396 bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node,
1397 bool TraverseQualifier) override {
1398 return true;
1399 }
1400
1401 bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node,
1402 bool TraverseQualifier) override {
1403 return true;
1404 }
1405
1406 bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override {
1407 return true;
1408 }
1409
1410 bool TraverseCXXTypeidExpr(CXXTypeidExpr *Node) override { return true; }
1411
1412 // Skip concept requirements since they don't generate code.
1413 bool TraverseConceptRequirement(concepts::Requirement *R) override {
1414 return true;
1415 }
1416 };
1417};
1418
1419Analyzer::AnalysisMap::~AnalysisMap() {
1420 for (const auto &Item : *this) {
1421 FuncAnalysisPtr AP = Item.second;
1422 if (auto *PFA = dyn_cast<PendingFunctionAnalysis *>(AP))
1423 delete PFA;
1424 else
1426 }
1427}
1428
1429} // anonymous namespace
1430
1431namespace clang {
1432
1434 const FunctionEffectsRef &FX, const FunctionEffectWithCondition &NewEC,
1435 SourceLocation NewAttrLoc) {
1436 // If the new effect has a condition, we can't detect conflicts until the
1437 // condition is resolved.
1438 if (NewEC.Cond.getCondition() != nullptr)
1439 return false;
1440
1441 // Diagnose the new attribute as incompatible with a previous one.
1442 auto Incompatible = [&](const FunctionEffectWithCondition &PrevEC) {
1443 Diag(NewAttrLoc, diag::err_attributes_are_not_compatible)
1444 << ("'" + NewEC.description() + "'")
1445 << ("'" + PrevEC.description() + "'") << false;
1446 // We don't necessarily have the location of the previous attribute,
1447 // so no note.
1448 return true;
1449 };
1450
1451 // Compare against previous attributes.
1452 FunctionEffect::Kind NewKind = NewEC.Effect.kind();
1453
1454 for (const FunctionEffectWithCondition &PrevEC : FX) {
1455 // Again, can't check yet when the effect is conditional.
1456 if (PrevEC.Cond.getCondition() != nullptr)
1457 continue;
1458
1459 FunctionEffect::Kind PrevKind = PrevEC.Effect.kind();
1460 // Note that we allow PrevKind == NewKind; it's redundant and ignored.
1461
1462 if (PrevEC.Effect.oppositeKind() == NewKind)
1463 return Incompatible(PrevEC);
1464
1465 // A new allocating is incompatible with a previous nonblocking.
1466 if (PrevKind == FunctionEffect::Kind::NonBlocking &&
1468 return Incompatible(PrevEC);
1469
1470 // A new nonblocking is incompatible with a previous allocating.
1471 if (PrevKind == FunctionEffect::Kind::Allocating &&
1473 return Incompatible(PrevEC);
1474 }
1475
1476 return false;
1477}
1478
1480 const FunctionEffectSet::Conflicts &Errs, SourceLocation NewLoc,
1481 SourceLocation OldLoc) {
1482 for (const FunctionEffectSet::Conflict &Conflict : Errs) {
1483 Diag(NewLoc, diag::warn_conflicting_func_effects)
1484 << Conflict.Kept.description() << Conflict.Rejected.description();
1485 Diag(OldLoc, diag::note_previous_declaration);
1486 }
1487}
1488
1489// Decl should be a FunctionDecl or BlockDecl.
1491 const FunctionEffectsRef &FX) {
1492 if (!D->hasBody()) {
1493 if (const auto *FD = D->getAsFunction(); FD && !FD->willHaveBody())
1494 return;
1495 }
1496
1497 if (Diags.getIgnoreAllWarnings() ||
1498 (Diags.getSuppressSystemWarnings() &&
1499 SourceMgr.isInSystemHeader(D->getLocation())))
1500 return;
1501
1503 return;
1504
1505 // For code in dependent contexts, we'll do this at instantiation time.
1506 // Without this check, we would analyze the function based on placeholder
1507 // template parameters, and potentially generate spurious diagnostics.
1508 if (cast<DeclContext>(D)->isDependentContext())
1509 return;
1510
1511 addDeclWithEffects(D, FX);
1512}
1513
1515 // To avoid the possibility of conflict, don't add effects which are
1516 // not FE_InferrableOnCallees and therefore not verified; this removes
1517 // blocking/allocating but keeps nonblocking/nonallocating.
1518 // Also, ignore any conditions when building the list of effects.
1519 bool AnyVerifiable = false;
1520 for (const FunctionEffectWithCondition &EC : FX)
1521 if (EC.Effect.flags() & FunctionEffect::FE_InferrableOnCallees) {
1522 AllEffectsToVerify.insert(EC.Effect);
1523 AnyVerifiable = true;
1524 }
1525
1526 // Record the declaration for later analysis.
1527 if (AnyVerifiable)
1528 DeclsWithEffectsToVerify.push_back(D);
1529}
1530
1532 if (hasUncompilableErrorOccurred() || Diags.getIgnoreAllWarnings())
1533 return;
1534 if (TU == nullptr)
1535 return;
1536 Analyzer{*this}.run(*TU);
1537}
1538
1540 const FunctionEffectsRef &Old, const FunctionEffectsRef &New) {
1541
1543 FunctionEffectsRef::iterator OldEnd = Old.end();
1544 FunctionEffectsRef::iterator PNew = New.begin();
1545 FunctionEffectsRef::iterator NewEnd = New.end();
1546
1547 while (true) {
1548 int cmp = 0;
1549 if (POld == OldEnd) {
1550 if (PNew == NewEnd)
1551 break;
1552 cmp = 1;
1553 } else if (PNew == NewEnd)
1554 cmp = -1;
1555 else {
1556 FunctionEffectWithCondition Old = *POld;
1558 if (Old.Effect.kind() < New.Effect.kind())
1559 cmp = -1;
1560 else if (New.Effect.kind() < Old.Effect.kind())
1561 cmp = 1;
1562 else {
1563 cmp = 0;
1564 if (Old.Cond.getCondition() != New.Cond.getCondition()) {
1565 // FIXME: Cases where the expressions are equivalent but
1566 // don't have the same identity.
1567 push_back(FunctionEffectDiff{
1569 Old, New});
1570 }
1571 }
1572 }
1573
1574 if (cmp < 0) {
1575 // removal
1576 FunctionEffectWithCondition Old = *POld;
1577 push_back(FunctionEffectDiff{Old.Effect.kind(),
1579 std::nullopt});
1580 ++POld;
1581 } else if (cmp > 0) {
1582 // addition
1584 push_back(FunctionEffectDiff{New.Effect.kind(),
1586 std::nullopt, New});
1587 ++PNew;
1588 } else {
1589 ++POld;
1590 ++PNew;
1591 }
1592 }
1593}
1594
1596 QualType SrcType, const FunctionEffectsRef &SrcFX, QualType DstType,
1597 const FunctionEffectsRef &DstFX) const {
1598
1599 switch (EffectKind) {
1601 // nonallocating can't be added (spoofed) during a conversion, unless we
1602 // have nonblocking.
1603 if (DiffKind == Kind::Added) {
1604 for (const auto &CFE : SrcFX) {
1605 if (CFE.Effect.kind() == FunctionEffect::Kind::NonBlocking)
1606 return false;
1607 }
1608 }
1609 [[fallthrough]];
1611 // nonblocking can't be added (spoofed) during a conversion.
1612 switch (DiffKind) {
1613 case Kind::Added:
1614 return true;
1615 case Kind::Removed:
1616 return false;
1618 // FIXME: Condition mismatches are too coarse right now -- expressions
1619 // which are equivalent but don't have the same identity are detected as
1620 // mismatches. We're going to diagnose those anyhow until expression
1621 // matching is better.
1622 return true;
1623 }
1624 break;
1627 return false;
1628 }
1629 llvm_unreachable("unknown effect kind");
1630}
1631
1633 const FunctionDecl &OldFunction, const FunctionEffectsRef &OldFX,
1634 const FunctionDecl &NewFunction, const FunctionEffectsRef &NewFX) const {
1635 switch (EffectKind) {
1638 // nonblocking/nonallocating can't be removed in a redeclaration.
1639 switch (DiffKind) {
1640 case Kind::Added:
1641 return false; // No diagnostic.
1642 case Kind::Removed:
1643 return true; // Issue diagnostic.
1645 // All these forms of mismatches are diagnosed.
1646 return true;
1647 }
1648 break;
1651 return false;
1652 }
1653 llvm_unreachable("unknown effect kind");
1654}
1655
1658 const CXXMethodDecl &OldMethod, const FunctionEffectsRef &OldFX,
1659 const CXXMethodDecl &NewMethod, const FunctionEffectsRef &NewFX) const {
1660 switch (EffectKind) {
1663 switch (DiffKind) {
1664
1665 // If added on an override, that's fine and not diagnosed.
1666 case Kind::Added:
1668
1669 // If missing from an override (removed), propagate from base to derived.
1670 case Kind::Removed:
1671 return OverrideResult::Merge;
1672
1673 // If there's a mismatch involving the effect's polarity or condition,
1674 // issue a warning.
1676 return OverrideResult::Warn;
1677 }
1678 break;
1682 }
1683 llvm_unreachable("unknown effect kind");
1684}
1685
1686} // 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....
Result
Implement __builtin_bit_cast and related operations.
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:82
static void emitDiagnostics(BoundNodes &Match, const Decl *D, BugReporter &BR, AnalysisManager &AM, const ObjCAutoreleaseWriteChecker *Checker)
*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:245
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3820
QualType getElementType() const
Definition TypeBase.h:3832
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6758
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1498
CXXTemporary * getTemporary()
Definition ExprCXX.h:1516
SourceLocation getBeginLoc() const LLVM_READONLY
Definition ExprCXX.h:1524
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:29
SourceLocation getCatchLoc() const
Definition StmtCXX.h:49
Represents a call to a C++ constructor.
Definition ExprCXX.h:1553
SourceLocation getLocation() const
Definition ExprCXX.h:1618
SourceLocation getBeginLoc() const LLVM_READONLY
Definition ExprCXX.cpp:605
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Definition ExprCXX.h:1616
Represents a C++ constructor within a class.
Definition DeclCXX.h:2645
Represents a C++ base or member initializer.
Definition DeclCXX.h:2410
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1275
SourceLocation getUsedLocation() const
Retrieve the location where this default argument was actually used.
Definition ExprCXX.h:1349
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2631
Represents a C++ destructor within a class.
Definition DeclCXX.h:2915
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2153
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2360
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition ExprCXX.h:4363
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
base_class_range bases()
Definition DeclCXX.h:609
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition DeclCXX.h:1028
const CXXDestructorDecl * getDestructor() const
Definition ExprCXX.h:1475
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1213
SourceLocation getThrowLoc() const
Definition ExprCXX.h:1236
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:853
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:3012
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2108
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:1315
ValueDecl * getDecl()
Definition Expr.h:1383
SourceLocation getLocation() const
Definition Expr.h:1391
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:1111
SourceLocation getLocation() const
Definition DeclBase.h:448
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:440
bool hasAttr() const
Definition DeclBase.h:586
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:996
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:833
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition Decl.h:857
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:811
virtual bool TraverseConstructorInitializer(MaybeConst< CXXCtorInitializer > *Init)
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
Expr * getCondition() const
Definition TypeBase.h:5275
This represents one expression.
Definition Expr.h:114
static QualType findBoundMemberType(const Expr *expr)
Given an expression of bound-member type, find the type of the member.
Definition Expr.cpp:3085
Decl * getReferencedDeclOfCallee()
Definition Expr.cpp:1578
bool isBoundMemberFunction(ASTContext &Ctx) const
Returns true if this expression is a bound member function.
Definition Expr.cpp:3079
QualType getType() const
Definition Expr.h:146
Represents a member of a struct/union/class.
Definition Decl.h:3311
Represents a function declaration or definition.
Definition Decl.h:2071
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
Definition Decl.cpp:3611
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3822
SourceLocation getPointOfInstantiation() const
Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...
Definition Decl.cpp:4596
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
Definition Decl.cpp:3711
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:4326
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
Definition Decl.h:2516
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:3807
FunctionEffectsRef getFunctionEffects() const
Definition Decl.h:3285
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
Definition Decl.cpp:4319
FunctionDecl * getDefinition()
Get the definition for this declaration.
Definition Decl.h:2408
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
Definition Decl.cpp:3204
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:3129
bool willHaveBody() const
True if this function will eventually have a body, once it's fully parsed.
Definition Decl.h:2828
A mutable set of FunctionEffect::Kind.
Definition TypeBase.h:5402
static FunctionEffectKindSet difference(FunctionEffectKindSet LHS, FunctionEffectKindSet RHS)
Definition TypeBase.h:5474
bool contains(const FunctionEffect::Kind EK) const
Definition TypeBase.h:5469
void dump(llvm::raw_ostream &OS) const
Definition Type.cpp:6130
void insert(FunctionEffect Effect)
Definition TypeBase.h:5461
SmallVector< Conflict > Conflicts
Definition TypeBase.h:5516
Represents an abstract function effect, using just an enumeration describing its kind.
Definition TypeBase.h:5161
Kind kind() const
The kind of the effect.
Definition TypeBase.h:5200
unsigned Flags
Flags describing some behaviors of the effect.
Definition TypeBase.h:5174
Kind
Identifies the particular effect.
Definition TypeBase.h:5164
Flags flags() const
Flags describing some behaviors of the effect.
Definition TypeBase.h:5212
bool shouldDiagnoseFunctionCall(bool Direct, FunctionEffectKindSet CalleeFX) const
Definition Type.cpp:5981
StringRef name() const
The description printed in diagnostics, e.g. 'nonblocking'.
Definition Type.cpp:5943
An immutable set of FunctionEffects and possibly conditions attached to them.
Definition TypeBase.h:5348
iterator begin() const
Definition TypeBase.h:5386
iterator end() const
Definition TypeBase.h:5387
FunctionEffectIterator< FunctionEffectsRef > iterator
Definition TypeBase.h:5384
static FunctionEffectsRef get(QualType QT)
Extract the effects from a Type if it is a function, block, or member function pointer,...
Definition TypeBase.h:9536
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5548
Represents a C11 generic selection.
Definition Expr.h:6268
Expr * getResultExpr()
Return the result expression of this controlling expression.
Definition Expr.h:6554
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1973
capture_iterator capture_begin() const
Retrieve an iterator pointing to the first lambda capture.
Definition ExprCXX.cpp:1395
unsigned capture_size() const
Determine the number of captures in this lambda.
Definition ExprCXX.h:2054
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
Definition ExprCXX.h:2099
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:972
SourceLocation getBeginLoc() const LLVM_READONLY
Definition ExprObjC.h:1490
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8578
field_range fields() const
Definition Decl.h:4679
SourceLocation getExceptLoc() const
Definition Stmt.h:3799
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:862
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:15983
ASTContext & getASTContext() const
Definition Sema.h:934
SmallVector< const Decl * > DeclsWithEffectsToVerify
All functions/lambdas/blocks which have bodies and which have a non-empty FunctionEffectsRef to be ve...
Definition Sema.h:15979
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition Sema.h:1235
const LangOptions & getLangOpts() const
Definition Sema.h:927
void maybeAddDeclWithEffects(FuncOrBlockDecl *D)
Inline checks from the start of maybeAddDeclWithEffects, to minimize performance impact on code not u...
Definition Sema.h:16002
void performFunctionEffectAnalysis(TranslationUnitDecl *TU)
SourceManager & getSourceManager() const
Definition Sema.h:932
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:1905
SourceManager & SourceMgr
Definition Sema.h:1334
DiagnosticsEngine & Diags
Definition Sema.h:1333
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 isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
Stmt - This represents one statement.
Definition Stmt.h:85
The top declaration context.
Definition Decl.h:107
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:8549
The base class of the type hierarchy.
Definition TypeBase.h:1879
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:8914
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition TypeBase.h:9484
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9431
bool isRecordType() const
Definition TypeBase.h:8942
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2694
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:714
QualType getType() const
Definition Decl.h:725
Represents a variable declaration or definition.
Definition Decl.h:934
TLSKind getTLSKind() const
Definition Decl.cpp:2149
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition Decl.h:1216
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
Definition Decl.cpp:2843
@ TLS_None
Not a TLS variable.
Definition Decl.h:954
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.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ Delete
'delete' clause, allowed on the 'exit data' construct.
@ Default
Set to the current date and time.
@ Incompatible
Incompatible - We reject this conversion outright, it is invalid to represent it in the AST.
Definition Sema.h:780
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
U cast(CodeGen::Address addr)
Definition Address.h:327
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 __builtin_elementwise_add_sat __builtin_elementwise_sub_sat int32_t uint32_t uint32_t __builtin_riscv_mhacc_i32 __builtin_riscv_mhaccu_u32 __builtin_riscv_mhaccsu_i32 __builtin_riscv_mulq_i32 __builtin_riscv_mqwacc_i64 uint8_t
const Expr * ConstraintExpr
Definition Decl.h:90
A FunctionEffect plus a potential boolean expression determining whether the effect is declared (e....
Definition TypeBase.h:5285
std::string description() const
Return a textual description of the effect, and its condition, if any.
Definition Type.cpp:6145
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:15944
FunctionEffect::Kind EffectKind
Definition Sema.h:15929