80#include "llvm/ADT/APFloat.h"
81#include "llvm/ADT/APInt.h"
82#include "llvm/ADT/APSInt.h"
83#include "llvm/ADT/ArrayRef.h"
84#include "llvm/ADT/DenseMap.h"
85#include "llvm/ADT/FoldingSet.h"
86#include "llvm/ADT/STLExtras.h"
87#include "llvm/ADT/SmallBitVector.h"
88#include "llvm/ADT/SmallPtrSet.h"
89#include "llvm/ADT/SmallString.h"
90#include "llvm/ADT/SmallVector.h"
91#include "llvm/ADT/StringExtras.h"
92#include "llvm/ADT/StringRef.h"
93#include "llvm/ADT/StringSet.h"
94#include "llvm/ADT/StringSwitch.h"
95#include "llvm/Support/AtomicOrdering.h"
96#include "llvm/Support/Casting.h"
97#include "llvm/Support/Compiler.h"
98#include "llvm/Support/ConvertUTF.h"
99#include "llvm/Support/ErrorHandling.h"
100#include "llvm/Support/Format.h"
101#include "llvm/Support/Locale.h"
102#include "llvm/Support/MathExtras.h"
103#include "llvm/Support/SaveAndRestore.h"
104#include "llvm/Support/raw_ostream.h"
105#include "llvm/TargetParser/RISCVTargetParser.h"
106#include "llvm/TargetParser/Triple.h"
120using namespace clang;
124 unsigned ByteNo)
const {
135 unsigned ArgCount =
Call->getNumArgs();
136 if (ArgCount >= MinArgCount)
139 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
140 << 0 << MinArgCount << ArgCount
141 << 0 <<
Call->getSourceRange();
145 unsigned ArgCount =
Call->getNumArgs();
146 if (ArgCount <= MaxArgCount)
148 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
149 << 0 << MaxArgCount << ArgCount
150 << 0 <<
Call->getSourceRange();
154 unsigned MaxArgCount) {
160 unsigned ArgCount =
Call->getNumArgs();
161 if (ArgCount == DesiredArgCount)
166 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
170 Call->getArg(ArgCount - 1)->getEndLoc());
173 << 0 << DesiredArgCount << ArgCount
174 << 0 <<
Call->getArg(1)->getSourceRange();
178 bool HasError =
false;
180 for (
unsigned I = 0; I <
Call->getNumArgs(); ++I) {
187 int DiagMsgKind = -1;
189 if (!ArgString.has_value())
191 else if (ArgString->find(
'$') != std::string::npos)
194 if (DiagMsgKind >= 0) {
205 if (
Value->isTypeDependent())
236 if (!Literal || !Literal->isOrdinary()) {
249 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
257 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
258 if (!Literal || !Literal->isWide()) {
259 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
260 << Arg->getSourceRange();
294 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
325 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
327 auto IsValidIntegerType = [](
QualType Ty) {
328 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
335 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
339 S.
Diag(Source->
getExprLoc(), diag::err_typecheck_expect_scalar_operand)
345 if (!IsValidIntegerType(AlignOp->
getType())) {
356 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
357 llvm::APSInt MaxValue(
358 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
359 if (AlignValue < 1) {
360 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
363 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
368 if (!AlignValue.isPowerOf2()) {
369 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
372 if (AlignValue == 1) {
373 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
374 << IsBooleanAlignBuiltin;
402 std::pair<unsigned, const char *> Builtins[] = {
403 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
404 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
405 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
408 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
410 return BuiltinID ==
P.first && TheCall->
getExprLoc().isMacroID() &&
415 auto ValidCkdIntType = [](
QualType QT) {
418 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
419 return (BT->getKind() >= BuiltinType::Short &&
420 BT->getKind() <= BuiltinType::Int128) || (
421 BT->getKind() >= BuiltinType::UShort &&
422 BT->getKind() <= BuiltinType::UInt128) ||
423 BT->getKind() == BuiltinType::UChar ||
424 BT->getKind() == BuiltinType::SChar;
429 for (
unsigned I = 0; I < 2; ++I) {
435 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
454 !PtrTy->getPointeeType()->isIntegerType() ||
455 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
456 PtrTy->getPointeeType().isConstQualified()) {
458 diag::err_overflow_builtin_must_be_ptr_int)
466 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
467 for (
unsigned I = 0; I < 3; ++I) {
468 const auto Arg = TheCall->
getArg(I);
471 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
473 return S.
Diag(Arg->getBeginLoc(),
474 diag::err_overflow_builtin_bit_int_max_size)
483struct BuiltinDumpStructGenerator {
492 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
493 Policy(S.Context.getPrintingPolicy()) {
497 Expr *makeOpaqueValueExpr(
Expr *Inner) {
500 Inner->getObjectKind(), Inner);
501 Actions.push_back(OVE);
505 Expr *getStringLiteral(llvm::StringRef Str) {
511 bool callPrintFunction(llvm::StringRef Format,
515 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
517 Args.push_back(getStringLiteral(Format));
518 Args.insert(Args.end(), Exprs.begin(), Exprs.end());
534 Actions.push_back(RealCall.
get());
540 Expr *getIndentString(
unsigned Depth) {
546 return getStringLiteral(Indent);
550 return getStringLiteral(
T.getAsString(Policy));
554 llvm::raw_svector_ostream OS(Str);
559 switch (BT->getKind()) {
560 case BuiltinType::Bool:
563 case BuiltinType::Char_U:
564 case BuiltinType::UChar:
567 case BuiltinType::Char_S:
568 case BuiltinType::SChar:
580 analyze_printf::PrintfConversionSpecifier::sArg) {
606 bool dumpUnnamedRecord(
const RecordDecl *RD,
Expr *
E,
unsigned Depth) {
607 Expr *IndentLit = getIndentString(Depth);
609 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
610 : callPrintFunction(
"%s", {TypeLit}))
613 return dumpRecordValue(RD,
E, IndentLit, Depth);
626 Expr *RecordArg = makeOpaqueValueExpr(
E);
629 if (callPrintFunction(
" {\n"))
633 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
634 for (
const auto &
Base : CXXRD->bases()) {
642 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
648 Expr *FieldIndentArg = getIndentString(Depth + 1);
651 for (
auto *
D : RD->
decls()) {
652 auto *IFD = dyn_cast<IndirectFieldDecl>(
D);
653 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(
D);
654 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
660 getStringLiteral(FD->getName())};
662 if (FD->isBitField()) {
666 FD->getBitWidthValue(S.
Context));
680 if (
Field.isInvalid())
683 auto *InnerRD = FD->getType()->getAsRecordDecl();
684 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
685 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
687 if (callPrintFunction(Format, Args) ||
688 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
692 if (appendFormatSpecifier(FD->getType(), Format)) {
694 Args.push_back(
Field.get());
704 Args.push_back(FieldAddr.
get());
707 if (callPrintFunction(Format, Args))
712 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
713 : callPrintFunction(
"}\n");
716 Expr *buildWrapper() {
719 TheCall->
setType(Wrapper->getType());
740 diag::err_expected_struct_pointer_argument)
749 diag::err_incomplete_type))
758 switch (BT ? BT->getKind() : BuiltinType::Void) {
759 case BuiltinType::Dependent:
760 case BuiltinType::Overload:
761 case BuiltinType::BoundMember:
762 case BuiltinType::PseudoObject:
763 case BuiltinType::UnknownAny:
764 case BuiltinType::BuiltinFn:
770 diag::err_expected_callable_argument)
776 BuiltinDumpStructGenerator Generator(S, TheCall);
782 Expr *PtrArg = PtrArgResult.
get();
786 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
789 return Generator.buildWrapper();
801 if (
Call->getStmtClass() != Stmt::CallExprClass) {
802 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
803 <<
Call->getSourceRange();
807 auto CE = cast<CallExpr>(
Call);
808 if (CE->getCallee()->getType()->isBlockPointerType()) {
809 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
810 <<
Call->getSourceRange();
814 const Decl *TargetDecl = CE->getCalleeDecl();
815 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
816 if (FD->getBuiltinID()) {
817 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
818 <<
Call->getSourceRange();
822 if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {
823 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
824 <<
Call->getSourceRange();
832 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
846 BuiltinCall->
setType(CE->getType());
850 BuiltinCall->
setArg(1, ChainResult.
get());
857class ScanfDiagnosticFormatHandler
861 using ComputeSizeFunction =
862 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
866 using DiagnoseFunction =
867 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
869 ComputeSizeFunction ComputeSizeArgument;
870 DiagnoseFunction Diagnose;
873 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
874 DiagnoseFunction Diagnose)
875 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
878 const char *StartSpecifier,
879 unsigned specifierLen)
override {
880 if (!FS.consumesDataArgument())
883 unsigned NulByte = 0;
884 switch ((FS.getConversionSpecifier().getKind())) {
897 analyze_format_string::OptionalAmount::HowSpecified::Constant)
902 std::optional<llvm::APSInt> DestSizeAPS =
903 ComputeSizeArgument(FS.getArgIndex());
907 unsigned DestSize = DestSizeAPS->getZExtValue();
909 if (DestSize < SourceSize)
910 Diagnose(FS.getArgIndex(), DestSize, SourceSize);
916class EstimateSizeFormatHandler
921 bool IsKernelCompatible =
true;
924 EstimateSizeFormatHandler(StringRef Format)
925 :
Size(
std::
min(Format.find(0), Format.size()) +
929 const char *,
unsigned SpecifierLen,
932 const size_t FieldWidth = computeFieldWidth(FS);
933 const size_t Precision = computePrecision(FS);
936 switch (FS.getConversionSpecifier().getKind()) {
940 Size += std::max(FieldWidth, (
size_t)1);
952 Size += std::max(FieldWidth, Precision);
968 Size += std::max(FieldWidth, 1 +
969 (Precision ? 1 + Precision
979 (Precision ? 1 + Precision : 0) +
989 (Precision ? 1 + Precision : 0) +
1004 IsKernelCompatible =
false;
1005 Size += std::max(FieldWidth, 2 + Precision);
1017 Size += FS.hasPlusPrefix() || FS.hasSpacePrefix();
1019 if (FS.hasAlternativeForm()) {
1020 switch (FS.getConversionSpecifier().getKind()) {
1049 Size += (Precision ? 0 : 1);
1056 assert(SpecifierLen <= Size &&
"no underflow");
1057 Size -= SpecifierLen;
1061 size_t getSizeLowerBound()
const {
return Size; }
1062 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1067 size_t FieldWidth = 0;
1075 size_t Precision = 0;
1080 switch (FS.getConversionSpecifier().getKind()) {
1122 StringRef &FormatStrRef,
size_t &StrLen,
1124 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1125 Format && (Format->isOrdinary() || Format->isUTF8())) {
1126 FormatStrRef = Format->getString();
1129 assert(
T &&
"String literal not of constant array type!");
1130 size_t TypeSize =
T->getZExtSize();
1132 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1138void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1144 bool UseDABAttr =
false;
1147 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1149 UseDecl = DABAttr->getFunction();
1150 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1162 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1169 unsigned DABIndices = DABAttr->argIndices_size();
1170 unsigned NewIndex = Index < DABIndices
1171 ? DABAttr->argIndices_begin()[Index]
1174 return std::nullopt;
1178 auto ComputeExplicitObjectSizeArgument =
1179 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1180 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1182 return std::nullopt;
1183 unsigned NewIndex = *IndexOptional;
1187 return std::nullopt;
1193 auto ComputeSizeArgument =
1194 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1200 if (Index < FD->getNumParams()) {
1201 if (
const auto *POS =
1203 BOSType = POS->getType();
1206 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1208 return std::nullopt;
1209 unsigned NewIndex = *IndexOptional;
1212 return std::nullopt;
1214 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1217 return std::nullopt;
1220 return llvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1223 auto ComputeStrLenArgument =
1224 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1225 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1227 return std::nullopt;
1228 unsigned NewIndex = *IndexOptional;
1230 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1233 return std::nullopt;
1235 return llvm::APSInt::getUnsigned(
Result + 1).extOrTrunc(SizeTypeWidth);
1238 std::optional<llvm::APSInt> SourceSize;
1239 std::optional<llvm::APSInt> DestinationSize;
1240 unsigned DiagID = 0;
1241 bool IsChkVariant =
false;
1243 auto GetFunctionName = [&]() {
1249 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1250 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1252 FunctionName.consume_front(
"__builtin_");
1254 return FunctionName;
1257 switch (BuiltinID) {
1260 case Builtin::BI__builtin_strcpy:
1261 case Builtin::BIstrcpy: {
1262 DiagID = diag::warn_fortify_strlen_overflow;
1263 SourceSize = ComputeStrLenArgument(1);
1264 DestinationSize = ComputeSizeArgument(0);
1268 case Builtin::BI__builtin___strcpy_chk: {
1269 DiagID = diag::warn_fortify_strlen_overflow;
1270 SourceSize = ComputeStrLenArgument(1);
1271 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1272 IsChkVariant =
true;
1276 case Builtin::BIscanf:
1277 case Builtin::BIfscanf:
1278 case Builtin::BIsscanf: {
1279 unsigned FormatIndex = 1;
1280 unsigned DataIndex = 2;
1281 if (BuiltinID == Builtin::BIscanf) {
1286 const auto *FormatExpr =
1289 StringRef FormatStrRef;
1294 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1295 unsigned SourceSize) {
1296 DiagID = diag::warn_fortify_scanf_overflow;
1297 unsigned Index = ArgIndex + DataIndex;
1298 StringRef FunctionName = GetFunctionName();
1300 PDiag(DiagID) << FunctionName << (Index + 1)
1301 << DestSize << SourceSize);
1304 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1305 return ComputeSizeArgument(Index + DataIndex);
1307 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1308 const char *FormatBytes = FormatStrRef.data();
1319 case Builtin::BIsprintf:
1320 case Builtin::BI__builtin___sprintf_chk: {
1321 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1324 StringRef FormatStrRef;
1327 EstimateSizeFormatHandler H(FormatStrRef);
1328 const char *FormatBytes = FormatStrRef.data();
1330 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1332 DiagID = H.isKernelCompatible()
1333 ? diag::warn_format_overflow
1334 : diag::warn_format_overflow_non_kprintf;
1335 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1336 .extOrTrunc(SizeTypeWidth);
1337 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1338 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1339 IsChkVariant =
true;
1341 DestinationSize = ComputeSizeArgument(0);
1348 case Builtin::BI__builtin___memcpy_chk:
1349 case Builtin::BI__builtin___memmove_chk:
1350 case Builtin::BI__builtin___memset_chk:
1351 case Builtin::BI__builtin___strlcat_chk:
1352 case Builtin::BI__builtin___strlcpy_chk:
1353 case Builtin::BI__builtin___strncat_chk:
1354 case Builtin::BI__builtin___strncpy_chk:
1355 case Builtin::BI__builtin___stpncpy_chk:
1356 case Builtin::BI__builtin___memccpy_chk:
1357 case Builtin::BI__builtin___mempcpy_chk: {
1358 DiagID = diag::warn_builtin_chk_overflow;
1359 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1361 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1362 IsChkVariant =
true;
1366 case Builtin::BI__builtin___snprintf_chk:
1367 case Builtin::BI__builtin___vsnprintf_chk: {
1368 DiagID = diag::warn_builtin_chk_overflow;
1369 SourceSize = ComputeExplicitObjectSizeArgument(1);
1370 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1371 IsChkVariant =
true;
1375 case Builtin::BIstrncat:
1376 case Builtin::BI__builtin_strncat:
1377 case Builtin::BIstrncpy:
1378 case Builtin::BI__builtin_strncpy:
1379 case Builtin::BIstpncpy:
1380 case Builtin::BI__builtin_stpncpy: {
1386 DiagID = diag::warn_fortify_source_size_mismatch;
1387 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1388 DestinationSize = ComputeSizeArgument(0);
1392 case Builtin::BImemcpy:
1393 case Builtin::BI__builtin_memcpy:
1394 case Builtin::BImemmove:
1395 case Builtin::BI__builtin_memmove:
1396 case Builtin::BImemset:
1397 case Builtin::BI__builtin_memset:
1398 case Builtin::BImempcpy:
1399 case Builtin::BI__builtin_mempcpy: {
1400 DiagID = diag::warn_fortify_source_overflow;
1401 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1402 DestinationSize = ComputeSizeArgument(0);
1405 case Builtin::BIsnprintf:
1406 case Builtin::BI__builtin_snprintf:
1407 case Builtin::BIvsnprintf:
1408 case Builtin::BI__builtin_vsnprintf: {
1409 DiagID = diag::warn_fortify_source_size_mismatch;
1410 SourceSize = ComputeExplicitObjectSizeArgument(1);
1412 StringRef FormatStrRef;
1416 EstimateSizeFormatHandler H(FormatStrRef);
1417 const char *FormatBytes = FormatStrRef.data();
1419 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1421 llvm::APSInt FormatSize =
1422 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1423 .extOrTrunc(SizeTypeWidth);
1424 if (FormatSize > *SourceSize && *SourceSize != 0) {
1425 unsigned TruncationDiagID =
1426 H.isKernelCompatible() ? diag::warn_format_truncation
1427 : diag::warn_format_truncation_non_kprintf;
1430 SourceSize->toString(SpecifiedSizeStr, 10);
1431 FormatSize.toString(FormatSizeStr, 10);
1433 PDiag(TruncationDiagID)
1434 << GetFunctionName() << SpecifiedSizeStr
1439 DestinationSize = ComputeSizeArgument(0);
1443 if (!SourceSize || !DestinationSize ||
1444 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1447 StringRef FunctionName = GetFunctionName();
1451 DestinationSize->toString(DestinationStr, 10);
1452 SourceSize->toString(SourceStr, 10);
1455 << FunctionName << DestinationStr << SourceStr);
1468 while (S && !S->isSEHExceptScope())
1470 if (!S || !(S->getFlags() & NeededScopeFlags)) {
1473 << DRE->getDecl()->getIdentifier();
1485 "__builtin_alloca has invalid address space");
1493enum PointerAuthOpKind {
1542 llvm::raw_svector_ostream Str(
Value);
1551 Result = KeyValue->getZExtValue();
1555static std::pair<const ValueDecl *, CharUnits>
1562 const auto *BaseDecl =
1567 return {BaseDecl,
Result.Val.getLValueOffset()};
1571 bool RequireConstant =
false) {
1579 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1580 return OpKind != PAO_BlendInteger;
1582 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1583 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1584 OpKind == PAO_SignGeneric;
1593 }
else if (AllowsInteger(OpKind) &&
1600 <<
unsigned(OpKind == PAO_Discriminator ? 1
1601 : OpKind == PAO_BlendPointer ? 2
1602 : OpKind == PAO_BlendInteger ? 3
1604 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1614 if (!RequireConstant) {
1616 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1619 ? diag::warn_ptrauth_sign_null_pointer
1620 : diag::warn_ptrauth_auth_null_pointer)
1630 if (OpKind == PAO_Sign) {
1640 else if (isa<FunctionDecl>(BaseDecl))
1648 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1653 assert(OpKind == PAO_Discriminator);
1659 if (
Call->getBuiltinCallee() ==
1660 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1675 assert(
Pointer->getType()->isPointerType());
1681 if (!BaseDecl || !isa<VarDecl>(BaseDecl))
1687 assert(
Integer->getType()->isIntegerType());
1693 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1706 Call->setType(
Call->getArgs()[0]->getType());
1737 PointerAuthOpKind OpKind,
1738 bool RequireConstant) {
1749 Call->setType(
Call->getArgs()[0]->getType());
1765 Call->setType(
Call->getArgs()[0]->getType());
1774 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1777 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1778 if (!Literal || Literal->getCharByteWidth() != 1) {
1808 auto DiagSelect = [&]() -> std::optional<unsigned> {
1815 return std::optional<unsigned>{};
1830 diag::err_incomplete_type))
1834 "Unhandled non-object pointer case");
1852 llvm::Triple::ObjectFormatType CurObjFormat =
1854 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
1867 llvm::Triple::ArchType CurArch =
1869 if (llvm::is_contained(SupportedArchs, CurArch))
1879bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
1886 case llvm::Triple::arm:
1887 case llvm::Triple::armeb:
1888 case llvm::Triple::thumb:
1889 case llvm::Triple::thumbeb:
1891 case llvm::Triple::aarch64:
1892 case llvm::Triple::aarch64_32:
1893 case llvm::Triple::aarch64_be:
1895 case llvm::Triple::bpfeb:
1896 case llvm::Triple::bpfel:
1898 case llvm::Triple::hexagon:
1900 case llvm::Triple::mips:
1901 case llvm::Triple::mipsel:
1902 case llvm::Triple::mips64:
1903 case llvm::Triple::mips64el:
1905 case llvm::Triple::systemz:
1907 case llvm::Triple::x86:
1908 case llvm::Triple::x86_64:
1910 case llvm::Triple::ppc:
1911 case llvm::Triple::ppcle:
1912 case llvm::Triple::ppc64:
1913 case llvm::Triple::ppc64le:
1915 case llvm::Triple::amdgcn:
1917 case llvm::Triple::riscv32:
1918 case llvm::Triple::riscv64:
1920 case llvm::Triple::loongarch32:
1921 case llvm::Triple::loongarch64:
1924 case llvm::Triple::wasm32:
1925 case llvm::Triple::wasm64:
1927 case llvm::Triple::nvptx:
1928 case llvm::Triple::nvptx64:
1940 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1941 << ArgIndex << 0 << ArgTy;
1951 EltTy = VecTy->getElementType();
1954 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1955 << ArgIndex << 5 << ArgTy;
1965 const TargetInfo *AuxTI,
unsigned BuiltinID) {
1966 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
1967 BuiltinID == Builtin::BI__builtin_cpu_is) &&
1968 "Expecting __builtin_cpu_...");
1970 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
1972 auto SupportsBI = [=](
const TargetInfo *TInfo) {
1973 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
1974 (!IsCPUSupports && TInfo->supportsCpuIs()));
1976 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
1983 ? diag::err_builtin_aix_os_unsupported
1984 : diag::err_builtin_target_unsupported)
1989 if (!isa<StringLiteral>(Arg))
1990 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
1994 StringRef Feature = cast<StringLiteral>(Arg)->getString();
2041 TheCall->
setArg(0, Arg0);
2047 << 1 << 7 << Arg0Ty;
2057 TheCall->
setArg(1, Arg1);
2063 << 2 << 8 << Arg1Ty;
2072Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2077 unsigned ICEArguments = 0;
2084 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2086 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2091 if (ArgNo < TheCall->getNumArgs() &&
2094 ICEArguments &= ~(1 << ArgNo);
2098 switch (BuiltinID) {
2099 case Builtin::BI__builtin_cpu_supports:
2100 case Builtin::BI__builtin_cpu_is:
2105 case Builtin::BI__builtin_cpu_init:
2112 case Builtin::BI__builtin___CFStringMakeConstantString:
2116 *
this, BuiltinID, TheCall,
2117 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2120 "Wrong # arguments to builtin CFStringMakeConstantString");
2121 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2124 case Builtin::BI__builtin_ms_va_start:
2125 case Builtin::BI__builtin_stdarg_start:
2126 case Builtin::BI__builtin_va_start:
2127 if (BuiltinVAStart(BuiltinID, TheCall))
2130 case Builtin::BI__va_start: {
2132 case llvm::Triple::aarch64:
2133 case llvm::Triple::arm:
2134 case llvm::Triple::thumb:
2135 if (BuiltinVAStartARMMicrosoft(TheCall))
2139 if (BuiltinVAStart(BuiltinID, TheCall))
2147 case Builtin::BI_interlockedbittestandset_acq:
2148 case Builtin::BI_interlockedbittestandset_rel:
2149 case Builtin::BI_interlockedbittestandset_nf:
2150 case Builtin::BI_interlockedbittestandreset_acq:
2151 case Builtin::BI_interlockedbittestandreset_rel:
2152 case Builtin::BI_interlockedbittestandreset_nf:
2155 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2160 case Builtin::BI_bittest64:
2161 case Builtin::BI_bittestandcomplement64:
2162 case Builtin::BI_bittestandreset64:
2163 case Builtin::BI_bittestandset64:
2164 case Builtin::BI_interlockedbittestandreset64:
2165 case Builtin::BI_interlockedbittestandset64:
2168 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2169 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2173 case Builtin::BI__builtin_set_flt_rounds:
2176 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2177 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2181 case Builtin::BI__builtin_isgreater:
2182 case Builtin::BI__builtin_isgreaterequal:
2183 case Builtin::BI__builtin_isless:
2184 case Builtin::BI__builtin_islessequal:
2185 case Builtin::BI__builtin_islessgreater:
2186 case Builtin::BI__builtin_isunordered:
2187 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2190 case Builtin::BI__builtin_fpclassify:
2191 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2194 case Builtin::BI__builtin_isfpclass:
2195 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2198 case Builtin::BI__builtin_isfinite:
2199 case Builtin::BI__builtin_isinf:
2200 case Builtin::BI__builtin_isinf_sign:
2201 case Builtin::BI__builtin_isnan:
2202 case Builtin::BI__builtin_issignaling:
2203 case Builtin::BI__builtin_isnormal:
2204 case Builtin::BI__builtin_issubnormal:
2205 case Builtin::BI__builtin_iszero:
2206 case Builtin::BI__builtin_signbit:
2207 case Builtin::BI__builtin_signbitf:
2208 case Builtin::BI__builtin_signbitl:
2209 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2212 case Builtin::BI__builtin_shufflevector:
2216 case Builtin::BI__builtin_prefetch:
2217 if (BuiltinPrefetch(TheCall))
2220 case Builtin::BI__builtin_alloca_with_align:
2221 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2222 if (BuiltinAllocaWithAlign(TheCall))
2225 case Builtin::BI__builtin_alloca:
2226 case Builtin::BI__builtin_alloca_uninitialized:
2233 case Builtin::BI__arithmetic_fence:
2234 if (BuiltinArithmeticFence(TheCall))
2237 case Builtin::BI__assume:
2238 case Builtin::BI__builtin_assume:
2239 if (BuiltinAssume(TheCall))
2242 case Builtin::BI__builtin_assume_aligned:
2243 if (BuiltinAssumeAligned(TheCall))
2246 case Builtin::BI__builtin_dynamic_object_size:
2247 case Builtin::BI__builtin_object_size:
2251 case Builtin::BI__builtin_longjmp:
2252 if (BuiltinLongjmp(TheCall))
2255 case Builtin::BI__builtin_setjmp:
2256 if (BuiltinSetjmp(TheCall))
2259 case Builtin::BI__builtin_classify_type:
2264 case Builtin::BI__builtin_complex:
2265 if (BuiltinComplex(TheCall))
2268 case Builtin::BI__builtin_constant_p: {
2277 case Builtin::BI__builtin_launder:
2279 case Builtin::BI__sync_fetch_and_add:
2280 case Builtin::BI__sync_fetch_and_add_1:
2281 case Builtin::BI__sync_fetch_and_add_2:
2282 case Builtin::BI__sync_fetch_and_add_4:
2283 case Builtin::BI__sync_fetch_and_add_8:
2284 case Builtin::BI__sync_fetch_and_add_16:
2285 case Builtin::BI__sync_fetch_and_sub:
2286 case Builtin::BI__sync_fetch_and_sub_1:
2287 case Builtin::BI__sync_fetch_and_sub_2:
2288 case Builtin::BI__sync_fetch_and_sub_4:
2289 case Builtin::BI__sync_fetch_and_sub_8:
2290 case Builtin::BI__sync_fetch_and_sub_16:
2291 case Builtin::BI__sync_fetch_and_or:
2292 case Builtin::BI__sync_fetch_and_or_1:
2293 case Builtin::BI__sync_fetch_and_or_2:
2294 case Builtin::BI__sync_fetch_and_or_4:
2295 case Builtin::BI__sync_fetch_and_or_8:
2296 case Builtin::BI__sync_fetch_and_or_16:
2297 case Builtin::BI__sync_fetch_and_and:
2298 case Builtin::BI__sync_fetch_and_and_1:
2299 case Builtin::BI__sync_fetch_and_and_2:
2300 case Builtin::BI__sync_fetch_and_and_4:
2301 case Builtin::BI__sync_fetch_and_and_8:
2302 case Builtin::BI__sync_fetch_and_and_16:
2303 case Builtin::BI__sync_fetch_and_xor:
2304 case Builtin::BI__sync_fetch_and_xor_1:
2305 case Builtin::BI__sync_fetch_and_xor_2:
2306 case Builtin::BI__sync_fetch_and_xor_4:
2307 case Builtin::BI__sync_fetch_and_xor_8:
2308 case Builtin::BI__sync_fetch_and_xor_16:
2309 case Builtin::BI__sync_fetch_and_nand:
2310 case Builtin::BI__sync_fetch_and_nand_1:
2311 case Builtin::BI__sync_fetch_and_nand_2:
2312 case Builtin::BI__sync_fetch_and_nand_4:
2313 case Builtin::BI__sync_fetch_and_nand_8:
2314 case Builtin::BI__sync_fetch_and_nand_16:
2315 case Builtin::BI__sync_add_and_fetch:
2316 case Builtin::BI__sync_add_and_fetch_1:
2317 case Builtin::BI__sync_add_and_fetch_2:
2318 case Builtin::BI__sync_add_and_fetch_4:
2319 case Builtin::BI__sync_add_and_fetch_8:
2320 case Builtin::BI__sync_add_and_fetch_16:
2321 case Builtin::BI__sync_sub_and_fetch:
2322 case Builtin::BI__sync_sub_and_fetch_1:
2323 case Builtin::BI__sync_sub_and_fetch_2:
2324 case Builtin::BI__sync_sub_and_fetch_4:
2325 case Builtin::BI__sync_sub_and_fetch_8:
2326 case Builtin::BI__sync_sub_and_fetch_16:
2327 case Builtin::BI__sync_and_and_fetch:
2328 case Builtin::BI__sync_and_and_fetch_1:
2329 case Builtin::BI__sync_and_and_fetch_2:
2330 case Builtin::BI__sync_and_and_fetch_4:
2331 case Builtin::BI__sync_and_and_fetch_8:
2332 case Builtin::BI__sync_and_and_fetch_16:
2333 case Builtin::BI__sync_or_and_fetch:
2334 case Builtin::BI__sync_or_and_fetch_1:
2335 case Builtin::BI__sync_or_and_fetch_2:
2336 case Builtin::BI__sync_or_and_fetch_4:
2337 case Builtin::BI__sync_or_and_fetch_8:
2338 case Builtin::BI__sync_or_and_fetch_16:
2339 case Builtin::BI__sync_xor_and_fetch:
2340 case Builtin::BI__sync_xor_and_fetch_1:
2341 case Builtin::BI__sync_xor_and_fetch_2:
2342 case Builtin::BI__sync_xor_and_fetch_4:
2343 case Builtin::BI__sync_xor_and_fetch_8:
2344 case Builtin::BI__sync_xor_and_fetch_16:
2345 case Builtin::BI__sync_nand_and_fetch:
2346 case Builtin::BI__sync_nand_and_fetch_1:
2347 case Builtin::BI__sync_nand_and_fetch_2:
2348 case Builtin::BI__sync_nand_and_fetch_4:
2349 case Builtin::BI__sync_nand_and_fetch_8:
2350 case Builtin::BI__sync_nand_and_fetch_16:
2351 case Builtin::BI__sync_val_compare_and_swap:
2352 case Builtin::BI__sync_val_compare_and_swap_1:
2353 case Builtin::BI__sync_val_compare_and_swap_2:
2354 case Builtin::BI__sync_val_compare_and_swap_4:
2355 case Builtin::BI__sync_val_compare_and_swap_8:
2356 case Builtin::BI__sync_val_compare_and_swap_16:
2357 case Builtin::BI__sync_bool_compare_and_swap:
2358 case Builtin::BI__sync_bool_compare_and_swap_1:
2359 case Builtin::BI__sync_bool_compare_and_swap_2:
2360 case Builtin::BI__sync_bool_compare_and_swap_4:
2361 case Builtin::BI__sync_bool_compare_and_swap_8:
2362 case Builtin::BI__sync_bool_compare_and_swap_16:
2363 case Builtin::BI__sync_lock_test_and_set:
2364 case Builtin::BI__sync_lock_test_and_set_1:
2365 case Builtin::BI__sync_lock_test_and_set_2:
2366 case Builtin::BI__sync_lock_test_and_set_4:
2367 case Builtin::BI__sync_lock_test_and_set_8:
2368 case Builtin::BI__sync_lock_test_and_set_16:
2369 case Builtin::BI__sync_lock_release:
2370 case Builtin::BI__sync_lock_release_1:
2371 case Builtin::BI__sync_lock_release_2:
2372 case Builtin::BI__sync_lock_release_4:
2373 case Builtin::BI__sync_lock_release_8:
2374 case Builtin::BI__sync_lock_release_16:
2375 case Builtin::BI__sync_swap:
2376 case Builtin::BI__sync_swap_1:
2377 case Builtin::BI__sync_swap_2:
2378 case Builtin::BI__sync_swap_4:
2379 case Builtin::BI__sync_swap_8:
2380 case Builtin::BI__sync_swap_16:
2381 return BuiltinAtomicOverloaded(TheCallResult);
2382 case Builtin::BI__sync_synchronize:
2386 case Builtin::BI__builtin_nontemporal_load:
2387 case Builtin::BI__builtin_nontemporal_store:
2388 return BuiltinNontemporalOverloaded(TheCallResult);
2389 case Builtin::BI__builtin_memcpy_inline: {
2402 case Builtin::BI__builtin_memset_inline: {
2413#define BUILTIN(ID, TYPE, ATTRS)
2414#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2415 case Builtin::BI##ID: \
2416 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2417#include "clang/Basic/Builtins.inc"
2418 case Builtin::BI__annotation:
2422 case Builtin::BI__builtin_annotation:
2426 case Builtin::BI__builtin_addressof:
2430 case Builtin::BI__builtin_function_start:
2434 case Builtin::BI__builtin_is_aligned:
2435 case Builtin::BI__builtin_align_up:
2436 case Builtin::BI__builtin_align_down:
2440 case Builtin::BI__builtin_add_overflow:
2441 case Builtin::BI__builtin_sub_overflow:
2442 case Builtin::BI__builtin_mul_overflow:
2446 case Builtin::BI__builtin_operator_new:
2447 case Builtin::BI__builtin_operator_delete: {
2448 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2450 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2455 case Builtin::BI__builtin_dump_struct:
2457 case Builtin::BI__builtin_expect_with_probability: {
2468 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2475 bool LoseInfo =
false;
2476 Probability.convert(llvm::APFloat::IEEEdouble(),
2477 llvm::RoundingMode::Dynamic, &LoseInfo);
2478 if (!(Probability >= llvm::APFloat(0.0) &&
2479 Probability <= llvm::APFloat(1.0))) {
2486 case Builtin::BI__builtin_preserve_access_index:
2490 case Builtin::BI__builtin_call_with_static_chain:
2494 case Builtin::BI__exception_code:
2495 case Builtin::BI_exception_code:
2497 diag::err_seh___except_block))
2500 case Builtin::BI__exception_info:
2501 case Builtin::BI_exception_info:
2503 diag::err_seh___except_filter))
2506 case Builtin::BI__GetExceptionInfo:
2518 case Builtin::BIaddressof:
2519 case Builtin::BI__addressof:
2520 case Builtin::BIforward:
2521 case Builtin::BIforward_like:
2522 case Builtin::BImove:
2523 case Builtin::BImove_if_noexcept:
2524 case Builtin::BIas_const: {
2532 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
2533 BuiltinID == Builtin::BI__addressof;
2535 (ReturnsPointer ?
Result->isAnyPointerType()
2536 :
Result->isReferenceType()) &&
2538 Result->getPointeeType()))) {
2539 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
2545 case Builtin::BI__builtin_ptrauth_strip:
2547 case Builtin::BI__builtin_ptrauth_blend_discriminator:
2549 case Builtin::BI__builtin_ptrauth_sign_constant:
2552 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
2555 case Builtin::BI__builtin_ptrauth_auth:
2558 case Builtin::BI__builtin_ptrauth_sign_generic_data:
2560 case Builtin::BI__builtin_ptrauth_auth_and_resign:
2562 case Builtin::BI__builtin_ptrauth_string_discriminator:
2565 case Builtin::BIread_pipe:
2566 case Builtin::BIwrite_pipe:
2569 if (
OpenCL().checkBuiltinRWPipe(TheCall))
2572 case Builtin::BIreserve_read_pipe:
2573 case Builtin::BIreserve_write_pipe:
2574 case Builtin::BIwork_group_reserve_read_pipe:
2575 case Builtin::BIwork_group_reserve_write_pipe:
2576 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
2579 case Builtin::BIsub_group_reserve_read_pipe:
2580 case Builtin::BIsub_group_reserve_write_pipe:
2581 if (
OpenCL().checkSubgroupExt(TheCall) ||
2582 OpenCL().checkBuiltinReserveRWPipe(TheCall))
2585 case Builtin::BIcommit_read_pipe:
2586 case Builtin::BIcommit_write_pipe:
2587 case Builtin::BIwork_group_commit_read_pipe:
2588 case Builtin::BIwork_group_commit_write_pipe:
2589 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
2592 case Builtin::BIsub_group_commit_read_pipe:
2593 case Builtin::BIsub_group_commit_write_pipe:
2594 if (
OpenCL().checkSubgroupExt(TheCall) ||
2595 OpenCL().checkBuiltinCommitRWPipe(TheCall))
2598 case Builtin::BIget_pipe_num_packets:
2599 case Builtin::BIget_pipe_max_packets:
2600 if (
OpenCL().checkBuiltinPipePackets(TheCall))
2603 case Builtin::BIto_global:
2604 case Builtin::BIto_local:
2605 case Builtin::BIto_private:
2606 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
2610 case Builtin::BIenqueue_kernel:
2611 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
2614 case Builtin::BIget_kernel_work_group_size:
2615 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
2616 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
2619 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2620 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
2621 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
2624 case Builtin::BI__builtin_os_log_format:
2627 case Builtin::BI__builtin_os_log_format_buffer_size:
2628 if (BuiltinOSLogFormat(TheCall))
2631 case Builtin::BI__builtin_frame_address:
2632 case Builtin::BI__builtin_return_address: {
2641 Result.Val.getInt() != 0)
2643 << ((BuiltinID == Builtin::BI__builtin_return_address)
2644 ?
"__builtin_return_address"
2645 :
"__builtin_frame_address")
2650 case Builtin::BI__builtin_nondeterministic_value: {
2651 if (BuiltinNonDeterministicValue(TheCall))
2658 case Builtin::BI__builtin_elementwise_abs: {
2666 EltTy = VecTy->getElementType();
2669 diag::err_builtin_invalid_arg_type)
2678 case Builtin::BI__builtin_elementwise_acos:
2679 case Builtin::BI__builtin_elementwise_asin:
2680 case Builtin::BI__builtin_elementwise_atan:
2681 case Builtin::BI__builtin_elementwise_ceil:
2682 case Builtin::BI__builtin_elementwise_cos:
2683 case Builtin::BI__builtin_elementwise_cosh:
2684 case Builtin::BI__builtin_elementwise_exp:
2685 case Builtin::BI__builtin_elementwise_exp2:
2686 case Builtin::BI__builtin_elementwise_floor:
2687 case Builtin::BI__builtin_elementwise_log:
2688 case Builtin::BI__builtin_elementwise_log2:
2689 case Builtin::BI__builtin_elementwise_log10:
2690 case Builtin::BI__builtin_elementwise_roundeven:
2691 case Builtin::BI__builtin_elementwise_round:
2692 case Builtin::BI__builtin_elementwise_rint:
2693 case Builtin::BI__builtin_elementwise_nearbyint:
2694 case Builtin::BI__builtin_elementwise_sin:
2695 case Builtin::BI__builtin_elementwise_sinh:
2696 case Builtin::BI__builtin_elementwise_sqrt:
2697 case Builtin::BI__builtin_elementwise_tan:
2698 case Builtin::BI__builtin_elementwise_tanh:
2699 case Builtin::BI__builtin_elementwise_trunc:
2700 case Builtin::BI__builtin_elementwise_canonicalize: {
2710 case Builtin::BI__builtin_elementwise_fma: {
2718 case Builtin::BI__builtin_elementwise_pow: {
2719 if (BuiltinElementwiseMath(TheCall))
2733 case Builtin::BI__builtin_elementwise_add_sat:
2734 case Builtin::BI__builtin_elementwise_sub_sat: {
2735 if (BuiltinElementwiseMath(TheCall))
2743 EltTy = VecTy->getElementType();
2753 case Builtin::BI__builtin_elementwise_min:
2754 case Builtin::BI__builtin_elementwise_max:
2755 if (BuiltinElementwiseMath(TheCall))
2759 case Builtin::BI__builtin_elementwise_bitreverse: {
2768 EltTy = VecTy->getElementType();
2778 case Builtin::BI__builtin_elementwise_copysign: {
2798 diag::err_typecheck_call_different_arg_types)
2799 << MagnitudeTy << SignTy;
2807 case Builtin::BI__builtin_reduce_max:
2808 case Builtin::BI__builtin_reduce_min: {
2809 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2817 ElTy = TyA->getElementType();
2821 if (ElTy.isNull()) {
2833 case Builtin::BI__builtin_reduce_add:
2834 case Builtin::BI__builtin_reduce_mul:
2835 case Builtin::BI__builtin_reduce_xor:
2836 case Builtin::BI__builtin_reduce_or:
2837 case Builtin::BI__builtin_reduce_and: {
2838 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2846 ElTy = TyA->getElementType();
2850 if (ElTy.isNull() || !ElTy->isIntegerType()) {
2860 case Builtin::BI__builtin_matrix_transpose:
2861 return BuiltinMatrixTranspose(TheCall, TheCallResult);
2863 case Builtin::BI__builtin_matrix_column_major_load:
2864 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
2866 case Builtin::BI__builtin_matrix_column_major_store:
2867 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
2869 case Builtin::BI__builtin_verbose_trap:
2874 case Builtin::BI__builtin_get_device_side_mangled_name: {
2875 auto Check = [](
CallExpr *TheCall) {
2881 auto *
D = DRE->getDecl();
2882 if (!isa<FunctionDecl>(
D) && !isa<VarDecl>(
D))
2887 if (!Check(TheCall)) {
2889 diag::err_hip_invalid_args_builtin_mangled_name);
2894 case Builtin::BI__builtin_popcountg:
2898 case Builtin::BI__builtin_clzg:
2899 case Builtin::BI__builtin_ctzg:
2904 case Builtin::BI__builtin_allow_runtime_check: {
2924 "Aux Target Builtin, but not an aux target?");
2926 if (CheckTSBuiltinFunctionCall(
2937 return TheCallResult;
2952 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
2956 diag::err_argument_not_contiguous_bit_field)
2962 if (Format->getFirstArg() == 0)
2964 else if (IsVariadic)
2968 FSI->
FormatIdx = Format->getFormatIdx() - 1;
2992 if (isa<CXXNullPtrLiteralExpr>(
3007 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3008 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3009 Expr = ILE->getInit(0);
3019 const Expr *ArgExpr,
3023 S.
PDiag(diag::warn_null_arg)
3029 if (
auto nullability =
type->getNullability())
3040 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3046 llvm::SmallBitVector NonNullArgs;
3052 for (
const auto *Arg : Args)
3059 unsigned IdxAST = Idx.getASTIndex();
3060 if (IdxAST >= Args.size())
3062 if (NonNullArgs.empty())
3063 NonNullArgs.resize(Args.size());
3064 NonNullArgs.set(IdxAST);
3069 if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {
3073 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3076 parms = cast<ObjCMethodDecl>(FDecl)->parameters();
3078 unsigned ParamIndex = 0;
3080 I !=
E; ++I, ++ParamIndex) {
3083 if (NonNullArgs.empty())
3084 NonNullArgs.resize(Args.size());
3086 NonNullArgs.set(ParamIndex);
3093 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3098 type = blockType->getPointeeType();
3112 if (NonNullArgs.empty())
3113 NonNullArgs.resize(Args.size());
3115 NonNullArgs.set(Index);
3124 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3125 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3126 if (NonNullArgs[ArgIndex])
3132 StringRef ParamName,
QualType ArgTy,
3160 if (ArgAlign < ParamAlign)
3161 Diag(
Loc, diag::warn_param_mismatched_alignment)
3163 << ParamName << (FDecl !=
nullptr) << FDecl;
3175 llvm::SmallBitVector CheckedVarArgs;
3179 CheckedVarArgs.resize(Args.size());
3181 CheckFormatArguments(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3188 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3192 : isa_and_nonnull<FunctionDecl>(FDecl)
3193 ? cast<FunctionDecl>(FDecl)->getNumParams()
3194 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3195 ? cast<ObjCMethodDecl>(FDecl)->param_size()
3198 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3200 if (
const Expr *Arg = Args[ArgIdx]) {
3201 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3207 if (FDecl || Proto) {
3212 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3213 CheckArgumentWithTypeTag(I, Args,
Loc);
3219 if (!Proto && FDecl) {
3221 if (isa_and_nonnull<FunctionProtoType>(FT))
3227 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3229 bool IsScalableArg =
false;
3230 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3232 if (
const Expr *Arg = Args[ArgIdx]) {
3244 IsScalableArg =
true;
3246 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3255 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3256 llvm::StringMap<bool> CallerFeatureMap;
3258 if (!CallerFeatureMap.contains(
"sme"))
3259 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3261 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3268 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3270 (IsScalableArg || IsScalableRet)) {
3271 bool IsCalleeStreaming =
3273 bool IsCalleeStreamingCompatible =
3277 if (!IsCalleeStreamingCompatible &&
3281 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3284 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3295 bool CallerHasZAState =
false;
3296 bool CallerHasZT0State =
false;
3298 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3300 CallerHasZAState =
true;
3302 CallerHasZT0State =
true;
3306 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3308 CallerHasZT0State |=
3310 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3316 Diag(
Loc, diag::err_sme_za_call_no_za_state);
3319 Diag(
Loc, diag::err_sme_zt0_call_no_zt0_state);
3323 Diag(
Loc, diag::err_sme_unimplemented_za_save_restore);
3324 Diag(
Loc, diag::note_sme_use_preserves_za);
3329 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3330 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3331 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3332 if (!Arg->isValueDependent()) {
3334 if (Arg->EvaluateAsInt(Align,
Context)) {
3335 const llvm::APSInt &I = Align.
Val.
getInt();
3336 if (!I.isPowerOf2())
3337 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3338 << Arg->getSourceRange();
3341 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3364 auto *Ctor = cast<CXXConstructorDecl>(FDecl);
3369 checkCall(FDecl, Proto,
nullptr, Args,
true,
3375 bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
3376 isa<CXXMethodDecl>(FDecl);
3377 bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
3378 IsMemberOperatorCall;
3384 Expr *ImplicitThis =
nullptr;
3389 ImplicitThis = Args[0];
3392 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
3395 cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
3407 cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());
3409 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
3427 CheckAbsoluteValueFunction(TheCall, FDecl);
3428 CheckMaxUnsignedZero(TheCall, FDecl);
3429 CheckInfNaNFunction(TheCall, FDecl);
3440 case Builtin::BIstrlcpy:
3441 case Builtin::BIstrlcat:
3442 CheckStrlcpycatArguments(TheCall, FnInfo);
3444 case Builtin::BIstrncat:
3445 CheckStrncatArguments(TheCall, FnInfo);
3447 case Builtin::BIfree:
3448 CheckFreeArguments(TheCall);
3451 CheckMemaccessArguments(TheCall, CMId, FnInfo);
3460 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
3461 Ty =
V->getType().getNonReferenceType();
3462 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
3463 Ty = F->getType().getNonReferenceType();
3500 if (!llvm::isValidAtomicOrderingCABI(Ordering))
3503 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
3505 case AtomicExpr::AO__c11_atomic_init:
3506 case AtomicExpr::AO__opencl_atomic_init:
3507 llvm_unreachable(
"There is no ordering argument for an init");
3509 case AtomicExpr::AO__c11_atomic_load:
3510 case AtomicExpr::AO__opencl_atomic_load:
3511 case AtomicExpr::AO__hip_atomic_load:
3512 case AtomicExpr::AO__atomic_load_n:
3513 case AtomicExpr::AO__atomic_load:
3514 case AtomicExpr::AO__scoped_atomic_load_n:
3515 case AtomicExpr::AO__scoped_atomic_load:
3516 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
3517 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3519 case AtomicExpr::AO__c11_atomic_store:
3520 case AtomicExpr::AO__opencl_atomic_store:
3521 case AtomicExpr::AO__hip_atomic_store:
3522 case AtomicExpr::AO__atomic_store:
3523 case AtomicExpr::AO__atomic_store_n:
3524 case AtomicExpr::AO__scoped_atomic_store:
3525 case AtomicExpr::AO__scoped_atomic_store_n:
3526 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
3527 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
3528 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3537 CallExpr *TheCall = cast<CallExpr>(TheCallResult.
get());
3581 const unsigned NumForm = GNUCmpXchg + 1;
3582 const unsigned NumArgs[] = { 2, 2, 3, 3, 3, 3, 4, 5, 6 };
3583 const unsigned NumVals[] = { 1, 0, 1, 1, 1, 1, 2, 2, 3 };
3591 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
3592 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
3593 "need to update code for modified forms");
3594 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
3595 AtomicExpr::AO__atomic_xor_fetch + 1 ==
3596 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
3597 "need to update code for modified C11 atomics");
3598 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
3599 Op <= AtomicExpr::AO__opencl_atomic_store;
3600 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
3601 Op <= AtomicExpr::AO__hip_atomic_store;
3602 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
3603 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
3604 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
3605 Op <= AtomicExpr::AO__c11_atomic_store) ||
3607 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
3608 Op == AtomicExpr::AO__atomic_store_n ||
3609 Op == AtomicExpr::AO__atomic_exchange_n ||
3610 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
3611 Op == AtomicExpr::AO__scoped_atomic_load_n ||
3612 Op == AtomicExpr::AO__scoped_atomic_store_n ||
3613 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
3614 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
3618 enum ArithOpExtraValueType {
3623 unsigned ArithAllows = AOEVT_None;
3626 case AtomicExpr::AO__c11_atomic_init:
3627 case AtomicExpr::AO__opencl_atomic_init:
3631 case AtomicExpr::AO__c11_atomic_load:
3632 case AtomicExpr::AO__opencl_atomic_load:
3633 case AtomicExpr::AO__hip_atomic_load:
3634 case AtomicExpr::AO__atomic_load_n:
3635 case AtomicExpr::AO__scoped_atomic_load_n:
3639 case AtomicExpr::AO__atomic_load:
3640 case AtomicExpr::AO__scoped_atomic_load:
3644 case AtomicExpr::AO__c11_atomic_store:
3645 case AtomicExpr::AO__opencl_atomic_store:
3646 case AtomicExpr::AO__hip_atomic_store:
3647 case AtomicExpr::AO__atomic_store:
3648 case AtomicExpr::AO__atomic_store_n:
3649 case AtomicExpr::AO__scoped_atomic_store:
3650 case AtomicExpr::AO__scoped_atomic_store_n:
3653 case AtomicExpr::AO__atomic_fetch_add:
3654 case AtomicExpr::AO__atomic_fetch_sub:
3655 case AtomicExpr::AO__atomic_add_fetch:
3656 case AtomicExpr::AO__atomic_sub_fetch:
3657 case AtomicExpr::AO__scoped_atomic_fetch_add:
3658 case AtomicExpr::AO__scoped_atomic_fetch_sub:
3659 case AtomicExpr::AO__scoped_atomic_add_fetch:
3660 case AtomicExpr::AO__scoped_atomic_sub_fetch:
3661 case AtomicExpr::AO__c11_atomic_fetch_add:
3662 case AtomicExpr::AO__c11_atomic_fetch_sub:
3663 case AtomicExpr::AO__opencl_atomic_fetch_add:
3664 case AtomicExpr::AO__opencl_atomic_fetch_sub:
3665 case AtomicExpr::AO__hip_atomic_fetch_add:
3666 case AtomicExpr::AO__hip_atomic_fetch_sub:
3667 ArithAllows = AOEVT_Pointer | AOEVT_FP;
3670 case AtomicExpr::AO__atomic_fetch_max:
3671 case AtomicExpr::AO__atomic_fetch_min:
3672 case AtomicExpr::AO__atomic_max_fetch:
3673 case AtomicExpr::AO__atomic_min_fetch:
3674 case AtomicExpr::AO__scoped_atomic_fetch_max:
3675 case AtomicExpr::AO__scoped_atomic_fetch_min:
3676 case AtomicExpr::AO__scoped_atomic_max_fetch:
3677 case AtomicExpr::AO__scoped_atomic_min_fetch:
3678 case AtomicExpr::AO__c11_atomic_fetch_max:
3679 case AtomicExpr::AO__c11_atomic_fetch_min:
3680 case AtomicExpr::AO__opencl_atomic_fetch_max:
3681 case AtomicExpr::AO__opencl_atomic_fetch_min:
3682 case AtomicExpr::AO__hip_atomic_fetch_max:
3683 case AtomicExpr::AO__hip_atomic_fetch_min:
3684 ArithAllows = AOEVT_FP;
3687 case AtomicExpr::AO__c11_atomic_fetch_and:
3688 case AtomicExpr::AO__c11_atomic_fetch_or:
3689 case AtomicExpr::AO__c11_atomic_fetch_xor:
3690 case AtomicExpr::AO__hip_atomic_fetch_and:
3691 case AtomicExpr::AO__hip_atomic_fetch_or:
3692 case AtomicExpr::AO__hip_atomic_fetch_xor:
3693 case AtomicExpr::AO__c11_atomic_fetch_nand:
3694 case AtomicExpr::AO__opencl_atomic_fetch_and:
3695 case AtomicExpr::AO__opencl_atomic_fetch_or:
3696 case AtomicExpr::AO__opencl_atomic_fetch_xor:
3697 case AtomicExpr::AO__atomic_fetch_and:
3698 case AtomicExpr::AO__atomic_fetch_or:
3699 case AtomicExpr::AO__atomic_fetch_xor:
3700 case AtomicExpr::AO__atomic_fetch_nand:
3701 case AtomicExpr::AO__atomic_and_fetch:
3702 case AtomicExpr::AO__atomic_or_fetch:
3703 case AtomicExpr::AO__atomic_xor_fetch:
3704 case AtomicExpr::AO__atomic_nand_fetch:
3705 case AtomicExpr::AO__scoped_atomic_fetch_and:
3706 case AtomicExpr::AO__scoped_atomic_fetch_or:
3707 case AtomicExpr::AO__scoped_atomic_fetch_xor:
3708 case AtomicExpr::AO__scoped_atomic_fetch_nand:
3709 case AtomicExpr::AO__scoped_atomic_and_fetch:
3710 case AtomicExpr::AO__scoped_atomic_or_fetch:
3711 case AtomicExpr::AO__scoped_atomic_xor_fetch:
3712 case AtomicExpr::AO__scoped_atomic_nand_fetch:
3716 case AtomicExpr::AO__c11_atomic_exchange:
3717 case AtomicExpr::AO__hip_atomic_exchange:
3718 case AtomicExpr::AO__opencl_atomic_exchange:
3719 case AtomicExpr::AO__atomic_exchange_n:
3720 case AtomicExpr::AO__scoped_atomic_exchange_n:
3724 case AtomicExpr::AO__atomic_exchange:
3725 case AtomicExpr::AO__scoped_atomic_exchange:
3729 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
3730 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
3731 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
3732 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
3733 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
3734 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
3738 case AtomicExpr::AO__atomic_compare_exchange:
3739 case AtomicExpr::AO__atomic_compare_exchange_n:
3740 case AtomicExpr::AO__scoped_atomic_compare_exchange:
3741 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
3746 unsigned AdjustedNumArgs = NumArgs[Form];
3747 if ((IsOpenCL || IsHIP || IsScoped) &&
3748 Op != AtomicExpr::AO__opencl_atomic_init)
3751 if (Args.size() < AdjustedNumArgs) {
3752 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
3753 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3756 }
else if (Args.size() > AdjustedNumArgs) {
3757 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
3758 diag::err_typecheck_call_too_many_args)
3759 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3765 Expr *Ptr = Args[0];
3770 Ptr = ConvertedPtr.
get();
3773 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3783 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
3789 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
3795 }
else if (Form != Load && Form != LoadCopy) {
3797 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
3805 diag::err_incomplete_type))
3808 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3814 if (Form == Arithmetic) {
3817 auto IsAllowedValueType = [&](
QualType ValType,
3818 unsigned AllowedType) ->
bool {
3822 return AllowedType & AOEVT_Pointer;
3828 &llvm::APFloat::x87DoubleExtended())
3832 if (!IsAllowedValueType(ValType, ArithAllows)) {
3833 auto DID = ArithAllows & AOEVT_FP
3834 ? (ArithAllows & AOEVT_Pointer
3835 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
3836 : diag::err_atomic_op_needs_atomic_int_or_fp)
3837 : diag::err_atomic_op_needs_atomic_int;
3844 diag::err_incomplete_type)) {
3850 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
3861 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
3877 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
3889 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg ||
3892 else if (Form == C11CmpXchg || Form == GNUCmpXchg)
3898 bool IsPassedByAddress =
false;
3899 if (!IsC11 && !IsHIP && !IsN) {
3901 IsPassedByAddress =
true;
3906 APIOrderedArgs.push_back(Args[0]);
3910 APIOrderedArgs.push_back(Args[1]);
3916 APIOrderedArgs.push_back(Args[2]);
3917 APIOrderedArgs.push_back(Args[1]);
3920 APIOrderedArgs.push_back(Args[2]);
3921 APIOrderedArgs.push_back(Args[3]);
3922 APIOrderedArgs.push_back(Args[1]);
3925 APIOrderedArgs.push_back(Args[2]);
3926 APIOrderedArgs.push_back(Args[4]);
3927 APIOrderedArgs.push_back(Args[1]);
3928 APIOrderedArgs.push_back(Args[3]);
3931 APIOrderedArgs.push_back(Args[2]);
3932 APIOrderedArgs.push_back(Args[4]);
3933 APIOrderedArgs.push_back(Args[5]);
3934 APIOrderedArgs.push_back(Args[1]);
3935 APIOrderedArgs.push_back(Args[3]);
3939 APIOrderedArgs.append(Args.begin(), Args.end());
3946 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
3948 if (i < NumVals[Form] + 1) {
3961 assert(Form != Load);
3964 else if (Form ==
Init || Form == Arithmetic)
3966 else if (Form ==
Copy || Form == Xchg) {
3967 if (IsPassedByAddress) {
3974 Expr *ValArg = APIOrderedArgs[i];
3981 AS = PtrTy->getPointeeType().getAddressSpace();
3990 if (IsPassedByAddress)
4010 APIOrderedArgs[i] = Arg.
get();
4015 SubExprs.push_back(Ptr);
4019 SubExprs.push_back(APIOrderedArgs[1]);
4022 SubExprs.push_back(APIOrderedArgs[1]);
4028 SubExprs.push_back(APIOrderedArgs[2]);
4029 SubExprs.push_back(APIOrderedArgs[1]);
4033 SubExprs.push_back(APIOrderedArgs[3]);
4034 SubExprs.push_back(APIOrderedArgs[1]);
4035 SubExprs.push_back(APIOrderedArgs[2]);
4038 SubExprs.push_back(APIOrderedArgs[3]);
4039 SubExprs.push_back(APIOrderedArgs[1]);
4040 SubExprs.push_back(APIOrderedArgs[4]);
4041 SubExprs.push_back(APIOrderedArgs[2]);
4044 SubExprs.push_back(APIOrderedArgs[4]);
4045 SubExprs.push_back(APIOrderedArgs[1]);
4046 SubExprs.push_back(APIOrderedArgs[5]);
4047 SubExprs.push_back(APIOrderedArgs[2]);
4048 SubExprs.push_back(APIOrderedArgs[3]);
4053 if (SubExprs.size() >= 2 && Form !=
Init) {
4054 std::optional<llvm::APSInt>
Success =
4055 SubExprs[1]->getIntegerConstantExpr(
Context);
4057 Diag(SubExprs[1]->getBeginLoc(),
4058 diag::warn_atomic_op_has_invalid_memory_order)
4059 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4060 << SubExprs[1]->getSourceRange();
4062 if (SubExprs.size() >= 5) {
4063 if (std::optional<llvm::APSInt> Failure =
4064 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4065 if (!llvm::is_contained(
4066 {llvm::AtomicOrderingCABI::relaxed,
4067 llvm::AtomicOrderingCABI::consume,
4068 llvm::AtomicOrderingCABI::acquire,
4069 llvm::AtomicOrderingCABI::seq_cst},
4070 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4071 Diag(SubExprs[3]->getBeginLoc(),
4072 diag::warn_atomic_op_has_invalid_memory_order)
4073 << 2 << SubExprs[3]->getSourceRange();
4080 auto *
Scope = Args[Args.size() - 1];
4081 if (std::optional<llvm::APSInt>
Result =
4083 if (!ScopeModel->isValid(
Result->getZExtValue()))
4084 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope)
4085 <<
Scope->getSourceRange();
4087 SubExprs.push_back(
Scope);
4093 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4094 Op == AtomicExpr::AO__c11_atomic_store ||
4095 Op == AtomicExpr::AO__opencl_atomic_load ||
4096 Op == AtomicExpr::AO__hip_atomic_load ||
4097 Op == AtomicExpr::AO__opencl_atomic_store ||
4098 Op == AtomicExpr::AO__hip_atomic_store) &&
4101 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4102 Op == AtomicExpr::AO__opencl_atomic_load ||
4103 Op == AtomicExpr::AO__hip_atomic_load)
4108 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4124 assert(Fn &&
"builtin call without direct callee!");
4135 E->setArg(ArgIndex, Arg.
get());
4147 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4149 <<
Callee->getSourceRange();
4162 FirstArg = FirstArgResult.
get();
4163 TheCall->
setArg(0, FirstArg);
4175 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4210#define BUILTIN_ROW(x) \
4211 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4212 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4214 static const unsigned BuiltinIndices[][5] = {
4240 case 1: SizeIndex = 0;
break;
4241 case 2: SizeIndex = 1;
break;
4242 case 4: SizeIndex = 2;
break;
4243 case 8: SizeIndex = 3;
break;
4244 case 16: SizeIndex = 4;
break;
4256 unsigned BuiltinIndex, NumFixed = 1;
4257 bool WarnAboutSemanticsChange =
false;
4258 switch (BuiltinID) {
4259 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4260 case Builtin::BI__sync_fetch_and_add:
4261 case Builtin::BI__sync_fetch_and_add_1:
4262 case Builtin::BI__sync_fetch_and_add_2:
4263 case Builtin::BI__sync_fetch_and_add_4:
4264 case Builtin::BI__sync_fetch_and_add_8:
4265 case Builtin::BI__sync_fetch_and_add_16:
4269 case Builtin::BI__sync_fetch_and_sub:
4270 case Builtin::BI__sync_fetch_and_sub_1:
4271 case Builtin::BI__sync_fetch_and_sub_2:
4272 case Builtin::BI__sync_fetch_and_sub_4:
4273 case Builtin::BI__sync_fetch_and_sub_8:
4274 case Builtin::BI__sync_fetch_and_sub_16:
4278 case Builtin::BI__sync_fetch_and_or:
4279 case Builtin::BI__sync_fetch_and_or_1:
4280 case Builtin::BI__sync_fetch_and_or_2:
4281 case Builtin::BI__sync_fetch_and_or_4:
4282 case Builtin::BI__sync_fetch_and_or_8:
4283 case Builtin::BI__sync_fetch_and_or_16:
4287 case Builtin::BI__sync_fetch_and_and:
4288 case Builtin::BI__sync_fetch_and_and_1:
4289 case Builtin::BI__sync_fetch_and_and_2:
4290 case Builtin::BI__sync_fetch_and_and_4:
4291 case Builtin::BI__sync_fetch_and_and_8:
4292 case Builtin::BI__sync_fetch_and_and_16:
4296 case Builtin::BI__sync_fetch_and_xor:
4297 case Builtin::BI__sync_fetch_and_xor_1:
4298 case Builtin::BI__sync_fetch_and_xor_2:
4299 case Builtin::BI__sync_fetch_and_xor_4:
4300 case Builtin::BI__sync_fetch_and_xor_8:
4301 case Builtin::BI__sync_fetch_and_xor_16:
4305 case Builtin::BI__sync_fetch_and_nand:
4306 case Builtin::BI__sync_fetch_and_nand_1:
4307 case Builtin::BI__sync_fetch_and_nand_2:
4308 case Builtin::BI__sync_fetch_and_nand_4:
4309 case Builtin::BI__sync_fetch_and_nand_8:
4310 case Builtin::BI__sync_fetch_and_nand_16:
4312 WarnAboutSemanticsChange =
true;
4315 case Builtin::BI__sync_add_and_fetch:
4316 case Builtin::BI__sync_add_and_fetch_1:
4317 case Builtin::BI__sync_add_and_fetch_2:
4318 case Builtin::BI__sync_add_and_fetch_4:
4319 case Builtin::BI__sync_add_and_fetch_8:
4320 case Builtin::BI__sync_add_and_fetch_16:
4324 case Builtin::BI__sync_sub_and_fetch:
4325 case Builtin::BI__sync_sub_and_fetch_1:
4326 case Builtin::BI__sync_sub_and_fetch_2:
4327 case Builtin::BI__sync_sub_and_fetch_4:
4328 case Builtin::BI__sync_sub_and_fetch_8:
4329 case Builtin::BI__sync_sub_and_fetch_16:
4333 case Builtin::BI__sync_and_and_fetch:
4334 case Builtin::BI__sync_and_and_fetch_1:
4335 case Builtin::BI__sync_and_and_fetch_2:
4336 case Builtin::BI__sync_and_and_fetch_4:
4337 case Builtin::BI__sync_and_and_fetch_8:
4338 case Builtin::BI__sync_and_and_fetch_16:
4342 case Builtin::BI__sync_or_and_fetch:
4343 case Builtin::BI__sync_or_and_fetch_1:
4344 case Builtin::BI__sync_or_and_fetch_2:
4345 case Builtin::BI__sync_or_and_fetch_4:
4346 case Builtin::BI__sync_or_and_fetch_8:
4347 case Builtin::BI__sync_or_and_fetch_16:
4351 case Builtin::BI__sync_xor_and_fetch:
4352 case Builtin::BI__sync_xor_and_fetch_1:
4353 case Builtin::BI__sync_xor_and_fetch_2:
4354 case Builtin::BI__sync_xor_and_fetch_4:
4355 case Builtin::BI__sync_xor_and_fetch_8:
4356 case Builtin::BI__sync_xor_and_fetch_16:
4360 case Builtin::BI__sync_nand_and_fetch:
4361 case Builtin::BI__sync_nand_and_fetch_1:
4362 case Builtin::BI__sync_nand_and_fetch_2:
4363 case Builtin::BI__sync_nand_and_fetch_4:
4364 case Builtin::BI__sync_nand_and_fetch_8:
4365 case Builtin::BI__sync_nand_and_fetch_16:
4367 WarnAboutSemanticsChange =
true;
4370 case Builtin::BI__sync_val_compare_and_swap:
4371 case Builtin::BI__sync_val_compare_and_swap_1:
4372 case Builtin::BI__sync_val_compare_and_swap_2:
4373 case Builtin::BI__sync_val_compare_and_swap_4:
4374 case Builtin::BI__sync_val_compare_and_swap_8:
4375 case Builtin::BI__sync_val_compare_and_swap_16:
4380 case Builtin::BI__sync_bool_compare_and_swap:
4381 case Builtin::BI__sync_bool_compare_and_swap_1:
4382 case Builtin::BI__sync_bool_compare_and_swap_2:
4383 case Builtin::BI__sync_bool_compare_and_swap_4:
4384 case Builtin::BI__sync_bool_compare_and_swap_8:
4385 case Builtin::BI__sync_bool_compare_and_swap_16:
4391 case Builtin::BI__sync_lock_test_and_set:
4392 case Builtin::BI__sync_lock_test_and_set_1:
4393 case Builtin::BI__sync_lock_test_and_set_2:
4394 case Builtin::BI__sync_lock_test_and_set_4:
4395 case Builtin::BI__sync_lock_test_and_set_8:
4396 case Builtin::BI__sync_lock_test_and_set_16:
4400 case Builtin::BI__sync_lock_release:
4401 case Builtin::BI__sync_lock_release_1:
4402 case Builtin::BI__sync_lock_release_2:
4403 case Builtin::BI__sync_lock_release_4:
4404 case Builtin::BI__sync_lock_release_8:
4405 case Builtin::BI__sync_lock_release_16:
4411 case Builtin::BI__sync_swap:
4412 case Builtin::BI__sync_swap_1:
4413 case Builtin::BI__sync_swap_2:
4414 case Builtin::BI__sync_swap_4:
4415 case Builtin::BI__sync_swap_8:
4416 case Builtin::BI__sync_swap_16:
4424 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4425 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
4426 <<
Callee->getSourceRange();
4430 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
4431 <<
Callee->getSourceRange();
4433 if (WarnAboutSemanticsChange) {
4434 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
4435 <<
Callee->getSourceRange();
4440 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
4443 if (NewBuiltinID == BuiltinID)
4444 NewBuiltinDecl = FDecl;
4450 assert(Res.getFoundDecl());
4451 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
4452 if (!NewBuiltinDecl)
4459 for (
unsigned i = 0; i != NumFixed; ++i) {
4490 CK_BuiltinFnToFnPtr);
4502 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
4503 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
4507 return TheCallResult;
4516 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
4517 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
4518 "Unexpected nontemporal load/store builtin!");
4519 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
4520 unsigned numArgs = isStore ? 2 : 1;
4530 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
4536 PointerArg = PointerArgResult.
get();
4537 TheCall->
setArg(numArgs - 1, PointerArg);
4541 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
4554 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
4561 return TheCallResult;
4573 return TheCallResult;
4580 auto *
Literal = dyn_cast<StringLiteral>(Arg);
4582 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
4583 Literal = ObjcLiteral->getString();
4587 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
4605 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
4606 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
4607 TT.getArch() == llvm::Triple::aarch64_32);
4608 bool IsWindows = TT.isOSWindows();
4609 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
4610 if (IsX64 || IsAArch64) {
4617 return S.
Diag(Fn->getBeginLoc(),
4618 diag::err_ms_va_start_used_in_sysv_function);
4626 return S.
Diag(Fn->getBeginLoc(),
4627 diag::err_va_start_used_in_wrong_abi_function)
4634 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
4642 bool IsVariadic =
false;
4645 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
4646 IsVariadic =
Block->isVariadic();
4647 Params =
Block->parameters();
4648 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
4651 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
4652 IsVariadic = MD->isVariadic();
4654 Params = MD->parameters();
4655 }
else if (isa<CapturedDecl>(Caller)) {
4657 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
4661 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
4666 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
4671 *LastParam = Params.empty() ? nullptr : Params.back();
4676bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
4701 bool SecondArgIsLastNamedArgument =
false;
4703 if (std::optional<llvm::APSInt> Val =
4712 bool IsCRegister =
false;
4714 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
4715 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
4716 SecondArgIsLastNamedArgument = PV == LastParam;
4718 Type = PV->getType();
4719 ParamLoc = PV->getLocation();
4725 if (!SecondArgIsLastNamedArgument)
4727 diag::warn_second_arg_of_va_start_not_last_named_param);
4732 if (!Context.isPromotableIntegerType(Type))
4734 if (!Type->isEnumeralType())
4736 const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();
4738 Context.typesAreCompatible(ED->getPromotionType(), Type));
4740 unsigned Reason = 0;
4742 else if (IsCRegister) Reason = 2;
4743 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
4744 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
4751 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
4771 if (
Call->getNumArgs() < 3)
4773 diag::err_typecheck_call_too_few_args_at_least)
4774 << 0 << 3 <<
Call->getNumArgs()
4787 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
4790 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
4795 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
4797 << Arg1->
getType() << ConstCharPtrTy << 1
4800 << 2 << Arg1->
getType() << ConstCharPtrTy;
4805 << Arg2->
getType() << SizeTy << 1
4808 << 3 << Arg2->
getType() << SizeTy;
4813bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
4817 if (BuiltinID == Builtin::BI__builtin_isunordered &&
4845 diag::err_typecheck_call_invalid_ordered_compare)
4853bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
4854 unsigned BuiltinID) {
4859 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
4860 BuiltinID == Builtin::BI__builtin_isinf ||
4861 BuiltinID == Builtin::BI__builtin_isinf_sign))
4865 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
4866 BuiltinID == Builtin::BI__builtin_isunordered))
4870 bool IsFPClass = NumArgs == 2;
4873 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
4877 for (
unsigned i = 0; i < FPArgNo; ++i) {
4902 TheCall->
setArg(FPArgNo, OrigArg);
4916 diag::err_typecheck_call_invalid_unary_fp)
4928 if (!VectorResultTy.
isNull())
4929 ResultTy = VectorResultTy;
4938bool Sema::BuiltinComplex(
CallExpr *TheCall) {
4943 for (
unsigned I = 0; I != 2; ++I) {
4954 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
4973 diag::err_typecheck_call_different_arg_types)
4997 diag::err_typecheck_call_too_few_args_at_least)
5005 unsigned numElements = 0;
5020 unsigned numResElements = TheCall->
getNumArgs() - 2;
5029 diag::err_vec_builtin_incompatible_vector)
5036 diag::err_vec_builtin_incompatible_vector)
5041 }
else if (numElements != numResElements) {
5048 for (
unsigned i = 2; i < TheCall->
getNumArgs(); i++) {
5053 std::optional<llvm::APSInt>
Result;
5056 diag::err_shufflevector_nonconstant_argument)
5063 if (
Result->getActiveBits() > 64 ||
5064 Result->getZExtValue() >= numElements * 2)
5066 diag::err_shufflevector_argument_too_large)
5072 for (
unsigned i = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5073 exprs.push_back(TheCall->
getArg(i));
5074 TheCall->
setArg(i,
nullptr);
5092 diag::err_convertvector_non_vector)
5095 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5097 <<
"__builtin_convertvector");
5102 if (SrcElts != DstElts)
5104 diag::err_convertvector_incompatible_vector)
5109 BuiltinLoc, RParenLoc);
5112bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5117 diag::err_typecheck_call_too_many_args_at_most)
5118 << 0 << 3 << NumArgs << 0
5123 for (
unsigned i = 1; i != NumArgs; ++i)
5130bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5132 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5142 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5152bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5159 << cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5164bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5170 if (
const auto *UE =
5172 if (UE->getKind() == UETT_AlignOf ||
5173 UE->getKind() == UETT_PreferredAlignOf)
5179 if (!
Result.isPowerOf2())
5180 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5187 if (
Result > std::numeric_limits<int32_t>::max())
5195bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5208 TheCall->
setArg(0, FirstArgResult.
get());
5220 if (!
Result.isPowerOf2())
5221 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5233 TheCall->
setArg(2, ThirdArg);
5239bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5240 unsigned BuiltinID =
5241 cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5242 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5245 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5246 if (NumArgs < NumRequiredArgs) {
5247 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5248 << 0 << NumRequiredArgs << NumArgs
5251 if (NumArgs >= NumRequiredArgs + 0x100) {
5253 diag::err_typecheck_call_too_many_args_at_most)
5254 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5265 if (Arg.isInvalid())
5267 TheCall->
setArg(i, Arg.get());
5272 unsigned FormatIdx = i;
5282 unsigned FirstDataArg = i;
5283 while (i < NumArgs) {
5301 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5303 bool Success = CheckFormatArguments(
5327 std::optional<llvm::APSInt> R;
5329 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5336 int High,
bool RangeIsError) {
5350 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
5358 PDiag(diag::warn_argument_invalid_range)
5379 if (
Result.getSExtValue() % Num != 0)
5403 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5408 if (
Value.isNegative())
5419 if ((
Value & 0xFF) != 0)
5444 Result.setIsUnsigned(
true);
5449 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
5468 Result.setIsUnsigned(
true);
5476 diag::err_argument_not_shifted_byte_or_xxff)
5480bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
5482 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
5493 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
5499bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
5501 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
5508class UncoveredArgHandler {
5509 enum {
Unknown = -1, AllCovered = -2 };
5511 signed FirstUncoveredArg =
Unknown;
5515 UncoveredArgHandler() =
default;
5517 bool hasUncoveredArg()
const {
5518 return (FirstUncoveredArg >= 0);
5521 unsigned getUncoveredArg()
const {
5522 assert(hasUncoveredArg() &&
"no uncovered argument");
5523 return FirstUncoveredArg;
5526 void setAllCovered() {
5529 DiagnosticExprs.clear();
5530 FirstUncoveredArg = AllCovered;
5533 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
5534 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
5537 if (FirstUncoveredArg == AllCovered)
5542 if (NewFirstUncoveredArg == FirstUncoveredArg)
5543 DiagnosticExprs.push_back(StrExpr);
5544 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
5545 DiagnosticExprs.clear();
5546 DiagnosticExprs.push_back(StrExpr);
5547 FirstUncoveredArg = NewFirstUncoveredArg;
5551 void Diagnose(
Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
5554enum StringLiteralCheckType {
5556 SLCT_UncheckedLiteral,
5564 bool AddendIsRight) {
5565 unsigned BitWidth = Offset.getBitWidth();
5566 unsigned AddendBitWidth = Addend.getBitWidth();
5568 if (Addend.isUnsigned()) {
5569 Addend = Addend.zext(++AddendBitWidth);
5570 Addend.setIsSigned(
true);
5573 if (AddendBitWidth > BitWidth) {
5574 Offset = Offset.sext(AddendBitWidth);
5575 BitWidth = AddendBitWidth;
5576 }
else if (BitWidth > AddendBitWidth) {
5577 Addend = Addend.sext(BitWidth);
5581 llvm::APSInt ResOffset = Offset;
5582 if (BinOpKind == BO_Add)
5583 ResOffset = Offset.sadd_ov(Addend, Ov);
5585 assert(AddendIsRight && BinOpKind == BO_Sub &&
5586 "operator must be add or sub with addend on the right");
5587 ResOffset = Offset.ssub_ov(Addend, Ov);
5593 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
5594 "index (intermediate) result too big");
5595 Offset = Offset.sext(2 * BitWidth);
5596 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
5608class FormatStringLiteral {
5613 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
5614 : FExpr(fexpr), Offset(Offset) {}
5616 StringRef getString()
const {
5617 return FExpr->
getString().drop_front(Offset);
5620 unsigned getByteLength()
const {
5621 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
5624 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
5631 bool isAscii()
const {
return FExpr->
isOrdinary(); }
5632 bool isWide()
const {
return FExpr->
isWide(); }
5633 bool isUTF8()
const {
return FExpr->
isUTF8(); }
5634 bool isUTF16()
const {
return FExpr->
isUTF16(); }
5635 bool isUTF32()
const {
return FExpr->
isUTF32(); }
5636 bool isPascal()
const {
return FExpr->
isPascal(); }
5641 unsigned *StartTokenByteOffset =
nullptr)
const {
5643 StartToken, StartTokenByteOffset);
5656 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
5660 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
5661 bool IgnoreStringsWithoutSpecifiers);
5670static StringLiteralCheckType
5675 llvm::SmallBitVector &CheckedVarArgs,
5676 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
5677 bool IgnoreStringsWithoutSpecifiers =
false) {
5679 return SLCT_NotALiteral;
5681 assert(Offset.isSigned() &&
"invalid offset");
5684 return SLCT_NotALiteral;
5693 return SLCT_UncheckedLiteral;
5696 case Stmt::InitListExprClass:
5700 Type, CallType,
false,
5701 CheckedVarArgs, UncoveredArg, Offset,
5702 IgnoreStringsWithoutSpecifiers);
5704 return SLCT_NotALiteral;
5705 case Stmt::BinaryConditionalOperatorClass:
5706 case Stmt::ConditionalOperatorClass: {
5710 cast<AbstractConditionalOperator>(
E);
5715 bool CheckLeft =
true, CheckRight =
true;
5718 if (
C->getCond()->EvaluateAsBooleanCondition(
5730 StringLiteralCheckType Left;
5732 Left = SLCT_UncheckedLiteral;
5735 firstDataArg,
Type, CallType, InFunctionCall,
5736 CheckedVarArgs, UncoveredArg, Offset,
5737 IgnoreStringsWithoutSpecifiers);
5738 if (Left == SLCT_NotALiteral || !CheckRight) {
5744 S,
C->getFalseExpr(), Args, APK, format_idx, firstDataArg,
Type,
5745 CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5746 IgnoreStringsWithoutSpecifiers);
5748 return (CheckLeft && Left < Right) ? Left : Right;
5751 case Stmt::ImplicitCastExprClass:
5752 E = cast<ImplicitCastExpr>(
E)->getSubExpr();
5755 case Stmt::OpaqueValueExprClass:
5756 if (
const Expr *src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
5760 return SLCT_NotALiteral;
5762 case Stmt::PredefinedExprClass:
5766 return SLCT_UncheckedLiteral;
5768 case Stmt::DeclRefExprClass: {
5774 bool isConstant =
false;
5778 isConstant = AT->getElementType().isConstant(S.
Context);
5780 isConstant =
T.isConstant(S.
Context) &&
5785 isConstant =
T.isConstant(S.
Context);
5789 if (
const Expr *
Init = VD->getAnyInitializer()) {
5792 if (InitList->isStringLiteralInit())
5793 Init = InitList->getInit(0)->IgnoreParenImpCasts();
5796 S,
Init, Args, APK, format_idx, firstDataArg,
Type, CallType,
5797 false, CheckedVarArgs, UncoveredArg, Offset);
5838 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
5839 if (
const auto *
D = dyn_cast<Decl>(PV->getDeclContext())) {
5841 bool IsCXXMember =
false;
5842 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D))
5843 IsCXXMember = MD->isInstance();
5845 bool IsVariadic =
false;
5847 IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();
5848 else if (
const auto *BD = dyn_cast<BlockDecl>(
D))
5849 IsVariadic = BD->isVariadic();
5850 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D))
5851 IsVariadic = OMD->isVariadic();
5858 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx &&
5871 return SLCT_UncheckedLiteral;
5880 return SLCT_NotALiteral;
5883 case Stmt::CallExprClass:
5884 case Stmt::CXXMemberCallExprClass: {
5887 bool IsFirst =
true;
5888 StringLiteralCheckType CommonResult;
5889 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
5890 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
5892 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
5893 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5894 IgnoreStringsWithoutSpecifiers);
5901 return CommonResult;
5903 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
5905 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
5906 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
5909 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
5910 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5911 IgnoreStringsWithoutSpecifiers);
5917 Type, CallType,
false,
5918 CheckedVarArgs, UncoveredArg, Offset,
5919 IgnoreStringsWithoutSpecifiers);
5920 return SLCT_NotALiteral;
5922 case Stmt::ObjCMessageExprClass: {
5923 const auto *ME = cast<ObjCMessageExpr>(
E);
5924 if (
const auto *MD = ME->getMethodDecl()) {
5925 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
5934 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
5936 MD->getSelector().isKeywordSelector(
5937 {
"localizedStringForKey",
"value",
"table"})) {
5938 IgnoreStringsWithoutSpecifiers =
true;
5941 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
5943 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
5944 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5945 IgnoreStringsWithoutSpecifiers);
5949 return SLCT_NotALiteral;
5951 case Stmt::ObjCStringLiteralClass:
5952 case Stmt::StringLiteralClass: {
5958 StrE = cast<StringLiteral>(
E);
5961 if (Offset.isNegative() || Offset > StrE->
getLength()) {
5964 return SLCT_NotALiteral;
5966 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
5968 InFunctionCall, CallType, CheckedVarArgs, UncoveredArg,
5969 IgnoreStringsWithoutSpecifiers);
5970 return SLCT_CheckedLiteral;
5973 return SLCT_NotALiteral;
5975 case Stmt::BinaryOperatorClass: {
5989 if (LIsInt != RIsInt) {
5993 if (BinOpKind == BO_Add) {
6006 return SLCT_NotALiteral;
6008 case Stmt::UnaryOperatorClass: {
6010 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6011 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6013 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6023 return SLCT_NotALiteral;
6027 return SLCT_NotALiteral;
6038 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6039 if (isa_and_nonnull<StringLiteral>(LVE))
6046 return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
6048 .Cases(
"printf",
"printf0",
"syslog",
FST_Printf)
6052 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
FST_Kprintf)
6059bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6063 llvm::SmallBitVector &CheckedVarArgs) {
6064 FormatStringInfo FSI;
6067 return CheckFormatArguments(Args, FSI.ArgPassingKind, FSI.FormatIdx,
6069 CallType,
Loc,
Range, CheckedVarArgs);
6075 unsigned format_idx,
unsigned firstDataArg,
6076 FormatStringType
Type,
6079 llvm::SmallBitVector &CheckedVarArgs) {
6081 if (format_idx >= Args.size()) {
6086 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6100 UncoveredArgHandler UncoveredArg;
6102 *
this, OrigFormatExpr, Args, APK, format_idx, firstDataArg,
Type,
6104 true, CheckedVarArgs, UncoveredArg,
6105 llvm::APSInt(64,
false) = 0);
6108 if (UncoveredArg.hasUncoveredArg()) {
6109 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6110 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6111 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6114 if (CT != SLCT_NotALiteral)
6116 return CT == SLCT_CheckedLiteral;
6133 if (Args.size() == firstDataArg) {
6134 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6143 Diag(FormatLoc, diag::note_format_security_fixit)
6147 Diag(FormatLoc, diag::note_format_security_fixit)
6152 Diag(FormatLoc, diag::warn_format_nonliteral)
6163 const FormatStringLiteral *FExpr;
6164 const Expr *OrigFormatExpr;
6166 const unsigned FirstDataArg;
6167 const unsigned NumDataArgs;
6172 llvm::SmallBitVector CoveredArgs;
6173 bool usesPositionalArgs =
false;
6174 bool atFirstArg =
true;
6175 bool inFunctionCall;
6177 llvm::SmallBitVector &CheckedVarArgs;
6178 UncoveredArgHandler &UncoveredArg;
6181 CheckFormatHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6182 const Expr *origFormatExpr,
6184 unsigned numDataArgs,
const char *beg,
6188 llvm::SmallBitVector &CheckedVarArgs,
6189 UncoveredArgHandler &UncoveredArg)
6190 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6191 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6192 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6193 inFunctionCall(inFunctionCall), CallType(callType),
6194 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6195 CoveredArgs.resize(numDataArgs);
6196 CoveredArgs.reset();
6199 void DoneProcessing();
6201 void HandleIncompleteSpecifier(
const char *startSpecifier,
6202 unsigned specifierLen)
override;
6204 void HandleInvalidLengthModifier(
6207 const char *startSpecifier,
unsigned specifierLen,
6210 void HandleNonStandardLengthModifier(
6212 const char *startSpecifier,
unsigned specifierLen);
6214 void HandleNonStandardConversionSpecifier(
6216 const char *startSpecifier,
unsigned specifierLen);
6218 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
6220 void HandleInvalidPosition(
const char *startSpecifier,
6221 unsigned specifierLen,
6224 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
6226 void HandleNullChar(
const char *nullCharacter)
override;
6228 template <
typename Range>
6230 EmitFormatDiagnostic(
Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
6232 bool IsStringLocation,
Range StringRange,
6237 const char *startSpec,
6238 unsigned specifierLen,
6239 const char *csStart,
unsigned csLen);
6242 const char *startSpec,
6243 unsigned specifierLen);
6247 unsigned specifierLen);
6250 const Expr *getDataArg(
unsigned i)
const;
6254 const char *startSpecifier,
unsigned specifierLen,
6257 template <
typename Range>
6259 bool IsStringLocation,
Range StringRange,
6265SourceRange CheckFormatHandler::getFormatStringRange() {
6270getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
6272 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
6275 End = End.getLocWithOffset(1);
6280SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
6285void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
6286 unsigned specifierLen){
6287 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
6288 getLocationOfByte(startSpecifier),
6290 getSpecifierRange(startSpecifier, specifierLen));
6293void CheckFormatHandler::HandleInvalidLengthModifier(
6296 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
6297 using namespace analyze_format_string;
6299 const LengthModifier &LM = FS.getLengthModifier();
6300 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6303 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6305 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6306 getLocationOfByte(LM.getStart()),
6308 getSpecifierRange(startSpecifier, specifierLen));
6310 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6311 << FixedLM->toString()
6316 if (DiagID == diag::warn_format_nonsensical_length)
6319 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6320 getLocationOfByte(LM.getStart()),
6322 getSpecifierRange(startSpecifier, specifierLen),
6327void CheckFormatHandler::HandleNonStandardLengthModifier(
6329 const char *startSpecifier,
unsigned specifierLen) {
6330 using namespace analyze_format_string;
6332 const LengthModifier &LM = FS.getLengthModifier();
6333 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6336 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6338 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6339 << LM.toString() << 0,
6340 getLocationOfByte(LM.getStart()),
6342 getSpecifierRange(startSpecifier, specifierLen));
6344 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6345 << FixedLM->toString()
6349 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6350 << LM.toString() << 0,
6351 getLocationOfByte(LM.getStart()),
6353 getSpecifierRange(startSpecifier, specifierLen));
6357void CheckFormatHandler::HandleNonStandardConversionSpecifier(
6359 const char *startSpecifier,
unsigned specifierLen) {
6360 using namespace analyze_format_string;
6365 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6369 getSpecifierRange(startSpecifier, specifierLen));
6372 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
6373 << FixedCS->toString()
6376 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6380 getSpecifierRange(startSpecifier, specifierLen));
6384void CheckFormatHandler::HandlePosition(
const char *startPos,
6386 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
6387 getLocationOfByte(startPos),
6389 getSpecifierRange(startPos, posLen));
6392void CheckFormatHandler::HandleInvalidPosition(
6393 const char *startSpecifier,
unsigned specifierLen,
6395 EmitFormatDiagnostic(
6396 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
6397 getLocationOfByte(startSpecifier),
true,
6398 getSpecifierRange(startSpecifier, specifierLen));
6401void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
6403 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
6404 getLocationOfByte(startPos),
6406 getSpecifierRange(startPos, posLen));
6409void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
6410 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {
6412 EmitFormatDiagnostic(
6413 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
6414 getLocationOfByte(nullCharacter),
true,
6415 getFormatStringRange());
6421const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
6422 return Args[FirstDataArg + i];
6425void CheckFormatHandler::DoneProcessing() {
6431 signed notCoveredArg = CoveredArgs.find_first();
6432 if (notCoveredArg >= 0) {
6433 assert((
unsigned)notCoveredArg < NumDataArgs);
6434 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
6436 UncoveredArg.setAllCovered();
6441void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
6442 const Expr *ArgExpr) {
6443 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
6455 for (
auto E : DiagnosticExprs)
6458 CheckFormatHandler::EmitFormatDiagnostic(
6459 S, IsFunctionCall, DiagnosticExprs[0],
6465CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
6467 const char *startSpec,
6468 unsigned specifierLen,
6469 const char *csStart,
6471 bool keepGoing =
true;
6472 if (argIndex < NumDataArgs) {
6475 CoveredArgs.set(argIndex);
6491 std::string CodePointStr;
6492 if (!llvm::sys::locale::isPrint(*csStart)) {
6493 llvm::UTF32 CodePoint;
6494 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
6495 const llvm::UTF8 *
E =
6496 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
6497 llvm::ConversionResult
Result =
6498 llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
6500 if (
Result != llvm::conversionOK) {
6501 unsigned char FirstChar = *csStart;
6502 CodePoint = (llvm::UTF32)FirstChar;
6505 llvm::raw_string_ostream OS(CodePointStr);
6506 if (CodePoint < 256)
6507 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
6508 else if (CodePoint <= 0xFFFF)
6509 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
6511 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
6516 EmitFormatDiagnostic(
6517 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier,
Loc,
6518 true, getSpecifierRange(startSpec, specifierLen));
6525 const char *startSpec,
6526 unsigned specifierLen) {
6527 EmitFormatDiagnostic(
6528 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
6529 Loc,
true, getSpecifierRange(startSpec, specifierLen));
6533CheckFormatHandler::CheckNumArgs(
6536 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
6538 if (argIndex >= NumDataArgs) {
6540 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
6541 << (argIndex+1) << NumDataArgs)
6542 : S.
PDiag(diag::warn_printf_insufficient_data_args);
6543 EmitFormatDiagnostic(
6544 PDiag, getLocationOfByte(CS.
getStart()),
true,
6545 getSpecifierRange(startSpecifier, specifierLen));
6549 UncoveredArg.setAllCovered();
6555template<
typename Range>
6558 bool IsStringLocation,
6561 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
6562 Loc, IsStringLocation, StringRange, FixIt);
6592template <
typename Range>
6593void CheckFormatHandler::EmitFormatDiagnostic(
6594 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
6597 if (InFunctionCall) {
6606 S.
Diag(IsStringLocation ?
Loc : StringRange.getBegin(),
6607 diag::note_format_string_defined);
6609 Note << StringRange;
6618class CheckPrintfHandler :
public CheckFormatHandler {
6620 CheckPrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6621 const Expr *origFormatExpr,
6623 unsigned numDataArgs,
bool isObjC,
const char *beg,
6627 llvm::SmallBitVector &CheckedVarArgs,
6628 UncoveredArgHandler &UncoveredArg)
6629 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
6630 numDataArgs, beg, APK, Args, formatIdx,
6631 inFunctionCall, CallType, CheckedVarArgs,
6637 bool allowsObjCArg()
const {
6642 bool HandleInvalidPrintfConversionSpecifier(
6644 const char *startSpecifier,
6645 unsigned specifierLen)
override;
6647 void handleInvalidMaskType(StringRef MaskType)
override;
6650 const char *startSpecifier,
unsigned specifierLen,
6653 const char *StartSpecifier,
6654 unsigned SpecifierLen,
6658 const char *startSpecifier,
unsigned specifierLen);
6662 const char *startSpecifier,
unsigned specifierLen);
6665 const char *startSpecifier,
unsigned specifierLen);
6669 const char *startSpecifier,
unsigned specifierLen);
6673 void HandleEmptyObjCModifierFlag(
const char *startFlag,
6674 unsigned flagLen)
override;
6676 void HandleInvalidObjCModifierFlag(
const char *startFlag,
6677 unsigned flagLen)
override;
6679 void HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
6680 const char *flagsEnd,
6681 const char *conversionPosition)
6687bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
6689 const char *startSpecifier,
6690 unsigned specifierLen) {
6692 FS.getConversionSpecifier();
6694 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
6696 startSpecifier, specifierLen,
6700void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
6701 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
6704bool CheckPrintfHandler::HandleAmount(
6706 const char *startSpecifier,
unsigned specifierLen) {
6710 if (argIndex >= NumDataArgs) {
6711 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
6715 getSpecifierRange(startSpecifier, specifierLen));
6725 CoveredArgs.set(argIndex);
6726 const Expr *Arg = getDataArg(argIndex);
6736 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
6741 getSpecifierRange(startSpecifier, specifierLen));
6751void CheckPrintfHandler::HandleInvalidAmount(
6755 const char *startSpecifier,
6756 unsigned specifierLen) {
6758 FS.getConversionSpecifier();
6766 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
6770 getSpecifierRange(startSpecifier, specifierLen),
6776 const char *startSpecifier,
6777 unsigned specifierLen) {
6780 FS.getConversionSpecifier();
6781 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
6785 getSpecifierRange(startSpecifier, specifierLen),
6790void CheckPrintfHandler::HandleIgnoredFlag(
6794 const char *startSpecifier,
6795 unsigned specifierLen) {
6797 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
6801 getSpecifierRange(startSpecifier, specifierLen),
6803 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
6806void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
6809 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
6810 getLocationOfByte(startFlag),
6812 getSpecifierRange(startFlag, flagLen));
6815void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
6818 auto Range = getSpecifierRange(startFlag, flagLen);
6819 StringRef flag(startFlag, flagLen);
6820 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
6821 getLocationOfByte(startFlag),
6826void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
6827 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
6829 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
6830 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
6831 EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
6832 getLocationOfByte(conversionPosition),
6840template<
typename MemberKind>
6861 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
6875 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
6876 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
6878 if ((*MI)->getMinRequiredArguments() == 0)
6886bool CheckPrintfHandler::checkForCStrMembers(
6891 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
6893 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
6909bool CheckPrintfHandler::HandlePrintfSpecifier(
6912 using namespace analyze_format_string;
6913 using namespace analyze_printf;
6915 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
6917 if (FS.consumesDataArgument()) {
6920 usesPositionalArgs = FS.usesPositionalArg();
6922 else if (usesPositionalArgs != FS.usesPositionalArg()) {
6923 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
6924 startSpecifier, specifierLen);
6931 if (!HandleAmount(FS.getFieldWidth(), 0,
6932 startSpecifier, specifierLen)) {
6936 if (!HandleAmount(FS.getPrecision(), 1,
6937 startSpecifier, specifierLen)) {
6941 if (!CS.consumesDataArgument()) {
6948 unsigned argIndex = FS.getArgIndex();
6949 if (argIndex < NumDataArgs) {
6953 CoveredArgs.set(argIndex);
6957 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
6958 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
6960 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
6964 CoveredArgs.set(argIndex + 1);
6967 const Expr *Ex = getDataArg(argIndex);
6969 (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
6972 EmitFormatDiagnostic(
6973 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
6977 getSpecifierRange(startSpecifier, specifierLen));
6980 Ex = getDataArg(argIndex + 1);
6983 EmitFormatDiagnostic(
6984 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
6988 getSpecifierRange(startSpecifier, specifierLen));
6995 if (!allowsObjCArg() && CS.isObjCArg()) {
6996 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7001 if (FSType !=
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::PArg) {
7002 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7007 if (FSType ==
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::nArg) {
7008 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
7009 getLocationOfByte(CS.getStart()),
7011 getSpecifierRange(startSpecifier, specifierLen));
7018 (CS.getKind() == ConversionSpecifier::PArg ||
7019 CS.getKind() == ConversionSpecifier::sArg ||
7020 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
7021 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7027 if (FS.isPublic().isSet()) {
7028 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7030 getLocationOfByte(FS.isPublic().getPosition()),
7032 getSpecifierRange(startSpecifier, specifierLen));
7034 if (FS.isPrivate().isSet()) {
7035 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7037 getLocationOfByte(FS.isPrivate().getPosition()),
7039 getSpecifierRange(startSpecifier, specifierLen));
7043 const llvm::Triple &Triple =
Target.getTriple();
7044 if (CS.getKind() == ConversionSpecifier::nArg &&
7045 (Triple.isAndroid() || Triple.isOSFuchsia())) {
7046 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
7047 getLocationOfByte(CS.getStart()),
7049 getSpecifierRange(startSpecifier, specifierLen));
7053 if (!FS.hasValidFieldWidth()) {
7054 HandleInvalidAmount(FS, FS.getFieldWidth(), 0,
7055 startSpecifier, specifierLen);
7059 if (!FS.hasValidPrecision()) {
7060 HandleInvalidAmount(FS, FS.getPrecision(), 1,
7061 startSpecifier, specifierLen);
7065 if (CS.getKind() == ConversionSpecifier::PArg &&
7066 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
7067 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
7068 getLocationOfByte(startSpecifier),
7070 getSpecifierRange(startSpecifier, specifierLen));
7074 if (!FS.hasValidThousandsGroupingPrefix())
7075 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
7076 if (!FS.hasValidLeadingZeros())
7077 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
7078 if (!FS.hasValidPlusPrefix())
7079 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
7080 if (!FS.hasValidSpacePrefix())
7081 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
7082 if (!FS.hasValidAlternativeForm())
7083 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
7084 if (!FS.hasValidLeftJustified())
7085 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
7088 if (FS.hasSpacePrefix() && FS.hasPlusPrefix())
7089 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
7090 startSpecifier, specifierLen);
7091 if (FS.hasLeadingZeros() && FS.isLeftJustified())
7092 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
7093 startSpecifier, specifierLen);
7098 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7099 diag::warn_format_nonsensical_length);
7100 else if (!FS.hasStandardLengthModifier())
7101 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7102 else if (!FS.hasStandardLengthConversionCombination())
7103 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7104 diag::warn_format_non_standard_conversion_spec);
7106 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7107 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7113 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7116 const Expr *Arg = getDataArg(argIndex);
7120 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
7132 case Stmt::ArraySubscriptExprClass:
7133 case Stmt::CallExprClass:
7134 case Stmt::CharacterLiteralClass:
7135 case Stmt::CXXBoolLiteralExprClass:
7136 case Stmt::DeclRefExprClass:
7137 case Stmt::FloatingLiteralClass:
7138 case Stmt::IntegerLiteralClass:
7139 case Stmt::MemberExprClass:
7140 case Stmt::ObjCArrayLiteralClass:
7141 case Stmt::ObjCBoolLiteralExprClass:
7142 case Stmt::ObjCBoxedExprClass:
7143 case Stmt::ObjCDictionaryLiteralClass:
7144 case Stmt::ObjCEncodeExprClass:
7145 case Stmt::ObjCIvarRefExprClass:
7146 case Stmt::ObjCMessageExprClass:
7147 case Stmt::ObjCPropertyRefExprClass:
7148 case Stmt::ObjCStringLiteralClass:
7149 case Stmt::ObjCSubscriptRefExprClass:
7150 case Stmt::ParenExprClass:
7151 case Stmt::StringLiteralClass:
7152 case Stmt::UnaryOperatorClass:
7159static std::pair<QualType, StringRef>
7166 StringRef Name = UserTy->getDecl()->getName();
7167 QualType CastTy = llvm::StringSwitch<QualType>(Name)
7171 .Case(
"SInt32", Context.
IntTy)
7176 return std::make_pair(CastTy, Name);
7178 TyTy = UserTy->desugar();
7182 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(
E))
7184 PE->getSubExpr()->getType(),
7193 StringRef TrueName, FalseName;
7195 std::tie(TrueTy, TrueName) =
7197 CO->getTrueExpr()->getType(),
7199 std::tie(FalseTy, FalseName) =
7201 CO->getFalseExpr()->getType(),
7202 CO->getFalseExpr());
7204 if (TrueTy == FalseTy)
7205 return std::make_pair(TrueTy, TrueName);
7206 else if (TrueTy.
isNull())
7207 return std::make_pair(FalseTy, FalseName);
7208 else if (FalseTy.
isNull())
7209 return std::make_pair(TrueTy, TrueName);
7212 return std::make_pair(
QualType(), StringRef());
7231 From = VecTy->getElementType();
7233 To = VecTy->getElementType();
7245 diag::warn_format_conversion_argument_type_mismatch_signedness,
Loc)
7254 const char *StartSpecifier,
7255 unsigned SpecifierLen,
7257 using namespace analyze_format_string;
7258 using namespace analyze_printf;
7267 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
7268 ExprTy = TET->getUnderlyingExpr()->getType();
7280 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
7283 getSpecifierRange(StartSpecifier, SpecifierLen);
7285 llvm::raw_svector_ostream os(FSString);
7287 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
7295 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
7298 getSpecifierRange(StartSpecifier, SpecifierLen);
7299 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
7304 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
7306 ArgType::MatchKind OrigMatch = Match;
7309 if (Match == ArgType::Match)
7313 assert(Match != ArgType::NoMatchPromotionTypeConfusion);
7322 E = ICE->getSubExpr();
7332 if (OrigMatch == ArgType::NoMatchSignedness &&
7333 ImplicitMatch != ArgType::NoMatchSignedness)
7340 if (ImplicitMatch == ArgType::Match)
7351 FS.getLengthModifier().getKind() != LengthModifier::AsChar)
7358 if (Match == ArgType::MatchPromotion)
7359 Match = ArgType::NoMatch;
7362 if (Match == ArgType::MatchPromotion) {
7366 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
7367 ImplicitMatch != ArgType::NoMatchTypeConfusion)
7369 Match = ArgType::NoMatch;
7371 if (ImplicitMatch == ArgType::NoMatchPedantic ||
7372 ImplicitMatch == ArgType::NoMatchTypeConfusion)
7373 Match = ImplicitMatch;
7374 assert(Match != ArgType::MatchPromotion);
7377 bool IsEnum =
false;
7378 bool IsScopedEnum =
false;
7381 IntendedTy = EnumTy->getDecl()->getIntegerType();
7382 if (EnumTy->isUnscopedEnumerationType()) {
7383 ExprTy = IntendedTy;
7388 IsScopedEnum =
true;
7395 if (isObjCContext() &&
7396 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
7406 const llvm::APInt &
V = IL->getValue();
7416 if (TD->getUnderlyingType() == IntendedTy)
7424 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
7432 if (!IsScopedEnum &&
7433 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
7436 Match = ArgType::NoMatchPedantic;
7437 IntendedTy = CastTy;
7438 ShouldNotPrintDirectly =
true;
7443 PrintfSpecifier fixedFS = FS;
7450 llvm::raw_svector_ostream os(buf);
7451 fixedFS.toString(os);
7453 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
7455 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
7458 case ArgType::Match:
7459 case ArgType::MatchPromotion:
7460 case ArgType::NoMatchPromotionTypeConfusion:
7461 case ArgType::NoMatchSignedness:
7462 llvm_unreachable(
"expected non-matching");
7463 case ArgType::NoMatchPedantic:
7464 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7466 case ArgType::NoMatchTypeConfusion:
7467 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7469 case ArgType::NoMatch:
7470 Diag = diag::warn_format_conversion_argument_type_mismatch;
7491 llvm::raw_svector_ostream CastFix(CastBuf);
7492 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
7494 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
7500 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
7505 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
7527 if (ShouldNotPrintDirectly && !IsScopedEnum) {
7533 Name = TypedefTy->getDecl()->getName();
7536 unsigned Diag = Match == ArgType::NoMatchPedantic
7537 ? diag::warn_format_argument_needs_cast_pedantic
7538 : diag::warn_format_argument_needs_cast;
7539 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
7550 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
7551 : diag::warn_format_conversion_argument_type_mismatch;
7553 EmitFormatDiagnostic(
7565 bool EmitTypeMismatch =
false;
7571 case ArgType::Match:
7572 case ArgType::MatchPromotion:
7573 case ArgType::NoMatchPromotionTypeConfusion:
7574 case ArgType::NoMatchSignedness:
7575 llvm_unreachable(
"expected non-matching");
7576 case ArgType::NoMatchPedantic:
7577 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7579 case ArgType::NoMatchTypeConfusion:
7580 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7582 case ArgType::NoMatch:
7583 Diag = diag::warn_format_conversion_argument_type_mismatch;
7587 EmitFormatDiagnostic(
7596 EmitTypeMismatch =
true;
7598 EmitFormatDiagnostic(
7599 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
7600 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7604 checkForCStrMembers(AT,
E);
7610 EmitTypeMismatch =
true;
7612 EmitFormatDiagnostic(
7613 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
7614 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7622 << isa<InitListExpr>(
E) << ExprTy << CallType
7627 if (EmitTypeMismatch) {
7633 EmitFormatDiagnostic(
7634 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7640 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
7641 "format string specifier index out of range");
7642 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
7652class CheckScanfHandler :
public CheckFormatHandler {
7654 CheckScanfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7656 unsigned firstDataArg,
unsigned numDataArgs,
7660 llvm::SmallBitVector &CheckedVarArgs,
7661 UncoveredArgHandler &UncoveredArg)
7662 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7663 numDataArgs, beg, APK, Args, formatIdx,
7664 inFunctionCall, CallType, CheckedVarArgs,
7668 const char *startSpecifier,
7669 unsigned specifierLen)
override;
7671 bool HandleInvalidScanfConversionSpecifier(
7673 const char *startSpecifier,
7674 unsigned specifierLen)
override;
7676 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
7681void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
7683 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
7684 getLocationOfByte(end),
true,
7685 getSpecifierRange(start, end - start));
7688bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
7690 const char *startSpecifier,
7691 unsigned specifierLen) {
7693 FS.getConversionSpecifier();
7695 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
7697 startSpecifier, specifierLen,
7701bool CheckScanfHandler::HandleScanfSpecifier(
7703 const char *startSpecifier,
7704 unsigned specifierLen) {
7705 using namespace analyze_scanf;
7706 using namespace analyze_format_string;
7708 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
7712 if (FS.consumesDataArgument()) {
7715 usesPositionalArgs = FS.usesPositionalArg();
7717 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7718 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7719 startSpecifier, specifierLen);
7725 const OptionalAmount &Amt = FS.getFieldWidth();
7726 if (Amt.getHowSpecified() == OptionalAmount::Constant) {
7727 if (Amt.getConstantAmount() == 0) {
7729 Amt.getConstantLength());
7730 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
7731 getLocationOfByte(Amt.getStart()),
7737 if (!FS.consumesDataArgument()) {
7744 unsigned argIndex = FS.getArgIndex();
7745 if (argIndex < NumDataArgs) {
7749 CoveredArgs.set(argIndex);
7755 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7756 diag::warn_format_nonsensical_length);
7757 else if (!FS.hasStandardLengthModifier())
7758 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7759 else if (!FS.hasStandardLengthConversionCombination())
7760 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7761 diag::warn_format_non_standard_conversion_spec);
7763 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7764 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7770 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7774 const Expr *Ex = getDataArg(argIndex);
7791 ScanfSpecifier fixedFS = FS;
7796 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
7797 : diag::warn_format_conversion_argument_type_mismatch;
7802 llvm::raw_svector_ostream os(buf);
7803 fixedFS.toString(os);
7805 EmitFormatDiagnostic(
7810 getSpecifierRange(startSpecifier, specifierLen),
7812 getSpecifierRange(startSpecifier, specifierLen), os.str()));
7819 getSpecifierRange(startSpecifier, specifierLen));
7826 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
7830 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7831 bool IgnoreStringsWithoutSpecifiers) {
7833 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
7834 CheckFormatHandler::EmitFormatDiagnostic(
7835 S, inFunctionCall, Args[format_idx],
7836 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
7842 StringRef StrRef = FExpr->getString();
7843 const char *Str = StrRef.data();
7847 assert(
T &&
"String literal not of constant array type!");
7848 size_t TypeSize =
T->getZExtSize();
7849 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
7850 const unsigned numDataArgs = Args.size() - firstDataArg;
7852 if (IgnoreStringsWithoutSpecifiers &&
7859 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
7860 CheckFormatHandler::EmitFormatDiagnostic(
7861 S, inFunctionCall, Args[format_idx],
7862 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
7863 FExpr->getBeginLoc(),
7869 if (StrLen == 0 && numDataArgs > 0) {
7870 CheckFormatHandler::EmitFormatDiagnostic(
7871 S, inFunctionCall, Args[format_idx],
7872 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
7880 CheckPrintfHandler H(
7881 S, FExpr, OrigFormatExpr,
Type, firstDataArg, numDataArgs,
7883 Args, format_idx, inFunctionCall, CallType, CheckedVarArgs,
7891 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
7892 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
7893 CallType, CheckedVarArgs, UncoveredArg);
7904 const char *Str = StrRef.data();
7907 assert(
T &&
"String literal not of constant array type!");
7908 size_t TypeSize =
T->getZExtSize();
7909 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
7920 switch (AbsFunction) {
7924 case Builtin::BI__builtin_abs:
7925 return Builtin::BI__builtin_labs;
7926 case Builtin::BI__builtin_labs:
7927 return Builtin::BI__builtin_llabs;
7928 case Builtin::BI__builtin_llabs:
7931 case Builtin::BI__builtin_fabsf:
7932 return Builtin::BI__builtin_fabs;
7933 case Builtin::BI__builtin_fabs:
7934 return Builtin::BI__builtin_fabsl;
7935 case Builtin::BI__builtin_fabsl:
7938 case Builtin::BI__builtin_cabsf:
7939 return Builtin::BI__builtin_cabs;
7940 case Builtin::BI__builtin_cabs:
7941 return Builtin::BI__builtin_cabsl;
7942 case Builtin::BI__builtin_cabsl:
7945 case Builtin::BIabs:
7946 return Builtin::BIlabs;
7947 case Builtin::BIlabs:
7948 return Builtin::BIllabs;
7949 case Builtin::BIllabs:
7952 case Builtin::BIfabsf:
7953 return Builtin::BIfabs;
7954 case Builtin::BIfabs:
7955 return Builtin::BIfabsl;
7956 case Builtin::BIfabsl:
7959 case Builtin::BIcabsf:
7960 return Builtin::BIcabs;
7961 case Builtin::BIcabs:
7962 return Builtin::BIcabsl;
7963 case Builtin::BIcabsl:
7992 unsigned AbsFunctionKind) {
7993 unsigned BestKind = 0;
7995 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
8001 else if (Context.
hasSameType(ParamType, ArgType)) {
8024 llvm_unreachable(
"Type not integer, floating, or complex");
8031 switch (ValueKind) {
8036 case Builtin::BI__builtin_fabsf:
8037 case Builtin::BI__builtin_fabs:
8038 case Builtin::BI__builtin_fabsl:
8039 case Builtin::BI__builtin_cabsf:
8040 case Builtin::BI__builtin_cabs:
8041 case Builtin::BI__builtin_cabsl:
8042 return Builtin::BI__builtin_abs;
8043 case Builtin::BIfabsf:
8044 case Builtin::BIfabs:
8045 case Builtin::BIfabsl:
8046 case Builtin::BIcabsf:
8047 case Builtin::BIcabs:
8048 case Builtin::BIcabsl:
8049 return Builtin::BIabs;
8055 case Builtin::BI__builtin_abs:
8056 case Builtin::BI__builtin_labs:
8057 case Builtin::BI__builtin_llabs:
8058 case Builtin::BI__builtin_cabsf:
8059 case Builtin::BI__builtin_cabs:
8060 case Builtin::BI__builtin_cabsl:
8061 return Builtin::BI__builtin_fabsf;
8062 case Builtin::BIabs:
8063 case Builtin::BIlabs:
8064 case Builtin::BIllabs:
8065 case Builtin::BIcabsf:
8066 case Builtin::BIcabs:
8067 case Builtin::BIcabsl:
8068 return Builtin::BIfabsf;
8074 case Builtin::BI__builtin_abs:
8075 case Builtin::BI__builtin_labs:
8076 case Builtin::BI__builtin_llabs:
8077 case Builtin::BI__builtin_fabsf:
8078 case Builtin::BI__builtin_fabs:
8079 case Builtin::BI__builtin_fabsl:
8080 return Builtin::BI__builtin_cabsf;
8081 case Builtin::BIabs:
8082 case Builtin::BIlabs:
8083 case Builtin::BIllabs:
8084 case Builtin::BIfabsf:
8085 case Builtin::BIfabs:
8086 case Builtin::BIfabsl:
8087 return Builtin::BIcabsf;
8090 llvm_unreachable(
"Unable to convert function");
8101 case Builtin::BI__builtin_abs:
8102 case Builtin::BI__builtin_fabs:
8103 case Builtin::BI__builtin_fabsf:
8104 case Builtin::BI__builtin_fabsl:
8105 case Builtin::BI__builtin_labs:
8106 case Builtin::BI__builtin_llabs:
8107 case Builtin::BI__builtin_cabs:
8108 case Builtin::BI__builtin_cabsf:
8109 case Builtin::BI__builtin_cabsl:
8110 case Builtin::BIabs:
8111 case Builtin::BIlabs:
8112 case Builtin::BIllabs:
8113 case Builtin::BIfabs:
8114 case Builtin::BIfabsf:
8115 case Builtin::BIfabsl:
8116 case Builtin::BIcabs:
8117 case Builtin::BIcabsf:
8118 case Builtin::BIcabsl:
8121 llvm_unreachable(
"Unknown Builtin type");
8127 unsigned AbsKind,
QualType ArgType) {
8128 bool EmitHeaderHint =
true;
8129 const char *HeaderName =
nullptr;
8130 StringRef FunctionName;
8132 FunctionName =
"std::abs";
8134 HeaderName =
"cstdlib";
8136 HeaderName =
"cmath";
8138 llvm_unreachable(
"Invalid Type");
8147 for (
const auto *I : R) {
8150 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
8152 FDecl = dyn_cast<FunctionDecl>(I);
8167 EmitHeaderHint =
false;
8185 EmitHeaderHint =
false;
8189 }
else if (!R.
empty()) {
8195 S.
Diag(
Loc, diag::note_replace_abs_function)
8201 if (!EmitHeaderHint)
8204 S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
8208template <std::
size_t StrLen>
8210 const char (&Str)[StrLen]) {
8223 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
8224 return std::any_of(names.begin(), names.end(), [&](llvm::StringRef name) {
8225 return calleeName == name;
8230 case MathCheck::NaN:
8231 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
8232 "__builtin_nanf16",
"__builtin_nanf128"});
8233 case MathCheck::Inf:
8234 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
8235 "__builtin_inff16",
"__builtin_inff128"});
8237 llvm_unreachable(
"unknown MathCheck");
8244 bool IsNaNOrIsUnordered =
8248 if ((IsNaNOrIsUnordered || IsSpecialNaN) && FPO.getNoHonorNaNs()) {
8249 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8250 << 1 << 0 <<
Call->getSourceRange();
8252 bool IsInfOrIsFinite =
8254 bool IsInfinityOrIsSpecialInf =
8255 HasIdentifier && ((FDecl->
getName() ==
"infinity") ||
8257 if ((IsInfOrIsFinite || IsInfinityOrIsSpecialInf) && FPO.getNoHonorInfs())
8258 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8259 << 0 << 0 <<
Call->getSourceRange();
8263void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
8265 if (
Call->getNumArgs() != 1)
8270 if (AbsKind == 0 && !IsStdAbs)
8273 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8279 StringRef FunctionName =
8281 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
8282 Diag(
Call->getExprLoc(), diag::note_remove_abs)
8291 unsigned DiagType = 0;
8297 Diag(
Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
8311 if (ArgValueKind == ParamValueKind) {
8316 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
8317 << FDecl << ArgType << ParamType;
8319 if (NewAbsKind == 0)
8323 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8332 if (NewAbsKind == 0)
8335 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
8336 << FDecl << ParamValueKind << ArgValueKind;
8339 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8345 if (!
Call || !FDecl)
return;
8349 if (
Call->getExprLoc().isMacroID())
return;
8352 if (
Call->getNumArgs() != 2)
return;
8355 if (!ArgList)
return;
8356 if (ArgList->size() != 1)
return;
8359 const auto& TA = ArgList->
get(0);
8365 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
8366 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
8367 if (!MTE)
return false;
8368 const auto *Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
8369 if (!Num)
return false;
8370 if (Num->getValue() != 0)
return false;
8374 const Expr *FirstArg =
Call->getArg(0);
8375 const Expr *SecondArg =
Call->getArg(1);
8376 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
8377 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
8380 if (IsFirstArgZero == IsSecondArgZero)
return;
8385 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
8387 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
8388 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
8392 if (IsFirstArgZero) {
8400 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
8420 if (!Size->isComparisonOp() && !Size->isLogicalOp())
8424 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
8425 << SizeRange << FnName;
8426 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
8431 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
8442 bool &IsContained) {
8445 IsContained =
false;
8458 for (
auto *FD : RD->
fields()) {
8471 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
8472 if (Unary->getKind() == UETT_SizeOf)
8481 if (!
SizeOf->isArgumentType())
8482 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
8489 return SizeOf->getTypeOfArgument();
8495struct SearchNonTrivialToInitializeField
8500 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8504 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8505 asDerived().visitArray(PDIK, AT, SL);
8509 Super::visitWithKind(PDIK, FT, SL);
8524 visit(getContext().getBaseElementType(AT), SL);
8529 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
8538struct SearchNonTrivialToCopyField
8542 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8546 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8547 asDerived().visitArray(PCK, AT, SL);
8551 Super::visitWithKind(PCK, FT, SL);
8566 visit(getContext().getBaseElementType(AT), SL);
8589 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
8590 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
8614 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
8616 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
8617 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
8623 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
8626 const Expr *SizeArg =
8627 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
8629 auto isLiteralZero = [](
const Expr *
E) {
8630 return (isa<IntegerLiteral>(
E) &&
8631 cast<IntegerLiteral>(
E)->getValue() == 0) ||
8632 (isa<CharacterLiteral>(
E) &&
8633 cast<CharacterLiteral>(
E)->getValue() == 0);
8639 if (isLiteralZero(SizeArg) &&
8646 if (BId == Builtin::BIbzero ||
8649 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
8650 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
8651 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
8652 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
8653 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
8661 if (BId == Builtin::BImemset &&
8665 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
8666 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
8671void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
8678 unsigned ExpectedNumArgs =
8679 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
8680 if (
Call->getNumArgs() < ExpectedNumArgs)
8683 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
8684 BId == Builtin::BIstrndup ? 1 : 2);
8686 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
8687 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
8690 Call->getBeginLoc(),
Call->getRParenLoc()))
8699 llvm::FoldingSetNodeID SizeOfArgID;
8704 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8708 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
8709 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
8731 if (SizeOfArgID == llvm::FoldingSetNodeID())
8733 llvm::FoldingSetNodeID DestID;
8735 if (DestID == SizeOfArgID) {
8738 unsigned ActionIdx = 0;
8739 StringRef ReadableName = FnName->
getName();
8741 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
8742 if (UnaryOp->getOpcode() == UO_AddrOf)
8756 if (
SM.isMacroArgExpansion(SL)) {
8758 SL =
SM.getSpellingLoc(SL);
8766 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
8773 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
8788 PDiag(diag::warn_sizeof_pointer_type_memaccess)
8789 << FnName << SizeOfArgTy << ArgIdx
8807 unsigned OperationType = 0;
8808 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
8811 if (ArgIdx != 0 || IsCmp) {
8812 if (BId == Builtin::BImemcpy)
8814 else if(BId == Builtin::BImemmove)
8821 PDiag(diag::warn_dyn_class_memaccess)
8822 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
8823 << IsContained << ContainedRD << OperationType
8824 <<
Call->getCallee()->getSourceRange());
8826 BId != Builtin::BImemset)
8829 PDiag(diag::warn_arc_object_memaccess)
8830 << ArgIdx << FnName << PointeeTy
8831 <<
Call->getCallee()->getSourceRange());
8833 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
8834 RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
8836 PDiag(diag::warn_cstruct_memaccess)
8837 << ArgIdx << FnName << PointeeTy << 0);
8838 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
8839 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
8840 RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
8842 PDiag(diag::warn_cstruct_memaccess)
8843 << ArgIdx << FnName << PointeeTy << 1);
8844 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
8853 PDiag(diag::note_bad_memaccess_silence)
8873 if (isa<IntegerLiteral>(RHS))
8875 else if (isa<IntegerLiteral>(LHS))
8889 if (CAT->getZExtSize() <= 1)
8897void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
8901 unsigned NumArgs =
Call->getNumArgs();
8902 if ((NumArgs != 3) && (NumArgs != 4))
8907 const Expr *CompareWithSrc =
nullptr;
8910 Call->getBeginLoc(),
Call->getRParenLoc()))
8915 CompareWithSrc = Ex;
8918 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
8919 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
8920 SizeCall->getNumArgs() == 1)
8925 if (!CompareWithSrc)
8932 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
8936 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
8937 if (!CompareWithSrcDRE ||
8941 const Expr *OriginalSizeArg =
Call->getArg(2);
8942 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
8949 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
8954 llvm::raw_svector_ostream
OS(sizeString);
8959 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
8966 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
8967 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
8968 return D1->getDecl() == D2->getDecl();
8973 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
8977 return CE->getArg(0)->IgnoreParenCasts();
8982void Sema::CheckStrncatArguments(
const CallExpr *CE,
8997 unsigned PatternType = 0;
9005 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
9006 if (BE->getOpcode() == BO_Sub) {
9019 if (PatternType == 0)
9028 if (
SM.isMacroArgExpansion(SL)) {
9029 SL =
SM.getSpellingLoc(SL);
9038 if (!isKnownSizeArray) {
9039 if (PatternType == 1)
9040 Diag(SL, diag::warn_strncat_wrong_size) << SR;
9042 Diag(SL, diag::warn_strncat_src_size) << SR;
9046 if (PatternType == 1)
9047 Diag(SL, diag::warn_strncat_large_size) << SR;
9049 Diag(SL, diag::warn_strncat_src_size) << SR;
9052 llvm::raw_svector_ostream
OS(sizeString);
9060 Diag(SL, diag::note_strncat_wrong_size)
9065void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
9067 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
9069 << CalleeName << 0 << cast<NamedDecl>(
D);
9074void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
9076 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
9077 const Decl *
D = Lvalue->getDecl();
9078 if (isa<DeclaratorDecl>(
D))
9079 if (!dyn_cast<DeclaratorDecl>(
D)->getType()->isReferenceType())
9080 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
9083 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
9084 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
9085 Lvalue->getMemberDecl());
9088void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
9090 const auto *Lambda = dyn_cast<LambdaExpr>(
9095 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
9096 << CalleeName << 2 ;
9099void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
9101 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
9106 << CalleeName << 0 << Var;
9109void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
9112 llvm::raw_svector_ostream OS(SizeString);
9115 if (Kind == clang::CK_BitCast &&
9116 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
9118 if (Kind == clang::CK_IntegralToPointer &&
9119 !isa<IntegerLiteral>(
9120 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
9123 switch (
Cast->getCastKind()) {
9124 case clang::CK_BitCast:
9125 case clang::CK_IntegralToPointer:
9126 case clang::CK_FunctionToPointerDecay:
9135 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
9136 << CalleeName << 0 << OS.str();
9140void Sema::CheckFreeArguments(
const CallExpr *
E) {
9141 const std::string CalleeName =
9142 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
9146 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
9148 case UnaryOperator::Opcode::UO_AddrOf:
9149 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
9150 case UnaryOperator::Opcode::UO_Plus:
9151 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
9156 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
9158 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
9160 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
9161 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
9162 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
9166 if (isa<BlockExpr>(Arg)) {
9168 << CalleeName << 1 ;
9173 if (
const auto *Cast = dyn_cast<CastExpr>(
E->getArg(0)))
9174 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
9178Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
9184 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
9187 Diag(ReturnLoc, diag::warn_null_ret)
9197 if (Op == OO_New || Op == OO_Array_New) {
9202 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
9208 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
9225 auto getCastAndLiteral = [&FPLiteral, &FPCast](
Expr *L,
Expr *R) {
9226 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
9228 return FPLiteral && FPCast;
9231 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
9237 llvm::APFloat TargetC = FPLiteral->
getValue();
9239 llvm::APFloat::rmNearestTiesToEven, &Lossy);
9243 Diag(
Loc, diag::warn_float_compare_literal)
9244 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
9257 if (
auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
9258 if (
auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
9259 if (DRL->getDecl() == DRR->getDecl())
9267 if (
FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
9271 if (
FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
9276 if (
CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
9277 if (CL->getBuiltinCallee())
9280 if (
CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
9281 if (CR->getBuiltinCallee())
9285 Diag(
Loc, diag::warn_floatingpoint_eq)
9306 IntRange(
unsigned Width,
bool NonNegative)
9307 : Width(Width), NonNegative(NonNegative) {}
9310 unsigned valueBits()
const {
9311 return NonNegative ? Width : Width - 1;
9315 static IntRange forBoolType() {
9316 return IntRange(1,
true);
9321 return forValueOfCanonicalType(
C,
9329 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9330 T = VT->getElementType().getTypePtr();
9332 T = CT->getElementType().getTypePtr();
9333 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9334 T = AT->getValueType().getTypePtr();
9336 if (!
C.getLangOpts().CPlusPlus) {
9338 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9339 T = ET->getDecl()->getIntegerType().getDesugaredType(
C).getTypePtr();
9340 }
else if (
const EnumType *ET = dyn_cast<EnumType>(
T)) {
9345 if (
Enum->isFixed()) {
9346 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
9347 !ET->isSignedIntegerOrEnumerationType());
9350 unsigned NumPositive =
Enum->getNumPositiveBits();
9351 unsigned NumNegative =
Enum->getNumNegativeBits();
9353 if (NumNegative == 0)
9354 return IntRange(NumPositive,
true);
9356 return IntRange(std::max(NumPositive + 1, NumNegative),
9360 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9361 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9377 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9378 T = VT->getElementType().getTypePtr();
9380 T = CT->getElementType().getTypePtr();
9381 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9382 T = AT->getValueType().getTypePtr();
9383 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9384 T =
C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
9386 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9387 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9396 static IntRange join(IntRange L, IntRange R) {
9397 bool Unsigned = L.NonNegative && R.NonNegative;
9398 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
9399 L.NonNegative && R.NonNegative);
9403 static IntRange bit_and(IntRange L, IntRange R) {
9404 unsigned Bits = std::max(L.Width, R.Width);
9405 bool NonNegative =
false;
9406 if (L.NonNegative) {
9407 Bits = std::min(Bits, L.Width);
9410 if (R.NonNegative) {
9411 Bits = std::min(Bits, R.Width);
9414 return IntRange(Bits, NonNegative);
9418 static IntRange sum(IntRange L, IntRange R) {
9419 bool Unsigned = L.NonNegative && R.NonNegative;
9420 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
9425 static IntRange difference(IntRange L, IntRange R) {
9429 bool CanWiden = !L.NonNegative || !R.NonNegative;
9430 bool Unsigned = L.NonNegative && R.Width == 0;
9431 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
9437 static IntRange product(IntRange L, IntRange R) {
9441 bool CanWiden = !L.NonNegative && !R.NonNegative;
9442 bool Unsigned = L.NonNegative && R.NonNegative;
9443 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
9448 static IntRange rem(IntRange L, IntRange R) {
9452 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
9460 unsigned MaxWidth) {
9461 if (value.isSigned() && value.isNegative())
9462 return IntRange(value.getSignificantBits(),
false);
9464 if (value.getBitWidth() > MaxWidth)
9465 value = value.trunc(MaxWidth);
9469 return IntRange(value.getActiveBits(),
true);
9473 unsigned MaxWidth) {
9481 R = IntRange::join(R, El);
9489 return IntRange::join(R, I);
9504 Ty = AtomicRHS->getValueType();
9517 bool InConstantContext,
bool Approximate) {
9528 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
9529 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
9530 return GetExprRange(
C, CE->getSubExpr(), MaxWidth, InConstantContext,
9533 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
9535 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
9536 CE->getCastKind() == CK_BooleanToSignedIntegral;
9540 return OutputTypeRange;
9543 std::min(MaxWidth, OutputTypeRange.Width),
9544 InConstantContext, Approximate);
9547 if (SubRange.Width >= OutputTypeRange.Width)
9548 return OutputTypeRange;
9552 return IntRange(SubRange.Width,
9553 SubRange.NonNegative || OutputTypeRange.NonNegative);
9556 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
9559 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
9561 CondResult ? CO->getTrueExpr() : CO->getFalseExpr(),
9562 MaxWidth, InConstantContext, Approximate);
9567 Expr *
E = CO->getTrueExpr();
9571 E = CO->getFalseExpr();
9575 return IntRange::join(L, R);
9578 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
9579 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
9581 switch (BO->getOpcode()) {
9583 llvm_unreachable(
"builtin <=> should have class type");
9594 return IntRange::forBoolType();
9612 return GetExprRange(
C, BO->getRHS(), MaxWidth, InConstantContext,
9623 Combine = IntRange::bit_and;
9631 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
9632 if (I->getValue() == 1) {
9634 return IntRange(R.Width,
true);
9644 case BO_ShrAssign: {
9645 IntRange L =
GetExprRange(
C, BO->getLHS(), MaxWidth, InConstantContext,
9650 if (std::optional<llvm::APSInt> shift =
9651 BO->getRHS()->getIntegerConstantExpr(
C)) {
9652 if (shift->isNonNegative()) {
9653 if (shift->uge(L.Width))
9654 L.Width = (L.NonNegative ? 0 : 1);
9656 L.Width -= shift->getZExtValue();
9665 return GetExprRange(
C, BO->getRHS(), MaxWidth, InConstantContext,
9670 Combine = IntRange::sum;
9674 if (BO->getLHS()->getType()->isPointerType())
9677 Combine = IntRange::difference;
9682 Combine = IntRange::product;
9690 IntRange L =
GetExprRange(
C, BO->getLHS(), opWidth, InConstantContext,
9694 if (std::optional<llvm::APSInt> divisor =
9695 BO->getRHS()->getIntegerConstantExpr(
C)) {
9696 unsigned log2 = divisor->logBase2();
9697 if (
log2 >= L.Width)
9698 L.Width = (L.NonNegative ? 0 : 1);
9700 L.Width = std::min(L.Width -
log2, MaxWidth);
9707 IntRange R =
GetExprRange(
C, BO->getRHS(), opWidth, InConstantContext,
9709 return IntRange(L.Width, L.NonNegative && R.NonNegative);
9713 Combine = IntRange::rem;
9725 unsigned opWidth =
C.getIntWidth(
T);
9727 GetExprRange(
C, BO->getLHS(), opWidth, InConstantContext, Approximate);
9729 GetExprRange(
C, BO->getRHS(), opWidth, InConstantContext, Approximate);
9730 IntRange
C = Combine(L, R);
9732 C.Width = std::min(
C.Width, MaxWidth);
9736 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
9737 switch (UO->getOpcode()) {
9740 return IntRange::forBoolType();
9748 return GetExprRange(
C, UO->getSubExpr(), MaxWidth, InConstantContext,
9753 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
9754 return GetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
9758 return IntRange(BitField->getBitWidthValue(
C),
9759 BitField->getType()->isUnsignedIntegerOrEnumerationType());
9765 bool InConstantContext,
bool Approximate) {
9774 const llvm::fltSemantics &Src,
9775 const llvm::fltSemantics &Tgt) {
9776 llvm::APFloat truncated = value;
9779 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
9780 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
9782 return truncated.bitwiseIsEqual(value);
9791 const llvm::fltSemantics &Src,
9792 const llvm::fltSemantics &Tgt) {
9809 bool IsListInit =
false);
9815 if (isa<EnumConstantDecl>(DR->getDecl()))
9825 return MacroName !=
"YES" && MacroName !=
"NO" &&
9826 MacroName !=
"true" && MacroName !=
"false";
9849struct PromotedRange {
9851 llvm::APSInt PromotedMin;
9853 llvm::APSInt PromotedMax;
9855 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
9857 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
9858 else if (R.Width >= BitWidth && !
Unsigned) {
9862 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
9863 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
9865 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
9866 .extOrTrunc(BitWidth);
9867 PromotedMin.setIsUnsigned(
Unsigned);
9869 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
9870 .extOrTrunc(BitWidth);
9871 PromotedMax.setIsUnsigned(
Unsigned);
9876 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
9889 Min =
LE | InRangeFlag,
9891 Max =
GE | InRangeFlag,
9894 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
9899 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
9900 Value.isUnsigned() == PromotedMin.isUnsigned());
9901 if (!isContiguous()) {
9902 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
9903 if (
Value.isMinValue())
return Min;
9904 if (
Value.isMaxValue())
return Max;
9910 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
9911 case -1:
return Less;
9912 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
9914 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
9921 llvm_unreachable(
"impossible compare result");
9924 static std::optional<StringRef>
9928 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
9930 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
9931 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
9932 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
9933 return std::nullopt;
9940 }
else if (Op == BO_NE) {
9944 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
9951 if (Op == BO_GE || Op == BO_LE)
9952 std::swap(TrueFlag, FalseFlag);
9955 return StringRef(
"true");
9957 return StringRef(
"false");
9958 return std::nullopt;
9966 if (ICE->getCastKind() != CK_IntegralCast &&
9967 ICE->getCastKind() != CK_NoOp)
9969 E = ICE->getSubExpr();
9978 enum ConstantValueKind {
9983 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
9984 return BL->getValue() ? ConstantValueKind::LiteralTrue
9985 : ConstantValueKind::LiteralFalse;
9986 return ConstantValueKind::Miscellaneous;
9991 const llvm::APSInt &
Value,
10017 OtherT = AT->getValueType();
10018 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
10022 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
10028 bool OtherIsBooleanDespiteType =
10030 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
10031 OtherTypeRange = OtherValueRange = IntRange::forBoolType();
10035 PromotedRange OtherPromotedValueRange(OtherValueRange,
Value.getBitWidth(),
10036 Value.isUnsigned());
10037 auto Cmp = OtherPromotedValueRange.compare(
Value);
10038 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
10044 bool TautologicalTypeCompare =
false;
10046 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
10047 Value.isUnsigned());
10048 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
10049 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
10051 TautologicalTypeCompare =
true;
10059 if (!TautologicalTypeCompare && OtherValueRange.Width == 0)
10068 bool InRange = Cmp & PromotedRange::InRangeFlag;
10074 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
10075 Other->getType()->isUnsignedIntegerOrEnumerationType())
10076 TautologicalTypeCompare =
true;
10081 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant))
10082 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
10086 llvm::raw_svector_ostream OS(PrettySourceValue);
10088 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
10089 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
10091 OS << (BL->getValue() ?
"YES" :
"NO");
10096 if (!TautologicalTypeCompare) {
10097 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
10098 << RhsConstant << OtherValueRange.Width << OtherValueRange.NonNegative
10099 <<
E->getOpcodeStr() << OS.str() << *
Result
10104 if (IsObjCSignedCharBool) {
10106 S.
PDiag(diag::warn_tautological_compare_objc_bool)
10107 << OS.str() << *
Result);
10114 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
10117 E->getOperatorLoc(),
E,
10118 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
10119 : diag::warn_tautological_bool_compare)
10121 << OtherIsBooleanDespiteType << *
Result
10128 ? diag::warn_unsigned_enum_always_true_comparison
10129 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
10130 : diag::warn_unsigned_always_true_comparison)
10131 : diag::warn_tautological_constant_compare;
10134 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result
10164 Expr *LHS =
E->getLHS();
10165 Expr *RHS =
E->getRHS();
10168 std::optional<llvm::APSInt> RHSValue =
10170 std::optional<llvm::APSInt> LHSValue =
10174 if (RHSValue && LHSValue)
10178 if ((
bool)RHSValue ^ (
bool)LHSValue) {
10180 const bool RhsConstant = (
bool)RHSValue;
10181 Expr *Const = RhsConstant ? RHS : LHS;
10183 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
10206 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
10208 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
10214 Expr *signedOperand, *unsignedOperand;
10217 "unsigned comparison between two signed integer expressions?");
10218 signedOperand = LHS;
10219 unsignedOperand = RHS;
10221 signedOperand = RHS;
10222 unsignedOperand = LHS;
10228 IntRange signedRange =
10238 if (signedRange.NonNegative)
10245 if (
E->isEqualityOp()) {
10247 IntRange unsignedRange =
10253 assert(unsignedRange.NonNegative &&
"unsigned range includes negative?");
10255 if (unsignedRange.Width < comparisonWidth)
10260 S.
PDiag(diag::warn_mixed_sign_comparison)
10288 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
10289 << BitfieldEnumDecl;
10296 Init->isValueDependent() ||
10297 Init->isTypeDependent())
10300 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
10323 unsigned DiagID = 0;
10324 if (SignedEnum && !SignedBitfield) {
10325 DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
10326 }
else if (SignedBitfield && !SignedEnum &&
10328 DiagID = diag::warn_signed_bitfield_enum_conversion;
10332 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
10337 << SignedEnum << TypeRange;
10348 if (BitsNeeded > FieldWidth) {
10350 S.
Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
10362 unsigned OriginalWidth =
Value.getBitWidth();
10368 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
10369 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
10376 if (!
Value.isSigned() ||
Value.isNegative())
10377 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
10378 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
10379 OriginalWidth =
Value.getSignificantBits();
10381 if (OriginalWidth <= FieldWidth)
10385 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
10389 TruncatedValue = TruncatedValue.extend(OriginalWidth);
10390 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
10394 std::string PrettyTrunc =
toString(TruncatedValue, 10);
10396 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
10397 ? diag::warn_impcast_single_bit_bitield_precision_constant
10398 : diag::warn_impcast_bitfield_precision_constant)
10399 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
10400 <<
Init->getSourceRange();
10415 E->getOperatorLoc())) {
10418 E->getOperatorLoc());
10432 bool pruneControlFlow =
false) {
10433 if (pruneControlFlow) {
10447 unsigned diag,
bool pruneControlFlow =
false) {
10460 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
10463 const bool IsLiteral =
10464 isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
10466 llvm::APFloat
Value(0.0);
10472 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10477 diag::warn_impcast_float_integer, PruneWarnings);
10480 bool isExact =
false;
10484 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
10485 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
10493 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
10494 precision = (precision * 59 + 195) / 196;
10495 Value.toString(PrettySourceValue, precision);
10499 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10500 << PrettySourceValue);
10503 if (
Result == llvm::APFloat::opOK && isExact) {
10504 if (IsLiteral)
return;
10511 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
10514 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
10515 : diag::warn_impcast_float_to_integer_out_of_range,
10518 unsigned DiagID = 0;
10521 DiagID = diag::warn_impcast_literal_float_to_integer;
10522 }
else if (IntegerValue == 0) {
10523 if (
Value.isZero()) {
10525 diag::warn_impcast_float_integer, PruneWarnings);
10528 DiagID = diag::warn_impcast_float_to_integer_zero;
10530 if (IntegerValue.isUnsigned()) {
10531 if (!IntegerValue.isMaxValue()) {
10533 diag::warn_impcast_float_integer, PruneWarnings);
10536 if (!IntegerValue.isMaxSignedValue() &&
10537 !IntegerValue.isMinSignedValue()) {
10539 diag::warn_impcast_float_integer, PruneWarnings);
10543 DiagID = diag::warn_impcast_float_to_integer;
10548 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
10550 IntegerValue.toString(PrettyTargetValue);
10552 if (PruneWarnings) {
10555 <<
E->
getType() <<
T.getUnqualifiedType()
10556 << PrettySourceValue << PrettyTargetValue
10560 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
10568 assert(isa<CompoundAssignOperator>(
E) &&
10569 "Must be compound assignment operation");
10575 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
10579 const auto *RBT = cast<CompoundAssignOperator>(
E)
10580 ->getComputationResultType()
10587 if (ResultBT->isInteger())
10589 E->
getExprLoc(), diag::warn_impcast_float_integer);
10591 if (!ResultBT->isFloatingPoint())
10600 diag::warn_impcast_float_result_precision);
10605 if (!
Range.Width)
return "0";
10607 llvm::APSInt ValueInRange =
Value;
10608 ValueInRange.setIsSigned(!
Range.NonNegative);
10609 ValueInRange = ValueInRange.trunc(
Range.Width);
10610 return toString(ValueInRange, 10);
10614 if (!isa<ImplicitCastExpr>(Ex))
10619 const Type *Source =
10621 if (
Target->isDependentType())
10625 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
10626 const Type *BoolCandidateType = ToBool ?
Target : Source;
10635 for (
unsigned i = 0; i < NumArgs; ++i) {
10640 bool IsSwapped = ((i > 0) &&
10642 IsSwapped |= ((i < (NumArgs - 1)) &&
10648 diag::warn_impcast_floating_point_to_bool);
10655 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
10660 if (isa<CallExpr>(
E))
10665 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
10667 if (!IsGNUNullExpr && !HasNullPtrType)
10687 if (MacroName ==
"NULL")
10695 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
10709 const char FirstLiteralCharacter =
10711 if (FirstLiteralCharacter ==
'0')
10718 const char FirstContextCharacter =
10720 if (FirstContextCharacter ==
'{')
10728 const auto *IL = dyn_cast<IntegerLiteral>(
E);
10730 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
10731 if (UO->getOpcode() == UO_Minus)
10732 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
10743 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
10747 if (Opc == BO_Shl) {
10750 if (LHS && LHS->getValue() == 0)
10751 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
10753 RHS->getValue().isNonNegative() &&
10755 S.
Diag(ExprLoc, diag::warn_left_shift_always)
10756 << (
Result.Val.getInt() != 0);
10758 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context) <<
E;
10762 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
10767 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
10768 (RHS->getValue() == 0 || RHS->getValue() == 1))
10771 if (LHS->getValue() != 0 && RHS->getValue() != 0)
10772 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
10777 bool *ICContext,
bool IsListInit) {
10782 if (Source ==
Target)
return;
10783 if (
Target->isDependentType())
return;
10797 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
10798 if (isa<StringLiteral>(
E))
10803 diag::warn_impcast_string_literal_to_bool);
10804 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
10805 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
10809 diag::warn_impcast_objective_c_literal_to_bool);
10824 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
10826 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
10835 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
10837 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
10841 if (isa<VectorType>(Source)) {
10842 if (
Target->isSveVLSBuiltinType() &&
10849 if (
Target->isRVVVLSBuiltinType() &&
10856 if (!isa<VectorType>(
Target)) {
10866 diag::warn_hlsl_impcast_vector_truncation);
10875 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
10876 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
10878 if (
auto VecTy = dyn_cast<VectorType>(
Target))
10879 Target = VecTy->getElementType().getTypePtr();
10882 if (isa<ComplexType>(Source)) {
10883 if (!isa<ComplexType>(
Target)) {
10889 ? diag::err_impcast_complex_scalar
10890 : diag::warn_impcast_complex_scalar);
10893 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
10894 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
10897 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
10950 else if (Order < 0) {
10960 if (TargetBT && TargetBT->
isInteger()) {
10975 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
10983 if (isa<ImplicitCastExpr>(LastA) &&
10987 diag::warn_impcast_floating_point_to_bool);
10996 if (
Target->isUnsaturatedFixedPointType()) {
11000 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
11005 PDiag(diag::warn_impcast_fixed_point_range)
11006 <<
Value.toString() <<
T
11012 }
else if (
Target->isIntegerType()) {
11016 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
11019 llvm::APSInt IntResult = FXResult.convertToInt(
11025 PDiag(diag::warn_impcast_fixed_point_range)
11026 << FXResult.toString() <<
T
11033 }
else if (
Target->isUnsaturatedFixedPointType()) {
11041 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
11046 PDiag(diag::warn_impcast_fixed_point_range)
11065 unsigned int SourcePrecision =
SourceRange.Width;
11069 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
11072 if (SourcePrecision > 0 && TargetPrecision > 0 &&
11073 SourcePrecision > TargetPrecision) {
11075 if (std::optional<llvm::APSInt> SourceInt =
11080 llvm::APFloat TargetFloatValue(
11082 llvm::APFloat::opStatus ConversionStatus =
11083 TargetFloatValue.convertFromAPInt(
11085 llvm::APFloat::rmNearestTiesToEven);
11087 if (ConversionStatus != llvm::APFloat::opOK) {
11089 SourceInt->toString(PrettySourceValue, 10);
11091 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
11095 PDiag(diag::warn_impcast_integer_float_precision_constant)
11096 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11102 diag::warn_impcast_integer_float_precision);
11111 if (
Target->isBooleanType())
11119 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
11125 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11129 IntRange SourceTypeRange =
11130 IntRange::forTargetOfCanonicalType(
Context, Source);
11133 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
11135 if (LikelySourceRange.Width > TargetRange.Width) {
11141 llvm::APSInt
Value(32);
11151 PDiag(diag::warn_impcast_integer_precision_constant)
11152 << PrettySourceValue << PrettyTargetValue
11166 diag::warn_impcast_integer_precision);
11169 if (TargetRange.Width > SourceTypeRange.Width) {
11170 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
11171 if (UO->getOpcode() == UO_Minus)
11173 if (
Target->isUnsignedIntegerType())
11175 diag::warn_impcast_high_order_zero_bits);
11176 if (
Target->isSignedIntegerType())
11178 diag::warn_impcast_nonnegative_result);
11182 if (TargetRange.Width == LikelySourceRange.Width &&
11183 !TargetRange.NonNegative && LikelySourceRange.NonNegative &&
11198 PDiag(diag::warn_impcast_integer_precision_constant)
11199 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11208 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
11209 ((TargetRange.NonNegative && !LikelySourceRange.NonNegative) ||
11210 (!TargetRange.NonNegative && LikelySourceRange.NonNegative &&
11211 LikelySourceRange.Width == TargetRange.Width))) {
11215 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
11221 unsigned DiagID = diag::warn_impcast_integer_sign;
11229 DiagID = diag::warn_impcast_integer_sign_conditional;
11244 if (SourceEnum->getDecl()->hasNameForLinkage() &&
11245 TargetEnum->getDecl()->hasNameForLinkage() &&
11246 SourceEnum != TargetEnum) {
11251 diag::warn_impcast_different_enum_types);
11265 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
11277 Expr *TrueExpr =
E->getTrueExpr();
11278 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
11279 TrueExpr = BCO->getCommon();
11281 bool Suspicious =
false;
11290 if (!Suspicious)
return;
11293 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
11300 Suspicious =
false;
11322struct AnalyzeImplicitConversionsWorkItem {
11332 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
11334 Expr *OrigE = Item.E;
11343 bool IsListInit = Item.IsListInit ||
11344 (isa<InitListExpr>(OrigE) && S.
getLangOpts().CPlusPlus);
11349 Expr *SourceExpr =
E;
11354 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11355 if (
auto *Src = OVE->getSourceExpr())
11358 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
11359 if (UO->getOpcode() == UO_Not &&
11360 UO->getSubExpr()->isKnownToHaveBooleanValue())
11361 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
11365 if (
const auto *BO = dyn_cast<BinaryOperator>(SourceExpr))
11366 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
11367 BO->getLHS()->isKnownToHaveBooleanValue() &&
11368 BO->getRHS()->isKnownToHaveBooleanValue() &&
11369 BO->getLHS()->HasSideEffects(S.
Context) &&
11370 BO->getRHS()->HasSideEffects(S.
Context)) {
11381 if (SR.str() ==
"&" || SR.str() ==
"|") {
11383 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
11384 << (BO->getOpcode() == BO_And ?
"&" :
"|")
11387 BO->getOperatorLoc(),
11388 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
11389 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
11395 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
11416 for (
auto *SE : POE->semantics())
11417 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
11418 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
11422 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
11426 WorkList.push_back({
E, CC, IsListInit});
11432 if (BO->isComparisonOp())
11436 if (BO->getOpcode() == BO_Assign)
11439 if (BO->isAssignmentOp())
11447 if (isa<StmtExpr>(
E))
return;
11450 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
11455 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
11457 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
11461 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
11462 if (ChildExpr == CSE->getOperand())
11468 if (IsLogicalAndOperator &&
11473 WorkList.push_back({ChildExpr, CC, IsListInit});
11478 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11482 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11487 if (
U->getOpcode() == UO_LNot) {
11489 }
else if (
U->getOpcode() != UO_AddrOf) {
11490 if (
U->getSubExpr()->getType()->isAtomicType())
11491 S.
Diag(
U->getSubExpr()->getBeginLoc(),
11492 diag::warn_atomic_implicit_seq_cst);
11503 WorkList.push_back({OrigE, CC, IsListInit});
11504 while (!WorkList.empty())
11516 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
11519 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11520 if (!M->getMemberDecl()->getType()->isReferenceType())
11523 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
11525 FD =
Call->getDirectCallee();
11534 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
11548 if (
SM.isMacroBodyExpansion(
Loc))
11550 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
11573 if (isa<CXXThisExpr>(
E)) {
11574 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
11575 : diag::warn_this_bool_conversion;
11580 bool IsAddressOf =
false;
11582 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
11583 if (UO->getOpcode() != UO_AddrOf)
11585 IsAddressOf =
true;
11586 E = UO->getSubExpr();
11590 unsigned DiagID = IsCompare
11591 ? diag::warn_address_of_reference_null_compare
11592 : diag::warn_address_of_reference_bool_conversion;
11600 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
11601 bool IsParam = isa<NonNullAttr>(NonnullAttr);
11603 llvm::raw_string_ostream S(Str);
11605 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
11606 : diag::warn_cast_nonnull_to_bool;
11609 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
11614 if (
auto *Callee =
Call->getDirectCallee()) {
11615 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
11616 ComplainAboutNonnullParamOrCall(A);
11625 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
11626 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
11627 MRecordDecl && MRecordDecl->isLambda()) {
11630 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
11640 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11641 D = M->getMemberDecl();
11645 if (!
D ||
D->isWeak())
11649 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
11652 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
11653 ComplainAboutNonnullParamOrCall(A);
11657 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
11661 auto ParamIter = llvm::find(FD->
parameters(), PV);
11663 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
11667 ComplainAboutNonnullParamOrCall(
NonNull);
11672 if (ArgNo.getASTIndex() == ParamNo) {
11673 ComplainAboutNonnullParamOrCall(
NonNull);
11687 if (IsAddressOf && IsFunction) {
11692 if (!IsAddressOf && !IsFunction && !IsArray)
11697 llvm::raw_string_ostream S(Str);
11700 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
11701 : diag::warn_impcast_pointer_to_bool;
11708 DiagType = AddressOf;
11709 else if (IsFunction)
11710 DiagType = FunctionPointer;
11712 DiagType = ArrayPointer;
11714 llvm_unreachable(
"Could not determine diagnostic.");
11716 <<
Range << IsEqual;
11729 if (ReturnType.
isNull())
11767 CheckArrayAccess(
E);
11774 ::CheckBoolLikeConversion(*
this,
E, CC);
11777void Sema::CheckForIntOverflow (
const Expr *
E) {
11782 const Expr *OriginalE = Exprs.pop_back_val();
11785 if (isa<BinaryOperator, UnaryOperator>(
E)) {
11790 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
11791 Exprs.append(InitList->inits().begin(), InitList->inits().end());
11792 else if (isa<ObjCBoxedExpr>(OriginalE))
11794 else if (
const auto *
Call = dyn_cast<CallExpr>(
E))
11795 Exprs.append(
Call->arg_begin(),
Call->arg_end());
11796 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
11797 Exprs.append(Message->arg_begin(), Message->arg_end());
11798 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
11799 Exprs.append(Construct->arg_begin(), Construct->arg_end());
11800 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
11801 Exprs.push_back(Temporary->getSubExpr());
11802 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
11803 Exprs.push_back(Array->getIdx());
11804 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
11805 Exprs.push_back(Compound->getInitializer());
11806 else if (
const auto *New = dyn_cast<CXXNewExpr>(
E);
11807 New && New->isArray()) {
11808 if (
auto ArraySize = New->getArraySize())
11809 Exprs.push_back(*ArraySize);
11811 }
while (!Exprs.empty());
11826 class SequenceTree {
11830 LLVM_PREFERRED_TYPE(
bool)
11831 unsigned Merged : 1;
11839 friend class SequenceTree;
11843 explicit Seq(
unsigned N) : Index(N) {}
11846 Seq() : Index(0) {}
11849 SequenceTree() { Values.push_back(
Value(0)); }
11850 Seq root()
const {
return Seq(0); }
11857 return Seq(Values.size() - 1);
11861 void merge(
Seq S) {
11862 Values[S.Index].Merged =
true;
11868 bool isUnsequenced(
Seq Cur,
Seq Old) {
11869 unsigned C = representative(Cur.Index);
11870 unsigned Target = representative(Old.Index);
11874 C = Values[
C].Parent;
11881 unsigned representative(
unsigned K) {
11882 if (Values[K].Merged)
11884 return Values[K].Parent = representative(Values[K].
Parent);
11904 UK_ModAsSideEffect,
11906 UK_Count = UK_ModAsSideEffect + 1
11912 const Expr *UsageExpr =
nullptr;
11913 SequenceTree::Seq
Seq;
11919 Usage Uses[UK_Count];
11922 bool Diagnosed =
false;
11926 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
11934 UsageInfoMap UsageMap;
11937 SequenceTree::Seq Region;
11952 struct SequencedSubexpression {
11953 SequencedSubexpression(SequenceChecker &Self)
11954 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
11955 Self.ModAsSideEffect = &ModAsSideEffect;
11958 ~SequencedSubexpression() {
11959 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
11963 UsageInfo &UI = Self.UsageMap[M.first];
11964 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
11965 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
11966 SideEffectUsage = M.second;
11968 Self.ModAsSideEffect = OldModAsSideEffect;
11971 SequenceChecker &Self;
11980 class EvaluationTracker {
11982 EvaluationTracker(SequenceChecker &Self)
11983 : Self(Self), Prev(Self.EvalTracker) {
11984 Self.EvalTracker =
this;
11987 ~EvaluationTracker() {
11988 Self.EvalTracker = Prev;
11990 Prev->EvalOK &= EvalOK;
11993 bool evaluate(
const Expr *
E,
bool &Result) {
11997 Result, Self.SemaRef.Context,
11998 Self.SemaRef.isConstantEvaluatedContext());
12003 SequenceChecker &Self;
12004 EvaluationTracker *Prev;
12005 bool EvalOK =
true;
12006 } *EvalTracker =
nullptr;
12010 Object getObject(
const Expr *
E,
bool Mod)
const {
12013 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
12014 return getObject(UO->getSubExpr(), Mod);
12016 if (BO->getOpcode() == BO_Comma)
12017 return getObject(BO->getRHS(), Mod);
12018 if (Mod && BO->isAssignmentOp())
12019 return getObject(BO->getLHS(), Mod);
12020 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
12022 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
12023 return ME->getMemberDecl();
12024 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
12033 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
12035 Usage &
U = UI.Uses[UK];
12036 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
12040 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
12041 ModAsSideEffect->push_back(std::make_pair(O,
U));
12043 U.UsageExpr = UsageExpr;
12053 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
12054 UsageKind OtherKind,
bool IsModMod) {
12058 const Usage &
U = UI.Uses[OtherKind];
12059 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
12062 const Expr *Mod =
U.UsageExpr;
12063 const Expr *ModOrUse = UsageExpr;
12064 if (OtherKind == UK_Use)
12065 std::swap(Mod, ModOrUse);
12069 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
12070 : diag::warn_unsequenced_mod_use)
12072 UI.Diagnosed =
true;
12101 void notePreUse(Object O,
const Expr *UseExpr) {
12102 UsageInfo &UI = UsageMap[O];
12104 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
12107 void notePostUse(Object O,
const Expr *UseExpr) {
12108 UsageInfo &UI = UsageMap[O];
12109 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
12111 addUsage(O, UI, UseExpr, UK_Use);
12114 void notePreMod(Object O,
const Expr *ModExpr) {
12115 UsageInfo &UI = UsageMap[O];
12117 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
12118 checkUsage(O, UI, ModExpr, UK_Use,
false);
12121 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
12122 UsageInfo &UI = UsageMap[O];
12123 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
12125 addUsage(O, UI, ModExpr, UK);
12129 SequenceChecker(
Sema &S,
const Expr *
E,
12131 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
12135 (void)this->WorkList;
12138 void VisitStmt(
const Stmt *S) {
12142 void VisitExpr(
const Expr *
E) {
12144 Base::VisitStmt(
E);
12148 for (
auto *Sub : CSE->
children()) {
12149 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
12164 void VisitCastExpr(
const CastExpr *
E) {
12166 if (
E->getCastKind() == CK_LValueToRValue)
12167 O = getObject(
E->getSubExpr(),
false);
12176 void VisitSequencedExpressions(
const Expr *SequencedBefore,
12177 const Expr *SequencedAfter) {
12178 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
12179 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
12180 SequenceTree::Seq OldRegion = Region;
12183 SequencedSubexpression SeqBefore(*
this);
12184 Region = BeforeRegion;
12185 Visit(SequencedBefore);
12188 Region = AfterRegion;
12189 Visit(SequencedAfter);
12191 Region = OldRegion;
12193 Tree.merge(BeforeRegion);
12194 Tree.merge(AfterRegion);
12202 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
12209 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12210 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12216 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12223 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12224 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12229 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12241 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12245 SequenceTree::Seq RHSRegion;
12246 SequenceTree::Seq LHSRegion;
12248 RHSRegion =
Tree.allocate(Region);
12249 LHSRegion =
Tree.allocate(Region);
12251 RHSRegion = Region;
12252 LHSRegion = Region;
12254 SequenceTree::Seq OldRegion = Region;
12270 SequencedSubexpression SeqBefore(*
this);
12271 Region = RHSRegion;
12275 Region = LHSRegion;
12278 if (O && isa<CompoundAssignOperator>(BO))
12279 notePostUse(O, BO);
12283 Region = LHSRegion;
12286 if (O && isa<CompoundAssignOperator>(BO))
12287 notePostUse(O, BO);
12289 Region = RHSRegion;
12297 Region = OldRegion;
12301 : UK_ModAsSideEffect);
12303 Tree.merge(RHSRegion);
12304 Tree.merge(LHSRegion);
12309 VisitBinAssign(CAO);
12312 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12313 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12317 return VisitExpr(UO);
12325 : UK_ModAsSideEffect);
12328 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12329 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12333 return VisitExpr(UO);
12337 notePostMod(O, UO, UK_ModAsSideEffect);
12346 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12347 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12348 SequenceTree::Seq OldRegion = Region;
12350 EvaluationTracker Eval(*
this);
12352 SequencedSubexpression Sequenced(*
this);
12353 Region = LHSRegion;
12360 bool EvalResult =
false;
12361 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12362 bool ShouldVisitRHS = !EvalOK || !EvalResult;
12363 if (ShouldVisitRHS) {
12364 Region = RHSRegion;
12368 Region = OldRegion;
12369 Tree.merge(LHSRegion);
12370 Tree.merge(RHSRegion);
12379 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12380 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12381 SequenceTree::Seq OldRegion = Region;
12383 EvaluationTracker Eval(*
this);
12385 SequencedSubexpression Sequenced(*
this);
12386 Region = LHSRegion;
12392 bool EvalResult =
false;
12393 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12394 bool ShouldVisitRHS = !EvalOK || EvalResult;
12395 if (ShouldVisitRHS) {
12396 Region = RHSRegion;
12400 Region = OldRegion;
12401 Tree.merge(LHSRegion);
12402 Tree.merge(RHSRegion);
12410 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
12426 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
12427 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
12428 SequenceTree::Seq OldRegion = Region;
12430 EvaluationTracker Eval(*
this);
12432 SequencedSubexpression Sequenced(*
this);
12433 Region = ConditionRegion;
12443 bool EvalResult =
false;
12444 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
12445 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
12446 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
12447 if (ShouldVisitTrueExpr) {
12448 Region = TrueRegion;
12451 if (ShouldVisitFalseExpr) {
12452 Region = FalseRegion;
12456 Region = OldRegion;
12457 Tree.merge(ConditionRegion);
12458 Tree.merge(TrueRegion);
12459 Tree.merge(FalseRegion);
12462 void VisitCallExpr(
const CallExpr *CE) {
12474 SequencedSubexpression Sequenced(*
this);
12479 SequenceTree::Seq CalleeRegion;
12480 SequenceTree::Seq OtherRegion;
12481 if (SemaRef.getLangOpts().CPlusPlus17) {
12482 CalleeRegion = Tree.allocate(Region);
12483 OtherRegion = Tree.allocate(Region);
12485 CalleeRegion = Region;
12486 OtherRegion = Region;
12488 SequenceTree::Seq OldRegion = Region;
12491 Region = CalleeRegion;
12493 SequencedSubexpression Sequenced(*this);
12494 Visit(CE->getCallee());
12496 Visit(CE->getCallee());
12500 Region = OtherRegion;
12504 Region = OldRegion;
12506 Tree.merge(CalleeRegion);
12507 Tree.merge(OtherRegion);
12525 return VisitCallExpr(CXXOCE);
12536 case OO_MinusEqual:
12538 case OO_SlashEqual:
12539 case OO_PercentEqual:
12540 case OO_CaretEqual:
12543 case OO_LessLessEqual:
12544 case OO_GreaterGreaterEqual:
12545 SequencingKind = RHSBeforeLHS;
12549 case OO_GreaterGreater:
12555 SequencingKind = LHSBeforeRHS;
12559 SequencingKind = LHSBeforeRest;
12563 SequencingKind = NoSequencing;
12567 if (SequencingKind == NoSequencing)
12568 return VisitCallExpr(CXXOCE);
12571 SequencedSubexpression Sequenced(*
this);
12574 assert(SemaRef.getLangOpts().CPlusPlus17 &&
12575 "Should only get there with C++17 and above!");
12576 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
12577 "Should only get there with an overloaded binary operator"
12578 " or an overloaded call operator!");
12580 if (SequencingKind == LHSBeforeRest) {
12581 assert(CXXOCE->getOperator() == OO_Call &&
12582 "We should only have an overloaded call operator here!");
12591 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
12592 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
12593 SequenceTree::Seq OldRegion = Region;
12595 assert(CXXOCE->getNumArgs() >= 1 &&
12596 "An overloaded call operator must have at least one argument"
12597 " for the postfix-expression!");
12598 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
12599 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
12600 CXXOCE->getNumArgs() - 1);
12604 Region = PostfixExprRegion;
12605 SequencedSubexpression Sequenced(*this);
12606 Visit(PostfixExpr);
12610 Region = ArgsRegion;
12611 for (const Expr *Arg : Args)
12614 Region = OldRegion;
12615 Tree.merge(PostfixExprRegion);
12616 Tree.merge(ArgsRegion);
12618 assert(CXXOCE->getNumArgs() == 2 &&
12619 "Should only have two arguments here!");
12620 assert((SequencingKind == LHSBeforeRHS ||
12621 SequencingKind == RHSBeforeLHS) &&
12622 "Unexpected sequencing kind!");
12626 const Expr *E1 = CXXOCE->getArg(0);
12627 const Expr *E2 = CXXOCE->getArg(1);
12628 if (SequencingKind == RHSBeforeLHS)
12631 return VisitSequencedExpressions(E1, E2);
12638 SequencedSubexpression Sequenced(*
this);
12641 return VisitExpr(CCE);
12644 SequenceExpressionsInOrder(
12650 return VisitExpr(ILE);
12653 SequenceExpressionsInOrder(ILE->
inits());
12665 SequenceTree::Seq
Parent = Region;
12666 for (
const Expr *
E : ExpressionList) {
12670 Elts.push_back(Region);
12676 for (
unsigned I = 0; I < Elts.size(); ++I)
12677 Tree.merge(Elts[I]);
12681SequenceChecker::UsageInfo::UsageInfo() =
default;
12685void Sema::CheckUnsequencedOperations(
const Expr *
E) {
12687 WorkList.push_back(
E);
12688 while (!WorkList.empty()) {
12689 const Expr *Item = WorkList.pop_back_val();
12690 SequenceChecker(*
this, Item, WorkList);
12695 bool IsConstexpr) {
12697 IsConstexpr || isa<ConstantExpr>(
E));
12698 CheckImplicitConversions(
E, CheckLoc);
12700 CheckUnsequencedOperations(
E);
12702 CheckForIntOverflow(
E);
12716 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
12720 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
12724 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
12738 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
12742 bool CheckParameterNames) {
12743 bool HasInvalidParm =
false;
12745 assert(Param &&
"null in a parameter list");
12754 if (!Param->isInvalidDecl() &&
12756 diag::err_typecheck_decl_incomplete_type) ||
12758 diag::err_abstract_type_in_decl,
12760 Param->setInvalidDecl();
12761 HasInvalidParm =
true;
12766 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
12770 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
12778 QualType PType = Param->getOriginalType();
12786 if (!Param->isInvalidDecl()) {
12788 if (!ClassDecl->isInvalidDecl() &&
12789 !ClassDecl->hasIrrelevantDestructor() &&
12790 !ClassDecl->isDependentContext() &&
12791 ClassDecl->isParamDestroyedInCallee()) {
12803 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
12804 if (!Param->getType().isConstQualified())
12805 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
12809 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
12814 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
12815 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
12820 if (!Param->isInvalidDecl() &&
12822 Param->setInvalidDecl();
12823 HasInvalidParm =
true;
12824 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
12828 return HasInvalidParm;
12831std::optional<std::pair<
12840static std::pair<CharUnits, CharUnits>
12848 if (
Base->isVirtual()) {
12855 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
12862 DerivedType =
Base->getType();
12865 return std::make_pair(BaseAlignment, Offset);
12869static std::optional<std::pair<CharUnits, CharUnits>>
12875 return std::nullopt;
12880 return std::nullopt;
12884 CharUnits Offset = EltSize * IdxRes->getExtValue();
12887 return std::make_pair(
P->first,
P->second + Offset);
12893 return std::make_pair(
12894 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
12900std::optional<std::pair<
12908 case Stmt::CStyleCastExprClass:
12909 case Stmt::CXXStaticCastExprClass:
12910 case Stmt::ImplicitCastExprClass: {
12911 auto *CE = cast<CastExpr>(
E);
12912 const Expr *From = CE->getSubExpr();
12913 switch (CE->getCastKind()) {
12918 case CK_UncheckedDerivedToBase:
12919 case CK_DerivedToBase: {
12929 case Stmt::ArraySubscriptExprClass: {
12930 auto *ASE = cast<ArraySubscriptExpr>(
E);
12934 case Stmt::DeclRefExprClass: {
12935 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
12938 if (!VD->getType()->isReferenceType()) {
12940 if (VD->hasDependentAlignment())
12949 case Stmt::MemberExprClass: {
12950 auto *ME = cast<MemberExpr>(
E);
12951 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
12955 std::optional<std::pair<CharUnits, CharUnits>>
P;
12964 return std::make_pair(
P->first,
12967 case Stmt::UnaryOperatorClass: {
12968 auto *UO = cast<UnaryOperator>(
E);
12977 case Stmt::BinaryOperatorClass: {
12978 auto *BO = cast<BinaryOperator>(
E);
12989 return std::nullopt;
12994std::optional<std::pair<
13003 case Stmt::CStyleCastExprClass:
13004 case Stmt::CXXStaticCastExprClass:
13005 case Stmt::ImplicitCastExprClass: {
13006 auto *CE = cast<CastExpr>(
E);
13007 const Expr *From = CE->getSubExpr();
13008 switch (CE->getCastKind()) {
13013 case CK_ArrayToPointerDecay:
13015 case CK_UncheckedDerivedToBase:
13016 case CK_DerivedToBase: {
13026 case Stmt::CXXThisExprClass: {
13031 case Stmt::UnaryOperatorClass: {
13032 auto *UO = cast<UnaryOperator>(
E);
13037 case Stmt::BinaryOperatorClass: {
13038 auto *BO = cast<BinaryOperator>(
E);
13046 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
13047 std::swap(LHS, RHS);
13057 return std::nullopt;
13062 std::optional<std::pair<CharUnits, CharUnits>>
P =
13066 return P->first.alignmentAtOffset(
P->second);
13084 if (!DestPtr)
return;
13090 if (DestAlign.
isOne())
return;
13094 if (!SrcPtr)
return;
13105 if (SrcAlign >= DestAlign)
return;
13110 <<
static_cast<unsigned>(DestAlign.
getQuantity())
13114void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
13116 bool AllowOnePastEnd,
bool IndexNegated) {
13125 const Type *EffectiveType =
13132 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
13134 const Type *BaseType =
13136 bool IsUnboundedArray =
13138 Context, StrictFlexArraysLevel,
13148 llvm::APSInt index =
Result.Val.getInt();
13149 if (IndexNegated) {
13150 index.setIsUnsigned(
false);
13154 if (IsUnboundedArray) {
13157 if (index.isUnsigned() || !index.isNegative()) {
13159 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
13161 if (index.getBitWidth() < AddrBits)
13162 index = index.zext(AddrBits);
13163 std::optional<CharUnits> ElemCharUnits =
13164 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
13167 if (!ElemCharUnits || ElemCharUnits->isZero())
13169 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
13174 if (index.getActiveBits() <= AddrBits) {
13176 llvm::APInt Product(index);
13178 Product = Product.umul_ov(ElemBytes, Overflow);
13179 if (!Overflow && Product.getActiveBits() <= AddrBits)
13185 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
13186 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
13188 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
13189 MaxElems = MaxElems.udiv(ElemBytes);
13192 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
13193 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
13199 <<
toString(index, 10,
true) << AddrBits
13200 << (
unsigned)ASTC.toBits(*ElemCharUnits)
13203 << (
unsigned)MaxElems.getLimitedValue(~0
U)
13208 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13210 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13212 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13213 ND = ME->getMemberDecl();
13217 PDiag(diag::note_array_declared_here) << ND);
13222 if (index.isUnsigned() || !index.isNegative()) {
13232 llvm::APInt size = ArrayTy->
getSize();
13234 if (BaseType != EffectiveType) {
13242 if (!ptrarith_typesize)
13245 if (ptrarith_typesize != array_typesize) {
13247 uint64_t ratio = array_typesize / ptrarith_typesize;
13251 if (ptrarith_typesize * ratio == array_typesize)
13252 size *= llvm::APInt(size.getBitWidth(), ratio);
13256 if (size.getBitWidth() > index.getBitWidth())
13257 index = index.zext(size.getBitWidth());
13258 else if (size.getBitWidth() < index.getBitWidth())
13259 size = size.zext(index.getBitWidth());
13265 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
13282 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
13283 : diag::warn_ptr_arith_exceeds_bounds;
13284 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
13292 unsigned DiagID = diag::warn_array_index_precedes_bounds;
13294 DiagID = diag::warn_ptr_arith_precedes_bounds;
13295 if (index.isNegative()) index = -index;
13305 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13307 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13309 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13310 ND = ME->getMemberDecl();
13314 PDiag(diag::note_array_declared_here) << ND);
13317void Sema::CheckArrayAccess(
const Expr *
expr) {
13318 int AllowOnePastEnd = 0;
13320 expr =
expr->IgnoreParenImpCasts();
13321 switch (
expr->getStmtClass()) {
13322 case Stmt::ArraySubscriptExprClass: {
13325 AllowOnePastEnd > 0);
13329 case Stmt::MemberExprClass: {
13330 expr = cast<MemberExpr>(
expr)->getBase();
13333 case Stmt::ArraySectionExprClass: {
13339 nullptr, AllowOnePastEnd > 0);
13342 case Stmt::UnaryOperatorClass: {
13358 case Stmt::ConditionalOperatorClass: {
13361 CheckArrayAccess(lhs);
13363 CheckArrayAccess(rhs);
13366 case Stmt::CXXOperatorCallExprClass: {
13367 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
13368 for (
const auto *Arg : OCE->arguments())
13369 CheckArrayAccess(Arg);
13379 Expr *RHS,
bool isProperty) {
13391 S.
Diag(
Loc, diag::warn_arc_literal_assign)
13393 << (isProperty ? 0 : 1)
13401 Expr *RHS,
bool isProperty) {
13404 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13405 S.
Diag(
Loc, diag::warn_arc_retained_assign)
13407 << (isProperty ? 0 : 1)
13411 RHS =
cast->getSubExpr();
13482 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13483 Diag(
Loc, diag::warn_arc_retained_property_assign)
13487 RHS =
cast->getSubExpr();
13510 bool StmtLineInvalid;
13513 if (StmtLineInvalid)
13516 bool BodyLineInvalid;
13519 if (BodyLineInvalid)
13523 if (StmtLine != BodyLine)
13538 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13547 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13551 const Stmt *PossibleBody) {
13557 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
13558 StmtLoc = FS->getRParenLoc();
13559 Body = FS->getBody();
13560 DiagID = diag::warn_empty_for_body;
13561 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
13562 StmtLoc = WS->getRParenLoc();
13563 Body = WS->getBody();
13564 DiagID = diag::warn_empty_while_body;
13569 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13592 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
13593 if (!ProbableTypo) {
13594 bool BodyColInvalid;
13597 if (BodyColInvalid)
13600 bool StmtColInvalid;
13603 if (StmtColInvalid)
13606 if (BodyCol > StmtCol)
13607 ProbableTypo =
true;
13610 if (ProbableTypo) {
13612 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13620 if (
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
13632 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
13634 RHSExpr = CE->
getArg(0);
13635 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
13636 CXXSCE && CXXSCE->isXValue())
13637 RHSExpr = CXXSCE->getSubExpr();
13641 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
13642 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
13645 if (LHSDeclRef && RHSDeclRef) {
13652 auto D =
Diag(OpLoc, diag::warn_self_move)
13668 const Expr *LHSBase = LHSExpr;
13669 const Expr *RHSBase = RHSExpr;
13670 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
13671 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
13672 if (!LHSME || !RHSME)
13675 while (LHSME && RHSME) {
13682 LHSME = dyn_cast<MemberExpr>(LHSBase);
13683 RHSME = dyn_cast<MemberExpr>(RHSBase);
13686 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
13687 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
13688 if (LHSDeclRef && RHSDeclRef) {
13695 Diag(OpLoc, diag::warn_self_move)
13701 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
13702 Diag(OpLoc, diag::warn_self_move)
13726 bool AreUnionMembers =
false) {
13727 [[maybe_unused]]
const Type *Field1Parent =
13729 [[maybe_unused]]
const Type *Field2Parent =
13734 "Can't evaluate layout compatibility between a struct field and a "
13737 (AreUnionMembers && Field1Parent->
isUnionType())) &&
13738 "AreUnionMembers should be 'true' for union fields (only).");
13751 if (Bits1 != Bits2)
13755 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
13756 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
13759 if (!AreUnionMembers &&
13771 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
13772 RD1 = D1CXX->getStandardLayoutBaseWithFields();
13774 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
13775 RD2 = D2CXX->getStandardLayoutBaseWithFields();
13780 return isLayoutCompatible(C, F1, F2);
13789 for (
auto *Field2 : RD2->
fields())
13790 UnmatchedFields.insert(Field2);
13792 for (
auto *Field1 : RD1->
fields()) {
13793 auto I = UnmatchedFields.begin();
13794 auto E = UnmatchedFields.end();
13796 for ( ; I !=
E; ++I) {
13798 bool Result = UnmatchedFields.erase(*I);
13808 return UnmatchedFields.empty();
13834 if (
C.hasSameType(T1, T2))
13843 if (TC1 == Type::Enum) {
13845 cast<EnumType>(T1)->getDecl(),
13846 cast<EnumType>(T2)->getDecl());
13847 }
else if (TC1 == Type::Record) {
13852 cast<RecordType>(T1)->getDecl(),
13853 cast<RecordType>(T2)->getDecl());
13867 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
13898 const ValueDecl **VD, uint64_t *MagicValue,
13899 bool isConstantEvaluated) {
13907 case Stmt::UnaryOperatorClass: {
13916 case Stmt::DeclRefExprClass: {
13917 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
13922 case Stmt::IntegerLiteralClass: {
13924 llvm::APInt MagicValueAPInt = IL->
getValue();
13925 if (MagicValueAPInt.getActiveBits() <= 64) {
13926 *MagicValue = MagicValueAPInt.getZExtValue();
13932 case Stmt::BinaryConditionalOperatorClass:
13933 case Stmt::ConditionalOperatorClass: {
13935 cast<AbstractConditionalOperator>(TypeExpr);
13938 isConstantEvaluated)) {
13948 case Stmt::BinaryOperatorClass: {
13951 TypeExpr = BO->
getRHS();
13981 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
13984 bool isConstantEvaluated) {
13985 FoundWrongKind =
false;
13990 uint64_t MagicValue;
13992 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
13996 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
13997 if (I->getArgumentKind() != ArgumentKind) {
13998 FoundWrongKind =
true;
14001 TypeInfo.Type = I->getMatchingCType();
14002 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
14003 TypeInfo.MustBeNull = I->getMustBeNull();
14014 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
14015 if (I == MagicValues->end())
14024 bool LayoutCompatible,
14026 if (!TypeTagForDatatypeMagicValues)
14027 TypeTagForDatatypeMagicValues.reset(
14028 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
14031 (*TypeTagForDatatypeMagicValues)[Magic] =
14047 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
14048 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
14049 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
14050 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
14053void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
14057 bool IsPointerAttr =
Attr->getIsPointer();
14060 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
14061 if (TypeTagIdxAST >= ExprArgs.size()) {
14062 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14063 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
14066 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
14067 bool FoundWrongKind;
14070 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
14072 if (FoundWrongKind)
14074 diag::warn_type_tag_for_datatype_wrong_kind)
14080 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
14081 if (ArgumentIdxAST >= ExprArgs.size()) {
14082 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14083 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
14086 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
14087 if (IsPointerAttr) {
14089 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
14090 if (ICE->getType()->isVoidPointerType() &&
14091 ICE->getCastKind() == CK_BitCast)
14092 ArgumentExpr = ICE->getSubExpr();
14105 diag::warn_type_safety_null_pointer_required)
14117 bool mismatch =
false;
14140 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
14141 << ArgumentType << ArgumentKind
14142 <<
TypeInfo.LayoutCompatible << RequiredType
14149 MisalignedMembers.emplace_back(
E, RD, MD, Alignment);
14153 for (MisalignedMember &m : MisalignedMembers) {
14159 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
14162 MisalignedMembers.clear();
14169 if (isa<UnaryOperator>(
E) &&
14170 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
14171 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
14172 if (isa<MemberExpr>(Op)) {
14173 auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
14174 if (MA != MisalignedMembers.end() &&
14179 MisalignedMembers.erase(MA);
14188 const auto *ME = dyn_cast<MemberExpr>(
E);
14200 bool AnyIsPacked =
false;
14202 QualType BaseType = ME->getBase()->getType();
14212 auto *FD = dyn_cast<FieldDecl>(MD);
14218 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
14219 ReverseMemberChain.push_back(FD);
14222 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
14224 assert(TopME &&
"We did not compute a topmost MemberExpr!");
14231 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
14235 if (!DRE && !isa<CXXThisExpr>(TopBase))
14242 if (ExpectedAlignment.
isOne())
14247 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
14252 ReverseMemberChain.back()->getParent()->getTypeForDecl());
14256 if (DRE && !TopME->
isArrow()) {
14259 CompleteObjectAlignment =
14264 if (Offset % ExpectedAlignment != 0 ||
14267 CompleteObjectAlignment < ExpectedAlignment) {
14278 for (
FieldDecl *FDI : ReverseMemberChain) {
14279 if (FDI->hasAttr<PackedAttr>() ||
14280 FDI->getParent()->hasAttr<PackedAttr>()) {
14282 Alignment = std::min(
14288 assert(FD &&
"We did not find a packed FieldDecl!");
14293void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
14294 using namespace std::placeholders;
14297 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
14319bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall) {
14333 TheCall->
setType(VecTy0->getElementType());
14357 diag::err_typecheck_call_different_arg_types)
14369 bool CheckForFloatArgs) {
14374 for (
int I = 0; I < 3; ++I) {
14378 Args[I] = Converted.
get();
14381 if (CheckForFloatArgs) {
14382 int ArgOrdinal = 1;
14383 for (
Expr *Arg : Args) {
14385 Arg->
getType(), ArgOrdinal++))
14389 int ArgOrdinal = 1;
14390 for (
Expr *Arg : Args) {
14397 for (
int I = 1; I < 3; ++I) {
14398 if (Args[0]->getType().getCanonicalType() !=
14399 Args[I]->getType().getCanonicalType()) {
14400 return Diag(Args[0]->getBeginLoc(),
14401 diag::err_typecheck_call_different_arg_types)
14405 TheCall->
setArg(I, Args[I]);
14408 TheCall->
setType(Args[0]->getType());
14412bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
14424bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
14433 << 1 << 0 << TyArg;
14447 Expr *Matrix = MatrixArg.
get();
14452 << 1 << 1 << Matrix->
getType();
14459 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
14462 TheCall->
setType(ResultType);
14465 TheCall->
setArg(0, Matrix);
14470static std::optional<unsigned>
14473 std::optional<llvm::APSInt>
Value =
14480 uint64_t Dim =
Value->getZExtValue();
14499 unsigned PtrArgIdx = 0;
14505 bool ArgError =
false;
14512 PtrExpr = PtrConv.
get();
14513 TheCall->
setArg(0, PtrExpr);
14524 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14531 << PtrArgIdx + 1 << 2
14538 auto ApplyArgumentConversions = [
this](
Expr *
E) {
14547 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
14549 RowsExpr = RowsConv.
get();
14550 TheCall->
setArg(1, RowsExpr);
14552 RowsExpr =
nullptr;
14554 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
14556 ColumnsExpr = ColumnsConv.
get();
14557 TheCall->
setArg(2, ColumnsExpr);
14559 ColumnsExpr =
nullptr;
14570 std::optional<unsigned> MaybeRows;
14574 std::optional<unsigned> MaybeColumns;
14579 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
14582 StrideExpr = StrideConv.
get();
14583 TheCall->
setArg(3, StrideExpr);
14586 if (std::optional<llvm::APSInt>
Value =
14589 if (Stride < *MaybeRows) {
14591 diag::err_builtin_matrix_stride_too_small);
14597 if (ArgError || !MaybeRows || !MaybeColumns)
14610 unsigned PtrArgIdx = 1;
14615 bool ArgError =
false;
14621 MatrixExpr = MatrixConv.
get();
14622 TheCall->
setArg(0, MatrixExpr);
14632 << 1 << 1 << MatrixExpr->
getType();
14640 PtrExpr = PtrConv.
get();
14641 TheCall->
setArg(1, PtrExpr);
14652 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14657 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
14664 diag::err_builtin_matrix_pointer_arg_mismatch)
14665 << ElementTy << MatrixTy->getElementType();
14680 StrideExpr = StrideConv.
get();
14681 TheCall->
setArg(2, StrideExpr);
14686 if (std::optional<llvm::APSInt>
Value =
14689 if (Stride < MatrixTy->getNumRows()) {
14691 diag::err_builtin_matrix_stride_too_small);
14711 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
14716 llvm::StringSet<> CalleeTCBs;
14717 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
14718 CalleeTCBs.insert(A->getTCBName());
14719 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
14720 CalleeTCBs.insert(A->getTCBName());
14724 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
14725 StringRef CallerTCB = A->getTCBName();
14726 if (CalleeTCBs.count(CallerTCB) == 0) {
14727 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
14728 << 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 IntRange GetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Pseudo-evaluate the given integer expression, estimating the range of values it might take.
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 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 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.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Defines the TargetCXXABI class, which abstracts details of the C++ ABI that we're targeting.
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
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
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
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.
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
bool BuiltinVectorMath(CallExpr *TheCall, QualType &Res)
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...
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
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
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)
The JSON file list parser is used to communicate input to InstallAPI.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
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.
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.