A RetroSearch Logo

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

Search Query:

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

clang: lib/Sema/SemaChecking.cpp Source File

77#include "llvm/ADT/APFloat.h" 78#include "llvm/ADT/APInt.h" 79#include "llvm/ADT/APSInt.h" 80#include "llvm/ADT/ArrayRef.h" 81#include "llvm/ADT/DenseMap.h" 82#include "llvm/ADT/FoldingSet.h" 83#include "llvm/ADT/STLExtras.h" 84#include "llvm/ADT/SmallBitVector.h" 85#include "llvm/ADT/SmallPtrSet.h" 86#include "llvm/ADT/SmallString.h" 87#include "llvm/ADT/SmallVector.h" 88#include "llvm/ADT/StringExtras.h" 89#include "llvm/ADT/StringRef.h" 90#include "llvm/ADT/StringSet.h" 91#include "llvm/ADT/StringSwitch.h" 92#include "llvm/Support/AtomicOrdering.h" 93#include "llvm/Support/Compiler.h" 94#include "llvm/Support/ConvertUTF.h" 95#include "llvm/Support/ErrorHandling.h" 96#include "llvm/Support/Format.h" 97#include "llvm/Support/Locale.h" 98#include "llvm/Support/MathExtras.h" 99#include "llvm/Support/SaveAndRestore.h" 100#include "llvm/Support/raw_ostream.h" 101#include "llvm/TargetParser/RISCVTargetParser.h" 102#include "llvm/TargetParser/Triple.h" 115using namespace clang

;

119 unsigned

ByteNo)

const

{

130 unsigned

ArgCount =

Call

->getNumArgs();

131 if

(ArgCount >= MinArgCount)

134 return Diag

(

Call

->getEndLoc(), diag::err_typecheck_call_too_few_args)

135

<< 0

<< MinArgCount << ArgCount

136

<<

0 <<

Call

->getSourceRange();

140 unsigned

ArgCount =

Call

->getNumArgs();

141 if

(ArgCount <= MaxArgCount)

143 return Diag

(

Call

->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)

144

<< 0

<< MaxArgCount << ArgCount

145

<<

0 <<

Call

->getSourceRange();

149 unsigned

MaxArgCount) {

155 unsigned

ArgCount =

Call

->getNumArgs();

156 if

(ArgCount == DesiredArgCount)

161

assert(ArgCount > DesiredArgCount &&

"should have diagnosed this"

);

165 Call

->getArg(ArgCount - 1)->getEndLoc());

168

<< 0

<< DesiredArgCount << ArgCount

169

<<

0 <<

Call

->getArg(1)->getSourceRange();

173 bool

HasError =

false

;

175 for

