A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://clang.llvm.org/doxygen/SemaFunctionEffects_8cpp_source.html below:

clang: lib/Sema/SemaFunctionEffects.cpp Source File

23#define DEBUG_TYPE "effectanalysis" 25using namespace clang

;

29enum class

ViolationID : uint8_t {

34

AllocatesMemory = BaseDiagnosticIndex,

35

ThrowsOrCatchesExceptions,

36

HasStaticLocalVariable,

37

AccessesThreadLocalVariable,

38

AccessesObjCMethodOrProperty,

41

DeclDisallowsInference,

47

CallsDeclWithoutEffect,

48

CallsExprWithoutEffect,

55 enum class

Kind : uint8_t {

62

llvm::PointerIntPair<CXXDefaultArgExpr *, 2, Kind> Impl;

65

ViolationSite() =

default

;

68

: Impl(

E

, Kind::DefaultArgExpr) {}

70

Kind kind()

const

{

return static_cast<

Kind

>

(Impl.getInt()); }

73 void

setKind(Kind K) { Impl.setPointerAndInt(

nullptr

, K); }

84

std::optional<FunctionEffect>

85

CalleeEffectPreventingInference;

86

ViolationID ID = ViolationID::None;

92

Violation(

FunctionEffect

Effect, ViolationID ID, ViolationSite VS,

94

std::optional<FunctionEffect> CalleeEffect = std::nullopt)

95

: Effect(Effect), CalleeEffectPreventingInference(CalleeEffect), ID(ID),

96

Site(VS),

Loc

(

Loc

), Callee(Callee) {}

98 unsigned

diagnosticSelectIndex()

const

{

103enum class

SpecialFuncType : uint8_t {

None

, OperatorNew, OperatorDelete };

104enum class

CallableType : uint8_t {

114static bool

functionIsVerifiable(

const FunctionDecl

*FD) {

125 return

FPT && (FPT->isNothrow() || FD->

hasAttr

<NoThrowAttr>());

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:

157 case

Builtin::ID::BIfopen:

158 case

Builtin::ID::BIpthread_create:

159 case

Builtin::ID::BI_Block_object_dispose:

160

Result.insert(

FunctionEffect

(FunctionEffect::Kind::Allocating));

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:

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:

189 case

Builtin::ID::BIfread:

190 case

Builtin::ID::BIfwrite:

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:

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:

227

CallableType CType = CallableType::Unknown;

232

SpecialFuncType FuncType = SpecialFuncType::None;

237

CallableInfo(

const Decl

&CD, SpecialFuncType FT = SpecialFuncType::None)

238

: CDecl(&CD), FuncType(FT) {

240 if

(

auto

*FD = dyn_cast<FunctionDecl>(CDecl)) {

244

CType = CallableType::Function;

245 if

(

auto

*Method = dyn_cast<CXXMethodDecl>(FD);

246

Method && Method->isVirtual())

247

CType = CallableType::Virtual;

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)) {

259

CallableType

type

()

const

{

return

CType; }

261 bool

isCalledDirectly()

const

{

262 return

CType == CallableType::Function || CType == CallableType::Block;

265 bool

isVerifiable()

const

{

267 case

CallableType::Unknown:

268 case

CallableType::Virtual:

270 case

CallableType::Block:

272 case

CallableType::Function:

273 return

functionIsVerifiable(dyn_cast<FunctionDecl>(CDecl));

275

llvm_unreachable(

"undefined CallableType"

);

279

std::string getNameForDiagnostic(

Sema

&S)

const

{

281

llvm::raw_string_ostream OS(Name);

283 if

(

auto

*FD = dyn_cast<FunctionDecl>(CDecl))

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);

297class

EffectToViolationMap {

304

std::unique_ptr<ImplVec> Impl;

308 void

maybeInsert(

const

Violation &Viol) {

309 if

(Impl ==

nullptr

)

310

Impl = std::make_unique<ImplVec>();

311 else if

(lookup(Viol.Effect) !=

nullptr

)

314

Impl->push_back(Viol);

318 if

(Impl ==

nullptr

)

321 auto

*

Iter

= llvm::find_if(

322

*Impl, [&](

const auto

&Item) {

return

Item.Effect == Key; });

323 return Iter

!= Impl->end() ? &*

Iter

:

nullptr

;

326 size_t

size()

const

{

return

Impl ? Impl->size() : 0; }

332class

PendingFunctionAnalysis {

333 friend class

CompleteFunctionAnalysis;

341 bool

Recursed =

false

;

345

: Callee(

D

), CallLoc(CallLoc), VSite(VSite) {}

359

EffectToViolationMap InferrableEffectToFirstViolation;

366

PendingFunctionAnalysis(

Sema

&S,

const

CallableInfo &CInfo,

368

: DeclaredVerifiableEffects(CInfo.Effects) {

373

std::optional<FunctionEffect> ProblemCalleeEffect =

374

effect.effectProhibitingInference(*CInfo.CDecl, CInfo.Effects);

375 if

(!ProblemCalleeEffect)

376

InferrableEffects.

insert

(effect);

380

InferrableEffectToFirstViolation.maybeInsert(Violation(

381

effect, ViolationID::DeclDisallowsInference, ViolationSite{},

382

CInfo.CDecl->getLocation(),

nullptr

, ProblemCalleeEffect));

388

InferrableEffects, DeclaredVerifiableEffects);

393 void

checkAddViolation(

bool

Inferring,

const

Violation &NewViol) {

395

ViolationsForExplicitEffects.push_back(NewViol);

397

InferrableEffectToFirstViolation.maybeInsert(NewViol);

401

ViolationSite VSite) {

402

UnverifiedDirectCalls.emplace_back(

D

, CallLoc, VSite);

406 bool

isComplete()

const

{

return

UnverifiedDirectCalls.empty(); }

408 const

Violation *violationForInferrableEffect(

FunctionEffect

effect) {

409 return

InferrableEffectToFirstViolation.lookup(effect);

414

assert(!isComplete());

415 return

UnverifiedDirectCalls;

419 if

(!ViolationsForExplicitEffects.empty())

420

llvm::sort(ViolationsForExplicitEffects,

421

[&

SM

](

const

Violation &LHS,

const

Violation &RHS) {

422 return SM

.isBeforeInTranslationUnit(LHS.Loc, RHS.Loc);

424 return

ViolationsForExplicitEffects;

427 void dump

(

Sema

&SemaRef, llvm::raw_ostream &OS)

const

{

428

OS <<

"Pending: Declared "

;

429

DeclaredVerifiableEffects.

dump

(OS);

430

OS <<

", "

<< ViolationsForExplicitEffects.size() <<

" violations; "

;

432

EffectsToInfer.

dump

(OS);

433

OS <<

", "

<< InferrableEffectToFirstViolation.size() <<

" violations"

;

434 if

(!UnverifiedDirectCalls.empty()) {

436 for

(

const

DirectCall &

Call

: UnverifiedDirectCalls) {

437

CallableInfo CI(*

Call

.Callee);

438

OS <<

" "

<< CI.getNameForDiagnostic(SemaRef);

446class

CompleteFunctionAnalysis {

457

EffectToViolationMap InferrableEffectToFirstViolation;

461

CompleteFunctionAnalysis(

ASTContext

&Ctx, PendingFunctionAnalysis &&Pending,

464

: VerifiedEffects(DeclaredEffects) {

466 if

(Pending.violationForInferrableEffect(effect) ==

nullptr

)

467

VerifiedEffects.

insert

(effect);

469

InferrableEffectToFirstViolation =

470

std::move(Pending.InferrableEffectToFirstViolation);

473 const

Violation *firstViolationForEffect(

FunctionEffect

Effect) {

474 return

InferrableEffectToFirstViolation.lookup(Effect);

477 void dump

(llvm::raw_ostream &OS)

const

{

478

OS <<

"Complete: Verified "

;

479

VerifiedEffects.

dump

(OS);

481

OS << InferrableEffectToFirstViolation.size() <<

" violations\n"

;

492 using

FuncAnalysisPtr =

493

llvm::PointerUnion<PendingFunctionAnalysis *, CompleteFunctionAnalysis *>;

498 class

AnalysisMap : llvm::DenseMap<const Decl *, FuncAnalysisPtr> {

499 using Base

= llvm::DenseMap<const Decl *, FuncAnalysisPtr>;

507

FuncAnalysisPtr lookup(

const Decl

*Key)

const

{

511

FuncAnalysisPtr &operator[](

const Decl

*Key) {

516

CompleteFunctionAnalysis *completedAnalysisForDecl(

const Decl

*

D

)

const

{

517 if

(FuncAnalysisPtr AP = lookup(

D

);

518

isa_and_nonnull<CompleteFunctionAnalysis *>(AP))

519 return

cast<CompleteFunctionAnalysis *>(AP);

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) <<

" : "

;

531

}

else if

(

auto

*CFA = dyn_cast<CompleteFunctionAnalysis *>(AP)) {

534

}

else if

(

auto

*PFA = dyn_cast<PendingFunctionAnalysis *>(AP)) {

536

PFA->dump(SemaRef, OS);

538

llvm_unreachable(

"never"

);

543

AnalysisMap DeclAnalysis;

546

Analyzer(

Sema

&S) : S(S) {}

554

AllInferrableEffectsToVerify.

insert

(Effect);

556

LLVM_DEBUG(llvm::dbgs() <<

"AllInferrableEffectsToVerify: "

;

557

AllInferrableEffectsToVerify.

dump

(llvm::dbgs());

558

llvm::dbgs() <<

"\n"

;);

565

std::reverse(VerificationQueue.begin(), VerificationQueue.end());

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)) {

572

finishPendingAnalysis(

D

, Pending);

574

VerificationQueue.pop_back();

579

PendingFunctionAnalysis *Pending = verifyDecl(

D

);

580 if

(Pending ==

nullptr

) {

582

VerificationQueue.pop_back();

588 for

(PendingFunctionAnalysis::DirectCall &

Call

:

589

Pending->unverifiedCalls()) {

590

FuncAnalysisPtr AP = DeclAnalysis.lookup(

Call

.Callee);

592

VerificationQueue.push_back(

Call

.Callee);

599

assert(isa<PendingFunctionAnalysis *>(AP));

600 Call

.Recursed =

true

;

608

PendingFunctionAnalysis *verifyDecl(

const Decl

*

D

) {

609

CallableInfo CInfo(*

D

);

623 bool

IsNoexcept =

false

;

626

}

else if

(

auto

*BD = dyn_cast<BlockDecl>(

D

)) {

627 if

(

auto

*TSI = BD->getSignatureAsWritten()) {

629

IsNoexcept = FPT->

isNothrow

() || BD->hasAttr<NoThrowAttr>();

634

<< GetCallableDeclKind(

D

,

nullptr

) << Effect.

name

();

642

PendingFunctionAnalysis FAnalysis(S, CInfo, AllInferrableEffectsToVerify);

644

LLVM_DEBUG(llvm::dbgs()

645

<<

"\nVerifying "

<< CInfo.getNameForDiagnostic(S) <<

" "

;

646

FAnalysis.dump(S, llvm::dbgs()););

648

FunctionBodyASTVisitor Visitor(*

this

, FAnalysis, CInfo);

651 if

(FAnalysis.isComplete()) {

652

completeAnalysis(CInfo, std::move(FAnalysis));

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()););

666 void

completeAnalysis(

const

CallableInfo &CInfo,

667

PendingFunctionAnalysis &&Pending) {

673

CompleteFunctionAnalysis *CompletePtr =

new

CompleteFunctionAnalysis(

675

AllInferrableEffectsToVerify);

676

DeclAnalysis[CInfo.CDecl] = CompletePtr;

677

LLVM_DEBUG(llvm::dbgs() <<

"inserted complete "

<< CompletePtr <<

"\n"

;

678

DeclAnalysis.dump(S, llvm::dbgs()););

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()) {

694

CallableInfo Callee(*

Call

.Callee);

695

followCall(Caller, *Pending, Callee,

Call

.CallLoc,

698

completeAnalysis(Caller, std::move(*Pending));

704 void

followCall(

const

CallableInfo &Caller, PendingFunctionAnalysis &PFA,

706 bool

AssertNoFurtherInference, ViolationSite VSite) {

707 const bool

DirectCall = Callee.isCalledDirectly();

712 bool

IsInferencePossible = DirectCall;

715 if

(CompleteFunctionAnalysis *CFA =

716

DeclAnalysis.completedAnalysisForDecl(Callee.CDecl)) {

718

CalleeEffects.

insert

(CFA->VerifiedEffects);

719

IsInferencePossible =

false

;

722 if

(AssertNoFurtherInference) {

723

assert(!IsInferencePossible);

726 if

(!Callee.isVerifiable())

727

IsInferencePossible =

false

;

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"

;);

743 if

(!IsInferencePossible ||

745 if

(Callee.FuncType == SpecialFuncType::None)

746

PFA.checkAddViolation(Inferring,

747

{Effect, ViolationID::CallsDeclWithoutEffect,

748

VSite, CallLoc, Callee.CDecl});

750

PFA.checkAddViolation(

752

{Effect, ViolationID::AllocatesMemory, VSite, CallLoc});

755

PFA.addUnverifiedDirectCall(Callee.CDecl, CallLoc, VSite);

760

Check1Effect(Effect,

false

);

763

Check1Effect(Effect,

true

);

769 enum

CallableDeclKind {

775

CDK_MemberInitializer,

781 static

CallableDeclKind GetCallableDeclKind(

const Decl

*

D

,

782 const

Violation *

V

) {

784 V

->Site.kind() == ViolationSite::Kind::MemberInitializer)

785 return

CDK_MemberInitializer;

786 if

(isa<BlockDecl>(

D

))

788 if

(

auto

*Method = dyn_cast<CXXMethodDecl>(

D

)) {

789 if

(isa<CXXConstructorDecl>(

D

))

790 return

CDK_Constructor;

791 if

(isa<CXXDestructorDecl>(

D

))

792 return

CDK_Destructor;

806 auto

MaybeAddTemplateNote = [&](

const Decl

*

D

) {

811

diag::note_func_effect_from_template);

818 enum

{ Indirect_VirtualMethod, Indirect_FunctionPtr };

820 auto

MaybeAddSiteContext = [&](

const Decl

*

D

,

const

Violation &

V

) {

823 if

(

V

.Site.kind() == ViolationSite::Kind::MemberInitializer) {

824 unsigned

ImplicitCtor = 0;

825 if

(

auto

*Ctor = dyn_cast<CXXConstructorDecl>(

D

);

826

Ctor && Ctor->isImplicit())

834 else if

(

V

.Site.kind() == ViolationSite::Kind::DefaultArgExpr)

835

S.

Diag

(

V

.Site.defaultArgExpr()->getUsedLocation(),

836

diag::note_in_evaluating_default_argument);

840 for

(

const

Violation &Viol1 : Viols) {

841

StringRef effectName = Viol1.Effect.name();

843 case

ViolationID::None:

844 case

ViolationID::DeclDisallowsInference:

846

llvm_unreachable(

"Unexpected violation kind"

);

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);

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);

866 case

ViolationID::CallsDeclWithoutEffect: {

867

CallableInfo CalleeInfo(*Viol1.Callee);

868

std::string CalleeName = CalleeInfo.getNameForDiagnostic(S);

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);

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

) {

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

902 else if

(

const FunctionDecl

*FD = dyn_cast<FunctionDecl>(Callee);

906

S.

Diag

(Callee->getLocation(), diag::note_func_effect_call_extern)

911 const

Violation *PtrViol2 =

912

Completed->firstViolationForEffect(Viol1.Effect);

913 if

(PtrViol2 ==

nullptr

)

916 const

Violation &Viol2 = *PtrViol2;

918 case

ViolationID::None:

919

llvm_unreachable(

"Unexpected violation kind"

);

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();

926 case

ViolationID::CallsExprWithoutEffect:

927

S.

Diag

(Viol2.Loc, diag::note_func_effect_call_indirect)

928

<< Indirect_FunctionPtr << effectName;

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);

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);

948

MaybeAddTemplateNote(Callee);

949

Callee = Viol2.Callee;

950 if

(MaybeNextCallee) {

951

CalleeInfo = *MaybeNextCallee;

952

CalleeName = CalleeInfo.getNameForDiagnostic(S);

970

PendingFunctionAnalysis &CurrentFunction;

971

CallableInfo &CurrentCaller;

973 const Expr

*TrailingRequiresClause =

nullptr

;

974 const Expr

*NoexceptExpr =

nullptr

;

976

FunctionBodyASTVisitor(Analyzer &Outer,

977

PendingFunctionAnalysis &CurrentFunction,

978

CallableInfo &CurrentCaller)

979

: Outer(Outer), CurrentFunction(CurrentFunction),

980

CurrentCaller(CurrentCaller) {

981

ShouldVisitImplicitCode =

true

;

982

ShouldWalkTypesOfTypeLocs =

false

;

989 if

(

auto

*Dtor = dyn_cast<CXXDestructorDecl>(CurrentCaller.CDecl))

990

followDestructor(dyn_cast<CXXRecordDecl>(Dtor->getParent()), Dtor);

992 if

(

auto

*FD = dyn_cast<FunctionDecl>(CurrentCaller.CDecl)) {

1004

NoexceptExpr = FPT->getNoexceptExpr();

1009

TraverseDecl(

const_cast<Decl

*

>

(CurrentCaller.CDecl));

1019 const Decl

*Callee =

nullptr

) {

1022 for

(

FunctionEffect

Effect : CurrentFunction.DeclaredVerifiableEffects) {

1023 if

(Effect.

flags

() & Flag) {

1024

addViolation(

false

, Effect, VID,

Loc

, Callee);

1031 if

(Effect.

flags

() & Flag)

1032

addViolation(

true

, Effect, VID,

Loc

, Callee);

1035 void

addViolation(

bool

Inferring,

FunctionEffect

Effect, ViolationID VID,

1037

CurrentFunction.checkAddViolation(

1038

Inferring, Violation(Effect, VID, VSite,

Loc

, Callee));

1046 if

(

const auto

*FD = dyn_cast<FunctionDecl>(CI.CDecl)) {

1048

CI.Effects = getBuiltinFunctionEffects(BuiltinID);

1049 if

(CI.Effects.empty()) {

1061

(!Outer.S.getLangOpts().CPlusPlus ||

isNoexcept

(FD)))

1066

Outer.followCall(CurrentCaller, CurrentFunction, CI, CallLoc,

1074

CalleeEffects.

insert

(Effects);

1076 auto

Check1Effect = [&](

FunctionEffect

Effect,

bool

Inferring) {

1078 false

, CalleeEffects))

1079

addViolation(Inferring, Effect, ViolationID::CallsExprWithoutEffect,

1080 Call

->getBeginLoc());

1083 for

(

FunctionEffect

Effect : CurrentFunction.DeclaredVerifiableEffects)

1084

Check1Effect(Effect,

false

);

1087

Check1Effect(Effect,

true

);

1096

followTypeDtor(Field->getType(), DtorLoc);

1098 if

(

const auto

*

Class

= dyn_cast<CXXRecordDecl>(Rec))

1100

followTypeDtor(

Base

.getType(), DtorLoc);

1115

CallableInfo CI(*Dtor);

1116

followCall(CI, CallSite);

1124 bool

VisitCXXThrowExpr(

CXXThrowExpr

*Throw)

override

{

1126

ViolationID::ThrowsOrCatchesExceptions,

1131 bool

VisitCXXCatchStmt(

CXXCatchStmt

*Catch)

override

{

1133

ViolationID::ThrowsOrCatchesExceptions,

1140

ViolationID::ThrowsOrCatchesExceptions,

1147

ViolationID::ThrowsOrCatchesExceptions,

1154

ViolationID::ThrowsOrCatchesExceptions,

1161

ViolationID::AccessesObjCMethodOrProperty,

1171

ViolationID::AccessesObjCMethodOrProperty,

1181

ViolationID::AccessesObjCMethodOrProperty,

1188

ViolationID::ThrowsOrCatchesExceptions,

1194

LLVM_DEBUG(llvm::dbgs()

1195

<<

"VisitCallExpr : " 1196

<<

Call

->getBeginLoc().printToString(Outer.S.SourceMgr)

1199 Expr

*CalleeExpr =

Call

->getCallee();

1201

CallableInfo CI(*Callee);

1202

followCall(CI,

Call

->getBeginLoc());

1206 if

(isa<CXXPseudoDestructorExpr>(CalleeExpr)) {

1212

checkIndirectCall(

Call

, CalleeExpr->

getType

());

1217 bool

VisitVarDecl(

VarDecl

*Var)

override

{

1218

LLVM_DEBUG(llvm::dbgs()

1219

<<

"VisitVarDecl : " 1225

ViolationID::HasStaticLocalVariable,

1235 bool

VisitCXXNewExpr(

CXXNewExpr

*New)

override

{

1238

CallableInfo CI(*FD, SpecialFuncType::OperatorNew);

1254

CallableInfo CI(*FD, SpecialFuncType::OperatorDelete);

1255

followCall(CI,

Delete

->getBeginLoc());

1264

LLVM_DEBUG(llvm::dbgs() <<

"VisitCXXConstructExpr : " 1272

CallableInfo CI(*Ctor);

1278 bool

TraverseStmt(

Stmt

*Statement)

override

{

1284 if

(Statement != TrailingRequiresClause && Statement != NoexceptExpr)

1290

ViolationSite PrevVS = VSite;

1291 if

(

Init

->isAnyMemberInitializer())

1292

VSite.setKind(ViolationSite::Kind::MemberInitializer);

1300

LLVM_DEBUG(llvm::dbgs()

1301

<<

"TraverseCXXDefaultArgExpr : " 1302

<<

E

->getUsedLocation().printToString(Outer.S.SourceMgr)

1305

ViolationSite PrevVS = VSite;

1306 if

(VSite.kind() == ViolationSite::Kind::Default)

1307

VSite = ViolationSite{

E

};

1309 bool

Result = DynamicRecursiveASTVisitor::TraverseCXXDefaultArgExpr(

E

);

1314 bool

TraverseLambdaExpr(

LambdaExpr

*Lambda)

override

{

1320 for

(

unsigned

I = 0, N = Lambda->

capture_size

(); I < N; ++I)

1321

TraverseLambdaCapture(Lambda, Lambda->

capture_begin

() + I,

1327 bool

TraverseBlockExpr(

BlockExpr

*

)

override

{

1335 if

(

const auto

*Var = dyn_cast<VarDecl>(Val)) {

1340

ViolationID::AccessesThreadLocalVariable,

1348 return

TraverseStmt(

Node

->getResultExpr());

1374

Analyzer::AnalysisMap::~AnalysisMap() {

1375 for

(

const auto

&Item : *

this

) {

1376

FuncAnalysisPtr AP = Item.second;

1377 if

(

auto

*PFA = dyn_cast<PendingFunctionAnalysis *>(AP))

1380 delete

cast<CompleteFunctionAnalysis *>(AP);

1398 Diag

(NewAttrLoc, diag::err_attributes_are_not_compatible)

1400

<< (

"'"

+ PrevEC.description() +

"'"

) <<

false

;

1411 if

(PrevEC.Cond.getCondition() !=

nullptr

)

1417 if

(PrevEC.Effect.oppositeKind() == NewKind)

1438 Diag

(NewLoc, diag::warn_conflicting_func_effects)

1439

<< Conflict.Kept.description() << Conflict.Rejected.description();

1440 Diag

(OldLoc, diag::note_previous_declaration);

1463 if

(cast<DeclContext>(

D

)->isDependentContext())

1474 bool

AnyVerifiable =

false

;

1478

AnyVerifiable =

true

;

1491

Analyzer{*

this

}.run(*TU);

1504 if

(POld == OldEnd) {

1508

}

else if

(PNew == NewEnd)

1536

}

else if

(cmp > 0) {

1541

std::nullopt, New});

1554 switch

(EffectKind) {

1558 if

(DiffKind == Kind::Added) {

1559 for

(

const auto

&CFE : SrcFX) {

1572 case

Kind::ConditionMismatch:

1584

llvm_unreachable(

"unknown effect kind"

);

1590 switch

(EffectKind) {

1599 case

Kind::ConditionMismatch:

1608

llvm_unreachable(

"unknown effect kind"

);

1615 switch

(EffectKind) {

1622 return

OverrideResult::NoAction;

1626 return

OverrideResult::Merge;

1630 case

Kind::ConditionMismatch:

1631 return

OverrideResult::Warn;

1636 return

OverrideResult::NoAction;

1638

llvm_unreachable(

"unknown effect kind"

);

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 isExternC(const NamedDecl *ND)

static void emitDiagnostics(BoundNodes &Match, const Decl *D, BugReporter &BR, AnalysisManager &AM, const ObjCAutoreleaseWriteChecker *Checker)

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 ...

Represents an array type, per C99 6.7.5.2 - Array Declarators.

QualType getElementType() const

BlockExpr - Adaptor class for mixing a BlockDecl with expressions.

Represents a base class of a C++ class.

CXXCatchStmt - This represents a C++ catch block.

SourceLocation getCatchLoc() const

Represents a call to a C++ constructor.

SourceLocation getLocation() const

SourceLocation getBeginLoc() const LLVM_READONLY

CXXConstructorDecl * getConstructor() const

Get the constructor that this expression will (ultimately) call.

Represents a C++ constructor within a class.

Represents a C++ base or member initializer.

A default argument (C++ [dcl.fct.default]).

Represents a delete expression for memory deallocation and destructor calls, e.g.

Represents a C++ destructor within a class.

Represents a static or instance method of a struct/union/class.

Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".

SourceLocation getBeginLoc() const

FunctionDecl * getOperatorNew() const

Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).

Represents a C++ struct/union/class.

bool isLambda() const

Determine whether this class describes a lambda function object.

A C++ throw-expression (C++ [except.throw]).

SourceLocation getThrowLoc() const

A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

DeclContext * getParent()

getParent - Returns the containing DeclContext.

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.

Decl - This represents one declaration (or definition), e.g.

FunctionDecl * getAsFunction() LLVM_READONLY

Returns the function itself, or the templated function if this is a function template.

virtual bool hasBody() const

Returns true if this Decl represents a declaration for a body of code, such as a function or method d...

SourceLocation getLocation() const

SourceLocation getBeginLoc() const LLVM_READONLY

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

SourceLocation getBeginLoc() const LLVM_READONLY

Expr * getTrailingRequiresClause()

Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...

TypeSourceInfo * getTypeSourceInfo() const

bool getIgnoreAllWarnings() const

bool getSuppressSystemWarnings() const

Recursive AST visitor that supports extension via dynamic dispatch.

virtual bool TraverseConstructorInitializer(MaybeConst< CXXCtorInitializer > *Init)

Recursively visit a constructor initializer.

virtual bool TraverseStmt(MaybeConst< Stmt > *S)

Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...

Expr * getCondition() const

This represents one expression.

Decl * getReferencedDeclOfCallee()

Represents a member of a struct/union/class.

Represents a function declaration or definition.

unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const

Returns a value indicating whether this function corresponds to a builtin function.

SourceLocation getPointOfInstantiation() const

Retrieve the (first) point of instantiation of a function template specialization or a member of a cl...

bool isNoReturn() const

Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...

FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const

Retrieve the function declaration from which this function could be instantiated, if it is an instant...

bool isTrivial() const

Whether this function is "trivial" in some specialized C++ senses.

FunctionDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

bool isDeleted() const

Whether this function has been deleted.

FunctionEffectsRef getFunctionEffects() const

bool isTemplateInstantiation() const

Determines if the given function was instantiated from a function template.

FunctionDecl * getDefinition()

Get the definition for this declaration.

bool hasBody(const FunctionDecl *&Definition) const

Returns true if the function has a body.

void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const override

Appends a human-readable name for this declaration into the given stream.

bool willHaveBody() const

True if this function will eventually have a body, once it's fully parsed.

Support iteration in parallel through a pair of FunctionEffect and EffectConditionExpr containers.

A mutable set of FunctionEffect::Kind.

static FunctionEffectKindSet difference(FunctionEffectKindSet LHS, FunctionEffectKindSet RHS)

void dump(llvm::raw_ostream &OS) const

void insert(FunctionEffect Effect)

Represents an abstract function effect, using just an enumeration describing its kind.

Kind kind() const

The kind of the effect.

@ FE_ExcludeStaticLocalVars

@ FE_ExcludeThreadLocalVars

@ FE_ExcludeObjCMessageSend

Kind

Identifies the particular effect.

Flags flags() const

Flags describing some behaviors of the effect.

bool shouldDiagnoseFunctionCall(bool Direct, FunctionEffectKindSet CalleeFX) const

StringRef name() const

The description printed in diagnostics, e.g. 'nonblocking'.

An immutable set of FunctionEffects and possibly conditions attached to them.

static FunctionEffectsRef get(QualType QT)

Extract the effects from a Type if it is a function, block, or member function pointer,...

Represents a prototype with parameter type info, e.g.

bool isNothrow(bool ResultIfDependent=false) const

Determine whether this function type has a non-throwing exception specification.

Represents a C11 generic selection.

A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...

capture_iterator capture_begin() const

Retrieve an iterator pointing to the first lambda capture.

unsigned capture_size() const

Determine the number of captures in this lambda.

capture_init_iterator capture_init_begin()

Retrieve the first initialization argument for this lambda expression (which initializes the first ca...

Represents Objective-C's @catch statement.

SourceLocation getAtCatchLoc() const

Represents Objective-C's @finally statement.

SourceLocation getAtFinallyLoc() const

Represents Objective-C's @synchronized statement.

SourceLocation getBeginLoc() const LLVM_READONLY

Represents Objective-C's @throw statement.

SourceLocation getThrowLoc() const LLVM_READONLY

Represents Objective-C's @autoreleasepool Statement.

SourceLocation getBeginLoc() const LLVM_READONLY

An expression that sends a message to the given Objective-C object or class.

SourceLocation getBeginLoc() const LLVM_READONLY

A (possibly-)qualified type.

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

field_range fields() const

SourceLocation getExceptLoc() const

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)

Emit a diagnostic.

Sema - This implements semantic analysis and AST building for C.

void addDeclWithEffects(const Decl *D, const FunctionEffectsRef &FX)

Unconditionally add a Decl to DeclsWithEfffectsToVerify.

FunctionEffectKindSet AllEffectsToVerify

The union of all effects present on DeclsWithEffectsToVerify.

ASTContext & getASTContext() const

SmallVector< const Decl * > DeclsWithEffectsToVerify

All functions/lambdas/blocks which have bodies and which have a non-empty FunctionEffectsRef to be ve...

PrintingPolicy getPrintingPolicy() const

Retrieve a suitable printing policy for diagnostics.

const LangOptions & getLangOpts() const

void maybeAddDeclWithEffects(FuncOrBlockDecl *D)

Inline checks from the start of maybeAddDeclWithEffects, to minimize performance impact on code not u...

void performFunctionEffectAnalysis(TranslationUnitDecl *TU)

@ Incompatible

Incompatible - We reject this conversion outright, it is invalid to represent it in the AST.

SourceManager & getSourceManager() const

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.

SourceManager & SourceMgr

DiagnosticsEngine & Diags

Encodes a location in the source.

std::string printToString(const SourceManager &SM) const

bool isValid() const

Return true if this is a valid SourceLocation object.

This class handles loading and caching of source files into memory.

bool isInSystemHeader(SourceLocation Loc) const

Returns if a SourceLocation is in a system header.

Stmt - This represents one statement.

The top declaration context.

T getAs() const

Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...

A container of type source information.

The base class of the type hierarchy.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

const ArrayType * getAsArrayTypeUnsafe() const

A variant of getAs<> for array types which silently discards qualifiers from the outermost type.

const T * getAs() const

Member-template getAs<specific type>'.

bool isRecordType() const

UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

TLSKind getTLSKind() const

bool isStaticLocal() const

Returns true if a variable with function scope is a static local variable.

QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const

Would the destruction of this variable have any effect, and if so, what kind?

@ TLS_None

Not a TLS variable.

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.

@ Delete

'delete' clause, allowed on the 'exit data' construct.

@ None

The alignment was not explicit in code.

@ Class

The "class" keyword introduces the elaborated-type-specifier.

A FunctionEffect plus a potential boolean expression determining whether the effect is declared (e....

std::string description() const

Return a textual description of the effect, and its condition, if any.

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...


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4