76#include "llvm/ADT/APFloat.h"
77#include "llvm/ADT/APInt.h"
78#include "llvm/ADT/APSInt.h"
79#include "llvm/ADT/ArrayRef.h"
80#include "llvm/ADT/DenseMap.h"
81#include "llvm/ADT/FoldingSet.h"
82#include "llvm/ADT/STLExtras.h"
83#include "llvm/ADT/SmallBitVector.h"
84#include "llvm/ADT/SmallPtrSet.h"
85#include "llvm/ADT/SmallString.h"
86#include "llvm/ADT/SmallVector.h"
87#include "llvm/ADT/StringExtras.h"
88#include "llvm/ADT/StringRef.h"
89#include "llvm/ADT/StringSet.h"
90#include "llvm/ADT/StringSwitch.h"
91#include "llvm/Support/AtomicOrdering.h"
92#include "llvm/Support/Compiler.h"
93#include "llvm/Support/ConvertUTF.h"
94#include "llvm/Support/ErrorHandling.h"
95#include "llvm/Support/Format.h"
96#include "llvm/Support/Locale.h"
97#include "llvm/Support/MathExtras.h"
98#include "llvm/Support/SaveAndRestore.h"
99#include "llvm/Support/raw_ostream.h"
100#include "llvm/TargetParser/RISCVTargetParser.h"
101#include "llvm/TargetParser/Triple.h"
114using namespace clang;
118 unsigned ByteNo)
const {
129 unsigned ArgCount =
Call->getNumArgs();
130 if (ArgCount >= MinArgCount)
133 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
134 << 0 << MinArgCount << ArgCount
135 << 0 <<
Call->getSourceRange();
139 unsigned ArgCount =
Call->getNumArgs();
140 if (ArgCount <= MaxArgCount)
142 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
143 << 0 << MaxArgCount << ArgCount
144 << 0 <<
Call->getSourceRange();
148 unsigned MaxArgCount) {
154 unsigned ArgCount =
Call->getNumArgs();
155 if (ArgCount == DesiredArgCount)
160 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
164 Call->getArg(ArgCount - 1)->getEndLoc());
167 << 0 << DesiredArgCount << ArgCount
168 << 0 <<
Call->getArg(1)->getSourceRange();
172 bool HasError =
false;
174 for (
unsigned I = 0; I <
Call->getNumArgs(); ++I) {
181 int DiagMsgKind = -1;
183 if (!ArgString.has_value())
185 else if (ArgString->find(
'$') != std::string::npos)
188 if (DiagMsgKind >= 0) {
199 if (
Value->isTypeDependent())
230 if (!Literal || !Literal->isOrdinary()) {
243 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
251 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
252 if (!Literal || !Literal->isWide()) {
253 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
254 << Arg->getSourceRange();
288 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
319 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
321 auto IsValidIntegerType = [](
QualType Ty) {
322 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
329 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
333 S.
Diag(Source->
getExprLoc(), diag::err_typecheck_expect_scalar_operand)
339 if (!IsValidIntegerType(AlignOp->
getType())) {
350 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
351 llvm::APSInt MaxValue(
352 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
353 if (AlignValue < 1) {
354 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
357 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
362 if (!AlignValue.isPowerOf2()) {
363 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
366 if (AlignValue == 1) {
367 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
368 << IsBooleanAlignBuiltin;
396 std::pair<unsigned, const char *> Builtins[] = {
397 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
398 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
399 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
402 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
404 return BuiltinID ==
P.first && TheCall->
getExprLoc().isMacroID() &&
409 auto ValidCkdIntType = [](
QualType QT) {
412 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
413 return (BT->getKind() >= BuiltinType::Short &&
414 BT->getKind() <= BuiltinType::Int128) || (
415 BT->getKind() >= BuiltinType::UShort &&
416 BT->getKind() <= BuiltinType::UInt128) ||
417 BT->getKind() == BuiltinType::UChar ||
418 BT->getKind() == BuiltinType::SChar;
423 for (
unsigned I = 0; I < 2; ++I) {
429 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
448 !PtrTy->getPointeeType()->isIntegerType() ||
449 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
450 PtrTy->getPointeeType().isConstQualified()) {
452 diag::err_overflow_builtin_must_be_ptr_int)
460 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
461 for (
unsigned I = 0; I < 3; ++I) {
462 const auto Arg = TheCall->
getArg(I);
465 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
467 return S.
Diag(Arg->getBeginLoc(),
468 diag::err_overflow_builtin_bit_int_max_size)
477struct BuiltinDumpStructGenerator {
486 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
487 Policy(S.Context.getPrintingPolicy()) {
491 Expr *makeOpaqueValueExpr(
Expr *Inner) {
494 Inner->getObjectKind(), Inner);
495 Actions.push_back(OVE);
499 Expr *getStringLiteral(llvm::StringRef Str) {
505 bool callPrintFunction(llvm::StringRef Format,
509 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
511 Args.push_back(getStringLiteral(Format));
512 Args.insert(Args.end(), Exprs.begin(), Exprs.end());
528 Actions.push_back(RealCall.
get());
534 Expr *getIndentString(
unsigned Depth) {
540 return getStringLiteral(Indent);
544 return getStringLiteral(
T.getAsString(Policy));
548 llvm::raw_svector_ostream OS(Str);
553 switch (BT->getKind()) {
554 case BuiltinType::Bool:
557 case BuiltinType::Char_U:
558 case BuiltinType::UChar:
561 case BuiltinType::Char_S:
562 case BuiltinType::SChar:
574 analyze_printf::PrintfConversionSpecifier::sArg) {
600 bool dumpUnnamedRecord(
const RecordDecl *RD,
Expr *
E,
unsigned Depth) {
601 Expr *IndentLit = getIndentString(Depth);
603 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
604 : callPrintFunction(
"%s", {TypeLit}))
607 return dumpRecordValue(RD,
E, IndentLit, Depth);
620 Expr *RecordArg = makeOpaqueValueExpr(
E);
623 if (callPrintFunction(
" {\n"))
627 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
628 for (
const auto &
Base : CXXRD->bases()) {
636 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
642 Expr *FieldIndentArg = getIndentString(Depth + 1);
645 for (
auto *
D : RD->
decls()) {
646 auto *IFD = dyn_cast<IndirectFieldDecl>(
D);
647 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(
D);
648 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
654 getStringLiteral(FD->getName())};
656 if (FD->isBitField()) {
660 FD->getBitWidthValue(S.
Context));
674 if (
Field.isInvalid())
677 auto *InnerRD = FD->getType()->getAsRecordDecl();
678 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
679 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
681 if (callPrintFunction(Format, Args) ||
682 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
686 if (appendFormatSpecifier(FD->getType(), Format)) {
688 Args.push_back(
Field.get());
698 Args.push_back(FieldAddr.
get());
701 if (callPrintFunction(Format, Args))
706 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
707 : callPrintFunction(
"}\n");
710 Expr *buildWrapper() {
713 TheCall->
setType(Wrapper->getType());
734 diag::err_expected_struct_pointer_argument)
743 diag::err_incomplete_type))
752 switch (BT ? BT->getKind() : BuiltinType::Void) {
753 case BuiltinType::Dependent:
754 case BuiltinType::Overload:
755 case BuiltinType::BoundMember:
756 case BuiltinType::PseudoObject:
757 case BuiltinType::UnknownAny:
758 case BuiltinType::BuiltinFn:
764 diag::err_expected_callable_argument)
770 BuiltinDumpStructGenerator Generator(S, TheCall);
776 Expr *PtrArg = PtrArgResult.
get();
780 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
783 return Generator.buildWrapper();
795 if (
Call->getStmtClass() != Stmt::CallExprClass) {
796 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
797 <<
Call->getSourceRange();
801 auto CE = cast<CallExpr>(
Call);
802 if (CE->getCallee()->getType()->isBlockPointerType()) {
803 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
804 <<
Call->getSourceRange();
808 const Decl *TargetDecl = CE->getCalleeDecl();
809 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
810 if (FD->getBuiltinID()) {
811 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
812 <<
Call->getSourceRange();
816 if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {
817 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
818 <<
Call->getSourceRange();
826 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
840 BuiltinCall->
setType(CE->getType());
844 BuiltinCall->
setArg(1, ChainResult.
get());
851class ScanfDiagnosticFormatHandler
855 using ComputeSizeFunction =
856 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
860 using DiagnoseFunction =
861 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
863 ComputeSizeFunction ComputeSizeArgument;
864 DiagnoseFunction Diagnose;
867 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
868 DiagnoseFunction Diagnose)
869 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
872 const char *StartSpecifier,
873 unsigned specifierLen)
override {
874 if (!FS.consumesDataArgument())
877 unsigned NulByte = 0;
878 switch ((FS.getConversionSpecifier().getKind())) {
891 analyze_format_string::OptionalAmount::HowSpecified::Constant)
896 std::optional<llvm::APSInt> DestSizeAPS =
897 ComputeSizeArgument(FS.getArgIndex());
901 unsigned DestSize = DestSizeAPS->getZExtValue();
903 if (DestSize < SourceSize)
904 Diagnose(FS.getArgIndex(), DestSize, SourceSize);
910class EstimateSizeFormatHandler
915 bool IsKernelCompatible =
true;
918 EstimateSizeFormatHandler(StringRef Format)
919 :
Size(
std::
min(Format.find(0), Format.size()) +
923 const char *,
unsigned SpecifierLen,
926 const size_t FieldWidth = computeFieldWidth(FS);
927 const size_t Precision = computePrecision(FS);
930 switch (FS.getConversionSpecifier().getKind()) {
934 Size += std::max(FieldWidth, (
size_t)1);
946 Size += std::max(FieldWidth, Precision);
962 Size += std::max(FieldWidth, 1 +
963 (Precision ? 1 + Precision
973 (Precision ? 1 + Precision : 0) +
983 (Precision ? 1 + Precision : 0) +
998 IsKernelCompatible =
false;
999 Size += std::max(FieldWidth, 2 + Precision);
1011 Size += FS.hasPlusPrefix() || FS.hasSpacePrefix();
1013 if (FS.hasAlternativeForm()) {
1014 switch (FS.getConversionSpecifier().getKind()) {
1043 Size += (Precision ? 0 : 1);
1050 assert(SpecifierLen <= Size &&
"no underflow");
1051 Size -= SpecifierLen;
1055 size_t getSizeLowerBound()
const {
return Size; }
1056 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1061 size_t FieldWidth = 0;
1069 size_t Precision = 0;
1074 switch (FS.getConversionSpecifier().getKind()) {
1116 StringRef &FormatStrRef,
size_t &StrLen,
1118 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1119 Format && (Format->isOrdinary() || Format->isUTF8())) {
1120 FormatStrRef = Format->getString();
1123 assert(
T &&
"String literal not of constant array type!");
1124 size_t TypeSize =
T->getZExtSize();
1126 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1132void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1138 bool UseDABAttr =
false;
1141 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1143 UseDecl = DABAttr->getFunction();
1144 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1156 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1163 unsigned DABIndices = DABAttr->argIndices_size();
1164 unsigned NewIndex = Index < DABIndices
1165 ? DABAttr->argIndices_begin()[Index]
1168 return std::nullopt;
1172 auto ComputeExplicitObjectSizeArgument =
1173 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1174 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1176 return std::nullopt;
1177 unsigned NewIndex = *IndexOptional;
1181 return std::nullopt;
1187 auto ComputeSizeArgument =
1188 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1194 if (Index < FD->getNumParams()) {
1195 if (
const auto *POS =
1197 BOSType = POS->getType();
1200 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1202 return std::nullopt;
1203 unsigned NewIndex = *IndexOptional;
1206 return std::nullopt;
1208 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1211 return std::nullopt;
1214 return llvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1217 auto ComputeStrLenArgument =
1218 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1219 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1221 return std::nullopt;
1222 unsigned NewIndex = *IndexOptional;
1224 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1227 return std::nullopt;
1229 return llvm::APSInt::getUnsigned(
Result + 1).extOrTrunc(SizeTypeWidth);
1232 std::optional<llvm::APSInt> SourceSize;
1233 std::optional<llvm::APSInt> DestinationSize;
1234 unsigned DiagID = 0;
1235 bool IsChkVariant =
false;
1237 auto GetFunctionName = [&]() {
1243 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1244 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1246 FunctionName.consume_front(
"__builtin_");
1248 return FunctionName;
1251 switch (BuiltinID) {
1254 case Builtin::BI__builtin_strcpy:
1255 case Builtin::BIstrcpy: {
1256 DiagID = diag::warn_fortify_strlen_overflow;
1257 SourceSize = ComputeStrLenArgument(1);
1258 DestinationSize = ComputeSizeArgument(0);
1262 case Builtin::BI__builtin___strcpy_chk: {
1263 DiagID = diag::warn_fortify_strlen_overflow;
1264 SourceSize = ComputeStrLenArgument(1);
1265 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1266 IsChkVariant =
true;
1270 case Builtin::BIscanf:
1271 case Builtin::BIfscanf:
1272 case Builtin::BIsscanf: {
1273 unsigned FormatIndex = 1;
1274 unsigned DataIndex = 2;
1275 if (BuiltinID == Builtin::BIscanf) {
1280 const auto *FormatExpr =
1283 StringRef FormatStrRef;
1288 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1289 unsigned SourceSize) {
1290 DiagID = diag::warn_fortify_scanf_overflow;
1291 unsigned Index = ArgIndex + DataIndex;
1292 StringRef FunctionName = GetFunctionName();
1294 PDiag(DiagID) << FunctionName << (Index + 1)
1295 << DestSize << SourceSize);
1298 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1299 return ComputeSizeArgument(Index + DataIndex);
1301 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1302 const char *FormatBytes = FormatStrRef.data();
1313 case Builtin::BIsprintf:
1314 case Builtin::BI__builtin___sprintf_chk: {
1315 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1318 StringRef FormatStrRef;
1321 EstimateSizeFormatHandler H(FormatStrRef);
1322 const char *FormatBytes = FormatStrRef.data();
1324 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1326 DiagID = H.isKernelCompatible()
1327 ? diag::warn_format_overflow
1328 : diag::warn_format_overflow_non_kprintf;
1329 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1330 .extOrTrunc(SizeTypeWidth);
1331 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1332 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1333 IsChkVariant =
true;
1335 DestinationSize = ComputeSizeArgument(0);
1342 case Builtin::BI__builtin___memcpy_chk:
1343 case Builtin::BI__builtin___memmove_chk:
1344 case Builtin::BI__builtin___memset_chk:
1345 case Builtin::BI__builtin___strlcat_chk:
1346 case Builtin::BI__builtin___strlcpy_chk:
1347 case Builtin::BI__builtin___strncat_chk:
1348 case Builtin::BI__builtin___strncpy_chk:
1349 case Builtin::BI__builtin___stpncpy_chk:
1350 case Builtin::BI__builtin___memccpy_chk:
1351 case Builtin::BI__builtin___mempcpy_chk: {
1352 DiagID = diag::warn_builtin_chk_overflow;
1353 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1355 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1356 IsChkVariant =
true;
1360 case Builtin::BI__builtin___snprintf_chk:
1361 case Builtin::BI__builtin___vsnprintf_chk: {
1362 DiagID = diag::warn_builtin_chk_overflow;
1363 SourceSize = ComputeExplicitObjectSizeArgument(1);
1364 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1365 IsChkVariant =
true;
1369 case Builtin::BIstrncat:
1370 case Builtin::BI__builtin_strncat:
1371 case Builtin::BIstrncpy:
1372 case Builtin::BI__builtin_strncpy:
1373 case Builtin::BIstpncpy:
1374 case Builtin::BI__builtin_stpncpy: {
1380 DiagID = diag::warn_fortify_source_size_mismatch;
1381 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1382 DestinationSize = ComputeSizeArgument(0);
1386 case Builtin::BImemcpy:
1387 case Builtin::BI__builtin_memcpy:
1388 case Builtin::BImemmove:
1389 case Builtin::BI__builtin_memmove:
1390 case Builtin::BImemset:
1391 case Builtin::BI__builtin_memset:
1392 case Builtin::BImempcpy:
1393 case Builtin::BI__builtin_mempcpy: {
1394 DiagID = diag::warn_fortify_source_overflow;
1395 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1396 DestinationSize = ComputeSizeArgument(0);
1399 case Builtin::BIsnprintf:
1400 case Builtin::BI__builtin_snprintf:
1401 case Builtin::BIvsnprintf:
1402 case Builtin::BI__builtin_vsnprintf: {
1403 DiagID = diag::warn_fortify_source_size_mismatch;
1404 SourceSize = ComputeExplicitObjectSizeArgument(1);
1406 StringRef FormatStrRef;
1410 EstimateSizeFormatHandler H(FormatStrRef);
1411 const char *FormatBytes = FormatStrRef.data();
1413 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1415 llvm::APSInt FormatSize =
1416 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1417 .extOrTrunc(SizeTypeWidth);
1418 if (FormatSize > *SourceSize && *SourceSize != 0) {
1419 unsigned TruncationDiagID =
1420 H.isKernelCompatible() ? diag::warn_format_truncation
1421 : diag::warn_format_truncation_non_kprintf;
1424 SourceSize->toString(SpecifiedSizeStr, 10);
1425 FormatSize.toString(FormatSizeStr, 10);
1427 PDiag(TruncationDiagID)
1428 << GetFunctionName() << SpecifiedSizeStr
1433 DestinationSize = ComputeSizeArgument(0);
1437 if (!SourceSize || !DestinationSize ||
1438 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1441 StringRef FunctionName = GetFunctionName();
1445 DestinationSize->toString(DestinationStr, 10);
1446 SourceSize->toString(SourceStr, 10);
1449 << FunctionName << DestinationStr << SourceStr);
1462 while (S && !S->isSEHExceptScope())
1464 if (!S || !(S->getFlags() & NeededScopeFlags)) {
1467 << DRE->getDecl()->getIdentifier();
1479 "__builtin_alloca has invalid address space");
1487enum PointerAuthOpKind {
1536 llvm::raw_svector_ostream Str(
Value);
1545 Result = KeyValue->getZExtValue();
1549static std::pair<const ValueDecl *, CharUnits>
1556 const auto *BaseDecl =
1561 return {BaseDecl,
Result.Val.getLValueOffset()};
1565 bool RequireConstant =
false) {
1573 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1574 return OpKind != PAO_BlendInteger;
1576 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1577 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1578 OpKind == PAO_SignGeneric;
1587 }
else if (AllowsInteger(OpKind) &&
1594 <<
unsigned(OpKind == PAO_Discriminator ? 1
1595 : OpKind == PAO_BlendPointer ? 2
1596 : OpKind == PAO_BlendInteger ? 3
1598 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1608 if (!RequireConstant) {
1610 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1613 ? diag::warn_ptrauth_sign_null_pointer
1614 : diag::warn_ptrauth_auth_null_pointer)
1624 if (OpKind == PAO_Sign) {
1634 else if (isa<FunctionDecl>(BaseDecl))
1642 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1647 assert(OpKind == PAO_Discriminator);
1653 if (
Call->getBuiltinCallee() ==
1654 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1669 assert(
Pointer->getType()->isPointerType());
1675 if (!BaseDecl || !isa<VarDecl>(BaseDecl))
1681 assert(
Integer->getType()->isIntegerType());
1687 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1700 Call->setType(
Call->getArgs()[0]->getType());
1731 PointerAuthOpKind OpKind,
1732 bool RequireConstant) {
1743 Call->setType(
Call->getArgs()[0]->getType());
1759 Call->setType(
Call->getArgs()[0]->getType());
1768 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1771 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1772 if (!Literal || Literal->getCharByteWidth() != 1) {
1802 auto DiagSelect = [&]() -> std::optional<unsigned> {
1809 return std::optional<unsigned>{};
1824 diag::err_incomplete_type))
1828 "Unhandled non-object pointer case");
1856 if (PT->getPointeeType()->isFunctionType()) {
1858 diag::err_builtin_is_within_lifetime_invalid_arg)
1864 if (PT->getPointeeType()->isVariableArrayType()) {
1866 << 1 <<
"__builtin_is_within_lifetime";
1871 diag::err_builtin_is_within_lifetime_invalid_arg)
1884 llvm::Triple::ObjectFormatType CurObjFormat =
1886 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
1899 llvm::Triple::ArchType CurArch =
1901 if (llvm::is_contained(SupportedArchs, CurArch))
1911bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
1918 case llvm::Triple::arm:
1919 case llvm::Triple::armeb:
1920 case llvm::Triple::thumb:
1921 case llvm::Triple::thumbeb:
1923 case llvm::Triple::aarch64:
1924 case llvm::Triple::aarch64_32:
1925 case llvm::Triple::aarch64_be:
1927 case llvm::Triple::bpfeb:
1928 case llvm::Triple::bpfel:
1930 case llvm::Triple::hexagon:
1932 case llvm::Triple::mips:
1933 case llvm::Triple::mipsel:
1934 case llvm::Triple::mips64:
1935 case llvm::Triple::mips64el:
1937 case llvm::Triple::systemz:
1939 case llvm::Triple::x86:
1940 case llvm::Triple::x86_64:
1942 case llvm::Triple::ppc:
1943 case llvm::Triple::ppcle:
1944 case llvm::Triple::ppc64:
1945 case llvm::Triple::ppc64le:
1947 case llvm::Triple::amdgcn:
1949 case llvm::Triple::riscv32:
1950 case llvm::Triple::riscv64:
1952 case llvm::Triple::loongarch32:
1953 case llvm::Triple::loongarch64:
1956 case llvm::Triple::wasm32:
1957 case llvm::Triple::wasm64:
1959 case llvm::Triple::nvptx:
1960 case llvm::Triple::nvptx64:
1972 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1973 << ArgIndex << 0 << ArgTy;
1983 EltTy = VecTy->getElementType();
1986 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1987 << ArgIndex << 5 << ArgTy;
1997 const TargetInfo *AuxTI,
unsigned BuiltinID) {
1998 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
1999 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2000 "Expecting __builtin_cpu_...");
2002 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2004 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2005 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2006 (!IsCPUSupports && TInfo->supportsCpuIs()));
2008 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2015 ? diag::err_builtin_aix_os_unsupported
2016 : diag::err_builtin_target_unsupported)
2021 if (!isa<StringLiteral>(Arg))
2022 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2026 StringRef Feature = cast<StringLiteral>(Arg)->getString();
2073 TheCall->
setArg(0, Arg0);
2079 << 1 << 7 << Arg0Ty;
2089 TheCall->
setArg(1, Arg1);
2095 << 2 << 8 << Arg1Ty;
2104Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2109 unsigned ICEArguments = 0;
2116 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2118 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2123 if (ArgNo < TheCall->getNumArgs() &&
2126 ICEArguments &= ~(1 << ArgNo);
2130 switch (BuiltinID) {
2131 case Builtin::BI__builtin_cpu_supports:
2132 case Builtin::BI__builtin_cpu_is:
2137 case Builtin::BI__builtin_cpu_init:
2144 case Builtin::BI__builtin___CFStringMakeConstantString:
2148 *
this, BuiltinID, TheCall,
2149 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2152 "Wrong # arguments to builtin CFStringMakeConstantString");
2153 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2156 case Builtin::BI__builtin_ms_va_start:
2157 case Builtin::BI__builtin_stdarg_start:
2158 case Builtin::BI__builtin_va_start:
2159 if (BuiltinVAStart(BuiltinID, TheCall))
2162 case Builtin::BI__va_start: {
2164 case llvm::Triple::aarch64:
2165 case llvm::Triple::arm:
2166 case llvm::Triple::thumb:
2167 if (BuiltinVAStartARMMicrosoft(TheCall))
2171 if (BuiltinVAStart(BuiltinID, TheCall))
2179 case Builtin::BI_interlockedbittestandset_acq:
2180 case Builtin::BI_interlockedbittestandset_rel:
2181 case Builtin::BI_interlockedbittestandset_nf:
2182 case Builtin::BI_interlockedbittestandreset_acq:
2183 case Builtin::BI_interlockedbittestandreset_rel:
2184 case Builtin::BI_interlockedbittestandreset_nf:
2187 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2192 case Builtin::BI_bittest64:
2193 case Builtin::BI_bittestandcomplement64:
2194 case Builtin::BI_bittestandreset64:
2195 case Builtin::BI_bittestandset64:
2196 case Builtin::BI_interlockedbittestandreset64:
2197 case Builtin::BI_interlockedbittestandset64:
2200 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2201 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2205 case Builtin::BI__builtin_set_flt_rounds:
2208 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2209 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2210 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2211 llvm::Triple::ppc64le}))
2215 case Builtin::BI__builtin_isgreater:
2216 case Builtin::BI__builtin_isgreaterequal:
2217 case Builtin::BI__builtin_isless:
2218 case Builtin::BI__builtin_islessequal:
2219 case Builtin::BI__builtin_islessgreater:
2220 case Builtin::BI__builtin_isunordered:
2221 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2224 case Builtin::BI__builtin_fpclassify:
2225 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2228 case Builtin::BI__builtin_isfpclass:
2229 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2232 case Builtin::BI__builtin_isfinite:
2233 case Builtin::BI__builtin_isinf:
2234 case Builtin::BI__builtin_isinf_sign:
2235 case Builtin::BI__builtin_isnan:
2236 case Builtin::BI__builtin_issignaling:
2237 case Builtin::BI__builtin_isnormal:
2238 case Builtin::BI__builtin_issubnormal:
2239 case Builtin::BI__builtin_iszero:
2240 case Builtin::BI__builtin_signbit:
2241 case Builtin::BI__builtin_signbitf:
2242 case Builtin::BI__builtin_signbitl:
2243 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2246 case Builtin::BI__builtin_shufflevector:
2250 case Builtin::BI__builtin_prefetch:
2251 if (BuiltinPrefetch(TheCall))
2254 case Builtin::BI__builtin_alloca_with_align:
2255 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2256 if (BuiltinAllocaWithAlign(TheCall))
2259 case Builtin::BI__builtin_alloca:
2260 case Builtin::BI__builtin_alloca_uninitialized:
2267 case Builtin::BI__arithmetic_fence:
2268 if (BuiltinArithmeticFence(TheCall))
2271 case Builtin::BI__assume:
2272 case Builtin::BI__builtin_assume:
2273 if (BuiltinAssume(TheCall))
2276 case Builtin::BI__builtin_assume_aligned:
2277 if (BuiltinAssumeAligned(TheCall))
2280 case Builtin::BI__builtin_dynamic_object_size:
2281 case Builtin::BI__builtin_object_size:
2285 case Builtin::BI__builtin_longjmp:
2286 if (BuiltinLongjmp(TheCall))
2289 case Builtin::BI__builtin_setjmp:
2290 if (BuiltinSetjmp(TheCall))
2293 case Builtin::BI__builtin_classify_type:
2298 case Builtin::BI__builtin_complex:
2299 if (BuiltinComplex(TheCall))
2302 case Builtin::BI__builtin_constant_p: {
2311 case Builtin::BI__builtin_launder:
2313 case Builtin::BI__builtin_is_within_lifetime:
2315 case Builtin::BI__sync_fetch_and_add:
2316 case Builtin::BI__sync_fetch_and_add_1:
2317 case Builtin::BI__sync_fetch_and_add_2:
2318 case Builtin::BI__sync_fetch_and_add_4:
2319 case Builtin::BI__sync_fetch_and_add_8:
2320 case Builtin::BI__sync_fetch_and_add_16:
2321 case Builtin::BI__sync_fetch_and_sub:
2322 case Builtin::BI__sync_fetch_and_sub_1:
2323 case Builtin::BI__sync_fetch_and_sub_2:
2324 case Builtin::BI__sync_fetch_and_sub_4:
2325 case Builtin::BI__sync_fetch_and_sub_8:
2326 case Builtin::BI__sync_fetch_and_sub_16:
2327 case Builtin::BI__sync_fetch_and_or:
2328 case Builtin::BI__sync_fetch_and_or_1:
2329 case Builtin::BI__sync_fetch_and_or_2:
2330 case Builtin::BI__sync_fetch_and_or_4:
2331 case Builtin::BI__sync_fetch_and_or_8:
2332 case Builtin::BI__sync_fetch_and_or_16:
2333 case Builtin::BI__sync_fetch_and_and:
2334 case Builtin::BI__sync_fetch_and_and_1:
2335 case Builtin::BI__sync_fetch_and_and_2:
2336 case Builtin::BI__sync_fetch_and_and_4:
2337 case Builtin::BI__sync_fetch_and_and_8:
2338 case Builtin::BI__sync_fetch_and_and_16:
2339 case Builtin::BI__sync_fetch_and_xor:
2340 case Builtin::BI__sync_fetch_and_xor_1:
2341 case Builtin::BI__sync_fetch_and_xor_2:
2342 case Builtin::BI__sync_fetch_and_xor_4:
2343 case Builtin::BI__sync_fetch_and_xor_8:
2344 case Builtin::BI__sync_fetch_and_xor_16:
2345 case Builtin::BI__sync_fetch_and_nand:
2346 case Builtin::BI__sync_fetch_and_nand_1:
2347 case Builtin::BI__sync_fetch_and_nand_2:
2348 case Builtin::BI__sync_fetch_and_nand_4:
2349 case Builtin::BI__sync_fetch_and_nand_8:
2350 case Builtin::BI__sync_fetch_and_nand_16:
2351 case Builtin::BI__sync_add_and_fetch:
2352 case Builtin::BI__sync_add_and_fetch_1:
2353 case Builtin::BI__sync_add_and_fetch_2:
2354 case Builtin::BI__sync_add_and_fetch_4:
2355 case Builtin::BI__sync_add_and_fetch_8:
2356 case Builtin::BI__sync_add_and_fetch_16:
2357 case Builtin::BI__sync_sub_and_fetch:
2358 case Builtin::BI__sync_sub_and_fetch_1:
2359 case Builtin::BI__sync_sub_and_fetch_2:
2360 case Builtin::BI__sync_sub_and_fetch_4:
2361 case Builtin::BI__sync_sub_and_fetch_8:
2362 case Builtin::BI__sync_sub_and_fetch_16:
2363 case Builtin::BI__sync_and_and_fetch:
2364 case Builtin::BI__sync_and_and_fetch_1:
2365 case Builtin::BI__sync_and_and_fetch_2:
2366 case Builtin::BI__sync_and_and_fetch_4:
2367 case Builtin::BI__sync_and_and_fetch_8:
2368 case Builtin::BI__sync_and_and_fetch_16:
2369 case Builtin::BI__sync_or_and_fetch:
2370 case Builtin::BI__sync_or_and_fetch_1:
2371 case Builtin::BI__sync_or_and_fetch_2:
2372 case Builtin::BI__sync_or_and_fetch_4:
2373 case Builtin::BI__sync_or_and_fetch_8:
2374 case Builtin::BI__sync_or_and_fetch_16:
2375 case Builtin::BI__sync_xor_and_fetch:
2376 case Builtin::BI__sync_xor_and_fetch_1:
2377 case Builtin::BI__sync_xor_and_fetch_2:
2378 case Builtin::BI__sync_xor_and_fetch_4:
2379 case Builtin::BI__sync_xor_and_fetch_8:
2380 case Builtin::BI__sync_xor_and_fetch_16:
2381 case Builtin::BI__sync_nand_and_fetch:
2382 case Builtin::BI__sync_nand_and_fetch_1:
2383 case Builtin::BI__sync_nand_and_fetch_2:
2384 case Builtin::BI__sync_nand_and_fetch_4:
2385 case Builtin::BI__sync_nand_and_fetch_8:
2386 case Builtin::BI__sync_nand_and_fetch_16:
2387 case Builtin::BI__sync_val_compare_and_swap:
2388 case Builtin::BI__sync_val_compare_and_swap_1:
2389 case Builtin::BI__sync_val_compare_and_swap_2:
2390 case Builtin::BI__sync_val_compare_and_swap_4:
2391 case Builtin::BI__sync_val_compare_and_swap_8:
2392 case Builtin::BI__sync_val_compare_and_swap_16:
2393 case Builtin::BI__sync_bool_compare_and_swap:
2394 case Builtin::BI__sync_bool_compare_and_swap_1:
2395 case Builtin::BI__sync_bool_compare_and_swap_2:
2396 case Builtin::BI__sync_bool_compare_and_swap_4:
2397 case Builtin::BI__sync_bool_compare_and_swap_8:
2398 case Builtin::BI__sync_bool_compare_and_swap_16:
2399 case Builtin::BI__sync_lock_test_and_set:
2400 case Builtin::BI__sync_lock_test_and_set_1:
2401 case Builtin::BI__sync_lock_test_and_set_2:
2402 case Builtin::BI__sync_lock_test_and_set_4:
2403 case Builtin::BI__sync_lock_test_and_set_8:
2404 case Builtin::BI__sync_lock_test_and_set_16:
2405 case Builtin::BI__sync_lock_release:
2406 case Builtin::BI__sync_lock_release_1:
2407 case Builtin::BI__sync_lock_release_2:
2408 case Builtin::BI__sync_lock_release_4:
2409 case Builtin::BI__sync_lock_release_8:
2410 case Builtin::BI__sync_lock_release_16:
2411 case Builtin::BI__sync_swap:
2412 case Builtin::BI__sync_swap_1:
2413 case Builtin::BI__sync_swap_2:
2414 case Builtin::BI__sync_swap_4:
2415 case Builtin::BI__sync_swap_8:
2416 case Builtin::BI__sync_swap_16:
2417 return BuiltinAtomicOverloaded(TheCallResult);
2418 case Builtin::BI__sync_synchronize:
2422 case Builtin::BI__builtin_nontemporal_load:
2423 case Builtin::BI__builtin_nontemporal_store:
2424 return BuiltinNontemporalOverloaded(TheCallResult);
2425 case Builtin::BI__builtin_memcpy_inline: {
2438 case Builtin::BI__builtin_memset_inline: {
2449#define BUILTIN(ID, TYPE, ATTRS)
2450#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2451 case Builtin::BI##ID: \
2452 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2453#include "clang/Basic/Builtins.inc"
2454 case Builtin::BI__annotation:
2458 case Builtin::BI__builtin_annotation:
2462 case Builtin::BI__builtin_addressof:
2466 case Builtin::BI__builtin_function_start:
2470 case Builtin::BI__builtin_is_aligned:
2471 case Builtin::BI__builtin_align_up:
2472 case Builtin::BI__builtin_align_down:
2476 case Builtin::BI__builtin_add_overflow:
2477 case Builtin::BI__builtin_sub_overflow:
2478 case Builtin::BI__builtin_mul_overflow:
2482 case Builtin::BI__builtin_operator_new:
2483 case Builtin::BI__builtin_operator_delete: {
2484 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2486 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2491 case Builtin::BI__builtin_dump_struct:
2493 case Builtin::BI__builtin_expect_with_probability: {
2504 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2511 bool LoseInfo =
false;
2512 Probability.convert(llvm::APFloat::IEEEdouble(),
2513 llvm::RoundingMode::Dynamic, &LoseInfo);
2514 if (!(Probability >= llvm::APFloat(0.0) &&
2515 Probability <= llvm::APFloat(1.0))) {
2522 case Builtin::BI__builtin_preserve_access_index:
2526 case Builtin::BI__builtin_call_with_static_chain:
2530 case Builtin::BI__exception_code:
2531 case Builtin::BI_exception_code:
2533 diag::err_seh___except_block))
2536 case Builtin::BI__exception_info:
2537 case Builtin::BI_exception_info:
2539 diag::err_seh___except_filter))
2542 case Builtin::BI__GetExceptionInfo:
2554 case Builtin::BIaddressof:
2555 case Builtin::BI__addressof:
2556 case Builtin::BIforward:
2557 case Builtin::BIforward_like:
2558 case Builtin::BImove:
2559 case Builtin::BImove_if_noexcept:
2560 case Builtin::BIas_const: {
2568 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
2569 BuiltinID == Builtin::BI__addressof;
2571 (ReturnsPointer ?
Result->isAnyPointerType()
2572 :
Result->isReferenceType()) &&
2574 Result->getPointeeType()))) {
2575 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
2581 case Builtin::BI__builtin_ptrauth_strip:
2583 case Builtin::BI__builtin_ptrauth_blend_discriminator:
2585 case Builtin::BI__builtin_ptrauth_sign_constant:
2588 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
2591 case Builtin::BI__builtin_ptrauth_auth:
2594 case Builtin::BI__builtin_ptrauth_sign_generic_data:
2596 case Builtin::BI__builtin_ptrauth_auth_and_resign:
2598 case Builtin::BI__builtin_ptrauth_string_discriminator:
2601 case Builtin::BIread_pipe:
2602 case Builtin::BIwrite_pipe:
2605 if (
OpenCL().checkBuiltinRWPipe(TheCall))
2608 case Builtin::BIreserve_read_pipe:
2609 case Builtin::BIreserve_write_pipe:
2610 case Builtin::BIwork_group_reserve_read_pipe:
2611 case Builtin::BIwork_group_reserve_write_pipe:
2612 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
2615 case Builtin::BIsub_group_reserve_read_pipe:
2616 case Builtin::BIsub_group_reserve_write_pipe:
2617 if (
OpenCL().checkSubgroupExt(TheCall) ||
2618 OpenCL().checkBuiltinReserveRWPipe(TheCall))
2621 case Builtin::BIcommit_read_pipe:
2622 case Builtin::BIcommit_write_pipe:
2623 case Builtin::BIwork_group_commit_read_pipe:
2624 case Builtin::BIwork_group_commit_write_pipe:
2625 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
2628 case Builtin::BIsub_group_commit_read_pipe:
2629 case Builtin::BIsub_group_commit_write_pipe:
2630 if (
OpenCL().checkSubgroupExt(TheCall) ||
2631 OpenCL().checkBuiltinCommitRWPipe(TheCall))
2634 case Builtin::BIget_pipe_num_packets:
2635 case Builtin::BIget_pipe_max_packets:
2636 if (
OpenCL().checkBuiltinPipePackets(TheCall))
2639 case Builtin::BIto_global:
2640 case Builtin::BIto_local:
2641 case Builtin::BIto_private:
2642 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
2646 case Builtin::BIenqueue_kernel:
2647 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
2650 case Builtin::BIget_kernel_work_group_size:
2651 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
2652 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
2655 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2656 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
2657 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
2660 case Builtin::BI__builtin_os_log_format:
2663 case Builtin::BI__builtin_os_log_format_buffer_size:
2664 if (BuiltinOSLogFormat(TheCall))
2667 case Builtin::BI__builtin_frame_address:
2668 case Builtin::BI__builtin_return_address: {
2677 Result.Val.getInt() != 0)
2679 << ((BuiltinID == Builtin::BI__builtin_return_address)
2680 ?
"__builtin_return_address"
2681 :
"__builtin_frame_address")
2686 case Builtin::BI__builtin_nondeterministic_value: {
2687 if (BuiltinNonDeterministicValue(TheCall))
2694 case Builtin::BI__builtin_elementwise_abs: {
2702 EltTy = VecTy->getElementType();
2705 diag::err_builtin_invalid_arg_type)
2714 case Builtin::BI__builtin_elementwise_acos:
2715 case Builtin::BI__builtin_elementwise_asin:
2716 case Builtin::BI__builtin_elementwise_atan:
2717 case Builtin::BI__builtin_elementwise_ceil:
2718 case Builtin::BI__builtin_elementwise_cos:
2719 case Builtin::BI__builtin_elementwise_cosh:
2720 case Builtin::BI__builtin_elementwise_exp:
2721 case Builtin::BI__builtin_elementwise_exp2:
2722 case Builtin::BI__builtin_elementwise_floor:
2723 case Builtin::BI__builtin_elementwise_log:
2724 case Builtin::BI__builtin_elementwise_log2:
2725 case Builtin::BI__builtin_elementwise_log10:
2726 case Builtin::BI__builtin_elementwise_roundeven:
2727 case Builtin::BI__builtin_elementwise_round:
2728 case Builtin::BI__builtin_elementwise_rint:
2729 case Builtin::BI__builtin_elementwise_nearbyint:
2730 case Builtin::BI__builtin_elementwise_sin:
2731 case Builtin::BI__builtin_elementwise_sinh:
2732 case Builtin::BI__builtin_elementwise_sqrt:
2733 case Builtin::BI__builtin_elementwise_tan:
2734 case Builtin::BI__builtin_elementwise_tanh:
2735 case Builtin::BI__builtin_elementwise_trunc:
2736 case Builtin::BI__builtin_elementwise_canonicalize: {
2746 case Builtin::BI__builtin_elementwise_fma: {
2754 case Builtin::BI__builtin_elementwise_minimum:
2755 case Builtin::BI__builtin_elementwise_maximum:
2756 case Builtin::BI__builtin_elementwise_atan2:
2757 case Builtin::BI__builtin_elementwise_fmod:
2758 case Builtin::BI__builtin_elementwise_pow: {
2759 if (BuiltinElementwiseMath(TheCall,
true))
2766 case Builtin::BI__builtin_elementwise_add_sat:
2767 case Builtin::BI__builtin_elementwise_sub_sat: {
2768 if (BuiltinElementwiseMath(TheCall))
2776 EltTy = VecTy->getElementType();
2786 case Builtin::BI__builtin_elementwise_min:
2787 case Builtin::BI__builtin_elementwise_max:
2788 if (BuiltinElementwiseMath(TheCall))
2791 case Builtin::BI__builtin_elementwise_popcount:
2792 case Builtin::BI__builtin_elementwise_bitreverse: {
2801 EltTy = VecTy->getElementType();
2811 case Builtin::BI__builtin_elementwise_copysign: {
2831 diag::err_typecheck_call_different_arg_types)
2832 << MagnitudeTy << SignTy;
2840 case Builtin::BI__builtin_reduce_max:
2841 case Builtin::BI__builtin_reduce_min: {
2842 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2850 ElTy = TyA->getElementType();
2854 if (ElTy.isNull()) {
2863 case Builtin::BI__builtin_reduce_maximum:
2864 case Builtin::BI__builtin_reduce_minimum: {
2865 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2873 ElTy = TyA->getElementType();
2877 if (ElTy.isNull() || !ElTy->isFloatingType()) {
2889 case Builtin::BI__builtin_reduce_add:
2890 case Builtin::BI__builtin_reduce_mul:
2891 case Builtin::BI__builtin_reduce_xor:
2892 case Builtin::BI__builtin_reduce_or:
2893 case Builtin::BI__builtin_reduce_and: {
2894 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2902 ElTy = TyA->getElementType();
2906 if (ElTy.isNull() || !ElTy->isIntegerType()) {
2916 case Builtin::BI__builtin_matrix_transpose:
2917 return BuiltinMatrixTranspose(TheCall, TheCallResult);
2919 case Builtin::BI__builtin_matrix_column_major_load:
2920 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
2922 case Builtin::BI__builtin_matrix_column_major_store:
2923 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
2925 case Builtin::BI__builtin_verbose_trap:
2930 case Builtin::BI__builtin_get_device_side_mangled_name: {
2931 auto Check = [](
CallExpr *TheCall) {
2937 auto *
D = DRE->getDecl();
2938 if (!isa<FunctionDecl>(
D) && !isa<VarDecl>(
D))
2943 if (!Check(TheCall)) {
2945 diag::err_hip_invalid_args_builtin_mangled_name);
2950 case Builtin::BI__builtin_popcountg:
2954 case Builtin::BI__builtin_clzg:
2955 case Builtin::BI__builtin_ctzg:
2960 case Builtin::BI__builtin_allow_runtime_check: {
2970 case Builtin::BI__builtin_counted_by_ref:
2971 if (BuiltinCountedByRef(TheCall))
2984 "Aux Target Builtin, but not an aux target?");
2986 if (CheckTSBuiltinFunctionCall(
2997 return TheCallResult;
3012 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3016 diag::err_argument_not_contiguous_bit_field)
3022 if (Format->getFirstArg() == 0)
3024 else if (IsVariadic)
3028 FSI->
FormatIdx = Format->getFormatIdx() - 1;
3052 if (isa<CXXNullPtrLiteralExpr>(
3067 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3068 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3069 Expr = ILE->getInit(0);
3079 const Expr *ArgExpr,
3083 S.
PDiag(diag::warn_null_arg)
3089 if (
auto nullability =
type->getNullability())
3100 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3106 llvm::SmallBitVector NonNullArgs;
3112 for (
const auto *Arg : Args)
3119 unsigned IdxAST = Idx.getASTIndex();
3120 if (IdxAST >= Args.size())
3122 if (NonNullArgs.empty())
3123 NonNullArgs.resize(Args.size());
3124 NonNullArgs.set(IdxAST);
3129 if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {
3133 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3136 parms = cast<ObjCMethodDecl>(FDecl)->parameters();
3138 unsigned ParamIndex = 0;
3140 I !=
E; ++I, ++ParamIndex) {
3143 if (NonNullArgs.empty())
3144 NonNullArgs.resize(Args.size());
3146 NonNullArgs.set(ParamIndex);
3153 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3158 type = blockType->getPointeeType();
3172 if (NonNullArgs.empty())
3173 NonNullArgs.resize(Args.size());
3175 NonNullArgs.set(Index);
3184 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3185 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3186 if (NonNullArgs[ArgIndex])
3192 StringRef ParamName,
QualType ArgTy,
3220 if (ArgAlign < ParamAlign)
3221 Diag(
Loc, diag::warn_param_mismatched_alignment)
3223 << ParamName << (FDecl !=
nullptr) << FDecl;
3227 const Expr *ThisArg,
3229 if (!FD || Args.empty())
3231 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3232 if (Idx == LifetimeCaptureByAttr::GLOBAL ||
3233 Idx == LifetimeCaptureByAttr::UNKNOWN)
3235 if (IsMemberFunction && Idx == 0)
3237 return Args[Idx - IsMemberFunction];
3239 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3244 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3245 for (
int CapturingParamIdx :
Attr->params()) {
3248 if (CapturingParamIdx == LifetimeCaptureByAttr::THIS &&
3249 isa<CXXConstructorDecl>(FD))
3251 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3259 I + IsMemberFunction);
3261 if (IsMemberFunction) {
3269 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3282 llvm::SmallBitVector CheckedVarArgs;
3286 CheckedVarArgs.resize(Args.size());
3288 CheckFormatArguments(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3295 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3299 : isa_and_nonnull<FunctionDecl>(FDecl)
3300 ? cast<FunctionDecl>(FDecl)->getNumParams()
3301 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3302 ? cast<ObjCMethodDecl>(FDecl)->param_size()
3305 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3307 if (
const Expr *Arg = Args[ArgIdx]) {
3308 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3315 if (FDecl || Proto) {
3320 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3321 CheckArgumentWithTypeTag(I, Args,
Loc);
3327 if (!Proto && FDecl) {
3329 if (isa_and_nonnull<FunctionProtoType>(FT))
3335 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3337 bool IsScalableArg =
false;
3338 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3340 if (
const Expr *Arg = Args[ArgIdx]) {
3352 IsScalableArg =
true;
3354 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3363 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3364 llvm::StringMap<bool> CallerFeatureMap;
3366 if (!CallerFeatureMap.contains(
"sme"))
3367 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3369 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3376 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3378 (IsScalableArg || IsScalableRet)) {
3379 bool IsCalleeStreaming =
3381 bool IsCalleeStreamingCompatible =
3385 if (!IsCalleeStreamingCompatible &&
3389 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3392 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3403 bool CallerHasZAState =
false;
3404 bool CallerHasZT0State =
false;
3406 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3408 CallerHasZAState =
true;
3410 CallerHasZT0State =
true;
3414 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3416 CallerHasZT0State |=
3418 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3424 Diag(
Loc, diag::err_sme_za_call_no_za_state);
3427 Diag(
Loc, diag::err_sme_zt0_call_no_zt0_state);
3431 Diag(
Loc, diag::err_sme_unimplemented_za_save_restore);
3432 Diag(
Loc, diag::note_sme_use_preserves_za);
3437 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3438 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3439 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3440 if (!Arg->isValueDependent()) {
3442 if (Arg->EvaluateAsInt(Align,
Context)) {
3443 const llvm::APSInt &I = Align.
Val.
getInt();
3444 if (!I.isPowerOf2())
3445 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3446 << Arg->getSourceRange();
3449 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3472 auto *Ctor = cast<CXXConstructorDecl>(FDecl);
3477 checkCall(FDecl, Proto,
nullptr, Args,
true,
3483 bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
3484 isa<CXXMethodDecl>(FDecl);
3485 bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
3486 IsMemberOperatorCall;
3492 Expr *ImplicitThis =
nullptr;
3497 ImplicitThis = Args[0];
3500 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
3503 cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
3515 cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());
3517 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
3535 CheckAbsoluteValueFunction(TheCall, FDecl);
3536 CheckMaxUnsignedZero(TheCall, FDecl);
3537 CheckInfNaNFunction(TheCall, FDecl);
3548 case Builtin::BIstrlcpy:
3549 case Builtin::BIstrlcat:
3550 CheckStrlcpycatArguments(TheCall, FnInfo);
3552 case Builtin::BIstrncat:
3553 CheckStrncatArguments(TheCall, FnInfo);
3555 case Builtin::BIfree:
3556 CheckFreeArguments(TheCall);
3559 CheckMemaccessArguments(TheCall, CMId, FnInfo);
3568 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
3569 Ty =
V->getType().getNonReferenceType();
3570 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
3571 Ty = F->getType().getNonReferenceType();
3608 if (!llvm::isValidAtomicOrderingCABI(Ordering))
3611 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
3613 case AtomicExpr::AO__c11_atomic_init:
3614 case AtomicExpr::AO__opencl_atomic_init:
3615 llvm_unreachable(
"There is no ordering argument for an init");
3617 case AtomicExpr::AO__c11_atomic_load:
3618 case AtomicExpr::AO__opencl_atomic_load:
3619 case AtomicExpr::AO__hip_atomic_load:
3620 case AtomicExpr::AO__atomic_load_n:
3621 case AtomicExpr::AO__atomic_load:
3622 case AtomicExpr::AO__scoped_atomic_load_n:
3623 case AtomicExpr::AO__scoped_atomic_load:
3624 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
3625 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3627 case AtomicExpr::AO__c11_atomic_store:
3628 case AtomicExpr::AO__opencl_atomic_store:
3629 case AtomicExpr::AO__hip_atomic_store:
3630 case AtomicExpr::AO__atomic_store:
3631 case AtomicExpr::AO__atomic_store_n:
3632 case AtomicExpr::AO__scoped_atomic_store:
3633 case AtomicExpr::AO__scoped_atomic_store_n:
3634 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
3635 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
3636 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3645 CallExpr *TheCall = cast<CallExpr>(TheCallResult.
get());
3689 const unsigned NumForm = GNUCmpXchg + 1;
3690 const unsigned NumArgs[] = { 2, 2, 3, 3, 3, 3, 4, 5, 6 };
3691 const unsigned NumVals[] = { 1, 0, 1, 1, 1, 1, 2, 2, 3 };
3699 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
3700 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
3701 "need to update code for modified forms");
3702 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
3703 AtomicExpr::AO__atomic_xor_fetch + 1 ==
3704 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
3705 "need to update code for modified C11 atomics");
3706 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
3707 Op <= AtomicExpr::AO__opencl_atomic_store;
3708 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
3709 Op <= AtomicExpr::AO__hip_atomic_store;
3710 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
3711 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
3712 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
3713 Op <= AtomicExpr::AO__c11_atomic_store) ||
3715 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
3716 Op == AtomicExpr::AO__atomic_store_n ||
3717 Op == AtomicExpr::AO__atomic_exchange_n ||
3718 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
3719 Op == AtomicExpr::AO__scoped_atomic_load_n ||
3720 Op == AtomicExpr::AO__scoped_atomic_store_n ||
3721 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
3722 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
3726 enum ArithOpExtraValueType {
3731 unsigned ArithAllows = AOEVT_None;
3734 case AtomicExpr::AO__c11_atomic_init:
3735 case AtomicExpr::AO__opencl_atomic_init:
3739 case AtomicExpr::AO__c11_atomic_load:
3740 case AtomicExpr::AO__opencl_atomic_load:
3741 case AtomicExpr::AO__hip_atomic_load:
3742 case AtomicExpr::AO__atomic_load_n:
3743 case AtomicExpr::AO__scoped_atomic_load_n:
3747 case AtomicExpr::AO__atomic_load:
3748 case AtomicExpr::AO__scoped_atomic_load:
3752 case AtomicExpr::AO__c11_atomic_store:
3753 case AtomicExpr::AO__opencl_atomic_store:
3754 case AtomicExpr::AO__hip_atomic_store:
3755 case AtomicExpr::AO__atomic_store:
3756 case AtomicExpr::AO__atomic_store_n:
3757 case AtomicExpr::AO__scoped_atomic_store:
3758 case AtomicExpr::AO__scoped_atomic_store_n:
3761 case AtomicExpr::AO__atomic_fetch_add:
3762 case AtomicExpr::AO__atomic_fetch_sub:
3763 case AtomicExpr::AO__atomic_add_fetch:
3764 case AtomicExpr::AO__atomic_sub_fetch:
3765 case AtomicExpr::AO__scoped_atomic_fetch_add:
3766 case AtomicExpr::AO__scoped_atomic_fetch_sub:
3767 case AtomicExpr::AO__scoped_atomic_add_fetch:
3768 case AtomicExpr::AO__scoped_atomic_sub_fetch:
3769 case AtomicExpr::AO__c11_atomic_fetch_add:
3770 case AtomicExpr::AO__c11_atomic_fetch_sub:
3771 case AtomicExpr::AO__opencl_atomic_fetch_add:
3772 case AtomicExpr::AO__opencl_atomic_fetch_sub:
3773 case AtomicExpr::AO__hip_atomic_fetch_add:
3774 case AtomicExpr::AO__hip_atomic_fetch_sub:
3775 ArithAllows = AOEVT_Pointer | AOEVT_FP;
3778 case AtomicExpr::AO__atomic_fetch_max:
3779 case AtomicExpr::AO__atomic_fetch_min:
3780 case AtomicExpr::AO__atomic_max_fetch:
3781 case AtomicExpr::AO__atomic_min_fetch:
3782 case AtomicExpr::AO__scoped_atomic_fetch_max:
3783 case AtomicExpr::AO__scoped_atomic_fetch_min:
3784 case AtomicExpr::AO__scoped_atomic_max_fetch:
3785 case AtomicExpr::AO__scoped_atomic_min_fetch:
3786 case AtomicExpr::AO__c11_atomic_fetch_max:
3787 case AtomicExpr::AO__c11_atomic_fetch_min:
3788 case AtomicExpr::AO__opencl_atomic_fetch_max:
3789 case AtomicExpr::AO__opencl_atomic_fetch_min:
3790 case AtomicExpr::AO__hip_atomic_fetch_max:
3791 case AtomicExpr::AO__hip_atomic_fetch_min:
3792 ArithAllows = AOEVT_FP;
3795 case AtomicExpr::AO__c11_atomic_fetch_and:
3796 case AtomicExpr::AO__c11_atomic_fetch_or:
3797 case AtomicExpr::AO__c11_atomic_fetch_xor:
3798 case AtomicExpr::AO__hip_atomic_fetch_and:
3799 case AtomicExpr::AO__hip_atomic_fetch_or:
3800 case AtomicExpr::AO__hip_atomic_fetch_xor:
3801 case AtomicExpr::AO__c11_atomic_fetch_nand:
3802 case AtomicExpr::AO__opencl_atomic_fetch_and:
3803 case AtomicExpr::AO__opencl_atomic_fetch_or:
3804 case AtomicExpr::AO__opencl_atomic_fetch_xor:
3805 case AtomicExpr::AO__atomic_fetch_and:
3806 case AtomicExpr::AO__atomic_fetch_or:
3807 case AtomicExpr::AO__atomic_fetch_xor:
3808 case AtomicExpr::AO__atomic_fetch_nand:
3809 case AtomicExpr::AO__atomic_and_fetch:
3810 case AtomicExpr::AO__atomic_or_fetch:
3811 case AtomicExpr::AO__atomic_xor_fetch:
3812 case AtomicExpr::AO__atomic_nand_fetch:
3813 case AtomicExpr::AO__scoped_atomic_fetch_and:
3814 case AtomicExpr::AO__scoped_atomic_fetch_or:
3815 case AtomicExpr::AO__scoped_atomic_fetch_xor:
3816 case AtomicExpr::AO__scoped_atomic_fetch_nand:
3817 case AtomicExpr::AO__scoped_atomic_and_fetch:
3818 case AtomicExpr::AO__scoped_atomic_or_fetch:
3819 case AtomicExpr::AO__scoped_atomic_xor_fetch:
3820 case AtomicExpr::AO__scoped_atomic_nand_fetch:
3824 case AtomicExpr::AO__c11_atomic_exchange:
3825 case AtomicExpr::AO__hip_atomic_exchange:
3826 case AtomicExpr::AO__opencl_atomic_exchange:
3827 case AtomicExpr::AO__atomic_exchange_n:
3828 case AtomicExpr::AO__scoped_atomic_exchange_n:
3832 case AtomicExpr::AO__atomic_exchange:
3833 case AtomicExpr::AO__scoped_atomic_exchange:
3837 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
3838 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
3839 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
3840 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
3841 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
3842 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
3846 case AtomicExpr::AO__atomic_compare_exchange:
3847 case AtomicExpr::AO__atomic_compare_exchange_n:
3848 case AtomicExpr::AO__scoped_atomic_compare_exchange:
3849 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
3854 unsigned AdjustedNumArgs = NumArgs[Form];
3855 if ((IsOpenCL || IsHIP || IsScoped) &&
3856 Op != AtomicExpr::AO__opencl_atomic_init)
3859 if (Args.size() < AdjustedNumArgs) {
3860 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
3861 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3864 }
else if (Args.size() > AdjustedNumArgs) {
3865 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
3866 diag::err_typecheck_call_too_many_args)
3867 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3873 Expr *Ptr = Args[0];
3878 Ptr = ConvertedPtr.
get();
3881 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3891 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
3897 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
3903 }
else if (Form != Load && Form != LoadCopy) {
3905 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
3913 diag::err_incomplete_type))
3916 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3922 if (Form == Arithmetic) {
3925 auto IsAllowedValueType = [&](
QualType ValType,
3926 unsigned AllowedType) ->
bool {
3930 return AllowedType & AOEVT_Pointer;
3936 &llvm::APFloat::x87DoubleExtended())
3940 if (!IsAllowedValueType(ValType, ArithAllows)) {
3941 auto DID = ArithAllows & AOEVT_FP
3942 ? (ArithAllows & AOEVT_Pointer
3943 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
3944 : diag::err_atomic_op_needs_atomic_int_or_fp)
3945 : diag::err_atomic_op_needs_atomic_int;
3952 diag::err_incomplete_type)) {
3958 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
3969 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
3985 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
3997 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg ||
4000 else if (Form == C11CmpXchg || Form == GNUCmpXchg)
4006 bool IsPassedByAddress =
false;
4007 if (!IsC11 && !IsHIP && !IsN) {
4009 IsPassedByAddress =
true;
4014 APIOrderedArgs.push_back(Args[0]);
4018 APIOrderedArgs.push_back(Args[1]);
4024 APIOrderedArgs.push_back(Args[2]);
4025 APIOrderedArgs.push_back(Args[1]);
4028 APIOrderedArgs.push_back(Args[2]);
4029 APIOrderedArgs.push_back(Args[3]);
4030 APIOrderedArgs.push_back(Args[1]);
4033 APIOrderedArgs.push_back(Args[2]);
4034 APIOrderedArgs.push_back(Args[4]);
4035 APIOrderedArgs.push_back(Args[1]);
4036 APIOrderedArgs.push_back(Args[3]);
4039 APIOrderedArgs.push_back(Args[2]);
4040 APIOrderedArgs.push_back(Args[4]);
4041 APIOrderedArgs.push_back(Args[5]);
4042 APIOrderedArgs.push_back(Args[1]);
4043 APIOrderedArgs.push_back(Args[3]);
4047 APIOrderedArgs.append(Args.begin(), Args.end());
4054 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4056 if (i < NumVals[Form] + 1) {
4069 assert(Form != Load);
4072 else if (Form ==
Init || Form == Arithmetic)
4074 else if (Form ==
Copy || Form == Xchg) {
4075 if (IsPassedByAddress) {
4082 Expr *ValArg = APIOrderedArgs[i];
4089 AS = PtrTy->getPointeeType().getAddressSpace();
4098 if (IsPassedByAddress)
4118 APIOrderedArgs[i] = Arg.
get();
4123 SubExprs.push_back(Ptr);
4127 SubExprs.push_back(APIOrderedArgs[1]);
4130 SubExprs.push_back(APIOrderedArgs[1]);
4136 SubExprs.push_back(APIOrderedArgs[2]);
4137 SubExprs.push_back(APIOrderedArgs[1]);
4141 SubExprs.push_back(APIOrderedArgs[3]);
4142 SubExprs.push_back(APIOrderedArgs[1]);
4143 SubExprs.push_back(APIOrderedArgs[2]);
4146 SubExprs.push_back(APIOrderedArgs[3]);
4147 SubExprs.push_back(APIOrderedArgs[1]);
4148 SubExprs.push_back(APIOrderedArgs[4]);
4149 SubExprs.push_back(APIOrderedArgs[2]);
4152 SubExprs.push_back(APIOrderedArgs[4]);
4153 SubExprs.push_back(APIOrderedArgs[1]);
4154 SubExprs.push_back(APIOrderedArgs[5]);
4155 SubExprs.push_back(APIOrderedArgs[2]);
4156 SubExprs.push_back(APIOrderedArgs[3]);
4161 if (SubExprs.size() >= 2 && Form !=
Init) {
4162 std::optional<llvm::APSInt>
Success =
4163 SubExprs[1]->getIntegerConstantExpr(
Context);
4165 Diag(SubExprs[1]->getBeginLoc(),
4166 diag::warn_atomic_op_has_invalid_memory_order)
4167 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4168 << SubExprs[1]->getSourceRange();
4170 if (SubExprs.size() >= 5) {
4171 if (std::optional<llvm::APSInt> Failure =
4172 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4173 if (!llvm::is_contained(
4174 {llvm::AtomicOrderingCABI::relaxed,
4175 llvm::AtomicOrderingCABI::consume,
4176 llvm::AtomicOrderingCABI::acquire,
4177 llvm::AtomicOrderingCABI::seq_cst},
4178 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4179 Diag(SubExprs[3]->getBeginLoc(),
4180 diag::warn_atomic_op_has_invalid_memory_order)
4181 << 2 << SubExprs[3]->getSourceRange();
4188 auto *
Scope = Args[Args.size() - 1];
4189 if (std::optional<llvm::APSInt>
Result =
4191 if (!ScopeModel->isValid(
Result->getZExtValue()))
4192 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope)
4193 <<
Scope->getSourceRange();
4195 SubExprs.push_back(
Scope);
4201 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4202 Op == AtomicExpr::AO__c11_atomic_store ||
4203 Op == AtomicExpr::AO__opencl_atomic_load ||
4204 Op == AtomicExpr::AO__hip_atomic_load ||
4205 Op == AtomicExpr::AO__opencl_atomic_store ||
4206 Op == AtomicExpr::AO__hip_atomic_store) &&
4209 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4210 Op == AtomicExpr::AO__opencl_atomic_load ||
4211 Op == AtomicExpr::AO__hip_atomic_load)
4216 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4232 assert(Fn &&
"builtin call without direct callee!");
4243 E->setArg(ArgIndex, Arg.
get());
4255 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4257 <<
Callee->getSourceRange();
4270 FirstArg = FirstArgResult.
get();
4271 TheCall->
setArg(0, FirstArg);
4283 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4318#define BUILTIN_ROW(x) \
4319 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4320 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4322 static const unsigned BuiltinIndices[][5] = {
4348 case 1: SizeIndex = 0;
break;
4349 case 2: SizeIndex = 1;
break;
4350 case 4: SizeIndex = 2;
break;
4351 case 8: SizeIndex = 3;
break;
4352 case 16: SizeIndex = 4;
break;
4364 unsigned BuiltinIndex, NumFixed = 1;
4365 bool WarnAboutSemanticsChange =
false;
4366 switch (BuiltinID) {
4367 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4368 case Builtin::BI__sync_fetch_and_add:
4369 case Builtin::BI__sync_fetch_and_add_1:
4370 case Builtin::BI__sync_fetch_and_add_2:
4371 case Builtin::BI__sync_fetch_and_add_4:
4372 case Builtin::BI__sync_fetch_and_add_8:
4373 case Builtin::BI__sync_fetch_and_add_16:
4377 case Builtin::BI__sync_fetch_and_sub:
4378 case Builtin::BI__sync_fetch_and_sub_1:
4379 case Builtin::BI__sync_fetch_and_sub_2:
4380 case Builtin::BI__sync_fetch_and_sub_4:
4381 case Builtin::BI__sync_fetch_and_sub_8:
4382 case Builtin::BI__sync_fetch_and_sub_16:
4386 case Builtin::BI__sync_fetch_and_or:
4387 case Builtin::BI__sync_fetch_and_or_1:
4388 case Builtin::BI__sync_fetch_and_or_2:
4389 case Builtin::BI__sync_fetch_and_or_4:
4390 case Builtin::BI__sync_fetch_and_or_8:
4391 case Builtin::BI__sync_fetch_and_or_16:
4395 case Builtin::BI__sync_fetch_and_and:
4396 case Builtin::BI__sync_fetch_and_and_1:
4397 case Builtin::BI__sync_fetch_and_and_2:
4398 case Builtin::BI__sync_fetch_and_and_4:
4399 case Builtin::BI__sync_fetch_and_and_8:
4400 case Builtin::BI__sync_fetch_and_and_16:
4404 case Builtin::BI__sync_fetch_and_xor:
4405 case Builtin::BI__sync_fetch_and_xor_1:
4406 case Builtin::BI__sync_fetch_and_xor_2:
4407 case Builtin::BI__sync_fetch_and_xor_4:
4408 case Builtin::BI__sync_fetch_and_xor_8:
4409 case Builtin::BI__sync_fetch_and_xor_16:
4413 case Builtin::BI__sync_fetch_and_nand:
4414 case Builtin::BI__sync_fetch_and_nand_1:
4415 case Builtin::BI__sync_fetch_and_nand_2:
4416 case Builtin::BI__sync_fetch_and_nand_4:
4417 case Builtin::BI__sync_fetch_and_nand_8:
4418 case Builtin::BI__sync_fetch_and_nand_16:
4420 WarnAboutSemanticsChange =
true;
4423 case Builtin::BI__sync_add_and_fetch:
4424 case Builtin::BI__sync_add_and_fetch_1:
4425 case Builtin::BI__sync_add_and_fetch_2:
4426 case Builtin::BI__sync_add_and_fetch_4:
4427 case Builtin::BI__sync_add_and_fetch_8:
4428 case Builtin::BI__sync_add_and_fetch_16:
4432 case Builtin::BI__sync_sub_and_fetch:
4433 case Builtin::BI__sync_sub_and_fetch_1:
4434 case Builtin::BI__sync_sub_and_fetch_2:
4435 case Builtin::BI__sync_sub_and_fetch_4:
4436 case Builtin::BI__sync_sub_and_fetch_8:
4437 case Builtin::BI__sync_sub_and_fetch_16:
4441 case Builtin::BI__sync_and_and_fetch:
4442 case Builtin::BI__sync_and_and_fetch_1:
4443 case Builtin::BI__sync_and_and_fetch_2:
4444 case Builtin::BI__sync_and_and_fetch_4:
4445 case Builtin::BI__sync_and_and_fetch_8:
4446 case Builtin::BI__sync_and_and_fetch_16:
4450 case Builtin::BI__sync_or_and_fetch:
4451 case Builtin::BI__sync_or_and_fetch_1:
4452 case Builtin::BI__sync_or_and_fetch_2:
4453 case Builtin::BI__sync_or_and_fetch_4:
4454 case Builtin::BI__sync_or_and_fetch_8:
4455 case Builtin::BI__sync_or_and_fetch_16:
4459 case Builtin::BI__sync_xor_and_fetch:
4460 case Builtin::BI__sync_xor_and_fetch_1:
4461 case Builtin::BI__sync_xor_and_fetch_2:
4462 case Builtin::BI__sync_xor_and_fetch_4:
4463 case Builtin::BI__sync_xor_and_fetch_8:
4464 case Builtin::BI__sync_xor_and_fetch_16:
4468 case Builtin::BI__sync_nand_and_fetch:
4469 case Builtin::BI__sync_nand_and_fetch_1:
4470 case Builtin::BI__sync_nand_and_fetch_2:
4471 case Builtin::BI__sync_nand_and_fetch_4:
4472 case Builtin::BI__sync_nand_and_fetch_8:
4473 case Builtin::BI__sync_nand_and_fetch_16:
4475 WarnAboutSemanticsChange =
true;
4478 case Builtin::BI__sync_val_compare_and_swap:
4479 case Builtin::BI__sync_val_compare_and_swap_1:
4480 case Builtin::BI__sync_val_compare_and_swap_2:
4481 case Builtin::BI__sync_val_compare_and_swap_4:
4482 case Builtin::BI__sync_val_compare_and_swap_8:
4483 case Builtin::BI__sync_val_compare_and_swap_16:
4488 case Builtin::BI__sync_bool_compare_and_swap:
4489 case Builtin::BI__sync_bool_compare_and_swap_1:
4490 case Builtin::BI__sync_bool_compare_and_swap_2:
4491 case Builtin::BI__sync_bool_compare_and_swap_4:
4492 case Builtin::BI__sync_bool_compare_and_swap_8:
4493 case Builtin::BI__sync_bool_compare_and_swap_16:
4499 case Builtin::BI__sync_lock_test_and_set:
4500 case Builtin::BI__sync_lock_test_and_set_1:
4501 case Builtin::BI__sync_lock_test_and_set_2:
4502 case Builtin::BI__sync_lock_test_and_set_4:
4503 case Builtin::BI__sync_lock_test_and_set_8:
4504 case Builtin::BI__sync_lock_test_and_set_16:
4508 case Builtin::BI__sync_lock_release:
4509 case Builtin::BI__sync_lock_release_1:
4510 case Builtin::BI__sync_lock_release_2:
4511 case Builtin::BI__sync_lock_release_4:
4512 case Builtin::BI__sync_lock_release_8:
4513 case Builtin::BI__sync_lock_release_16:
4519 case Builtin::BI__sync_swap:
4520 case Builtin::BI__sync_swap_1:
4521 case Builtin::BI__sync_swap_2:
4522 case Builtin::BI__sync_swap_4:
4523 case Builtin::BI__sync_swap_8:
4524 case Builtin::BI__sync_swap_16:
4532 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4533 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
4534 <<
Callee->getSourceRange();
4538 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
4539 <<
Callee->getSourceRange();
4541 if (WarnAboutSemanticsChange) {
4542 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
4543 <<
Callee->getSourceRange();
4548 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
4551 if (NewBuiltinID == BuiltinID)
4552 NewBuiltinDecl = FDecl;
4558 assert(Res.getFoundDecl());
4559 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
4560 if (!NewBuiltinDecl)
4567 for (
unsigned i = 0; i != NumFixed; ++i) {
4598 CK_BuiltinFnToFnPtr);
4610 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
4611 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
4615 return TheCallResult;
4624 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
4625 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
4626 "Unexpected nontemporal load/store builtin!");
4627 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
4628 unsigned numArgs = isStore ? 2 : 1;
4638 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
4644 PointerArg = PointerArgResult.
get();
4645 TheCall->
setArg(numArgs - 1, PointerArg);
4649 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
4662 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
4669 return TheCallResult;
4681 return TheCallResult;
4688 auto *
Literal = dyn_cast<StringLiteral>(Arg);
4690 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
4691 Literal = ObjcLiteral->getString();
4695 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
4713 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
4714 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
4715 TT.getArch() == llvm::Triple::aarch64_32);
4716 bool IsWindows = TT.isOSWindows();
4717 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
4718 if (IsX64 || IsAArch64) {
4725 return S.
Diag(Fn->getBeginLoc(),
4726 diag::err_ms_va_start_used_in_sysv_function);
4734 return S.
Diag(Fn->getBeginLoc(),
4735 diag::err_va_start_used_in_wrong_abi_function)
4742 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
4750 bool IsVariadic =
false;
4753 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
4754 IsVariadic =
Block->isVariadic();
4755 Params =
Block->parameters();
4756 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
4759 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
4760 IsVariadic = MD->isVariadic();
4762 Params = MD->parameters();
4763 }
else if (isa<CapturedDecl>(Caller)) {
4765 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
4769 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
4774 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
4779 *LastParam = Params.empty() ? nullptr : Params.back();
4784bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
4809 bool SecondArgIsLastNamedArgument =
false;
4811 if (std::optional<llvm::APSInt> Val =
4820 bool IsCRegister =
false;
4822 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
4823 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
4824 SecondArgIsLastNamedArgument = PV == LastParam;
4826 Type = PV->getType();
4827 ParamLoc = PV->getLocation();
4833 if (!SecondArgIsLastNamedArgument)
4835 diag::warn_second_arg_of_va_start_not_last_named_param);
4840 if (!Context.isPromotableIntegerType(Type))
4842 if (!Type->isEnumeralType())
4844 const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();
4846 Context.typesAreCompatible(ED->getPromotionType(), Type));
4848 unsigned Reason = 0;
4850 else if (IsCRegister) Reason = 2;
4851 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
4852 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
4859 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
4879 if (
Call->getNumArgs() < 3)
4881 diag::err_typecheck_call_too_few_args_at_least)
4882 << 0 << 3 <<
Call->getNumArgs()
4895 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
4898 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
4903 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
4905 << Arg1->
getType() << ConstCharPtrTy << 1
4908 << 2 << Arg1->
getType() << ConstCharPtrTy;
4913 << Arg2->
getType() << SizeTy << 1
4916 << 3 << Arg2->
getType() << SizeTy;
4921bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
4925 if (BuiltinID == Builtin::BI__builtin_isunordered &&
4953 diag::err_typecheck_call_invalid_ordered_compare)
4961bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
4962 unsigned BuiltinID) {
4967 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
4968 BuiltinID == Builtin::BI__builtin_isinf ||
4969 BuiltinID == Builtin::BI__builtin_isinf_sign))
4973 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
4974 BuiltinID == Builtin::BI__builtin_isunordered))
4978 bool IsFPClass = NumArgs == 2;
4981 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
4985 for (
unsigned i = 0; i < FPArgNo; ++i) {
5012 OrigArg = Res.
get();
5018 OrigArg = Res.
get();
5020 TheCall->
setArg(FPArgNo, OrigArg);
5034 diag::err_typecheck_call_invalid_unary_fp)
5046 if (!VectorResultTy.
isNull())
5047 ResultTy = VectorResultTy;
5056bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5061 for (
unsigned I = 0; I != 2; ++I) {
5072 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5091 diag::err_typecheck_call_different_arg_types)
5115 diag::err_typecheck_call_too_few_args_at_least)
5123 unsigned numElements = 0;
5138 unsigned numResElements = TheCall->
getNumArgs() - 2;
5147 diag::err_vec_builtin_incompatible_vector)
5154 diag::err_vec_builtin_incompatible_vector)
5159 }
else if (numElements != numResElements) {
5166 for (
unsigned i = 2; i < TheCall->
getNumArgs(); i++) {
5171 std::optional<llvm::APSInt>
Result;
5174 diag::err_shufflevector_nonconstant_argument)
5181 if (
Result->getActiveBits() > 64 ||
5182 Result->getZExtValue() >= numElements * 2)
5184 diag::err_shufflevector_argument_too_large)
5190 for (
unsigned i = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5191 exprs.push_back(TheCall->
getArg(i));
5192 TheCall->
setArg(i,
nullptr);
5210 diag::err_convertvector_non_vector)
5213 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5215 <<
"__builtin_convertvector");
5220 if (SrcElts != DstElts)
5222 diag::err_convertvector_incompatible_vector)
5227 BuiltinLoc, RParenLoc);
5230bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5235 diag::err_typecheck_call_too_many_args_at_most)
5236 << 0 << 3 << NumArgs << 0
5241 for (
unsigned i = 1; i != NumArgs; ++i)
5248bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5250 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5260 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5270bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5277 << cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5282bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5288 if (
const auto *UE =
5290 if (UE->getKind() == UETT_AlignOf ||
5291 UE->getKind() == UETT_PreferredAlignOf)
5297 if (!
Result.isPowerOf2())
5298 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5305 if (
Result > std::numeric_limits<int32_t>::max())
5313bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5324 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
5328 TheCall->
setArg(0, FirstArgResult.
get());
5340 if (!
Result.isPowerOf2())
5341 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5353 TheCall->
setArg(2, ThirdArg);
5359bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5360 unsigned BuiltinID =
5361 cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5362 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5365 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5366 if (NumArgs < NumRequiredArgs) {
5367 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5368 << 0 << NumRequiredArgs << NumArgs
5371 if (NumArgs >= NumRequiredArgs + 0x100) {
5373 diag::err_typecheck_call_too_many_args_at_most)
5374 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5385 if (Arg.isInvalid())
5387 TheCall->
setArg(i, Arg.get());
5392 unsigned FormatIdx = i;
5402 unsigned FirstDataArg = i;
5403 while (i < NumArgs) {
5421 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5423 bool Success = CheckFormatArguments(
5447 std::optional<llvm::APSInt> R;
5449 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5456 int High,
bool RangeIsError) {
5470 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
5478 PDiag(diag::warn_argument_invalid_range)
5523 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5528 if (
Value.isNegative())
5539 if ((
Value & 0xFF) != 0)
5564 Result.setIsUnsigned(
true);
5569 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
5588 Result.setIsUnsigned(
true);
5596 diag::err_argument_not_shifted_byte_or_xxff)
5600bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
5602 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
5613 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
5619bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
5621 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
5626bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
5641 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5646 diag::err_builtin_counted_by_ref_has_side_effects)
5649 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
5650 if (!ME->isFlexibleArrayMemberLike(
5653 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5659 const auto *FAMDecl = cast<FieldDecl>(ME->getMemberDecl());
5667 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5677bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *
E,
5678 BuiltinCountedByRefKind K) {
5685 case AssignmentKind:
5686 case InitializerKind:
5688 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5691 case FunctionArgKind:
5693 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5698 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5701 case ArraySubscriptKind:
5705 case BinaryExprKind:
5716class UncoveredArgHandler {
5717 enum {
Unknown = -1, AllCovered = -2 };
5719 signed FirstUncoveredArg =
Unknown;
5723 UncoveredArgHandler() =
default;
5725 bool hasUncoveredArg()
const {
5726 return (FirstUncoveredArg >= 0);
5729 unsigned getUncoveredArg()
const {
5730 assert(hasUncoveredArg() &&
"no uncovered argument");
5731 return FirstUncoveredArg;
5734 void setAllCovered() {
5737 DiagnosticExprs.clear();
5738 FirstUncoveredArg = AllCovered;
5741 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
5742 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
5745 if (FirstUncoveredArg == AllCovered)
5750 if (NewFirstUncoveredArg == FirstUncoveredArg)
5751 DiagnosticExprs.push_back(StrExpr);
5752 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
5753 DiagnosticExprs.clear();
5754 DiagnosticExprs.push_back(StrExpr);
5755 FirstUncoveredArg = NewFirstUncoveredArg;
5759 void Diagnose(
Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
5762enum StringLiteralCheckType {
5764 SLCT_UncheckedLiteral,
5772 bool AddendIsRight) {
5773 unsigned BitWidth = Offset.getBitWidth();
5774 unsigned AddendBitWidth = Addend.getBitWidth();
5776 if (Addend.isUnsigned()) {
5777 Addend = Addend.zext(++AddendBitWidth);
5778 Addend.setIsSigned(
true);
5781 if (AddendBitWidth > BitWidth) {
5782 Offset = Offset.sext(AddendBitWidth);
5783 BitWidth = AddendBitWidth;
5784 }
else if (BitWidth > AddendBitWidth) {
5785 Addend = Addend.sext(BitWidth);
5789 llvm::APSInt ResOffset = Offset;
5790 if (BinOpKind == BO_Add)
5791 ResOffset = Offset.sadd_ov(Addend, Ov);
5793 assert(AddendIsRight && BinOpKind == BO_Sub &&
5794 "operator must be add or sub with addend on the right");
5795 ResOffset = Offset.ssub_ov(Addend, Ov);
5801 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
5802 "index (intermediate) result too big");
5803 Offset = Offset.sext(2 * BitWidth);
5804 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
5816class FormatStringLiteral {
5821 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
5822 : FExpr(fexpr), Offset(Offset) {}
5824 StringRef getString()
const {
5825 return FExpr->
getString().drop_front(Offset);
5828 unsigned getByteLength()
const {
5829 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
5832 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
5839 bool isAscii()
const {
return FExpr->
isOrdinary(); }
5840 bool isWide()
const {
return FExpr->
isWide(); }
5841 bool isUTF8()
const {
return FExpr->
isUTF8(); }
5842 bool isUTF16()
const {
return FExpr->
isUTF16(); }
5843 bool isUTF32()
const {
return FExpr->
isUTF32(); }
5844 bool isPascal()
const {
return FExpr->
isPascal(); }
5849 unsigned *StartTokenByteOffset =
nullptr)
const {
5851 StartToken, StartTokenByteOffset);
5864 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
5868 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
5869 bool IgnoreStringsWithoutSpecifiers);
5878static StringLiteralCheckType
5883 llvm::SmallBitVector &CheckedVarArgs,
5884 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
5885 bool IgnoreStringsWithoutSpecifiers =
false) {
5887 return SLCT_NotALiteral;
5889 assert(Offset.isSigned() &&
"invalid offset");
5892 return SLCT_NotALiteral;
5901 return SLCT_UncheckedLiteral;
5904 case Stmt::InitListExprClass:
5908 Type, CallType,
false,
5909 CheckedVarArgs, UncoveredArg, Offset,
5910 IgnoreStringsWithoutSpecifiers);
5912 return SLCT_NotALiteral;
5913 case Stmt::BinaryConditionalOperatorClass:
5914 case Stmt::ConditionalOperatorClass: {
5918 cast<AbstractConditionalOperator>(
E);
5923 bool CheckLeft =
true, CheckRight =
true;
5926 if (
C->getCond()->EvaluateAsBooleanCondition(
5938 StringLiteralCheckType Left;
5940 Left = SLCT_UncheckedLiteral;
5943 firstDataArg,
Type, CallType, InFunctionCall,
5944 CheckedVarArgs, UncoveredArg, Offset,
5945 IgnoreStringsWithoutSpecifiers);
5946 if (Left == SLCT_NotALiteral || !CheckRight) {
5952 S,
C->getFalseExpr(), Args, APK, format_idx, firstDataArg,
Type,
5953 CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5954 IgnoreStringsWithoutSpecifiers);
5956 return (CheckLeft && Left < Right) ? Left : Right;
5959 case Stmt::ImplicitCastExprClass:
5960 E = cast<ImplicitCastExpr>(
E)->getSubExpr();
5963 case Stmt::OpaqueValueExprClass:
5964 if (
const Expr *src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
5968 return SLCT_NotALiteral;
5970 case Stmt::PredefinedExprClass:
5974 return SLCT_UncheckedLiteral;
5976 case Stmt::DeclRefExprClass: {
5982 bool isConstant =
false;
5986 isConstant = AT->getElementType().isConstant(S.
Context);
5988 isConstant =
T.isConstant(S.
Context) &&
5993 isConstant =
T.isConstant(S.
Context);
5997 if (
const Expr *
Init = VD->getAnyInitializer()) {
6000 if (InitList->isStringLiteralInit())
6001 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6004 S,
Init, Args, APK, format_idx, firstDataArg,
Type, CallType,
6005 false, CheckedVarArgs, UncoveredArg, Offset);
6046 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6047 if (
const auto *
D = dyn_cast<Decl>(PV->getDeclContext())) {
6049 bool IsCXXMember =
false;
6050 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D))
6051 IsCXXMember = MD->isInstance();
6053 bool IsVariadic =
false;
6055 IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();
6056 else if (
const auto *BD = dyn_cast<BlockDecl>(
D))
6057 IsVariadic = BD->isVariadic();
6058 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D))
6059 IsVariadic = OMD->isVariadic();
6066 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx &&
6079 return SLCT_UncheckedLiteral;
6088 return SLCT_NotALiteral;
6091 case Stmt::CallExprClass:
6092 case Stmt::CXXMemberCallExprClass: {
6095 bool IsFirst =
true;
6096 StringLiteralCheckType CommonResult;
6097 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6098 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6100 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6101 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6102 IgnoreStringsWithoutSpecifiers);
6109 return CommonResult;
6111 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6113 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6114 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6117 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6118 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6119 IgnoreStringsWithoutSpecifiers);
6125 Type, CallType,
false,
6126 CheckedVarArgs, UncoveredArg, Offset,
6127 IgnoreStringsWithoutSpecifiers);
6128 return SLCT_NotALiteral;
6130 case Stmt::ObjCMessageExprClass: {
6131 const auto *ME = cast<ObjCMessageExpr>(
E);
6132 if (
const auto *MD = ME->getMethodDecl()) {
6133 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6142 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6144 MD->getSelector().isKeywordSelector(
6145 {
"localizedStringForKey",
"value",
"table"})) {
6146 IgnoreStringsWithoutSpecifiers =
true;
6149 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6151 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6152 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6153 IgnoreStringsWithoutSpecifiers);
6157 return SLCT_NotALiteral;
6159 case Stmt::ObjCStringLiteralClass:
6160 case Stmt::StringLiteralClass: {
6166 StrE = cast<StringLiteral>(
E);
6169 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6172 return SLCT_NotALiteral;
6174 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6176 InFunctionCall, CallType, CheckedVarArgs, UncoveredArg,
6177 IgnoreStringsWithoutSpecifiers);
6178 return SLCT_CheckedLiteral;
6181 return SLCT_NotALiteral;
6183 case Stmt::BinaryOperatorClass: {
6197 if (LIsInt != RIsInt) {
6201 if (BinOpKind == BO_Add) {
6214 return SLCT_NotALiteral;
6216 case Stmt::UnaryOperatorClass: {
6218 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6219 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6221 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6231 return SLCT_NotALiteral;
6235 return SLCT_NotALiteral;
6246 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6247 if (isa_and_nonnull<StringLiteral>(LVE))
6254 return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
6256 .Cases(
"printf",
"printf0",
"syslog",
FST_Printf)
6260 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
FST_Kprintf)
6267bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6271 llvm::SmallBitVector &CheckedVarArgs) {
6272 FormatStringInfo FSI;
6275 return CheckFormatArguments(Args, FSI.ArgPassingKind, FSI.FormatIdx,
6277 CallType,
Loc,
Range, CheckedVarArgs);
6283 unsigned format_idx,
unsigned firstDataArg,
6284 FormatStringType
Type,
6287 llvm::SmallBitVector &CheckedVarArgs) {
6289 if (format_idx >= Args.size()) {
6294 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6308 UncoveredArgHandler UncoveredArg;
6310 *
this, OrigFormatExpr, Args, APK, format_idx, firstDataArg,
Type,
6312 true, CheckedVarArgs, UncoveredArg,
6313 llvm::APSInt(64,
false) = 0);
6316 if (UncoveredArg.hasUncoveredArg()) {
6317 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6318 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6319 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6322 if (CT != SLCT_NotALiteral)
6324 return CT == SLCT_CheckedLiteral;
6341 if (Args.size() == firstDataArg) {
6342 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6351 Diag(FormatLoc, diag::note_format_security_fixit)
6355 Diag(FormatLoc, diag::note_format_security_fixit)
6360 Diag(FormatLoc, diag::warn_format_nonliteral)
6371 const FormatStringLiteral *FExpr;
6372 const Expr *OrigFormatExpr;
6374 const unsigned FirstDataArg;
6375 const unsigned NumDataArgs;
6380 llvm::SmallBitVector CoveredArgs;
6381 bool usesPositionalArgs =
false;
6382 bool atFirstArg =
true;
6383 bool inFunctionCall;
6385 llvm::SmallBitVector &CheckedVarArgs;
6386 UncoveredArgHandler &UncoveredArg;
6389 CheckFormatHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6390 const Expr *origFormatExpr,
6392 unsigned numDataArgs,
const char *beg,
6396 llvm::SmallBitVector &CheckedVarArgs,
6397 UncoveredArgHandler &UncoveredArg)
6398 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6399 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6400 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6401 inFunctionCall(inFunctionCall), CallType(callType),
6402 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6403 CoveredArgs.resize(numDataArgs);
6404 CoveredArgs.reset();
6407 void DoneProcessing();
6409 void HandleIncompleteSpecifier(
const char *startSpecifier,
6410 unsigned specifierLen)
override;
6412 void HandleInvalidLengthModifier(
6415 const char *startSpecifier,
unsigned specifierLen,
6418 void HandleNonStandardLengthModifier(
6420 const char *startSpecifier,
unsigned specifierLen);
6422 void HandleNonStandardConversionSpecifier(
6424 const char *startSpecifier,
unsigned specifierLen);
6426 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
6428 void HandleInvalidPosition(
const char *startSpecifier,
6429 unsigned specifierLen,
6432 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
6434 void HandleNullChar(
const char *nullCharacter)
override;
6436 template <
typename Range>
6438 EmitFormatDiagnostic(
Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
6440 bool IsStringLocation,
Range StringRange,
6445 const char *startSpec,
6446 unsigned specifierLen,
6447 const char *csStart,
unsigned csLen);
6450 const char *startSpec,
6451 unsigned specifierLen);
6455 unsigned specifierLen);
6458 const Expr *getDataArg(
unsigned i)
const;
6462 const char *startSpecifier,
unsigned specifierLen,
6465 template <
typename Range>
6467 bool IsStringLocation,
Range StringRange,
6473SourceRange CheckFormatHandler::getFormatStringRange() {
6478getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
6480 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
6483 End = End.getLocWithOffset(1);
6488SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
6493void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
6494 unsigned specifierLen){
6495 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
6496 getLocationOfByte(startSpecifier),
6498 getSpecifierRange(startSpecifier, specifierLen));
6501void CheckFormatHandler::HandleInvalidLengthModifier(
6504 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
6505 using namespace analyze_format_string;
6507 const LengthModifier &LM = FS.getLengthModifier();
6508 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6511 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6513 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6514 getLocationOfByte(LM.getStart()),
6516 getSpecifierRange(startSpecifier, specifierLen));
6518 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6519 << FixedLM->toString()
6524 if (DiagID == diag::warn_format_nonsensical_length)
6527 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6528 getLocationOfByte(LM.getStart()),
6530 getSpecifierRange(startSpecifier, specifierLen),
6535void CheckFormatHandler::HandleNonStandardLengthModifier(
6537 const char *startSpecifier,
unsigned specifierLen) {
6538 using namespace analyze_format_string;
6540 const LengthModifier &LM = FS.getLengthModifier();
6541 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6544 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6546 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6547 << LM.toString() << 0,
6548 getLocationOfByte(LM.getStart()),
6550 getSpecifierRange(startSpecifier, specifierLen));
6552 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6553 << FixedLM->toString()
6557 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6558 << LM.toString() << 0,
6559 getLocationOfByte(LM.getStart()),
6561 getSpecifierRange(startSpecifier, specifierLen));
6565void CheckFormatHandler::HandleNonStandardConversionSpecifier(
6567 const char *startSpecifier,
unsigned specifierLen) {
6568 using namespace analyze_format_string;
6573 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6577 getSpecifierRange(startSpecifier, specifierLen));
6580 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
6581 << FixedCS->toString()
6584 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6588 getSpecifierRange(startSpecifier, specifierLen));
6592void CheckFormatHandler::HandlePosition(
const char *startPos,
6595 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
6596 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
6597 getLocationOfByte(startPos),
6599 getSpecifierRange(startPos, posLen));
6602void CheckFormatHandler::HandleInvalidPosition(
6603 const char *startSpecifier,
unsigned specifierLen,
6606 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
6607 EmitFormatDiagnostic(
6608 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
6609 getLocationOfByte(startSpecifier),
true,
6610 getSpecifierRange(startSpecifier, specifierLen));
6613void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
6617 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
6618 getLocationOfByte(startPos),
6620 getSpecifierRange(startPos, posLen));
6623void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
6624 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {
6626 EmitFormatDiagnostic(
6627 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
6628 getLocationOfByte(nullCharacter),
true,
6629 getFormatStringRange());
6635const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
6636 return Args[FirstDataArg + i];
6639void CheckFormatHandler::DoneProcessing() {
6645 signed notCoveredArg = CoveredArgs.find_first();
6646 if (notCoveredArg >= 0) {
6647 assert((
unsigned)notCoveredArg < NumDataArgs);
6648 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
6650 UncoveredArg.setAllCovered();
6655void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
6656 const Expr *ArgExpr) {
6657 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
6669 for (
auto E : DiagnosticExprs)
6672 CheckFormatHandler::EmitFormatDiagnostic(
6673 S, IsFunctionCall, DiagnosticExprs[0],
6679CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
6681 const char *startSpec,
6682 unsigned specifierLen,
6683 const char *csStart,
6685 bool keepGoing =
true;
6686 if (argIndex < NumDataArgs) {
6689 CoveredArgs.set(argIndex);
6705 std::string CodePointStr;
6706 if (!llvm::sys::locale::isPrint(*csStart)) {
6707 llvm::UTF32 CodePoint;
6708 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
6709 const llvm::UTF8 *
E =
6710 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
6711 llvm::ConversionResult
Result =
6712 llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
6714 if (
Result != llvm::conversionOK) {
6715 unsigned char FirstChar = *csStart;
6716 CodePoint = (llvm::UTF32)FirstChar;
6719 llvm::raw_string_ostream OS(CodePointStr);
6720 if (CodePoint < 256)
6721 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
6722 else if (CodePoint <= 0xFFFF)
6723 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
6725 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
6729 EmitFormatDiagnostic(
6730 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier,
Loc,
6731 true, getSpecifierRange(startSpec, specifierLen));
6738 const char *startSpec,
6739 unsigned specifierLen) {
6740 EmitFormatDiagnostic(
6741 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
6742 Loc,
true, getSpecifierRange(startSpec, specifierLen));
6746CheckFormatHandler::CheckNumArgs(
6749 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
6751 if (argIndex >= NumDataArgs) {
6753 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
6754 << (argIndex+1) << NumDataArgs)
6755 : S.
PDiag(diag::warn_printf_insufficient_data_args);
6756 EmitFormatDiagnostic(
6757 PDiag, getLocationOfByte(CS.
getStart()),
true,
6758 getSpecifierRange(startSpecifier, specifierLen));
6762 UncoveredArg.setAllCovered();
6768template<
typename Range>
6771 bool IsStringLocation,
6774 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
6775 Loc, IsStringLocation, StringRange, FixIt);
6805template <
typename Range>
6806void CheckFormatHandler::EmitFormatDiagnostic(
6807 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
6810 if (InFunctionCall) {
6819 S.
Diag(IsStringLocation ?
Loc : StringRange.getBegin(),
6820 diag::note_format_string_defined);
6822 Note << StringRange;
6831class CheckPrintfHandler :
public CheckFormatHandler {
6833 CheckPrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6834 const Expr *origFormatExpr,
6836 unsigned numDataArgs,
bool isObjC,
const char *beg,
6840 llvm::SmallBitVector &CheckedVarArgs,
6841 UncoveredArgHandler &UncoveredArg)
6842 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
6843 numDataArgs, beg, APK, Args, formatIdx,
6844 inFunctionCall, CallType, CheckedVarArgs,
6850 bool allowsObjCArg()
const {
6855 bool HandleInvalidPrintfConversionSpecifier(
6857 const char *startSpecifier,
6858 unsigned specifierLen)
override;
6860 void handleInvalidMaskType(StringRef MaskType)
override;
6863 const char *startSpecifier,
unsigned specifierLen,
6866 const char *StartSpecifier,
6867 unsigned SpecifierLen,
6871 const char *startSpecifier,
unsigned specifierLen);
6875 const char *startSpecifier,
unsigned specifierLen);
6878 const char *startSpecifier,
unsigned specifierLen);
6882 const char *startSpecifier,
unsigned specifierLen);
6886 void HandleEmptyObjCModifierFlag(
const char *startFlag,
6887 unsigned flagLen)
override;
6889 void HandleInvalidObjCModifierFlag(
const char *startFlag,
6890 unsigned flagLen)
override;
6892 void HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
6893 const char *flagsEnd,
6894 const char *conversionPosition)
6900bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
6902 const char *startSpecifier,
6903 unsigned specifierLen) {
6905 FS.getConversionSpecifier();
6907 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
6909 startSpecifier, specifierLen,
6913void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
6914 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
6917bool CheckPrintfHandler::HandleAmount(
6919 const char *startSpecifier,
unsigned specifierLen) {
6923 if (argIndex >= NumDataArgs) {
6924 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
6928 getSpecifierRange(startSpecifier, specifierLen));
6938 CoveredArgs.set(argIndex);
6939 const Expr *Arg = getDataArg(argIndex);
6949 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
6954 getSpecifierRange(startSpecifier, specifierLen));
6964void CheckPrintfHandler::HandleInvalidAmount(
6968 const char *startSpecifier,
6969 unsigned specifierLen) {
6971 FS.getConversionSpecifier();
6979 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
6983 getSpecifierRange(startSpecifier, specifierLen),
6989 const char *startSpecifier,
6990 unsigned specifierLen) {
6993 FS.getConversionSpecifier();
6994 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
6998 getSpecifierRange(startSpecifier, specifierLen),
7003void CheckPrintfHandler::HandleIgnoredFlag(
7007 const char *startSpecifier,
7008 unsigned specifierLen) {
7010 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7014 getSpecifierRange(startSpecifier, specifierLen),
7016 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7019void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7022 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7023 getLocationOfByte(startFlag),
7025 getSpecifierRange(startFlag, flagLen));
7028void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7031 auto Range = getSpecifierRange(startFlag, flagLen);
7032 StringRef flag(startFlag, flagLen);
7033 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7034 getLocationOfByte(startFlag),
7039void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7040 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7042 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7043 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7044 EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
7045 getLocationOfByte(conversionPosition),
7053template<
typename MemberKind>
7074 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
7088 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
7089 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7091 if ((*MI)->getMinRequiredArguments() == 0)
7099bool CheckPrintfHandler::checkForCStrMembers(
7104 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
7106 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7122bool CheckPrintfHandler::HandlePrintfSpecifier(
7125 using namespace analyze_format_string;
7126 using namespace analyze_printf;
7128 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
7130 if (FS.consumesDataArgument()) {
7133 usesPositionalArgs = FS.usesPositionalArg();
7135 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7136 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7137 startSpecifier, specifierLen);
7144 if (!HandleAmount(FS.getFieldWidth(), 0,
7145 startSpecifier, specifierLen)) {
7149 if (!HandleAmount(FS.getPrecision(), 1,
7150 startSpecifier, specifierLen)) {
7154 if (!CS.consumesDataArgument()) {
7161 unsigned argIndex = FS.getArgIndex();
7162 if (argIndex < NumDataArgs) {
7166 CoveredArgs.set(argIndex);
7170 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
7171 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
7173 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
7177 CoveredArgs.set(argIndex + 1);
7180 const Expr *Ex = getDataArg(argIndex);
7182 (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
7185 EmitFormatDiagnostic(
7186 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7190 getSpecifierRange(startSpecifier, specifierLen));
7193 Ex = getDataArg(argIndex + 1);
7196 EmitFormatDiagnostic(
7197 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7201 getSpecifierRange(startSpecifier, specifierLen));
7208 if (!allowsObjCArg() && CS.isObjCArg()) {
7209 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7214 if (FSType !=
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::PArg) {
7215 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7220 if (FSType ==
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::nArg) {
7221 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
7222 getLocationOfByte(CS.getStart()),
7224 getSpecifierRange(startSpecifier, specifierLen));
7231 (CS.getKind() == ConversionSpecifier::PArg ||
7232 CS.getKind() == ConversionSpecifier::sArg ||
7233 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
7234 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7240 if (FS.isPublic().isSet()) {
7241 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7243 getLocationOfByte(FS.isPublic().getPosition()),
7245 getSpecifierRange(startSpecifier, specifierLen));
7247 if (FS.isPrivate().isSet()) {
7248 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7250 getLocationOfByte(FS.isPrivate().getPosition()),
7252 getSpecifierRange(startSpecifier, specifierLen));
7256 const llvm::Triple &Triple =
Target.getTriple();
7257 if (CS.getKind() == ConversionSpecifier::nArg &&
7258 (Triple.isAndroid() || Triple.isOSFuchsia())) {
7259 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
7260 getLocationOfByte(CS.getStart()),
7262 getSpecifierRange(startSpecifier, specifierLen));
7266 if (!FS.hasValidFieldWidth()) {
7267 HandleInvalidAmount(FS, FS.getFieldWidth(), 0,
7268 startSpecifier, specifierLen);
7272 if (!FS.hasValidPrecision()) {
7273 HandleInvalidAmount(FS, FS.getPrecision(), 1,
7274 startSpecifier, specifierLen);
7278 if (CS.getKind() == ConversionSpecifier::PArg &&
7279 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
7280 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
7281 getLocationOfByte(startSpecifier),
7283 getSpecifierRange(startSpecifier, specifierLen));
7287 if (!FS.hasValidThousandsGroupingPrefix())
7288 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
7289 if (!FS.hasValidLeadingZeros())
7290 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
7291 if (!FS.hasValidPlusPrefix())
7292 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
7293 if (!FS.hasValidSpacePrefix())
7294 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
7295 if (!FS.hasValidAlternativeForm())
7296 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
7297 if (!FS.hasValidLeftJustified())
7298 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
7301 if (FS.hasSpacePrefix() && FS.hasPlusPrefix())
7302 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
7303 startSpecifier, specifierLen);
7304 if (FS.hasLeadingZeros() && FS.isLeftJustified())
7305 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
7306 startSpecifier, specifierLen);
7311 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7312 diag::warn_format_nonsensical_length);
7313 else if (!FS.hasStandardLengthModifier())
7314 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7315 else if (!FS.hasStandardLengthConversionCombination())
7316 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7317 diag::warn_format_non_standard_conversion_spec);
7319 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7320 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7326 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7329 const Expr *Arg = getDataArg(argIndex);
7333 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
7345 case Stmt::ArraySubscriptExprClass:
7346 case Stmt::CallExprClass:
7347 case Stmt::CharacterLiteralClass:
7348 case Stmt::CXXBoolLiteralExprClass:
7349 case Stmt::DeclRefExprClass:
7350 case Stmt::FloatingLiteralClass:
7351 case Stmt::IntegerLiteralClass:
7352 case Stmt::MemberExprClass:
7353 case Stmt::ObjCArrayLiteralClass:
7354 case Stmt::ObjCBoolLiteralExprClass:
7355 case Stmt::ObjCBoxedExprClass:
7356 case Stmt::ObjCDictionaryLiteralClass:
7357 case Stmt::ObjCEncodeExprClass:
7358 case Stmt::ObjCIvarRefExprClass:
7359 case Stmt::ObjCMessageExprClass:
7360 case Stmt::ObjCPropertyRefExprClass:
7361 case Stmt::ObjCStringLiteralClass:
7362 case Stmt::ObjCSubscriptRefExprClass:
7363 case Stmt::ParenExprClass:
7364 case Stmt::StringLiteralClass:
7365 case Stmt::UnaryOperatorClass:
7372static std::pair<QualType, StringRef>
7379 StringRef Name = UserTy->getDecl()->getName();
7380 QualType CastTy = llvm::StringSwitch<QualType>(Name)
7384 .Case(
"SInt32", Context.
IntTy)
7389 return std::make_pair(CastTy, Name);
7391 TyTy = UserTy->desugar();
7395 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(
E))
7397 PE->getSubExpr()->getType(),
7406 StringRef TrueName, FalseName;
7408 std::tie(TrueTy, TrueName) =
7410 CO->getTrueExpr()->getType(),
7412 std::tie(FalseTy, FalseName) =
7414 CO->getFalseExpr()->getType(),
7415 CO->getFalseExpr());
7417 if (TrueTy == FalseTy)
7418 return std::make_pair(TrueTy, TrueName);
7419 else if (TrueTy.
isNull())
7420 return std::make_pair(FalseTy, FalseName);
7421 else if (FalseTy.
isNull())
7422 return std::make_pair(TrueTy, TrueName);
7425 return std::make_pair(
QualType(), StringRef());
7444 From = VecTy->getElementType();
7446 To = VecTy->getElementType();
7458 diag::warn_format_conversion_argument_type_mismatch_signedness,
Loc)
7467 const char *StartSpecifier,
7468 unsigned SpecifierLen,
7470 using namespace analyze_format_string;
7471 using namespace analyze_printf;
7480 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
7481 ExprTy = TET->getUnderlyingExpr()->getType();
7493 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
7496 getSpecifierRange(StartSpecifier, SpecifierLen);
7498 llvm::raw_svector_ostream os(FSString);
7500 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
7508 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
7511 getSpecifierRange(StartSpecifier, SpecifierLen);
7512 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
7517 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
7519 ArgType::MatchKind OrigMatch = Match;
7522 if (Match == ArgType::Match)
7526 assert(Match != ArgType::NoMatchPromotionTypeConfusion);
7535 E = ICE->getSubExpr();
7545 if (OrigMatch == ArgType::NoMatchSignedness &&
7546 ImplicitMatch != ArgType::NoMatchSignedness)
7553 if (ImplicitMatch == ArgType::Match)
7564 FS.getLengthModifier().getKind() != LengthModifier::AsChar)
7571 if (Match == ArgType::MatchPromotion)
7572 Match = ArgType::NoMatch;
7575 if (Match == ArgType::MatchPromotion) {
7579 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
7580 ImplicitMatch != ArgType::NoMatchTypeConfusion)
7582 Match = ArgType::NoMatch;
7584 if (ImplicitMatch == ArgType::NoMatchPedantic ||
7585 ImplicitMatch == ArgType::NoMatchTypeConfusion)
7586 Match = ImplicitMatch;
7587 assert(Match != ArgType::MatchPromotion);
7590 bool IsEnum =
false;
7591 bool IsScopedEnum =
false;
7594 IntendedTy = EnumTy->getDecl()->getIntegerType();
7595 if (EnumTy->isUnscopedEnumerationType()) {
7596 ExprTy = IntendedTy;
7601 IsScopedEnum =
true;
7608 if (isObjCContext() &&
7609 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
7619 const llvm::APInt &
V = IL->getValue();
7629 if (TD->getUnderlyingType() == IntendedTy)
7637 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
7645 if (!IsScopedEnum &&
7646 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
7649 Match = ArgType::NoMatchPedantic;
7650 IntendedTy = CastTy;
7651 ShouldNotPrintDirectly =
true;
7656 PrintfSpecifier fixedFS = FS;
7663 llvm::raw_svector_ostream os(buf);
7664 fixedFS.toString(os);
7666 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
7668 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
7671 case ArgType::Match:
7672 case ArgType::MatchPromotion:
7673 case ArgType::NoMatchPromotionTypeConfusion:
7674 case ArgType::NoMatchSignedness:
7675 llvm_unreachable(
"expected non-matching");
7676 case ArgType::NoMatchPedantic:
7677 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7679 case ArgType::NoMatchTypeConfusion:
7680 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7682 case ArgType::NoMatch:
7683 Diag = diag::warn_format_conversion_argument_type_mismatch;
7704 llvm::raw_svector_ostream CastFix(CastBuf);
7705 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
7707 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
7713 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
7718 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
7740 if (ShouldNotPrintDirectly && !IsScopedEnum) {
7746 Name = TypedefTy->getDecl()->getName();
7749 unsigned Diag = Match == ArgType::NoMatchPedantic
7750 ? diag::warn_format_argument_needs_cast_pedantic
7751 : diag::warn_format_argument_needs_cast;
7752 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
7763 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
7764 : diag::warn_format_conversion_argument_type_mismatch;
7766 EmitFormatDiagnostic(
7778 bool EmitTypeMismatch =
false;
7784 case ArgType::Match:
7785 case ArgType::MatchPromotion:
7786 case ArgType::NoMatchPromotionTypeConfusion:
7787 case ArgType::NoMatchSignedness:
7788 llvm_unreachable(
"expected non-matching");
7789 case ArgType::NoMatchPedantic:
7790 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7792 case ArgType::NoMatchTypeConfusion:
7793 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7795 case ArgType::NoMatch:
7796 Diag = diag::warn_format_conversion_argument_type_mismatch;
7800 EmitFormatDiagnostic(
7809 EmitTypeMismatch =
true;
7811 EmitFormatDiagnostic(
7812 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
7813 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7817 checkForCStrMembers(AT,
E);
7823 EmitTypeMismatch =
true;
7825 EmitFormatDiagnostic(
7826 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
7827 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7835 << isa<InitListExpr>(
E) << ExprTy << CallType
7840 if (EmitTypeMismatch) {
7846 EmitFormatDiagnostic(
7847 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7853 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
7854 "format string specifier index out of range");
7855 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
7865class CheckScanfHandler :
public CheckFormatHandler {
7867 CheckScanfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7869 unsigned firstDataArg,
unsigned numDataArgs,
7873 llvm::SmallBitVector &CheckedVarArgs,
7874 UncoveredArgHandler &UncoveredArg)
7875 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7876 numDataArgs, beg, APK, Args, formatIdx,
7877 inFunctionCall, CallType, CheckedVarArgs,
7881 const char *startSpecifier,
7882 unsigned specifierLen)
override;
7884 bool HandleInvalidScanfConversionSpecifier(
7886 const char *startSpecifier,
7887 unsigned specifierLen)
override;
7889 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
7894void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
7896 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
7897 getLocationOfByte(end),
true,
7898 getSpecifierRange(start, end - start));
7901bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
7903 const char *startSpecifier,
7904 unsigned specifierLen) {
7906 FS.getConversionSpecifier();
7908 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
7910 startSpecifier, specifierLen,
7914bool CheckScanfHandler::HandleScanfSpecifier(
7916 const char *startSpecifier,
7917 unsigned specifierLen) {
7918 using namespace analyze_scanf;
7919 using namespace analyze_format_string;
7921 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
7925 if (FS.consumesDataArgument()) {
7928 usesPositionalArgs = FS.usesPositionalArg();
7930 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7931 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7932 startSpecifier, specifierLen);
7938 const OptionalAmount &Amt = FS.getFieldWidth();
7939 if (Amt.getHowSpecified() == OptionalAmount::Constant) {
7940 if (Amt.getConstantAmount() == 0) {
7942 Amt.getConstantLength());
7943 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
7944 getLocationOfByte(Amt.getStart()),
7950 if (!FS.consumesDataArgument()) {
7957 unsigned argIndex = FS.getArgIndex();
7958 if (argIndex < NumDataArgs) {
7962 CoveredArgs.set(argIndex);
7968 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7969 diag::warn_format_nonsensical_length);
7970 else if (!FS.hasStandardLengthModifier())
7971 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7972 else if (!FS.hasStandardLengthConversionCombination())
7973 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7974 diag::warn_format_non_standard_conversion_spec);
7976 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7977 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7983 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7987 const Expr *Ex = getDataArg(argIndex);
8004 ScanfSpecifier fixedFS = FS;
8009 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8010 : diag::warn_format_conversion_argument_type_mismatch;
8015 llvm::raw_svector_ostream os(buf);
8016 fixedFS.toString(os);
8018 EmitFormatDiagnostic(
8023 getSpecifierRange(startSpecifier, specifierLen),
8025 getSpecifierRange(startSpecifier, specifierLen), os.str()));
8032 getSpecifierRange(startSpecifier, specifierLen));
8039 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
8043 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
8044 bool IgnoreStringsWithoutSpecifiers) {
8046 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
8047 CheckFormatHandler::EmitFormatDiagnostic(
8048 S, inFunctionCall, Args[format_idx],
8049 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
8055 StringRef StrRef = FExpr->getString();
8056 const char *Str = StrRef.data();
8060 assert(
T &&
"String literal not of constant array type!");
8061 size_t TypeSize =
T->getZExtSize();
8062 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8063 const unsigned numDataArgs = Args.size() - firstDataArg;
8065 if (IgnoreStringsWithoutSpecifiers &&
8072 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
8073 CheckFormatHandler::EmitFormatDiagnostic(
8074 S, inFunctionCall, Args[format_idx],
8075 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
8076 FExpr->getBeginLoc(),
8082 if (StrLen == 0 && numDataArgs > 0) {
8083 CheckFormatHandler::EmitFormatDiagnostic(
8084 S, inFunctionCall, Args[format_idx],
8085 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
8094 CheckPrintfHandler H(
8095 S, FExpr, OrigFormatExpr,
Type, firstDataArg, numDataArgs,
8097 Args, format_idx, inFunctionCall, CallType, CheckedVarArgs,
8105 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
8106 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
8107 CallType, CheckedVarArgs, UncoveredArg);
8118 const char *Str = StrRef.data();
8121 assert(
T &&
"String literal not of constant array type!");
8122 size_t TypeSize =
T->getZExtSize();
8123 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8134 switch (AbsFunction) {
8138 case Builtin::BI__builtin_abs:
8139 return Builtin::BI__builtin_labs;
8140 case Builtin::BI__builtin_labs:
8141 return Builtin::BI__builtin_llabs;
8142 case Builtin::BI__builtin_llabs:
8145 case Builtin::BI__builtin_fabsf:
8146 return Builtin::BI__builtin_fabs;
8147 case Builtin::BI__builtin_fabs:
8148 return Builtin::BI__builtin_fabsl;
8149 case Builtin::BI__builtin_fabsl:
8152 case Builtin::BI__builtin_cabsf:
8153 return Builtin::BI__builtin_cabs;
8154 case Builtin::BI__builtin_cabs:
8155 return Builtin::BI__builtin_cabsl;
8156 case Builtin::BI__builtin_cabsl:
8159 case Builtin::BIabs:
8160 return Builtin::BIlabs;
8161 case Builtin::BIlabs:
8162 return Builtin::BIllabs;
8163 case Builtin::BIllabs:
8166 case Builtin::BIfabsf:
8167 return Builtin::BIfabs;
8168 case Builtin::BIfabs:
8169 return Builtin::BIfabsl;
8170 case Builtin::BIfabsl:
8173 case Builtin::BIcabsf:
8174 return Builtin::BIcabs;
8175 case Builtin::BIcabs:
8176 return Builtin::BIcabsl;
8177 case Builtin::BIcabsl:
8206 unsigned AbsFunctionKind) {
8207 unsigned BestKind = 0;
8209 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
8215 else if (Context.
hasSameType(ParamType, ArgType)) {
8238 llvm_unreachable(
"Type not integer, floating, or complex");
8245 switch (ValueKind) {
8250 case Builtin::BI__builtin_fabsf:
8251 case Builtin::BI__builtin_fabs:
8252 case Builtin::BI__builtin_fabsl:
8253 case Builtin::BI__builtin_cabsf:
8254 case Builtin::BI__builtin_cabs:
8255 case Builtin::BI__builtin_cabsl:
8256 return Builtin::BI__builtin_abs;
8257 case Builtin::BIfabsf:
8258 case Builtin::BIfabs:
8259 case Builtin::BIfabsl:
8260 case Builtin::BIcabsf:
8261 case Builtin::BIcabs:
8262 case Builtin::BIcabsl:
8263 return Builtin::BIabs;
8269 case Builtin::BI__builtin_abs:
8270 case Builtin::BI__builtin_labs:
8271 case Builtin::BI__builtin_llabs:
8272 case Builtin::BI__builtin_cabsf:
8273 case Builtin::BI__builtin_cabs:
8274 case Builtin::BI__builtin_cabsl:
8275 return Builtin::BI__builtin_fabsf;
8276 case Builtin::BIabs:
8277 case Builtin::BIlabs:
8278 case Builtin::BIllabs:
8279 case Builtin::BIcabsf:
8280 case Builtin::BIcabs:
8281 case Builtin::BIcabsl:
8282 return Builtin::BIfabsf;
8288 case Builtin::BI__builtin_abs:
8289 case Builtin::BI__builtin_labs:
8290 case Builtin::BI__builtin_llabs:
8291 case Builtin::BI__builtin_fabsf:
8292 case Builtin::BI__builtin_fabs:
8293 case Builtin::BI__builtin_fabsl:
8294 return Builtin::BI__builtin_cabsf;
8295 case Builtin::BIabs:
8296 case Builtin::BIlabs:
8297 case Builtin::BIllabs:
8298 case Builtin::BIfabsf:
8299 case Builtin::BIfabs:
8300 case Builtin::BIfabsl:
8301 return Builtin::BIcabsf;
8304 llvm_unreachable(
"Unable to convert function");
8315 case Builtin::BI__builtin_abs:
8316 case Builtin::BI__builtin_fabs:
8317 case Builtin::BI__builtin_fabsf:
8318 case Builtin::BI__builtin_fabsl:
8319 case Builtin::BI__builtin_labs:
8320 case Builtin::BI__builtin_llabs:
8321 case Builtin::BI__builtin_cabs:
8322 case Builtin::BI__builtin_cabsf:
8323 case Builtin::BI__builtin_cabsl:
8324 case Builtin::BIabs:
8325 case Builtin::BIlabs:
8326 case Builtin::BIllabs:
8327 case Builtin::BIfabs:
8328 case Builtin::BIfabsf:
8329 case Builtin::BIfabsl:
8330 case Builtin::BIcabs:
8331 case Builtin::BIcabsf:
8332 case Builtin::BIcabsl:
8335 llvm_unreachable(
"Unknown Builtin type");
8341 unsigned AbsKind,
QualType ArgType) {
8342 bool EmitHeaderHint =
true;
8343 const char *HeaderName =
nullptr;
8344 StringRef FunctionName;
8346 FunctionName =
"std::abs";
8348 HeaderName =
"cstdlib";
8350 HeaderName =
"cmath";
8352 llvm_unreachable(
"Invalid Type");
8361 for (
const auto *I : R) {
8364 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
8366 FDecl = dyn_cast<FunctionDecl>(I);
8381 EmitHeaderHint =
false;
8399 EmitHeaderHint =
false;
8403 }
else if (!R.
empty()) {
8409 S.
Diag(
Loc, diag::note_replace_abs_function)
8415 if (!EmitHeaderHint)
8418 S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
8422template <std::
size_t StrLen>
8424 const char (&Str)[StrLen]) {
8437 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
8438 return std::any_of(names.begin(), names.end(), [&](llvm::StringRef name) {
8439 return calleeName == name;
8444 case MathCheck::NaN:
8445 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
8446 "__builtin_nanf16",
"__builtin_nanf128"});
8447 case MathCheck::Inf:
8448 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
8449 "__builtin_inff16",
"__builtin_inff128"});
8451 llvm_unreachable(
"unknown MathCheck");
8458 bool IsNaNOrIsUnordered =
8462 if ((IsNaNOrIsUnordered || IsSpecialNaN) && FPO.getNoHonorNaNs()) {
8463 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8464 << 1 << 0 <<
Call->getSourceRange();
8466 bool IsInfOrIsFinite =
8468 bool IsInfinityOrIsSpecialInf =
8469 HasIdentifier && ((FDecl->
getName() ==
"infinity") ||
8471 if ((IsInfOrIsFinite || IsInfinityOrIsSpecialInf) && FPO.getNoHonorInfs())
8472 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8473 << 0 << 0 <<
Call->getSourceRange();
8477void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
8479 if (
Call->getNumArgs() != 1)
8484 if (AbsKind == 0 && !IsStdAbs)
8487 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8493 StringRef FunctionName =
8495 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
8496 Diag(
Call->getExprLoc(), diag::note_remove_abs)
8505 unsigned DiagType = 0;
8511 Diag(
Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
8525 if (ArgValueKind == ParamValueKind) {
8530 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
8531 << FDecl << ArgType << ParamType;
8533 if (NewAbsKind == 0)
8537 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8546 if (NewAbsKind == 0)
8549 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
8550 << FDecl << ParamValueKind << ArgValueKind;
8553 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8559 if (!
Call || !FDecl)
return;
8563 if (
Call->getExprLoc().isMacroID())
return;
8566 if (
Call->getNumArgs() != 2)
return;
8569 if (!ArgList)
return;
8570 if (ArgList->size() != 1)
return;
8573 const auto& TA = ArgList->
get(0);
8579 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
8580 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
8581 if (!MTE)
return false;
8582 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
8583 if (!
Num)
return false;
8584 if (
Num->getValue() != 0)
return false;
8588 const Expr *FirstArg =
Call->getArg(0);
8589 const Expr *SecondArg =
Call->getArg(1);
8590 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
8591 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
8594 if (IsFirstArgZero == IsSecondArgZero)
return;
8599 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
8601 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
8602 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
8606 if (IsFirstArgZero) {
8614 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
8634 if (!Size->isComparisonOp() && !Size->isLogicalOp())
8638 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
8639 << SizeRange << FnName;
8640 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
8645 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
8656 bool &IsContained) {
8659 IsContained =
false;
8672 for (
auto *FD : RD->
fields()) {
8685 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
8686 if (Unary->getKind() == UETT_SizeOf)
8695 if (!
SizeOf->isArgumentType())
8696 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
8703 return SizeOf->getTypeOfArgument();
8709struct SearchNonTrivialToInitializeField
8714 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8718 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8719 asDerived().visitArray(PDIK, AT, SL);
8723 Super::visitWithKind(PDIK, FT, SL);
8738 visit(getContext().getBaseElementType(AT), SL);
8743 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
8752struct SearchNonTrivialToCopyField
8756 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8760 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8761 asDerived().visitArray(PCK, AT, SL);
8765 Super::visitWithKind(PCK, FT, SL);
8780 visit(getContext().getBaseElementType(AT), SL);
8803 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
8804 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
8828 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
8830 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
8831 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
8837 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
8840 const Expr *SizeArg =
8841 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
8843 auto isLiteralZero = [](
const Expr *
E) {
8844 return (isa<IntegerLiteral>(
E) &&
8845 cast<IntegerLiteral>(
E)->getValue() == 0) ||
8846 (isa<CharacterLiteral>(
E) &&
8847 cast<CharacterLiteral>(
E)->getValue() == 0);
8853 if (isLiteralZero(SizeArg) &&
8860 if (BId == Builtin::BIbzero ||
8863 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
8864 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
8865 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
8866 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
8867 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
8875 if (BId == Builtin::BImemset &&
8879 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
8880 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
8885void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
8892 unsigned ExpectedNumArgs =
8893 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
8894 if (
Call->getNumArgs() < ExpectedNumArgs)
8897 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
8898 BId == Builtin::BIstrndup ? 1 : 2);
8900 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
8901 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
8904 Call->getBeginLoc(),
Call->getRParenLoc()))
8913 llvm::FoldingSetNodeID SizeOfArgID;
8918 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8922 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
8923 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
8945 if (SizeOfArgID == llvm::FoldingSetNodeID())
8947 llvm::FoldingSetNodeID DestID;
8949 if (DestID == SizeOfArgID) {
8952 unsigned ActionIdx = 0;
8953 StringRef ReadableName = FnName->
getName();
8955 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
8956 if (UnaryOp->getOpcode() == UO_AddrOf)
8970 if (
SM.isMacroArgExpansion(SL)) {
8972 SL =
SM.getSpellingLoc(SL);
8980 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
8987 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
9002 PDiag(diag::warn_sizeof_pointer_type_memaccess)
9003 << FnName << SizeOfArgTy << ArgIdx
9021 unsigned OperationType = 0;
9022 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
9025 if (ArgIdx != 0 || IsCmp) {
9026 if (BId == Builtin::BImemcpy)
9028 else if(BId == Builtin::BImemmove)
9035 PDiag(diag::warn_dyn_class_memaccess)
9036 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
9037 << IsContained << ContainedRD << OperationType
9038 <<
Call->getCallee()->getSourceRange());
9040 BId != Builtin::BImemset)
9043 PDiag(diag::warn_arc_object_memaccess)
9044 << ArgIdx << FnName << PointeeTy
9045 <<
Call->getCallee()->getSourceRange());
9052 bool MayBeTriviallyCopyableCXXRecord =
9054 RT->desugar().isTriviallyCopyableType(
Context);
9056 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9057 RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
9059 PDiag(diag::warn_cstruct_memaccess)
9060 << ArgIdx << FnName << PointeeTy << 0);
9061 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
9062 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9063 !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9067 PDiag(diag::warn_cxxstruct_memaccess)
9068 << FnName << PointeeTy);
9069 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9070 RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
9072 PDiag(diag::warn_cstruct_memaccess)
9073 << ArgIdx << FnName << PointeeTy << 1);
9074 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
9075 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9076 !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9080 PDiag(diag::warn_cxxstruct_memaccess)
9081 << FnName << PointeeTy);
9090 PDiag(diag::note_bad_memaccess_silence)
9110 if (isa<IntegerLiteral>(RHS))
9112 else if (isa<IntegerLiteral>(LHS))
9126 if (CAT->getZExtSize() <= 1)
9134void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
9138 unsigned NumArgs =
Call->getNumArgs();
9139 if ((NumArgs != 3) && (NumArgs != 4))
9144 const Expr *CompareWithSrc =
nullptr;
9147 Call->getBeginLoc(),
Call->getRParenLoc()))
9152 CompareWithSrc = Ex;
9155 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
9156 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
9157 SizeCall->getNumArgs() == 1)
9162 if (!CompareWithSrc)
9169 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
9173 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
9174 if (!CompareWithSrcDRE ||
9178 const Expr *OriginalSizeArg =
Call->getArg(2);
9179 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
9186 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
9191 llvm::raw_svector_ostream
OS(sizeString);
9196 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
9203 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
9204 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
9205 return D1->getDecl() == D2->getDecl();
9210 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
9219void Sema::CheckStrncatArguments(
const CallExpr *CE,
9234 unsigned PatternType = 0;
9242 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
9243 if (BE->getOpcode() == BO_Sub) {
9256 if (PatternType == 0)
9265 if (
SM.isMacroArgExpansion(SL)) {
9266 SL =
SM.getSpellingLoc(SL);
9275 if (!isKnownSizeArray) {
9276 if (PatternType == 1)
9277 Diag(SL, diag::warn_strncat_wrong_size) << SR;
9279 Diag(SL, diag::warn_strncat_src_size) << SR;
9283 if (PatternType == 1)
9284 Diag(SL, diag::warn_strncat_large_size) << SR;
9286 Diag(SL, diag::warn_strncat_src_size) << SR;
9289 llvm::raw_svector_ostream
OS(sizeString);
9297 Diag(SL, diag::note_strncat_wrong_size)
9302void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
9304 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
9306 << CalleeName << 0 << cast<NamedDecl>(
D);
9311void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
9313 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
9314 const Decl *
D = Lvalue->getDecl();
9315 if (isa<DeclaratorDecl>(
D))
9316 if (!dyn_cast<DeclaratorDecl>(
D)->getType()->isReferenceType())
9317 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
9320 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
9321 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
9322 Lvalue->getMemberDecl());
9325void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
9327 const auto *Lambda = dyn_cast<LambdaExpr>(
9332 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
9333 << CalleeName << 2 ;
9336void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
9338 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
9343 << CalleeName << 0 << Var;
9346void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
9349 llvm::raw_svector_ostream OS(SizeString);
9352 if (Kind == clang::CK_BitCast &&
9353 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
9355 if (Kind == clang::CK_IntegralToPointer &&
9356 !isa<IntegerLiteral>(
9357 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
9360 switch (
Cast->getCastKind()) {
9361 case clang::CK_BitCast:
9362 case clang::CK_IntegralToPointer:
9363 case clang::CK_FunctionToPointerDecay:
9372 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
9373 << CalleeName << 0 << OS.str();
9377void Sema::CheckFreeArguments(
const CallExpr *
E) {
9378 const std::string CalleeName =
9379 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
9383 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
9385 case UnaryOperator::Opcode::UO_AddrOf:
9386 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
9387 case UnaryOperator::Opcode::UO_Plus:
9388 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
9393 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
9395 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
9397 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
9398 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
9399 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
9403 if (isa<BlockExpr>(Arg)) {
9405 << CalleeName << 1 ;
9410 if (
const auto *Cast = dyn_cast<CastExpr>(
E->getArg(0)))
9411 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
9415Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
9421 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
9424 Diag(ReturnLoc, diag::warn_null_ret)
9434 if (Op == OO_New || Op == OO_Array_New) {
9439 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
9445 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
9462 auto getCastAndLiteral = [&FPLiteral, &FPCast](
Expr *L,
Expr *R) {
9463 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
9465 return FPLiteral && FPCast;
9468 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
9474 llvm::APFloat TargetC = FPLiteral->
getValue();
9476 llvm::APFloat::rmNearestTiesToEven, &Lossy);
9480 Diag(
Loc, diag::warn_float_compare_literal)
9481 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
9494 if (
auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
9495 if (
auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
9496 if (DRL->getDecl() == DRR->getDecl())
9504 if (
FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
9508 if (
FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
9513 if (
CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
9514 if (CL->getBuiltinCallee())
9517 if (
CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
9518 if (CR->getBuiltinCallee())
9522 Diag(
Loc, diag::warn_floatingpoint_eq)
9543 IntRange(
unsigned Width,
bool NonNegative)
9544 : Width(Width), NonNegative(NonNegative) {}
9547 unsigned valueBits()
const {
9548 return NonNegative ? Width : Width - 1;
9552 static IntRange forBoolType() {
9553 return IntRange(1,
true);
9558 return forValueOfCanonicalType(
C,
9566 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9567 T = VT->getElementType().getTypePtr();
9569 T = CT->getElementType().getTypePtr();
9570 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9571 T = AT->getValueType().getTypePtr();
9573 if (!
C.getLangOpts().CPlusPlus) {
9575 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9576 T = ET->getDecl()->getIntegerType().getDesugaredType(
C).getTypePtr();
9577 }
else if (
const EnumType *ET = dyn_cast<EnumType>(
T)) {
9582 if (
Enum->isFixed()) {
9583 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
9584 !ET->isSignedIntegerOrEnumerationType());
9587 unsigned NumPositive =
Enum->getNumPositiveBits();
9588 unsigned NumNegative =
Enum->getNumNegativeBits();
9590 if (NumNegative == 0)
9591 return IntRange(NumPositive,
true);
9593 return IntRange(std::max(NumPositive + 1, NumNegative),
9597 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9598 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9614 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9615 T = VT->getElementType().getTypePtr();
9617 T = CT->getElementType().getTypePtr();
9618 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9619 T = AT->getValueType().getTypePtr();
9620 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9621 T =
C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
9623 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9624 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9633 static IntRange join(IntRange L, IntRange R) {
9634 bool Unsigned = L.NonNegative && R.NonNegative;
9635 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
9636 L.NonNegative && R.NonNegative);
9640 static IntRange bit_and(IntRange L, IntRange R) {
9641 unsigned Bits = std::max(L.Width, R.Width);
9642 bool NonNegative =
false;
9643 if (L.NonNegative) {
9644 Bits = std::min(Bits, L.Width);
9647 if (R.NonNegative) {
9648 Bits = std::min(Bits, R.Width);
9651 return IntRange(Bits, NonNegative);
9655 static IntRange sum(IntRange L, IntRange R) {
9656 bool Unsigned = L.NonNegative && R.NonNegative;
9657 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
9662 static IntRange difference(IntRange L, IntRange R) {
9666 bool CanWiden = !L.NonNegative || !R.NonNegative;
9667 bool Unsigned = L.NonNegative && R.Width == 0;
9668 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
9674 static IntRange product(IntRange L, IntRange R) {
9678 bool CanWiden = !L.NonNegative && !R.NonNegative;
9679 bool Unsigned = L.NonNegative && R.NonNegative;
9680 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
9685 static IntRange rem(IntRange L, IntRange R) {
9689 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
9697 unsigned MaxWidth) {
9698 if (value.isSigned() && value.isNegative())
9699 return IntRange(value.getSignificantBits(),
false);
9701 if (value.getBitWidth() > MaxWidth)
9702 value = value.trunc(MaxWidth);
9706 return IntRange(value.getActiveBits(),
true);
9710 unsigned MaxWidth) {
9718 R = IntRange::join(R, El);
9726 return IntRange::join(R, I);
9741 Ty = AtomicRHS->getValueType();
9760 bool InConstantContext,
9772 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
9773 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
9777 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
9779 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
9780 CE->getCastKind() == CK_BooleanToSignedIntegral;
9784 return OutputTypeRange;
9787 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
9788 InConstantContext, Approximate);
9790 return std::nullopt;
9793 if (SubRange->Width >= OutputTypeRange.Width)
9794 return OutputTypeRange;
9798 return IntRange(SubRange->Width,
9799 SubRange->NonNegative || OutputTypeRange.NonNegative);
9802 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
9805 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
9807 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
9808 InConstantContext, Approximate);
9813 Expr *TrueExpr = CO->getTrueExpr();
9815 return std::nullopt;
9817 std::optional<IntRange> L =
9820 return std::nullopt;
9822 Expr *FalseExpr = CO->getFalseExpr();
9824 return std::nullopt;
9826 std::optional<IntRange> R =
9829 return std::nullopt;
9831 return IntRange::join(*L, *R);
9834 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
9835 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
9837 switch (BO->getOpcode()) {
9839 llvm_unreachable(
"builtin <=> should have class type");
9850 return IntRange::forBoolType();
9879 Combine = IntRange::bit_and;
9887 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
9888 if (I->getValue() == 1) {
9890 return IntRange(R.Width,
true);
9900 case BO_ShrAssign: {
9902 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
9904 return std::nullopt;
9908 if (std::optional<llvm::APSInt> shift =
9909 BO->getRHS()->getIntegerConstantExpr(
C)) {
9910 if (shift->isNonNegative()) {
9911 if (shift->uge(L->Width))
9912 L->Width = (L->NonNegative ? 0 : 1);
9914 L->Width -= shift->getZExtValue();
9928 Combine = IntRange::sum;
9932 if (BO->getLHS()->getType()->isPointerType())
9935 Combine = IntRange::difference;
9940 Combine = IntRange::product;
9949 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
9951 return std::nullopt;
9954 if (std::optional<llvm::APSInt> divisor =
9955 BO->getRHS()->getIntegerConstantExpr(
C)) {
9956 unsigned log2 = divisor->logBase2();
9957 if (
log2 >= L->Width)
9958 L->Width = (L->NonNegative ? 0 : 1);
9960 L->Width = std::min(L->Width -
log2, MaxWidth);
9968 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
9970 return std::nullopt;
9972 return IntRange(L->Width, L->NonNegative && R->NonNegative);
9976 Combine = IntRange::rem;
9988 unsigned opWidth =
C.getIntWidth(
T);
9990 InConstantContext, Approximate);
9992 return std::nullopt;
9995 InConstantContext, Approximate);
9997 return std::nullopt;
9999 IntRange
C = Combine(*L, *R);
10001 C.Width = std::min(
C.Width, MaxWidth);
10005 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
10006 switch (UO->getOpcode()) {
10009 return IntRange::forBoolType();
10022 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
10023 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
10027 return IntRange(BitField->getBitWidthValue(
C),
10028 BitField->getType()->isUnsignedIntegerOrEnumerationType());
10031 return std::nullopt;
10037 bool InConstantContext,
10038 bool Approximate) {
10047 const llvm::fltSemantics &Src,
10048 const llvm::fltSemantics &Tgt) {
10049 llvm::APFloat truncated = value;
10052 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
10053 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
10055 return truncated.bitwiseIsEqual(value);
10064 const llvm::fltSemantics &Src,
10065 const llvm::fltSemantics &Tgt) {
10082 bool IsListInit =
false);
10088 if (isa<EnumConstantDecl>(DR->getDecl()))
10098 return MacroName !=
"YES" && MacroName !=
"NO" &&
10099 MacroName !=
"true" && MacroName !=
"false";
10122struct PromotedRange {
10124 llvm::APSInt PromotedMin;
10126 llvm::APSInt PromotedMax;
10128 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
10130 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
10131 else if (R.Width >= BitWidth && !
Unsigned) {
10135 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
10136 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
10138 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
10139 .extOrTrunc(BitWidth);
10140 PromotedMin.setIsUnsigned(
Unsigned);
10142 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
10143 .extOrTrunc(BitWidth);
10144 PromotedMax.setIsUnsigned(
Unsigned);
10149 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
10159 InRangeFlag = 0x40,
10162 Min =
LE | InRangeFlag,
10164 Max =
GE | InRangeFlag,
10167 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
10172 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
10173 Value.isUnsigned() == PromotedMin.isUnsigned());
10174 if (!isContiguous()) {
10175 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
10176 if (
Value.isMinValue())
return Min;
10177 if (
Value.isMaxValue())
return Max;
10183 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
10184 case -1:
return Less;
10185 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
10187 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
10189 case 0:
return Max;
10194 llvm_unreachable(
"impossible compare result");
10197 static std::optional<StringRef>
10199 if (Op == BO_Cmp) {
10201 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
10203 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
10204 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
10205 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
10206 return std::nullopt;
10213 }
else if (Op == BO_NE) {
10217 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
10224 if (Op == BO_GE || Op == BO_LE)
10225 std::swap(TrueFlag, FalseFlag);
10228 return StringRef(
"true");
10230 return StringRef(
"false");
10231 return std::nullopt;
10239 if (ICE->getCastKind() != CK_IntegralCast &&
10240 ICE->getCastKind() != CK_NoOp)
10242 E = ICE->getSubExpr();
10251 enum ConstantValueKind {
10256 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
10257 return BL->getValue() ? ConstantValueKind::LiteralTrue
10258 : ConstantValueKind::LiteralFalse;
10259 return ConstantValueKind::Miscellaneous;
10264 const llvm::APSInt &
Value,
10265 bool RhsConstant) {
10287 if (!OtherValueRange)
10292 OtherT = AT->getValueType();
10293 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
10297 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
10303 bool OtherIsBooleanDespiteType =
10305 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
10306 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
10310 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
10311 Value.isUnsigned());
10312 auto Cmp = OtherPromotedValueRange.compare(
Value);
10313 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
10319 bool TautologicalTypeCompare =
false;
10321 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
10322 Value.isUnsigned());
10323 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
10324 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
10326 TautologicalTypeCompare =
true;
10334 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
10343 bool InRange = Cmp & PromotedRange::InRangeFlag;
10349 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
10350 Other->getType()->isUnsignedIntegerOrEnumerationType())
10351 TautologicalTypeCompare =
true;
10356 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant))
10357 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
10361 llvm::raw_svector_ostream OS(PrettySourceValue);
10363 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
10364 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
10366 OS << (BL->getValue() ?
"YES" :
"NO");
10371 if (!TautologicalTypeCompare) {
10372 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
10373 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
10374 <<
E->getOpcodeStr() << OS.str() << *
Result
10379 if (IsObjCSignedCharBool) {
10381 S.
PDiag(diag::warn_tautological_compare_objc_bool)
10382 << OS.str() << *
Result);
10389 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
10392 E->getOperatorLoc(),
E,
10393 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
10394 : diag::warn_tautological_bool_compare)
10396 << OtherIsBooleanDespiteType << *
Result
10403 ? diag::warn_unsigned_enum_always_true_comparison
10404 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
10405 : diag::warn_unsigned_always_true_comparison)
10406 : diag::warn_tautological_constant_compare;
10409 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result
10439 Expr *LHS =
E->getLHS();
10440 Expr *RHS =
E->getRHS();
10443 std::optional<llvm::APSInt> RHSValue =
10445 std::optional<llvm::APSInt> LHSValue =
10449 if (RHSValue && LHSValue)
10453 if ((
bool)RHSValue ^ (
bool)LHSValue) {
10455 const bool RhsConstant = (
bool)RHSValue;
10456 Expr *Const = RhsConstant ? RHS : LHS;
10458 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
10481 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
10483 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
10489 Expr *signedOperand, *unsignedOperand;
10492 "unsigned comparison between two signed integer expressions?");
10493 signedOperand = LHS;
10494 unsignedOperand = RHS;
10496 signedOperand = RHS;
10497 unsignedOperand = LHS;
10503 std::optional<IntRange> signedRange =
10515 if (signedRange->NonNegative)
10522 if (
E->isEqualityOp()) {
10527 if (!unsignedRange)
10532 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
10534 if (unsignedRange->Width < comparisonWidth)
10539 S.
PDiag(diag::warn_mixed_sign_comparison)
10567 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
10568 << BitfieldEnumDecl;
10575 Init->isValueDependent() ||
10576 Init->isTypeDependent())
10579 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
10602 unsigned DiagID = 0;
10603 if (SignedEnum && !SignedBitfield) {
10604 DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
10605 }
else if (SignedBitfield && !SignedEnum &&
10607 DiagID = diag::warn_signed_bitfield_enum_conversion;
10611 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
10616 << SignedEnum << TypeRange;
10627 if (BitsNeeded > FieldWidth) {
10629 S.
Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
10641 unsigned OriginalWidth =
Value.getBitWidth();
10647 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
10648 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
10655 if (!
Value.isSigned() ||
Value.isNegative())
10656 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
10657 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
10658 OriginalWidth =
Value.getSignificantBits();
10660 if (OriginalWidth <= FieldWidth)
10664 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
10668 TruncatedValue = TruncatedValue.extend(OriginalWidth);
10669 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
10673 std::string PrettyTrunc =
toString(TruncatedValue, 10);
10675 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
10676 ? diag::warn_impcast_single_bit_bitield_precision_constant
10677 : diag::warn_impcast_bitfield_precision_constant)
10678 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
10679 <<
Init->getSourceRange();
10694 E->getOperatorLoc())) {
10697 E->getOperatorLoc());
10711 bool pruneControlFlow =
false) {
10712 if (pruneControlFlow) {
10726 unsigned diag,
bool pruneControlFlow =
false) {
10739 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
10742 const bool IsLiteral =
10743 isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
10745 llvm::APFloat
Value(0.0);
10751 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10756 diag::warn_impcast_float_integer, PruneWarnings);
10759 bool isExact =
false;
10763 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
10764 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
10772 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
10773 precision = (precision * 59 + 195) / 196;
10774 Value.toString(PrettySourceValue, precision);
10778 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10779 << PrettySourceValue);
10782 if (
Result == llvm::APFloat::opOK && isExact) {
10783 if (IsLiteral)
return;
10790 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
10793 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
10794 : diag::warn_impcast_float_to_integer_out_of_range,
10797 unsigned DiagID = 0;
10800 DiagID = diag::warn_impcast_literal_float_to_integer;
10801 }
else if (IntegerValue == 0) {
10802 if (
Value.isZero()) {
10804 diag::warn_impcast_float_integer, PruneWarnings);
10807 DiagID = diag::warn_impcast_float_to_integer_zero;
10809 if (IntegerValue.isUnsigned()) {
10810 if (!IntegerValue.isMaxValue()) {
10812 diag::warn_impcast_float_integer, PruneWarnings);
10815 if (!IntegerValue.isMaxSignedValue() &&
10816 !IntegerValue.isMinSignedValue()) {
10818 diag::warn_impcast_float_integer, PruneWarnings);
10822 DiagID = diag::warn_impcast_float_to_integer;
10827 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
10829 IntegerValue.toString(PrettyTargetValue);
10831 if (PruneWarnings) {
10834 <<
E->
getType() <<
T.getUnqualifiedType()
10835 << PrettySourceValue << PrettyTargetValue
10839 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
10847 assert(isa<CompoundAssignOperator>(
E) &&
10848 "Must be compound assignment operation");
10854 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
10858 const auto *RBT = cast<CompoundAssignOperator>(
E)
10859 ->getComputationResultType()
10866 if (ResultBT->isInteger())
10868 E->
getExprLoc(), diag::warn_impcast_float_integer);
10870 if (!ResultBT->isFloatingPoint())
10879 diag::warn_impcast_float_result_precision);
10884 if (!
Range.Width)
return "0";
10886 llvm::APSInt ValueInRange =
Value;
10887 ValueInRange.setIsSigned(!
Range.NonNegative);
10888 ValueInRange = ValueInRange.trunc(
Range.Width);
10889 return toString(ValueInRange, 10);
10893 if (!isa<ImplicitCastExpr>(Ex))
10898 const Type *Source =
10900 if (
Target->isDependentType())
10904 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
10905 const Type *BoolCandidateType = ToBool ?
Target : Source;
10914 for (
unsigned i = 0; i < NumArgs; ++i) {
10919 bool IsSwapped = ((i > 0) &&
10921 IsSwapped |= ((i < (NumArgs - 1)) &&
10927 diag::warn_impcast_floating_point_to_bool);
10934 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
10939 if (isa<CallExpr>(
E))
10944 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
10946 if (!IsGNUNullExpr && !HasNullPtrType)
10966 if (MacroName ==
"NULL")
10974 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
10988 const char FirstLiteralCharacter =
10990 if (FirstLiteralCharacter ==
'0')
10997 const char FirstContextCharacter =
10999 if (FirstContextCharacter ==
'{')
11007 const auto *IL = dyn_cast<IntegerLiteral>(
E);
11009 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
11010 if (UO->getOpcode() == UO_Minus)
11011 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
11022 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
11026 if (Opc == BO_Shl) {
11029 if (LHS && LHS->getValue() == 0)
11030 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
11032 RHS->getValue().isNonNegative() &&
11034 S.
Diag(ExprLoc, diag::warn_left_shift_always)
11035 << (
Result.Val.getInt() != 0);
11037 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context) <<
E;
11041 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
11046 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
11047 (RHS->getValue() == 0 || RHS->getValue() == 1))
11050 if (LHS->getValue() != 0 && RHS->getValue() != 0)
11051 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
11056 bool *ICContext,
bool IsListInit) {
11061 if (Source ==
Target)
return;
11062 if (
Target->isDependentType())
return;
11076 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
11077 if (isa<StringLiteral>(
E))
11082 diag::warn_impcast_string_literal_to_bool);
11083 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
11084 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
11088 diag::warn_impcast_objective_c_literal_to_bool);
11103 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
11105 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
11114 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
11116 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
11120 if (isa<VectorType>(Source)) {
11121 if (
Target->isSveVLSBuiltinType() &&
11128 if (
Target->isRVVVLSBuiltinType() &&
11135 if (!isa<VectorType>(
Target)) {
11145 diag::warn_hlsl_impcast_vector_truncation);
11154 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
11155 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
11157 if (
auto VecTy = dyn_cast<VectorType>(
Target))
11158 Target = VecTy->getElementType().getTypePtr();
11161 if (isa<ComplexType>(Source)) {
11162 if (!isa<ComplexType>(
Target)) {
11168 ? diag::err_impcast_complex_scalar
11169 : diag::warn_impcast_complex_scalar);
11172 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
11173 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
11176 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
11229 else if (Order < 0) {
11239 if (TargetBT && TargetBT->
isInteger()) {
11254 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
11262 if (isa<ImplicitCastExpr>(LastA) &&
11266 diag::warn_impcast_floating_point_to_bool);
11275 if (
Target->isUnsaturatedFixedPointType()) {
11279 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
11284 PDiag(diag::warn_impcast_fixed_point_range)
11285 <<
Value.toString() <<
T
11291 }
else if (
Target->isIntegerType()) {
11295 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
11298 llvm::APSInt IntResult = FXResult.convertToInt(
11304 PDiag(diag::warn_impcast_fixed_point_range)
11305 << FXResult.toString() <<
T
11312 }
else if (
Target->isUnsaturatedFixedPointType()) {
11320 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
11325 PDiag(diag::warn_impcast_fixed_point_range)
11346 unsigned int SourcePrecision =
SourceRange->Width;
11350 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
11353 if (SourcePrecision > 0 && TargetPrecision > 0 &&
11354 SourcePrecision > TargetPrecision) {
11356 if (std::optional<llvm::APSInt> SourceInt =
11361 llvm::APFloat TargetFloatValue(
11363 llvm::APFloat::opStatus ConversionStatus =
11364 TargetFloatValue.convertFromAPInt(
11366 llvm::APFloat::rmNearestTiesToEven);
11368 if (ConversionStatus != llvm::APFloat::opOK) {
11370 SourceInt->toString(PrettySourceValue, 10);
11372 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
11376 PDiag(diag::warn_impcast_integer_float_precision_constant)
11377 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11383 diag::warn_impcast_integer_float_precision);
11392 if (
Target->isBooleanType())
11400 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
11406 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11411 if (!LikelySourceRange)
11414 IntRange SourceTypeRange =
11415 IntRange::forTargetOfCanonicalType(
Context, Source);
11416 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
11418 if (LikelySourceRange->Width > TargetRange.Width) {
11424 llvm::APSInt
Value(32);
11434 PDiag(diag::warn_impcast_integer_precision_constant)
11435 << PrettySourceValue << PrettyTargetValue
11449 diag::warn_impcast_integer_precision);
11452 if (TargetRange.Width > SourceTypeRange.Width) {
11453 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
11454 if (UO->getOpcode() == UO_Minus)
11456 if (
Target->isUnsignedIntegerType())
11458 diag::warn_impcast_high_order_zero_bits);
11459 if (
Target->isSignedIntegerType())
11461 diag::warn_impcast_nonnegative_result);
11465 if (TargetRange.Width == LikelySourceRange->Width &&
11466 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11481 PDiag(diag::warn_impcast_integer_precision_constant)
11482 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11491 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
11492 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
11493 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11494 LikelySourceRange->Width == TargetRange.Width))) {
11498 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
11504 unsigned DiagID = diag::warn_impcast_integer_sign;
11512 DiagID = diag::warn_impcast_integer_sign_conditional;
11527 if (SourceEnum->getDecl()->hasNameForLinkage() &&
11528 TargetEnum->getDecl()->hasNameForLinkage() &&
11529 SourceEnum != TargetEnum) {
11534 diag::warn_impcast_different_enum_types);
11548 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
11560 Expr *TrueExpr =
E->getTrueExpr();
11561 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
11562 TrueExpr = BCO->getCommon();
11564 bool Suspicious =
false;
11573 if (!Suspicious)
return;
11576 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
11583 Suspicious =
false;
11605struct AnalyzeImplicitConversionsWorkItem {
11615 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
11617 Expr *OrigE = Item.E;
11626 bool IsListInit = Item.IsListInit ||
11627 (isa<InitListExpr>(OrigE) && S.
getLangOpts().CPlusPlus);
11632 Expr *SourceExpr =
E;
11637 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11638 if (
auto *Src = OVE->getSourceExpr())
11641 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
11642 if (UO->getOpcode() == UO_Not &&
11643 UO->getSubExpr()->isKnownToHaveBooleanValue())
11644 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
11648 if (
const auto *BO = dyn_cast<BinaryOperator>(SourceExpr))
11649 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
11650 BO->getLHS()->isKnownToHaveBooleanValue() &&
11651 BO->getRHS()->isKnownToHaveBooleanValue() &&
11652 BO->getLHS()->HasSideEffects(S.
Context) &&
11653 BO->getRHS()->HasSideEffects(S.
Context)) {
11664 if (SR.str() ==
"&" || SR.str() ==
"|") {
11666 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
11667 << (BO->getOpcode() == BO_And ?
"&" :
"|")
11670 BO->getOperatorLoc(),
11671 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
11672 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
11678 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
11699 for (
auto *SE : POE->semantics())
11700 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
11701 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
11705 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
11709 WorkList.push_back({
E, CC, IsListInit});
11713 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(
E)) {
11714 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
11718 if (OutArgE->isInOut())
11719 WorkList.push_back(
11720 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
11721 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
11727 if (BO->isComparisonOp())
11731 if (BO->getOpcode() == BO_Assign)
11734 if (BO->isAssignmentOp())
11742 if (isa<StmtExpr>(
E))
return;
11745 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
11750 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
11752 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
11756 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
11757 if (ChildExpr == CSE->getOperand())
11763 if (IsLogicalAndOperator &&
11768 WorkList.push_back({ChildExpr, CC, IsListInit});
11773 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11777 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11782 if (
U->getOpcode() == UO_LNot) {
11784 }
else if (
U->getOpcode() != UO_AddrOf) {
11785 if (
U->getSubExpr()->getType()->isAtomicType())
11786 S.
Diag(
U->getSubExpr()->getBeginLoc(),
11787 diag::warn_atomic_implicit_seq_cst);
11798 WorkList.push_back({OrigE, CC, IsListInit});
11799 while (!WorkList.empty())
11811 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
11814 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11815 if (!M->getMemberDecl()->getType()->isReferenceType())
11818 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
11820 FD =
Call->getDirectCallee();
11829 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
11843 if (
SM.isMacroBodyExpansion(
Loc))
11845 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
11868 if (isa<CXXThisExpr>(
E)) {
11869 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
11870 : diag::warn_this_bool_conversion;
11875 bool IsAddressOf =
false;
11877 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
11878 if (UO->getOpcode() != UO_AddrOf)
11880 IsAddressOf =
true;
11881 E = UO->getSubExpr();
11885 unsigned DiagID = IsCompare
11886 ? diag::warn_address_of_reference_null_compare
11887 : diag::warn_address_of_reference_bool_conversion;
11895 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
11896 bool IsParam = isa<NonNullAttr>(NonnullAttr);
11898 llvm::raw_string_ostream S(Str);
11900 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
11901 : diag::warn_cast_nonnull_to_bool;
11904 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
11909 if (
auto *Callee =
Call->getDirectCallee()) {
11910 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
11911 ComplainAboutNonnullParamOrCall(A);
11920 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
11921 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
11922 MRecordDecl && MRecordDecl->isLambda()) {
11925 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
11935 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11936 D = M->getMemberDecl();
11940 if (!
D ||
D->isWeak())
11944 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
11947 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
11948 ComplainAboutNonnullParamOrCall(A);
11952 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
11956 auto ParamIter = llvm::find(FD->
parameters(), PV);
11958 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
11962 ComplainAboutNonnullParamOrCall(
NonNull);
11967 if (ArgNo.getASTIndex() == ParamNo) {
11968 ComplainAboutNonnullParamOrCall(
NonNull);
11982 if (IsAddressOf && IsFunction) {
11987 if (!IsAddressOf && !IsFunction && !IsArray)
11992 llvm::raw_string_ostream S(Str);
11995 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
11996 : diag::warn_impcast_pointer_to_bool;
12003 DiagType = AddressOf;
12004 else if (IsFunction)
12005 DiagType = FunctionPointer;
12007 DiagType = ArrayPointer;
12009 llvm_unreachable(
"Could not determine diagnostic.");
12011 <<
Range << IsEqual;
12024 if (ReturnType.
isNull())
12062 CheckArrayAccess(
E);
12069 ::CheckBoolLikeConversion(*
this,
E, CC);
12072void Sema::CheckForIntOverflow (
const Expr *
E) {
12077 const Expr *OriginalE = Exprs.pop_back_val();
12080 if (isa<BinaryOperator, UnaryOperator>(
E)) {
12085 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
12086 Exprs.append(InitList->inits().begin(), InitList->inits().end());
12087 else if (isa<ObjCBoxedExpr>(OriginalE))
12089 else if (
const auto *
Call = dyn_cast<CallExpr>(
E))
12090 Exprs.append(
Call->arg_begin(),
Call->arg_end());
12091 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
12092 Exprs.append(Message->arg_begin(), Message->arg_end());
12093 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
12094 Exprs.append(Construct->arg_begin(), Construct->arg_end());
12095 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
12096 Exprs.push_back(Temporary->getSubExpr());
12097 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
12098 Exprs.push_back(Array->getIdx());
12099 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
12100 Exprs.push_back(Compound->getInitializer());
12101 else if (
const auto *New = dyn_cast<CXXNewExpr>(
E);
12102 New && New->isArray()) {
12103 if (
auto ArraySize = New->getArraySize())
12104 Exprs.push_back(*ArraySize);
12105 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
12106 Exprs.push_back(MTE->getSubExpr());
12107 }
while (!Exprs.empty());
12122 class SequenceTree {
12126 LLVM_PREFERRED_TYPE(
bool)
12127 unsigned Merged : 1;
12135 friend class SequenceTree;
12139 explicit Seq(
unsigned N) : Index(N) {}
12142 Seq() : Index(0) {}
12145 SequenceTree() { Values.push_back(
Value(0)); }
12146 Seq root()
const {
return Seq(0); }
12153 return Seq(Values.size() - 1);
12157 void merge(
Seq S) {
12158 Values[S.Index].Merged =
true;
12164 bool isUnsequenced(
Seq Cur,
Seq Old) {
12165 unsigned C = representative(Cur.Index);
12166 unsigned Target = representative(Old.Index);
12170 C = Values[
C].Parent;
12177 unsigned representative(
unsigned K) {
12178 if (Values[K].Merged)
12180 return Values[K].Parent = representative(Values[K].
Parent);
12200 UK_ModAsSideEffect,
12202 UK_Count = UK_ModAsSideEffect + 1
12208 const Expr *UsageExpr =
nullptr;
12209 SequenceTree::Seq
Seq;
12215 Usage Uses[UK_Count];
12218 bool Diagnosed =
false;
12222 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
12230 UsageInfoMap UsageMap;
12233 SequenceTree::Seq Region;
12248 struct SequencedSubexpression {
12249 SequencedSubexpression(SequenceChecker &Self)
12250 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
12251 Self.ModAsSideEffect = &ModAsSideEffect;
12254 ~SequencedSubexpression() {
12255 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
12259 UsageInfo &UI = Self.UsageMap[M.first];
12260 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
12261 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
12262 SideEffectUsage = M.second;
12264 Self.ModAsSideEffect = OldModAsSideEffect;
12267 SequenceChecker &Self;
12276 class EvaluationTracker {
12278 EvaluationTracker(SequenceChecker &Self)
12279 : Self(Self), Prev(Self.EvalTracker) {
12280 Self.EvalTracker =
this;
12283 ~EvaluationTracker() {
12284 Self.EvalTracker = Prev;
12286 Prev->EvalOK &= EvalOK;
12289 bool evaluate(
const Expr *
E,
bool &Result) {
12293 Result, Self.SemaRef.Context,
12294 Self.SemaRef.isConstantEvaluatedContext());
12299 SequenceChecker &Self;
12300 EvaluationTracker *Prev;
12301 bool EvalOK =
true;
12302 } *EvalTracker =
nullptr;
12306 Object getObject(
const Expr *
E,
bool Mod)
const {
12309 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
12310 return getObject(UO->getSubExpr(), Mod);
12312 if (BO->getOpcode() == BO_Comma)
12313 return getObject(BO->getRHS(), Mod);
12314 if (Mod && BO->isAssignmentOp())
12315 return getObject(BO->getLHS(), Mod);
12316 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
12318 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
12319 return ME->getMemberDecl();
12320 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
12329 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
12331 Usage &
U = UI.Uses[UK];
12332 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
12336 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
12337 ModAsSideEffect->push_back(std::make_pair(O,
U));
12339 U.UsageExpr = UsageExpr;
12349 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
12350 UsageKind OtherKind,
bool IsModMod) {
12354 const Usage &
U = UI.Uses[OtherKind];
12355 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
12358 const Expr *Mod =
U.UsageExpr;
12359 const Expr *ModOrUse = UsageExpr;
12360 if (OtherKind == UK_Use)
12361 std::swap(Mod, ModOrUse);
12365 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
12366 : diag::warn_unsequenced_mod_use)
12368 UI.Diagnosed =
true;
12397 void notePreUse(Object O,
const Expr *UseExpr) {
12398 UsageInfo &UI = UsageMap[O];
12400 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
12403 void notePostUse(Object O,
const Expr *UseExpr) {
12404 UsageInfo &UI = UsageMap[O];
12405 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
12407 addUsage(O, UI, UseExpr, UK_Use);
12410 void notePreMod(Object O,
const Expr *ModExpr) {
12411 UsageInfo &UI = UsageMap[O];
12413 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
12414 checkUsage(O, UI, ModExpr, UK_Use,
false);
12417 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
12418 UsageInfo &UI = UsageMap[O];
12419 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
12421 addUsage(O, UI, ModExpr, UK);
12425 SequenceChecker(
Sema &S,
const Expr *
E,
12427 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
12431 (void)this->WorkList;
12434 void VisitStmt(
const Stmt *S) {
12438 void VisitExpr(
const Expr *
E) {
12440 Base::VisitStmt(
E);
12444 for (
auto *Sub : CSE->
children()) {
12445 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
12460 void VisitCastExpr(
const CastExpr *
E) {
12462 if (
E->getCastKind() == CK_LValueToRValue)
12463 O = getObject(
E->getSubExpr(),
false);
12472 void VisitSequencedExpressions(
const Expr *SequencedBefore,
12473 const Expr *SequencedAfter) {
12474 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
12475 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
12476 SequenceTree::Seq OldRegion = Region;
12479 SequencedSubexpression SeqBefore(*
this);
12480 Region = BeforeRegion;
12481 Visit(SequencedBefore);
12484 Region = AfterRegion;
12485 Visit(SequencedAfter);
12487 Region = OldRegion;
12489 Tree.merge(BeforeRegion);
12490 Tree.merge(AfterRegion);
12498 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
12505 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12506 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12512 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12519 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12520 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12525 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12537 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12541 SequenceTree::Seq RHSRegion;
12542 SequenceTree::Seq LHSRegion;
12544 RHSRegion =
Tree.allocate(Region);
12545 LHSRegion =
Tree.allocate(Region);
12547 RHSRegion = Region;
12548 LHSRegion = Region;
12550 SequenceTree::Seq OldRegion = Region;
12566 SequencedSubexpression SeqBefore(*
this);
12567 Region = RHSRegion;
12571 Region = LHSRegion;
12574 if (O && isa<CompoundAssignOperator>(BO))
12575 notePostUse(O, BO);
12579 Region = LHSRegion;
12582 if (O && isa<CompoundAssignOperator>(BO))
12583 notePostUse(O, BO);
12585 Region = RHSRegion;
12593 Region = OldRegion;
12597 : UK_ModAsSideEffect);
12599 Tree.merge(RHSRegion);
12600 Tree.merge(LHSRegion);
12605 VisitBinAssign(CAO);
12608 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12609 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12613 return VisitExpr(UO);
12621 : UK_ModAsSideEffect);
12624 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12625 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12629 return VisitExpr(UO);
12633 notePostMod(O, UO, UK_ModAsSideEffect);
12642 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12643 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12644 SequenceTree::Seq OldRegion = Region;
12646 EvaluationTracker Eval(*
this);
12648 SequencedSubexpression Sequenced(*
this);
12649 Region = LHSRegion;
12656 bool EvalResult =
false;
12657 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12658 bool ShouldVisitRHS = !EvalOK || !EvalResult;
12659 if (ShouldVisitRHS) {
12660 Region = RHSRegion;
12664 Region = OldRegion;
12665 Tree.merge(LHSRegion);
12666 Tree.merge(RHSRegion);
12675 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12676 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12677 SequenceTree::Seq OldRegion = Region;
12679 EvaluationTracker Eval(*
this);
12681 SequencedSubexpression Sequenced(*
this);
12682 Region = LHSRegion;
12688 bool EvalResult =
false;
12689 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12690 bool ShouldVisitRHS = !EvalOK || EvalResult;
12691 if (ShouldVisitRHS) {
12692 Region = RHSRegion;
12696 Region = OldRegion;
12697 Tree.merge(LHSRegion);
12698 Tree.merge(RHSRegion);
12706 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
12722 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
12723 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
12724 SequenceTree::Seq OldRegion = Region;
12726 EvaluationTracker Eval(*
this);
12728 SequencedSubexpression Sequenced(*
this);
12729 Region = ConditionRegion;
12739 bool EvalResult =
false;
12740 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
12741 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
12742 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
12743 if (ShouldVisitTrueExpr) {
12744 Region = TrueRegion;
12747 if (ShouldVisitFalseExpr) {
12748 Region = FalseRegion;
12752 Region = OldRegion;
12753 Tree.merge(ConditionRegion);
12754 Tree.merge(TrueRegion);
12755 Tree.merge(FalseRegion);
12758 void VisitCallExpr(
const CallExpr *CE) {
12770 SequencedSubexpression Sequenced(*
this);
12775 SequenceTree::Seq CalleeRegion;
12776 SequenceTree::Seq OtherRegion;
12777 if (SemaRef.getLangOpts().CPlusPlus17) {
12778 CalleeRegion = Tree.allocate(Region);
12779 OtherRegion = Tree.allocate(Region);
12781 CalleeRegion = Region;
12782 OtherRegion = Region;
12784 SequenceTree::Seq OldRegion = Region;
12787 Region = CalleeRegion;
12789 SequencedSubexpression Sequenced(*this);
12790 Visit(CE->getCallee());
12792 Visit(CE->getCallee());
12796 Region = OtherRegion;
12800 Region = OldRegion;
12802 Tree.merge(CalleeRegion);
12803 Tree.merge(OtherRegion);
12821 return VisitCallExpr(CXXOCE);
12832 case OO_MinusEqual:
12834 case OO_SlashEqual:
12835 case OO_PercentEqual:
12836 case OO_CaretEqual:
12839 case OO_LessLessEqual:
12840 case OO_GreaterGreaterEqual:
12841 SequencingKind = RHSBeforeLHS;
12845 case OO_GreaterGreater:
12851 SequencingKind = LHSBeforeRHS;
12855 SequencingKind = LHSBeforeRest;
12859 SequencingKind = NoSequencing;
12863 if (SequencingKind == NoSequencing)
12864 return VisitCallExpr(CXXOCE);
12867 SequencedSubexpression Sequenced(*
this);
12870 assert(SemaRef.getLangOpts().CPlusPlus17 &&
12871 "Should only get there with C++17 and above!");
12872 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
12873 "Should only get there with an overloaded binary operator"
12874 " or an overloaded call operator!");
12876 if (SequencingKind == LHSBeforeRest) {
12877 assert(CXXOCE->getOperator() == OO_Call &&
12878 "We should only have an overloaded call operator here!");
12887 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
12888 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
12889 SequenceTree::Seq OldRegion = Region;
12891 assert(CXXOCE->getNumArgs() >= 1 &&
12892 "An overloaded call operator must have at least one argument"
12893 " for the postfix-expression!");
12894 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
12895 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
12896 CXXOCE->getNumArgs() - 1);
12900 Region = PostfixExprRegion;
12901 SequencedSubexpression Sequenced(*this);
12902 Visit(PostfixExpr);
12906 Region = ArgsRegion;
12907 for (const Expr *Arg : Args)
12910 Region = OldRegion;
12911 Tree.merge(PostfixExprRegion);
12912 Tree.merge(ArgsRegion);
12914 assert(CXXOCE->getNumArgs() == 2 &&
12915 "Should only have two arguments here!");
12916 assert((SequencingKind == LHSBeforeRHS ||
12917 SequencingKind == RHSBeforeLHS) &&
12918 "Unexpected sequencing kind!");
12922 const Expr *E1 = CXXOCE->getArg(0);
12923 const Expr *E2 = CXXOCE->getArg(1);
12924 if (SequencingKind == RHSBeforeLHS)
12927 return VisitSequencedExpressions(E1, E2);
12934 SequencedSubexpression Sequenced(*
this);
12937 return VisitExpr(CCE);
12940 SequenceExpressionsInOrder(
12946 return VisitExpr(ILE);
12949 SequenceExpressionsInOrder(ILE->
inits());
12961 SequenceTree::Seq
Parent = Region;
12962 for (
const Expr *
E : ExpressionList) {
12966 Elts.push_back(Region);
12972 for (
unsigned I = 0; I < Elts.size(); ++I)
12973 Tree.merge(Elts[I]);
12977SequenceChecker::UsageInfo::UsageInfo() =
default;
12981void Sema::CheckUnsequencedOperations(
const Expr *
E) {
12983 WorkList.push_back(
E);
12984 while (!WorkList.empty()) {
12985 const Expr *Item = WorkList.pop_back_val();
12986 SequenceChecker(*
this, Item, WorkList);
12991 bool IsConstexpr) {
12993 IsConstexpr || isa<ConstantExpr>(
E));
12994 CheckImplicitConversions(
E, CheckLoc);
12996 CheckUnsequencedOperations(
E);
12998 CheckForIntOverflow(
E);
13012 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
13016 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
13020 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
13034 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
13038 bool CheckParameterNames) {
13039 bool HasInvalidParm =
false;
13041 assert(Param &&
"null in a parameter list");
13050 if (!Param->isInvalidDecl() &&
13052 diag::err_typecheck_decl_incomplete_type) ||
13054 diag::err_abstract_type_in_decl,
13056 Param->setInvalidDecl();
13057 HasInvalidParm =
true;
13062 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
13066 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
13074 QualType PType = Param->getOriginalType();
13082 if (!Param->isInvalidDecl()) {
13084 if (!ClassDecl->isInvalidDecl() &&
13085 !ClassDecl->hasIrrelevantDestructor() &&
13086 !ClassDecl->isDependentContext() &&
13087 ClassDecl->isParamDestroyedInCallee()) {
13099 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
13100 if (!Param->getType().isConstQualified())
13101 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
13105 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
13110 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
13111 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
13116 if (!Param->isInvalidDecl() &&
13118 Param->setInvalidDecl();
13119 HasInvalidParm =
true;
13120 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
13124 return HasInvalidParm;
13127std::optional<std::pair<
13136static std::pair<CharUnits, CharUnits>
13144 if (
Base->isVirtual()) {
13151 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
13158 DerivedType =
Base->getType();
13161 return std::make_pair(BaseAlignment, Offset);
13165static std::optional<std::pair<CharUnits, CharUnits>>
13171 return std::nullopt;
13176 return std::nullopt;
13180 CharUnits Offset = EltSize * IdxRes->getExtValue();
13183 return std::make_pair(
P->first,
P->second + Offset);
13189 return std::make_pair(
13190 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
13196std::optional<std::pair<
13204 case Stmt::CStyleCastExprClass:
13205 case Stmt::CXXStaticCastExprClass:
13206 case Stmt::ImplicitCastExprClass: {
13207 auto *CE = cast<CastExpr>(
E);
13208 const Expr *From = CE->getSubExpr();
13209 switch (CE->getCastKind()) {
13214 case CK_UncheckedDerivedToBase:
13215 case CK_DerivedToBase: {
13225 case Stmt::ArraySubscriptExprClass: {
13226 auto *ASE = cast<ArraySubscriptExpr>(
E);
13230 case Stmt::DeclRefExprClass: {
13231 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
13234 if (!VD->getType()->isReferenceType()) {
13236 if (VD->hasDependentAlignment())
13245 case Stmt::MemberExprClass: {
13246 auto *ME = cast<MemberExpr>(
E);
13247 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
13251 std::optional<std::pair<CharUnits, CharUnits>>
P;
13260 return std::make_pair(
P->first,
13263 case Stmt::UnaryOperatorClass: {
13264 auto *UO = cast<UnaryOperator>(
E);
13273 case Stmt::BinaryOperatorClass: {
13274 auto *BO = cast<BinaryOperator>(
E);
13285 return std::nullopt;
13290std::optional<std::pair<
13299 case Stmt::CStyleCastExprClass:
13300 case Stmt::CXXStaticCastExprClass:
13301 case Stmt::ImplicitCastExprClass: {
13302 auto *CE = cast<CastExpr>(
E);
13303 const Expr *From = CE->getSubExpr();
13304 switch (CE->getCastKind()) {
13309 case CK_ArrayToPointerDecay:
13311 case CK_UncheckedDerivedToBase:
13312 case CK_DerivedToBase: {
13322 case Stmt::CXXThisExprClass: {
13327 case Stmt::UnaryOperatorClass: {
13328 auto *UO = cast<UnaryOperator>(
E);
13333 case Stmt::BinaryOperatorClass: {
13334 auto *BO = cast<BinaryOperator>(
E);
13342 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
13343 std::swap(LHS, RHS);
13353 return std::nullopt;
13358 std::optional<std::pair<CharUnits, CharUnits>>
P =
13362 return P->first.alignmentAtOffset(
P->second);
13380 if (!DestPtr)
return;
13386 if (DestAlign.
isOne())
return;
13390 if (!SrcPtr)
return;
13401 if (SrcAlign >= DestAlign)
return;
13406 <<
static_cast<unsigned>(DestAlign.
getQuantity())
13410void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
13412 bool AllowOnePastEnd,
bool IndexNegated) {
13421 const Type *EffectiveType =
13428 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
13430 const Type *BaseType =
13432 bool IsUnboundedArray =
13434 Context, StrictFlexArraysLevel,
13444 llvm::APSInt index =
Result.Val.getInt();
13445 if (IndexNegated) {
13446 index.setIsUnsigned(
false);
13450 if (IsUnboundedArray) {
13453 if (index.isUnsigned() || !index.isNegative()) {
13455 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
13457 if (index.getBitWidth() < AddrBits)
13458 index = index.zext(AddrBits);
13459 std::optional<CharUnits> ElemCharUnits =
13460 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
13463 if (!ElemCharUnits || ElemCharUnits->isZero())
13465 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
13470 if (index.getActiveBits() <= AddrBits) {
13472 llvm::APInt Product(index);
13474 Product = Product.umul_ov(ElemBytes, Overflow);
13475 if (!Overflow && Product.getActiveBits() <= AddrBits)
13481 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
13482 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
13484 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
13485 MaxElems = MaxElems.udiv(ElemBytes);
13488 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
13489 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
13495 <<
toString(index, 10,
true) << AddrBits
13496 << (
unsigned)ASTC.toBits(*ElemCharUnits)
13499 << (
unsigned)MaxElems.getLimitedValue(~0
U)
13504 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13506 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13508 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13509 ND = ME->getMemberDecl();
13513 PDiag(diag::note_array_declared_here) << ND);
13518 if (index.isUnsigned() || !index.isNegative()) {
13528 llvm::APInt size = ArrayTy->
getSize();
13530 if (BaseType != EffectiveType) {
13538 if (!ptrarith_typesize)
13541 if (ptrarith_typesize != array_typesize) {
13543 uint64_t ratio = array_typesize / ptrarith_typesize;
13547 if (ptrarith_typesize * ratio == array_typesize)
13548 size *= llvm::APInt(size.getBitWidth(), ratio);
13552 if (size.getBitWidth() > index.getBitWidth())
13553 index = index.zext(size.getBitWidth());
13554 else if (size.getBitWidth() < index.getBitWidth())
13555 size = size.zext(index.getBitWidth());
13561 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
13578 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
13579 : diag::warn_ptr_arith_exceeds_bounds;
13580 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
13588 unsigned DiagID = diag::warn_array_index_precedes_bounds;
13590 DiagID = diag::warn_ptr_arith_precedes_bounds;
13591 if (index.isNegative()) index = -index;
13601 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13603 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13605 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13606 ND = ME->getMemberDecl();
13610 PDiag(diag::note_array_declared_here) << ND);
13613void Sema::CheckArrayAccess(
const Expr *
expr) {
13614 int AllowOnePastEnd = 0;
13616 expr =
expr->IgnoreParenImpCasts();
13617 switch (
expr->getStmtClass()) {
13618 case Stmt::ArraySubscriptExprClass: {
13621 AllowOnePastEnd > 0);
13625 case Stmt::MemberExprClass: {
13626 expr = cast<MemberExpr>(
expr)->getBase();
13629 case Stmt::ArraySectionExprClass: {
13635 nullptr, AllowOnePastEnd > 0);
13638 case Stmt::UnaryOperatorClass: {
13654 case Stmt::ConditionalOperatorClass: {
13657 CheckArrayAccess(lhs);
13659 CheckArrayAccess(rhs);
13662 case Stmt::CXXOperatorCallExprClass: {
13663 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
13664 for (
const auto *Arg : OCE->arguments())
13665 CheckArrayAccess(Arg);
13675 Expr *RHS,
bool isProperty) {
13687 S.
Diag(
Loc, diag::warn_arc_literal_assign)
13689 << (isProperty ? 0 : 1)
13697 Expr *RHS,
bool isProperty) {
13700 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13701 S.
Diag(
Loc, diag::warn_arc_retained_assign)
13703 << (isProperty ? 0 : 1)
13707 RHS =
cast->getSubExpr();
13778 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13779 Diag(
Loc, diag::warn_arc_retained_property_assign)
13783 RHS =
cast->getSubExpr();
13806 bool StmtLineInvalid;
13809 if (StmtLineInvalid)
13812 bool BodyLineInvalid;
13815 if (BodyLineInvalid)
13819 if (StmtLine != BodyLine)
13834 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13843 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13847 const Stmt *PossibleBody) {
13853 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
13854 StmtLoc = FS->getRParenLoc();
13855 Body = FS->getBody();
13856 DiagID = diag::warn_empty_for_body;
13857 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
13858 StmtLoc = WS->getRParenLoc();
13859 Body = WS->getBody();
13860 DiagID = diag::warn_empty_while_body;
13865 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13888 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
13889 if (!ProbableTypo) {
13890 bool BodyColInvalid;
13893 if (BodyColInvalid)
13896 bool StmtColInvalid;
13899 if (StmtColInvalid)
13902 if (BodyCol > StmtCol)
13903 ProbableTypo =
true;
13906 if (ProbableTypo) {
13908 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13916 if (
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
13928 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
13930 RHSExpr = CE->
getArg(0);
13931 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
13932 CXXSCE && CXXSCE->isXValue())
13933 RHSExpr = CXXSCE->getSubExpr();
13937 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
13938 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
13941 if (LHSDeclRef && RHSDeclRef) {
13948 auto D =
Diag(OpLoc, diag::warn_self_move)
13964 const Expr *LHSBase = LHSExpr;
13965 const Expr *RHSBase = RHSExpr;
13966 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
13967 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
13968 if (!LHSME || !RHSME)
13971 while (LHSME && RHSME) {
13978 LHSME = dyn_cast<MemberExpr>(LHSBase);
13979 RHSME = dyn_cast<MemberExpr>(RHSBase);
13982 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
13983 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
13984 if (LHSDeclRef && RHSDeclRef) {
13991 Diag(OpLoc, diag::warn_self_move)
13997 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
13998 Diag(OpLoc, diag::warn_self_move)
14022 bool AreUnionMembers =
false) {
14023 [[maybe_unused]]
const Type *Field1Parent =
14025 [[maybe_unused]]
const Type *Field2Parent =
14030 "Can't evaluate layout compatibility between a struct field and a "
14033 (AreUnionMembers && Field1Parent->
isUnionType())) &&
14034 "AreUnionMembers should be 'true' for union fields (only).");
14047 if (Bits1 != Bits2)
14051 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
14052 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
14055 if (!AreUnionMembers &&
14067 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
14068 RD1 = D1CXX->getStandardLayoutBaseWithFields();
14070 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
14071 RD2 = D2CXX->getStandardLayoutBaseWithFields();
14076 return isLayoutCompatible(C, F1, F2);
14085 for (
auto *Field2 : RD2->
fields())
14086 UnmatchedFields.insert(Field2);
14088 for (
auto *Field1 : RD1->
fields()) {
14089 auto I = UnmatchedFields.begin();
14090 auto E = UnmatchedFields.end();
14092 for ( ; I !=
E; ++I) {
14094 bool Result = UnmatchedFields.erase(*I);
14104 return UnmatchedFields.empty();
14130 if (
C.hasSameType(T1, T2))
14139 if (TC1 == Type::Enum) {
14141 cast<EnumType>(T1)->getDecl(),
14142 cast<EnumType>(T2)->getDecl());
14143 }
else if (TC1 == Type::Record) {
14148 cast<RecordType>(T1)->getDecl(),
14149 cast<RecordType>(T2)->getDecl());
14163 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
14194 const ValueDecl **VD, uint64_t *MagicValue,
14195 bool isConstantEvaluated) {
14203 case Stmt::UnaryOperatorClass: {
14212 case Stmt::DeclRefExprClass: {
14213 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
14218 case Stmt::IntegerLiteralClass: {
14220 llvm::APInt MagicValueAPInt = IL->
getValue();
14221 if (MagicValueAPInt.getActiveBits() <= 64) {
14222 *MagicValue = MagicValueAPInt.getZExtValue();
14228 case Stmt::BinaryConditionalOperatorClass:
14229 case Stmt::ConditionalOperatorClass: {
14231 cast<AbstractConditionalOperator>(TypeExpr);
14234 isConstantEvaluated)) {
14244 case Stmt::BinaryOperatorClass: {
14247 TypeExpr = BO->
getRHS();
14277 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
14280 bool isConstantEvaluated) {
14281 FoundWrongKind =
false;
14286 uint64_t MagicValue;
14288 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
14292 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
14293 if (I->getArgumentKind() != ArgumentKind) {
14294 FoundWrongKind =
true;
14297 TypeInfo.Type = I->getMatchingCType();
14298 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
14299 TypeInfo.MustBeNull = I->getMustBeNull();
14310 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
14311 if (I == MagicValues->end())
14320 bool LayoutCompatible,
14322 if (!TypeTagForDatatypeMagicValues)
14323 TypeTagForDatatypeMagicValues.reset(
14324 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
14327 (*TypeTagForDatatypeMagicValues)[Magic] =
14343 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
14344 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
14345 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
14346 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
14349void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
14353 bool IsPointerAttr =
Attr->getIsPointer();
14356 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
14357 if (TypeTagIdxAST >= ExprArgs.size()) {
14358 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14359 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
14362 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
14363 bool FoundWrongKind;
14366 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
14368 if (FoundWrongKind)
14370 diag::warn_type_tag_for_datatype_wrong_kind)
14376 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
14377 if (ArgumentIdxAST >= ExprArgs.size()) {
14378 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14379 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
14382 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
14383 if (IsPointerAttr) {
14385 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
14386 if (ICE->getType()->isVoidPointerType() &&
14387 ICE->getCastKind() == CK_BitCast)
14388 ArgumentExpr = ICE->getSubExpr();
14401 diag::warn_type_safety_null_pointer_required)
14413 bool mismatch =
false;
14436 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
14437 << ArgumentType << ArgumentKind
14438 <<
TypeInfo.LayoutCompatible << RequiredType
14445 MisalignedMembers.emplace_back(
E, RD, MD, Alignment);
14449 for (MisalignedMember &m : MisalignedMembers) {
14455 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
14458 MisalignedMembers.clear();
14465 if (isa<UnaryOperator>(
E) &&
14466 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
14467 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
14468 if (isa<MemberExpr>(Op)) {
14469 auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
14470 if (MA != MisalignedMembers.end() &&
14475 MisalignedMembers.erase(MA);
14484 const auto *ME = dyn_cast<MemberExpr>(
E);
14496 bool AnyIsPacked =
false;
14498 QualType BaseType = ME->getBase()->getType();
14508 auto *FD = dyn_cast<FieldDecl>(MD);
14514 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
14515 ReverseMemberChain.push_back(FD);
14518 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
14520 assert(TopME &&
"We did not compute a topmost MemberExpr!");
14527 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
14531 if (!DRE && !isa<CXXThisExpr>(TopBase))
14538 if (ExpectedAlignment.
isOne())
14543 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
14548 ReverseMemberChain.back()->getParent()->getTypeForDecl());
14552 if (DRE && !TopME->
isArrow()) {
14555 CompleteObjectAlignment =
14560 if (Offset % ExpectedAlignment != 0 ||
14563 CompleteObjectAlignment < ExpectedAlignment) {
14574 for (
FieldDecl *FDI : ReverseMemberChain) {
14575 if (FDI->hasAttr<PackedAttr>() ||
14576 FDI->getParent()->hasAttr<PackedAttr>()) {
14578 Alignment = std::min(
14584 assert(FD &&
"We did not find a packed FieldDecl!");
14589void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
14590 using namespace std::placeholders;
14593 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
14615bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
bool FPOnly) {
14629 TheCall->
setType(VecTy0->getElementType());
14653 diag::err_typecheck_call_different_arg_types)
14670 bool CheckForFloatArgs) {
14675 for (
int I = 0; I < 3; ++I) {
14679 Args[I] = Converted.
get();
14682 if (CheckForFloatArgs) {
14683 int ArgOrdinal = 1;
14684 for (
Expr *Arg : Args) {
14686 Arg->
getType(), ArgOrdinal++))
14690 int ArgOrdinal = 1;
14691 for (
Expr *Arg : Args) {
14698 for (
int I = 1; I < 3; ++I) {
14699 if (Args[0]->getType().getCanonicalType() !=
14700 Args[I]->getType().getCanonicalType()) {
14701 return Diag(Args[0]->getBeginLoc(),
14702 diag::err_typecheck_call_different_arg_types)
14706 TheCall->
setArg(I, Args[I]);
14709 TheCall->
setType(Args[0]->getType());
14713bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
14725bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
14734 << 1 << 0 << TyArg;
14748 Expr *Matrix = MatrixArg.
get();
14753 << 1 << 1 << Matrix->
getType();
14760 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
14763 TheCall->
setType(ResultType);
14766 TheCall->
setArg(0, Matrix);
14771static std::optional<unsigned>
14774 std::optional<llvm::APSInt>
Value =
14781 uint64_t
Dim =
Value->getZExtValue();
14800 unsigned PtrArgIdx = 0;
14806 bool ArgError =
false;
14813 PtrExpr = PtrConv.
get();
14814 TheCall->
setArg(0, PtrExpr);
14825 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14832 << PtrArgIdx + 1 << 2
14839 auto ApplyArgumentConversions = [
this](
Expr *
E) {
14848 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
14850 RowsExpr = RowsConv.
get();
14851 TheCall->
setArg(1, RowsExpr);
14853 RowsExpr =
nullptr;
14855 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
14857 ColumnsExpr = ColumnsConv.
get();
14858 TheCall->
setArg(2, ColumnsExpr);
14860 ColumnsExpr =
nullptr;
14871 std::optional<unsigned> MaybeRows;
14875 std::optional<unsigned> MaybeColumns;
14880 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
14883 StrideExpr = StrideConv.
get();
14884 TheCall->
setArg(3, StrideExpr);
14887 if (std::optional<llvm::APSInt>
Value =
14890 if (Stride < *MaybeRows) {
14892 diag::err_builtin_matrix_stride_too_small);
14898 if (ArgError || !MaybeRows || !MaybeColumns)
14911 unsigned PtrArgIdx = 1;
14916 bool ArgError =
false;
14922 MatrixExpr = MatrixConv.
get();
14923 TheCall->
setArg(0, MatrixExpr);
14933 << 1 << 1 << MatrixExpr->
getType();
14941 PtrExpr = PtrConv.
get();
14942 TheCall->
setArg(1, PtrExpr);
14953 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14958 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
14965 diag::err_builtin_matrix_pointer_arg_mismatch)
14966 << ElementTy << MatrixTy->getElementType();
14981 StrideExpr = StrideConv.
get();
14982 TheCall->
setArg(2, StrideExpr);
14987 if (std::optional<llvm::APSInt>
Value =
14990 if (Stride < MatrixTy->getNumRows()) {
14992 diag::err_builtin_matrix_stride_too_small);
15012 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
15017 llvm::StringSet<> CalleeTCBs;
15018 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
15019 CalleeTCBs.insert(A->getTCBName());
15020 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
15021 CalleeTCBs.insert(A->getTCBName());
15025 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
15026 StringRef CallerTCB = A->getTCBName();
15027 if (CalleeTCBs.count(CallerTCB) == 0) {
15028 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
15029 << 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 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 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 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 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.
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
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 ASTContext &Ctx) 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()
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 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
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
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...
bool BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly=false)
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 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.
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
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...
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
unsigned NumCallArgs
The number of expressions in CallArgs.
const Expr *const * CallArgs
The list of argument expressions in a synthesized call.
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.