(

unsigned

I = 0; I <

Call

->getNumArgs(); ++I) {

182 int

DiagMsgKind = -1;

184 if

(!ArgString.has_value())

186 else if

(ArgString->find(

'$'

) != std::string::npos)

189 if

(DiagMsgKind >= 0) {

200 if

(

Value

->isTypeDependent())

223

S.

Diag

(ValArg->

getBeginLoc

(), diag::err_builtin_annotation_first_arg)

231 if

(!Literal || !Literal->isOrdinary()) {

232

S.

Diag

(StrArg->

getBeginLoc

(), diag::err_builtin_annotation_second_arg)

244

S.

Diag

(TheCall->

getEndLoc

(), diag::err_typecheck_call_too_few_args_at_least)

252 auto

*Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());

253 if

(!Literal || !Literal->isWide()) {

254

S.

Diag

(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)

255

<< Arg->getSourceRange();

271 if

(ResultType.

isNull

())

275

TheCall->

setType

(ResultType);

289 const FunctionDecl

*FD = dyn_cast_or_null<FunctionDecl>(

293

S.

Diag

(TheCall->

getBeginLoc

(), diag::err_function_start_invalid_type)

320 bool

IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;

322 auto

IsValidIntegerType = [](

QualType

Ty) {

323 return

Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();

330 if

((!SrcTy->

isPointerType

() && !IsValidIntegerType(SrcTy)) ||

334

S.

Diag

(Source->

getExprLoc

(), diag::err_typecheck_expect_scalar_operand)

340 if

(!IsValidIntegerType(AlignOp->

getType

())) {

351

llvm::APSInt AlignValue = AlignResult.

Val

.

getInt

();

352

llvm::APSInt MaxValue(

353

llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));

354 if

(AlignValue < 1) {

355

S.

Diag

(AlignOp->

getExprLoc

(), diag::err_alignment_too_small) << 1;

358 if

(llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {

363 if

(!AlignValue.isPowerOf2()) {

364

S.

Diag

(AlignOp->

getExprLoc

(), diag::err_alignment_not_power_of_two);

367 if

(AlignValue == 1) {

368

S.

Diag

(AlignOp->

getExprLoc

(), diag::warn_alignment_builtin_useless)

369

<< IsBooleanAlignBuiltin;

397

std::pair<unsigned, const char *> Builtins[] = {

398

{ Builtin::BI__builtin_add_overflow,

"ckd_add"

},

399

{ Builtin::BI__builtin_sub_overflow,

"ckd_sub"

},

400

{ Builtin::BI__builtin_mul_overflow,

"ckd_mul"

},

403 bool

CkdOperation = llvm::any_of(Builtins, [&](

const

std::pair<

unsigned

,

404 const char

*> &

P

) {

405 return

BuiltinID ==

P

.first && TheCall->

getExprLoc

().isMacroID() &&

410 auto

ValidCkdIntType = [](

QualType

QT) {

413 if

(

const auto

*BT = QT.getCanonicalType()->getAs<

BuiltinType

>())

414 return

(BT->getKind() >= BuiltinType::Short &&

415

BT->getKind() <= BuiltinType::Int128) || (

416

BT->getKind() >= BuiltinType::UShort &&

417

BT->getKind() <= BuiltinType::UInt128) ||

418

BT->getKind() == BuiltinType::UChar ||

419

BT->getKind() == BuiltinType::SChar;

424 for

(

unsigned

I = 0; I < 2; ++I) {

430 bool

IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->

isIntegerType

();

449

!PtrTy->getPointeeType()->isIntegerType() ||

450

(!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||

451

PtrTy->getPointeeType().isConstQualified()) {

453

diag::err_overflow_builtin_must_be_ptr_int)

461 if

(BuiltinID == Builtin::BI__builtin_mul_overflow) {

462 for

(

unsigned

I = 0; I < 3; ++I) {

463 const auto

Arg = TheCall->

getArg

(I);

466 if

(Ty->isBitIntType() && Ty->isSignedIntegerType() &&

468 return

S.

Diag

(Arg->getBeginLoc(),

469

diag::err_overflow_builtin_bit_int_max_size)

478struct

BuiltinDumpStructGenerator {

487

: S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),

488

Policy(S.Context.getPrintingPolicy()) {

492 Expr

*makeOpaqueValueExpr(

Expr

*Inner) {

495

Inner->getObjectKind(), Inner);

496

Actions.push_back(OVE);

500 Expr

*getStringLiteral(llvm::StringRef Str) {

506 bool

callPrintFunction(llvm::StringRef Format,

510

Args.reserve((TheCall->

getNumArgs

() - 2) +

1 + Exprs.size());

512

Args.push_back(getStringLiteral(Format));

513

Args.insert(Args.end(), Exprs.begin(), Exprs.end());

518

Ctx.PointOfInstantiation =

Loc

;

519

Ctx.CallArgs = Args.data();

520

Ctx.NumCallArgs = Args.size();

529

Actions.push_back(RealCall.

get

());

535 Expr

*getIndentString(

unsigned

Depth) {

541 return

getStringLiteral(Indent);

545 return

getStringLiteral(

T

.getAsString(Policy));

549

llvm::raw_svector_ostream OS(Str);

554 switch

(BT->getKind()) {

555 case

BuiltinType::Bool:

558 case

BuiltinType::Char_U:

559 case

BuiltinType::UChar:

562 case

BuiltinType::Char_S:

563 case

BuiltinType::SChar:

575

analyze_printf::PrintfConversionSpecifier::sArg) {

601 bool

dumpUnnamedRecord(

const RecordDecl

*RD,

Expr

*

E

,

unsigned

Depth) {

602 Expr

*IndentLit = getIndentString(Depth);

604 if

(IndentLit ? callPrintFunction(

"%s%s"

, {IndentLit, TypeLit})

605

: callPrintFunction(

"%s"

, {TypeLit}))

608 return

dumpRecordValue(RD,

E

, IndentLit, Depth);

621 Expr

*RecordArg = makeOpaqueValueExpr(

E

);

624 if

(callPrintFunction(

" {\n"

))

628 if

(

const auto

*CXXRD = dyn_cast<CXXRecordDecl>(RD)) {

629 for

(

const auto

&

Base

: CXXRD->bases()) {

637

dumpUnnamedRecord(

Base

.getType()->getAsRecordDecl(), BasePtr.

get

(),

643 Expr

*FieldIndentArg = getIndentString(Depth + 1);

646 for

(

auto

*

D

: RD->

decls

()) {

647 auto

*IFD = dyn_cast<IndirectFieldDecl>(

D

);

648 auto

*FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(

D

);

649 if

(!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())

655

getStringLiteral(FD->getName())};

657 if

(FD->isBitField()) {

661

FD->getBitWidthValue());

675 if

(

Field

.isInvalid())

678 auto

*InnerRD = FD->getType()->getAsRecordDecl();

679 auto

*InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);

680 if

(InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {

682 if

(callPrintFunction(Format, Args) ||

683

dumpRecordValue(InnerRD,

Field

.get(), FieldIndentArg, Depth + 1))

687 if

(appendFormatSpecifier(FD->getType(), Format)) {

689

Args.push_back(

Field

.get());

699

Args.push_back(FieldAddr.

get

());

702 if

(callPrintFunction(Format, Args))

707 return

RecordIndent ? callPrintFunction(

"%s}\n"

, RecordIndent)

708

: callPrintFunction(

"}\n"

);

711 Expr

*buildWrapper() {

714

TheCall->

setType

(Wrapper->getType());

728

TheCall->

setArg

(0, PtrArgResult.

get

());

735

diag::err_expected_struct_pointer_argument)

744

diag::err_incomplete_type))

753 switch

(BT ? BT->getKind() : BuiltinType::Void) {

754 case

BuiltinType::Dependent:

755 case

BuiltinType::Overload:

756 case

BuiltinType::BoundMember:

757 case

BuiltinType::PseudoObject:

758 case

BuiltinType::UnknownAny:

759 case

BuiltinType::BuiltinFn:

765

diag::err_expected_callable_argument)

771

BuiltinDumpStructGenerator Generator(S, TheCall);

777 Expr

*PtrArg = PtrArgResult.

get

();

781 if

(Generator.dumpUnnamedRecord(RD, PtrArg, 0))

784 return

Generator.buildWrapper();

796 if

(

Call

->getStmtClass() != Stmt::CallExprClass) {

797

S.

Diag

(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)

798

<<

Call

->getSourceRange();

802 auto

CE = cast<CallExpr>(

Call

);

803 if

(CE->getCallee()->getType()->isBlockPointerType()) {

804

S.

Diag

(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)

805

<<

Call

->getSourceRange();

809 const Decl

*TargetDecl = CE->getCalleeDecl();

810 if

(

const FunctionDecl

*FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))

811 if

(FD->getBuiltinID()) {

812

S.

Diag

(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)

813

<<

Call

->getSourceRange();

817 if

(isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {

818

S.

Diag

(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)

819

<<

Call

->getSourceRange();

827

S.

Diag

(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)

841

BuiltinCall->

setType

(CE->getType());

845

BuiltinCall->

setArg

(1, ChainResult.

get

());

852class

ScanfDiagnosticFormatHandler

856 using

ComputeSizeFunction =

857

llvm::function_ref<std::optional<llvm::APSInt>(

unsigned

)>;

861 using

DiagnoseFunction =

862

llvm::function_ref<void(

unsigned

,

unsigned

,

unsigned

)>;

864

ComputeSizeFunction ComputeSizeArgument;

865

DiagnoseFunction Diagnose;

868

ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,

869

DiagnoseFunction Diagnose)

870

: ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}

873 const char

*StartSpecifier,

874 unsigned

specifierLen)

override

{

875 if

(!FS.consumesDataArgument())

878 unsigned

NulByte = 0;

879 switch

((FS.getConversionSpecifier().getKind())) {

892

analyze_format_string::OptionalAmount::HowSpecified::Constant)

897

std::optional<llvm::APSInt> DestSizeAPS =

898

ComputeSizeArgument(FS.getArgIndex());

902 unsigned

DestSize = DestSizeAPS->getZExtValue();

904 if

(DestSize < SourceSize)

905

Diagnose(FS.getArgIndex(), DestSize, SourceSize);

911class

EstimateSizeFormatHandler

916 bool

IsKernelCompatible =

true

;

919

EstimateSizeFormatHandler(StringRef Format)

920

:

Size

(

std

::

min

(Format.find(0), Format.size()) +

924 const char

*,

unsigned

SpecifierLen,

927 const size_t

FieldWidth = computeFieldWidth(FS);

928 const size_t

Precision = computePrecision(FS);

931 switch

(FS.getConversionSpecifier().getKind()) {

935 Size

+= std::max(FieldWidth, (

size_t

)1);

947 Size

+= std::max(FieldWidth, Precision);

963 Size

+= std::max(FieldWidth, 1

+

964

(Precision ? 1 + Precision

974

(Precision ? 1 + Precision : 0)

+

984

(Precision ? 1 + Precision : 0)

+

999

IsKernelCompatible =

false

;

1000 Size

+= std::max(FieldWidth, 2

+ Precision);

1012 Size

+= FS.hasPlusPrefix() || FS.hasSpacePrefix();

1014 if

(FS.hasAlternativeForm()) {

1015 switch

(FS.getConversionSpecifier().getKind()) {

1044 Size

+= (Precision ? 0 : 1);

1051

assert(SpecifierLen <= Size &&

"no underflow"

);

1052 Size

-= SpecifierLen;

1056 size_t

getSizeLowerBound()

const

{

return Size

; }

1057 bool

isKernelCompatible()

const

{

return

IsKernelCompatible; }

1062 size_t

FieldWidth = 0;

1070 size_t

Precision = 0;

1075 switch

(FS.getConversionSpecifier().getKind()) {

1117

StringRef &FormatStrRef,

size_t

&StrLen,

1119 if

(

const auto

*Format = dyn_cast<StringLiteral>(FormatExpr);

1120

Format && (Format->isOrdinary() || Format->isUTF8())) {

1121

FormatStrRef = Format->getString();

1124

assert(

T

&&

"String literal not of constant array type!"

);

1125 size_t

TypeSize =

T

->getZExtSize();

1127

StrLen = std::min(std::max(TypeSize,

size_t

(1)) - 1, FormatStrRef.find(0));

1133void

Sema::checkFortifiedBuiltinMemoryFunction(

FunctionDecl

*FD,

1139 bool

UseDABAttr =

false

;

1142 const auto

*DABAttr = FD->

getAttr

<DiagnoseAsBuiltinAttr>();

1144

UseDecl = DABAttr->getFunction();

1145

assert(UseDecl &&

"Missing FunctionDecl in DiagnoseAsBuiltin attribute!"

);

1157 auto

TranslateIndex = [&](

unsigned

Index) -> std::optional<unsigned> {

1164 unsigned

DABIndices = DABAttr->argIndices_size();

1165 unsigned

NewIndex = Index < DABIndices

1166

? DABAttr->argIndices_begin()[Index]

1169 return

std::nullopt;

1173 auto

ComputeExplicitObjectSizeArgument =

1174

[&](

unsigned

Index) -> std::optional<llvm::APSInt> {

1175

std::optional<unsigned> IndexOptional = TranslateIndex(Index);

1177 return

std::nullopt;

1178 unsigned

NewIndex = *IndexOptional;

1182 return

std::nullopt;

1184 Integer

.setIsUnsigned(

true

);

1188 auto

ComputeSizeArgument =

1189

[&](

unsigned

Index) -> std::optional<llvm::APSInt> {

1195 if

(Index < FD->getNumParams()) {

1196 if

(

const auto

*POS =

1198

BOSType = POS->getType();

1201

std::optional<unsigned> IndexOptional = TranslateIndex(Index);

1203 return

std::nullopt;

1204 unsigned

NewIndex = *IndexOptional;

1207 return

std::nullopt;

1209 const Expr

*ObjArg = TheCall->

getArg

(NewIndex);

1212 return

std::nullopt;

1215 return

llvm::APSInt::getUnsigned(

Result

).extOrTrunc(SizeTypeWidth);

1218 auto

ComputeStrLenArgument =

1219

[&](

unsigned

Index) -> std::optional<llvm::APSInt> {

1220

std::optional<unsigned> IndexOptional = TranslateIndex(Index);

1222 return

std::nullopt;

1223 unsigned

NewIndex = *IndexOptional;

1225 const Expr

*ObjArg = TheCall->

getArg

(NewIndex);

1228 return

std::nullopt;

1230 return

llvm::APSInt::getUnsigned(

Result

+ 1).extOrTrunc(SizeTypeWidth);

1233

std::optional<llvm::APSInt> SourceSize;

1234

std::optional<llvm::APSInt> DestinationSize;

1235 unsigned

DiagID = 0;

1236 bool

IsChkVariant =

false

;

1238 auto

GetFunctionName = [&]() {

1244

FunctionName = FunctionName.drop_front(std::strlen(

"__builtin___"

));

1245

FunctionName = FunctionName.drop_back(std::strlen(

"_chk"

));

1247

FunctionName.consume_front(

"__builtin_"

);

1249 return

FunctionName;

1252 switch

(BuiltinID) {

1255 case

Builtin::BI__builtin_strcpy:

1256 case

Builtin::BIstrcpy: {

1257

DiagID = diag::warn_fortify_strlen_overflow;

1258

SourceSize = ComputeStrLenArgument(1);

1259

DestinationSize = ComputeSizeArgument(0);

1263 case

Builtin::BI__builtin___strcpy_chk: {

1264

DiagID = diag::warn_fortify_strlen_overflow;

1265

SourceSize = ComputeStrLenArgument(1);

1266

DestinationSize = ComputeExplicitObjectSizeArgument(2);

1267

IsChkVariant =

true

;

1271 case

Builtin::BIscanf:

1272 case

Builtin::BIfscanf:

1273 case

Builtin::BIsscanf: {

1274 unsigned

FormatIndex = 1;

1275 unsigned

DataIndex = 2;

1276 if

(BuiltinID == Builtin::BIscanf) {

1281 const auto

*FormatExpr =

1284

StringRef FormatStrRef;

1289 auto Diagnose

= [&](

unsigned

ArgIndex,

unsigned

DestSize,

1290 unsigned

SourceSize) {

1291

DiagID = diag::warn_fortify_scanf_overflow;

1292 unsigned

Index = ArgIndex + DataIndex;

1293

StringRef FunctionName = GetFunctionName();

1295 PDiag

(DiagID) << FunctionName << (Index + 1)

1296

<< DestSize << SourceSize);

1299 auto

ShiftedComputeSizeArgument = [&](

unsigned

Index) {

1300 return

ComputeSizeArgument(Index + DataIndex);

1302

ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,

Diagnose

);

1303 const char

*FormatBytes = FormatStrRef.data();

1314 case

Builtin::BIsprintf:

1315 case

Builtin::BI__builtin___sprintf_chk: {

1316 size_t

FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;

1319

StringRef FormatStrRef;

1322

EstimateSizeFormatHandler H(FormatStrRef);

1323 const char

*FormatBytes = FormatStrRef.data();

1325

H, FormatBytes, FormatBytes + StrLen,

getLangOpts

(),

1327

DiagID = H.isKernelCompatible()

1328

? diag::warn_format_overflow

1329

: diag::warn_format_overflow_non_kprintf;

1330

SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())

1331

.extOrTrunc(SizeTypeWidth);

1332 if

(BuiltinID == Builtin::BI__builtin___sprintf_chk) {

1333

DestinationSize = ComputeExplicitObjectSizeArgument(2);

1334

IsChkVariant =

true

;

1336

DestinationSize = ComputeSizeArgument(0);

1343 case

Builtin::BI__builtin___memcpy_chk:

1344 case

Builtin::BI__builtin___memmove_chk:

1345 case

Builtin::BI__builtin___memset_chk:

1346 case

Builtin::BI__builtin___strlcat_chk:

1347 case

Builtin::BI__builtin___strlcpy_chk:

1348 case

Builtin::BI__builtin___strncat_chk:

1349 case

Builtin::BI__builtin___strncpy_chk:

1350 case

Builtin::BI__builtin___stpncpy_chk:

1351 case

Builtin::BI__builtin___memccpy_chk:

1352 case

Builtin::BI__builtin___mempcpy_chk: {

1353

DiagID = diag::warn_builtin_chk_overflow;

1354

SourceSize = ComputeExplicitObjectSizeArgument(TheCall->

getNumArgs

() - 2);

1356

ComputeExplicitObjectSizeArgument(TheCall->

getNumArgs

() - 1);

1357

IsChkVariant =

true

;

1361 case

Builtin::BI__builtin___snprintf_chk:

1362 case

Builtin::BI__builtin___vsnprintf_chk: {

1363

DiagID = diag::warn_builtin_chk_overflow;

1364

SourceSize = ComputeExplicitObjectSizeArgument(1);

1365

DestinationSize = ComputeExplicitObjectSizeArgument(3);

1366

IsChkVariant =

true

;

1370 case

Builtin::BIstrncat:

1371 case

Builtin::BI__builtin_strncat:

1372 case

Builtin::BIstrncpy:

1373 case

Builtin::BI__builtin_strncpy:

1374 case

Builtin::BIstpncpy:

1375 case

Builtin::BI__builtin_stpncpy: {

1381

DiagID = diag::warn_fortify_source_size_mismatch;

1382

SourceSize = ComputeExplicitObjectSizeArgument(TheCall->

getNumArgs

() - 1);

1383

DestinationSize = ComputeSizeArgument(0);

1387 case

Builtin::BImemcpy:

1388 case

Builtin::BI__builtin_memcpy:

1389 case

Builtin::BImemmove:

1390 case

Builtin::BI__builtin_memmove:

1391 case

Builtin::BImemset:

1392 case

Builtin::BI__builtin_memset:

1393 case

Builtin::BImempcpy:

1394 case

Builtin::BI__builtin_mempcpy: {

1395

DiagID = diag::warn_fortify_source_overflow;

1396

SourceSize = ComputeExplicitObjectSizeArgument(TheCall->

getNumArgs

() - 1);

1397

DestinationSize = ComputeSizeArgument(0);

1400 case

Builtin::BIsnprintf:

1401 case

Builtin::BI__builtin_snprintf:

1402 case

Builtin::BIvsnprintf:

1403 case

Builtin::BI__builtin_vsnprintf: {

1404

DiagID = diag::warn_fortify_source_size_mismatch;

1405

SourceSize = ComputeExplicitObjectSizeArgument(1);

1407

StringRef FormatStrRef;

1411

EstimateSizeFormatHandler H(FormatStrRef);

1412 const char

*FormatBytes = FormatStrRef.data();

1414

H, FormatBytes, FormatBytes + StrLen,

getLangOpts

(),

1416

llvm::APSInt FormatSize =

1417

llvm::APSInt::getUnsigned(H.getSizeLowerBound())

1418

.extOrTrunc(SizeTypeWidth);

1419 if

(FormatSize > *SourceSize && *SourceSize != 0) {

1420 unsigned

TruncationDiagID =

1421

H.isKernelCompatible() ? diag::warn_format_truncation

1422

: diag::warn_format_truncation_non_kprintf;

1425

SourceSize->toString(SpecifiedSizeStr,

10);

1426

FormatSize.toString(FormatSizeStr,

10);

1428 PDiag

(TruncationDiagID)

1429

<< GetFunctionName() << SpecifiedSizeStr

1434

DestinationSize = ComputeSizeArgument(0);

1438 if

(!SourceSize || !DestinationSize ||

1439

llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)

1442

StringRef FunctionName = GetFunctionName();

1446

DestinationSize->toString(DestinationStr,

10);

1447

SourceSize->toString(SourceStr,

10);

1450

<< FunctionName << DestinationStr << SourceStr);

1463 while

(S && !S->isSEHExceptScope())

1465 if

(!S || !(S->getFlags() & NeededScopeFlags)) {

1468

<< DRE->getDecl()->getIdentifier();

1480 "__builtin_alloca has invalid address space"

);

1488enum

PointerAuthOpKind {

1537

llvm::raw_svector_ostream Str(

Value

);

1546 Result

= KeyValue->getZExtValue();

1550static

std::pair<const ValueDecl *, CharUnits>

1557 const auto

*BaseDecl =

1562 return

{BaseDecl,

Result

.Val.getLValueOffset()};

1566 bool

RequireConstant =

false

) {

1574 auto

AllowsPointer = [](PointerAuthOpKind OpKind) {

1575 return

OpKind != PAO_BlendInteger;

1577 auto

AllowsInteger = [](PointerAuthOpKind OpKind) {

1578 return

OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||

1579

OpKind == PAO_SignGeneric;

1588

}

else if

(AllowsInteger(OpKind) &&

1595

<<

unsigned

(OpKind == PAO_Discriminator ? 1

1596

: OpKind == PAO_BlendPointer ? 2

1597

: OpKind == PAO_BlendInteger ? 3

1599

<<

unsigned

(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)

1609 if

(!RequireConstant) {

1611 if

((OpKind == PAO_Sign || OpKind == PAO_Auth) &&

1614

? diag::warn_ptrauth_sign_null_pointer

1615

: diag::warn_ptrauth_auth_null_pointer)

1625 if

(OpKind == PAO_Sign) {

1635 else if

(isa<FunctionDecl>(BaseDecl))

1643

S.

Diag

(Arg->

getExprLoc

(), diag::err_ptrauth_bad_constant_pointer);

1648

assert(OpKind == PAO_Discriminator);

1654 if

(

Call

->getBuiltinCallee() ==

1655

Builtin::BI__builtin_ptrauth_blend_discriminator) {

1670

assert(

Pointer

->getType()->isPointerType());

1676 if

(!BaseDecl || !isa<VarDecl>(BaseDecl))

1682

assert(

Integer

->getType()->isIntegerType());

1688

S.

Diag

(Arg->

getExprLoc

(), diag::err_ptrauth_bad_constant_discriminator);

1701 Call

->setType(

Call

->getArgs()[0]->getType());

1732

PointerAuthOpKind OpKind,

1733 bool

RequireConstant) {

1744 Call

->setType(

Call

->getArgs()[0]->getType());

1760 Call

->setType(

Call

->getArgs()[0]->getType());

1769 const Expr

*Arg =

Call

->getArg(0)->IgnoreParenImpCasts();

1772 const auto

*Literal = dyn_cast<StringLiteral>(Arg);

1773 if

(!Literal || Literal->getCharByteWidth() != 1) {

1774

S.

Diag

(Arg->

getExprLoc

(), diag::err_ptrauth_string_not_literal)

1803 auto

DiagSelect = [&]() -> std::optional<unsigned> {

1810 return

std::optional<unsigned>{};

1813

S.

Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_launder_invalid_arg)

1825

diag::err_incomplete_type))

1829 "Unhandled non-object pointer case"

);

1857 if

(PT->getPointeeType()->isFunctionType()) {

1859

diag::err_builtin_is_within_lifetime_invalid_arg)

1865 if

(PT->getPointeeType()->isVariableArrayType()) {

1867

<< 1 <<

"__builtin_is_within_lifetime"

;

1872

diag::err_builtin_is_within_lifetime_invalid_arg)

1885

llvm::Triple::ObjectFormatType CurObjFormat =

1887 if

(llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {

1888

S.

Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_target_unsupported)

1900

llvm::Triple::ArchType CurArch =

1902 if

(llvm::is_contained(SupportedArchs, CurArch))

1904

S.

Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_target_unsupported)

1912bool

Sema::CheckTSBuiltinFunctionCall(

const TargetInfo

&TI,

unsigned

BuiltinID,

1919 case

llvm::Triple::arm:

1920 case

llvm::Triple::armeb:

1921 case

llvm::Triple::thumb:

1922 case

llvm::Triple::thumbeb:

1924 case

llvm::Triple::aarch64:

1925 case

llvm::Triple::aarch64_32:

1926 case

llvm::Triple::aarch64_be:

1928 case

llvm::Triple::bpfeb:

1929 case

llvm::Triple::bpfel:

1931 case

llvm::Triple::hexagon:

1933 case

llvm::Triple::mips:

1934 case

llvm::Triple::mipsel:

1935 case

llvm::Triple::mips64:

1936 case

llvm::Triple::mips64el:

1938 case

llvm::Triple::spirv:

1940 case

llvm::Triple::systemz:

1942 case

llvm::Triple::x86:

1943 case

llvm::Triple::x86_64:

1945 case

llvm::Triple::ppc:

1946 case

llvm::Triple::ppcle:

1947 case

llvm::Triple::ppc64:

1948 case

llvm::Triple::ppc64le:

1950 case

llvm::Triple::amdgcn:

1952 case

llvm::Triple::riscv32:

1953 case

llvm::Triple::riscv64:

1955 case

llvm::Triple::loongarch32:

1956 case

llvm::Triple::loongarch64:

1959 case

llvm::Triple::wasm32:

1960 case

llvm::Triple::wasm64:

1962 case

llvm::Triple::nvptx:

1963 case

llvm::Triple::nvptx64:

1975 return

S.

Diag

(

Loc

, diag::err_builtin_invalid_arg_type)

1976

<< ArgIndex <<

0 << ArgTy;

1986

EltTy = VecTy->getElementType();

1989 return

S.

Diag

(

Loc

, diag::err_builtin_invalid_arg_type)

1990

<< ArgIndex <<

5 << ArgTy;

2000 const TargetInfo

*AuxTI,

unsigned

BuiltinID) {

2001

assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||

2002

BuiltinID == Builtin::BI__builtin_cpu_is) &&

2003 "Expecting __builtin_cpu_..."

);

2005 bool

IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;

2007 auto

SupportsBI = [=](

const TargetInfo

*TInfo) {

2008 return

TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||

2009

(!IsCPUSupports && TInfo->supportsCpuIs()));

2011 if

(!SupportsBI(&TI) && SupportsBI(AuxTI))

2018

? diag::err_builtin_aix_os_unsupported

2019

: diag::err_builtin_target_unsupported)

2024 if

(!isa<StringLiteral>(Arg))

2025 return

S.

Diag

(TheCall->

getBeginLoc

(), diag::err_expr_not_string_literal)

2029

StringRef Feature = cast<StringLiteral>(Arg)->getString();

2052

TheCall->

setArg

(0, Arg);

2076

TheCall->

setArg

(0, Arg0);

2082

<< 1 <<

7 << Arg0Ty;

2092

TheCall->

setArg

(1, Arg1);

2098

<< 2 <<

8 << Arg1Ty;

2107

Sema::CheckBuiltinFunctionCall(

FunctionDecl

*FDecl,

unsigned

BuiltinID,

2112 unsigned

ICEArguments = 0;

2119 for

(

unsigned

ArgNo = 0; ICEArguments != 0; ++ArgNo) {

2121 if

((ICEArguments & (1 << ArgNo)) == 0)

continue

;

2126 if

(ArgNo < TheCall->getNumArgs() &&

2129

ICEArguments &= ~(1 << ArgNo);

2133 switch

(BuiltinID) {

2134 case

Builtin::BI__builtin_cpu_supports:

2135 case

Builtin::BI__builtin_cpu_is:

2140 case

Builtin::BI__builtin_cpu_init:

2147 case

Builtin::BI__builtin___CFStringMakeConstantString:

2151

*

this

, BuiltinID, TheCall,

2152

{llvm::Triple::GOFF, llvm::Triple::XCOFF}))

2155 "Wrong # arguments to builtin CFStringMakeConstantString"

);

2156 if

(

ObjC

().CheckObjCString(TheCall->

getArg

(0)))

2159 case

Builtin::BI__builtin_ms_va_start:

2160 case

Builtin::BI__builtin_stdarg_start:

2161 case

Builtin::BI__builtin_va_start:

2162 if

(BuiltinVAStart(BuiltinID, TheCall))

2165 case

Builtin::BI__va_start: {

2167 case

llvm::Triple::aarch64:

2168 case

llvm::Triple::arm:

2169 case

llvm::Triple::thumb:

2170 if

(BuiltinVAStartARMMicrosoft(TheCall))

2174 if

(BuiltinVAStart(BuiltinID, TheCall))

2182 case

Builtin::BI_interlockedbittestandset_acq:

2183 case

Builtin::BI_interlockedbittestandset_rel:

2184 case

Builtin::BI_interlockedbittestandset_nf:

2185 case

Builtin::BI_interlockedbittestandreset_acq:

2186 case

Builtin::BI_interlockedbittestandreset_rel:

2187 case

Builtin::BI_interlockedbittestandreset_nf:

2190

{llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))

2195 case

Builtin::BI_bittest64:

2196 case

Builtin::BI_bittestandcomplement64:

2197 case

Builtin::BI_bittestandreset64:

2198 case

Builtin::BI_bittestandset64:

2199 case

Builtin::BI_interlockedbittestandreset64:

2200 case

Builtin::BI_interlockedbittestandset64:

2203

{llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,

2204

llvm::Triple::aarch64, llvm::Triple::amdgcn}))

2208 case

Builtin::BI__builtin_set_flt_rounds:

2211

{llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,

2212

llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,

2213

llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,

2214

llvm::Triple::ppc64le}))

2218 case

Builtin::BI__builtin_isgreater:

2219 case

Builtin::BI__builtin_isgreaterequal:

2220 case

Builtin::BI__builtin_isless:

2221 case

Builtin::BI__builtin_islessequal:

2222 case

Builtin::BI__builtin_islessgreater:

2223 case

Builtin::BI__builtin_isunordered:

2224 if

(BuiltinUnorderedCompare(TheCall, BuiltinID))

2227 case

Builtin::BI__builtin_fpclassify:

2228 if

(BuiltinFPClassification(TheCall, 6, BuiltinID))

2231 case

Builtin::BI__builtin_isfpclass:

2232 if

(BuiltinFPClassification(TheCall, 2, BuiltinID))

2235 case

Builtin::BI__builtin_isfinite:

2236 case

Builtin::BI__builtin_isinf:

2237 case

Builtin::BI__builtin_isinf_sign:

2238 case

Builtin::BI__builtin_isnan:

2239 case

Builtin::BI__builtin_issignaling:

2240 case

Builtin::BI__builtin_isnormal:

2241 case

Builtin::BI__builtin_issubnormal:

2242 case

Builtin::BI__builtin_iszero:

2243 case

Builtin::BI__builtin_signbit:

2244 case

Builtin::BI__builtin_signbitf:

2245 case

Builtin::BI__builtin_signbitl:

2246 if

(BuiltinFPClassification(TheCall, 1, BuiltinID))

2249 case

Builtin::BI__builtin_shufflevector:

2253 case

Builtin::BI__builtin_prefetch:

2254 if

(BuiltinPrefetch(TheCall))

2257 case

Builtin::BI__builtin_alloca_with_align:

2258 case

Builtin::BI__builtin_alloca_with_align_uninitialized:

2259 if

(BuiltinAllocaWithAlign(TheCall))

2262 case

Builtin::BI__builtin_alloca:

2263 case

Builtin::BI__builtin_alloca_uninitialized:

2270 case

Builtin::BI__arithmetic_fence:

2271 if

(BuiltinArithmeticFence(TheCall))

2274 case

Builtin::BI__assume:

2275 case

Builtin::BI__builtin_assume:

2276 if

(BuiltinAssume(TheCall))

2279 case

Builtin::BI__builtin_assume_aligned:

2280 if

(BuiltinAssumeAligned(TheCall))

2283 case

Builtin::BI__builtin_dynamic_object_size:

2284 case

Builtin::BI__builtin_object_size:

2288 case

Builtin::BI__builtin_longjmp:

2289 if

(BuiltinLongjmp(TheCall))

2292 case

Builtin::BI__builtin_setjmp:

2293 if

(BuiltinSetjmp(TheCall))

2296 case

Builtin::BI__builtin_classify_type:

2301 case

Builtin::BI__builtin_complex:

2302 if

(BuiltinComplex(TheCall))

2305 case

Builtin::BI__builtin_constant_p: {

2314 case

Builtin::BI__builtin_launder:

2316 case

Builtin::BI__builtin_is_within_lifetime:

2318 case

Builtin::BI__sync_fetch_and_add:

2319 case

Builtin::BI__sync_fetch_and_add_1:

2320 case

Builtin::BI__sync_fetch_and_add_2:

2321 case

Builtin::BI__sync_fetch_and_add_4:

2322 case

Builtin::BI__sync_fetch_and_add_8:

2323 case

Builtin::BI__sync_fetch_and_add_16:

2324 case

Builtin::BI__sync_fetch_and_sub:

2325 case

Builtin::BI__sync_fetch_and_sub_1:

2326 case

Builtin::BI__sync_fetch_and_sub_2:

2327 case

Builtin::BI__sync_fetch_and_sub_4:

2328 case

Builtin::BI__sync_fetch_and_sub_8:

2329 case

Builtin::BI__sync_fetch_and_sub_16:

2330 case

Builtin::BI__sync_fetch_and_or:

2331 case

Builtin::BI__sync_fetch_and_or_1:

2332 case

Builtin::BI__sync_fetch_and_or_2:

2333 case

Builtin::BI__sync_fetch_and_or_4:

2334 case

Builtin::BI__sync_fetch_and_or_8:

2335 case

Builtin::BI__sync_fetch_and_or_16:

2336 case

Builtin::BI__sync_fetch_and_and:

2337 case

Builtin::BI__sync_fetch_and_and_1:

2338 case

Builtin::BI__sync_fetch_and_and_2:

2339 case

Builtin::BI__sync_fetch_and_and_4:

2340 case

Builtin::BI__sync_fetch_and_and_8:

2341 case

Builtin::BI__sync_fetch_and_and_16:

2342 case

Builtin::BI__sync_fetch_and_xor:

2343 case

Builtin::BI__sync_fetch_and_xor_1:

2344 case

Builtin::BI__sync_fetch_and_xor_2:

2345 case

Builtin::BI__sync_fetch_and_xor_4:

2346 case

Builtin::BI__sync_fetch_and_xor_8:

2347 case

Builtin::BI__sync_fetch_and_xor_16:

2348 case

Builtin::BI__sync_fetch_and_nand:

2349 case

Builtin::BI__sync_fetch_and_nand_1:

2350 case

Builtin::BI__sync_fetch_and_nand_2:

2351 case

Builtin::BI__sync_fetch_and_nand_4:

2352 case

Builtin::BI__sync_fetch_and_nand_8:

2353 case

Builtin::BI__sync_fetch_and_nand_16:

2354 case

Builtin::BI__sync_add_and_fetch:

2355 case

Builtin::BI__sync_add_and_fetch_1:

2356 case

Builtin::BI__sync_add_and_fetch_2:

2357 case

Builtin::BI__sync_add_and_fetch_4:

2358 case

Builtin::BI__sync_add_and_fetch_8:

2359 case

Builtin::BI__sync_add_and_fetch_16:

2360 case

Builtin::BI__sync_sub_and_fetch:

2361 case

Builtin::BI__sync_sub_and_fetch_1:

2362 case

Builtin::BI__sync_sub_and_fetch_2:

2363 case

Builtin::BI__sync_sub_and_fetch_4:

2364 case

Builtin::BI__sync_sub_and_fetch_8:

2365 case

Builtin::BI__sync_sub_and_fetch_16:

2366 case

Builtin::BI__sync_and_and_fetch:

2367 case

Builtin::BI__sync_and_and_fetch_1:

2368 case

Builtin::BI__sync_and_and_fetch_2:

2369 case

Builtin::BI__sync_and_and_fetch_4:

2370 case

Builtin::BI__sync_and_and_fetch_8:

2371 case

Builtin::BI__sync_and_and_fetch_16:

2372 case

Builtin::BI__sync_or_and_fetch:

2373 case

Builtin::BI__sync_or_and_fetch_1:

2374 case

Builtin::BI__sync_or_and_fetch_2:

2375 case

Builtin::BI__sync_or_and_fetch_4:

2376 case

Builtin::BI__sync_or_and_fetch_8:

2377 case

Builtin::BI__sync_or_and_fetch_16:

2378 case

Builtin::BI__sync_xor_and_fetch:

2379 case

Builtin::BI__sync_xor_and_fetch_1:

2380 case

Builtin::BI__sync_xor_and_fetch_2:

2381 case

Builtin::BI__sync_xor_and_fetch_4:

2382 case

Builtin::BI__sync_xor_and_fetch_8:

2383 case

Builtin::BI__sync_xor_and_fetch_16:

2384 case

Builtin::BI__sync_nand_and_fetch:

2385 case

Builtin::BI__sync_nand_and_fetch_1:

2386 case

Builtin::BI__sync_nand_and_fetch_2:

2387 case

Builtin::BI__sync_nand_and_fetch_4:

2388 case

Builtin::BI__sync_nand_and_fetch_8:

2389 case

Builtin::BI__sync_nand_and_fetch_16:

2390 case

Builtin::BI__sync_val_compare_and_swap:

2391 case

Builtin::BI__sync_val_compare_and_swap_1:

2392 case

Builtin::BI__sync_val_compare_and_swap_2:

2393 case

Builtin::BI__sync_val_compare_and_swap_4:

2394 case

Builtin::BI__sync_val_compare_and_swap_8:

2395 case

Builtin::BI__sync_val_compare_and_swap_16:

2396 case

Builtin::BI__sync_bool_compare_and_swap:

2397 case

Builtin::BI__sync_bool_compare_and_swap_1:

2398 case

Builtin::BI__sync_bool_compare_and_swap_2:

2399 case

Builtin::BI__sync_bool_compare_and_swap_4:

2400 case

Builtin::BI__sync_bool_compare_and_swap_8:

2401 case

Builtin::BI__sync_bool_compare_and_swap_16:

2402 case

Builtin::BI__sync_lock_test_and_set:

2403 case

Builtin::BI__sync_lock_test_and_set_1:

2404 case

Builtin::BI__sync_lock_test_and_set_2:

2405 case

Builtin::BI__sync_lock_test_and_set_4:

2406 case

Builtin::BI__sync_lock_test_and_set_8:

2407 case

Builtin::BI__sync_lock_test_and_set_16:

2408 case

Builtin::BI__sync_lock_release:

2409 case

Builtin::BI__sync_lock_release_1:

2410 case

Builtin::BI__sync_lock_release_2:

2411 case

Builtin::BI__sync_lock_release_4:

2412 case

Builtin::BI__sync_lock_release_8:

2413 case

Builtin::BI__sync_lock_release_16:

2414 case

Builtin::BI__sync_swap:

2415 case

Builtin::BI__sync_swap_1:

2416 case

Builtin::BI__sync_swap_2:

2417 case

Builtin::BI__sync_swap_4:

2418 case

Builtin::BI__sync_swap_8:

2419 case

Builtin::BI__sync_swap_16:

2420 return

BuiltinAtomicOverloaded(TheCallResult);

2421 case

Builtin::BI__sync_synchronize:

2425 case

Builtin::BI__builtin_nontemporal_load:

2426 case

Builtin::BI__builtin_nontemporal_store:

2427 return

BuiltinNontemporalOverloaded(TheCallResult);

2428 case

Builtin::BI__builtin_memcpy_inline: {

2441 case

Builtin::BI__builtin_memset_inline: {

2452#define BUILTIN(ID, TYPE, ATTRS) 2453#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \ 2454 case Builtin::BI##ID: \ 2455 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID); 2456#include "clang/Basic/Builtins.inc" 2457 case

Builtin::BI__annotation:

2461 case

Builtin::BI__builtin_annotation:

2465 case

Builtin::BI__builtin_addressof:

2469 case

Builtin::BI__builtin_function_start:

2473 case

Builtin::BI__builtin_is_aligned:

2474 case

Builtin::BI__builtin_align_up:

2475 case

Builtin::BI__builtin_align_down:

2479 case

Builtin::BI__builtin_add_overflow:

2480 case

Builtin::BI__builtin_sub_overflow:

2481 case

Builtin::BI__builtin_mul_overflow:

2485 case

Builtin::BI__builtin_operator_new:

2486 case

Builtin::BI__builtin_operator_delete: {

2487 bool

IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;

2489

BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);

2494 case

Builtin::BI__builtin_dump_struct:

2496 case

Builtin::BI__builtin_expect_with_probability: {

2504

Eval.

Diag

= &Notes;

2507 Diag

(ProbArg->

getBeginLoc

(), diag::err_probability_not_constant_float)

2513

llvm::APFloat Probability = Eval.

Val

.

getFloat

();

2514 bool

LoseInfo =

false

;

2515

Probability.convert(llvm::APFloat::IEEEdouble(),

2516

llvm::RoundingMode::Dynamic, &LoseInfo);

2517 if

(!(Probability >= llvm::APFloat(0.0) &&

2518

Probability <= llvm::APFloat(1.0))) {

2525 case

Builtin::BI__builtin_preserve_access_index:

2529 case

Builtin::BI__builtin_call_with_static_chain:

2533 case

Builtin::BI__exception_code:

2534 case

Builtin::BI_exception_code:

2536

diag::err_seh___except_block))

2539 case

Builtin::BI__exception_info:

2540 case

Builtin::BI_exception_info:

2542

diag::err_seh___except_filter))

2545 case

Builtin::BI__GetExceptionInfo:

2557 case

Builtin::BIaddressof:

2558 case

Builtin::BI__addressof:

2559 case

Builtin::BIforward:

2560 case

Builtin::BIforward_like:

2561 case

Builtin::BImove:

2562 case

Builtin::BImove_if_noexcept:

2563 case

Builtin::BIas_const: {

2571 bool

ReturnsPointer = BuiltinID == Builtin::BIaddressof ||

2572

BuiltinID == Builtin::BI__addressof;

2574

(ReturnsPointer ?

Result

->isAnyPointerType()

2575

:

Result

->isReferenceType()) &&

2577 Result

->getPointeeType()))) {

2578 Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_move_forward_unsupported)

2584 case

Builtin::BI__builtin_ptrauth_strip:

2586 case

Builtin::BI__builtin_ptrauth_blend_discriminator:

2588 case

Builtin::BI__builtin_ptrauth_sign_constant:

2591 case

Builtin::BI__builtin_ptrauth_sign_unauthenticated:

2594 case

Builtin::BI__builtin_ptrauth_auth:

2597 case

Builtin::BI__builtin_ptrauth_sign_generic_data:

2599 case

Builtin::BI__builtin_ptrauth_auth_and_resign:

2601 case

Builtin::BI__builtin_ptrauth_string_discriminator:

2604 case

Builtin::BIread_pipe:

2605 case

Builtin::BIwrite_pipe:

2608 if

(

OpenCL

().checkBuiltinRWPipe(TheCall))

2611 case

Builtin::BIreserve_read_pipe:

2612 case

Builtin::BIreserve_write_pipe:

2613 case

Builtin::BIwork_group_reserve_read_pipe:

2614 case

Builtin::BIwork_group_reserve_write_pipe:

2615 if

(

OpenCL

().checkBuiltinReserveRWPipe(TheCall))

2618 case

Builtin::BIsub_group_reserve_read_pipe:

2619 case

Builtin::BIsub_group_reserve_write_pipe:

2620 if

(

OpenCL

().checkSubgroupExt(TheCall) ||

2621 OpenCL

().checkBuiltinReserveRWPipe(TheCall))

2624 case

Builtin::BIcommit_read_pipe:

2625 case

Builtin::BIcommit_write_pipe:

2626 case

Builtin::BIwork_group_commit_read_pipe:

2627 case

Builtin::BIwork_group_commit_write_pipe:

2628 if

(

OpenCL

().checkBuiltinCommitRWPipe(TheCall))

2631 case

Builtin::BIsub_group_commit_read_pipe:

2632 case

Builtin::BIsub_group_commit_write_pipe:

2633 if

(

OpenCL

().checkSubgroupExt(TheCall) ||

2634 OpenCL

().checkBuiltinCommitRWPipe(TheCall))

2637 case

Builtin::BIget_pipe_num_packets:

2638 case

Builtin::BIget_pipe_max_packets:

2639 if

(

OpenCL

().checkBuiltinPipePackets(TheCall))

2642 case

Builtin::BIto_global:

2643 case

Builtin::BIto_local:

2644 case

Builtin::BIto_private:

2645 if

(

OpenCL

().checkBuiltinToAddr(BuiltinID, TheCall))

2649 case

Builtin::BIenqueue_kernel:

2650 if

(

OpenCL

().checkBuiltinEnqueueKernel(TheCall))

2653 case

Builtin::BIget_kernel_work_group_size:

2654 case

Builtin::BIget_kernel_preferred_work_group_size_multiple:

2655 if

(

OpenCL

().checkBuiltinKernelWorkGroupSize(TheCall))

2658 case

Builtin::BIget_kernel_max_sub_group_size_for_ndrange:

2659 case

Builtin::BIget_kernel_sub_group_count_for_ndrange:

2660 if

(

OpenCL

().checkBuiltinNDRangeAndBlock(TheCall))

2663 case

Builtin::BI__builtin_os_log_format:

2666 case

Builtin::BI__builtin_os_log_format_buffer_size:

2667 if

(BuiltinOSLogFormat(TheCall))

2670 case

Builtin::BI__builtin_frame_address:

2671 case

Builtin::BI__builtin_return_address: {

2680 Result

.Val.getInt() != 0)

2682

<< ((BuiltinID == Builtin::BI__builtin_return_address)

2683

?

"__builtin_return_address" 2684

:

"__builtin_frame_address"

)

2689 case

Builtin::BI__builtin_nondeterministic_value: {

2690 if

(BuiltinNonDeterministicValue(TheCall))

2697 case

Builtin::BI__builtin_elementwise_abs: {

2705

EltTy = VecTy->getElementType();

2708

diag::err_builtin_invalid_arg_type)

2717 case

Builtin::BI__builtin_elementwise_acos:

2718 case

Builtin::BI__builtin_elementwise_asin:

2719 case

Builtin::BI__builtin_elementwise_atan:

2720 case

Builtin::BI__builtin_elementwise_ceil:

2721 case

Builtin::BI__builtin_elementwise_cos:

2722 case

Builtin::BI__builtin_elementwise_cosh:

2723 case

Builtin::BI__builtin_elementwise_exp:

2724 case

Builtin::BI__builtin_elementwise_exp2:

2725 case

Builtin::BI__builtin_elementwise_floor:

2726 case

Builtin::BI__builtin_elementwise_log:

2727 case

Builtin::BI__builtin_elementwise_log2:

2728 case

Builtin::BI__builtin_elementwise_log10:

2729 case

Builtin::BI__builtin_elementwise_roundeven:

2730 case

Builtin::BI__builtin_elementwise_round:

2731 case

Builtin::BI__builtin_elementwise_rint:

2732 case

Builtin::BI__builtin_elementwise_nearbyint:

2733 case

Builtin::BI__builtin_elementwise_sin:

2734 case

Builtin::BI__builtin_elementwise_sinh:

2735 case

Builtin::BI__builtin_elementwise_sqrt:

2736 case

Builtin::BI__builtin_elementwise_tan:

2737 case

Builtin::BI__builtin_elementwise_tanh:

2738 case

Builtin::BI__builtin_elementwise_trunc:

2739 case

Builtin::BI__builtin_elementwise_canonicalize: {

2749 case

Builtin::BI__builtin_elementwise_fma: {

2757 case

Builtin::BI__builtin_elementwise_minimum:

2758 case

Builtin::BI__builtin_elementwise_maximum:

2759 case

Builtin::BI__builtin_elementwise_atan2:

2760 case

Builtin::BI__builtin_elementwise_fmod:

2761 case

Builtin::BI__builtin_elementwise_pow: {

2762 if

(BuiltinElementwiseMath(TheCall,

true

))

2769 case

Builtin::BI__builtin_elementwise_add_sat:

2770 case

Builtin::BI__builtin_elementwise_sub_sat: {

2771 if

(BuiltinElementwiseMath(TheCall))

2779

EltTy = VecTy->getElementType();

2789 case

Builtin::BI__builtin_elementwise_min:

2790 case

Builtin::BI__builtin_elementwise_max:

2791 if

(BuiltinElementwiseMath(TheCall))

2794 case

Builtin::BI__builtin_elementwise_popcount:

2795 case

Builtin::BI__builtin_elementwise_bitreverse: {

2804

EltTy = VecTy->getElementType();

2814 case

Builtin::BI__builtin_elementwise_copysign: {

2834

diag::err_typecheck_call_different_arg_types)

2835

<< MagnitudeTy << SignTy;

2838

TheCall->

setArg

(0, Magnitude.

get

());

2843 case

Builtin::BI__builtin_reduce_max:

2844 case

Builtin::BI__builtin_reduce_min: {

2845 if

(PrepareBuiltinReduceMathOneArgCall(TheCall))

2853

ElTy = TyA->getElementType();

2857 if

(ElTy.isNull()) {

2859

<< 1 <<

4 << Arg->

getType

();

2866 case

Builtin::BI__builtin_reduce_maximum:

2867 case

Builtin::BI__builtin_reduce_minimum: {

2868 if

(PrepareBuiltinReduceMathOneArgCall(TheCall))

2876

ElTy = TyA->getElementType();

2880 if

(ElTy.isNull() || !ElTy->isFloatingType()) {

2882

<< 1 <<

9 << Arg->

getType

();

2892 case

Builtin::BI__builtin_reduce_add:

2893 case

Builtin::BI__builtin_reduce_mul:

2894 case

Builtin::BI__builtin_reduce_xor:

2895 case

Builtin::BI__builtin_reduce_or:

2896 case

Builtin::BI__builtin_reduce_and: {

2897 if

(PrepareBuiltinReduceMathOneArgCall(TheCall))

2905

ElTy = TyA->getElementType();

2909 if

(ElTy.isNull() || !ElTy->isIntegerType()) {

2911

<< 1 <<

6 << Arg->

getType

();

2919 case

Builtin::BI__builtin_matrix_transpose:

2920 return

BuiltinMatrixTranspose(TheCall, TheCallResult);

2922 case

Builtin::BI__builtin_matrix_column_major_load:

2923 return

BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);

2925 case

Builtin::BI__builtin_matrix_column_major_store:

2926 return

BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);

2928 case

Builtin::BI__builtin_verbose_trap:

2933 case

Builtin::BI__builtin_get_device_side_mangled_name: {

2934 auto

Check = [](

CallExpr

*TheCall) {

2940 auto

*

D

= DRE->getDecl();

2941 if

(!isa<FunctionDecl>(

D

) && !isa<VarDecl>(

D

))

2943 return D

->

hasAttr

<CUDAGlobalAttr>() ||

D

->

hasAttr

<CUDADeviceAttr>() ||

2946 if

(!Check(TheCall)) {

2948

diag::err_hip_invalid_args_builtin_mangled_name);

2953 case

Builtin::BI__builtin_popcountg:

2957 case

Builtin::BI__builtin_clzg:

2958 case

Builtin::BI__builtin_ctzg:

2963 case

Builtin::BI__builtin_allow_runtime_check: {

2973 case

Builtin::BI__builtin_counted_by_ref:

2974 if

(BuiltinCountedByRef(TheCall))

2987 "Aux Target Builtin, but not an aux target?"

);

2989 if

(CheckTSBuiltinFunctionCall(

3000 return

TheCallResult;

3015 if

(

Result

.isShiftedMask() || (~

Result

).isShiftedMask())

3019

diag::err_argument_not_contiguous_bit_field)

3025 if

(Format->getFirstArg() == 0)

3027 else if

(IsVariadic)

3031

FSI->

FormatIdx

= Format->getFormatIdx() - 1;

3055 if

(isa<CXXNullPtrLiteralExpr>(

3070 if

(

const auto

*CLE = dyn_cast<CompoundLiteralExpr>(

Expr

))

3071 if

(

const auto

*ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))

3072 Expr

= ILE->getInit(0);

3082 const Expr

*ArgExpr,

3086

S.

PDiag

(diag::warn_null_arg)

3092 if

(

auto

nullability =

type

->getNullability())

3103

assert((FDecl || Proto) &&

"Need a function declaration or prototype"

);

3109

llvm::SmallBitVector NonNullArgs;

3113 if

(!

NonNull

->args_size()) {

3115 for

(

const auto

*Arg : Args)

3122 unsigned

IdxAST = Idx.getASTIndex();

3123 if

(IdxAST >= Args.size())

3125 if

(NonNullArgs.empty())

3126

NonNullArgs.resize(Args.size());

3127

NonNullArgs.set(IdxAST);

3132 if

(FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {

3136 if

(

const FunctionDecl

*FD = dyn_cast<FunctionDecl>(FDecl))

3139

parms = cast<ObjCMethodDecl>(FDecl)->parameters();

3141 unsigned

ParamIndex = 0;

3143

I !=

E

; ++I, ++ParamIndex) {

3146 if

(NonNullArgs.empty())

3147

NonNullArgs.resize(Args.size());

3149

NonNullArgs.set(ParamIndex);

3156 if

(

const ValueDecl

*VD = dyn_cast<ValueDecl>(FDecl)) {

3161 type

= blockType->getPointeeType();

3175 if

(NonNullArgs.empty())

3176

NonNullArgs.resize(Args.size());

3178

NonNullArgs.set(Index);

3187 for

(

unsigned

ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();

3188

ArgIndex != ArgIndexEnd; ++ArgIndex) {

3189 if

(NonNullArgs[ArgIndex])

3195

StringRef ParamName,

QualType

ArgTy,

3223 if

(ArgAlign < ParamAlign)

3224 Diag

(

Loc

, diag::warn_param_mismatched_alignment)

3226

<< ParamName << (FDecl !=

nullptr

) << FDecl;

3230 const Expr

*ThisArg,

3232 if

(!FD || Args.empty())

3234 auto

GetArgAt = [&](

int

Idx) ->

const Expr

* {

3235 if

(Idx == LifetimeCaptureByAttr::GLOBAL ||

3236

Idx == LifetimeCaptureByAttr::UNKNOWN)

3238 if

(IsMemberFunction && Idx == 0)

3240 return

Args[Idx - IsMemberFunction];

3242 auto

HandleCaptureByAttr = [&](

const

LifetimeCaptureByAttr *

Attr

,

3247 Expr

*Captured =

const_cast<Expr

*

>

(GetArgAt(ArgIdx));

3248 for

(

int

CapturingParamIdx :

Attr

->params()) {

3251 if

(CapturingParamIdx == LifetimeCaptureByAttr::THIS &&

3252

isa<CXXConstructorDecl>(FD))

3254 Expr

*Capturing =

const_cast<Expr

*

>

(GetArgAt(CapturingParamIdx));

3262

I + IsMemberFunction);

3264 if

(IsMemberFunction) {

3272

HandleCaptureByAttr(ATL.

getAttrAs

<LifetimeCaptureByAttr>(), 0);

3285

llvm::SmallBitVector CheckedVarArgs;

3289

CheckedVarArgs.resize(Args.size());

3291

CheckFormatArguments(I, Args, IsMemberFunction, CallType,

Loc

,

Range

,

3298 auto

*FD = dyn_cast_or_null<FunctionDecl>(FDecl);

3302

: isa_and_nonnull<FunctionDecl>(FDecl)

3303

? cast<FunctionDecl>(FDecl)->getNumParams()

3304

: isa_and_nonnull<ObjCMethodDecl>(FDecl)

3305

? cast<ObjCMethodDecl>(FDecl)->param_size()

3308 for

(

unsigned

ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {

3310 if

(

const Expr

*Arg = Args[ArgIdx]) {

3311 if

(CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])

3318 if

(FDecl || Proto) {

3323 for

(

const auto

*I : FDecl->

specific_attrs

<ArgumentWithTypeTagAttr>())

3324

CheckArgumentWithTypeTag(I, Args,

Loc

);

3330 if

(!Proto && FDecl) {

3332 if

(isa_and_nonnull<FunctionProtoType>(FT))

3338 const auto

N = std::min<unsigned>(Proto->

getNumParams

(), Args.size());

3340 bool

IsScalableArg =

false

;

3341 for

(

unsigned

ArgIdx = 0; ArgIdx < N; ++ArgIdx) {

3343 if

(

const Expr

*Arg = Args[ArgIdx]) {

3355

IsScalableArg =

true

;

3357

CheckArgAlignment(Arg->

getExprLoc

(), FDecl, std::to_string(ArgIdx + 1),

3366 if

(

auto

*CallerFD = dyn_cast<FunctionDecl>(

CurContext

)) {

3367

llvm::StringMap<bool> CallerFeatureMap;

3369 if

(!CallerFeatureMap.contains(

"sme"

))

3370 Diag

(

Loc

, diag::err_sme_call_in_non_sme_target);

3372 Diag

(

Loc

, diag::err_sme_call_in_non_sme_target);

3379 const auto

*CallerFD = dyn_cast<FunctionDecl>(

CurContext

);

3381

(IsScalableArg || IsScalableRet)) {

3382 bool

IsCalleeStreaming =

3384 bool

IsCalleeStreamingCompatible =

3388 if

(!IsCalleeStreamingCompatible &&

3392 Diag

(

Loc

, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)

3395 Diag

(

Loc

, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)

3406 bool

CallerHasZAState =

false

;

3407 bool

CallerHasZT0State =

false

;

3409 auto

*

Attr

= CallerFD->getAttr<ArmNewAttr>();

3411

CallerHasZAState =

true

;

3413

CallerHasZT0State =

true

;

3417

FPT->getExtProtoInfo().AArch64SMEAttributes) !=

3419

CallerHasZT0State |=

3421

FPT->getExtProtoInfo().AArch64SMEAttributes) !=

3427 Diag

(

Loc

, diag::err_sme_za_call_no_za_state);

3430 Diag

(

Loc

, diag::err_sme_zt0_call_no_zt0_state);

3434 Diag

(

Loc

, diag::err_sme_unimplemented_za_save_restore);

3435 Diag

(

Loc

, diag::note_sme_use_preserves_za);

3440 if

(FDecl && FDecl->

hasAttr

<AllocAlignAttr>()) {

3441 auto

*AA = FDecl->

getAttr

<AllocAlignAttr>();

3442 const Expr

*Arg = Args[AA->getParamIndex().getASTIndex()];

3443 if

(!Arg->isValueDependent()) {

3445 if

(Arg->EvaluateAsInt(Align,

Context

)) {

3446 const

llvm::APSInt &I = Align.

Val

.

getInt

();

3447 if

(!I.isPowerOf2())

3448 Diag

(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)

3449

<< Arg->getSourceRange();

3452 Diag

(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)

3475 auto

*Ctor = cast<CXXConstructorDecl>(FDecl);

3480 checkCall

(FDecl, Proto,

nullptr

, Args,

true

,

3486 bool

IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&

3487

isa<CXXMethodDecl>(FDecl);

3488 bool

IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||

3489

IsMemberOperatorCall;

3495 Expr

*ImplicitThis =

nullptr

;

3500

ImplicitThis = Args[0];

3503

}

else if

(IsMemberFunction && !FDecl->

isStatic

() &&

3506

cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();

3518

cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());

3520

CheckArgAlignment(TheCall->

getRParenLoc

(), FDecl,

"'this'"

, ThisType,

3538

CheckAbsoluteValueFunction(TheCall, FDecl);

3539

CheckMaxUnsignedZero(TheCall, FDecl);

3540

CheckInfNaNFunction(TheCall, FDecl);

3551 case

Builtin::BIstrlcpy:

3552 case

Builtin::BIstrlcat:

3553

CheckStrlcpycatArguments(TheCall, FnInfo);

3555 case

Builtin::BIstrncat:

3556

CheckStrncatArguments(TheCall, FnInfo);

3558 case

Builtin::BIfree:

3559

CheckFreeArguments(TheCall);

3562

CheckMemaccessArguments(TheCall, CMId, FnInfo);

3571 if

(

const auto

*

V

= dyn_cast<VarDecl>(NDecl))

3572

Ty =

V

->getType().getNonReferenceType();

3573 else if

(

const auto

*F = dyn_cast<FieldDecl>(NDecl))

3574

Ty = F->getType().getNonReferenceType();

3611 if

(!llvm::isValidAtomicOrderingCABI(Ordering))

3614 auto

OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;

3616 case

AtomicExpr::AO__c11_atomic_init:

3617 case

AtomicExpr::AO__opencl_atomic_init:

3618

llvm_unreachable(

"There is no ordering argument for an init"

);

3620 case

AtomicExpr::AO__c11_atomic_load:

3621 case

AtomicExpr::AO__opencl_atomic_load:

3622 case

AtomicExpr::AO__hip_atomic_load:

3623 case

AtomicExpr::AO__atomic_load_n:

3624 case

AtomicExpr::AO__atomic_load:

3625 case

AtomicExpr::AO__scoped_atomic_load_n:

3626 case

AtomicExpr::AO__scoped_atomic_load:

3627 return

OrderingCABI != llvm::AtomicOrderingCABI::release &&

3628

OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;

3630 case

AtomicExpr::AO__c11_atomic_store:

3631 case

AtomicExpr::AO__opencl_atomic_store:

3632 case

AtomicExpr::AO__hip_atomic_store:

3633 case

AtomicExpr::AO__atomic_store:

3634 case

AtomicExpr::AO__atomic_store_n:

3635 case

AtomicExpr::AO__scoped_atomic_store:

3636 case

AtomicExpr::AO__scoped_atomic_store_n:

3637 case

AtomicExpr::AO__atomic_clear:

3638 return

OrderingCABI != llvm::AtomicOrderingCABI::consume &&

3639

OrderingCABI != llvm::AtomicOrderingCABI::acquire &&

3640

OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;

3649 CallExpr

*TheCall = cast<CallExpr>(TheCallResult.

get

());

3699 const unsigned

NumForm = ClearByte + 1;

3700 const unsigned

NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};

3701 const unsigned

NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};

3709 static_assert

(

sizeof

(NumArgs)/

sizeof

(NumArgs[0]) == NumForm

3710

&&

sizeof

(NumVals)/

sizeof

(NumVals[0]) == NumForm,

3711 "need to update code for modified forms"

);

3712 static_assert

(AtomicExpr::AO__atomic_add_fetch == 0 &&

3713

AtomicExpr::AO__atomic_xor_fetch + 1 ==

3714

AtomicExpr::AO__c11_atomic_compare_exchange_strong,

3715 "need to update code for modified C11 atomics"

);

3716 bool

IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&

3717

Op <= AtomicExpr::AO__opencl_atomic_store;

3718 bool

IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&

3719

Op <= AtomicExpr::AO__hip_atomic_store;

3720 bool

IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&

3721

Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;

3722 bool

IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&

3723

Op <= AtomicExpr::AO__c11_atomic_store) ||

3725 bool

IsN = Op == AtomicExpr::AO__atomic_load_n ||

3726

Op == AtomicExpr::AO__atomic_store_n ||

3727

Op == AtomicExpr::AO__atomic_exchange_n ||

3728

Op == AtomicExpr::AO__atomic_compare_exchange_n ||

3729

Op == AtomicExpr::AO__scoped_atomic_load_n ||

3730

Op == AtomicExpr::AO__scoped_atomic_store_n ||

3731

Op == AtomicExpr::AO__scoped_atomic_exchange_n ||

3732

Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;

3736 enum

ArithOpExtraValueType {

3741 unsigned

ArithAllows = AOEVT_None;

3744 case

AtomicExpr::AO__c11_atomic_init:

3745 case

AtomicExpr::AO__opencl_atomic_init:

3749 case

AtomicExpr::AO__c11_atomic_load:

3750 case

AtomicExpr::AO__opencl_atomic_load:

3751 case

AtomicExpr::AO__hip_atomic_load:

3752 case

AtomicExpr::AO__atomic_load_n:

3753 case

AtomicExpr::AO__scoped_atomic_load_n:

3757 case

AtomicExpr::AO__atomic_load:

3758 case

AtomicExpr::AO__scoped_atomic_load:

3762 case

AtomicExpr::AO__c11_atomic_store:

3763 case

AtomicExpr::AO__opencl_atomic_store:

3764 case

AtomicExpr::AO__hip_atomic_store:

3765 case

AtomicExpr::AO__atomic_store:

3766 case

AtomicExpr::AO__atomic_store_n:

3767 case

AtomicExpr::AO__scoped_atomic_store:

3768 case

AtomicExpr::AO__scoped_atomic_store_n:

3771 case

AtomicExpr::AO__atomic_fetch_add:

3772 case

AtomicExpr::AO__atomic_fetch_sub:

3773 case

AtomicExpr::AO__atomic_add_fetch:

3774 case

AtomicExpr::AO__atomic_sub_fetch:

3775 case

AtomicExpr::AO__scoped_atomic_fetch_add:

3776 case

AtomicExpr::AO__scoped_atomic_fetch_sub:

3777 case

AtomicExpr::AO__scoped_atomic_add_fetch:

3778 case

AtomicExpr::AO__scoped_atomic_sub_fetch:

3779 case

AtomicExpr::AO__c11_atomic_fetch_add:

3780 case

AtomicExpr::AO__c11_atomic_fetch_sub:

3781 case

AtomicExpr::AO__opencl_atomic_fetch_add:

3782 case

AtomicExpr::AO__opencl_atomic_fetch_sub:

3783 case

AtomicExpr::AO__hip_atomic_fetch_add:

3784 case

AtomicExpr::AO__hip_atomic_fetch_sub:

3785

ArithAllows = AOEVT_Pointer | AOEVT_FP;

3788 case

AtomicExpr::AO__atomic_fetch_max:

3789 case

AtomicExpr::AO__atomic_fetch_min:

3790 case

AtomicExpr::AO__atomic_max_fetch:

3791 case

AtomicExpr::AO__atomic_min_fetch:

3792 case

AtomicExpr::AO__scoped_atomic_fetch_max:

3793 case

AtomicExpr::AO__scoped_atomic_fetch_min:

3794 case

AtomicExpr::AO__scoped_atomic_max_fetch:

3795 case

AtomicExpr::AO__scoped_atomic_min_fetch:

3796 case

AtomicExpr::AO__c11_atomic_fetch_max:

3797 case

AtomicExpr::AO__c11_atomic_fetch_min:

3798 case

AtomicExpr::AO__opencl_atomic_fetch_max:

3799 case

AtomicExpr::AO__opencl_atomic_fetch_min:

3800 case

AtomicExpr::AO__hip_atomic_fetch_max:

3801 case

AtomicExpr::AO__hip_atomic_fetch_min:

3802

ArithAllows = AOEVT_FP;

3805 case

AtomicExpr::AO__c11_atomic_fetch_and:

3806 case

AtomicExpr::AO__c11_atomic_fetch_or:

3807 case

AtomicExpr::AO__c11_atomic_fetch_xor:

3808 case

AtomicExpr::AO__hip_atomic_fetch_and:

3809 case

AtomicExpr::AO__hip_atomic_fetch_or:

3810 case

AtomicExpr::AO__hip_atomic_fetch_xor:

3811 case

AtomicExpr::AO__c11_atomic_fetch_nand:

3812 case

AtomicExpr::AO__opencl_atomic_fetch_and:

3813 case

AtomicExpr::AO__opencl_atomic_fetch_or:

3814 case

AtomicExpr::AO__opencl_atomic_fetch_xor:

3815 case

AtomicExpr::AO__atomic_fetch_and:

3816 case

AtomicExpr::AO__atomic_fetch_or:

3817 case

AtomicExpr::AO__atomic_fetch_xor:

3818 case

AtomicExpr::AO__atomic_fetch_nand:

3819 case

AtomicExpr::AO__atomic_and_fetch:

3820 case

AtomicExpr::AO__atomic_or_fetch:

3821 case

AtomicExpr::AO__atomic_xor_fetch:

3822 case

AtomicExpr::AO__atomic_nand_fetch:

3823 case

AtomicExpr::AO__scoped_atomic_fetch_and:

3824 case

AtomicExpr::AO__scoped_atomic_fetch_or:

3825 case

AtomicExpr::AO__scoped_atomic_fetch_xor:

3826 case

AtomicExpr::AO__scoped_atomic_fetch_nand:

3827 case

AtomicExpr::AO__scoped_atomic_and_fetch:

3828 case

AtomicExpr::AO__scoped_atomic_or_fetch:

3829 case

AtomicExpr::AO__scoped_atomic_xor_fetch:

3830 case

AtomicExpr::AO__scoped_atomic_nand_fetch:

3834 case

AtomicExpr::AO__c11_atomic_exchange:

3835 case

AtomicExpr::AO__hip_atomic_exchange:

3836 case

AtomicExpr::AO__opencl_atomic_exchange:

3837 case

AtomicExpr::AO__atomic_exchange_n:

3838 case

AtomicExpr::AO__scoped_atomic_exchange_n:

3842 case

AtomicExpr::AO__atomic_exchange:

3843 case

AtomicExpr::AO__scoped_atomic_exchange:

3847 case

AtomicExpr::AO__c11_atomic_compare_exchange_strong:

3848 case

AtomicExpr::AO__c11_atomic_compare_exchange_weak:

3849 case

AtomicExpr::AO__hip_atomic_compare_exchange_strong:

3850 case

AtomicExpr::AO__opencl_atomic_compare_exchange_strong:

3851 case

AtomicExpr::AO__opencl_atomic_compare_exchange_weak:

3852 case

AtomicExpr::AO__hip_atomic_compare_exchange_weak:

3856 case

AtomicExpr::AO__atomic_compare_exchange:

3857 case

AtomicExpr::AO__atomic_compare_exchange_n:

3858 case

AtomicExpr::AO__scoped_atomic_compare_exchange:

3859 case

AtomicExpr::AO__scoped_atomic_compare_exchange_n:

3863 case

AtomicExpr::AO__atomic_test_and_set:

3864

Form = TestAndSetByte;

3867 case

AtomicExpr::AO__atomic_clear:

3872 unsigned

AdjustedNumArgs = NumArgs[Form];

3873 if

((IsOpenCL || IsHIP || IsScoped) &&

3874

Op != AtomicExpr::AO__opencl_atomic_init)

3877 if

(Args.size() < AdjustedNumArgs) {

3878 Diag

(CallRange.

getEnd

(), diag::err_typecheck_call_too_few_args)

3879

<< 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())

3882

}

else if

(Args.size() > AdjustedNumArgs) {

3883 Diag

(Args[AdjustedNumArgs]->getBeginLoc(),

3884

diag::err_typecheck_call_too_many_args)

3885

<< 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())

3891 Expr

*Ptr = Args[0];

3896

Ptr = ConvertedPtr.

get

();

3899 Diag

(ExprRange.

getBegin

(), diag::err_atomic_builtin_must_be_pointer)

3909 Diag

(ExprRange.

getBegin

(), diag::err_atomic_op_needs_atomic)

3915 Diag

(ExprRange.

getBegin

(), diag::err_atomic_op_needs_non_const_atomic)

3921

}

else if

(Form != Load && Form != LoadCopy) {

3923 Diag

(ExprRange.

getBegin

(), diag::err_atomic_op_needs_non_const_pointer)

3929 if

(Form != TestAndSetByte && Form != ClearByte) {

3932

diag::err_incomplete_type))

3936 Diag

(ExprRange.

getBegin

(), diag::err_atomic_builtin_must_be_pointer)

3946 pointerType

->getPointeeType().getCVRQualifiers());

3954 if

(Form == Arithmetic) {

3957 auto

IsAllowedValueType = [&](

QualType

ValType,

3958 unsigned

AllowedType) ->

bool

{

3962 return

AllowedType & AOEVT_Pointer;

3968

&llvm::APFloat::x87DoubleExtended())

3972 if

(!IsAllowedValueType(ValType, ArithAllows)) {

3973 auto

DID = ArithAllows & AOEVT_FP

3974

? (ArithAllows & AOEVT_Pointer

3975

? diag::err_atomic_op_needs_atomic_int_ptr_or_fp

3976

: diag::err_atomic_op_needs_atomic_int_or_fp)

3977

: diag::err_atomic_op_needs_atomic_int;

3984

diag::err_incomplete_type)) {

3990 Diag

(ExprRange.

getBegin

(), diag::err_atomic_op_needs_atomic_int_or_ptr)

4001 Diag

(ExprRange.

getBegin

(), diag::err_atomic_op_needs_trivial_copy)

4017 Diag

(ExprRange.

getBegin

(), diag::err_arc_atomic_ownership)

4029 if

(Form ==

Copy

|| Form == LoadCopy || Form == GNUXchg || Form ==

Init

||

4032 else if

(Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)

4038 bool

IsPassedByAddress =

false

;

4039 if

(!IsC11 && !IsHIP && !IsN) {

4041

IsPassedByAddress =

true

;

4046

APIOrderedArgs.push_back(Args[0]);

4050

APIOrderedArgs.push_back(Args[1]);

4056

APIOrderedArgs.push_back(Args[2]);

4057

APIOrderedArgs.push_back(Args[1]);

4060

APIOrderedArgs.push_back(Args[2]);

4061

APIOrderedArgs.push_back(Args[3]);

4062

APIOrderedArgs.push_back(Args[1]);

4065

APIOrderedArgs.push_back(Args[2]);

4066

APIOrderedArgs.push_back(Args[4]);

4067

APIOrderedArgs.push_back(Args[1]);

4068

APIOrderedArgs.push_back(Args[3]);

4071

APIOrderedArgs.push_back(Args[2]);

4072

APIOrderedArgs.push_back(Args[4]);

4073

APIOrderedArgs.push_back(Args[5]);

4074

APIOrderedArgs.push_back(Args[1]);

4075

APIOrderedArgs.push_back(Args[3]);

4077 case

TestAndSetByte:

4079

APIOrderedArgs.push_back(Args[1]);

4083

APIOrderedArgs.append(Args.begin(), Args.end());

4090 for

(

unsigned

i = 0; i != APIOrderedArgs.size(); ++i) {

4092 if

(i < NumVals[Form] + 1) {

4105

assert(Form != Load);

4108 else if

(Form ==

Init

|| Form == Arithmetic)

4110 else if

(Form ==

Copy

|| Form == Xchg) {

4111 if

(IsPassedByAddress) {

4118 Expr

*ValArg = APIOrderedArgs[i];

4125

AS = PtrTy->getPointeeType().getAddressSpace();

4134 if

(IsPassedByAddress)

4154

APIOrderedArgs[i] = Arg.

get

();

4159

SubExprs.push_back(Ptr);

4163

SubExprs.push_back(APIOrderedArgs[1]);

4166 case

TestAndSetByte:

4168

SubExprs.push_back(APIOrderedArgs[1]);

4174

SubExprs.push_back(APIOrderedArgs[2]);

4175

SubExprs.push_back(APIOrderedArgs[1]);

4179

SubExprs.push_back(APIOrderedArgs[3]);

4180

SubExprs.push_back(APIOrderedArgs[1]);

4181

SubExprs.push_back(APIOrderedArgs[2]);

4184

SubExprs.push_back(APIOrderedArgs[3]);

4185

SubExprs.push_back(APIOrderedArgs[1]);

4186

SubExprs.push_back(APIOrderedArgs[4]);

4187

SubExprs.push_back(APIOrderedArgs[2]);

4190

SubExprs.push_back(APIOrderedArgs[4]);

4191

SubExprs.push_back(APIOrderedArgs[1]);

4192

SubExprs.push_back(APIOrderedArgs[5]);

4193

SubExprs.push_back(APIOrderedArgs[2]);

4194

SubExprs.push_back(APIOrderedArgs[3]);

4199 if

(SubExprs.size() >= 2 && Form !=

Init

) {

4200

std::optional<llvm::APSInt>

Success

=

4201

SubExprs[1]->getIntegerConstantExpr(

Context

);

4203 Diag

(SubExprs[1]->getBeginLoc(),

4204

diag::warn_atomic_op_has_invalid_memory_order)

4205

<<

(Form == C11CmpXchg || Form == GNUCmpXchg)

4206

<< SubExprs[1]->getSourceRange();

4208 if

(SubExprs.size() >= 5) {

4209 if

(std::optional<llvm::APSInt> Failure =

4210

SubExprs[3]->getIntegerConstantExpr(

Context

)) {

4211 if

(!llvm::is_contained(

4212

{llvm::AtomicOrderingCABI::relaxed,

4213

llvm::AtomicOrderingCABI::consume,

4214

llvm::AtomicOrderingCABI::acquire,

4215

llvm::AtomicOrderingCABI::seq_cst},

4216

(llvm::AtomicOrderingCABI)Failure->getSExtValue())) {

4217 Diag

(SubExprs[3]->getBeginLoc(),

4218

diag::warn_atomic_op_has_invalid_memory_order)

4219

<<

2 << SubExprs[3]->getSourceRange();

4226 auto

*

Scope

= Args[Args.size() - 1];

4227 if

(std::optional<llvm::APSInt>

Result

=

4229 if

(!ScopeModel->isValid(

Result

->getZExtValue()))

4230 Diag

(

Scope

->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope)

4231

<<

Scope

->getSourceRange();

4233

SubExprs.push_back(

Scope

);

4239 if

((Op == AtomicExpr::AO__c11_atomic_load ||

4240

Op == AtomicExpr::AO__c11_atomic_store ||

4241

Op == AtomicExpr::AO__opencl_atomic_load ||

4242

Op == AtomicExpr::AO__hip_atomic_load ||

4243

Op == AtomicExpr::AO__opencl_atomic_store ||

4244

Op == AtomicExpr::AO__hip_atomic_store) &&

4247

<< ((Op == AtomicExpr::AO__c11_atomic_load ||

4248

Op == AtomicExpr::AO__opencl_atomic_load ||

4249

Op == AtomicExpr::AO__hip_atomic_load)

4254 Diag

(Ptr->

getExprLoc

(), diag::err_atomic_builtin_bit_int_prohibit);

4270

assert(Fn &&

"builtin call without direct callee!"

);

4281 E

->setArg(ArgIndex, Arg.

get

());

4293 Diag

(TheCall->

getEndLoc

(), diag::err_typecheck_call_too_few_args_at_least)

4295

<<

Callee

->getSourceRange();

4308

FirstArg = FirstArgResult.

get

();

4309

TheCall->

setArg

(0, FirstArg);

4321 Diag

(DRE->

getBeginLoc

(), diag::err_atomic_builtin_must_be_pointer_intptr)

4356#define BUILTIN_ROW(x) \ 4357 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \ 4358 Builtin::BI##x##_8, Builtin::BI##x##_16 } 4360 static const unsigned

BuiltinIndices[][5] = {

4386 case

1: SizeIndex = 0;

break

;

4387 case

2: SizeIndex = 1;

break

;

4388 case

4: SizeIndex = 2;

break

;

4389 case

8: SizeIndex = 3;

break

;

4390 case

16: SizeIndex = 4;

break

;

4402 unsigned

BuiltinIndex, NumFixed = 1;

4403 bool

WarnAboutSemanticsChange =

false

;

4404 switch

(BuiltinID) {

4405 default

: llvm_unreachable(

"Unknown overloaded atomic builtin!"

);

4406 case

Builtin::BI__sync_fetch_and_add:

4407 case

Builtin::BI__sync_fetch_and_add_1:

4408 case

Builtin::BI__sync_fetch_and_add_2:

4409 case

Builtin::BI__sync_fetch_and_add_4:

4410 case

Builtin::BI__sync_fetch_and_add_8:

4411 case

Builtin::BI__sync_fetch_and_add_16:

4415 case

Builtin::BI__sync_fetch_and_sub:

4416 case

Builtin::BI__sync_fetch_and_sub_1:

4417 case

Builtin::BI__sync_fetch_and_sub_2:

4418 case

Builtin::BI__sync_fetch_and_sub_4:

4419 case

Builtin::BI__sync_fetch_and_sub_8:

4420 case

Builtin::BI__sync_fetch_and_sub_16:

4424 case

Builtin::BI__sync_fetch_and_or:

4425 case

Builtin::BI__sync_fetch_and_or_1:

4426 case

Builtin::BI__sync_fetch_and_or_2:

4427 case

Builtin::BI__sync_fetch_and_or_4:

4428 case

Builtin::BI__sync_fetch_and_or_8:

4429 case

Builtin::BI__sync_fetch_and_or_16:

4433 case

Builtin::BI__sync_fetch_and_and:

4434 case

Builtin::BI__sync_fetch_and_and_1:

4435 case

Builtin::BI__sync_fetch_and_and_2:

4436 case

Builtin::BI__sync_fetch_and_and_4:

4437 case

Builtin::BI__sync_fetch_and_and_8:

4438 case

Builtin::BI__sync_fetch_and_and_16:

4442 case

Builtin::BI__sync_fetch_and_xor:

4443 case

Builtin::BI__sync_fetch_and_xor_1:

4444 case

Builtin::BI__sync_fetch_and_xor_2:

4445 case

Builtin::BI__sync_fetch_and_xor_4:

4446 case

Builtin::BI__sync_fetch_and_xor_8:

4447 case

Builtin::BI__sync_fetch_and_xor_16:

4451 case

Builtin::BI__sync_fetch_and_nand:

4452 case

Builtin::BI__sync_fetch_and_nand_1:

4453 case

Builtin::BI__sync_fetch_and_nand_2:

4454 case

Builtin::BI__sync_fetch_and_nand_4:

4455 case

Builtin::BI__sync_fetch_and_nand_8:

4456 case

Builtin::BI__sync_fetch_and_nand_16:

4458

WarnAboutSemanticsChange =

true

;

4461 case

Builtin::BI__sync_add_and_fetch:

4462 case

Builtin::BI__sync_add_and_fetch_1:

4463 case

Builtin::BI__sync_add_and_fetch_2:

4464 case

Builtin::BI__sync_add_and_fetch_4:

4465 case

Builtin::BI__sync_add_and_fetch_8:

4466 case

Builtin::BI__sync_add_and_fetch_16:

4470 case

Builtin::BI__sync_sub_and_fetch:

4471 case

Builtin::BI__sync_sub_and_fetch_1:

4472 case

Builtin::BI__sync_sub_and_fetch_2:

4473 case

Builtin::BI__sync_sub_and_fetch_4:

4474 case

Builtin::BI__sync_sub_and_fetch_8:

4475 case

Builtin::BI__sync_sub_and_fetch_16:

4479 case

Builtin::BI__sync_and_and_fetch:

4480 case

Builtin::BI__sync_and_and_fetch_1:

4481 case

Builtin::BI__sync_and_and_fetch_2:

4482 case

Builtin::BI__sync_and_and_fetch_4:

4483 case

Builtin::BI__sync_and_and_fetch_8:

4484 case

Builtin::BI__sync_and_and_fetch_16:

4488 case

Builtin::BI__sync_or_and_fetch:

4489 case

Builtin::BI__sync_or_and_fetch_1:

4490 case

Builtin::BI__sync_or_and_fetch_2:

4491 case

Builtin::BI__sync_or_and_fetch_4:

4492 case

Builtin::BI__sync_or_and_fetch_8:

4493 case

Builtin::BI__sync_or_and_fetch_16:

4497 case

Builtin::BI__sync_xor_and_fetch:

4498 case

Builtin::BI__sync_xor_and_fetch_1:

4499 case

Builtin::BI__sync_xor_and_fetch_2:

4500 case

Builtin::BI__sync_xor_and_fetch_4:

4501 case

Builtin::BI__sync_xor_and_fetch_8:

4502 case

Builtin::BI__sync_xor_and_fetch_16:

4506 case

Builtin::BI__sync_nand_and_fetch:

4507 case

Builtin::BI__sync_nand_and_fetch_1:

4508 case

Builtin::BI__sync_nand_and_fetch_2:

4509 case

Builtin::BI__sync_nand_and_fetch_4:

4510 case

Builtin::BI__sync_nand_and_fetch_8:

4511 case

Builtin::BI__sync_nand_and_fetch_16:

4513

WarnAboutSemanticsChange =

true

;

4516 case

Builtin::BI__sync_val_compare_and_swap:

4517 case

Builtin::BI__sync_val_compare_and_swap_1:

4518 case

Builtin::BI__sync_val_compare_and_swap_2:

4519 case

Builtin::BI__sync_val_compare_and_swap_4:

4520 case

Builtin::BI__sync_val_compare_and_swap_8:

4521 case

Builtin::BI__sync_val_compare_and_swap_16:

4526 case

Builtin::BI__sync_bool_compare_and_swap:

4527 case

Builtin::BI__sync_bool_compare_and_swap_1:

4528 case

Builtin::BI__sync_bool_compare_and_swap_2:

4529 case

Builtin::BI__sync_bool_compare_and_swap_4:

4530 case

Builtin::BI__sync_bool_compare_and_swap_8:

4531 case

Builtin::BI__sync_bool_compare_and_swap_16:

4537 case

Builtin::BI__sync_lock_test_and_set:

4538 case

Builtin::BI__sync_lock_test_and_set_1:

4539 case

Builtin::BI__sync_lock_test_and_set_2:

4540 case

Builtin::BI__sync_lock_test_and_set_4:

4541 case

Builtin::BI__sync_lock_test_and_set_8:

4542 case

Builtin::BI__sync_lock_test_and_set_16:

4546 case

Builtin::BI__sync_lock_release:

4547 case

Builtin::BI__sync_lock_release_1:

4548 case

Builtin::BI__sync_lock_release_2:

4549 case

Builtin::BI__sync_lock_release_4:

4550 case

Builtin::BI__sync_lock_release_8:

4551 case

Builtin::BI__sync_lock_release_16:

4557 case

Builtin::BI__sync_swap:

4558 case

Builtin::BI__sync_swap_1:

4559 case

Builtin::BI__sync_swap_2:

4560 case

Builtin::BI__sync_swap_4:

4561 case

Builtin::BI__sync_swap_8:

4562 case

Builtin::BI__sync_swap_16:

4570 Diag

(TheCall->

getEndLoc

(), diag::err_typecheck_call_too_few_args_at_least)

4571

<< 0 << 1 + NumFixed << TheCall->

getNumArgs

() <<

0

4572

<<

Callee

->getSourceRange();

4576 Diag

(TheCall->

getEndLoc

(), diag::warn_atomic_implicit_seq_cst)

4577

<<

Callee

->getSourceRange();

4579 if

(WarnAboutSemanticsChange) {

4580 Diag

(TheCall->

getEndLoc

(), diag::warn_sync_fetch_and_nand_semantics_change)

4581

<<

Callee

->getSourceRange();

4586 unsigned

NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];

4589 if

(NewBuiltinID == BuiltinID)

4590

NewBuiltinDecl = FDecl;

4596

assert(Res.getFoundDecl());

4597

NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());

4598 if

(!NewBuiltinDecl)

4605 for

(

unsigned

i = 0; i != NumFixed; ++i) {

4636

CK_BuiltinFnToFnPtr);

4642

TheCall->

setType

(ResultType);

4648 if

(BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {

4649 Diag

(FirstArg->

getExprLoc

(), diag::err_atomic_builtin_ext_int_size);

4653 return

TheCallResult;

4662

assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||

4663

BuiltinID == Builtin::BI__builtin_nontemporal_load) &&

4664 "Unexpected nontemporal load/store builtin!"

);

4665 bool

isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;

4666 unsigned

numArgs = isStore ? 2 : 1;

4676 Expr

*PointerArg = TheCall->

getArg

(numArgs - 1);

4682

PointerArg = PointerArgResult.

get

();

4683

TheCall->

setArg

(numArgs - 1, PointerArg);

4687 Diag

(DRE->

getBeginLoc

(), diag::err_nontemporal_builtin_must_be_pointer)

4700

diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)

4707 return

TheCallResult;

4719 return

TheCallResult;

4726 auto

*

Literal

= dyn_cast<StringLiteral>(Arg);

4728 if

(

auto

*ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {

4729 Literal

= ObjcLiteral->getString();

4733 if

(!Literal || (!

Literal

->isOrdinary() && !

Literal

->isUTF8())) {

4735 Diag

(Arg->

getBeginLoc

(), diag::err_os_log_format_not_string_constant)

4751 bool

IsX64 = TT.getArch() == llvm::Triple::x86_64;

4752 bool

IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||

4753

TT.getArch() == llvm::Triple::aarch64_32);

4754 bool

IsWindows = TT.isOSWindows();

4755 bool

IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;

4756 if

(IsX64 || IsAArch64) {

4763 return

S.

Diag

(Fn->getBeginLoc(),

4764

diag::err_ms_va_start_used_in_sysv_function);

4772 return

S.

Diag

(Fn->getBeginLoc(),

4773

diag::err_va_start_used_in_wrong_abi_function)

4780 return

S.

Diag

(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);

4788 bool

IsVariadic =

false

;

4791 if

(

auto

*

Block

= dyn_cast<BlockDecl>(Caller)) {

4792

IsVariadic =

Block

->isVariadic();

4793

Params =

Block

->parameters();

4794

}

else if

(

auto

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

4797

}

else if

(

auto

*MD = dyn_cast<ObjCMethodDecl>(Caller)) {

4798

IsVariadic = MD->isVariadic();

4800

Params = MD->parameters();

4801

}

else if

(isa<CapturedDecl>(Caller)) {

4803

S.

Diag

(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);

4807

S.

Diag

(Fn->getBeginLoc(), diag::err_va_start_outside_function);

4812

S.

Diag

(Fn->getBeginLoc(), diag::err_va_start_fixed_function);

4817

*LastParam = Params.empty() ? nullptr : Params.back();

4822bool

Sema::BuiltinVAStart(

unsigned

BuiltinID,

CallExpr

*TheCall) {

4847 bool

SecondArgIsLastNamedArgument =

false

;

4849 if

(std::optional<llvm::APSInt> Val =

4858 bool

IsCRegister =

false

;

4860 if

(

const DeclRefExpr

*DR = dyn_cast<DeclRefExpr>(Arg)) {

4861 if

(

const ParmVarDecl

*PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {

4862

SecondArgIsLastNamedArgument = PV == LastParam;

4864 Type

= PV->getType();

4865

ParamLoc = PV->getLocation();

4871 if

(!SecondArgIsLastNamedArgument)

4873

diag::warn_second_arg_of_va_start_not_last_named_param);

4878

if (!Context.isPromotableIntegerType(Type))

4880

if (!Type->isEnumeralType())

4882

const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();

4884

Context.typesAreCompatible(ED->getPromotionType(), Type));

4886 unsigned

Reason = 0;

4888 else if

(IsCRegister) Reason = 2;

4889 Diag

(Arg->

getBeginLoc

(), diag::warn_va_start_type_is_undefined) << Reason;

4890 Diag

(ParamLoc, diag::note_parameter_type) <<

Type

;

4896bool

Sema::BuiltinVAStartARMMicrosoft(

CallExpr

*

Call

) {

4897 auto

IsSuitablyTypedFormatArgument = [

this

](

const Expr

*Arg) ->

bool

{

4917 if

(

Call

->getNumArgs() < 3)

4919

diag::err_typecheck_call_too_few_args_at_least)

4920

<< 0

<< 3 <<

Call

->getNumArgs()

4933 const Expr

*Arg1 =

Call

->getArg(1)->IgnoreParens();

4936 const Expr

*Arg2 =

Call

->getArg(2)->IgnoreParens();

4941 if

(!Arg1Ty->

isPointerType

() || !IsSuitablyTypedFormatArgument(Arg1))

4942 Diag

(Arg1->

getBeginLoc

(), diag::err_typecheck_convert_incompatible)

4943

<< Arg1->

getType

() << ConstCharPtrTy << 1

4946

<< 2 << Arg1->

getType

() << ConstCharPtrTy;

4950 Diag

(Arg2->

getBeginLoc

(), diag::err_typecheck_convert_incompatible)

4951

<< Arg2->

getType

() << SizeTy << 1

4954

<< 3 << Arg2->

getType

() << SizeTy;

4959bool

Sema::BuiltinUnorderedCompare(

CallExpr

*TheCall,

unsigned

BuiltinID) {

4963 if

(BuiltinID == Builtin::BI__builtin_isunordered &&

4991

diag::err_typecheck_call_invalid_ordered_compare)

4999bool

Sema::BuiltinFPClassification(

CallExpr

*TheCall,

unsigned

NumArgs,

5000 unsigned

BuiltinID) {

5005 if

(FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||

5006

BuiltinID == Builtin::BI__builtin_isinf ||

5007

BuiltinID == Builtin::BI__builtin_isinf_sign))

5011 if

(FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||

5012

BuiltinID == Builtin::BI__builtin_isunordered))

5016 bool

IsFPClass = NumArgs == 2;

5019 unsigned

FPArgNo = IsFPClass ? 0 : NumArgs - 1;

5023 for

(

unsigned

i = 0; i < FPArgNo; ++i) {

5050

OrigArg = Res.

get

();

5056

OrigArg = Res.

get

();

5058

TheCall->

setArg

(FPArgNo, OrigArg);

5072

diag::err_typecheck_call_invalid_unary_fp)

5084 if

(!VectorResultTy.

isNull

())

5085

ResultTy = VectorResultTy;

5094bool

Sema::BuiltinComplex(

CallExpr

*TheCall) {

5099 for

(

unsigned

I = 0; I != 2; ++I) {

5110 return Diag

(Arg->

getBeginLoc

(), diag::err_typecheck_call_requires_real_fp)

5117

TheCall->

setArg

(I, Converted.

get

());

5129

diag::err_typecheck_call_different_arg_types)

5138 return Diag

(TheCall->

getBeginLoc

(), diag::err_invalid_complex_spec)

5141 return Diag

(TheCall->

getBeginLoc

(), diag::err_invalid_complex_spec)

5153

diag::err_typecheck_call_too_few_args_at_least)

5161 unsigned

numElements = 0;

5176 unsigned

numResElements = TheCall->

getNumArgs

() - 2;

5185

diag::err_vec_builtin_incompatible_vector)

5192

diag::err_vec_builtin_incompatible_vector)

5197

}

else if

(numElements != numResElements) {

5204 for

(

unsigned

i = 2; i < TheCall->

getNumArgs

(); i++) {

5209

std::optional<llvm::APSInt>

Result

;

5212

diag::err_shufflevector_nonconstant_argument)

5219 if

(

Result

->getActiveBits() > 64 ||

5220 Result

->getZExtValue() >= numElements * 2)

5222

diag::err_shufflevector_argument_too_large)

5228 for

(

unsigned

i = 0, e = TheCall->

getNumArgs

(); i != e; i++) {

5229

exprs.push_back(TheCall->

getArg

(i));

5230

TheCall->

setArg

(i,

nullptr

);

5248

diag::err_convertvector_non_vector)

5251 return ExprError

(

Diag

(BuiltinLoc, diag::err_builtin_non_vector_type)

5253

<<

"__builtin_convertvector"

);

5258 if

(SrcElts != DstElts)

5260

diag::err_convertvector_incompatible_vector)

5265

BuiltinLoc, RParenLoc);

5268bool

Sema::BuiltinPrefetch(

CallExpr

*TheCall) {

5273

diag::err_typecheck_call_too_many_args_at_most)

5274

<< 0

<< 3 << NumArgs <<

0

5279 for

(

unsigned

i = 1; i != NumArgs; ++i)

5286bool

Sema::BuiltinArithmeticFence(

CallExpr

*TheCall) {

5288 return Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_target_unsupported)

5298 return Diag

(TheCall->

getEndLoc

(), diag::err_typecheck_expect_flt_or_vector)

5308bool

Sema::BuiltinAssume(

CallExpr

*TheCall) {

5315

<< cast<FunctionDecl>(TheCall->

getCalleeDecl

())->getIdentifier();

5320bool

Sema::BuiltinAllocaWithAlign(

CallExpr

*TheCall) {

5326 if

(

const auto

*UE =

5328 if

(UE->getKind() == UETT_AlignOf ||

5329

UE->getKind() == UETT_PreferredAlignOf)

5335 if

(!

Result

.isPowerOf2())

5336 return Diag

(TheCall->

getBeginLoc

(), diag::err_alignment_not_power_of_two)

5343 if

(

Result

> std::numeric_limits<int32_t>::max())

5345

<< std::numeric_limits<int32_t>::max() << Arg->

getSourceRange

();

5351bool

Sema::BuiltinAssumeAligned(

CallExpr

*TheCall) {

5362 Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_assume_aligned_invalid_arg)

5366

TheCall->

setArg

(0, FirstArgResult.

get

());

5378 if

(!

Result

.isPowerOf2())

5379 return Diag

(TheCall->

getBeginLoc

(), diag::err_alignment_not_power_of_two)

5391

TheCall->

setArg

(2, ThirdArg);

5397bool

Sema::BuiltinOSLogFormat(

CallExpr

*TheCall) {

5398 unsigned

BuiltinID =

5399

cast<FunctionDecl>(TheCall->

getCalleeDecl

())->getBuiltinID();

5400 bool

IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;

5403 unsigned

NumRequiredArgs = IsSizeCall ? 1 : 2;

5404 if

(NumArgs < NumRequiredArgs) {

5405 return Diag

(TheCall->

getEndLoc

(), diag::err_typecheck_call_too_few_args)

5406

<< 0

<< NumRequiredArgs << NumArgs

5409 if

(NumArgs >= NumRequiredArgs + 0x100) {

5411

diag::err_typecheck_call_too_many_args_at_most)

5412

<< 0

<< (NumRequiredArgs + 0xff) << NumArgs

5423 if

(Arg.isInvalid())

5425

TheCall->

setArg

(i, Arg.get());

5430 unsigned

FormatIdx = i;

5440 unsigned

FirstDataArg = i;

5441 while

(i < NumArgs) {

5448 return Diag

(Arg.

get

()->

getEndLoc

(), diag::err_os_log_argument_too_big)

5459

llvm::SmallBitVector CheckedVarArgs(NumArgs,

false

);

5461 bool Success

= CheckFormatArguments(

5478

llvm::APSInt &

Result

) {

5485

std::optional<llvm::APSInt> R;

5487 return Diag

(TheCall->

getBeginLoc

(), diag::err_constant_integer_arg_type)

5494 int

High,

bool

RangeIsError) {

5508 if

(

Result

.getSExtValue() < Low ||

Result

.getSExtValue() > High) {

5510 return Diag

(TheCall->

getBeginLoc

(), diag::err_argument_invalid_range)

5516 PDiag

(diag::warn_argument_invalid_range)

5538 return Diag

(TheCall->

getBeginLoc

(), diag::err_argument_not_multiple)

5561 return Diag

(TheCall->

getBeginLoc

(), diag::err_argument_not_power_of_2)

5566 if

(

Value

.isNegative())

5577 if

((

Value

& 0xFF) != 0)

5602 Result

.setIsUnsigned(

true

);

5607 return Diag

(TheCall->

getBeginLoc

(), diag::err_argument_not_shifted_byte)

5626 Result

.setIsUnsigned(

true

);

5634

diag::err_argument_not_shifted_byte_or_xxff)

5638bool

Sema::BuiltinLongjmp(

CallExpr

*TheCall) {

5640 return Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_longjmp_unsupported)

5651 return Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_longjmp_invalid_val)

5657bool

Sema::BuiltinSetjmp(

CallExpr

*TheCall) {

5659 return Diag

(TheCall->

getBeginLoc

(), diag::err_builtin_setjmp_unsupported)

5664bool

Sema::BuiltinCountedByRef(

CallExpr

*TheCall) {

5679

diag::err_builtin_counted_by_ref_must_be_flex_array_member)

5684

diag::err_builtin_counted_by_ref_has_side_effects)

5687 if

(

const auto

*ME = dyn_cast<MemberExpr>(Arg)) {

5688 if

(!ME->isFlexibleArrayMemberLike(

5691

diag::err_builtin_counted_by_ref_must_be_flex_array_member)

5697 const auto

*FAMDecl = cast<FieldDecl>(ME->getMemberDecl());

5705

diag::err_builtin_counted_by_ref_must_be_flex_array_member)

5715bool

Sema::CheckInvalidBuiltinCountedByRef(

const Expr

*

E

,

5716

BuiltinCountedByRefKind K) {

5719 if

(!CE || CE->

getBuiltinCallee

() != Builtin::BI__builtin_counted_by_ref)

5723 case

AssignmentKind:

5724 case

InitializerKind:

5726

diag::err_builtin_counted_by_ref_cannot_leak_reference)

5729 case

FunctionArgKind:

5731

diag::err_builtin_counted_by_ref_cannot_leak_reference)

5736

diag::err_builtin_counted_by_ref_cannot_leak_reference)

5739 case

ArraySubscriptKind:

5740 Diag

(

E

->

getExprLoc

(), diag::err_builtin_counted_by_ref_invalid_use)

5743 case

BinaryExprKind:

5744 Diag

(

E

->

getExprLoc

(), diag::err_builtin_counted_by_ref_invalid_use)

5754class

UncoveredArgHandler {

5755 enum

{

Unknown

= -1, AllCovered = -2 };

5757 signed

FirstUncoveredArg =

Unknown

;

5761

UncoveredArgHandler() =

default

;

5763 bool

hasUncoveredArg()

const

{

5764 return

(FirstUncoveredArg >= 0);

5767 unsigned

getUncoveredArg()

const

{

5768

assert(hasUncoveredArg() &&

"no uncovered argument"

);

5769 return

FirstUncoveredArg;

5772 void

setAllCovered() {

5775

DiagnosticExprs.clear();

5776

FirstUncoveredArg = AllCovered;

5779 void Update

(

signed

NewFirstUncoveredArg,

const Expr

*StrExpr) {

5780

assert(NewFirstUncoveredArg >= 0 &&

"Outside range"

);

5783 if

(FirstUncoveredArg == AllCovered)

5788 if

(NewFirstUncoveredArg == FirstUncoveredArg)

5789

DiagnosticExprs.push_back(StrExpr);

5790 else if

(NewFirstUncoveredArg > FirstUncoveredArg) {

5791

DiagnosticExprs.clear();

5792

DiagnosticExprs.push_back(StrExpr);

5793

FirstUncoveredArg = NewFirstUncoveredArg;

5797 void

Diagnose(

Sema

&S,

bool

IsFunctionCall,

const Expr

*ArgExpr);

5800enum

StringLiteralCheckType {

5802

SLCT_UncheckedLiteral,

5808static void sumOffsets

(llvm::APSInt &Offset, llvm::APSInt Addend,

5810 bool

AddendIsRight) {

5811 unsigned

BitWidth = Offset.getBitWidth();

5812 unsigned

AddendBitWidth = Addend.getBitWidth();

5814 if

(Addend.isUnsigned()) {

5815

Addend = Addend.zext(++AddendBitWidth);

5816

Addend.setIsSigned(

true

);

5819 if

(AddendBitWidth > BitWidth) {

5820

Offset = Offset.sext(AddendBitWidth);

5821

BitWidth = AddendBitWidth;

5822

}

else if

(BitWidth > AddendBitWidth) {

5823

Addend = Addend.sext(BitWidth);

5827

llvm::APSInt ResOffset = Offset;

5828 if

(BinOpKind == BO_Add)

5829

ResOffset = Offset.sadd_ov(Addend, Ov);

5831

assert(AddendIsRight && BinOpKind == BO_Sub &&

5832 "operator must be add or sub with addend on the right"

);

5833

ResOffset = Offset.ssub_ov(Addend, Ov);

5839

assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&

5840 "index (intermediate) result too big"

);

5841

Offset = Offset.sext(2 * BitWidth);

5842 sumOffsets

(Offset, Addend, BinOpKind, AddendIsRight);

5854class

FormatStringLiteral {

5859

FormatStringLiteral(

const StringLiteral

*fexpr, int64_t Offset = 0)

5860

: FExpr(fexpr), Offset(Offset) {}

5862

StringRef getString()

const

{

5863 return

FExpr->

getString

().drop_front(Offset);

5866 unsigned

getByteLength()

const

{

5867 return

FExpr->

getByteLength

() - getCharByteWidth() * Offset;

5870 unsigned

getLength()

const

{

return

FExpr->

getLength

() - Offset; }

5877 bool

isAscii()

const

{

return

FExpr->

isOrdinary

(); }

5878 bool

isWide()

const

{

return

FExpr->

isWide

(); }

5879 bool

isUTF8()

const

{

return

FExpr->

isUTF8

(); }

5880 bool

isUTF16()

const

{

return

FExpr->

isUTF16

(); }

5881 bool

isUTF32()

const

{

return

FExpr->

isUTF32

(); }

5882 bool

isPascal()

const

{

return

FExpr->

isPascal

(); }

5887 unsigned

*StartTokenByteOffset =

nullptr

)

const

{

5889

StartToken, StartTokenByteOffset);

5902 Sema

&S,

const

FormatStringLiteral *FExpr,

const Expr

*OrigFormatExpr,

5906

llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,

5907 bool

IgnoreStringsWithoutSpecifiers);

5916static

StringLiteralCheckType

5921

llvm::SmallBitVector &CheckedVarArgs,

5922

UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,

5923 bool

IgnoreStringsWithoutSpecifiers =

false

) {

5925 return

SLCT_NotALiteral;

5927

assert(Offset.isSigned() &&

"invalid offset"

);

5930 return

SLCT_NotALiteral;

5939 return

SLCT_UncheckedLiteral;

5942 case

Stmt::InitListExprClass:

5946 Type

, CallType,

false

,

5947

CheckedVarArgs, UncoveredArg, Offset,

5948

IgnoreStringsWithoutSpecifiers);

5950 return

SLCT_NotALiteral;

5951 case

Stmt::BinaryConditionalOperatorClass:

5952 case

Stmt::ConditionalOperatorClass: {

5956

cast<AbstractConditionalOperator>(

E

);

5961 bool

CheckLeft =

true

, CheckRight =

true

;

5964 if

(

C

->getCond()->EvaluateAsBooleanCondition(

5967

CheckRight =

false

;

5976

StringLiteralCheckType Left;

5978

Left = SLCT_UncheckedLiteral;

5981

firstDataArg,

Type

, CallType, InFunctionCall,

5982

CheckedVarArgs, UncoveredArg, Offset,

5983

IgnoreStringsWithoutSpecifiers);

5984 if

(Left == SLCT_NotALiteral || !CheckRight) {

5990

S,

C

->getFalseExpr(), Args, APK, format_idx, firstDataArg,

Type

,

5991

CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,

5992

IgnoreStringsWithoutSpecifiers);

5994 return

(CheckLeft && Left < Right) ? Left : Right;

5997 case

Stmt::ImplicitCastExprClass:

5998 E

= cast<ImplicitCastExpr>(

E

)->getSubExpr();

6001 case

Stmt::OpaqueValueExprClass:

6002 if

(

const Expr

*src = cast<OpaqueValueExpr>(

E

)->getSourceExpr()) {

6006 return

SLCT_NotALiteral;

6008 case

Stmt::PredefinedExprClass:

6012 return

SLCT_UncheckedLiteral;

6014 case

Stmt::DeclRefExprClass: {

6020 bool

isConstant =

false

;

6024

isConstant = AT->getElementType().isConstant(S.

Context

);

6026

isConstant =

T

.isConstant(S.

Context

) &&

6031

isConstant =

T

.isConstant(S.

Context

);

6035 if

(

const Expr

*

Init

= VD->getAnyInitializer()) {

6038 if

(InitList->isStringLiteralInit())

6039 Init

= InitList->getInit(0)->IgnoreParenImpCasts();

6042

S,

Init

, Args, APK, format_idx, firstDataArg,

Type

, CallType,

6043 false

, CheckedVarArgs, UncoveredArg, Offset);

6084 if

(

const auto

*PV = dyn_cast<ParmVarDecl>(VD)) {

6085 if

(

const auto

*

D

= dyn_cast<Decl>(PV->getDeclContext())) {

6087 bool

IsCXXMember =

false

;

6088 if

(

const auto

*MD = dyn_cast<CXXMethodDecl>(

D

))

6089

IsCXXMember = MD->isInstance();

6091 bool

IsVariadic =

false

;

6093

IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();

6094 else if

(

const auto

*BD = dyn_cast<BlockDecl>(

D

))

6095

IsVariadic = BD->isVariadic();

6096 else if

(

const auto

*OMD = dyn_cast<ObjCMethodDecl>(

D

))

6097

IsVariadic = OMD->isVariadic();

6104 if

(PV->getFunctionScopeIndex() == CallerFSI.

FormatIdx

&&

6117 return

SLCT_UncheckedLiteral;

6126 return

SLCT_NotALiteral;

6129 case

Stmt::CallExprClass:

6130 case

Stmt::CXXMemberCallExprClass: {

6131 const CallExpr

*CE = cast<CallExpr>(

E

);

6133 bool

IsFirst =

true

;

6134

StringLiteralCheckType CommonResult;

6135 for

(

const auto

*FA : ND->specific_attrs<FormatArgAttr>()) {

6136 const Expr

*Arg = CE->

getArg

(FA->getFormatIdx().getASTIndex());

6138

S, Arg, Args, APK, format_idx, firstDataArg,

Type

, CallType,

6139

InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,

6140

IgnoreStringsWithoutSpecifiers);

6147 return

CommonResult;

6149 if

(

const auto

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

6151 if

(BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||

6152

BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {

6155

S, Arg, Args, APK, format_idx, firstDataArg,

Type

, CallType,

6156

InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,

6157

IgnoreStringsWithoutSpecifiers);

6163 Type

, CallType,

false

,

6164

CheckedVarArgs, UncoveredArg, Offset,

6165

IgnoreStringsWithoutSpecifiers);

6166 return

SLCT_NotALiteral;

6168 case

Stmt::ObjCMessageExprClass: {

6169 const auto

*ME = cast<ObjCMessageExpr>(

E

);

6170 if

(

const auto

*MD = ME->getMethodDecl()) {

6171 if

(

const auto

*FA = MD->getAttr<FormatArgAttr>()) {

6180 if

(MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&

6182

MD->getSelector().isKeywordSelector(

6183

{

"localizedStringForKey"

,

"value"

,

"table"

})) {

6184

IgnoreStringsWithoutSpecifiers =

true

;

6187 const Expr

*Arg = ME->getArg(FA->getFormatIdx().getASTIndex());

6189

S, Arg, Args, APK, format_idx, firstDataArg,

Type

, CallType,

6190

InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,

6191

IgnoreStringsWithoutSpecifiers);

6195 return

SLCT_NotALiteral;

6197 case

Stmt::ObjCStringLiteralClass:

6198 case

Stmt::StringLiteralClass: {

6204

StrE = cast<StringLiteral>(

E

);

6207 if

(Offset.isNegative() || Offset > StrE->

getLength

()) {

6210 return

SLCT_NotALiteral;

6212

FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());

6214

InFunctionCall, CallType, CheckedVarArgs, UncoveredArg,

6215

IgnoreStringsWithoutSpecifiers);

6216 return

SLCT_CheckedLiteral;

6219 return

SLCT_NotALiteral;

6221 case

Stmt::BinaryOperatorClass: {

6235 if

(LIsInt != RIsInt) {

6239 if

(BinOpKind == BO_Add) {

6252 return

SLCT_NotALiteral;

6254 case

Stmt::UnaryOperatorClass: {

6256 auto

ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->

getSubExpr

());

6257 if

(UnaOp->

getOpcode

() == UO_AddrOf && ASE) {

6259 if

(ASE->getRHS()->EvaluateAsInt(IndexResult, S.

Context

,

6269 return

SLCT_NotALiteral;

6273 return

SLCT_NotALiteral;

6284 const auto

*LVE =

Result

.Val.getLValueBase().dyn_cast<

const Expr

*>();

6285 if

(isa_and_nonnull<StringLiteral>(LVE))

6292 return

llvm::StringSwitch<FormatStringType>(Format->getType()->getName())

6294

.Cases(

"printf"

,

"printf0"

,

"syslog"

,

FST_Printf

)

6298

.Cases(

"kprintf"

,

"cmn_err"

,

"vcmn_err"

,

"zcmn_err"

,

FST_Kprintf

)

6305bool

Sema::CheckFormatArguments(

const

FormatAttr *Format,

6309

llvm::SmallBitVector &CheckedVarArgs) {

6310

FormatStringInfo FSI;

6313 return

CheckFormatArguments(Args, FSI.ArgPassingKind, FSI.FormatIdx,

6315

CallType,

Loc

,

Range

, CheckedVarArgs);

6321 unsigned

format_idx,

unsigned

firstDataArg,

6322

FormatStringType

Type

,

6325

llvm::SmallBitVector &CheckedVarArgs) {

6327 if

(format_idx >= Args.size()) {

6328 Diag

(

Loc

, diag::warn_missing_format_string) <<

Range

;

6332 const Expr

*OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();

6346

UncoveredArgHandler UncoveredArg;

6348

*

this

, OrigFormatExpr, Args, APK, format_idx, firstDataArg,

Type

,

6350 true

, CheckedVarArgs, UncoveredArg,

6351

llvm::APSInt(64,

false

) = 0);

6354 if

(UncoveredArg.hasUncoveredArg()) {

6355 unsigned

ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;

6356

assert(ArgIdx < Args.size() &&

"ArgIdx outside bounds"

);

6357

UncoveredArg.Diagnose(*

this

,

true

, Args[ArgIdx]);

6360 if

(CT != SLCT_NotALiteral)

6362 return

CT == SLCT_CheckedLiteral;

6379 if

(Args.size() == firstDataArg) {

6380 Diag

(FormatLoc, diag::warn_format_nonliteral_noargs)

6389 Diag

(FormatLoc, diag::note_format_security_fixit)

6393 Diag

(FormatLoc, diag::note_format_security_fixit)

6398 Diag

(FormatLoc, diag::warn_format_nonliteral)

6409 const

FormatStringLiteral *FExpr;

6410 const Expr

*OrigFormatExpr;

6412 const unsigned

FirstDataArg;

6413 const unsigned

NumDataArgs;

6418

llvm::SmallBitVector CoveredArgs;

6419 bool

usesPositionalArgs =

false

;

6420 bool

atFirstArg =

true

;

6421 bool

inFunctionCall;

6423

llvm::SmallBitVector &CheckedVarArgs;

6424

UncoveredArgHandler &UncoveredArg;

6427

CheckFormatHandler(

Sema

&

s

,

const

FormatStringLiteral *fexpr,

6428 const Expr

*origFormatExpr,

6430 unsigned

numDataArgs,

const char

*beg,

6434

llvm::SmallBitVector &CheckedVarArgs,

6435

UncoveredArgHandler &UncoveredArg)

6436

: S(

s

), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(

type

),

6437

FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),

6438

ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),

6439

inFunctionCall(inFunctionCall), CallType(callType),

6440

CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {

6441

CoveredArgs.resize(numDataArgs);

6442

CoveredArgs.reset();

6445 void

DoneProcessing();

6447 void

HandleIncompleteSpecifier(

const char

*startSpecifier,

6448 unsigned

specifierLen)

override

;

6450 void

HandleInvalidLengthModifier(

6453 const char

*startSpecifier,

unsigned

specifierLen,

6456 void

HandleNonStandardLengthModifier(

6458 const char

*startSpecifier,

unsigned

specifierLen);

6460 void

HandleNonStandardConversionSpecifier(

6462 const char

*startSpecifier,

unsigned

specifierLen);

6464 void

HandlePosition(

const char

*startPos,

unsigned

posLen)

override

;

6466 void

HandleInvalidPosition(

const char

*startSpecifier,

6467 unsigned

specifierLen,

6470 void

HandleZeroPosition(

const char

*startPos,

unsigned

posLen)

override

;

6472 void

HandleNullChar(

const char

*nullCharacter)

override

;

6474 template

<

typename

Range>

6476

EmitFormatDiagnostic(

Sema

&S,

bool

inFunctionCall,

const Expr

*ArgumentExpr,

6478 bool

IsStringLocation,

Range

StringRange,

6483 const char

*startSpec,

6484 unsigned

specifierLen,

6485 const char

*csStart,

unsigned

csLen);

6488 const char

*startSpec,

6489 unsigned

specifierLen);

6493 unsigned

specifierLen);

6496 const Expr

*getDataArg(

unsigned

i)

const

;

6500 const char

*startSpecifier,

unsigned

specifierLen,

6503 template

<

typename

Range>

6505 bool

IsStringLocation,

Range

StringRange,

6511SourceRange

CheckFormatHandler::getFormatStringRange() {

6516

getSpecifierRange(

const char

*startSpecifier,

unsigned

specifierLen) {

6518 SourceLocation

End = getLocationOfByte(startSpecifier + specifierLen - 1);

6521

End = End.getLocWithOffset(1);

6526SourceLocation

CheckFormatHandler::getLocationOfByte(

const char

*x) {

6531void

CheckFormatHandler::HandleIncompleteSpecifier(

const char

*startSpecifier,

6532 unsigned

specifierLen){

6533

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_incomplete_specifier),

6534

getLocationOfByte(startSpecifier),

6536

getSpecifierRange(startSpecifier, specifierLen));

6539void

CheckFormatHandler::HandleInvalidLengthModifier(

6542 const char

*startSpecifier,

unsigned

specifierLen,

unsigned

DiagID) {

6543 using namespace

analyze_format_string;

6545 const

LengthModifier &LM = FS.getLengthModifier();

6546 CharSourceRange

LMRange = getSpecifierRange(LM.getStart(), LM.getLength());

6549

std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();

6551

EmitFormatDiagnostic(S.

PDiag

(DiagID) << LM.toString() << CS.

toString

(),

6552

getLocationOfByte(LM.getStart()),

6554

getSpecifierRange(startSpecifier, specifierLen));

6556

S.

Diag

(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)

6557

<< FixedLM->toString()

6562 if

(DiagID == diag::warn_format_nonsensical_length)

6565

EmitFormatDiagnostic(S.

PDiag

(DiagID) << LM.toString() << CS.

toString

(),

6566

getLocationOfByte(LM.getStart()),

6568

getSpecifierRange(startSpecifier, specifierLen),

6573void

CheckFormatHandler::HandleNonStandardLengthModifier(

6575 const char

*startSpecifier,

unsigned

specifierLen) {

6576 using namespace

analyze_format_string;

6578 const

LengthModifier &LM = FS.getLengthModifier();

6579 CharSourceRange

LMRange = getSpecifierRange(LM.getStart(), LM.getLength());

6582

std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();

6584

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_non_standard)

6585

<< LM.toString() << 0,

6586

getLocationOfByte(LM.getStart()),

6588

getSpecifierRange(startSpecifier, specifierLen));

6590

S.

Diag

(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)

6591

<< FixedLM->toString()

6595

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_non_standard)

6596

<< LM.toString() << 0,

6597

getLocationOfByte(LM.getStart()),

6599

getSpecifierRange(startSpecifier, specifierLen));

6603void

CheckFormatHandler::HandleNonStandardConversionSpecifier(

6605 const char

*startSpecifier,

unsigned

specifierLen) {

6606 using namespace

analyze_format_string;

6611

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_non_standard)

6613

getLocationOfByte(CS.

getStart

()),

6615

getSpecifierRange(startSpecifier, specifierLen));

6618

S.

Diag

(getLocationOfByte(CS.

getStart

()), diag::note_format_fix_specifier)

6619

<< FixedCS->toString()

6622

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_non_standard)

6624

getLocationOfByte(CS.

getStart

()),

6626

getSpecifierRange(startSpecifier, specifierLen));

6630void

CheckFormatHandler::HandlePosition(

const char

*startPos,

6633

diag::warn_format_non_standard_positional_arg,

SourceLocation

()))

6634

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_non_standard_positional_arg),

6635

getLocationOfByte(startPos),

6637

getSpecifierRange(startPos, posLen));

6640void

CheckFormatHandler::HandleInvalidPosition(

6641 const char

*startSpecifier,

unsigned

specifierLen,

6644

diag::warn_format_invalid_positional_specifier,

SourceLocation

()))

6645

EmitFormatDiagnostic(

6646

S.

PDiag

(diag::warn_format_invalid_positional_specifier) << (

unsigned

)p,

6647

getLocationOfByte(startSpecifier),

true

,

6648

getSpecifierRange(startSpecifier, specifierLen));

6651void

CheckFormatHandler::HandleZeroPosition(

const char

*startPos,

6655

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_zero_positional_specifier),

6656

getLocationOfByte(startPos),

6658

getSpecifierRange(startPos, posLen));

6661void

CheckFormatHandler::HandleNullChar(

const char

*nullCharacter) {

6662 if

(!isa<ObjCStringLiteral>(OrigFormatExpr)) {

6664

EmitFormatDiagnostic(

6665

S.

PDiag

(diag::warn_printf_format_string_contains_null_char),

6666

getLocationOfByte(nullCharacter),

true

,

6667

getFormatStringRange());

6673const Expr

*CheckFormatHandler::getDataArg(

unsigned

i)

const

{

6674 return

Args[FirstDataArg + i];

6677void

CheckFormatHandler::DoneProcessing() {

6683 signed

notCoveredArg = CoveredArgs.find_first();

6684 if

(notCoveredArg >= 0) {

6685

assert((

unsigned

)notCoveredArg < NumDataArgs);

6686

UncoveredArg.Update(notCoveredArg, OrigFormatExpr);

6688

UncoveredArg.setAllCovered();

6693void

UncoveredArgHandler::Diagnose(

Sema

&S,

bool

IsFunctionCall,

6694 const Expr

*ArgExpr) {

6695

assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&

6707 for

(

auto E

: DiagnosticExprs)

6710

CheckFormatHandler::EmitFormatDiagnostic(

6711

S, IsFunctionCall, DiagnosticExprs[0],

6712

PDiag,

Loc

,

false

,

6717

CheckFormatHandler::HandleInvalidConversionSpecifier(

unsigned

argIndex,

6719 const char

*startSpec,

6720 unsigned

specifierLen,

6721 const char

*csStart,

6723 bool

keepGoing =

true

;

6724 if

(argIndex < NumDataArgs) {

6727

CoveredArgs.set(argIndex);

6743

std::string CodePointStr;

6744 if

(!llvm::sys::locale::isPrint(*csStart)) {

6745

llvm::UTF32 CodePoint;

6746 const

llvm::UTF8 **B =

reinterpret_cast<const

llvm::UTF8 **

>

(&csStart);

6747 const

llvm::UTF8 *

E

=

6748 reinterpret_cast<const

llvm::UTF8 *

>

(csStart + csLen);

6749

llvm::ConversionResult

Result

=

6750

llvm::convertUTF8Sequence(B,

E

, &CodePoint, llvm::strictConversion);

6752 if

(

Result

!= llvm::conversionOK) {

6753 unsigned char

FirstChar = *csStart;

6754

CodePoint = (llvm::UTF32)FirstChar;

6757

llvm::raw_string_ostream OS(CodePointStr);

6758 if

(CodePoint < 256)

6759

OS <<

"\\x"

<< llvm::format(

"%02x"

, CodePoint);

6760 else if

(CodePoint <= 0xFFFF)

6761

OS <<

"\\u"

<< llvm::format(

"%04x"

, CodePoint);

6763

OS <<

"\\U"

<< llvm::format(

"%08x"

, CodePoint);

6767

EmitFormatDiagnostic(

6768

S.

PDiag

(diag::warn_format_invalid_conversion) << Specifier,

Loc

,

6769 true

, getSpecifierRange(startSpec, specifierLen));

6776 const char

*startSpec,

6777 unsigned

specifierLen) {

6778

EmitFormatDiagnostic(

6779

S.

PDiag

(diag::warn_format_mix_positional_nonpositional_args),

6780 Loc

,

true

, getSpecifierRange(startSpec, specifierLen));

6784

CheckFormatHandler::CheckNumArgs(

6787 const char

*startSpecifier,

unsigned

specifierLen,

unsigned

argIndex) {

6789 if

(argIndex >= NumDataArgs) {

6791

? (S.

PDiag

(diag::warn_printf_positional_arg_exceeds_data_args)

6792

<< (argIndex+1) << NumDataArgs)

6793

: S.

PDiag

(diag::warn_printf_insufficient_data_args);

6794

EmitFormatDiagnostic(

6795

PDiag, getLocationOfByte(CS.

getStart

()),

true

,

6796

getSpecifierRange(startSpecifier, specifierLen));

6800

UncoveredArg.setAllCovered();

6806template

<

typename

Range>

6809 bool

IsStringLocation,

6812

EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,

6813 Loc

, IsStringLocation, StringRange, FixIt);

6843template

<

typename

Range>

6844void

CheckFormatHandler::EmitFormatDiagnostic(

6845 Sema

&S,

bool

InFunctionCall,

const Expr

*ArgumentExpr,

6848 if

(InFunctionCall) {

6857

S.

Diag

(IsStringLocation ?

Loc

: StringRange.getBegin(),

6858

diag::note_format_string_defined);

6860 Note

<< StringRange;

6869class

CheckPrintfHandler :

public

CheckFormatHandler {

6871

CheckPrintfHandler(

Sema

&

s

,

const

FormatStringLiteral *fexpr,

6872 const Expr

*origFormatExpr,

6874 unsigned

numDataArgs,

bool

isObjC,

const char

*beg,

6878

llvm::SmallBitVector &CheckedVarArgs,

6879

UncoveredArgHandler &UncoveredArg)

6880

: CheckFormatHandler(

s

, fexpr, origFormatExpr,

type

, firstDataArg,

6881

numDataArgs, beg, APK, Args, formatIdx,

6882

inFunctionCall, CallType, CheckedVarArgs,

6888 bool

allowsObjCArg()

const

{

6893 bool

HandleInvalidPrintfConversionSpecifier(

6895 const char

*startSpecifier,

6896 unsigned

specifierLen)

override

;

6898 void

handleInvalidMaskType(StringRef MaskType)

override

;

6901 const char

*startSpecifier,

unsigned

specifierLen,

6904 const char

*StartSpecifier,

6905 unsigned

SpecifierLen,

6909 const char

*startSpecifier,

unsigned

specifierLen);

6913 const char

*startSpecifier,

unsigned

specifierLen);

6916 const char

*startSpecifier,

unsigned

specifierLen);

6920 const char

*startSpecifier,

unsigned

specifierLen);

6924 void

HandleEmptyObjCModifierFlag(

const char

*startFlag,

6925 unsigned

flagLen)

override

;

6927 void

HandleInvalidObjCModifierFlag(

const char

*startFlag,

6928 unsigned

flagLen)

override

;

6930 void

HandleObjCFlagsWithNonObjCConversion(

const char

*flagsStart,

6931 const char

*flagsEnd,

6932 const char

*conversionPosition)

6938bool

CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(

6940 const char

*startSpecifier,

6941 unsigned

specifierLen) {

6943

FS.getConversionSpecifier();

6945 return

HandleInvalidConversionSpecifier(FS.getArgIndex(),

6946

getLocationOfByte(CS.

getStart

()),

6947

startSpecifier, specifierLen,

6951void

CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {

6952

S.

Diag

(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);

6955bool

CheckPrintfHandler::HandleAmount(

6957 const char

*startSpecifier,

unsigned

specifierLen) {

6961 if

(argIndex >= NumDataArgs) {

6962

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_asterisk_missing_arg)

6964

getLocationOfByte(Amt.

getStart

()),

6966

getSpecifierRange(startSpecifier, specifierLen));

6976

CoveredArgs.set(argIndex);

6977 const Expr

*Arg = getDataArg(argIndex);

6987

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_asterisk_wrong_type)

6990

getLocationOfByte(Amt.

getStart

()),

6992

getSpecifierRange(startSpecifier, specifierLen));

7002void

CheckPrintfHandler::HandleInvalidAmount(

7006 const char

*startSpecifier,

7007 unsigned

specifierLen) {

7009

FS.getConversionSpecifier();

7017

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_nonsensical_optional_amount)

7019

getLocationOfByte(Amt.

getStart

()),

7021

getSpecifierRange(startSpecifier, specifierLen),

7027 const char

*startSpecifier,

7028 unsigned

specifierLen) {

7031

FS.getConversionSpecifier();

7032

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_nonsensical_flag)

7036

getSpecifierRange(startSpecifier, specifierLen),

7041void

CheckPrintfHandler::HandleIgnoredFlag(

7045 const char

*startSpecifier,

7046 unsigned

specifierLen) {

7048

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_ignored_flag)

7052

getSpecifierRange(startSpecifier, specifierLen),

7054

getSpecifierRange(ignoredFlag.

getPosition

(), 1)));

7057void

CheckPrintfHandler::HandleEmptyObjCModifierFlag(

const char

*startFlag,

7060

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_empty_objc_flag),

7061

getLocationOfByte(startFlag),

7063

getSpecifierRange(startFlag, flagLen));

7066void

CheckPrintfHandler::HandleInvalidObjCModifierFlag(

const char

*startFlag,

7069 auto Range

= getSpecifierRange(startFlag, flagLen);

7070

StringRef flag(startFlag, flagLen);

7071

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_invalid_objc_flag) << flag,

7072

getLocationOfByte(startFlag),

7077void

CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(

7078 const char

*flagsStart,

const char

*flagsEnd,

const char

*conversionPosition) {

7080 auto Range

= getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);

7081 auto

diag = diag::warn_printf_ObjCflags_without_ObjCConversion;

7082

EmitFormatDiagnostic(S.

PDiag

(diag) << StringRef(conversionPosition, 1),

7083

getLocationOfByte(conversionPosition),

7091template

<

typename

MemberKind>

7112 if

(MemberKind *FK = dyn_cast<MemberKind>(

decl

))

7126

CXXRecordMembersNamed<CXXMethodDecl>(

"c_str"

, *

this

,

E

->

getType

());

7127 for

(MethodSet::iterator MI = Results.begin(), ME = Results.end();

7129 if

((*MI)->getMinRequiredArguments() == 0)

7137bool

CheckPrintfHandler::checkForCStrMembers(

7142

CXXRecordMembersNamed<CXXMethodDecl>(

"c_str"

, S,

E

->

getType

());

7144 for

(MethodSet::iterator MI = Results.begin(), ME = Results.end();

7160bool

CheckPrintfHandler::HandlePrintfSpecifier(

7163 using namespace

analyze_format_string;

7164 using namespace

analyze_printf;

7166 const

PrintfConversionSpecifier &CS = FS.getConversionSpecifier();

7168 if

(FS.consumesDataArgument()) {

7170

atFirstArg =

false

;

7171

usesPositionalArgs = FS.usesPositionalArg();

7173 else if

(usesPositionalArgs != FS.usesPositionalArg()) {

7174

HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),

7175

startSpecifier, specifierLen);

7182 if

(!HandleAmount(FS.getFieldWidth(),

0,

7183

startSpecifier, specifierLen)) {

7187 if

(!HandleAmount(FS.getPrecision(),

1,

7188

startSpecifier, specifierLen)) {

7192 if

(!CS.consumesDataArgument()) {

7199 unsigned

argIndex = FS.getArgIndex();

7200 if

(argIndex < NumDataArgs) {

7204

CoveredArgs.set(argIndex);

7208 if

(CS.getKind() == ConversionSpecifier::FreeBSDbArg ||

7209

CS.getKind() == ConversionSpecifier::FreeBSDDArg) {

7211 if

(!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))

7215

CoveredArgs.set(argIndex + 1);

7218 const Expr

*Ex = getDataArg(argIndex);

7220

(CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?

7223

EmitFormatDiagnostic(

7224

S.

PDiag

(diag::warn_format_conversion_argument_type_mismatch)

7228

getSpecifierRange(startSpecifier, specifierLen));

7231

Ex = getDataArg(argIndex + 1);

7234

EmitFormatDiagnostic(

7235

S.

PDiag

(diag::warn_format_conversion_argument_type_mismatch)

7239

getSpecifierRange(startSpecifier, specifierLen));

7246 if

(!allowsObjCArg() && CS.isObjCArg()) {

7247 return

HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,

7252 if

(FSType !=

Sema::FST_OSLog

&& CS.getKind() == ConversionSpecifier::PArg) {

7253 return

HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,

7258 if

(FSType ==

Sema::FST_OSLog

&& CS.getKind() == ConversionSpecifier::nArg) {

7259

EmitFormatDiagnostic(S.

PDiag

(diag::warn_os_log_format_narg),

7260

getLocationOfByte(CS.getStart()),

7262

getSpecifierRange(startSpecifier, specifierLen));

7269

(CS.getKind() == ConversionSpecifier::PArg ||

7270

CS.getKind() == ConversionSpecifier::sArg ||

7271

CS.getKind() == ConversionSpecifier::ObjCObjArg)) {

7272 return

HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,

7278 if

(FS.isPublic().isSet()) {

7279

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_invalid_annotation)

7281

getLocationOfByte(FS.isPublic().getPosition()),

7283

getSpecifierRange(startSpecifier, specifierLen));

7285 if

(FS.isPrivate().isSet()) {

7286

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_invalid_annotation)

7288

getLocationOfByte(FS.isPrivate().getPosition()),

7290

getSpecifierRange(startSpecifier, specifierLen));

7294 const

llvm::Triple &Triple =

Target

.getTriple();

7295 if

(CS.getKind() == ConversionSpecifier::nArg &&

7296

(Triple.isAndroid() || Triple.isOSFuchsia())) {

7297

EmitFormatDiagnostic(S.

PDiag

(diag::warn_printf_narg_not_supported),

7298

getLocationOfByte(CS.getStart()),

7300

getSpecifierRange(startSpecifier, specifierLen));

7304 if

(!FS.hasValidFieldWidth()) {

7305

HandleInvalidAmount(FS, FS.getFieldWidth(),

0,

7306

startSpecifier, specifierLen);

7310 if

(!FS.hasValidPrecision()) {

7311

HandleInvalidAmount(FS, FS.getPrecision(),

1,

7312

startSpecifier, specifierLen);

7316 if

(CS.getKind() == ConversionSpecifier::PArg &&

7317

FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {

7318

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_P_no_precision),

7319

getLocationOfByte(startSpecifier),

7321

getSpecifierRange(startSpecifier, specifierLen));

7325 if

(!FS.hasValidThousandsGroupingPrefix())

7326

HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);

7327 if

(!FS.hasValidLeadingZeros())

7328

HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);

7329 if

(!FS.hasValidPlusPrefix())

7330

HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);

7331 if

(!FS.hasValidSpacePrefix())

7332

HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);

7333 if

(!FS.hasValidAlternativeForm())

7334

HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);

7335 if

(!FS.hasValidLeftJustified())

7336

HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);

7339 if

(FS.hasSpacePrefix() && FS.hasPlusPrefix())

7340

HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),

7341

startSpecifier, specifierLen);

7342 if

(FS.hasLeadingZeros() && FS.isLeftJustified())

7343

HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),

7344

startSpecifier, specifierLen);

7349

HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,

7350

diag::warn_format_nonsensical_length);

7351 else if

(!FS.hasStandardLengthModifier())

7352

HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);

7353 else if

(!FS.hasStandardLengthConversionCombination())

7354

HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,

7355

diag::warn_format_non_standard_conversion_spec);

7357 if

(!FS.hasStandardConversionSpecifier(S.

getLangOpts

()))

7358

HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);

7364 if

(!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))

7367 const Expr

*Arg = getDataArg(argIndex);

7371 return

checkFormatExpr(FS, startSpecifier, specifierLen, Arg);

7383 case

Stmt::ArraySubscriptExprClass:

7384 case

Stmt::CallExprClass:

7385 case

Stmt::CharacterLiteralClass:

7386 case

Stmt::CXXBoolLiteralExprClass:

7387 case

Stmt::DeclRefExprClass:

7388 case

Stmt::FloatingLiteralClass:

7389 case

Stmt::IntegerLiteralClass:

7390 case

Stmt::MemberExprClass:

7391 case

Stmt::ObjCArrayLiteralClass:

7392 case

Stmt::ObjCBoolLiteralExprClass:

7393 case

Stmt::ObjCBoxedExprClass:

7394 case

Stmt::ObjCDictionaryLiteralClass:

7395 case

Stmt::ObjCEncodeExprClass:

7396 case

Stmt::ObjCIvarRefExprClass:

7397 case

Stmt::ObjCMessageExprClass:

7398 case

Stmt::ObjCPropertyRefExprClass:

7399 case

Stmt::ObjCStringLiteralClass:

7400 case

Stmt::ObjCSubscriptRefExprClass:

7401 case

Stmt::ParenExprClass:

7402 case

Stmt::StringLiteralClass:

7403 case

Stmt::UnaryOperatorClass:

7410static

std::pair<QualType, StringRef>

7417

StringRef Name = UserTy->getDecl()->getName();

7418 QualType

CastTy = llvm::StringSwitch<QualType>(Name)

7422

.Case(

"SInt32"

, Context.

IntTy

)

7427 return

std::make_pair(CastTy, Name);

7429

TyTy = UserTy->desugar();

7433 if

(

const ParenExpr

*PE = dyn_cast<ParenExpr>(

E

))

7435

PE->getSubExpr()->getType(),

7444

StringRef TrueName, FalseName;

7446

std::tie(TrueTy, TrueName) =

7448

CO->getTrueExpr()->getType(),

7450

std::tie(FalseTy, FalseName) =

7452

CO->getFalseExpr()->getType(),

7453

CO->getFalseExpr());

7455 if

(TrueTy == FalseTy)

7456 return

std::make_pair(TrueTy, TrueName);

7457 else if

(TrueTy.

isNull

())

7458 return

std::make_pair(FalseTy, FalseName);

7459 else if

(FalseTy.

isNull

())

7460 return

std::make_pair(TrueTy, TrueName);

7463 return

std::make_pair(

QualType

(), StringRef());

7482

From = VecTy->getElementType();

7484

To = VecTy->getElementType();

7496

diag::warn_format_conversion_argument_type_mismatch_signedness,

Loc

)

7505 const char

*StartSpecifier,

7506 unsigned

SpecifierLen,

7508 using namespace

analyze_format_string;

7509 using namespace

analyze_printf;

7518 while

(

const TypeOfExprType

*TET = dyn_cast<TypeOfExprType>(ExprTy)) {

7519

ExprTy = TET->getUnderlyingExpr()->getType();

7531 if

(FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&

7534

getSpecifierRange(StartSpecifier, SpecifierLen);

7536

llvm::raw_svector_ostream os(FSString);

7538

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_bool_as_character)

7546 if

(FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&

7549

getSpecifierRange(StartSpecifier, SpecifierLen);

7550

EmitFormatDiagnostic(S.

PDiag

(diag::warn_format_P_with_objc_pointer),

7555

ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;

7557

ArgType::MatchKind OrigMatch = Match;

7560 if

(Match == ArgType::Match)

7564

assert(Match != ArgType::NoMatchPromotionTypeConfusion);

7573 E

= ICE->getSubExpr();

7583 if

(OrigMatch == ArgType::NoMatchSignedness &&

7584

ImplicitMatch != ArgType::NoMatchSignedness)

7591 if

(ImplicitMatch == ArgType::Match)

7602

FS.getLengthModifier().getKind() != LengthModifier::AsChar)

7609 if

(Match == ArgType::MatchPromotion)

7610

Match = ArgType::NoMatch;

7613 if

(Match == ArgType::MatchPromotion) {

7617

ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&

7618

ImplicitMatch != ArgType::NoMatchTypeConfusion)

7620

Match = ArgType::NoMatch;

7622 if

(ImplicitMatch == ArgType::NoMatchPedantic ||

7623

ImplicitMatch == ArgType::NoMatchTypeConfusion)

7624

Match = ImplicitMatch;

7625

assert(Match != ArgType::MatchPromotion);

7628 bool

IsEnum =

false

;

7629 bool

IsScopedEnum =

false

;

7632

IntendedTy = EnumTy->getDecl()->getIntegerType();

7633 if

(EnumTy->isUnscopedEnumerationType()) {

7634

ExprTy = IntendedTy;

7639

IsScopedEnum =

true

;

7646 if

(isObjCContext() &&

7647

FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {

7657 const

llvm::APInt &

V

= IL->getValue();

7667 if

(TD->getUnderlyingType() == IntendedTy)

7675 bool

ShouldNotPrintDirectly =

false

; StringRef CastTyName;

7679 if

(!CastTy.

isNull

()) {

7683 if

(!IsScopedEnum &&

7684

(CastTyName ==

"NSInteger"

|| CastTyName ==

"NSUInteger"

) &&

7687

Match = ArgType::NoMatchPedantic;

7688

IntendedTy = CastTy;

7689

ShouldNotPrintDirectly =

true

;

7694

PrintfSpecifier fixedFS = FS;

7701

llvm::raw_svector_ostream os(buf);

7702

fixedFS.toString(os);

7704 CharSourceRange

SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);

7706 if

(IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {

7709 case

ArgType::Match:

7710 case

ArgType::MatchPromotion:

7711 case

ArgType::NoMatchPromotionTypeConfusion:

7712 case

ArgType::NoMatchSignedness:

7713

llvm_unreachable(

"expected non-matching"

);

7714 case

ArgType::NoMatchPedantic:

7715 Diag

= diag::warn_format_conversion_argument_type_mismatch_pedantic;

7717 case

ArgType::NoMatchTypeConfusion:

7718 Diag

= diag::warn_format_conversion_argument_type_mismatch_confusion;

7720 case

ArgType::NoMatch:

7721 Diag

= diag::warn_format_conversion_argument_type_mismatch;

7742

llvm::raw_svector_ostream CastFix(CastBuf);

7743

CastFix << (S.

LangOpts

.CPlusPlus ?

"static_cast<"

:

"("

);

7745

CastFix << (S.

LangOpts

.CPlusPlus ?

">"

:

")"

);

7751 if

((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)

7756 SourceRange

CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());

7778 if

(ShouldNotPrintDirectly && !IsScopedEnum) {

7784

Name = TypedefTy->getDecl()->getName();

7787 unsigned Diag

= Match == ArgType::NoMatchPedantic

7788

? diag::warn_format_argument_needs_cast_pedantic

7789

: diag::warn_format_argument_needs_cast;

7790

EmitFormatDiagnostic(S.

PDiag

(

Diag

) << Name << IntendedTy << IsEnum

7801

? diag::warn_format_conversion_argument_type_mismatch_pedantic

7802

: diag::warn_format_conversion_argument_type_mismatch;

7804

EmitFormatDiagnostic(

7816 bool

EmitTypeMismatch =

false

;

7822 case

ArgType::Match:

7823 case

ArgType::MatchPromotion:

7824 case

ArgType::NoMatchPromotionTypeConfusion:

7825 case

ArgType::NoMatchSignedness:

7826

llvm_unreachable(

"expected non-matching"

);

7827 case

ArgType::NoMatchPedantic:

7828 Diag

= diag::warn_format_conversion_argument_type_mismatch_pedantic;

7830 case

ArgType::NoMatchTypeConfusion:

7831 Diag

= diag::warn_format_conversion_argument_type_mismatch_confusion;

7833 case

ArgType::NoMatch:

7834 Diag

= diag::warn_format_conversion_argument_type_mismatch;

7838

EmitFormatDiagnostic(

7847

EmitTypeMismatch =

true

;

7849

EmitFormatDiagnostic(

7850

S.

PDiag

(diag::warn_non_pod_vararg_with_format_string)

7851

<< S.

getLangOpts

().CPlusPlus11 << ExprTy << CallType

7855

checkForCStrMembers(AT,

E

);

7861

EmitTypeMismatch =

true

;

7863

EmitFormatDiagnostic(

7864

S.

PDiag

(diag::err_cannot_pass_objc_interface_to_vararg_format)

7865

<< S.

getLangOpts

().CPlusPlus11 << ExprTy << CallType

7873

<< isa<InitListExpr>(

E

) << ExprTy << CallType

7878 if

(EmitTypeMismatch) {

7884

EmitFormatDiagnostic(

7885

S.

PDiag

(diag::warn_format_conversion_argument_type_mismatch)

7891

assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&

7892 "format string specifier index out of range"

);

7893

CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =

true

;

7903class

CheckScanfHandler :

public

CheckFormatHandler {

7905

CheckScanfHandler(

Sema

&

s

,

const

FormatStringLiteral *fexpr,

7907 unsigned

firstDataArg,

unsigned

numDataArgs,

7911

llvm::SmallBitVector &CheckedVarArgs,

7912

UncoveredArgHandler &UncoveredArg)

7913

: CheckFormatHandler(

s

, fexpr, origFormatExpr,

type

, firstDataArg,

7914

numDataArgs, beg, APK, Args, formatIdx,

7915

inFunctionCall, CallType, CheckedVarArgs,

7919 const char

*startSpecifier,

7920 unsigned

specifierLen)

override

;

7922 bool

HandleInvalidScanfConversionSpecifier(

7924 const char

*startSpecifier,

7925 unsigned

specifierLen)

override

;

7927 void

HandleIncompleteScanList(

const char

*start,

const char

*end)

override

;

7932void

CheckScanfHandler::HandleIncompleteScanList(

const char

*start,

7934

EmitFormatDiagnostic(S.

PDiag

(diag::warn_scanf_scanlist_incomplete),

7935

getLocationOfByte(end),

true

,

7936

getSpecifierRange(start, end - start));

7939bool

CheckScanfHandler::HandleInvalidScanfConversionSpecifier(

7941 const char

*startSpecifier,

7942 unsigned

specifierLen) {

7944

FS.getConversionSpecifier();

7946 return

HandleInvalidConversionSpecifier(FS.getArgIndex(),

7947

getLocationOfByte(CS.

getStart

()),

7948

startSpecifier, specifierLen,

7952bool

CheckScanfHandler::HandleScanfSpecifier(

7954 const char

*startSpecifier,

7955 unsigned

specifierLen) {

7956 using namespace

analyze_scanf;

7957 using namespace

analyze_format_string;

7959 const

ScanfConversionSpecifier &CS = FS.getConversionSpecifier();

7963 if

(FS.consumesDataArgument()) {

7965

atFirstArg =

false

;

7966

usesPositionalArgs = FS.usesPositionalArg();

7968 else if

(usesPositionalArgs != FS.usesPositionalArg()) {

7969

HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),

7970

startSpecifier, specifierLen);

7976 const

OptionalAmount &Amt = FS.getFieldWidth();

7977 if

(Amt.getHowSpecified() == OptionalAmount::Constant) {

7978 if

(Amt.getConstantAmount() == 0) {

7980

Amt.getConstantLength());

7981

EmitFormatDiagnostic(S.

PDiag

(diag::warn_scanf_nonzero_width),

7982

getLocationOfByte(Amt.getStart()),

7988 if

(!FS.consumesDataArgument()) {

7995 unsigned

argIndex = FS.getArgIndex();

7996 if

(argIndex < NumDataArgs) {

8000

CoveredArgs.set(argIndex);

8006

HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,

8007

diag::warn_format_nonsensical_length);

8008 else if

(!FS.hasStandardLengthModifier())

8009

HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);

8010 else if

(!FS.hasStandardLengthConversionCombination())

8011

HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,

8012

diag::warn_format_non_standard_conversion_spec);

8014 if

(!FS.hasStandardConversionSpecifier(S.

getLangOpts

()))

8015

HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);

8021 if

(!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))

8025 const Expr

*Ex = getDataArg(argIndex);

8042

ScanfSpecifier fixedFS = FS;

8047 Pedantic

? diag::warn_format_conversion_argument_type_mismatch_pedantic

8048

: diag::warn_format_conversion_argument_type_mismatch;

8053

llvm::raw_svector_ostream os(buf);

8054

fixedFS.toString(os);

8056

EmitFormatDiagnostic(

8061

getSpecifierRange(startSpecifier, specifierLen),

8063

getSpecifierRange(startSpecifier, specifierLen), os.str()));

8070

getSpecifierRange(startSpecifier, specifierLen));

8077 Sema

&S,

const

FormatStringLiteral *FExpr,

const Expr

*OrigFormatExpr,

8081

llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,

8082 bool

IgnoreStringsWithoutSpecifiers) {

8084 if

(!FExpr->isAscii() && !FExpr->isUTF8()) {

8085

CheckFormatHandler::EmitFormatDiagnostic(

8086

S, inFunctionCall, Args[format_idx],

8087

S.

PDiag

(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),

8093

StringRef StrRef = FExpr->getString();

8094 const char

*Str = StrRef.data();

8098

assert(

T

&&

"String literal not of constant array type!"

);

8099 size_t

TypeSize =

T

->getZExtSize();

8100 size_t

StrLen = std::min(std::max(TypeSize,

size_t

(1)) - 1, StrRef.size());

8101 const unsigned

numDataArgs = Args.size() - firstDataArg;

8103 if

(IgnoreStringsWithoutSpecifiers &&

8110 if

(TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(

'\0'

)) {

8111

CheckFormatHandler::EmitFormatDiagnostic(

8112

S, inFunctionCall, Args[format_idx],

8113

S.

PDiag

(diag::warn_printf_format_string_not_null_terminated),

8114

FExpr->getBeginLoc(),

8120 if

(StrLen == 0 && numDataArgs > 0) {

8121

CheckFormatHandler::EmitFormatDiagnostic(

8122

S, inFunctionCall, Args[format_idx],

8123

S.

PDiag

(diag::warn_empty_format_string), FExpr->getBeginLoc(),

8132

CheckPrintfHandler H(

8133

S, FExpr, OrigFormatExpr,

Type

, firstDataArg, numDataArgs,

8135

Args, format_idx, inFunctionCall, CallType, CheckedVarArgs,

8143

CheckScanfHandler H(S, FExpr, OrigFormatExpr,

Type

, firstDataArg,

8144

numDataArgs, Str, APK, Args, format_idx, inFunctionCall,

8145

CallType, CheckedVarArgs, UncoveredArg);

8155

StringRef StrRef = FExpr->

getString

();

8156 const char

*Str = StrRef.data();

8159

assert(

T

&&

"String literal not of constant array type!"

);

8160 size_t

TypeSize =

T

->getZExtSize();

8161 size_t

StrLen = std::min(std::max(TypeSize,

size_t

(1)) - 1, StrRef.size());

8172 switch

(AbsFunction) {

8176 case

Builtin::BI__builtin_abs:

8177 return

Builtin::BI__builtin_labs;

8178 case

Builtin::BI__builtin_labs:

8179 return

Builtin::BI__builtin_llabs;

8180 case

Builtin::BI__builtin_llabs:

8183 case

Builtin::BI__builtin_fabsf:

8184 return

Builtin::BI__builtin_fabs;

8185 case

Builtin::BI__builtin_fabs:

8186 return

Builtin::BI__builtin_fabsl;

8187 case

Builtin::BI__builtin_fabsl:

8190 case

Builtin::BI__builtin_cabsf:

8191 return

Builtin::BI__builtin_cabs;

8192 case

Builtin::BI__builtin_cabs:

8193 return

Builtin::BI__builtin_cabsl;

8194 case

Builtin::BI__builtin_cabsl:

8197 case

Builtin::BIabs:

8198 return

Builtin::BIlabs;

8199 case

Builtin::BIlabs:

8200 return

Builtin::BIllabs;

8201 case

Builtin::BIllabs:

8204 case

Builtin::BIfabsf:

8205 return

Builtin::BIfabs;

8206 case

Builtin::BIfabs:

8207 return

Builtin::BIfabsl;

8208 case

Builtin::BIfabsl:

8211 case

Builtin::BIcabsf:

8212 return

Builtin::BIcabs;

8213 case

Builtin::BIcabs:

8214 return

Builtin::BIcabsl;

8215 case

Builtin::BIcabsl:

8244 unsigned

AbsFunctionKind) {

8245 unsigned

BestKind = 0;

8246

uint64_t ArgSize = Context.

getTypeSize

(ArgType);

8247 for

(

unsigned

Kind = AbsFunctionKind; Kind != 0;

8250 if

(Context.

getTypeSize

(ParamType) >= ArgSize) {

8253 else if

(Context.

hasSameType

(ParamType, ArgType)) {

8276

llvm_unreachable(

"Type not integer, floating, or complex"

);

8283 switch

(ValueKind) {

8288 case

Builtin::BI__builtin_fabsf:

8289 case

Builtin::BI__builtin_fabs:

8290 case

Builtin::BI__builtin_fabsl:

8291 case

Builtin::BI__builtin_cabsf:

8292 case

Builtin::BI__builtin_cabs:

8293 case

Builtin::BI__builtin_cabsl:

8294 return

Builtin::BI__builtin_abs;

8295 case

Builtin::BIfabsf:

8296 case

Builtin::BIfabs:

8297 case

Builtin::BIfabsl:

8298 case

Builtin::BIcabsf:

8299 case

Builtin::BIcabs:

8300 case

Builtin::BIcabsl:

8301 return

Builtin::BIabs;

8307 case

Builtin::BI__builtin_abs:

8308 case

Builtin::BI__builtin_labs:

8309 case

Builtin::BI__builtin_llabs:

8310 case

Builtin::BI__builtin_cabsf:

8311 case

Builtin::BI__builtin_cabs:

8312 case

Builtin::BI__builtin_cabsl:

8313 return

Builtin::BI__builtin_fabsf;

8314 case

Builtin::BIabs:

8315 case

Builtin::BIlabs:

8316 case

Builtin::BIllabs:

8317 case

Builtin::BIcabsf:

8318 case

Builtin::BIcabs:

8319 case

Builtin::BIcabsl:

8320 return

Builtin::BIfabsf;

8326 case

Builtin::BI__builtin_abs:

8327 case

Builtin::BI__builtin_labs:

8328 case

Builtin::BI__builtin_llabs:

8329 case

Builtin::BI__builtin_fabsf:

8330 case

Builtin::BI__builtin_fabs:

8331 case

Builtin::BI__builtin_fabsl:

8332 return

Builtin::BI__builtin_cabsf;

8333 case

Builtin::BIabs:

8334 case

Builtin::BIlabs:

8335 case

Builtin::BIllabs:

8336 case

Builtin::BIfabsf:

8337 case

Builtin::BIfabs:

8338 case

Builtin::BIfabsl:

8339 return

Builtin::BIcabsf;

8342

llvm_unreachable(

"Unable to convert function"

);

8353 case

Builtin::BI__builtin_abs:

8354 case

Builtin::BI__builtin_fabs:

8355 case

Builtin::BI__builtin_fabsf:

8356 case

Builtin::BI__builtin_fabsl:

8357 case

Builtin::BI__builtin_labs:

8358 case

Builtin::BI__builtin_llabs:

8359 case

Builtin::BI__builtin_cabs:

8360 case

Builtin::BI__builtin_cabsf:

8361 case

Builtin::BI__builtin_cabsl:

8362 case

Builtin::BIabs:

8363 case

Builtin::BIlabs:

8364 case

Builtin::BIllabs:

8365 case

Builtin::BIfabs:

8366 case

Builtin::BIfabsf:

8367 case

Builtin::BIfabsl:

8368 case

Builtin::BIcabs:

8369 case

Builtin::BIcabsf:

8370 case

Builtin::BIcabsl:

8373

llvm_unreachable(

"Unknown Builtin type"

);

8379 unsigned

AbsKind,

QualType

ArgType) {

8380 bool

EmitHeaderHint =

true

;

8381 const char

*HeaderName =

nullptr

;

8382

StringRef FunctionName;

8384

FunctionName =

"std::abs"

;

8386

HeaderName =

"cstdlib"

;

8388

HeaderName =

"cmath"

;

8390

llvm_unreachable(

"Invalid Type"

);

8399 for

(

const auto

*I : R) {

8402

FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());

8404

FDecl = dyn_cast<FunctionDecl>(I);

8419

EmitHeaderHint =

false

;

8437

EmitHeaderHint =

false

;

8441

}

else if

(!R.

empty

()) {

8447

S.

Diag

(

Loc

, diag::note_replace_abs_function)

8453 if

(!EmitHeaderHint)

8456

S.

Diag

(

Loc

, diag::note_include_header_or_declare) << HeaderName

8460template

<std::

size_t

StrLen>

8462 const char

(&Str)[StrLen]) {

8475 auto

MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {

8476 return

std::any_of(names.begin(), names.end(), [&](llvm::StringRef name) {

8477

return calleeName == name;

8482 case

MathCheck::NaN:

8483 return

MatchesAny({

"__builtin_nan"

,

"__builtin_nanf"

,

"__builtin_nanl"

,

8484 "__builtin_nanf16"

,

"__builtin_nanf128"

});

8485 case

MathCheck::Inf:

8486 return

MatchesAny({

"__builtin_inf"

,

"__builtin_inff"

,

"__builtin_infl"

,

8487 "__builtin_inff16"

,

"__builtin_inff128"

});

8489

llvm_unreachable(

"unknown MathCheck"

);

8493 if

(FDecl->

getName

() !=

"infinity"

)

8496 if

(

const CXXMethodDecl

*MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {

8498 if

(RDecl->

getName

() !=

"numeric_limits"

)

8515 if

(FPO.getNoHonorNaNs() &&

8518 Diag

(

Call

->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)

8519

<< 1 << 0 <<

Call

->getSourceRange();

8523 if

(FPO.getNoHonorInfs() &&

8527 Diag

(

Call

->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)

8528

<< 0 << 0 <<

Call

->getSourceRange();

8532void

Sema::CheckAbsoluteValueFunction(

const CallExpr

*

Call

,

8534 if

(

Call

->getNumArgs() != 1)

8539 if

(AbsKind == 0 && !IsStdAbs)

8542 QualType

ArgType =

Call

->getArg(0)->IgnoreParenImpCasts()->getType();

8548

StringRef FunctionName =

8550 Diag

(

Call

->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;

8551 Diag

(

Call

->getExprLoc(), diag::note_remove_abs)

8560 unsigned

DiagType = 0;

8566 Diag

(

Call

->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;

8580 if

(ArgValueKind == ParamValueKind) {

8585 Diag

(

Call

->getExprLoc(), diag::warn_abs_too_small)

8586

<< FDecl << ArgType << ParamType;

8588 if

(NewAbsKind == 0)

8592 Call

->getCallee()->getSourceRange(), NewAbsKind, ArgType);

8601 if

(NewAbsKind == 0)

8604 Diag

(

Call

->getExprLoc(), diag::warn_wrong_absolute_value_type)

8605

<< FDecl << ParamValueKind << ArgValueKind;

8608 Call

->getCallee()->getSourceRange(), NewAbsKind, ArgType);

8612void

Sema::CheckMaxUnsignedZero(

const CallExpr

*

Call

,

8614 if

(!

Call

|| !FDecl)

return

;

8618 if

(

Call

->getExprLoc().isMacroID())

return

;

8621 if

(

Call

->getNumArgs() != 2)

return

;

8624 if

(!ArgList)

return

;

8625 if

(ArgList->size() != 1)

return

;

8628 const auto

& TA = ArgList->

get

(0);

8634 auto

IsLiteralZeroArg = [](

const Expr

*

E

) ->

bool

{

8635 const auto

*MTE = dyn_cast<MaterializeTemporaryExpr>(

E

);

8636 if

(!MTE)

return false

;

8637 const auto

*

Num

= dyn_cast<IntegerLiteral>(MTE->getSubExpr());

8638 if

(!

Num

)

return false

;

8639 if

(

Num

->getValue() != 0)

return false

;

8643 const Expr

*FirstArg =

Call

->getArg(0);

8644 const Expr

*SecondArg =

Call

->getArg(1);

8645 const bool

IsFirstArgZero = IsLiteralZeroArg(FirstArg);

8646 const bool

IsSecondArgZero = IsLiteralZeroArg(SecondArg);

8649 if

(IsFirstArgZero == IsSecondArgZero)

return

;

8654 SourceRange

ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;

8656 Diag

(

Call

->getExprLoc(), diag::warn_max_unsigned_zero)

8657

<< IsFirstArgZero <<

Call

->getCallee()->getSourceRange() << ZeroRange;

8661 if

(IsFirstArgZero) {

8669 Diag

(

Call

->getExprLoc(), diag::note_remove_max_call)

8689 if

(!Size->isComparisonOp() && !Size->isLogicalOp())

8693

S.

Diag

(Size->getOperatorLoc(), diag::warn_memsize_comparison)

8694

<< SizeRange << FnName;

8695

S.

Diag

(FnLoc, diag::note_memsize_comparison_paren)

8700

S.

Diag

(SizeRange.

getBegin

(), diag::note_memsize_comparison_cast_silence)

8711 bool

&IsContained) {

8714

IsContained =

false

;

8727 for

(

auto

*FD : RD->

fields

()) {

8731

IsContained =

true

;

8740 if

(

const auto

*Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(

E

))

8741 if

(Unary->getKind() == UETT_SizeOf)

8750 if

(!

SizeOf

->isArgumentType())

8751 return SizeOf

->getArgumentExpr()->IgnoreParenImpCasts();

8758 return SizeOf

->getTypeOfArgument();

8764struct

SearchNonTrivialToInitializeField

8769

SearchNonTrivialToInitializeField(

const Expr

*

E

,

Sema

&S) :

E

(

E

), S(S) {}

8773 if

(

const auto

*AT = asDerived().getContext().getAsArrayType(FT)) {

8774

asDerived().visitArray(PDIK, AT, SL);

8778

Super::visitWithKind(PDIK, FT, SL);

8793

visit(getContext().getBaseElementType(AT), SL);

8798

SearchNonTrivialToInitializeField(

E

, S).visitStruct(RT,

SourceLocation

());

8807struct

SearchNonTrivialToCopyField

8811

SearchNonTrivialToCopyField(

const Expr

*

E

,

Sema

&S) :

E

(

E

), S(S) {}

8815 if

(

const auto

*AT = asDerived().getContext().getAsArrayType(FT)) {

8816

asDerived().visitArray(PCK, AT, SL);

8820

Super::visitWithKind(PCK, FT, SL);

8835

visit(getContext().getBaseElementType(AT), SL);

8843

SearchNonTrivialToCopyField(

E

, S).visitStruct(RT,

SourceLocation

());

8858 if

(

const auto

*BO = dyn_cast<BinaryOperator>(SizeofExpr)) {

8859 if

(BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)

8883 return SM

.getFileID(CallLoc) !=

SM

.getFileID(ArgLoc);

8885 return SM

.getFileID(

SM

.getImmediateMacroCallerLoc(CallLoc)) !=

8886 SM

.getFileID(

SM

.getImmediateMacroCallerLoc(ArgLoc));

8892 if

(BId != Builtin::BImemset && BId != Builtin::BIbzero)

8895 const Expr

*SizeArg =

8896 Call

->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();

8898 auto

isLiteralZero = [](

const Expr

*

E

) {

8899 return

(isa<IntegerLiteral>(

E

) &&

8900

cast<IntegerLiteral>(

E

)->getValue() == 0) ||

8901

(isa<CharacterLiteral>(

E

) &&

8902

cast<CharacterLiteral>(

E

)->getValue() == 0);

8908 if

(isLiteralZero(SizeArg) &&

8915 if

(BId == Builtin::BIbzero ||

8918

S.

Diag

(DiagLoc, diag::warn_suspicious_bzero_size);

8919

S.

Diag

(DiagLoc, diag::note_suspicious_bzero_size_silence);

8920

}

else if

(!isLiteralZero(

Call

->getArg(1)->IgnoreImpCasts())) {

8921

S.

Diag

(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;

8922

S.

Diag

(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;

8930 if

(BId == Builtin::BImemset &&

8934

S.

Diag

(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;

8935

S.

Diag

(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;

8940void

Sema::CheckMemaccessArguments(

const CallExpr

*

Call

,

8947 unsigned

ExpectedNumArgs =

8948

(BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);

8949 if

(

Call

->getNumArgs() < ExpectedNumArgs)

8952 unsigned

LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||

8953

BId == Builtin::BIstrndup ? 1 : 2);

8955

(BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);

8956 const Expr

*LenExpr =

Call

->getArg(LenArg)->IgnoreParenImpCasts();

8959 Call

->getBeginLoc(),

Call

->getRParenLoc()))

8968

llvm::FoldingSetNodeID SizeOfArgID;

8973 QualType

FirstArgTy =

Call

->getArg(0)->IgnoreParenImpCasts()->getType();

8977 for

(

unsigned

ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {

8978 const Expr

*Dest =

Call

->getArg(ArgIdx)->IgnoreParenImpCasts();

9000 if

(SizeOfArgID == llvm::FoldingSetNodeID())

9002

llvm::FoldingSetNodeID DestID;

9004 if

(DestID == SizeOfArgID) {

9007 unsigned

ActionIdx = 0;

9008

StringRef ReadableName = FnName->

getName

();

9010 if

(

const UnaryOperator

*UnaryOp = dyn_cast<UnaryOperator>(Dest))

9011 if

(UnaryOp->getOpcode() == UO_AddrOf)

9025 if

(

SM

.isMacroArgExpansion(SL)) {

9027

SL =

SM

.getSpellingLoc(SL);

9029 SM

.getSpellingLoc(DSR.

getEnd

()));

9031 SM

.getSpellingLoc(SSR.

getEnd

()));

9035 PDiag

(diag::warn_sizeof_pointer_expr_memaccess)

9042 PDiag

(diag::warn_sizeof_pointer_expr_memaccess_note)

9057 PDiag

(diag::warn_sizeof_pointer_type_memaccess)

9058

<< FnName << SizeOfArgTy << ArgIdx

9076 unsigned

OperationType = 0;

9077 const bool

IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;

9080 if

(ArgIdx != 0 || IsCmp) {

9081 if

(BId == Builtin::BImemcpy)

9083 else if

(BId == Builtin::BImemmove)

9090 PDiag

(diag::warn_dyn_class_memaccess)

9091

<< (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName

9092

<< IsContained << ContainedRD << OperationType

9093

<<

Call

->getCallee()->getSourceRange());

9095

BId != Builtin::BImemset)

9098 PDiag

(diag::warn_arc_object_memaccess)

9099

<< ArgIdx << FnName << PointeeTy

9100

<<

Call

->getCallee()->getSourceRange());

9107 bool

MayBeTriviallyCopyableCXXRecord =

9109

RT->desugar().isTriviallyCopyableType(

Context

);

9111 if

((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&

9112

RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {

9114 PDiag

(diag::warn_cstruct_memaccess)

9115

<< ArgIdx << FnName << PointeeTy << 0);

9116

SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *

this

);

9117

}

else if

((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&

9118

!MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {

9122 PDiag

(diag::warn_cxxstruct_memaccess)

9123

<< FnName << PointeeTy);

9124

}

else if

((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&

9125

RT->getDecl()->isNonTrivialToPrimitiveCopy()) {

9127 PDiag

(diag::warn_cstruct_memaccess)

9128

<< ArgIdx << FnName << PointeeTy << 1);

9129

SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *

this

);

9130

}

else if

((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&

9131

!MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {

9135 PDiag

(diag::warn_cxxstruct_memaccess)

9136

<< FnName << PointeeTy);

9145 PDiag

(diag::note_bad_memaccess_silence)

9165 if

(isa<IntegerLiteral>(RHS))

9167 else if

(isa<IntegerLiteral>(LHS))

9181 if

(CAT->getZExtSize() <= 1)

9189void

Sema::CheckStrlcpycatArguments(

const CallExpr

*

Call

,

9193 unsigned

NumArgs =

Call

->getNumArgs();

9194 if

((NumArgs != 3) && (NumArgs != 4))

9199 const Expr

*CompareWithSrc =

nullptr

;

9202 Call

->getBeginLoc(),

Call

->getRParenLoc()))

9207

CompareWithSrc = Ex;

9210 if

(

const CallExpr

*SizeCall = dyn_cast<CallExpr>(SizeArg)) {

9211 if

(SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&

9212

SizeCall->getNumArgs() == 1)

9217 if

(!CompareWithSrc)

9224 const DeclRefExpr

*SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);

9228 const DeclRefExpr

*CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);

9229 if

(!CompareWithSrcDRE ||

9233 const Expr

*OriginalSizeArg =

Call

->getArg(2);

9234 Diag

(CompareWithSrcDRE->

getBeginLoc

(), diag::warn_strlcpycat_wrong_size)

9241 const Expr

*DstArg =

Call

->getArg(0)->IgnoreParenImpCasts();

9246

llvm::raw_svector_ostream

OS

(sizeString);

9251 Diag

(OriginalSizeArg->

getBeginLoc

(), diag::note_strlcpycat_wrong_size)

9258 if

(

const DeclRefExpr

*D1 = dyn_cast_or_null<DeclRefExpr>(E1))

9259 if

(

const DeclRefExpr

*D2 = dyn_cast_or_null<DeclRefExpr>(E2))

9260 return

D1->getDecl() == D2->getDecl();

9265 if

(

const CallExpr

*CE = dyn_cast<CallExpr>(

E

)) {

9274void

Sema::CheckStrncatArguments(

const CallExpr

*CE,

9289 unsigned

PatternType = 0;

9297

}

else if

(

const BinaryOperator

*BE = dyn_cast<BinaryOperator>(LenArg)) {

9298 if

(BE->getOpcode() == BO_Sub) {

9311 if

(PatternType == 0)

9320 if

(

SM

.isMacroArgExpansion(SL)) {

9321

SL =

SM

.getSpellingLoc(SL);

9323 SM

.getSpellingLoc(SR.

getEnd

()));

9330 if

(!isKnownSizeArray) {

9331 if

(PatternType == 1)

9332 Diag

(SL, diag::warn_strncat_wrong_size) << SR;

9334 Diag

(SL, diag::warn_strncat_src_size) << SR;

9338 if

(PatternType == 1)

9339 Diag

(SL, diag::warn_strncat_large_size) << SR;

9341 Diag

(SL, diag::warn_strncat_src_size) << SR;

9344

llvm::raw_svector_ostream

OS

(sizeString);

9352 Diag

(SL, diag::note_strncat_wrong_size)

9357void

CheckFreeArgumentsOnLvalue(

Sema

&S,

const

std::string &CalleeName,

9359 if

(isa<FieldDecl, FunctionDecl, VarDecl>(

D

)) {

9361

<< CalleeName << 0

<< cast<NamedDecl>(

D

);

9366void

CheckFreeArgumentsAddressof(

Sema

&S,

const

std::string &CalleeName,

9368 if

(

const auto

*Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->

getSubExpr

())) {

9369 const Decl

*

D

= Lvalue->getDecl();

9370 if

(isa<DeclaratorDecl>(

D

))

9371 if

(!dyn_cast<DeclaratorDecl>(

D

)->getType()->isReferenceType())

9372 return

CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,

D

);

9375 if

(

const auto

*Lvalue = dyn_cast<MemberExpr>(UnaryExpr->

getSubExpr

()))

9376 return

CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,

9377

Lvalue->getMemberDecl());

9380void

CheckFreeArgumentsPlus(

Sema

&S,

const

std::string &CalleeName,

9382 const auto

*Lambda = dyn_cast<LambdaExpr>(

9387

S.

Diag

(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)

9388

<< CalleeName << 2

;

9391void

CheckFreeArgumentsStackArray(

Sema

&S,

const

std::string &CalleeName,

9393 const auto

*Var = dyn_cast<VarDecl>(Lvalue->

getDecl

());

9394 if

(Var ==

nullptr

)

9398

<< CalleeName << 0

<< Var;

9401void

CheckFreeArgumentsCast(

Sema

&S,

const

std::string &CalleeName,

9404

llvm::raw_svector_ostream OS(SizeString);

9407 if

(Kind == clang::CK_BitCast &&

9408

!

Cast

->getSubExpr()->getType()->isFunctionPointerType())

9410 if

(Kind == clang::CK_IntegralToPointer &&

9411

!isa<IntegerLiteral>(

9412 Cast

->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))

9415 switch

(

Cast

->getCastKind()) {

9416 case

clang::CK_BitCast:

9417 case

clang::CK_IntegralToPointer:

9418 case

clang::CK_FunctionToPointerDecay:

9427

S.

Diag

(

Cast

->getBeginLoc(), diag::warn_free_nonheap_object)

9428

<< CalleeName << 0

<< OS.str();

9432void

Sema::CheckFreeArguments(

const CallExpr

*

E

) {

9433 const

std::string CalleeName =

9434

cast<FunctionDecl>(

E

->getCalleeDecl())->getQualifiedNameAsString();

9438 if

(

const auto

*UnaryExpr = dyn_cast<UnaryOperator>(Arg))

9440 case

UnaryOperator::Opcode::UO_AddrOf:

9441 return

CheckFreeArgumentsAddressof(*

this

, CalleeName, UnaryExpr);

9442 case

UnaryOperator::Opcode::UO_Plus:

9443 return

CheckFreeArgumentsPlus(*

this

, CalleeName, UnaryExpr);

9448 if

(

const auto

*Lvalue = dyn_cast<DeclRefExpr>(Arg))

9450 return

CheckFreeArgumentsStackArray(*

this

, CalleeName, Lvalue);

9452 if

(

const auto

*

Label

= dyn_cast<AddrLabelExpr>(Arg)) {

9453 Diag

(

Label

->getBeginLoc(), diag::warn_free_nonheap_object)

9454

<< CalleeName << 0

<<

Label

->getLabel()->getIdentifier();

9458 if

(isa<BlockExpr>(Arg)) {

9460

<< CalleeName << 1

;

9465 if

(

const auto

*Cast = dyn_cast<CastExpr>(

E

->getArg(0)))

9466 return

CheckFreeArgumentsCast(*

this

, CalleeName, Cast);

9470

Sema::CheckReturnValExpr(

Expr

*RetValExp,

QualType

lhsType,

9476 if

(((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||

9479 Diag

(ReturnLoc, diag::warn_null_ret)

9489 if

(Op == OO_New || Op == OO_Array_New) {

9494 Diag

(ReturnLoc, diag::warn_operator_new_returns_null)

9500 Diag

(ReturnLoc, diag::err_wasm_table_art) << 1;

9517 auto

getCastAndLiteral = [&FPLiteral, &FPCast](

Expr

*L,

Expr

*R) {

9518

FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());

9520 return

FPLiteral && FPCast;

9523 if

(getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {

9529

llvm::APFloat TargetC = FPLiteral->

getValue

();

9531

llvm::APFloat::rmNearestTiesToEven, &Lossy);

9535 Diag

(

Loc

, diag::warn_float_compare_literal)

9536

<< (Opcode == BO_EQ) <<

QualType

(SourceTy, 0)

9549 if

(

auto

*DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))

9550 if

(

auto

*DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))

9551 if

(DRL->getDecl() == DRR->getDecl())

9559 if

(

FloatingLiteral

* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {

9563 if

(

FloatingLiteral

* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))

9568 if

(

CallExpr

* CL = dyn_cast<CallExpr>(LeftExprSansParen))

9569 if

(CL->getBuiltinCallee())

9572 if

(

CallExpr

* CR = dyn_cast<CallExpr>(RightExprSansParen))

9573 if

(CR->getBuiltinCallee())

9577 Diag

(

Loc

, diag::warn_floatingpoint_eq)

9598

IntRange(

unsigned

Width,

bool

NonNegative)

9599

: Width(Width), NonNegative(NonNegative) {}

9602 unsigned

valueBits()

const

{

9603 return

NonNegative ? Width : Width - 1;

9607 static

IntRange forBoolType() {

9608 return

IntRange(1,

true

);

9613 return

forValueOfCanonicalType(

C

,

9618 static

IntRange forValueOfCanonicalType(

ASTContext

&

C

,

const Type

*

T

) {

9621 if

(

const VectorType

*VT = dyn_cast<VectorType>(

T

))

9622 T

= VT->getElementType().getTypePtr();

9623 if

(

const ComplexType

*CT = dyn_cast<ComplexType>(

T

))

9624 T

= CT->getElementType().getTypePtr();

9625 if

(

const AtomicType

*AT = dyn_cast<AtomicType>(

T

))

9626 T

= AT->getValueType().getTypePtr();

9628 if

(!

C

.getLangOpts().CPlusPlus) {

9630 if

(

const EnumType

*ET = dyn_cast<EnumType>(

T

))

9631 T

= ET->getDecl()->getIntegerType().getDesugaredType(

C

).getTypePtr();

9632

}

else if

(

const EnumType

*ET = dyn_cast<EnumType>(

T

)) {

9637 if

(

Enum

->isFixed()) {

9638 return

IntRange(

C

.getIntWidth(

QualType

(

T

, 0)),

9639

!ET->isSignedIntegerOrEnumerationType());

9642 unsigned

NumPositive =

Enum

->getNumPositiveBits();

9643 unsigned

NumNegative =

Enum

->getNumNegativeBits();

9645 if

(NumNegative == 0)

9646 return

IntRange(NumPositive,

true

);

9648 return

IntRange(std::max(NumPositive + 1, NumNegative),

9652 if

(

const auto

*EIT = dyn_cast<BitIntType>(

T

))

9653 return

IntRange(EIT->getNumBits(), EIT->isUnsigned());

9666 static

IntRange forTargetOfCanonicalType(

ASTContext

&

C

,

const Type

*

T

) {

9669 if

(

const VectorType

*VT = dyn_cast<VectorType>(

T

))

9670 T

= VT->getElementType().getTypePtr();

9671 if

(

const ComplexType

*CT = dyn_cast<ComplexType>(

T

))

9672 T

= CT->getElementType().getTypePtr();

9673 if

(

const AtomicType

*AT = dyn_cast<AtomicType>(

T

))

9674 T

= AT->getValueType().getTypePtr();

9675 if

(

const EnumType

*ET = dyn_cast<EnumType>(

T

))

9676 T

=

C

.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();

9678 if

(

const auto

*EIT = dyn_cast<BitIntType>(

T

))

9679 return

IntRange(EIT->getNumBits(), EIT->isUnsigned());

9688 static

IntRange join(IntRange L, IntRange R) {

9689 bool Unsigned

= L.NonNegative && R.NonNegative;

9690 return

IntRange(std::max(L.valueBits(), R.valueBits()) + !

Unsigned

,

9691

L.NonNegative && R.NonNegative);

9695 static

IntRange bit_and(IntRange L, IntRange R) {

9696 unsigned

Bits = std::max(L.Width, R.Width);

9697 bool

NonNegative =

false

;

9698 if

(L.NonNegative) {

9699

Bits = std::min(Bits, L.Width);

9700

NonNegative =

true

;

9702 if

(R.NonNegative) {

9703

Bits = std::min(Bits, R.Width);

9704

NonNegative =

true

;

9706 return

IntRange(Bits, NonNegative);

9710 static

IntRange sum(IntRange L, IntRange R) {

9711 bool Unsigned

= L.NonNegative && R.NonNegative;

9712 return

IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !

Unsigned

,

9717 static

IntRange difference(IntRange L, IntRange R) {

9721 bool

CanWiden = !L.NonNegative || !R.NonNegative;

9722 bool Unsigned

= L.NonNegative && R.Width == 0;

9723 return

IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +

9729 static

IntRange product(IntRange L, IntRange R) {

9733 bool

CanWiden = !L.NonNegative && !R.NonNegative;

9734 bool Unsigned

= L.NonNegative && R.NonNegative;

9735 return

IntRange(L.valueBits() + R.valueBits() + CanWiden + !

Unsigned

,

9740 static

IntRange rem(IntRange L, IntRange R) {

9744 return

IntRange(std::min(L.valueBits(), R.valueBits()) + !

Unsigned

,

9752 unsigned

MaxWidth) {

9753 if

(value.isSigned() && value.isNegative())

9754 return

IntRange(value.getSignificantBits(),

false

);

9756 if

(value.getBitWidth() > MaxWidth)

9757

value = value.trunc(MaxWidth);

9761 return

IntRange(value.getActiveBits(),

true

);

9765 unsigned

MaxWidth) {

9766 if

(result.

isInt

())

9773

R = IntRange::join(R, El);

9781 return

IntRange::join(R, I);

9796

Ty = AtomicRHS->getValueType();

9815 bool

InConstantContext,

9827 if

(

const auto

*CE = dyn_cast<ImplicitCastExpr>(

E

)) {

9828 if

(CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)

9829 return TryGetExprRange

(

C

, CE->getSubExpr(), MaxWidth, InConstantContext,

9832

IntRange OutputTypeRange = IntRange::forValueOfType(

C

,

GetExprType

(CE));

9834 bool

isIntegerCast = CE->getCastKind() == CK_IntegralCast ||

9835

CE->getCastKind() == CK_BooleanToSignedIntegral;

9839 return

OutputTypeRange;

9842 C

, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),

9843

InConstantContext, Approximate);

9845 return

std::nullopt;

9848 if

(SubRange->Width >= OutputTypeRange.Width)

9849 return

OutputTypeRange;

9853 return

IntRange(SubRange->Width,

9854

SubRange->NonNegative || OutputTypeRange.NonNegative);

9857 if

(

const auto

*CO = dyn_cast<ConditionalOperator>(

E

)) {

9860 if

(CO->getCond()->EvaluateAsBooleanCondition(CondResult,

C

))

9862 C

, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,

9863

InConstantContext, Approximate);

9868 Expr

*TrueExpr = CO->getTrueExpr();

9870 return

std::nullopt;

9872

std::optional<IntRange> L =

9875 return

std::nullopt;

9877 Expr

*FalseExpr = CO->getFalseExpr();

9879 return

std::nullopt;

9881

std::optional<IntRange> R =

9882 TryGetExprRange

(

C

, FalseExpr, MaxWidth, InConstantContext, Approximate);

9884 return

std::nullopt;

9886 return

IntRange::join(*L, *R);

9889 if

(

const auto

*BO = dyn_cast<BinaryOperator>(

E

)) {

9890

IntRange (*Combine)(IntRange, IntRange) = IntRange::join;

9892 switch

(BO->getOpcode()) {

9894

llvm_unreachable(

"builtin <=> should have class type"

);

9905 return

IntRange::forBoolType();

9934

Combine = IntRange::bit_and;

9942

= dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {

9943 if

(I->getValue() == 1) {

9944

IntRange R = IntRange::forValueOfType(

C

,

GetExprType

(

E

));

9945 return

IntRange(R.Width,

true

);

9955 case

BO_ShrAssign: {

9957 C

, BO->getLHS(), MaxWidth, InConstantContext, Approximate);

9959 return

std::nullopt;

9963 if

(std::optional<llvm::APSInt> shift =

9964

BO->getRHS()->getIntegerConstantExpr(

C

)) {

9965 if

(shift->isNonNegative()) {

9966 if

(shift->uge(L->Width))

9967

L->Width = (L->NonNegative ? 0 : 1);

9969

L->Width -= shift->getZExtValue();

9983

Combine = IntRange::sum;

9987 if

(BO->getLHS()->getType()->isPointerType())

9990

Combine = IntRange::difference;

9995

Combine = IntRange::product;

10004 C

, BO->getLHS(), opWidth, InConstantContext, Approximate);

10006 return

std::nullopt;

10009 if

(std::optional<llvm::APSInt> divisor =

10010

BO->getRHS()->getIntegerConstantExpr(

C

)) {

10011 unsigned log2

= divisor->logBase2();

10012 if

(

log2

>= L->Width)

10013

L->Width = (L->NonNegative ? 0 : 1);

10015

L->Width = std::min(L->Width -

log2

, MaxWidth);

10023 C

, BO->getRHS(), opWidth, InConstantContext, Approximate);

10025 return

std::nullopt;

10027 return

IntRange(L->Width, L->NonNegative && R->NonNegative);

10031

Combine = IntRange::rem;

10043 unsigned

opWidth =

C

.getIntWidth(

T

);

10045

InConstantContext, Approximate);

10047 return

std::nullopt;

10050

InConstantContext, Approximate);

10052 return

std::nullopt;

10054

IntRange

C

= Combine(*L, *R);

10056 C

.Width = std::min(

C

.Width, MaxWidth);

10060 if

(

const auto

*UO = dyn_cast<UnaryOperator>(

E

)) {

10061 switch

(UO->getOpcode()) {

10064 return

IntRange::forBoolType();

10072 return TryGetExprRange

(

C

, UO->getSubExpr(), MaxWidth, InConstantContext,

10077 if

(

const auto

*OVE = dyn_cast<OpaqueValueExpr>(

E

))

10078 return TryGetExprRange

(

C

, OVE->getSourceExpr(), MaxWidth, InConstantContext,

10082 return

IntRange(BitField->getBitWidthValue(),

10083

BitField->getType()->isUnsignedIntegerOrEnumerationType());

10086 return

std::nullopt;

10092 bool

InConstantContext,

10093 bool

Approximate) {

10102 const

llvm::fltSemantics &Src,

10103 const

llvm::fltSemantics &Tgt) {

10104

llvm::APFloat truncated = value;

10107

truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);

10108

truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);

10110 return

truncated.bitwiseIsEqual(value);

10119 const

llvm::fltSemantics &Src,

10120 const

llvm::fltSemantics &Tgt) {

10137 bool

IsListInit =

false

);

10143 if

(isa<EnumConstantDecl>(DR->getDecl()))

10153 return

MacroName !=

"YES"

&& MacroName !=

"NO"

&&

10154

MacroName !=

"true"

&& MacroName !=

"false"

;

10177struct

PromotedRange {

10179

llvm::APSInt PromotedMin;

10181

llvm::APSInt PromotedMax;

10183

PromotedRange(IntRange R,

unsigned

BitWidth,

bool Unsigned

) {

10185

PromotedMin = PromotedMax = llvm::APSInt(BitWidth,

Unsigned

);

10186 else if

(R.Width >= BitWidth && !

Unsigned

) {

10190

PromotedMin = llvm::APSInt::getMinValue(BitWidth,

Unsigned

);

10191

PromotedMax = llvm::APSInt::getMaxValue(BitWidth,

Unsigned

);

10193

PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)

10194

.extOrTrunc(BitWidth);

10195

PromotedMin.setIsUnsigned(

Unsigned

);

10197

PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)

10198

.extOrTrunc(BitWidth);

10199

PromotedMax.setIsUnsigned(

Unsigned

);

10204 bool

isContiguous()

const

{

return

PromotedMin <= PromotedMax; }

10214

InRangeFlag = 0x40,

10217 Min

=

LE

| InRangeFlag,

10219 Max

=

GE

| InRangeFlag,

10222

OnlyValue =

LE

|

GE

|

EQ

| InRangeFlag,

10227

assert(

Value

.getBitWidth() == PromotedMin.getBitWidth() &&

10228 Value

.isUnsigned() == PromotedMin.isUnsigned());

10229 if

(!isContiguous()) {

10230

assert(

Value

.isUnsigned() &&

"discontiguous range for signed compare"

);

10231 if

(

Value

.isMinValue())

return Min

;

10232 if

(

Value

.isMaxValue())

return Max

;

10238 switch

(llvm::APSInt::compareValues(

Value

, PromotedMin)) {

10239 case

-1:

return Less

;

10240 case

0:

return

PromotedMin == PromotedMax ? OnlyValue :

Min

;

10242 switch

(llvm::APSInt::compareValues(

Value

, PromotedMax)) {

10244 case

0:

return Max

;

10249

llvm_unreachable(

"impossible compare result"

);

10252 static

std::optional<StringRef>

10254 if

(Op == BO_Cmp) {

10256 if

(ConstantOnRHS) std::swap(LTFlag, GTFlag);

10258 if

(R & EQ)

return

StringRef(

"'std::strong_ordering::equal'"

);

10259 if

(R & LTFlag)

return

StringRef(

"'std::strong_ordering::less'"

);

10260 if

(R & GTFlag)

return

StringRef(

"'std::strong_ordering::greater'"

);

10261 return

std::nullopt;

10268

}

else if

(Op == BO_NE) {

10272 if

((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {

10279 if

(Op == BO_GE || Op == BO_LE)

10280

std::swap(TrueFlag, FalseFlag);

10283 return

StringRef(

"true"

);

10285 return

StringRef(

"false"

);

10286 return

std::nullopt;

10294 if

(ICE->getCastKind() != CK_IntegralCast &&

10295

ICE->getCastKind() != CK_NoOp)

10297 E

= ICE->getSubExpr();

10306 enum

ConstantValueKind {

10311 if

(

auto

*BL = dyn_cast<CXXBoolLiteralExpr>(Constant))

10312 return

BL->getValue() ? ConstantValueKind::LiteralTrue

10313

: ConstantValueKind::LiteralFalse;

10314 return

ConstantValueKind::Miscellaneous;

10319 const

llvm::APSInt &

Value

,

10320 bool

RhsConstant) {

10342 if

(!OtherValueRange)

10347

OtherT = AT->getValueType();

10348

IntRange OtherTypeRange = IntRange::forValueOfType(S.

Context

, OtherT);

10352 bool

IsObjCSignedCharBool = S.

getLangOpts

().ObjC &&

10358 bool

OtherIsBooleanDespiteType =

10360 if

(OtherIsBooleanDespiteType || IsObjCSignedCharBool)

10361

OtherTypeRange = *OtherValueRange = IntRange::forBoolType();

10365

PromotedRange OtherPromotedValueRange(*OtherValueRange,

Value

.getBitWidth(),

10366 Value

.isUnsigned());

10367 auto

Cmp = OtherPromotedValueRange.compare(

Value

);

10368 auto Result

= PromotedRange::constantValue(

E

->getOpcode(), Cmp, RhsConstant);

10374 bool

TautologicalTypeCompare =

false

;

10376

PromotedRange OtherPromotedTypeRange(OtherTypeRange,

Value

.getBitWidth(),

10377 Value

.isUnsigned());

10378 auto

TypeCmp = OtherPromotedTypeRange.compare(

Value

);

10379 if

(

auto TypeResult

= PromotedRange::constantValue(

E

->getOpcode(), TypeCmp,

10381

TautologicalTypeCompare =

true

;

10389 if

(!TautologicalTypeCompare && OtherValueRange->Width == 0)

10398 bool

InRange = Cmp & PromotedRange::InRangeFlag;

10404 if

(

Other

->refersToBitField() && InRange &&

Value

== 0 &&

10405 Other

->getType()->isUnsignedIntegerOrEnumerationType())

10406

TautologicalTypeCompare =

true

;

10411 if

(

const DeclRefExpr

*DR = dyn_cast<DeclRefExpr>(Constant))

10412

ED = dyn_cast<EnumConstantDecl>(DR->getDecl());

10416

llvm::raw_svector_ostream OS(PrettySourceValue);

10418

OS <<

'\''

<< *ED <<

"' ("

<<

Value

<<

")"

;

10419

}

else if

(

auto

*BL = dyn_cast<ObjCBoolLiteralExpr>(

10421

OS << (BL->getValue() ?

"YES"

:

"NO"

);

10426 if

(!TautologicalTypeCompare) {

10427

S.

Diag

(

E

->getOperatorLoc(), diag::warn_tautological_compare_value_range)

10428

<< RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative

10429

<<

E

->getOpcodeStr() << OS.str() << *

Result 10434 if

(IsObjCSignedCharBool) {

10436

S.

PDiag

(diag::warn_tautological_compare_objc_bool)

10437

<< OS.str() << *

Result

);

10444 if

(!InRange ||

Other

->isKnownToHaveBooleanValue()) {

10447 E

->getOperatorLoc(),

E

,

10448

S.

PDiag

(!InRange ? diag::warn_out_of_range_compare

10449

: diag::warn_tautological_bool_compare)

10451

<< OtherIsBooleanDespiteType << *

Result 10458

? diag::warn_unsigned_enum_always_true_comparison

10459

: IsCharTy ? diag::warn_unsigned_char_always_true_comparison

10460

: diag::warn_unsigned_always_true_comparison)

10461

: diag::warn_tautological_constant_compare;

10464

<< RhsConstant << OtherT <<

E

->getOpcodeStr() << OS.str() << *

Result 10494 Expr

*LHS =

E

->getLHS();

10495 Expr

*RHS =

E

->getRHS();

10498

std::optional<llvm::APSInt> RHSValue =

10500

std::optional<llvm::APSInt> LHSValue =

10504 if

(RHSValue && LHSValue)

10508 if

((

bool

)RHSValue ^ (

bool

)LHSValue) {

10510 const bool

RhsConstant = (

bool

)RHSValue;

10511 Expr

*Const = RhsConstant ? RHS : LHS;

10512 Expr

*

Other

= RhsConstant ? LHS : RHS;

10513 const

llvm::APSInt &

Value

= RhsConstant ? *RHSValue : *LHSValue;

10536 if

(

const auto

*TET = dyn_cast<TypeOfExprType>(LHS->

getType

()))

10538 if

(

const auto

*TET = dyn_cast<TypeOfExprType>(RHS->

getType

()))

10544 Expr

*signedOperand, *unsignedOperand;

10547 "unsigned comparison between two signed integer expressions?"

);

10548

signedOperand = LHS;

10549

unsignedOperand = RHS;

10551

signedOperand = RHS;

10552

unsignedOperand = LHS;

10558

std::optional<IntRange> signedRange =

10570 if

(signedRange->NonNegative)

10577 if

(

E

->isEqualityOp()) {

10582 if

(!unsignedRange)

10587

assert(unsignedRange->NonNegative &&

"unsigned range includes negative?"

);

10589 if

(unsignedRange->Width < comparisonWidth)

10594

S.

PDiag

(diag::warn_mixed_sign_comparison)

10622

S.

Diag

(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)

10623

<< BitfieldEnumDecl;

10630 Init

->isValueDependent() ||

10631 Init

->isTypeDependent())

10634 Expr

*OriginalInit =

Init

->IgnoreParenImpCasts();

10657 unsigned

DiagID = 0;

10658 if

(SignedEnum && !SignedBitfield) {

10659

DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;

10660

}

else if

(SignedBitfield && !SignedEnum &&

10662

DiagID = diag::warn_signed_bitfield_enum_conversion;

10666

S.

Diag

(InitLoc, DiagID) << Bitfield << ED;

10671

<< SignedEnum << TypeRange;

10682 if

(BitsNeeded > FieldWidth) {

10684

S.

Diag

(InitLoc, diag::warn_bitfield_too_small_for_enum)

10696 unsigned

OriginalWidth =

Value

.getBitWidth();

10702 bool

OneAssignedToOneBitBitfield = FieldWidth == 1 &&

Value

== 1;

10703 if

(OneAssignedToOneBitBitfield && !S.

LangOpts

.CPlusPlus) {

10710 if

(!

Value

.isSigned() ||

Value

.isNegative())

10711 if

(

UnaryOperator

*UO = dyn_cast<UnaryOperator>(OriginalInit))

10712 if

(UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)

10713

OriginalWidth =

Value

.getSignificantBits();

10715 if

(OriginalWidth <= FieldWidth)

10719

llvm::APSInt TruncatedValue =

Value

.trunc(FieldWidth);

10723

TruncatedValue = TruncatedValue.extend(OriginalWidth);

10724 if

(llvm::APSInt::isSameValue(

Value

, TruncatedValue))

10728

std::string PrettyTrunc =

toString

(TruncatedValue, 10);

10730

S.

Diag

(InitLoc, OneAssignedToOneBitBitfield

10731

? diag::warn_impcast_single_bit_bitield_precision_constant

10732

: diag::warn_impcast_bitfield_precision_constant)

10733

<< PrettyValue << PrettyTrunc << OriginalInit->

getType

()

10734

<<

Init

->getSourceRange();

10749 E

->getOperatorLoc())) {

10752 E

->getOperatorLoc());

10760

S.

Diag

(

E

->getRHS()->

getBeginLoc

(), diag::warn_atomic_implicit_seq_cst);

10766 bool

pruneControlFlow =

false

) {

10767 if

(pruneControlFlow) {

10781 unsigned

diag,

bool

pruneControlFlow =

false

) {

10794 if

(UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)

10797 const bool

IsLiteral =

10798

isa<FloatingLiteral>(

E

) || isa<FloatingLiteral>(InnerE);

10800

llvm::APFloat

Value

(0.0);

10806 E

, S.

Diag

(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)

10811

diag::warn_impcast_float_integer, PruneWarnings);

10814 bool

isExact =

false

;

10818

llvm::APFloat::opStatus

Result

=

Value

.convertToInteger(

10819

IntegerValue, llvm::APFloat::rmTowardZero, &isExact);

10827 unsigned

precision = llvm::APFloat::semanticsPrecision(

Value

.getSemantics());

10828

precision = (precision * 59 + 195) / 196;

10829 Value

.toString(PrettySourceValue, precision);

10833 E

, S.

Diag

(CContext, diag::warn_impcast_constant_value_to_objc_bool)

10834

<< PrettySourceValue);

10837 if

(

Result

== llvm::APFloat::opOK && isExact) {

10838 if

(IsLiteral)

return

;

10845 if

(!IsBool &&

Result

== llvm::APFloat::opInvalidOp)

10847

S,

E

,

T

, CContext,

10848

IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range

10849

: diag::warn_impcast_float_to_integer_out_of_range,

10852 unsigned

DiagID = 0;

10855

DiagID = diag::warn_impcast_literal_float_to_integer;

10856

}

else if

(IntegerValue == 0) {

10857 if

(

Value

.isZero()) {

10859

diag::warn_impcast_float_integer, PruneWarnings);

10862

DiagID = diag::warn_impcast_float_to_integer_zero;

10864 if

(IntegerValue.isUnsigned()) {

10865 if

(!IntegerValue.isMaxValue()) {

10867

diag::warn_impcast_float_integer, PruneWarnings);

10870 if

(!IntegerValue.isMaxSignedValue() &&

10871

!IntegerValue.isMinSignedValue()) {

10873

diag::warn_impcast_float_integer, PruneWarnings);

10877

DiagID = diag::warn_impcast_float_to_integer;

10882

PrettyTargetValue =

Value

.isZero() ?

"false"

:

"true"

;

10884

IntegerValue.toString(PrettyTargetValue);

10886 if

(PruneWarnings) {

10889

<<

E

->

getType

() <<

T

.getUnqualifiedType()

10890

<< PrettySourceValue << PrettyTargetValue

10894

<<

E

->

getType

() <<

T

.getUnqualifiedType() << PrettySourceValue

10902

assert(isa<CompoundAssignOperator>(

E

) &&

10903 "Must be compound assignment operation"

);

10909

S.

Diag

(

E

->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);

10913 const auto

*RBT = cast<CompoundAssignOperator>(

E

)

10914

->getComputationResultType()

10921 if

(ResultBT->isInteger())

10923 E

->

getExprLoc

(), diag::warn_impcast_float_integer);

10925 if

(!ResultBT->isFloatingPoint())

10934

diag::warn_impcast_float_result_precision);

10939 if

(!

Range

.Width)

return "0"

;

10941

llvm::APSInt ValueInRange =

Value

;

10942

ValueInRange.setIsSigned(!

Range

.NonNegative);

10943

ValueInRange = ValueInRange.trunc(

Range

.Width);

10944 return toString

(ValueInRange, 10);

10948 if

(!isa<ImplicitCastExpr>(Ex))

10953 const Type

*Source =

10955 if

(

Target

->isDependentType())

10959

dyn_cast<BuiltinType>(ToBool ? Source :

Target

);

10960 const Type

*BoolCandidateType = ToBool ?

Target

: Source;

10969 for

(

unsigned

i = 0; i < NumArgs; ++i) {

10974 bool

IsSwapped = ((i > 0) &&

10976

IsSwapped |= ((i < (NumArgs - 1)) &&

10982

diag::warn_impcast_floating_point_to_bool);

10989 if

(S.

Diags

.

isIgnored

(diag::warn_impcast_null_pointer_to_integer,

10994 if

(isa<CallExpr>(

E

))

10999 bool

IsGNUNullExpr = isa<GNUNullExpr>(NewE);

11001 if

(!IsGNUNullExpr && !HasNullPtrType)

11021 if

(MacroName ==

"NULL"

)

11029

S.

Diag

(

Loc

, diag::warn_impcast_null_pointer_to_integer)

11043 const char

FirstLiteralCharacter =

11045 if

(FirstLiteralCharacter ==

'0'

)

11052 const char

FirstContextCharacter =

11054 if

(FirstContextCharacter ==

'{'

)

11062 const auto

*IL = dyn_cast<IntegerLiteral>(

E

);

11064 if

(

auto

*UO = dyn_cast<UnaryOperator>(

E

)) {

11065 if

(UO->getOpcode() == UO_Minus)

11066 return

dyn_cast<IntegerLiteral>(UO->getSubExpr());

11077 if

(

const auto

*BO = dyn_cast<BinaryOperator>(

E

)) {

11081 if

(Opc == BO_Shl) {

11084 if

(LHS && LHS->getValue() == 0)

11085

S.

Diag

(ExprLoc, diag::warn_left_shift_always) << 0;

11087

RHS->getValue().isNonNegative() &&

11089

S.

Diag

(ExprLoc, diag::warn_left_shift_always)

11090

<< (

Result

.Val.getInt() != 0);

11092

S.

Diag

(ExprLoc, diag::warn_left_shift_in_bool_context) <<

E

;

11096 if

(

const auto

*CO = dyn_cast<ConditionalOperator>(

E

)) {

11101 if

((LHS->getValue() == 0 || LHS->getValue() == 1) &&

11102

(RHS->getValue() == 0 || RHS->getValue() == 1))

11105 if

(LHS->getValue() != 0 && RHS->getValue() != 0)

11106

S.

Diag

(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);

11111 bool

*ICContext,

bool

IsListInit) {

11116 if

(Source ==

Target

)

return

;

11117 if

(

Target

->isDependentType())

return

;

11131 if

(

Target

->isSpecificBuiltinType(BuiltinType::Bool)) {

11132 if

(isa<StringLiteral>(

E

))

11137

diag::warn_impcast_string_literal_to_bool);

11138 if

(isa<ObjCStringLiteral>(

E

) || isa<ObjCArrayLiteral>(

E

) ||

11139

isa<ObjCDictionaryLiteral>(

E

) || isa<ObjCBoxedExpr>(

E

)) {

11143

diag::warn_impcast_objective_c_literal_to_bool);

11158 if

(

Result

.Val.getInt() != 1 &&

Result

.Val.getInt() != 0) {

11160 E

,

Diag

(CC, diag::warn_impcast_constant_value_to_objc_bool)

11169 if

(

auto

*ArrayLiteral = dyn_cast<ObjCArrayLiteral>(

E

))

11171 else if

(

auto

*DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(

E

))

11175 if

(isa<VectorType>(Source)) {

11176 if

(

Target

->isSveVLSBuiltinType() &&

11183 if

(

Target

->isRVVVLSBuiltinType() &&

11190 if

(!isa<VectorType>(

Target

)) {

11193 return DiagnoseImpCast

(*

this

,

E

,

T

, CC, diag::warn_impcast_vector_scalar);

11200

diag::warn_hlsl_impcast_vector_truncation);

11209

Source = cast<VectorType>(Source)->getElementType().getTypePtr();

11210 Target

= cast<VectorType>(

Target

)->getElementType().getTypePtr();

11212 if

(

auto

VecTy = dyn_cast<VectorType>(

Target

))

11213 Target

= VecTy->getElementType().getTypePtr();

11216 if

(isa<ComplexType>(Source)) {

11217 if

(!isa<ComplexType>(

Target

)) {

11223

? diag::err_impcast_complex_scalar

11224

: diag::warn_impcast_complex_scalar);

11227

Source = cast<ComplexType>(Source)->getElementType().getTypePtr();

11228 Target

= cast<ComplexType>(

Target

)->getElementType().getTypePtr();

11231 const BuiltinType

*SourceBT = dyn_cast<BuiltinType>(Source);

11284 else if

(Order < 0) {

11294 if

(TargetBT && TargetBT->

isInteger

()) {

11309 if

(

Target

->isBooleanType() && isa<CallExpr>(

E

)) {

11314 if

(

unsigned

NumArgs = CEx->

getNumArgs

()) {

11317 if

(isa<ImplicitCastExpr>(LastA) &&

11321

diag::warn_impcast_floating_point_to_bool);

11330 if

(

Target

->isUnsaturatedFixedPointType()) {

11334

llvm::APFixedPoint

Value

=

Result

.Val.getFixedPoint();

11339 PDiag

(diag::warn_impcast_fixed_point_range)

11340

<<

Value

.toString() <<

T 11346

}

else if

(

Target

->isIntegerType()) {

11350

llvm::APFixedPoint FXResult =

Result

.Val.getFixedPoint();

11353

llvm::APSInt IntResult = FXResult.convertToInt(

11359 PDiag

(diag::warn_impcast_fixed_point_range)

11360

<< FXResult.toString() <<

T 11367

}

else if

(

Target

->isUnsaturatedFixedPointType()) {

11375

llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(

11380 PDiag

(diag::warn_impcast_fixed_point_range)

11401 unsigned int

SourcePrecision =

SourceRange

->Width;

11405 unsigned int

TargetPrecision = llvm::APFloatBase::semanticsPrecision(

11408 if

(SourcePrecision > 0 && TargetPrecision > 0 &&

11409

SourcePrecision > TargetPrecision) {

11411 if

(std::optional<llvm::APSInt> SourceInt =

11416

llvm::APFloat TargetFloatValue(

11418

llvm::APFloat::opStatus ConversionStatus =

11419

TargetFloatValue.convertFromAPInt(

11421

llvm::APFloat::rmNearestTiesToEven);

11423 if

(ConversionStatus != llvm::APFloat::opOK) {

11425

SourceInt->toString(PrettySourceValue, 10);

11427

TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);

11431 PDiag

(diag::warn_impcast_integer_float_precision_constant)

11432

<< PrettySourceValue << PrettyTargetValue <<

E

->

getType

() <<

T 11438

diag::warn_impcast_integer_float_precision);

11447 if

(

Target

->isBooleanType())

11455 if

(

Target

->isSpecificBuiltinType(BuiltinType::Bool))

11461 E

,

Diag

(CC, diag::warn_impcast_int_to_objc_signed_char_bool)

11466 if

(!LikelySourceRange)

11469

IntRange SourceTypeRange =

11470

IntRange::forTargetOfCanonicalType(

Context

, Source);

11471

IntRange TargetRange = IntRange::forTargetOfCanonicalType(

Context

,

Target

);

11473 if

(LikelySourceRange->Width > TargetRange.Width) {

11479

llvm::APSInt

Value

(32);

11489 PDiag

(diag::warn_impcast_integer_precision_constant)

11490

<< PrettySourceValue << PrettyTargetValue

11504

diag::warn_impcast_integer_precision);

11507 if

(TargetRange.Width > SourceTypeRange.Width) {

11508 if

(

auto

*UO = dyn_cast<UnaryOperator>(

E

))

11509 if

(UO->getOpcode() == UO_Minus)

11511 if

(

Target

->isUnsignedIntegerType())

11513

diag::warn_impcast_high_order_zero_bits);

11514 if

(

Target

->isSignedIntegerType())

11516

diag::warn_impcast_nonnegative_result);

11520 if

(TargetRange.Width == LikelySourceRange->Width &&

11521

!TargetRange.NonNegative && LikelySourceRange->NonNegative &&

11536 PDiag

(diag::warn_impcast_integer_precision_constant)

11537

<< PrettySourceValue << PrettyTargetValue <<

E

->

getType

() <<

T 11546 if

((!isa<EnumType>(

Target

) || !isa<EnumType>(Source)) &&

11547

((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||

11548

(!TargetRange.NonNegative && LikelySourceRange->NonNegative &&

11549

LikelySourceRange->Width == TargetRange.Width))) {

11553 if

(SourceBT && SourceBT->

isInteger

() && TargetBT &&

11559 unsigned

DiagID = diag::warn_impcast_integer_sign;

11567

DiagID = diag::warn_impcast_integer_sign_conditional;

11568

*ICContext =

true

;

11582 if

(SourceEnum->getDecl()->hasNameForLinkage() &&

11583

TargetEnum->getDecl()->hasNameForLinkage() &&

11584

SourceEnum != TargetEnum) {

11589

diag::warn_impcast_different_enum_types);

11603 if

(

auto

*CO = dyn_cast<AbstractConditionalOperator>(

E

))

11615 Expr

*TrueExpr =

E

->getTrueExpr();

11616 if

(

auto

*BCO = dyn_cast<BinaryConditionalOperator>(

E

))

11617

TrueExpr = BCO->getCommon();

11619 bool

Suspicious =

false

;

11628 if

(!Suspicious)

return

;

11631 if

(!S.

Diags

.

isIgnored

(diag::warn_impcast_integer_sign_conditional, CC))

11638

Suspicious =

false

;

11643 E

->

getType

(), CC, &Suspicious);

11660struct

AnalyzeImplicitConversionsWorkItem {

11670 Sema

&S, AnalyzeImplicitConversionsWorkItem Item,

11672 Expr

*OrigE = Item.E;

11681 bool

IsListInit = Item.IsListInit ||

11682

(isa<InitListExpr>(OrigE) && S.

getLangOpts

().CPlusPlus);

11687 Expr

*SourceExpr =

E

;

11692 if

(

auto

*OVE = dyn_cast<OpaqueValueExpr>(

E

))

11693 if

(

auto

*Src = OVE->getSourceExpr())

11696 if

(

const auto

*UO = dyn_cast<UnaryOperator>(SourceExpr))

11697 if

(UO->getOpcode() == UO_Not &&

11698

UO->getSubExpr()->isKnownToHaveBooleanValue())

11699

S.

Diag

(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)

11703 if

(

const auto

*BO = dyn_cast<BinaryOperator>(SourceExpr))

11704 if

((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&

11705

BO->getLHS()->isKnownToHaveBooleanValue() &&

11706

BO->getRHS()->isKnownToHaveBooleanValue() &&

11707

BO->getLHS()->HasSideEffects(S.

Context

) &&

11708

BO->getRHS()->HasSideEffects(S.

Context

)) {

11719 if

(SR.str() ==

"&"

|| SR.str() ==

"|"

) {

11721

S.

Diag

(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)

11722

<< (BO->getOpcode() == BO_And ?

"&"

:

"|"

)

11725

BO->getOperatorLoc(),

11726

(BO->getOpcode() == BO_And ?

"&&"

:

"||"

));

11727

S.

Diag

(BO->getBeginLoc(), diag::note_cast_operand_to_int);

11733 if

(

auto

*CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {

11739 if

(

CallExpr

*

Call

= dyn_cast<CallExpr>(SourceExpr))

11745 if

(SourceExpr->

getType

() !=

T

)

11754 for

(

auto

*SE : POE->semantics())

11755 if

(

auto

*OVE = dyn_cast<OpaqueValueExpr>(SE))

11756

WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});

11760 if

(

auto

*CE = dyn_cast<ExplicitCastExpr>(

E

)) {

11764

WorkList.push_back({

E

, CC, IsListInit});

11768 if

(

auto

*OutArgE = dyn_cast<HLSLOutArgExpr>(

E

)) {

11769

WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});

11773 if

(OutArgE->isInOut())

11774

WorkList.push_back(

11775

{OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});

11776

WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});

11782 if

(BO->isComparisonOp())

11786 if

(BO->getOpcode() == BO_Assign)

11789 if

(BO->isAssignmentOp())

11797 if

(isa<StmtExpr>(

E

))

return

;

11800 if

(isa<UnaryExprOrTypeTraitExpr>(

E

))

return

;

11805 bool

IsLogicalAndOperator = BO && BO->

getOpcode

() == BO_LAnd;

11807 Expr

*ChildExpr = dyn_cast_or_null<Expr>(SubStmt);

11811 if

(

auto

*CSE = dyn_cast<CoroutineSuspendExpr>(

E

))

11812 if

(ChildExpr == CSE->getOperand())

11818 if

(IsLogicalAndOperator &&

11823

WorkList.push_back({ChildExpr, CC, IsListInit});

11828 if

(!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))

11832 if

(!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))

11837 if

(

U

->getOpcode() == UO_LNot) {

11839

}

else if

(

U

->getOpcode() != UO_AddrOf) {

11840 if

(

U

->getSubExpr()->getType()->isAtomicType())

11841

S.

Diag

(

U

->getSubExpr()->getBeginLoc(),

11842

diag::warn_atomic_implicit_seq_cst);

11851 bool

IsListInit

) {

11853

WorkList.push_back({OrigE, CC, IsListInit});

11854 while

(!WorkList.empty())

11866 if

(

const DeclRefExpr

*DRE = dyn_cast<DeclRefExpr>(

E

)) {

11869

}

else if

(

const MemberExpr

*M = dyn_cast<MemberExpr>(

E

)) {

11870 if

(!M->getMemberDecl()->getType()->isReferenceType())

11872

}

else if

(

const CallExpr

*

Call

= dyn_cast<CallExpr>(

E

)) {

11873 if

(!

Call

->getCallReturnType(SemaRef.

Context

)->isReferenceType())

11875

FD =

Call

->getDirectCallee();

11884

SemaRef.

Diag

(FD->

getLocation

(), diag::note_reference_is_return_value) << FD;

11898 if

(

SM

.isMacroBodyExpansion(

Loc

))

11900 Loc

=

SM

.getImmediateMacroCallerLoc(

Loc

);

11923 if

(isa<CXXThisExpr>(

E

)) {

11924 unsigned

DiagID = IsCompare ? diag::warn_this_null_compare

11925

: diag::warn_this_bool_conversion;

11930 bool

IsAddressOf =

false

;

11932 if

(

auto

*UO = dyn_cast<UnaryOperator>(

E

->

IgnoreParens

())) {

11933 if

(UO->getOpcode() != UO_AddrOf)

11935

IsAddressOf =

true

;

11936 E

= UO->getSubExpr();

11940 unsigned

DiagID = IsCompare

11941

? diag::warn_address_of_reference_null_compare

11942

: diag::warn_address_of_reference_bool_conversion;

11950 auto

ComplainAboutNonnullParamOrCall = [&](

const Attr

*NonnullAttr) {

11951 bool

IsParam = isa<NonNullAttr>(NonnullAttr);

11953

llvm::raw_string_ostream S(Str);

11955 unsigned

DiagID = IsCompare ? diag::warn_nonnull_expr_compare

11956

: diag::warn_cast_nonnull_to_bool;

11959 Diag

(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;

11964 if

(

auto

*Callee =

Call

->getDirectCallee()) {

11965 if

(

const Attr

*A = Callee->getAttr<ReturnsNonNullAttr>()) {

11966

ComplainAboutNonnullParamOrCall(A);

11975 if

(

const auto

*MCallExpr = dyn_cast<CXXMemberCallExpr>(

E

)) {

11976 if

(

const auto

*MRecordDecl = MCallExpr->getRecordDecl();

11977

MRecordDecl && MRecordDecl->isLambda()) {

11980

<< MRecordDecl->getSourceRange() <<

Range

<< IsEqual;

11990

}

else if

(

MemberExpr

*M = dyn_cast<MemberExpr>(

E

)) {

11991 D

= M->getMemberDecl();

11995 if

(!

D

||

D

->isWeak())

11999 if

(

const auto

* PV = dyn_cast<ParmVarDecl>(

D

)) {

12002 if

(

const Attr

*A = PV->getAttr<NonNullAttr>()) {

12003

ComplainAboutNonnullParamOrCall(A);

12007 if

(

const auto

*FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {

12011 auto

ParamIter = llvm::find(FD->

parameters

(), PV);

12012

assert(ParamIter != FD->

param_end

());

12013 unsigned

ParamNo = std::distance(FD->

param_begin

(), ParamIter);

12016 if

(!

NonNull

->args_size()) {

12017

ComplainAboutNonnullParamOrCall(

NonNull

);

12022 if

(ArgNo.getASTIndex() == ParamNo) {

12023

ComplainAboutNonnullParamOrCall(

NonNull

);

12037 if

(IsAddressOf && IsFunction) {

12042 if

(!IsAddressOf && !IsFunction && !IsArray)

12047

llvm::raw_string_ostream S(Str);

12050 unsigned

DiagID = IsCompare ? diag::warn_null_pointer_compare

12051

: diag::warn_impcast_pointer_to_bool;

12058

DiagType = AddressOf;

12059 else if

(IsFunction)

12060

DiagType = FunctionPointer;

12062

DiagType = ArrayPointer;

12064

llvm_unreachable(

"Could not determine diagnostic."

);

12066

<<

Range

<< IsEqual;

12079 if

(ReturnType.

isNull

())

12117

CheckArrayAccess(

E

);

12124

::CheckBoolLikeConversion(*

this

,

E

, CC);

12127void

Sema::CheckForIntOverflow (

const Expr

*

E

) {

12132 const Expr

*OriginalE = Exprs.pop_back_val();

12135 if

(isa<BinaryOperator, UnaryOperator>(

E

)) {

12140 if

(

const auto

*InitList = dyn_cast<InitListExpr>(OriginalE))

12141

Exprs.append(InitList->inits().begin(), InitList->inits().end());

12142 else if

(isa<ObjCBoxedExpr>(OriginalE))

12144 else if

(

const auto

*

Call

= dyn_cast<CallExpr>(

E

))

12145

Exprs.append(

Call

->arg_begin(),

Call

->arg_end());

12146 else if

(

const auto

*Message = dyn_cast<ObjCMessageExpr>(

E

))

12147

Exprs.append(Message->arg_begin(), Message->arg_end());

12148 else if

(

const auto

*Construct = dyn_cast<CXXConstructExpr>(

E

))

12149

Exprs.append(Construct->arg_begin(), Construct->arg_end());

12150 else if

(

const auto

*Temporary = dyn_cast<CXXBindTemporaryExpr>(

E

))

12151

Exprs.push_back(Temporary->getSubExpr());

12152 else if

(

const auto

*Array = dyn_cast<ArraySubscriptExpr>(

E

))

12153

Exprs.push_back(Array->getIdx());

12154 else if

(

const auto

*Compound = dyn_cast<CompoundLiteralExpr>(

E

))

12155

Exprs.push_back(Compound->getInitializer());

12156 else if

(

const auto

*New = dyn_cast<CXXNewExpr>(

E

);

12157

New && New->isArray()) {

12158 if

(

auto

ArraySize = New->getArraySize())

12159

Exprs.push_back(*ArraySize);

12160

}

else if

(

const auto

*MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))

12161

Exprs.push_back(MTE->getSubExpr());

12162

}

while

(!Exprs.empty());

12177 class

SequenceTree {

12181

LLVM_PREFERRED_TYPE(

bool

)

12182 unsigned

Merged : 1;

12190 friend class

SequenceTree;

12194 explicit Seq

(

unsigned

N) : Index(N) {}

12197 Seq

() : Index(0) {}

12200

SequenceTree() { Values.push_back(

Value

(0)); }

12201 Seq

root()

const

{

return Seq

(0); }

12208 return Seq

(Values.size() - 1);

12212 void

merge(

Seq

S) {

12213

Values[S.Index].Merged =

true

;

12219 bool

isUnsequenced(

Seq

Cur,

Seq

Old) {

12220 unsigned C

= representative(Cur.Index);

12221 unsigned Target

= representative(Old.Index);

12225 C

= Values[

C

].Parent;

12232 unsigned

representative(

unsigned

K) {

12233 if

(Values[K].Merged)

12235 return

Values[K].Parent = representative(Values[K].

Parent

);

12255

UK_ModAsSideEffect,

12257

UK_Count = UK_ModAsSideEffect + 1

12263 const Expr

*UsageExpr =

nullptr

;

12264

SequenceTree::Seq

Seq

;

12266

Usage() =

default

;

12270

Usage Uses[UK_Count];

12273 bool

Diagnosed =

false

;

12277 using

UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;

12282

SequenceTree

Tree

;

12285

UsageInfoMap UsageMap;

12288

SequenceTree::Seq Region;

12303 struct

SequencedSubexpression {

12304

SequencedSubexpression(SequenceChecker &Self)

12305

: Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {

12306

Self.ModAsSideEffect = &ModAsSideEffect;

12309

~SequencedSubexpression() {

12310 for

(

const

std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {

12314

UsageInfo &UI = Self.UsageMap[M.first];

12315 auto

&SideEffectUsage = UI.Uses[UK_ModAsSideEffect];

12316

Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);

12317

SideEffectUsage = M.second;

12319

Self.ModAsSideEffect = OldModAsSideEffect;

12322

SequenceChecker &Self;

12331 class

EvaluationTracker {

12333

EvaluationTracker(SequenceChecker &Self)

12334

: Self(Self), Prev(Self.EvalTracker) {

12335

Self.EvalTracker =

this

;

12338

~EvaluationTracker() {

12339

Self.EvalTracker = Prev;

12341

Prev->EvalOK &= EvalOK;

12344 bool

evaluate(

const Expr

*

E

,

bool

&Result) {

12348

Result, Self.SemaRef.Context,

12349

Self.SemaRef.isConstantEvaluatedContext());

12354

SequenceChecker &Self;

12355

EvaluationTracker *Prev;

12356 bool

EvalOK =

true

;

12357

} *EvalTracker =

nullptr

;

12361 Object

getObject(

const Expr

*

E

,

bool

Mod)

const

{

12364 if

(Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))

12365 return

getObject(UO->getSubExpr(), Mod);

12366

}

else if

(

const BinaryOperator

*BO = dyn_cast<BinaryOperator>(

E

)) {

12367 if

(BO->getOpcode() == BO_Comma)

12368 return

getObject(BO->getRHS(), Mod);

12369 if

(Mod && BO->isAssignmentOp())

12370 return

getObject(BO->getLHS(), Mod);

12371

}

else if

(

const MemberExpr

*ME = dyn_cast<MemberExpr>(

E

)) {

12373 if

(isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))

12374 return

ME->getMemberDecl();

12375

}

else if

(

const DeclRefExpr

*DRE = dyn_cast<DeclRefExpr>(

E

))

12384 void

addUsage(Object O, UsageInfo &UI,

const Expr

*UsageExpr, UsageKind UK) {

12386

Usage &

U

= UI.Uses[UK];

12387 if

(!

U

.UsageExpr || !

Tree

.isUnsequenced(Region,

U

.Seq)) {

12391 if

(UK == UK_ModAsSideEffect && ModAsSideEffect)

12392

ModAsSideEffect->push_back(std::make_pair(O,

U

));

12394 U

.UsageExpr = UsageExpr;

12404 void

checkUsage(Object O, UsageInfo &UI,

const Expr

*UsageExpr,

12405

UsageKind OtherKind,

bool

IsModMod) {

12409 const

Usage &

U

= UI.Uses[OtherKind];

12410 if

(!

U

.UsageExpr || !

Tree

.isUnsequenced(Region,

U

.Seq))

12413 const Expr

*Mod =

U

.UsageExpr;

12414 const Expr

*ModOrUse = UsageExpr;

12415 if

(OtherKind == UK_Use)

12416

std::swap(Mod, ModOrUse);

12420

SemaRef.

PDiag

(IsModMod ? diag::warn_unsequenced_mod_mod

12421

: diag::warn_unsequenced_mod_use)

12423

UI.Diagnosed =

true

;

12452 void

notePreUse(Object O,

const Expr

*UseExpr) {

12453

UsageInfo &UI = UsageMap[O];

12455

checkUsage(O, UI, UseExpr,

UK_ModAsValue,

false

);

12458 void

notePostUse(Object O,

const Expr

*UseExpr) {

12459

UsageInfo &UI = UsageMap[O];

12460

checkUsage(O, UI, UseExpr,

UK_ModAsSideEffect,

12462

addUsage(O, UI, UseExpr,

UK_Use);

12465 void

notePreMod(Object O,

const Expr

*ModExpr) {

12466

UsageInfo &UI = UsageMap[O];

12468

checkUsage(O, UI, ModExpr,

UK_ModAsValue,

true

);

12469

checkUsage(O, UI, ModExpr,

UK_Use,

false

);

12472 void

notePostMod(Object O,

const Expr

*ModExpr, UsageKind UK) {

12473

UsageInfo &UI = UsageMap[O];

12474

checkUsage(O, UI, ModExpr,

UK_ModAsSideEffect,

12476

addUsage(O, UI, ModExpr,

UK);

12480

SequenceChecker(

Sema

&S,

const Expr

*

E

,

12482

:

Base

(S.Context), SemaRef(S), Region(

Tree

.root()), WorkList(WorkList) {

12486

(void)this->WorkList;

12489 void

VisitStmt(

const Stmt

*S) {

12493 void

VisitExpr(

const Expr

*

E

) {

12495

Base::VisitStmt(

E

);

12499 for

(

auto

*Sub : CSE->

children

()) {

12500 const Expr

*ChildExpr = dyn_cast_or_null<Expr>(Sub);

12515 void

VisitCastExpr(

const CastExpr

*

E

) {

12517 if

(

E

->getCastKind() == CK_LValueToRValue)

12518

O = getObject(

E

->getSubExpr(),

false

);

12524

notePostUse(O,

E

);

12527 void

VisitSequencedExpressions(

const Expr

*SequencedBefore,

12528 const Expr

*SequencedAfter) {

12529

SequenceTree::Seq BeforeRegion =

Tree

.allocate(Region);

12530

SequenceTree::Seq AfterRegion =

Tree

.allocate(Region);

12531

SequenceTree::Seq OldRegion = Region;

12534

SequencedSubexpression SeqBefore(*

this

);

12535

Region = BeforeRegion;

12536

Visit(SequencedBefore);

12539

Region = AfterRegion;

12540

Visit(SequencedAfter);

12542

Region = OldRegion;

12544 Tree

.merge(BeforeRegion);

12545 Tree

.merge(AfterRegion);

12553

VisitSequencedExpressions(ASE->

getLHS

(), ASE->

getRHS

());

12560 void

VisitBinPtrMemD(

const BinaryOperator

*BO) { VisitBinPtrMem(BO); }

12561 void

VisitBinPtrMemI(

const BinaryOperator

*BO) { VisitBinPtrMem(BO); }

12567

VisitSequencedExpressions(BO->

getLHS

(), BO->

getRHS

());

12574 void

VisitBinShl(

const BinaryOperator

*BO) { VisitBinShlShr(BO); }

12575 void

VisitBinShr(

const BinaryOperator

*BO) { VisitBinShlShr(BO); }

12580

VisitSequencedExpressions(BO->

getLHS

(), BO->

getRHS

());

12592

VisitSequencedExpressions(BO->

getLHS

(), BO->

getRHS

());

12596

SequenceTree::Seq RHSRegion;

12597

SequenceTree::Seq LHSRegion;

12599

RHSRegion =

Tree

.allocate(Region);

12600

LHSRegion =

Tree

.allocate(Region);

12602

RHSRegion = Region;

12603

LHSRegion = Region;

12605

SequenceTree::Seq OldRegion = Region;

12621

SequencedSubexpression SeqBefore(*

this

);

12622

Region = RHSRegion;

12626

Region = LHSRegion;

12629 if

(O && isa<CompoundAssignOperator>(BO))

12630

notePostUse(O, BO);

12634

Region = LHSRegion;

12637 if

(O && isa<CompoundAssignOperator>(BO))

12638

notePostUse(O, BO);

12640

Region = RHSRegion;

12648

Region = OldRegion;

12651

SemaRef.

getLangOpts

().CPlusPlus ? UK_ModAsValue

12652

: UK_ModAsSideEffect);

12654 Tree

.merge(RHSRegion);

12655 Tree

.merge(LHSRegion);

12660

VisitBinAssign(CAO);

12663 void

VisitUnaryPreInc(

const UnaryOperator

*UO) { VisitUnaryPreIncDec(UO); }

12664 void

VisitUnaryPreDec(

const UnaryOperator

*UO) { VisitUnaryPreIncDec(UO); }

12668 return

VisitExpr(UO);

12675

SemaRef.

getLangOpts

().CPlusPlus ? UK_ModAsValue

12676

: UK_ModAsSideEffect);

12679 void

VisitUnaryPostInc(

const UnaryOperator

*UO) { VisitUnaryPostIncDec(UO); }

12680 void

VisitUnaryPostDec(

const UnaryOperator

*UO) { VisitUnaryPostIncDec(UO); }

12684 return

VisitExpr(UO);

12688

notePostMod(O, UO, UK_ModAsSideEffect);

12697

SequenceTree::Seq LHSRegion =

Tree

.allocate(Region);

12698

SequenceTree::Seq RHSRegion =

Tree

.allocate(Region);

12699

SequenceTree::Seq OldRegion = Region;

12701

EvaluationTracker Eval(*

this

);

12703

SequencedSubexpression Sequenced(*

this

);

12704

Region = LHSRegion;

12711 bool

EvalResult =

false

;

12712 bool

EvalOK = Eval.evaluate(BO->

getLHS

(), EvalResult);

12713 bool

ShouldVisitRHS = !EvalOK || !EvalResult;

12714 if

(ShouldVisitRHS) {

12715

Region = RHSRegion;

12719

Region = OldRegion;

12720 Tree

.merge(LHSRegion);

12721 Tree

.merge(RHSRegion);

12730

SequenceTree::Seq LHSRegion =

Tree

.allocate(Region);

12731

SequenceTree::Seq RHSRegion =

Tree

.allocate(Region);

12732

SequenceTree::Seq OldRegion = Region;

12734

EvaluationTracker Eval(*

this

);

12736

SequencedSubexpression Sequenced(*

this

);

12737

Region = LHSRegion;

12743 bool

EvalResult =

false

;

12744 bool

EvalOK = Eval.evaluate(BO->

getLHS

(), EvalResult);

12745 bool

ShouldVisitRHS = !EvalOK || EvalResult;

12746 if

(ShouldVisitRHS) {

12747

Region = RHSRegion;

12751

Region = OldRegion;

12752 Tree

.merge(LHSRegion);

12753 Tree

.merge(RHSRegion);

12761

SequenceTree::Seq ConditionRegion =

Tree

.allocate(Region);

12777

SequenceTree::Seq TrueRegion =

Tree

.allocate(Region);

12778

SequenceTree::Seq FalseRegion =

Tree

.allocate(Region);

12779

SequenceTree::Seq OldRegion = Region;

12781

EvaluationTracker Eval(*

this

);

12783

SequencedSubexpression Sequenced(*

this

);

12784

Region = ConditionRegion;

12794 bool

EvalResult =

false

;

12795 bool

EvalOK = Eval.evaluate(CO->

getCond

(), EvalResult);

12796 bool

ShouldVisitTrueExpr = !EvalOK || EvalResult;

12797 bool

ShouldVisitFalseExpr = !EvalOK || !EvalResult;

12798 if

(ShouldVisitTrueExpr) {

12799

Region = TrueRegion;

12802 if

(ShouldVisitFalseExpr) {

12803

Region = FalseRegion;

12807

Region = OldRegion;

12808 Tree

.merge(ConditionRegion);

12809 Tree

.merge(TrueRegion);

12810 Tree

.merge(FalseRegion);

12813 void

VisitCallExpr(

const CallExpr

*CE) {

12825

SequencedSubexpression Sequenced(*

this

);

12830

SequenceTree::Seq CalleeRegion;

12831

SequenceTree::Seq OtherRegion;

12832

if (SemaRef.getLangOpts().CPlusPlus17) {

12833

CalleeRegion = Tree.allocate(Region);

12834

OtherRegion = Tree.allocate(Region);

12836

CalleeRegion = Region;

12837

OtherRegion = Region;

12839

SequenceTree::Seq OldRegion = Region;

12842

Region = CalleeRegion;

12844

SequencedSubexpression Sequenced(*this);

12845

Visit(CE->getCallee());

12847

Visit(CE->getCallee());

12851

Region = OtherRegion;

12855

Region = OldRegion;

12857

Tree.merge(CalleeRegion);

12858

Tree.merge(OtherRegion);

12876 return

VisitCallExpr(CXXOCE);

12887 case

OO_MinusEqual:

12889 case

OO_SlashEqual:

12890 case

OO_PercentEqual:

12891 case

OO_CaretEqual:

12894 case

OO_LessLessEqual:

12895 case

OO_GreaterGreaterEqual:

12896

SequencingKind = RHSBeforeLHS;

12900 case

OO_GreaterGreater:

12906

SequencingKind = LHSBeforeRHS;

12910

SequencingKind = LHSBeforeRest;

12914

SequencingKind = NoSequencing;

12918 if

(SequencingKind == NoSequencing)

12919 return

VisitCallExpr(CXXOCE);

12922

SequencedSubexpression Sequenced(*

this

);

12925

assert(SemaRef.getLangOpts().CPlusPlus17 &&

12926 "Should only get there with C++17 and above!"

);

12927

assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&

12928 "Should only get there with an overloaded binary operator" 12929 " or an overloaded call operator!"

);

12931

if (SequencingKind == LHSBeforeRest) {

12932

assert(CXXOCE->getOperator() == OO_Call &&

12933 "We should only have an overloaded call operator here!"

);

12942

SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);

12943

SequenceTree::Seq ArgsRegion = Tree.allocate(Region);

12944

SequenceTree::Seq OldRegion = Region;

12946

assert(CXXOCE->getNumArgs() >= 1 &&

12947 "An overloaded call operator must have at least one argument" 12948 " for the postfix-expression!"

);

12949

const Expr *PostfixExpr = CXXOCE->getArgs()[0];

12950

llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,

12951

CXXOCE->getNumArgs() - 1);

12955

Region = PostfixExprRegion;

12956

SequencedSubexpression Sequenced(*this);

12957

Visit(PostfixExpr);

12961

Region = ArgsRegion;

12962

for (const Expr *Arg : Args)

12965

Region = OldRegion;

12966

Tree.merge(PostfixExprRegion);

12967

Tree.merge(ArgsRegion);

12969

assert(CXXOCE->getNumArgs() == 2 &&

12970 "Should only have two arguments here!"

);

12971

assert((SequencingKind == LHSBeforeRHS ||

12972

SequencingKind == RHSBeforeLHS) &&

12973 "Unexpected sequencing kind!"

);

12977

const Expr *E1 = CXXOCE->getArg(0);

12978

const Expr *E2 = CXXOCE->getArg(1);

12979

if (SequencingKind == RHSBeforeLHS)

12982

return VisitSequencedExpressions(E1, E2);

12989

SequencedSubexpression Sequenced(*

this

);

12992 return

VisitExpr(CCE);

12995

SequenceExpressionsInOrder(

13001 return

VisitExpr(ILE);

13004

SequenceExpressionsInOrder(ILE->

inits

());

13016

SequenceTree::Seq

Parent

= Region;

13017 for

(

const Expr

*

E

: ExpressionList) {

13021

Elts.push_back(Region);

13027 for

(

unsigned

I = 0; I < Elts.size(); ++I)

13028 Tree

.merge(Elts[I]);

13032

SequenceChecker::UsageInfo::UsageInfo() =

default

;

13036void

Sema::CheckUnsequencedOperations(

const Expr

*

E

) {

13038

WorkList.push_back(

E

);

13039 while

(!WorkList.empty()) {

13040 const Expr

*Item = WorkList.pop_back_val();

13041

SequenceChecker(*

this

, Item, WorkList);

13046 bool

IsConstexpr) {

13048

IsConstexpr || isa<ConstantExpr>(

E

));

13049

CheckImplicitConversions(

E

, CheckLoc);

13051

CheckUnsequencedOperations(

E

);

13053

CheckForIntOverflow(

E

);

13067 if

(

const auto

*PointerTy = dyn_cast<PointerType>(PType)) {

13071 if

(

const auto

*ReferenceTy = dyn_cast<ReferenceType>(PType)) {

13075 if

(

const auto

*ParenTy = dyn_cast<ParenType>(PType)) {

13089

S.

Diag

(

Loc

, diag::err_array_star_in_function_definition);

13093 bool

CheckParameterNames) {

13094 bool

HasInvalidParm =

false

;

13096

assert(Param &&

"null in a parameter list"

);

13105 if

(!Param->isInvalidDecl() &&

13107

diag::err_typecheck_decl_incomplete_type) ||

13109

diag::err_abstract_type_in_decl,

13111

Param->setInvalidDecl();

13112

HasInvalidParm =

true

;

13117 if

(CheckParameterNames && Param->getIdentifier() ==

nullptr

&&

13121 Diag

(Param->getLocation(), diag::ext_parameter_name_omitted_c23);

13129 QualType

PType = Param->getOriginalType();

13137 if

(!Param->isInvalidDecl()) {

13139 if

(!ClassDecl->isInvalidDecl() &&

13140

!ClassDecl->hasIrrelevantDestructor() &&

13141

!ClassDecl->isDependentContext() &&

13142

ClassDecl->isParamDestroyedInCallee()) {

13154 if

(

const auto

*

Attr

= Param->getAttr<PassObjectSizeAttr>())

13155 if

(!Param->getType().isConstQualified())

13156 Diag

(Param->getLocation(), diag::err_attribute_pointers_only)

13160 if

(

LangOpts

.CPlusPlus && !Param->isInvalidDecl()) {

13165 if

(

auto

*RD = dyn_cast<CXXRecordDecl>(DC->

getParent

()))

13166

CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),

13171 if

(!Param->isInvalidDecl() &&

13173

Param->setInvalidDecl();

13174

HasInvalidParm =

true

;

13175 Diag

(Param->getLocation(), diag::err_wasm_table_as_function_parameter);

13179 return

HasInvalidParm;

13182

std::optional<std::pair<

13191static

std::pair<CharUnits, CharUnits>

13199 if

(

Base

->isVirtual()) {

13206

BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);

13213

DerivedType =

Base

->getType();

13216 return

std::make_pair(BaseAlignment, Offset);

13220static

std::optional<std::pair<CharUnits, CharUnits>>

13226 return

std::nullopt;

13231 return

std::nullopt;

13235 CharUnits

Offset = EltSize * IdxRes->getExtValue();

13238 return

std::make_pair(

P

->first,

P

->second + Offset);

13244 return

std::make_pair(

13245 P

->first.alignmentAtOffset(

P

->second).alignmentAtOffset(EltSize),

13251

std::optional<std::pair<

13259 case

Stmt::CStyleCastExprClass:

13260 case

Stmt::CXXStaticCastExprClass:

13261 case

Stmt::ImplicitCastExprClass: {

13262 auto

*CE = cast<CastExpr>(

E

);

13263 const Expr

*From = CE->getSubExpr();

13264 switch

(CE->getCastKind()) {

13269 case

CK_UncheckedDerivedToBase:

13270 case

CK_DerivedToBase: {

13280 case

Stmt::ArraySubscriptExprClass: {

13281 auto

*ASE = cast<ArraySubscriptExpr>(

E

);

13285 case

Stmt::DeclRefExprClass: {

13286 if

(

auto

*VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(

E

)->getDecl())) {

13289 if

(!VD->getType()->isReferenceType()) {

13291 if

(VD->hasDependentAlignment())

13300 case

Stmt::MemberExprClass: {

13301 auto

*ME = cast<MemberExpr>(

E

);

13302 auto

*FD = dyn_cast<FieldDecl>(ME->getMemberDecl());

13306

std::optional<std::pair<CharUnits, CharUnits>>

P

;

13315 return

std::make_pair(

P

->first,

13318 case

Stmt::UnaryOperatorClass: {

13319 auto

*UO = cast<UnaryOperator>(

E

);

13328 case

Stmt::BinaryOperatorClass: {

13329 auto

*BO = cast<BinaryOperator>(

E

);

13340 return

std::nullopt;

13345

std::optional<std::pair<

13354 case

Stmt::CStyleCastExprClass:

13355 case

Stmt::CXXStaticCastExprClass:

13356 case

Stmt::ImplicitCastExprClass: {

13357 auto

*CE = cast<CastExpr>(

E

);

13358 const Expr

*From = CE->getSubExpr();

13359 switch

(CE->getCastKind()) {

13364 case

CK_ArrayToPointerDecay:

13366 case

CK_UncheckedDerivedToBase:

13367 case

CK_DerivedToBase: {

13377 case

Stmt::CXXThisExprClass: {

13382 case

Stmt::UnaryOperatorClass: {

13383 auto

*UO = cast<UnaryOperator>(

E

);

13388 case

Stmt::BinaryOperatorClass: {

13389 auto

*BO = cast<BinaryOperator>(

E

);

13397 if

(Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())

13398

std::swap(LHS, RHS);

13408 return

std::nullopt;

13413

std::optional<std::pair<CharUnits, CharUnits>>

P

=

13417 return P

->first.alignmentAtOffset(

P

->second);

13435 if

(!DestPtr)

return

;

13441 if

(DestAlign.

isOne

())

return

;

13445 if

(!SrcPtr)

return

;

13456 if

(SrcAlign >= DestAlign)

return

;

13460

<<

static_cast<unsigned>

(SrcAlign.

getQuantity

())

13461

<<

static_cast<unsigned>

(DestAlign.

getQuantity

())

13465void

Sema::CheckArrayAccess(

const Expr

*BaseExpr,

const Expr

*IndexExpr,

13467 bool

AllowOnePastEnd,

bool

IndexNegated) {

13476 const Type

*EffectiveType =

13483

StrictFlexArraysLevel =

getLangOpts

().getStrictFlexArraysLevel();

13485 const Type

*BaseType =

13487 bool

IsUnboundedArray =

13489 Context

, StrictFlexArraysLevel,

13499

llvm::APSInt index =

Result

.Val.getInt();

13500 if

(IndexNegated) {

13501

index.setIsUnsigned(

false

);

13505 if

(IsUnboundedArray) {

13508 if

(index.isUnsigned() || !index.isNegative()) {

13510 unsigned

AddrBits = ASTC.getTargetInfo().getPointerWidth(

13512 if

(index.getBitWidth() < AddrBits)

13513

index = index.zext(AddrBits);

13514

std::optional<CharUnits> ElemCharUnits =

13515

ASTC.getTypeSizeInCharsIfKnown(EffectiveType);

13518 if

(!ElemCharUnits || ElemCharUnits->isZero())

13520

llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());

13525 if

(index.getActiveBits() <= AddrBits) {

13527

llvm::APInt Product(index);

13529

Product = Product.umul_ov(ElemBytes, Overflow);

13530 if

(!Overflow && Product.getActiveBits() <= AddrBits)

13536

llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);

13537

MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));

13539

ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());

13540

MaxElems = MaxElems.udiv(ElemBytes);

13543

ASE ? diag::warn_array_index_exceeds_max_addressable_bounds

13544

: diag::warn_ptr_arith_exceeds_max_addressable_bounds;

13550

<<

toString

(index, 10,

true

) << AddrBits

13551

<< (

unsigned

)ASTC.toBits(*ElemCharUnits)

13552

<<

toString

(ElemBytes, 10,

false

)

13553

<<

toString

(MaxElems, 10,

false

)

13554

<< (

unsigned

)MaxElems.getLimitedValue(~0

U

)

13559 while

(

const auto

*ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))

13561 if

(

const auto

*DRE = dyn_cast<DeclRefExpr>(BaseExpr))

13563 if

(

const auto

*ME = dyn_cast<MemberExpr>(BaseExpr))

13564

ND = ME->getMemberDecl();

13568 PDiag

(diag::note_array_declared_here) << ND);

13573 if

(index.isUnsigned() || !index.isNegative()) {

13583

llvm::APInt size = ArrayTy->

getSize

();

13585 if

(BaseType != EffectiveType) {

13593 if

(!ptrarith_typesize)

13596 if

(ptrarith_typesize != array_typesize) {

13598 uint64_t

ratio = array_typesize / ptrarith_typesize;

13602 if

(ptrarith_typesize * ratio == array_typesize)

13603

size *= llvm::APInt(size.getBitWidth(), ratio);

13607 if

(size.getBitWidth() > index.getBitWidth())

13608

index = index.zext(size.getBitWidth());

13609 else if

(size.getBitWidth() < index.getBitWidth())

13610

size = size.zext(index.getBitWidth());

13616 if

(AllowOnePastEnd ? index.ule(size) : index.ult(size))

13633 unsigned

DiagID = ASE ? diag::warn_array_index_exceeds_bounds

13634

: diag::warn_ptr_arith_exceeds_bounds;

13635 unsigned

CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;

13643 unsigned

DiagID = diag::warn_array_index_precedes_bounds;

13645

DiagID = diag::warn_ptr_arith_precedes_bounds;

13646 if

(index.isNegative()) index = -index;

13656 while

(

const auto

*ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))

13658 if

(

const auto

*DRE = dyn_cast<DeclRefExpr>(BaseExpr))

13660 if

(

const auto

*ME = dyn_cast<MemberExpr>(BaseExpr))

13661

ND = ME->getMemberDecl();

13665 PDiag

(diag::note_array_declared_here) << ND);

13668void

Sema::CheckArrayAccess(

const Expr

*

expr

) {

13669 int

AllowOnePastEnd = 0;

13671 expr

=

expr

->IgnoreParenImpCasts();

13672 switch

(

expr

->getStmtClass()) {

13673 case

Stmt::ArraySubscriptExprClass: {

13676

AllowOnePastEnd > 0);

13680 case

Stmt::MemberExprClass: {

13681 expr

= cast<MemberExpr>(

expr

)->getBase();

13684 case

Stmt::ArraySectionExprClass: {

13690 nullptr

, AllowOnePastEnd > 0);

13693 case

Stmt::UnaryOperatorClass: {

13709 case

Stmt::ConditionalOperatorClass: {

13712

CheckArrayAccess(lhs);

13714

CheckArrayAccess(rhs);

13717 case

Stmt::CXXOperatorCallExprClass: {

13718 const auto

*OCE = cast<CXXOperatorCallExpr>(

expr

);

13719 for

(

const auto

*Arg : OCE->arguments())

13720

CheckArrayAccess(Arg);

13730 Expr

*RHS,

bool

isProperty) {

13742

S.

Diag

(

Loc

, diag::warn_arc_literal_assign)

13744

<< (isProperty ? 0 : 1)

13752 Expr

*RHS,

bool

isProperty) {

13755 if

(

cast

->getCastKind() == CK_ARCConsumeObject) {

13756

S.

Diag

(

Loc

, diag::warn_arc_retained_assign)

13758

<< (isProperty ? 0 : 1)

13762

RHS =

cast

->getSubExpr();

13791

= dyn_cast<ObjCPropertyRefExpr>(LHS->

IgnoreParens

());

13833 if

(

cast

->getCastKind() == CK_ARCConsumeObject) {

13834 Diag

(

Loc

, diag::warn_arc_retained_property_assign)

13838

RHS =

cast

->getSubExpr();

13861 bool

StmtLineInvalid;

13864 if

(StmtLineInvalid)

13867 bool

BodyLineInvalid;

13870 if

(BodyLineInvalid)

13874 if

(StmtLine != BodyLine)

13889 const NullStmt

*NBody = dyn_cast<NullStmt>(Body);

13898 Diag

(NBody->

getSemiLoc

(), diag::note_empty_body_on_separate_line);

13902 const Stmt

*PossibleBody) {

13908 if

(

const ForStmt

*FS = dyn_cast<ForStmt>(S)) {

13909

StmtLoc = FS->getRParenLoc();

13910

Body = FS->getBody();

13911

DiagID = diag::warn_empty_for_body;

13912

}

else if

(

const WhileStmt

*WS = dyn_cast<WhileStmt>(S)) {

13913

StmtLoc = WS->getRParenLoc();

13914

Body = WS->getBody();

13915

DiagID = diag::warn_empty_while_body;

13920 const NullStmt

*NBody = dyn_cast<NullStmt>(Body);

13943 bool

ProbableTypo = isa<CompoundStmt>(PossibleBody);

13944 if

(!ProbableTypo) {

13945 bool

BodyColInvalid;

13948 if

(BodyColInvalid)

13951 bool

StmtColInvalid;

13954 if

(StmtColInvalid)

13957 if

(BodyCol > StmtCol)

13958

ProbableTypo =

true

;

13961 if

(ProbableTypo) {

13963 Diag

(NBody->

getSemiLoc

(), diag::note_empty_body_on_separate_line);

13971 if

(

Diags

.

isIgnored

(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))

13983 if

(

const auto

*CE = dyn_cast<CallExpr>(RHSExpr);

13985

RHSExpr = CE->

getArg

(0);

13986 else if

(

const auto

*CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);

13987

CXXSCE && CXXSCE->isXValue())

13988

RHSExpr = CXXSCE->getSubExpr();

13992 const DeclRefExpr

*LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);

13993 const DeclRefExpr

*RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);

13996 if

(LHSDeclRef && RHSDeclRef) {

14003 auto D

=

Diag

(OpLoc, diag::warn_self_move)

14019 const Expr

*LHSBase = LHSExpr;

14020 const Expr

*RHSBase = RHSExpr;

14021 const MemberExpr

*LHSME = dyn_cast<MemberExpr>(LHSExpr);

14022 const MemberExpr

*RHSME = dyn_cast<MemberExpr>(RHSExpr);

14023 if

(!LHSME || !RHSME)

14026 while

(LHSME && RHSME) {

14031

LHSBase = LHSME->

getBase

();

14032

RHSBase = RHSME->

getBase

();

14033

LHSME = dyn_cast<MemberExpr>(LHSBase);

14034

RHSME = dyn_cast<MemberExpr>(RHSBase);

14037

LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);

14038

RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);

14039 if

(LHSDeclRef && RHSDeclRef) {

14046 Diag

(OpLoc, diag::warn_self_move)

14052 if

(isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))

14053 Diag

(OpLoc, diag::warn_self_move)

14077 bool

AreUnionMembers =

false

) {

14078

[[maybe_unused]]

const Type

*Field1Parent =

14080

[[maybe_unused]]

const Type

*Field2Parent =

14085 "Can't evaluate layout compatibility between a struct field and a " 14088

(AreUnionMembers && Field1Parent->

isUnionType

())) &&

14089 "AreUnionMembers should be 'true' for union fields (only)."

);

14102 if

(Bits1 != Bits2)

14106 if

(Field1->

hasAttr

<clang::NoUniqueAddressAttr>() ||

14107

Field2->

hasAttr

<clang::NoUniqueAddressAttr>())

14110 if

(!AreUnionMembers &&

14122 if

(

const CXXRecordDecl

*D1CXX = dyn_cast<CXXRecordDecl>(RD1))

14123

RD1 = D1CXX->getStandardLayoutBaseWithFields();

14125 if

(

const CXXRecordDecl

*D2CXX = dyn_cast<CXXRecordDecl>(RD2))

14126

RD2 = D2CXX->getStandardLayoutBaseWithFields();

14131

return isLayoutCompatible(C, F1, F2);

14140 for

(

auto

*Field2 : RD2->

fields

())

14141

UnmatchedFields.insert(Field2);

14143 for

(

auto

*Field1 : RD1->

fields

()) {

14144 auto

I = UnmatchedFields.begin();

14145 auto E

= UnmatchedFields.end();

14147 for

( ; I !=

E

; ++I) {

14149 bool Result

= UnmatchedFields.erase(*I);

14159 return

UnmatchedFields.empty();

14185 if

(

C

.hasSameType(T1, T2))

14194 if

(TC1 == Type::Enum) {

14196

cast<EnumType>(T1)->getDecl(),

14197

cast<EnumType>(T2)->getDecl());

14198

}

else if

(TC1 == Type::Record) {

14203

cast<RecordType>(T1)->getDecl(),

14204

cast<RecordType>(T2)->getDecl());

14218 QualType

BaseT =

Base

->getType()->getCanonicalTypeUnqualified();

14249 const ValueDecl

**VD, uint64_t *MagicValue,

14250 bool

isConstantEvaluated) {

14258 case

Stmt::UnaryOperatorClass: {

14267 case

Stmt::DeclRefExprClass: {

14268 const DeclRefExpr

*DRE = cast<DeclRefExpr>(TypeExpr);

14273 case

Stmt::IntegerLiteralClass: {

14275

llvm::APInt MagicValueAPInt = IL->

getValue

();

14276 if

(MagicValueAPInt.getActiveBits() <= 64) {

14277

*MagicValue = MagicValueAPInt.getZExtValue();

14283 case

Stmt::BinaryConditionalOperatorClass:

14284 case

Stmt::ConditionalOperatorClass: {

14286

cast<AbstractConditionalOperator>(TypeExpr);

14289

isConstantEvaluated)) {

14299 case

Stmt::BinaryOperatorClass: {

14302

TypeExpr = BO->

getRHS

();

14332 const

llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>

14335 bool

isConstantEvaluated) {

14336

FoundWrongKind =

false

;

14341

uint64_t MagicValue;

14343 if

(!

FindTypeTagExpr

(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))

14347 if

(TypeTagForDatatypeAttr *I = VD->

getAttr

<TypeTagForDatatypeAttr>()) {

14348 if

(I->getArgumentKind() != ArgumentKind) {

14349

FoundWrongKind =

true

;

14352 TypeInfo

.Type = I->getMatchingCType();

14353 TypeInfo

.LayoutCompatible = I->getLayoutCompatible();

14354 TypeInfo

.MustBeNull = I->getMustBeNull();

14365

MagicValues->find(std::make_pair(ArgumentKind, MagicValue));

14366 if

(I == MagicValues->end())

14375 bool

LayoutCompatible,

14377 if

(!TypeTagForDatatypeMagicValues)

14378

TypeTagForDatatypeMagicValues.reset(

14379 new

llvm::DenseMap<TypeTagMagicValue, TypeTagData>);

14382

(*TypeTagForDatatypeMagicValues)[Magic] =

14398 return

(T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||

14399

(T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||

14400

(T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||

14401

(T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);

14404void

Sema::CheckArgumentWithTypeTag(

const

ArgumentWithTypeTagAttr *

Attr

,

14408 bool

IsPointerAttr =

Attr

->getIsPointer();

14411 unsigned

TypeTagIdxAST =

Attr

->getTypeTagIdx().getASTIndex();

14412 if

(TypeTagIdxAST >= ExprArgs.size()) {

14413 Diag

(CallSiteLoc, diag::err_tag_index_out_of_range)

14414

<< 0 <<

Attr

->getTypeTagIdx().getSourceIndex();

14417 const Expr

*TypeTagExpr = ExprArgs[TypeTagIdxAST];

14418 bool

FoundWrongKind;

14421

TypeTagForDatatypeMagicValues.get(), FoundWrongKind,

14423 if

(FoundWrongKind)

14425

diag::warn_type_tag_for_datatype_wrong_kind)

14431 unsigned

ArgumentIdxAST =

Attr

->getArgumentIdx().getASTIndex();

14432 if

(ArgumentIdxAST >= ExprArgs.size()) {

14433 Diag

(CallSiteLoc, diag::err_tag_index_out_of_range)

14434

<< 1 <<

Attr

->getArgumentIdx().getSourceIndex();

14437 const Expr

*ArgumentExpr = ExprArgs[ArgumentIdxAST];

14438 if

(IsPointerAttr) {

14440 if

(

const ImplicitCastExpr

*ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))

14441 if

(ICE->getType()->isVoidPointerType() &&

14442

ICE->getCastKind() == CK_BitCast)

14443

ArgumentExpr = ICE->getSubExpr();

14456

diag::warn_type_safety_null_pointer_required)

14468 bool

mismatch =

false

;

14469 if

(!

TypeInfo

.LayoutCompatible) {

14480

(!IsPointerAttr &&

IsSameCharType

(ArgumentType, RequiredType)))

14491 Diag

(ArgumentExpr->

getExprLoc

(), diag::warn_type_safety_type_mismatch)

14492

<< ArgumentType << ArgumentKind

14493

<<

TypeInfo

.LayoutCompatible << RequiredType

14500

MisalignedMembers.emplace_back(

E

, RD, MD, Alignment);

14504 for

(MisalignedMember &m : MisalignedMembers) {

14506 if

(ND->

getName

().empty()) {

14510 Diag

(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)

14513

MisalignedMembers.clear();

14520 if

(isa<UnaryOperator>(

E

) &&

14521

cast<UnaryOperator>(

E

)->getOpcode() == UO_AddrOf) {

14522 auto

*Op = cast<UnaryOperator>(

E

)->getSubExpr()->

IgnoreParens

();

14523 if

(isa<MemberExpr>(Op)) {

14524 auto

*MA = llvm::find(MisalignedMembers, MisalignedMember(Op));

14525 if

(MA != MisalignedMembers.end() &&

14530

MisalignedMembers.erase(MA);

14539 const auto

*ME = dyn_cast<MemberExpr>(

E

);

14551 bool

AnyIsPacked =

false

;

14553 QualType

BaseType = ME->getBase()->getType();

14563 auto

*FD = dyn_cast<FieldDecl>(MD);

14569

AnyIsPacked || (RD->

hasAttr

<PackedAttr>() || MD->

hasAttr

<PackedAttr>());

14570

ReverseMemberChain.push_back(FD);

14573

ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());

14575

assert(TopME &&

"We did not compute a topmost MemberExpr!"

);

14582 const auto

*DRE = dyn_cast<DeclRefExpr>(TopBase);

14586 if

(!DRE && !isa<CXXThisExpr>(TopBase))

14593 if

(ExpectedAlignment.

isOne

())

14598 for

(

const FieldDecl

*FD : llvm::reverse(ReverseMemberChain))

14603

ReverseMemberChain.back()->getParent()->getTypeForDecl());

14607 if

(DRE && !TopME->

isArrow

()) {

14610

CompleteObjectAlignment =

14615 if

(Offset % ExpectedAlignment != 0 ||

14618

CompleteObjectAlignment < ExpectedAlignment) {

14629 for

(

FieldDecl

*FDI : ReverseMemberChain) {

14630 if

(FDI->hasAttr<PackedAttr>() ||

14631

FDI->getParent()->hasAttr<PackedAttr>()) {

14633

Alignment = std::min(

14639

assert(FD &&

"We did not find a packed FieldDecl!"

);

14640

Action(

E

, FD->

getParent

(), FD, Alignment);

14644void

Sema::CheckAddressOfPackedMember(

Expr

*rhs) {

14645 using namespace

std::placeholders;

14648

rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*

this

), _1,

14682bool

Sema::BuiltinElementwiseMath(

CallExpr

*TheCall,

bool

FPOnly) {

14695 if

(

auto

*VecTy0 = (*Res)->getAs<

VectorType

>())

14696

TheCall->

setType

(VecTy0->getElementType());

14709 return

S.

Diag

(

Loc

, diag::err_conv_mixed_enum_types_cxx26)

14719 return

std::nullopt;

14723 return

std::nullopt;

14726 for

(

int

I = 0; I < 2; ++I) {

14730 return

std::nullopt;

14731

Args[I] = Converted.

get

();

14739 Diag

(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB;

14740 return

std::nullopt;

14745 return

std::nullopt;

14748 return

std::nullopt;

14751

TheCall->

setArg

(0, Args[0]);

14752

TheCall->

setArg

(1, Args[1]);

14757 bool

CheckForFloatArgs) {

14769 for

(

int

I = 0; I < 3; ++I) {

14774

Args[I] = Converted.

get

();

14777 if

(CheckForFloatArgs) {

14778 int

ArgOrdinal = 1;

14779 for

(

Expr

*Arg : Args) {

14781

Arg->

getType

(), ArgOrdinal++))

14785 int

ArgOrdinal = 1;

14786 for

(

Expr

*Arg : Args) {

14793 for

(

int

I = 1; I < 3; ++I) {

14794 if

(Args[0]->getType().getCanonicalType() !=

14795

Args[I]->getType().getCanonicalType()) {

14796 return Diag

(Args[0]->getBeginLoc(),

14797

diag::err_typecheck_call_different_arg_types)

14801

TheCall->

setArg

(I, Args[I]);

14804

TheCall->

setType

(Args[0]->getType());

14808bool

Sema::PrepareBuiltinReduceMathOneArgCall(

CallExpr

*TheCall) {

14820bool

Sema::BuiltinNonDeterministicValue(

CallExpr

*TheCall) {

14829

<< 1 <<

0 << TyArg;

14843 Expr

*Matrix = MatrixArg.

get

();

14848

<< 1 <<

1 << Matrix->

getType

();

14855

MType->getElementType(), MType->getNumColumns(), MType->getNumRows());

14858

TheCall->

setType

(ResultType);

14861

TheCall->

setArg

(0, Matrix);

14866static

std::optional<unsigned>

14869

std::optional<llvm::APSInt>

Value

=

14876

uint64_t

Dim

=

Value

->getZExtValue();

14895 unsigned

PtrArgIdx = 0;

14896 Expr

*PtrExpr = TheCall->

getArg

(PtrArgIdx);

14901 bool

ArgError =

false

;

14908

PtrExpr = PtrConv.

get

();

14909

TheCall->

setArg

(0, PtrExpr);

14920

<< PtrArgIdx + 1 <<

2 << PtrExpr->

getType

();

14927

<< PtrArgIdx + 1 <<

2

14934 auto

ApplyArgumentConversions = [

this

](

Expr

*

E

) {

14943 ExprResult

RowsConv = ApplyArgumentConversions(RowsExpr);

14945

RowsExpr = RowsConv.

get

();

14946

TheCall->

setArg

(1, RowsExpr);

14948

RowsExpr =

nullptr

;

14950 ExprResult

ColumnsConv = ApplyArgumentConversions(ColumnsExpr);

14952

ColumnsExpr = ColumnsConv.

get

();

14953

TheCall->

setArg

(2, ColumnsExpr);

14955

ColumnsExpr =

nullptr

;

14966

std::optional<unsigned> MaybeRows;

14970

std::optional<unsigned> MaybeColumns;

14975 ExprResult

StrideConv = ApplyArgumentConversions(StrideExpr);

14978

StrideExpr = StrideConv.

get

();

14979

TheCall->

setArg

(3, StrideExpr);

14982 if

(std::optional<llvm::APSInt>

Value

=

14985 if

(Stride < *MaybeRows) {

14987

diag::err_builtin_matrix_stride_too_small);

14993 if

(ArgError || !MaybeRows || !MaybeColumns)

15006 unsigned

PtrArgIdx = 1;

15008 Expr

*PtrExpr = TheCall->

getArg

(PtrArgIdx);

15011 bool

ArgError =

false

;

15017

MatrixExpr = MatrixConv.

get

();

15018

TheCall->

setArg

(0, MatrixExpr);

15027 Diag

(MatrixExpr->

getBeginLoc

(), diag::err_builtin_invalid_arg_type)

15028

<< 1 <<

1 << MatrixExpr->

getType

();

15036

PtrExpr = PtrConv.

get

();

15037

TheCall->

setArg

(1, PtrExpr);

15048

<< PtrArgIdx + 1 <<

2 << PtrExpr->

getType

();

15053 Diag

(PtrExpr->

getBeginLoc

(), diag::err_builtin_matrix_store_to_const);

15060

diag::err_builtin_matrix_pointer_arg_mismatch)

15061

<< ElementTy << MatrixTy->getElementType();

15076

StrideExpr = StrideConv.

get

();

15077

TheCall->

setArg

(2, StrideExpr);

15082 if

(std::optional<llvm::APSInt>

Value

=

15085 if

(Stride < MatrixTy->getNumRows()) {

15087

diag::err_builtin_matrix_stride_too_small);

15107 if

(!Caller || !Caller->

hasAttr

<EnforceTCBAttr>())

15112

llvm::StringSet<> CalleeTCBs;

15113 for

(

const auto

*A : Callee->specific_attrs<EnforceTCBAttr>())

15114

CalleeTCBs.insert(A->getTCBName());

15115 for

(

const auto

*A : Callee->specific_attrs<EnforceTCBLeafAttr>())

15116

CalleeTCBs.insert(A->getTCBName());

15120 for

(

const auto

*A : Caller->

specific_attrs

<EnforceTCBAttr>()) {

15121

StringRef CallerTCB = A->getTCBName();

15122 if

(CalleeTCBs.count(CallerTCB) == 0) {

15123

this->

Diag

(CallExprLoc, diag::warn_tcb_enforcement_violation)

15124

<< Callee << CallerTCB;

Defines the clang::ASTContext interface.

ASTImporterLookupTable & LT

Provides definitions for the various language-specific address spaces.

Defines the Diagnostic-related interfaces.

static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)

The XCore ABI includes a type information section that communicates symbol type information to the li...

static Decl::Kind getKind(const Decl *D)

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the clang::Expr interface and subclasses for C++ expressions.

Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::LangOptions interface.

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.

llvm::MachO::Target Target

Defines the clang::OpenCLOptions class.

Defines an enumeration for C++ overloaded operators.

Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.

static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

This file declares semantic analysis functions specific to AMDGPU.

This file declares semantic analysis functions specific to ARM.

This file declares semantic analysis functions specific to BPF.

static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)

Check if two standard-layout unions are layout-compatible.

static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)

Given a type tag expression find the type tag itself.

static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)

static QualType getSizeOfArgType(const Expr *E)

If E is a sizeof expression, returns its argument type.

static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)

static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)

static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)

Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...

static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)

Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).

static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)

static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext)

Diagnose an implicit cast from a floating point value to an integer value.

static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)

static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, bool inFunctionCall, Sema::VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)

static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)

static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)

Checks whether the given value, which currently has the given source semantics, has the same value wh...

static StringLiteralCheckType checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, Sema::VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)

static IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth)

static bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool)

static void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool pruneControlFlow=false)

Diagnose an implicit cast; purely a helper for CheckImplicitConversion.

static void AnalyzeComparison(Sema &S, BinaryOperator *E)

Implements -Wsign-compare.

static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)

static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)

static QualType GetExprType(const Expr *E)

static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)

This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...

static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, SourceLocation CC)

static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)

static AbsoluteValueKind getAbsoluteValueKind(QualType T)

static bool isKnownToHaveUnsignedValue(Expr *E)

static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)

static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)

static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)

static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)

Analyze the given compound assignment for the possible losing of floating-point precision.

static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)

Detect if SizeofExpr is likely to calculate the sizeof an object.

static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)

Check the number of arguments and set the result type to the argument type.

static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)

static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)

static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)

static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)

Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...

static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)

Check conversion of given expression to boolean.

static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)

Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...

static bool checkPointerAuthEnabled(Sema &S, Expr *E)

static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)

static const Expr * getStrlenExprArg(const Expr *E)

static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)

static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)

static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)

BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).

static bool IsSameCharType(QualType T1, QualType T2)

static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)

static bool CheckNonNullExpr(Sema &S, const Expr *Expr)

Checks if a the given expression evaluates to null.

static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)

static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)

Check if the ArgLoc originated from a macro passed to the call at CallLoc.

static const IntegerLiteral * getIntegerLiteral(Expr *E)

static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)

static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)

static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])

static void AnalyzeAssignment(Sema &S, BinaryOperator *E)

Analyze the given simple or compound assignment for warning-worthy operations.

static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)

Check that the argument to __builtin_function_start is a function.

static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)

static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)

static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)

Compute the alignment and offset of the base class object given the derived-to-base cast expression a...

static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)

static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)

static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)

Attempts to estimate an approximate range for the given integer expression.

static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)

static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)

static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)

static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)

static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)

static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)

static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)

Analyzes an attempt to assign the given value to a bitfield.

static int classifyConstantValue(Expr *Constant)

static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)

static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)

static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)

Check if two types are layout-compatible in C++11 sense.

static bool checkPointerAuthKey(Sema &S, Expr *&Arg)

static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)

static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)

static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)

static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)

static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)

static bool IsInfinityFunction(const FunctionDecl *FDecl)

static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)

static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)

static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)

static bool referToTheSameDecl(const Expr *E1, const Expr *E2)

Check if two expressions refer to the same declaration.

static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)

Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...

static bool requiresParensToAddCast(const Expr *E)

static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)

static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)

static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)

static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)

static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)

static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)

static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)

Check if two standard-layout structs are layout-compatible.

static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)

Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.

static const Expr * getSizeOfExprArg(const Expr *E)

If E is a sizeof expression, returns its argument expression, otherwise returns NULL.

static void DiagnoseIntInBoolContext(Sema &S, Expr *E)

static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)

static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)

Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...

static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)

static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)

Check that the user is calling the appropriate va_start builtin for the target and calling convention...

static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)

static bool IsEnumConstOrFromMacro(Sema &S, Expr *E)

static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)

static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)

Retrieve the C type corresponding to type tag TypeExpr.

static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)

static bool isNonNullType(QualType type)

Determine whether the given type has a non-null nullability annotation.

static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)

static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)

Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...

static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)

This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...

static bool IsShiftedByte(llvm::APSInt Value)

static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)

static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)

checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...

static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)

Analyze the operands of the given comparison.

static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, SourceLocation Loc)

static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)

Return true if ICE is an implicit argument promotion of an arithmetic type.

static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)

AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...

static bool HasEnumType(Expr *E)

static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)

Compute the alignment and offset of a binary additive operator.

static bool checkFPMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)

static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)

static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)

This file declares semantic analysis for HLSL constructs.

This file declares semantic analysis functions specific to Hexagon.

This file declares semantic analysis functions specific to LoongArch.

This file declares semantic analysis functions specific to MIPS.

This file declares semantic analysis functions specific to NVPTX.

This file declares semantic analysis for Objective-C.

This file declares semantic analysis routines for OpenCL.

This file declares semantic analysis functions specific to PowerPC.

This file declares semantic analysis functions specific to RISC-V.

This file declares semantic analysis for SPIRV constructs.

This file declares semantic analysis functions specific to SystemZ.

This file declares semantic analysis functions specific to Wasm.

This file declares semantic analysis functions specific to X86.

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

Defines various enumerations that describe declaration and type specifiers.

Provides definitions for the atomic synchronization scopes.

Defines the clang::TypeLoc interface and its subclasses.

Defines enumerations for the type traits support.

C Language Family Type Representation.

const NestedNameSpecifier * Specifier

__DEVICE__ int min(int __a, int __b)

__device__ __2f16 float __ockl_bool s

llvm::APInt getValue() const

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

APSInt & getComplexIntImag()

bool isComplexInt() const

bool isComplexFloat() const

APValue & getVectorElt(unsigned I)

unsigned getVectorLength() const

APSInt & getComplexIntReal()

APFloat & getComplexFloatImag()

APFloat & getComplexFloatReal()

bool isAddrLabelDiff() const

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

const ConstantArrayType * getAsConstantArrayType(QualType T) const

bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType)

Return true if the given vector types are lax-compatible SVE vector types, false otherwise.

CharUnits getTypeAlignInChars(QualType T) const

Return the ABI-specified alignment of a (complete) type T, in characters.

unsigned getIntWidth(QualType T) const

bool areCompatibleRVVTypes(QualType FirstType, QualType SecondType)

Return true if the given types are an RISC-V vector builtin type and a VectorType that is a fixed-len...

const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const

Return the APFloat 'semantics' for the specified scalar floating point type.

uint64_t getFieldOffset(const ValueDecl *FD) const

Get the offset of a FieldDecl or IndirectFieldDecl, in bits.

QualType getRecordType(const RecordDecl *Decl) const

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

Get or compute information about the layout of the specified record (struct/union/class) D,...

CanQualType getCanonicalType(QualType T) const

Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const

Return the unique reference to a vector type of the specified element type and size.

QualType getPointerType(QualType T) const

Return the uniqued reference to the type for a pointer to the specified type.

QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const

Return the uniqued reference to the type for an lvalue reference to the specified type.

Builtin::Context & BuiltinInfo

bool areLaxCompatibleRVVTypes(QualType FirstType, QualType SecondType)

Return true if the given vector types are lax-compatible RISC-V vector types as defined by -flax-vect...

QualType getDecayedType(QualType T) const

Return the uniqued reference to the decayed version of the given type.

int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const

Compare the rank of two floating point types as above, but compare equal if both types have the same ...

QualType getUIntPtrType() const

Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.

QualType getPointerDiffType() const

Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.

int getFloatingTypeOrder(QualType LHS, QualType RHS) const

Compare the rank of the two specified floating point types, ignoring the domain of the type (i....

const TargetInfo * getAuxTargetInfo() const

llvm::APFixedPoint getFixedPointMin(QualType Ty) const

TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const

Allocate a TypeSourceInfo where all locations have been initialized to a given location,...

CanQualType getSizeType() const

Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.

TypeInfoChars getTypeInfoInChars(const Type *T) const

CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const

Return a conservative estimate of the alignment of the specified decl D.

const clang::PrintingPolicy & getPrintingPolicy() const

llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const

bool hasSameUnqualifiedType(QualType T1, QualType T2) const

Determine whether the given types are equivalent after cvr-qualifiers have been removed.

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

CanQualType UnsignedIntTy

QualType getExceptionObjectType(QualType T) const

QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const

Return the type for the specified builtin.

CanQualType UnsignedShortTy

bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const

QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const

Return a normal function type with a typed argument list.

QualType getPromotedIntegerType(QualType PromotableType) const

Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...

StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const

Return a string representing the human readable name for the specified function declaration or file n...

llvm::APFixedPoint getFixedPointMax(QualType Ty) const

QualType getComplexType(QualType T) const

Return the uniqued reference to the type for a complex number with the specified element type.

bool areCompatibleSveTypes(QualType FirstType, QualType SecondType)

Return true if the given types are an SVE builtin and a VectorType that is a fixed-length representat...

const TargetInfo & getTargetInfo() const

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const

CanQualType getNSIntegerType() const

bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)

Compatibility predicates used to check assignment expressions.

QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const

Return the uniqued reference to the type for an address space qualified type with the specified type ...

bool isPromotableIntegerType(QualType T) const

More type predicates useful for type checking/promotion.

QualType getTypedefType(const TypedefNameDecl *Decl, QualType Underlying=QualType()) const

Return the unique reference to the type for the specified typedef-name decl.

QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const

Return the unique reference to the matrix type of the specified element type and size.

CanQualType getNSUIntegerType() const

uint64_t getCharWidth() const

Return the size of the character type, in bits.

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

CharUnits getNonVirtualAlignment() const

getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

getBaseClassOffset - Get the offset, in chars, for the given base class.

AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...

Expr * getCond() const

getCond - Return the expression representing the condition for the ?: operator.

Expr * getTrueExpr() const

getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...

Expr * getFalseExpr() const

getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...

This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...

Expr * getBase()

Get base of the array section.

Expr * getLowerBound()

Get lower bound of array section.

ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.

SourceLocation getRBracketLoc() const

Expr * getLHS()

An array access can be written A[4] or 4[A] (both are equivalent).

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

ArraySizeModifier getSizeModifier() const

QualType getElementType() const

AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...

std::unique_ptr< AtomicScopeModel > getScopeModel() const

Get atomic scope model.

SourceLocation getBeginLoc() const LLVM_READONLY

Attr - This represents one attribute.

const char * getSpelling() const

Type source information for an attributed type.

TypeLoc getModifiedLoc() const

The modified type, which is generally canonically different from the attribute type.

Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.

ConceptDecl * getTypeConstraintConcept() const

A builtin binary operation expression such as "x + y" or "x <= y".

static bool isLogicalOp(Opcode Opc)

SourceLocation getExprLoc() const

bool isEqualityOp() const

static bool isAdditiveOp(Opcode Opc)

A fixed int type of a specified bitwidth.

This class is used for builtin types like 'int'.

bool isFloatingPoint() const

bool isSignedInteger() const

bool isUnsignedInteger() const

bool isAuxBuiltinID(unsigned ID) const

Return true if builtin ID belongs to AuxTarget.

const char * getHeaderName(unsigned ID) const

If this is a library function that comes from a specific header, retrieve that header name.

llvm::StringRef getName(unsigned ID) const

Return the identifier name for the specified builtin, e.g.

unsigned getAuxBuiltinID(unsigned ID) const

Return real builtin ID (i.e.

bool isTSBuiltin(unsigned ID) const

Return true if this function is a target-specific builtin.

CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....

Represents a base class of a C++ class.

Represents a call to a C++ constructor.

bool isListInitialization() const

Whether this constructor call was written as list-initialization.

unsigned getNumArgs() const

Return the number of arguments to the constructor call.

Represents a C++ destructor within a class.

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

A call to an overloaded operator written using operator syntax.

SourceLocation getExprLoc() const LLVM_READONLY

OverloadedOperatorKind getOperator() const

Returns the kind of overloaded operator that this expression refers to.

Represents a list-initialization with parenthesis.

ArrayRef< Expr * > getInitExprs()

Represents a C++ struct/union/class.

bool isStandardLayout() const

Determine whether this class is standard-layout per C++ [class]p7.

CXXRecordDecl * getDefinition() const

bool isDynamicClass() const

Represents a C++ nested-name-specifier or a global scope specifier.

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

Expr * getArg(unsigned Arg)

getArg - Return the specified argument.

void setArg(unsigned Arg, Expr *ArgExpr)

setArg - Set the specified argument.

SourceLocation getBeginLoc() const LLVM_READONLY

unsigned getBuiltinCallee() const

getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.

FunctionDecl * getDirectCallee()

If the callee is a FunctionDecl, return it. Otherwise return null.

bool isCallToStdMove() const

SourceLocation getEndLoc() const LLVM_READONLY

unsigned getNumArgs() const

getNumArgs - Return the number of actual arguments to this call.

FPOptions getFPFeaturesInEffect(const LangOptions &LO) const

Get the FP features status of this operator.

Expr ** getArgs()

Retrieve the call arguments.

SourceLocation getRParenLoc() const

bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const

Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...

QualType withConst() const

Retrieves a version of this type with const applied.

const T * getTypePtr() const

Retrieve the underlying type pointer, which refers to a canonical type.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

path_iterator path_begin()

CastKind getCastKind() const

Represents a character-granular source range.

static CharSourceRange getCharRange(SourceRange R)

static CharSourceRange getTokenRange(SourceRange R)

SourceLocation getBegin() const

CharUnits - This is an opaque type for sizes expressed in character units.

bool isZero() const

isZero - Test whether the quantity equals zero.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

bool isOne() const

isOne - Test whether the quantity equals one.

static CharUnits fromQuantity(QuantityType Quantity)

fromQuantity - Construct a CharUnits quantity from a raw integer type.

static CharUnits Zero()

Zero - Construct a CharUnits quantity of zero.

void setExprNeedsCleanups(bool SideEffects)

Complex values, per C99 6.2.5p11.

CompoundAssignOperator - For compound assignments (e.g.

Declaration of a C++20 concept.

ConditionalOperator - The ?: ternary operator.

ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.

Represents the canonical version of C arrays with a specified constant size.

llvm::APInt getSize() const

Return the constant array size as an APInt.

Represents a concrete matrix type with constant number of rows and columns.

static constexpr unsigned getMaxElementsPerDimension()

Returns the maximum number of elements per dimension.

static constexpr bool isDimensionValid(size_t NumElements)

Returns true if NumElements is a valid matrix dimension.

ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...

Represents an expression that might suspend coroutine execution; either a co_await or co_yield expres...

Expr * getOperand() const

Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...

DynamicCountPointerKind getKind() const

static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

bool isDependentContext() const

Determines whether this context is dependent on a template parameter.

bool isStdNamespace() const

decl_range decls() const

decls_begin/decls_end - Iterate over the declarations stored in this context.

bool isFunctionOrMethod() const

A reference to a declared variable, function, enum, etc.

SourceLocation getBeginLoc() const LLVM_READONLY

static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)

NestedNameSpecifierLoc getQualifierLoc() const

If the name was qualified, retrieves the nested-name-specifier that precedes the name,...

NonOdrUseReason isNonOdrUse() const

Is this expression a non-odr-use reference, and if so, why?

SourceLocation getLocation() const

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

bool isInStdNamespace() const

unsigned getMaxAlignment() const

getMaxAlignment - return the maximum alignment specified by attributes on this decl,...

const FunctionType * getFunctionType(bool BlocksToo=true) const

Looks through the Decl's underlying type to extract a FunctionType when possible.

bool isInvalidDecl() const

llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const

SourceLocation getLocation() const

DeclContext * getDeclContext()

SourceLocation getBeginLoc() const LLVM_READONLY

virtual Decl * getCanonicalDecl()

Retrieves the "canonical" declaration of the given declaration.

virtual SourceRange getSourceRange() const LLVM_READONLY

Source range that this declaration covers.

The name of a declaration.

SourceLocation getTypeSpecStartLoc() const

TypeSourceInfo * getTypeSourceInfo() const

RAII class that determines when any errors have occurred between the time the instance was created an...

bool hasErrorOccurred() const

Determine whether any errors have occurred since this object instance was created.

Concrete class used by the front-end to report problems and issues.

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

An instance of this object exists for each enum constant that is defined.

unsigned getNumNegativeBits() const

Returns the width in bits required to store all the negative enumerators of this enum.

bool isComplete() const

Returns true if this can be considered a complete type.

TypeSourceInfo * getIntegerTypeSourceInfo() const

Return the type source info for the underlying integer type, if no type source info exists,...

QualType getIntegerType() const

Return the integer type this enum decl corresponds to.

unsigned getNumPositiveBits() const

Returns the width in bits required to store all the non-negative enumerators of this enum.

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.

This represents one expression.

bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...

@ SE_AllowSideEffects

Allow any unmodeled side effect.

@ SE_NoSideEffects

Strictly evaluate the expression.

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

bool isValueDependent() const

Determines whether the value of this expression depends on.

ExprValueKind getValueKind() const

getValueKind - The value kind that this expression produces.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const

If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

Expr * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

Expr * IgnoreImplicit() LLVM_READONLY

Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.

bool containsErrors() const

Whether this expression contains subexpressions which had errors, e.g.

bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...

bool isLValue() const

isLValue - True if this expression is an "l-value" according to the rules of the current language.

FieldDecl * getSourceBitField()

If this expression refers to a bit-field, retrieve the declaration of that bit-field.

@ NPC_ValueDependentIsNull

Specifies that a value-dependent expression of integral or dependent type should be considered a null...

@ NPC_ValueDependentIsNotNull

Specifies that a value-dependent expression should be considered to never be a null pointer constant.

bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const

EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...

Expr * IgnoreImplicitAsWritten() LLVM_READONLY

Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.

bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const

HasSideEffects - This routine returns true for all those expressions which have any effect other than...

bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const

Evaluate an expression that is required to be a constant expression.

bool isInstantiationDependent() const

Whether this expression is instantiation-dependent, meaning that it depends in some way on.

std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const

If the current Expr can be evaluated to a pointer to a null-terminated constant string,...

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

NullPointerConstantKind

Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().

@ NPCK_ZeroExpression

Expression is a Null pointer constant built from a zero integer expression that is not a simple,...

@ NPCK_ZeroLiteral

Expression is a Null pointer constant built from a literal zero.

@ NPCK_NotNull

Expression is not a Null pointer constant.

bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const

EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...

NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const

isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.

QualType getEnumCoercedType(const ASTContext &Ctx) const

If this expression is an enumeration constant, return the enumeration type under which said constant ...

void setValueKind(ExprValueKind Cat)

setValueKind - Set the value kind produced by this expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

void setObjectKind(ExprObjectKind Cat)

setObjectKind - Set the object kind produced by this expression.

std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const

isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.

bool isFlexibleArrayMemberLike(ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const

Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...

bool hasPlaceholderType() const

Returns whether this expression has a placeholder type.

bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const

If the current Expr is a pointer, this will try to statically determine the number of bytes available...

const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const

If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...

bool isKnownToHaveBooleanValue(bool Semantic=true) const

isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...

void EvaluateForOverflow(const ASTContext &Ctx) const

ExtVectorType - Extended vector type.

Represents a member of a struct/union/class.

bool isBitField() const

Determines whether this field is a bitfield.

unsigned getBitWidthValue() const

Computes the bit width of this field, if this is a bit field.

const RecordDecl * getParent() const

Returns the parent of this field declaration, which is the struct in which this field is defined.

Expr * getBitWidth() const

Returns the expression that represents the bit width, if this field is a bit field.

const FieldDecl * findCountedByField() const

Find the FieldDecl specified in a FAM's "counted_by" attribute.

Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

Create a code modification hint that replaces the given source range with the given code string.

static FixItHint CreateRemoval(CharSourceRange RemoveRange)

Create a code modification hint that removes the given source range.

static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)

Create a code modification hint that inserts the given code string at a specific location.

llvm::APFloat getValue() const

ForStmt - This represents a 'for (init;cond;inc)' stmt.

Represents a function declaration or definition.

unsigned getMemoryFunctionKind() const

Identify a memory copying or setting function.

const ParmVarDecl * getParamDecl(unsigned i) const

unsigned getMinRequiredArguments() const

Returns the minimum number of arguments needed to call this function.

unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const

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

param_iterator param_end()

bool hasCXXExplicitFunctionObjectParameter() const

QualType getReturnType() const

ArrayRef< ParmVarDecl * > parameters() const

param_iterator param_begin()

bool isVariadic() const

Whether this function is variadic.

const TemplateArgumentList * getTemplateSpecializationArgs() const

Retrieve the template arguments used to produce this function template specialization from the primar...

TemplatedKind getTemplatedKind() const

What kind of templated function this is.

OverloadedOperatorKind getOverloadedOperator() const

getOverloadedOperator - Which C++ overloaded operator this function represents, if any.

unsigned getNumParams() const

Return the number of parameters this function must have based on its FunctionType.

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

unsigned getNumParams() const

QualType getParamType(unsigned i) const

bool isVariadic() const

Whether this function prototype is variadic.

ExtProtoInfo getExtProtoInfo() const

bool isNothrow(bool ResultIfDependent=false) const

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

ArrayRef< QualType > getParamTypes() const

FunctionType - C99 6.7.5.3 - Function Declarators.

static ArmStateValue getArmZT0State(unsigned AttrBits)

static ArmStateValue getArmZAState(unsigned AttrBits)

QualType getReturnType() const

@ SME_PStateSMEnabledMask

@ SME_PStateSMCompatibleMask

One of these records is kept for each identifier that is lexed.

bool isStr(const char(&Str)[StrLen]) const

Return true if this is the identifier for the specified string.

StringRef getName() const

Return the actual identifier string.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...

Describes an C or C++ initializer list.

ArrayRef< Expr * > inits()

Describes an entity that is being initialized.

static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)

Create the initialization entity for a parameter.

static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)

Returns a new integer literal with value 'V' and type 'type'.

StrictFlexArraysLevelKind

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)

Returns a string for the source that the range encompasses.

static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)

Retrieve the name of the immediate macro expansion.

static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)

MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...

static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)

Retrieve the name of the immediate macro expansion.

static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)

Computes the source location just past the end of the token at this source location.

Represents the results of name lookup.

bool empty() const

Return true if no decls were found.

NamedDecl * getFoundDecl() const

Fetch the unique decl found by this lookup.

bool isSingleResult() const

Determines if this names a single result which is not an unresolved value using decl.

void suppressDiagnostics()

Suppress the diagnostics that would normally fire because of this lookup.

static bool isValidElementType(QualType T)

Valid elements types are the following:

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

ValueDecl * getMemberDecl() const

Retrieve the member declaration to which this expression refers.

This represents a decl that may have a name.

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

Linkage getFormalLinkage() const

Get the linkage from a semantic point of view.

bool hasLinkage() const

Determine whether this declaration has linkage.

Represent a C++ namespace.

SpecifierKind getKind() const

Determine what kind of nested name specifier is stored.

NullStmt - This is the null statement ";": C99 6.8.3p3.

bool hasLeadingEmptyMacro() const

SourceLocation getSemiLoc() const

Represents an ObjC class declaration.

Represents one property declaration in an Objective-C interface.

ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const

ObjCPropertyAttribute::Kind getPropertyAttributes() const

ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.

ObjCPropertyDecl * getExplicitProperty() const

bool isImplicitProperty() const

ObjCStringLiteral, used for Objective-C string literals i.e.

OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.

A single parameter index whose accessors require each use to make explicit the parameter index encodi...

ParenExpr - This represents a parenthesized expression, e.g.

Represents a parameter to a function.

PointerType - C99 6.7.5.1 - Pointer Declarators.

QualType getPointeeType() const

PseudoObjectExpr - An expression which accesses a pseudo-object l-value.

static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)

A (possibly-)qualified type.

bool isTriviallyCopyableType(const ASTContext &Context) const

Return true if this is a trivially copyable type (C++0x [basic.types]p9)

PrimitiveDefaultInitializeKind

QualType withoutLocalFastQualifiers() const

bool isNull() const

Return true if this QualType doesn't point to a type yet.

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

LangAS getAddressSpace() const

Return the address space of this type.

bool isConstant(const ASTContext &Ctx) const

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

Qualifiers::ObjCLifetime getObjCLifetime() const

Returns lifetime attribute of this type.

void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const

QualType getCanonicalType() const

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

void removeLocalVolatile()

QualType withCVRQualifiers(unsigned CVR) const

bool isConstQualified() const

Determine whether this type is const-qualified.

bool hasAddressSpace() const

Check if this type has any address space qualifier.

bool hasNonTrivialObjCLifetime() const

@ OCL_Strong

Assigning into this object requires the old value to be released and the new value to be retained.

@ OCL_ExplicitNone

This object can be modified without requiring retains or releases.

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

@ OCL_Autoreleasing

Assigning into this object requires a lifetime extension.

bool hasUnaligned() const

Represents a struct/union/class.

field_range fields() const

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RecordDecl * getDecl() const

Scope - A scope is a transient data structure that is used while parsing the program.

ScopeFlags

ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...

@ SEHFilterScope

We are currently in the filter expression of an SEH except block.

@ SEHExceptScope

This scope corresponds to an SEH except.

bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)

bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

@ ArmStreaming

Intrinsic is only available in normal mode.

@ ArmStreamingCompatible

Intrinsic is only available in Streaming-SVE mode.

bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)

A generic diagnostic builder for errors which may or may not be deferred.

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

Emit a diagnostic.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)

bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)

Check an Objective-C array literal being converted to the given target type.

ObjCLiteralKind CheckLiteralKind(Expr *FromE)

bool isSignedCharBool(QualType Ty)

void adornBoolConversionDiagWithTernaryFixit(Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)

void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)

Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...

void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)

Check an Objective-C dictionary literal being converted to the given target type.

std::unique_ptr< NSAPI > NSAPIObj

Caches identifiers/selectors for NSFoundation APIs.

bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)

bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)

bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

bool CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)

bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)

bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)

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

const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)

Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...

bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)

bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)

Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...

LocalInstantiationScope * CurrentInstantiationScope

The current instantiation scope used to store local variables.

void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, BinaryOperatorKind Opcode)

Check for comparisons of floating-point values using == and !=.

Scope * getCurScope() const

Retrieve the parser's current scope.

bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)

Figure out if an expression could be turned into a call.

@ LookupOrdinaryName

Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....

@ LookupMemberName

Member name lookup, which finds the names of class/struct/union members.

@ LookupAnyName

Look up any declaration with any name.

bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)

Checks that a call expression's argument count is at most the desired number.

bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)

Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...

bool BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum)

BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...

void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)

Register a magic integral constant to be used as a type tag.

bool isValidPointerAttrType(QualType T, bool RefOkay=false)

Determine if type T is a valid subject for a nonnull and similar attributes.

bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, unsigned Multiple)

BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...

void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)

Diagnose pointers that are always non-null.

bool FormatStringHasSArg(const StringLiteral *FExpr)

QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)

UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....

static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI)

Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo parameter with the Format...

bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, unsigned ArgBits)

BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...

void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)

This function calls Action when it determines that E designates a misaligned member due to the packed...

FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const

Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...

ExprResult UsualUnaryConversions(Expr *E)

UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....

bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)

ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)

ExprResult tryConvertExprToType(Expr *E, QualType Ty)

Try to convert an expression E to type Ty.

QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)

CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...

DiagnosticsEngine & getDiagnostics() const

static FormatStringType GetFormatStringType(const FormatAttr *Format)

bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())

Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...

void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)

std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const

ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)

ASTContext & getASTContext() const

CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)

Look for the destructor of the given class.

ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)

ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)

ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.

bool isConstantEvaluatedOverride

Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...

bool BuiltinVectorToScalarMath(CallExpr *TheCall)

PrintingPolicy getPrintingPolicy() const

Retrieve a suitable printing policy for diagnostics.

void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)

DiagnoseSelfMove - Emits a warning if a value is moved to itself.

SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)

Calls Lexer::getLocForEndOfToken()

bool IsLayoutCompatible(QualType T1, QualType T2) const

const LangOptions & getLangOpts() const

bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type of the given expression is complete.

void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)

CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...

VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)

ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)

BuildCallExpr - Handle a call to Fn with the specified array of arguments.

bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)

bool hasCStrMethod(const Expr *E)

Check to see if a given expression could have '.c_str()' called on it.

const LangOptions & LangOpts

static const uint64_t MaximumAlignment

bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall)

ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)

ConvertVectorExpr - Handle __builtin_convertvector.

bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)

bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)

checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.

CleanupInfo Cleanup

Used to control the generation of ExprWithCleanups.

NamedDecl * getCurFunctionOrMethodDecl() const

getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...

VarArgKind isValidVarArgType(const QualType &Ty)

Determine the degree of POD-ness for an expression.

ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)

void popCodeSynthesisContext()

void DiagnoseMisalignedMembers()

Diagnoses the current set of gathered accesses.

sema::FunctionScopeInfo * getCurFunction() const

void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)

checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...

void pushCodeSynthesisContext(CodeSynthesisContext Ctx)

std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue

A pair of ArgumentKind identifier and magic value.

bool findMacroSpelling(SourceLocation &loc, StringRef name)

Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...

void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)

Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...

void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)

Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...

ExprResult DefaultLvalueConversion(Expr *E)

SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const

void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)

Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)

Checks that a call expression's argument count is at least the desired number.

FormatArgumentPassingKind

bool isUnevaluatedContext() const

Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.

@ ACK_Comparison

A comparison.

bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result)

BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.

ExprResult CheckPlaceholderExpr(Expr *E)

Check for operands with placeholder types and complain if found.

bool inTemplateInstantiation() const

Determine whether we are currently performing template instantiation.

SourceManager & getSourceManager() const

ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)

bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, bool CheckForFloatArgs=true)

bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)

Checks that a call expression's argument count is in the desired range.

void DiscardMisalignedMemberAddress(const Type *T, Expr *E)

This function checks if the expression is in the sef of potentially misaligned members and it is conv...

bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)

Conditionally issue a diagnostic based on the current evaluation context.

ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())

ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)

PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...

bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, unsigned ArgBits)

BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...

bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)

Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.

bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)

CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...

bool isConstantEvaluatedContext() const

bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)

Checks that a call expression's argument count is the desired number.

ExprResult BuiltinShuffleVector(CallExpr *TheCall)

BuiltinShuffleVector - Handle __builtin_shufflevector.

QualType GetSignedVectorType(QualType V)

Return a signed ext_vector_type that is of identical size and number of elements.

void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)

bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type T is a complete type.

Scope * TUScope

Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...

bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)

Perform qualified name lookup into a given context.

SourceManager & SourceMgr

ExprResult UsualUnaryFPConversions(Expr *E)

UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.

DiagnosticsEngine & Diags

NamespaceDecl * getStdNamespace() const

std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, bool FPOnly=false)

ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)

void checkVariadicArgument(const Expr *E, VariadicCallType CT)

Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...

void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)

void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)

Run some code with "sufficient" stack space.

void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)

Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...

bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)

BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...

ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)

bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)

Determine whether the type Derived is a C++ class that is derived from the type Base.

SemaLoongArch & LoongArch()

@ Diagnose

Diagnose issues that are non-constant or that are extensions.

bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)

CheckCXXThrowOperand - Validate the operand of a throw.

bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)

Perform unqualified name lookup starting from a given scope.

bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)

CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...

ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})

Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...

void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)

Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...

ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

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

unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const

FileID getFileID(SourceLocation SpellingLoc) const

Return the FileID for a SourceLocation.

SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const

SourceLocation getSpellingLoc(SourceLocation Loc) const

Given a SourceLocation object, return the spelling location referenced by the ID.

const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const

Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.

unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const

bool isInSystemMacro(SourceLocation loc) const

Returns whether Loc is expanded from a macro in a system header.

CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const

Return the start/end of the expansion information for an expansion location.

bool isInSystemHeader(SourceLocation Loc) const

Returns if a SourceLocation is in a system header.

bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const

Returns true if the spelling locations for both SourceLocations are part of the same file buffer.

unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const

A trivial tuple used to represent a source range.

SourceLocation getEnd() const

SourceLocation getBegin() const

Stmt - This represents one statement.

SourceLocation getEndLoc() const LLVM_READONLY

void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const

StmtClass getStmtClass() const

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const

Produce a unique representation of the given statement.

SourceLocation getBeginLoc() const LLVM_READONLY

StringLiteral - This represents a string literal expression, e.g.

SourceLocation getBeginLoc() const LLVM_READONLY

unsigned getLength() const

StringLiteralKind getKind() const

SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const

getLocationOfByte - Return a source location that points to the specified byte of this string literal...

unsigned getByteLength() const

StringRef getString() const

SourceLocation getEndLoc() const LLVM_READONLY

unsigned getCharByteWidth() const

Exposes information about the current target.

virtual bool validatePointerAuthKey(const llvm::APSInt &value) const

Determine whether the given pointer-authentication key is valid.

virtual bool supportsCpuSupports() const

virtual bool validateCpuIs(StringRef Name) const

virtual bool supportsCpuInit() const

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

virtual bool useFP16ConversionIntrinsics() const

Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...

unsigned getTypeWidth(IntType T) const

Return the width (in bits) of the specified integer type enum.

IntType getSizeType() const

virtual bool validateCpuSupports(StringRef Name) const

virtual bool supportsCpuIs() const

const llvm::fltSemantics & getLongDoubleFormat() const

virtual bool checkArithmeticFenceSupported() const

Controls if __arithmetic_fence is supported in the targeted backend.

virtual bool hasFeature(StringRef Feature) const

Determine whether the given target has the given feature.

virtual bool hasSjLjLowering() const

Controls if __builtin_longjmp / __builtin_setjmp can be lowered to llvm.eh.sjlj.longjmp / llvm....

const TemplateArgument & get(unsigned Idx) const

Retrieve the template argument at a given index.

@ Type

The template argument is a type.

const Type * getTypeForDecl() const

Base wrapper for a particular "section" of type source info.

SourceRange getSourceRange() const LLVM_READONLY

Get the full source range.

T getAsAdjusted() const

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

SourceLocation getBeginLoc() const

Get the begin source location.

Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

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

bool isBlockPointerType() const

bool isBooleanType() const

const Type * getPointeeOrArrayElementType() const

If this is a pointer type, return the pointee type.

const RecordType * getAsUnionType() const

NOTE: getAs*ArrayType are methods on ASTContext.

bool isSignedIntegerType() const

Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...

bool isFloat16Type() const

bool isUnsignedIntegerOrEnumerationType() const

Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...

bool isIntegralOrUnscopedEnumerationType() const

Determine whether this type is an integral or unscoped enumeration type.

bool canDecayToPointerType() const

Determines whether this type can decay to a pointer type.

bool hasIntegerRepresentation() const

Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...

bool isVoidPointerType() const

bool isConstantSizeType() const

Return true if this is not a variable sized type, according to the rules of C99 6....

bool isFunctionPointerType() const

bool isPointerType() const

CanQualType getCanonicalTypeUnqualified() const

bool isIntegerType() const

isIntegerType() does not include complex integers (a GCC extension).

const T * castAs() const

Member-template castAs<specific type>.

bool isReferenceType() const

bool isEnumeralType() const

bool isScalarType() const

bool isVariableArrayType() const

bool isSveVLSBuiltinType() const

Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...

bool isIntegralType(const ASTContext &Ctx) const

Determine whether this type is an integral type.

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

bool hasUnsignedIntegerRepresentation() const

Determine whether this type has an unsigned integer representation of some sort, e....

QualType getSveEltType(const ASTContext &Ctx) const

Returns the representative type for the element of an SVE builtin type.

bool isBitIntType() const

bool isSpecificBuiltinType(unsigned K) const

Test for a particular builtin type.

bool isBuiltinType() const

Helper methods to distinguish type categories.

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

bool isAnyComplexType() const

bool isFixedPointType() const

Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.

bool hasSignedIntegerRepresentation() const

Determine whether this type has an signed integer representation of some sort, e.g....

QualType getCanonicalTypeInternal() const

bool isWebAssemblyTableType() const

Returns true if this is a WebAssembly table type: either an array of reference types,...

const Type * getBaseElementTypeUnsafe() const

Get the base element type of this type, potentially discarding type qualifiers.

bool isMemberPointerType() const

bool isAtomicType() const

bool isFunctionProtoType() const

bool isStandardLayoutType() const

Test if this type is a standard-layout type.

bool isVariablyModifiedType() const

Whether this type is a variably-modified type (C99 6.7.5).

bool isUnscopedEnumerationType() const

bool isObjCObjectType() const

const ArrayType * getAsArrayTypeUnsafe() const

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

bool isUndeducedType() const

Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...

bool isObjectType() const

Determine whether this type is an object type.

bool isIncompleteType(NamedDecl **Def=nullptr) const

Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...

bool isFunctionType() const

bool isObjCObjectPointerType() const

bool hasFloatingRepresentation() const

Determine whether this type has a floating-point representation of some sort, e.g....

bool isStructureOrClassType() const

bool isVectorType() const

bool isRealFloatingType() const

Floating point categories.

bool isFloatingType() const

bool isUnsignedIntegerType() const

Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...

bool isAnyPointerType() const

TypeClass getTypeClass() const

bool isCanonicalUnqualified() const

Determines if this type would be canonical if it had no further qualification.

const T * getAs() const

Member-template getAs<specific type>'.

bool isNullPtrType() const

bool isRecordType() const

bool isObjCRetainableType() const

std::optional< NullabilityKind > getNullability() const

Determine the nullability of the given type.

bool isSizelessVectorType() const

Returns true for all scalable vector types.

QualType getSizelessVectorEltType(const ASTContext &Ctx) const

Returns the representative type for the element of a sizeless vector builtin type.

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

Base class for declarations which introduce a typedef-name.

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

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

Expr * getSubExpr() const

SourceLocation getBeginLoc() const LLVM_READONLY

The iterator over UnresolvedSets.

A set of unresolved declarations.

Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...

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.

Represents a GCC generic vector type.

unsigned getNumElements() const

WhileStmt - This represents a 'while' stmt.

MatchKind

How well a given conversion specifier matches its argument.

@ NoMatch

The conversion specifier and the argument types are incompatible.

@ NoMatchPedantic

The conversion specifier and the argument type are disallowed by the C standard, but are in practice ...

@ Match

The conversion specifier and the argument type are compatible.

@ NoMatchSignedness

The conversion specifier and the argument type have different sign.

std::string getRepresentativeTypeName(ASTContext &C) const

MatchKind matchesType(ASTContext &C, QualType argTy) const

std::optional< ConversionSpecifier > getStandardSpecifier() const

unsigned getLength() const

const char * getStart() const

const char * toString() const

ArgType getArgType(ASTContext &Ctx) const

const char * getStart() const

unsigned getArgIndex() const

bool hasDataArgument() const

HowSpecified getHowSpecified() const

unsigned getConstantAmount() const

unsigned getConstantLength() const

Class representing optional flags with location and representation information.

const char * toString() const

const char * getPosition() const

void markSafeWeakUse(const Expr *E)

Record that a given expression is a "safe" access of a weak object (e.g.

Defines the clang::TargetInfo interface.

__inline void unsigned int _2

bool parseFormatStringHasFormattingSpecifiers(const char *Begin, const char *End, const LangOptions &LO, const TargetInfo &Target)

Return true if the given string has at least one formatting specifier.

bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target, bool isFreeBSDKPrintf)

bool ParseScanfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)

bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)

const AstTypeMatcher< PointerType > pointerType

Matches pointer types, but does not match Objective-C object pointer types.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicAllOfMatcher< Decl > decl

Matches declarations.

const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr

Matches expressions.

ComparisonResult

Indicates the result of a tentative comparison.

uint32_t Literal

Literals are represented as positive integers.

@ After

Like System, but searched after the system directories.

@ FixIt

Parse and apply any fixits to the source.

bool GT(InterpState &S, CodePtr OpPC)

bool NE(InterpState &S, CodePtr OpPC)

bool LE(InterpState &S, CodePtr OpPC)

bool InRange(InterpState &S, CodePtr OpPC)

bool Cast(InterpState &S, CodePtr OpPC)

bool EQ(InterpState &S, CodePtr OpPC)

bool GE(InterpState &S, CodePtr OpPC)

void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)

The JSON file list parser is used to communicate input to InstallAPI.

OverloadedOperatorKind

Enumeration specifying the different kinds of C++ overloaded operators.

Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

@ NonNull

Values of this type can never be null.

Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)

Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...

ExprObjectKind

A further classification of the kind of object referenced by an l-value or x-value.

@ OK_Ordinary

An ordinary object is located at an address in memory.

@ Seq

'seq' clause, allowed on 'loop' and 'routine' directives.

SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)

@ Internal

Internal linkage, which indicates that the entity can be referred to from within the translation unit...

@ Result

The result type of a method or function.

LangAS

Defines the address space values used by the address space qualifier of QualType.

CastKind

CastKind - The kind of operation required for a conversion.

ActionResult< ParsedType > TypeResult

ExprValueKind

The categorization of expression values, currently following the C++11 scheme.

@ VK_PRValue

A pr-value expression (in the C++11 taxonomy) produces a temporary value.

for(const auto &A :T->param_types())

const FunctionProtoType * T

Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)

std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt

A partial diagnostic along with the source location where this diagnostic occurs.

@ Success

Template argument deduction was successful.

CallingConv

CallingConv - Specifies the calling convention that a function uses.

@ Generic

not a target-specific vector type

U cast(CodeGen::Address addr)

@ Enum

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

@ Other

Other implicit parameter.

DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...

EvalResult is a struct with detailed info about an evaluated expression.

APValue Val

Val - This is the value the expression can be folded to.

SmallVectorImpl< PartialDiagnosticAt > * Diag

Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...

Extra information about a function prototype.

unsigned AArch64SMEAttributes

Describes how types, statements, expressions, and declarations should be printed.

unsigned AnonymousTagLocations

When printing an anonymous tag name, also print the location of that entity (e.g.,...

unsigned Indentation

The number of spaces to use to indent each line.

A context in which code is being synthesized (where a source location alone is not sufficient to iden...

@ BuildingBuiltinDumpStructCall

We are building an implied call from __builtin_dump_struct.

FormatArgumentPassingKind ArgPassingKind


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