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();
1481enum PointerAuthOpKind {
1530 llvm::raw_svector_ostream Str(
Value);
1539 Result = KeyValue->getZExtValue();
1543static std::pair<const ValueDecl *, CharUnits>
1550 const auto *BaseDecl =
1555 return {BaseDecl,
Result.Val.getLValueOffset()};
1559 bool RequireConstant =
false) {
1567 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1568 return OpKind != PAO_BlendInteger;
1570 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1571 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1572 OpKind == PAO_SignGeneric;
1581 }
else if (AllowsInteger(OpKind) &&
1588 <<
unsigned(OpKind == PAO_Discriminator ? 1
1589 : OpKind == PAO_BlendPointer ? 2
1590 : OpKind == PAO_BlendInteger ? 3
1592 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1602 if (!RequireConstant) {
1604 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1607 ? diag::warn_ptrauth_sign_null_pointer
1608 : diag::warn_ptrauth_auth_null_pointer)
1618 if (OpKind == PAO_Sign) {
1628 else if (isa<FunctionDecl>(BaseDecl))
1636 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1641 assert(OpKind == PAO_Discriminator);
1647 if (
Call->getBuiltinCallee() ==
1648 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1663 assert(
Pointer->getType()->isPointerType());
1669 if (!BaseDecl || !isa<VarDecl>(BaseDecl))
1675 assert(
Integer->getType()->isIntegerType());
1681 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1694 Call->setType(
Call->getArgs()[0]->getType());
1725 PointerAuthOpKind OpKind,
1726 bool RequireConstant) {
1737 Call->setType(
Call->getArgs()[0]->getType());
1753 Call->setType(
Call->getArgs()[0]->getType());
1762 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1765 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1766 if (!Literal || Literal->getCharByteWidth() != 1) {
1796 auto DiagSelect = [&]() -> std::optional<unsigned> {
1803 return std::optional<unsigned>{};
1818 diag::err_incomplete_type))
1822 "Unhandled non-object pointer case");
1840 llvm::Triple::ObjectFormatType CurObjFormat =
1842 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
1855 llvm::Triple::ArchType CurArch =
1857 if (llvm::is_contained(SupportedArchs, CurArch))
1867bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
1874 case llvm::Triple::arm:
1875 case llvm::Triple::armeb:
1876 case llvm::Triple::thumb:
1877 case llvm::Triple::thumbeb:
1879 case llvm::Triple::aarch64:
1880 case llvm::Triple::aarch64_32:
1881 case llvm::Triple::aarch64_be:
1883 case llvm::Triple::bpfeb:
1884 case llvm::Triple::bpfel:
1886 case llvm::Triple::hexagon:
1888 case llvm::Triple::mips:
1889 case llvm::Triple::mipsel:
1890 case llvm::Triple::mips64:
1891 case llvm::Triple::mips64el:
1893 case llvm::Triple::systemz:
1895 case llvm::Triple::x86:
1896 case llvm::Triple::x86_64:
1898 case llvm::Triple::ppc:
1899 case llvm::Triple::ppcle:
1900 case llvm::Triple::ppc64:
1901 case llvm::Triple::ppc64le:
1903 case llvm::Triple::amdgcn:
1905 case llvm::Triple::riscv32:
1906 case llvm::Triple::riscv64:
1908 case llvm::Triple::loongarch32:
1909 case llvm::Triple::loongarch64:
1912 case llvm::Triple::wasm32:
1913 case llvm::Triple::wasm64:
1915 case llvm::Triple::nvptx:
1916 case llvm::Triple::nvptx64:
1928 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1929 << ArgIndex << 0 << ArgTy;
1939 EltTy = VecTy->getElementType();
1942 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1943 << ArgIndex << 5 << ArgTy;
1953 const TargetInfo *AuxTI,
unsigned BuiltinID) {
1954 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
1955 BuiltinID == Builtin::BI__builtin_cpu_is) &&
1956 "Expecting __builtin_cpu_...");
1958 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
1960 auto SupportsBI = [=](
const TargetInfo *TInfo) {
1961 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
1962 (!IsCPUSupports && TInfo->supportsCpuIs()));
1964 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
1971 ? diag::err_builtin_aix_os_unsupported
1972 : diag::err_builtin_target_unsupported)
1977 if (!isa<StringLiteral>(Arg))
1978 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
1982 StringRef Feature = cast<StringLiteral>(Arg)->getString();
2029 TheCall->
setArg(0, Arg0);
2035 << 1 << 7 << Arg0Ty;
2045 TheCall->
setArg(1, Arg1);
2051 << 2 << 8 << Arg1Ty;
2060Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2065 unsigned ICEArguments = 0;
2072 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2074 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2079 if (ArgNo < TheCall->getNumArgs() &&
2082 ICEArguments &= ~(1 << ArgNo);
2086 switch (BuiltinID) {
2087 case Builtin::BI__builtin_cpu_supports:
2088 case Builtin::BI__builtin_cpu_is:
2093 case Builtin::BI__builtin_cpu_init:
2100 case Builtin::BI__builtin___CFStringMakeConstantString:
2104 *
this, BuiltinID, TheCall,
2105 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2108 "Wrong # arguments to builtin CFStringMakeConstantString");
2109 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2112 case Builtin::BI__builtin_ms_va_start:
2113 case Builtin::BI__builtin_stdarg_start:
2114 case Builtin::BI__builtin_va_start:
2115 if (BuiltinVAStart(BuiltinID, TheCall))
2118 case Builtin::BI__va_start: {
2120 case llvm::Triple::aarch64:
2121 case llvm::Triple::arm:
2122 case llvm::Triple::thumb:
2123 if (BuiltinVAStartARMMicrosoft(TheCall))
2127 if (BuiltinVAStart(BuiltinID, TheCall))
2135 case Builtin::BI_interlockedbittestandset_acq:
2136 case Builtin::BI_interlockedbittestandset_rel:
2137 case Builtin::BI_interlockedbittestandset_nf:
2138 case Builtin::BI_interlockedbittestandreset_acq:
2139 case Builtin::BI_interlockedbittestandreset_rel:
2140 case Builtin::BI_interlockedbittestandreset_nf:
2142 *
this, BuiltinID, TheCall,
2143 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2148 case Builtin::BI_bittest64:
2149 case Builtin::BI_bittestandcomplement64:
2150 case Builtin::BI_bittestandreset64:
2151 case Builtin::BI_bittestandset64:
2152 case Builtin::BI_interlockedbittestandreset64:
2153 case Builtin::BI_interlockedbittestandset64:
2155 *
this, BuiltinID, TheCall,
2156 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2157 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2161 case Builtin::BI__builtin_set_flt_rounds:
2163 *
this, BuiltinID, TheCall,
2164 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2165 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2169 case Builtin::BI__builtin_isgreater:
2170 case Builtin::BI__builtin_isgreaterequal:
2171 case Builtin::BI__builtin_isless:
2172 case Builtin::BI__builtin_islessequal:
2173 case Builtin::BI__builtin_islessgreater:
2174 case Builtin::BI__builtin_isunordered:
2175 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2178 case Builtin::BI__builtin_fpclassify:
2179 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2182 case Builtin::BI__builtin_isfpclass:
2183 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2186 case Builtin::BI__builtin_isfinite:
2187 case Builtin::BI__builtin_isinf:
2188 case Builtin::BI__builtin_isinf_sign:
2189 case Builtin::BI__builtin_isnan:
2190 case Builtin::BI__builtin_issignaling:
2191 case Builtin::BI__builtin_isnormal:
2192 case Builtin::BI__builtin_issubnormal:
2193 case Builtin::BI__builtin_iszero:
2194 case Builtin::BI__builtin_signbit:
2195 case Builtin::BI__builtin_signbitf:
2196 case Builtin::BI__builtin_signbitl:
2197 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2200 case Builtin::BI__builtin_shufflevector:
2204 case Builtin::BI__builtin_prefetch:
2205 if (BuiltinPrefetch(TheCall))
2208 case Builtin::BI__builtin_alloca_with_align:
2209 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2210 if (BuiltinAllocaWithAlign(TheCall))
2213 case Builtin::BI__builtin_alloca:
2214 case Builtin::BI__builtin_alloca_uninitialized:
2218 case Builtin::BI__arithmetic_fence:
2219 if (BuiltinArithmeticFence(TheCall))
2222 case Builtin::BI__assume:
2223 case Builtin::BI__builtin_assume:
2224 if (BuiltinAssume(TheCall))
2227 case Builtin::BI__builtin_assume_aligned:
2228 if (BuiltinAssumeAligned(TheCall))
2231 case Builtin::BI__builtin_dynamic_object_size:
2232 case Builtin::BI__builtin_object_size:
2236 case Builtin::BI__builtin_longjmp:
2237 if (BuiltinLongjmp(TheCall))
2240 case Builtin::BI__builtin_setjmp:
2241 if (BuiltinSetjmp(TheCall))
2244 case Builtin::BI__builtin_classify_type:
2249 case Builtin::BI__builtin_complex:
2250 if (BuiltinComplex(TheCall))
2253 case Builtin::BI__builtin_constant_p: {
2262 case Builtin::BI__builtin_launder:
2264 case Builtin::BI__sync_fetch_and_add:
2265 case Builtin::BI__sync_fetch_and_add_1:
2266 case Builtin::BI__sync_fetch_and_add_2:
2267 case Builtin::BI__sync_fetch_and_add_4:
2268 case Builtin::BI__sync_fetch_and_add_8:
2269 case Builtin::BI__sync_fetch_and_add_16:
2270 case Builtin::BI__sync_fetch_and_sub:
2271 case Builtin::BI__sync_fetch_and_sub_1:
2272 case Builtin::BI__sync_fetch_and_sub_2:
2273 case Builtin::BI__sync_fetch_and_sub_4:
2274 case Builtin::BI__sync_fetch_and_sub_8:
2275 case Builtin::BI__sync_fetch_and_sub_16:
2276 case Builtin::BI__sync_fetch_and_or:
2277 case Builtin::BI__sync_fetch_and_or_1:
2278 case Builtin::BI__sync_fetch_and_or_2:
2279 case Builtin::BI__sync_fetch_and_or_4:
2280 case Builtin::BI__sync_fetch_and_or_8:
2281 case Builtin::BI__sync_fetch_and_or_16:
2282 case Builtin::BI__sync_fetch_and_and:
2283 case Builtin::BI__sync_fetch_and_and_1:
2284 case Builtin::BI__sync_fetch_and_and_2:
2285 case Builtin::BI__sync_fetch_and_and_4:
2286 case Builtin::BI__sync_fetch_and_and_8:
2287 case Builtin::BI__sync_fetch_and_and_16:
2288 case Builtin::BI__sync_fetch_and_xor:
2289 case Builtin::BI__sync_fetch_and_xor_1:
2290 case Builtin::BI__sync_fetch_and_xor_2:
2291 case Builtin::BI__sync_fetch_and_xor_4:
2292 case Builtin::BI__sync_fetch_and_xor_8:
2293 case Builtin::BI__sync_fetch_and_xor_16:
2294 case Builtin::BI__sync_fetch_and_nand:
2295 case Builtin::BI__sync_fetch_and_nand_1:
2296 case Builtin::BI__sync_fetch_and_nand_2:
2297 case Builtin::BI__sync_fetch_and_nand_4:
2298 case Builtin::BI__sync_fetch_and_nand_8:
2299 case Builtin::BI__sync_fetch_and_nand_16:
2300 case Builtin::BI__sync_add_and_fetch:
2301 case Builtin::BI__sync_add_and_fetch_1:
2302 case Builtin::BI__sync_add_and_fetch_2:
2303 case Builtin::BI__sync_add_and_fetch_4:
2304 case Builtin::BI__sync_add_and_fetch_8:
2305 case Builtin::BI__sync_add_and_fetch_16:
2306 case Builtin::BI__sync_sub_and_fetch:
2307 case Builtin::BI__sync_sub_and_fetch_1:
2308 case Builtin::BI__sync_sub_and_fetch_2:
2309 case Builtin::BI__sync_sub_and_fetch_4:
2310 case Builtin::BI__sync_sub_and_fetch_8:
2311 case Builtin::BI__sync_sub_and_fetch_16:
2312 case Builtin::BI__sync_and_and_fetch:
2313 case Builtin::BI__sync_and_and_fetch_1:
2314 case Builtin::BI__sync_and_and_fetch_2:
2315 case Builtin::BI__sync_and_and_fetch_4:
2316 case Builtin::BI__sync_and_and_fetch_8:
2317 case Builtin::BI__sync_and_and_fetch_16:
2318 case Builtin::BI__sync_or_and_fetch:
2319 case Builtin::BI__sync_or_and_fetch_1:
2320 case Builtin::BI__sync_or_and_fetch_2:
2321 case Builtin::BI__sync_or_and_fetch_4:
2322 case Builtin::BI__sync_or_and_fetch_8:
2323 case Builtin::BI__sync_or_and_fetch_16:
2324 case Builtin::BI__sync_xor_and_fetch:
2325 case Builtin::BI__sync_xor_and_fetch_1:
2326 case Builtin::BI__sync_xor_and_fetch_2:
2327 case Builtin::BI__sync_xor_and_fetch_4:
2328 case Builtin::BI__sync_xor_and_fetch_8:
2329 case Builtin::BI__sync_xor_and_fetch_16:
2330 case Builtin::BI__sync_nand_and_fetch:
2331 case Builtin::BI__sync_nand_and_fetch_1:
2332 case Builtin::BI__sync_nand_and_fetch_2:
2333 case Builtin::BI__sync_nand_and_fetch_4:
2334 case Builtin::BI__sync_nand_and_fetch_8:
2335 case Builtin::BI__sync_nand_and_fetch_16:
2336 case Builtin::BI__sync_val_compare_and_swap:
2337 case Builtin::BI__sync_val_compare_and_swap_1:
2338 case Builtin::BI__sync_val_compare_and_swap_2:
2339 case Builtin::BI__sync_val_compare_and_swap_4:
2340 case Builtin::BI__sync_val_compare_and_swap_8:
2341 case Builtin::BI__sync_val_compare_and_swap_16:
2342 case Builtin::BI__sync_bool_compare_and_swap:
2343 case Builtin::BI__sync_bool_compare_and_swap_1:
2344 case Builtin::BI__sync_bool_compare_and_swap_2:
2345 case Builtin::BI__sync_bool_compare_and_swap_4:
2346 case Builtin::BI__sync_bool_compare_and_swap_8:
2347 case Builtin::BI__sync_bool_compare_and_swap_16:
2348 case Builtin::BI__sync_lock_test_and_set:
2349 case Builtin::BI__sync_lock_test_and_set_1:
2350 case Builtin::BI__sync_lock_test_and_set_2:
2351 case Builtin::BI__sync_lock_test_and_set_4:
2352 case Builtin::BI__sync_lock_test_and_set_8:
2353 case Builtin::BI__sync_lock_test_and_set_16:
2354 case Builtin::BI__sync_lock_release:
2355 case Builtin::BI__sync_lock_release_1:
2356 case Builtin::BI__sync_lock_release_2:
2357 case Builtin::BI__sync_lock_release_4:
2358 case Builtin::BI__sync_lock_release_8:
2359 case Builtin::BI__sync_lock_release_16:
2360 case Builtin::BI__sync_swap:
2361 case Builtin::BI__sync_swap_1:
2362 case Builtin::BI__sync_swap_2:
2363 case Builtin::BI__sync_swap_4:
2364 case Builtin::BI__sync_swap_8:
2365 case Builtin::BI__sync_swap_16:
2366 return BuiltinAtomicOverloaded(TheCallResult);
2367 case Builtin::BI__sync_synchronize:
2371 case Builtin::BI__builtin_nontemporal_load:
2372 case Builtin::BI__builtin_nontemporal_store:
2373 return BuiltinNontemporalOverloaded(TheCallResult);
2374 case Builtin::BI__builtin_memcpy_inline: {
2387 case Builtin::BI__builtin_memset_inline: {
2398#define BUILTIN(ID, TYPE, ATTRS)
2399#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2400 case Builtin::BI##ID: \
2401 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2402#include "clang/Basic/Builtins.inc"
2403 case Builtin::BI__annotation:
2407 case Builtin::BI__builtin_annotation:
2411 case Builtin::BI__builtin_addressof:
2415 case Builtin::BI__builtin_function_start:
2419 case Builtin::BI__builtin_is_aligned:
2420 case Builtin::BI__builtin_align_up:
2421 case Builtin::BI__builtin_align_down:
2425 case Builtin::BI__builtin_add_overflow:
2426 case Builtin::BI__builtin_sub_overflow:
2427 case Builtin::BI__builtin_mul_overflow:
2431 case Builtin::BI__builtin_operator_new:
2432 case Builtin::BI__builtin_operator_delete: {
2433 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2435 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2440 case Builtin::BI__builtin_dump_struct:
2442 case Builtin::BI__builtin_expect_with_probability: {
2453 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2460 bool LoseInfo =
false;
2461 Probability.convert(llvm::APFloat::IEEEdouble(),
2462 llvm::RoundingMode::Dynamic, &LoseInfo);
2463 if (!(Probability >= llvm::APFloat(0.0) &&
2464 Probability <= llvm::APFloat(1.0))) {
2471 case Builtin::BI__builtin_preserve_access_index:
2475 case Builtin::BI__builtin_call_with_static_chain:
2479 case Builtin::BI__exception_code:
2480 case Builtin::BI_exception_code:
2482 diag::err_seh___except_block))
2485 case Builtin::BI__exception_info:
2486 case Builtin::BI_exception_info:
2488 diag::err_seh___except_filter))
2491 case Builtin::BI__GetExceptionInfo:
2503 case Builtin::BIaddressof:
2504 case Builtin::BI__addressof:
2505 case Builtin::BIforward:
2506 case Builtin::BIforward_like:
2507 case Builtin::BImove:
2508 case Builtin::BImove_if_noexcept:
2509 case Builtin::BIas_const: {
2517 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
2518 BuiltinID == Builtin::BI__addressof;
2520 (ReturnsPointer ?
Result->isAnyPointerType()
2521 :
Result->isReferenceType()) &&
2523 Result->getPointeeType()))) {
2524 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
2530 case Builtin::BI__builtin_ptrauth_strip:
2532 case Builtin::BI__builtin_ptrauth_blend_discriminator:
2534 case Builtin::BI__builtin_ptrauth_sign_constant:
2537 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
2540 case Builtin::BI__builtin_ptrauth_auth:
2543 case Builtin::BI__builtin_ptrauth_sign_generic_data:
2545 case Builtin::BI__builtin_ptrauth_auth_and_resign:
2547 case Builtin::BI__builtin_ptrauth_string_discriminator:
2550 case Builtin::BIread_pipe:
2551 case Builtin::BIwrite_pipe:
2554 if (
OpenCL().checkBuiltinRWPipe(TheCall))
2557 case Builtin::BIreserve_read_pipe:
2558 case Builtin::BIreserve_write_pipe:
2559 case Builtin::BIwork_group_reserve_read_pipe:
2560 case Builtin::BIwork_group_reserve_write_pipe:
2561 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
2564 case Builtin::BIsub_group_reserve_read_pipe:
2565 case Builtin::BIsub_group_reserve_write_pipe:
2566 if (
OpenCL().checkSubgroupExt(TheCall) ||
2567 OpenCL().checkBuiltinReserveRWPipe(TheCall))
2570 case Builtin::BIcommit_read_pipe:
2571 case Builtin::BIcommit_write_pipe:
2572 case Builtin::BIwork_group_commit_read_pipe:
2573 case Builtin::BIwork_group_commit_write_pipe:
2574 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
2577 case Builtin::BIsub_group_commit_read_pipe:
2578 case Builtin::BIsub_group_commit_write_pipe:
2579 if (
OpenCL().checkSubgroupExt(TheCall) ||
2580 OpenCL().checkBuiltinCommitRWPipe(TheCall))
2583 case Builtin::BIget_pipe_num_packets:
2584 case Builtin::BIget_pipe_max_packets:
2585 if (
OpenCL().checkBuiltinPipePackets(TheCall))
2588 case Builtin::BIto_global:
2589 case Builtin::BIto_local:
2590 case Builtin::BIto_private:
2591 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
2595 case Builtin::BIenqueue_kernel:
2596 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
2599 case Builtin::BIget_kernel_work_group_size:
2600 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
2601 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
2604 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2605 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
2606 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
2609 case Builtin::BI__builtin_os_log_format:
2612 case Builtin::BI__builtin_os_log_format_buffer_size:
2613 if (BuiltinOSLogFormat(TheCall))
2616 case Builtin::BI__builtin_frame_address:
2617 case Builtin::BI__builtin_return_address: {
2626 Result.Val.getInt() != 0)
2628 << ((BuiltinID == Builtin::BI__builtin_return_address)
2629 ?
"__builtin_return_address"
2630 :
"__builtin_frame_address")
2635 case Builtin::BI__builtin_nondeterministic_value: {
2636 if (BuiltinNonDeterministicValue(TheCall))
2643 case Builtin::BI__builtin_elementwise_abs: {
2651 EltTy = VecTy->getElementType();
2654 diag::err_builtin_invalid_arg_type)
2663 case Builtin::BI__builtin_elementwise_acos:
2664 case Builtin::BI__builtin_elementwise_asin:
2665 case Builtin::BI__builtin_elementwise_atan:
2666 case Builtin::BI__builtin_elementwise_ceil:
2667 case Builtin::BI__builtin_elementwise_cos:
2668 case Builtin::BI__builtin_elementwise_cosh:
2669 case Builtin::BI__builtin_elementwise_exp:
2670 case Builtin::BI__builtin_elementwise_exp2:
2671 case Builtin::BI__builtin_elementwise_floor:
2672 case Builtin::BI__builtin_elementwise_log:
2673 case Builtin::BI__builtin_elementwise_log2:
2674 case Builtin::BI__builtin_elementwise_log10:
2675 case Builtin::BI__builtin_elementwise_roundeven:
2676 case Builtin::BI__builtin_elementwise_round:
2677 case Builtin::BI__builtin_elementwise_rint:
2678 case Builtin::BI__builtin_elementwise_nearbyint:
2679 case Builtin::BI__builtin_elementwise_sin:
2680 case Builtin::BI__builtin_elementwise_sinh:
2681 case Builtin::BI__builtin_elementwise_sqrt:
2682 case Builtin::BI__builtin_elementwise_tan:
2683 case Builtin::BI__builtin_elementwise_tanh:
2684 case Builtin::BI__builtin_elementwise_trunc:
2685 case Builtin::BI__builtin_elementwise_canonicalize: {
2695 case Builtin::BI__builtin_elementwise_fma: {
2703 case Builtin::BI__builtin_elementwise_pow: {
2704 if (BuiltinElementwiseMath(TheCall))
2718 case Builtin::BI__builtin_elementwise_add_sat:
2719 case Builtin::BI__builtin_elementwise_sub_sat: {
2720 if (BuiltinElementwiseMath(TheCall))
2728 EltTy = VecTy->getElementType();
2738 case Builtin::BI__builtin_elementwise_min:
2739 case Builtin::BI__builtin_elementwise_max:
2740 if (BuiltinElementwiseMath(TheCall))
2744 case Builtin::BI__builtin_elementwise_bitreverse: {
2753 EltTy = VecTy->getElementType();
2763 case Builtin::BI__builtin_elementwise_copysign: {
2783 diag::err_typecheck_call_different_arg_types)
2784 << MagnitudeTy << SignTy;
2792 case Builtin::BI__builtin_reduce_max:
2793 case Builtin::BI__builtin_reduce_min: {
2794 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2802 ElTy = TyA->getElementType();
2806 if (ElTy.isNull()) {
2818 case Builtin::BI__builtin_reduce_add:
2819 case Builtin::BI__builtin_reduce_mul:
2820 case Builtin::BI__builtin_reduce_xor:
2821 case Builtin::BI__builtin_reduce_or:
2822 case Builtin::BI__builtin_reduce_and: {
2823 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2831 ElTy = TyA->getElementType();
2835 if (ElTy.isNull() || !ElTy->isIntegerType()) {
2845 case Builtin::BI__builtin_matrix_transpose:
2846 return BuiltinMatrixTranspose(TheCall, TheCallResult);
2848 case Builtin::BI__builtin_matrix_column_major_load:
2849 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
2851 case Builtin::BI__builtin_matrix_column_major_store:
2852 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
2854 case Builtin::BI__builtin_verbose_trap:
2859 case Builtin::BI__builtin_get_device_side_mangled_name: {
2860 auto Check = [](
CallExpr *TheCall) {
2866 auto *
D = DRE->getDecl();
2867 if (!isa<FunctionDecl>(
D) && !isa<VarDecl>(
D))
2872 if (!Check(TheCall)) {
2874 diag::err_hip_invalid_args_builtin_mangled_name);
2879 case Builtin::BI__builtin_popcountg:
2883 case Builtin::BI__builtin_clzg:
2884 case Builtin::BI__builtin_ctzg:
2889 case Builtin::BI__builtin_allow_runtime_check: {
2909 "Aux Target Builtin, but not an aux target?");
2911 if (CheckTSBuiltinFunctionCall(
2922 return TheCallResult;
2937 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
2941 diag::err_argument_not_contiguous_bit_field)
2947 if (Format->getFirstArg() == 0)
2949 else if (IsVariadic)
2953 FSI->
FormatIdx = Format->getFormatIdx() - 1;
2977 if (isa<CXXNullPtrLiteralExpr>(
2992 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
2993 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
2994 Expr = ILE->getInit(0);
3004 const Expr *ArgExpr,
3008 S.
PDiag(diag::warn_null_arg)
3014 if (
auto nullability =
type->getNullability())
3025 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3031 llvm::SmallBitVector NonNullArgs;
3037 for (
const auto *Arg : Args)
3044 unsigned IdxAST = Idx.getASTIndex();
3045 if (IdxAST >= Args.size())
3047 if (NonNullArgs.empty())
3048 NonNullArgs.resize(Args.size());
3049 NonNullArgs.set(IdxAST);
3054 if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {
3058 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3061 parms = cast<ObjCMethodDecl>(FDecl)->parameters();
3063 unsigned ParamIndex = 0;
3065 I !=
E; ++I, ++ParamIndex) {
3068 if (NonNullArgs.empty())
3069 NonNullArgs.resize(Args.size());
3071 NonNullArgs.set(ParamIndex);
3078 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3083 type = blockType->getPointeeType();
3097 if (NonNullArgs.empty())
3098 NonNullArgs.resize(Args.size());
3100 NonNullArgs.set(Index);
3109 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3110 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3111 if (NonNullArgs[ArgIndex])
3117 StringRef ParamName,
QualType ArgTy,
3145 if (ArgAlign < ParamAlign)
3146 Diag(
Loc, diag::warn_param_mismatched_alignment)
3148 << ParamName << (FDecl !=
nullptr) << FDecl;
3160 llvm::SmallBitVector CheckedVarArgs;
3164 CheckedVarArgs.resize(Args.size());
3166 CheckFormatArguments(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3173 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3177 : isa_and_nonnull<FunctionDecl>(FDecl)
3178 ? cast<FunctionDecl>(FDecl)->getNumParams()
3179 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3180 ? cast<ObjCMethodDecl>(FDecl)->param_size()
3183 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3185 if (
const Expr *Arg = Args[ArgIdx]) {
3186 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3192 if (FDecl || Proto) {
3197 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3198 CheckArgumentWithTypeTag(I, Args,
Loc);
3204 if (!Proto && FDecl) {
3206 if (isa_and_nonnull<FunctionProtoType>(FT))
3212 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3214 bool IsScalableArg =
false;
3215 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3217 if (
const Expr *Arg = Args[ArgIdx]) {
3229 IsScalableArg =
true;
3231 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3240 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3241 llvm::StringMap<bool> CallerFeatureMap;
3243 if (!CallerFeatureMap.contains(
"sme"))
3244 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3246 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3253 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3255 (IsScalableArg || IsScalableRet)) {
3256 bool IsCalleeStreaming =
3258 bool IsCalleeStreamingCompatible =
3262 if (!IsCalleeStreamingCompatible &&
3266 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3269 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3280 bool CallerHasZAState =
false;
3281 bool CallerHasZT0State =
false;
3283 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3285 CallerHasZAState =
true;
3287 CallerHasZT0State =
true;
3291 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3293 CallerHasZT0State |=
3295 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3301 Diag(
Loc, diag::err_sme_za_call_no_za_state);
3304 Diag(
Loc, diag::err_sme_zt0_call_no_zt0_state);
3308 Diag(
Loc, diag::err_sme_unimplemented_za_save_restore);
3309 Diag(
Loc, diag::note_sme_use_preserves_za);
3314 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3315 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3316 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3317 if (!Arg->isValueDependent()) {
3319 if (Arg->EvaluateAsInt(Align,
Context)) {
3320 const llvm::APSInt &I = Align.
Val.
getInt();
3321 if (!I.isPowerOf2())
3322 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3323 << Arg->getSourceRange();
3326 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3349 auto *Ctor = cast<CXXConstructorDecl>(FDecl);
3354 checkCall(FDecl, Proto,
nullptr, Args,
true,
3360 bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
3361 isa<CXXMethodDecl>(FDecl);
3362 bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
3363 IsMemberOperatorCall;
3369 Expr *ImplicitThis =
nullptr;
3374 ImplicitThis = Args[0];
3377 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
3380 cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
3392 cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());
3394 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
3412 CheckAbsoluteValueFunction(TheCall, FDecl);
3413 CheckMaxUnsignedZero(TheCall, FDecl);
3414 CheckInfNaNFunction(TheCall, FDecl);
3425 case Builtin::BIstrlcpy:
3426 case Builtin::BIstrlcat:
3427 CheckStrlcpycatArguments(TheCall, FnInfo);
3429 case Builtin::BIstrncat:
3430 CheckStrncatArguments(TheCall, FnInfo);
3432 case Builtin::BIfree:
3433 CheckFreeArguments(TheCall);
3436 CheckMemaccessArguments(TheCall, CMId, FnInfo);
3445 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
3446 Ty =
V->getType().getNonReferenceType();
3447 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
3448 Ty = F->getType().getNonReferenceType();
3485 if (!llvm::isValidAtomicOrderingCABI(Ordering))
3488 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
3490 case AtomicExpr::AO__c11_atomic_init:
3491 case AtomicExpr::AO__opencl_atomic_init:
3492 llvm_unreachable(
"There is no ordering argument for an init");
3494 case AtomicExpr::AO__c11_atomic_load:
3495 case AtomicExpr::AO__opencl_atomic_load:
3496 case AtomicExpr::AO__hip_atomic_load:
3497 case AtomicExpr::AO__atomic_load_n:
3498 case AtomicExpr::AO__atomic_load:
3499 case AtomicExpr::AO__scoped_atomic_load_n:
3500 case AtomicExpr::AO__scoped_atomic_load:
3501 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
3502 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3504 case AtomicExpr::AO__c11_atomic_store:
3505 case AtomicExpr::AO__opencl_atomic_store:
3506 case AtomicExpr::AO__hip_atomic_store:
3507 case AtomicExpr::AO__atomic_store:
3508 case AtomicExpr::AO__atomic_store_n:
3509 case AtomicExpr::AO__scoped_atomic_store:
3510 case AtomicExpr::AO__scoped_atomic_store_n:
3511 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
3512 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
3513 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3522 CallExpr *TheCall = cast<CallExpr>(TheCallResult.
get());
3566 const unsigned NumForm = GNUCmpXchg + 1;
3567 const unsigned NumArgs[] = { 2, 2, 3, 3, 3, 3, 4, 5, 6 };
3568 const unsigned NumVals[] = { 1, 0, 1, 1, 1, 1, 2, 2, 3 };
3576 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
3577 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
3578 "need to update code for modified forms");
3579 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
3580 AtomicExpr::AO__atomic_xor_fetch + 1 ==
3581 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
3582 "need to update code for modified C11 atomics");
3583 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
3584 Op <= AtomicExpr::AO__opencl_atomic_store;
3585 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
3586 Op <= AtomicExpr::AO__hip_atomic_store;
3587 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
3588 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
3589 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
3590 Op <= AtomicExpr::AO__c11_atomic_store) ||
3592 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
3593 Op == AtomicExpr::AO__atomic_store_n ||
3594 Op == AtomicExpr::AO__atomic_exchange_n ||
3595 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
3596 Op == AtomicExpr::AO__scoped_atomic_load_n ||
3597 Op == AtomicExpr::AO__scoped_atomic_store_n ||
3598 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
3599 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
3603 enum ArithOpExtraValueType {
3608 unsigned ArithAllows = AOEVT_None;
3611 case AtomicExpr::AO__c11_atomic_init:
3612 case AtomicExpr::AO__opencl_atomic_init:
3616 case AtomicExpr::AO__c11_atomic_load:
3617 case AtomicExpr::AO__opencl_atomic_load:
3618 case AtomicExpr::AO__hip_atomic_load:
3619 case AtomicExpr::AO__atomic_load_n:
3620 case AtomicExpr::AO__scoped_atomic_load_n:
3624 case AtomicExpr::AO__atomic_load:
3625 case AtomicExpr::AO__scoped_atomic_load:
3629 case AtomicExpr::AO__c11_atomic_store:
3630 case AtomicExpr::AO__opencl_atomic_store:
3631 case AtomicExpr::AO__hip_atomic_store:
3632 case AtomicExpr::AO__atomic_store:
3633 case AtomicExpr::AO__atomic_store_n:
3634 case AtomicExpr::AO__scoped_atomic_store:
3635 case AtomicExpr::AO__scoped_atomic_store_n:
3638 case AtomicExpr::AO__atomic_fetch_add:
3639 case AtomicExpr::AO__atomic_fetch_sub:
3640 case AtomicExpr::AO__atomic_add_fetch:
3641 case AtomicExpr::AO__atomic_sub_fetch:
3642 case AtomicExpr::AO__scoped_atomic_fetch_add:
3643 case AtomicExpr::AO__scoped_atomic_fetch_sub:
3644 case AtomicExpr::AO__scoped_atomic_add_fetch:
3645 case AtomicExpr::AO__scoped_atomic_sub_fetch:
3646 case AtomicExpr::AO__c11_atomic_fetch_add:
3647 case AtomicExpr::AO__c11_atomic_fetch_sub:
3648 case AtomicExpr::AO__opencl_atomic_fetch_add:
3649 case AtomicExpr::AO__opencl_atomic_fetch_sub:
3650 case AtomicExpr::AO__hip_atomic_fetch_add:
3651 case AtomicExpr::AO__hip_atomic_fetch_sub:
3652 ArithAllows = AOEVT_Pointer | AOEVT_FP;
3655 case AtomicExpr::AO__atomic_fetch_max:
3656 case AtomicExpr::AO__atomic_fetch_min:
3657 case AtomicExpr::AO__atomic_max_fetch:
3658 case AtomicExpr::AO__atomic_min_fetch:
3659 case AtomicExpr::AO__scoped_atomic_fetch_max:
3660 case AtomicExpr::AO__scoped_atomic_fetch_min:
3661 case AtomicExpr::AO__scoped_atomic_max_fetch:
3662 case AtomicExpr::AO__scoped_atomic_min_fetch:
3663 case AtomicExpr::AO__c11_atomic_fetch_max:
3664 case AtomicExpr::AO__c11_atomic_fetch_min:
3665 case AtomicExpr::AO__opencl_atomic_fetch_max:
3666 case AtomicExpr::AO__opencl_atomic_fetch_min:
3667 case AtomicExpr::AO__hip_atomic_fetch_max:
3668 case AtomicExpr::AO__hip_atomic_fetch_min:
3669 ArithAllows = AOEVT_FP;
3672 case AtomicExpr::AO__c11_atomic_fetch_and:
3673 case AtomicExpr::AO__c11_atomic_fetch_or:
3674 case AtomicExpr::AO__c11_atomic_fetch_xor:
3675 case AtomicExpr::AO__hip_atomic_fetch_and:
3676 case AtomicExpr::AO__hip_atomic_fetch_or:
3677 case AtomicExpr::AO__hip_atomic_fetch_xor:
3678 case AtomicExpr::AO__c11_atomic_fetch_nand:
3679 case AtomicExpr::AO__opencl_atomic_fetch_and:
3680 case AtomicExpr::AO__opencl_atomic_fetch_or:
3681 case AtomicExpr::AO__opencl_atomic_fetch_xor:
3682 case AtomicExpr::AO__atomic_fetch_and:
3683 case AtomicExpr::AO__atomic_fetch_or:
3684 case AtomicExpr::AO__atomic_fetch_xor:
3685 case AtomicExpr::AO__atomic_fetch_nand:
3686 case AtomicExpr::AO__atomic_and_fetch:
3687 case AtomicExpr::AO__atomic_or_fetch:
3688 case AtomicExpr::AO__atomic_xor_fetch:
3689 case AtomicExpr::AO__atomic_nand_fetch:
3690 case AtomicExpr::AO__scoped_atomic_fetch_and:
3691 case AtomicExpr::AO__scoped_atomic_fetch_or:
3692 case AtomicExpr::AO__scoped_atomic_fetch_xor:
3693 case AtomicExpr::AO__scoped_atomic_fetch_nand:
3694 case AtomicExpr::AO__scoped_atomic_and_fetch:
3695 case AtomicExpr::AO__scoped_atomic_or_fetch:
3696 case AtomicExpr::AO__scoped_atomic_xor_fetch:
3697 case AtomicExpr::AO__scoped_atomic_nand_fetch:
3701 case AtomicExpr::AO__c11_atomic_exchange:
3702 case AtomicExpr::AO__hip_atomic_exchange:
3703 case AtomicExpr::AO__opencl_atomic_exchange:
3704 case AtomicExpr::AO__atomic_exchange_n:
3705 case AtomicExpr::AO__scoped_atomic_exchange_n:
3709 case AtomicExpr::AO__atomic_exchange:
3710 case AtomicExpr::AO__scoped_atomic_exchange:
3714 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
3715 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
3716 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
3717 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
3718 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
3719 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
3723 case AtomicExpr::AO__atomic_compare_exchange:
3724 case AtomicExpr::AO__atomic_compare_exchange_n:
3725 case AtomicExpr::AO__scoped_atomic_compare_exchange:
3726 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
3731 unsigned AdjustedNumArgs = NumArgs[Form];
3732 if ((IsOpenCL || IsHIP || IsScoped) &&
3733 Op != AtomicExpr::AO__opencl_atomic_init)
3736 if (Args.size() < AdjustedNumArgs) {
3737 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
3738 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3741 }
else if (Args.size() > AdjustedNumArgs) {
3742 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
3743 diag::err_typecheck_call_too_many_args)
3744 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3750 Expr *Ptr = Args[0];
3755 Ptr = ConvertedPtr.
get();
3758 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3768 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
3774 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
3780 }
else if (Form != Load && Form != LoadCopy) {
3782 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
3790 diag::err_incomplete_type))
3793 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3799 if (Form == Arithmetic) {
3802 auto IsAllowedValueType = [&](
QualType ValType,
3803 unsigned AllowedType) ->
bool {
3807 return AllowedType & AOEVT_Pointer;
3813 &llvm::APFloat::x87DoubleExtended())
3817 if (!IsAllowedValueType(ValType, ArithAllows)) {
3818 auto DID = ArithAllows & AOEVT_FP
3819 ? (ArithAllows & AOEVT_Pointer
3820 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
3821 : diag::err_atomic_op_needs_atomic_int_or_fp)
3822 : diag::err_atomic_op_needs_atomic_int;
3829 diag::err_incomplete_type)) {
3835 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
3846 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
3862 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
3874 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg ||
3877 else if (Form == C11CmpXchg || Form == GNUCmpXchg)
3883 bool IsPassedByAddress =
false;
3884 if (!IsC11 && !IsHIP && !IsN) {
3886 IsPassedByAddress =
true;
3891 APIOrderedArgs.push_back(Args[0]);
3895 APIOrderedArgs.push_back(Args[1]);
3901 APIOrderedArgs.push_back(Args[2]);
3902 APIOrderedArgs.push_back(Args[1]);
3905 APIOrderedArgs.push_back(Args[2]);
3906 APIOrderedArgs.push_back(Args[3]);
3907 APIOrderedArgs.push_back(Args[1]);
3910 APIOrderedArgs.push_back(Args[2]);
3911 APIOrderedArgs.push_back(Args[4]);
3912 APIOrderedArgs.push_back(Args[1]);
3913 APIOrderedArgs.push_back(Args[3]);
3916 APIOrderedArgs.push_back(Args[2]);
3917 APIOrderedArgs.push_back(Args[4]);
3918 APIOrderedArgs.push_back(Args[5]);
3919 APIOrderedArgs.push_back(Args[1]);
3920 APIOrderedArgs.push_back(Args[3]);
3924 APIOrderedArgs.append(Args.begin(), Args.end());
3931 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
3933 if (i < NumVals[Form] + 1) {
3946 assert(Form != Load);
3949 else if (Form ==
Init || Form == Arithmetic)
3951 else if (Form ==
Copy || Form == Xchg) {
3952 if (IsPassedByAddress) {
3959 Expr *ValArg = APIOrderedArgs[i];
3966 AS = PtrTy->getPointeeType().getAddressSpace();
3975 if (IsPassedByAddress)
3995 APIOrderedArgs[i] = Arg.
get();
4000 SubExprs.push_back(Ptr);
4004 SubExprs.push_back(APIOrderedArgs[1]);
4007 SubExprs.push_back(APIOrderedArgs[1]);
4013 SubExprs.push_back(APIOrderedArgs[2]);
4014 SubExprs.push_back(APIOrderedArgs[1]);
4018 SubExprs.push_back(APIOrderedArgs[3]);
4019 SubExprs.push_back(APIOrderedArgs[1]);
4020 SubExprs.push_back(APIOrderedArgs[2]);
4023 SubExprs.push_back(APIOrderedArgs[3]);
4024 SubExprs.push_back(APIOrderedArgs[1]);
4025 SubExprs.push_back(APIOrderedArgs[4]);
4026 SubExprs.push_back(APIOrderedArgs[2]);
4029 SubExprs.push_back(APIOrderedArgs[4]);
4030 SubExprs.push_back(APIOrderedArgs[1]);
4031 SubExprs.push_back(APIOrderedArgs[5]);
4032 SubExprs.push_back(APIOrderedArgs[2]);
4033 SubExprs.push_back(APIOrderedArgs[3]);
4038 if (SubExprs.size() >= 2 && Form !=
Init) {
4039 std::optional<llvm::APSInt>
Success =
4040 SubExprs[1]->getIntegerConstantExpr(
Context);
4042 Diag(SubExprs[1]->getBeginLoc(),
4043 diag::warn_atomic_op_has_invalid_memory_order)
4044 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4045 << SubExprs[1]->getSourceRange();
4047 if (SubExprs.size() >= 5) {
4048 if (std::optional<llvm::APSInt> Failure =
4049 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4050 if (!llvm::is_contained(
4051 {llvm::AtomicOrderingCABI::relaxed,
4052 llvm::AtomicOrderingCABI::consume,
4053 llvm::AtomicOrderingCABI::acquire,
4054 llvm::AtomicOrderingCABI::seq_cst},
4055 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4056 Diag(SubExprs[3]->getBeginLoc(),
4057 diag::warn_atomic_op_has_invalid_memory_order)
4058 << 2 << SubExprs[3]->getSourceRange();
4065 auto *
Scope = Args[Args.size() - 1];
4066 if (std::optional<llvm::APSInt>
Result =
4068 if (!ScopeModel->isValid(
Result->getZExtValue()))
4069 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope)
4070 <<
Scope->getSourceRange();
4072 SubExprs.push_back(
Scope);
4078 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4079 Op == AtomicExpr::AO__c11_atomic_store ||
4080 Op == AtomicExpr::AO__opencl_atomic_load ||
4081 Op == AtomicExpr::AO__hip_atomic_load ||
4082 Op == AtomicExpr::AO__opencl_atomic_store ||
4083 Op == AtomicExpr::AO__hip_atomic_store) &&
4086 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4087 Op == AtomicExpr::AO__opencl_atomic_load ||
4088 Op == AtomicExpr::AO__hip_atomic_load)
4093 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4109 assert(Fn &&
"builtin call without direct callee!");
4120 E->setArg(ArgIndex, Arg.
get());
4132 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4134 <<
Callee->getSourceRange();
4147 FirstArg = FirstArgResult.
get();
4148 TheCall->
setArg(0, FirstArg);
4160 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4195#define BUILTIN_ROW(x) \
4196 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4197 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4199 static const unsigned BuiltinIndices[][5] = {
4225 case 1: SizeIndex = 0;
break;
4226 case 2: SizeIndex = 1;
break;
4227 case 4: SizeIndex = 2;
break;
4228 case 8: SizeIndex = 3;
break;
4229 case 16: SizeIndex = 4;
break;
4241 unsigned BuiltinIndex, NumFixed = 1;
4242 bool WarnAboutSemanticsChange =
false;
4243 switch (BuiltinID) {
4244 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4245 case Builtin::BI__sync_fetch_and_add:
4246 case Builtin::BI__sync_fetch_and_add_1:
4247 case Builtin::BI__sync_fetch_and_add_2:
4248 case Builtin::BI__sync_fetch_and_add_4:
4249 case Builtin::BI__sync_fetch_and_add_8:
4250 case Builtin::BI__sync_fetch_and_add_16:
4254 case Builtin::BI__sync_fetch_and_sub:
4255 case Builtin::BI__sync_fetch_and_sub_1:
4256 case Builtin::BI__sync_fetch_and_sub_2:
4257 case Builtin::BI__sync_fetch_and_sub_4:
4258 case Builtin::BI__sync_fetch_and_sub_8:
4259 case Builtin::BI__sync_fetch_and_sub_16:
4263 case Builtin::BI__sync_fetch_and_or:
4264 case Builtin::BI__sync_fetch_and_or_1:
4265 case Builtin::BI__sync_fetch_and_or_2:
4266 case Builtin::BI__sync_fetch_and_or_4:
4267 case Builtin::BI__sync_fetch_and_or_8:
4268 case Builtin::BI__sync_fetch_and_or_16:
4272 case Builtin::BI__sync_fetch_and_and:
4273 case Builtin::BI__sync_fetch_and_and_1:
4274 case Builtin::BI__sync_fetch_and_and_2:
4275 case Builtin::BI__sync_fetch_and_and_4:
4276 case Builtin::BI__sync_fetch_and_and_8:
4277 case Builtin::BI__sync_fetch_and_and_16:
4281 case Builtin::BI__sync_fetch_and_xor:
4282 case Builtin::BI__sync_fetch_and_xor_1:
4283 case Builtin::BI__sync_fetch_and_xor_2:
4284 case Builtin::BI__sync_fetch_and_xor_4:
4285 case Builtin::BI__sync_fetch_and_xor_8:
4286 case Builtin::BI__sync_fetch_and_xor_16:
4290 case Builtin::BI__sync_fetch_and_nand:
4291 case Builtin::BI__sync_fetch_and_nand_1:
4292 case Builtin::BI__sync_fetch_and_nand_2:
4293 case Builtin::BI__sync_fetch_and_nand_4:
4294 case Builtin::BI__sync_fetch_and_nand_8:
4295 case Builtin::BI__sync_fetch_and_nand_16:
4297 WarnAboutSemanticsChange =
true;
4300 case Builtin::BI__sync_add_and_fetch:
4301 case Builtin::BI__sync_add_and_fetch_1:
4302 case Builtin::BI__sync_add_and_fetch_2:
4303 case Builtin::BI__sync_add_and_fetch_4:
4304 case Builtin::BI__sync_add_and_fetch_8:
4305 case Builtin::BI__sync_add_and_fetch_16:
4309 case Builtin::BI__sync_sub_and_fetch:
4310 case Builtin::BI__sync_sub_and_fetch_1:
4311 case Builtin::BI__sync_sub_and_fetch_2:
4312 case Builtin::BI__sync_sub_and_fetch_4:
4313 case Builtin::BI__sync_sub_and_fetch_8:
4314 case Builtin::BI__sync_sub_and_fetch_16:
4318 case Builtin::BI__sync_and_and_fetch:
4319 case Builtin::BI__sync_and_and_fetch_1:
4320 case Builtin::BI__sync_and_and_fetch_2:
4321 case Builtin::BI__sync_and_and_fetch_4:
4322 case Builtin::BI__sync_and_and_fetch_8:
4323 case Builtin::BI__sync_and_and_fetch_16:
4327 case Builtin::BI__sync_or_and_fetch:
4328 case Builtin::BI__sync_or_and_fetch_1:
4329 case Builtin::BI__sync_or_and_fetch_2:
4330 case Builtin::BI__sync_or_and_fetch_4:
4331 case Builtin::BI__sync_or_and_fetch_8:
4332 case Builtin::BI__sync_or_and_fetch_16:
4336 case Builtin::BI__sync_xor_and_fetch:
4337 case Builtin::BI__sync_xor_and_fetch_1:
4338 case Builtin::BI__sync_xor_and_fetch_2:
4339 case Builtin::BI__sync_xor_and_fetch_4:
4340 case Builtin::BI__sync_xor_and_fetch_8:
4341 case Builtin::BI__sync_xor_and_fetch_16:
4345 case Builtin::BI__sync_nand_and_fetch:
4346 case Builtin::BI__sync_nand_and_fetch_1:
4347 case Builtin::BI__sync_nand_and_fetch_2:
4348 case Builtin::BI__sync_nand_and_fetch_4:
4349 case Builtin::BI__sync_nand_and_fetch_8:
4350 case Builtin::BI__sync_nand_and_fetch_16:
4352 WarnAboutSemanticsChange =
true;
4355 case Builtin::BI__sync_val_compare_and_swap:
4356 case Builtin::BI__sync_val_compare_and_swap_1:
4357 case Builtin::BI__sync_val_compare_and_swap_2:
4358 case Builtin::BI__sync_val_compare_and_swap_4:
4359 case Builtin::BI__sync_val_compare_and_swap_8:
4360 case Builtin::BI__sync_val_compare_and_swap_16:
4365 case Builtin::BI__sync_bool_compare_and_swap:
4366 case Builtin::BI__sync_bool_compare_and_swap_1:
4367 case Builtin::BI__sync_bool_compare_and_swap_2:
4368 case Builtin::BI__sync_bool_compare_and_swap_4:
4369 case Builtin::BI__sync_bool_compare_and_swap_8:
4370 case Builtin::BI__sync_bool_compare_and_swap_16:
4376 case Builtin::BI__sync_lock_test_and_set:
4377 case Builtin::BI__sync_lock_test_and_set_1:
4378 case Builtin::BI__sync_lock_test_and_set_2:
4379 case Builtin::BI__sync_lock_test_and_set_4:
4380 case Builtin::BI__sync_lock_test_and_set_8:
4381 case Builtin::BI__sync_lock_test_and_set_16:
4385 case Builtin::BI__sync_lock_release:
4386 case Builtin::BI__sync_lock_release_1:
4387 case Builtin::BI__sync_lock_release_2:
4388 case Builtin::BI__sync_lock_release_4:
4389 case Builtin::BI__sync_lock_release_8:
4390 case Builtin::BI__sync_lock_release_16:
4396 case Builtin::BI__sync_swap:
4397 case Builtin::BI__sync_swap_1:
4398 case Builtin::BI__sync_swap_2:
4399 case Builtin::BI__sync_swap_4:
4400 case Builtin::BI__sync_swap_8:
4401 case Builtin::BI__sync_swap_16:
4409 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4410 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
4411 <<
Callee->getSourceRange();
4415 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
4416 <<
Callee->getSourceRange();
4418 if (WarnAboutSemanticsChange) {
4419 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
4420 <<
Callee->getSourceRange();
4425 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
4428 if (NewBuiltinID == BuiltinID)
4429 NewBuiltinDecl = FDecl;
4435 assert(Res.getFoundDecl());
4436 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
4437 if (!NewBuiltinDecl)
4444 for (
unsigned i = 0; i != NumFixed; ++i) {
4475 CK_BuiltinFnToFnPtr);
4487 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
4488 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
4492 return TheCallResult;
4501 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
4502 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
4503 "Unexpected nontemporal load/store builtin!");
4504 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
4505 unsigned numArgs = isStore ? 2 : 1;
4515 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
4521 PointerArg = PointerArgResult.
get();
4522 TheCall->
setArg(numArgs - 1, PointerArg);
4526 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
4539 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
4546 return TheCallResult;
4558 return TheCallResult;
4565 auto *
Literal = dyn_cast<StringLiteral>(Arg);
4567 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
4568 Literal = ObjcLiteral->getString();
4572 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
4590 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
4591 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
4592 TT.getArch() == llvm::Triple::aarch64_32);
4593 bool IsWindows = TT.isOSWindows();
4594 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
4595 if (IsX64 || IsAArch64) {
4602 return S.
Diag(Fn->getBeginLoc(),
4603 diag::err_ms_va_start_used_in_sysv_function);
4611 return S.
Diag(Fn->getBeginLoc(),
4612 diag::err_va_start_used_in_wrong_abi_function)
4619 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
4627 bool IsVariadic =
false;
4630 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
4631 IsVariadic =
Block->isVariadic();
4632 Params =
Block->parameters();
4633 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
4636 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
4637 IsVariadic = MD->isVariadic();
4639 Params = MD->parameters();
4640 }
else if (isa<CapturedDecl>(Caller)) {
4642 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
4646 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
4651 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
4656 *LastParam = Params.empty() ? nullptr : Params.back();
4661bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
4686 bool SecondArgIsLastNamedArgument =
false;
4688 if (std::optional<llvm::APSInt> Val =
4697 bool IsCRegister =
false;
4699 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
4700 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
4701 SecondArgIsLastNamedArgument = PV == LastParam;
4703 Type = PV->getType();
4704 ParamLoc = PV->getLocation();
4710 if (!SecondArgIsLastNamedArgument)
4712 diag::warn_second_arg_of_va_start_not_last_named_param);
4717 if (!Context.isPromotableIntegerType(Type))
4719 if (!Type->isEnumeralType())
4721 const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();
4723 Context.typesAreCompatible(ED->getPromotionType(), Type));
4725 unsigned Reason = 0;
4727 else if (IsCRegister) Reason = 2;
4728 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
4729 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
4736 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
4756 if (
Call->getNumArgs() < 3)
4758 diag::err_typecheck_call_too_few_args_at_least)
4759 << 0 << 3 <<
Call->getNumArgs()
4772 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
4775 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
4780 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
4782 << Arg1->
getType() << ConstCharPtrTy << 1
4785 << 2 << Arg1->
getType() << ConstCharPtrTy;
4790 << Arg2->
getType() << SizeTy << 1
4793 << 3 << Arg2->
getType() << SizeTy;
4798bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
4802 if (BuiltinID == Builtin::BI__builtin_isunordered &&
4830 diag::err_typecheck_call_invalid_ordered_compare)
4838bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
4839 unsigned BuiltinID) {
4844 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
4845 BuiltinID == Builtin::BI__builtin_isinf ||
4846 BuiltinID == Builtin::BI__builtin_isinf_sign))
4850 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
4851 BuiltinID == Builtin::BI__builtin_isunordered))
4855 bool IsFPClass = NumArgs == 2;
4858 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
4862 for (
unsigned i = 0; i < FPArgNo; ++i) {
4887 TheCall->
setArg(FPArgNo, OrigArg);
4901 diag::err_typecheck_call_invalid_unary_fp)
4913 if (!VectorResultTy.
isNull())
4914 ResultTy = VectorResultTy;
4923bool Sema::BuiltinComplex(
CallExpr *TheCall) {
4928 for (
unsigned I = 0; I != 2; ++I) {
4939 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
4958 diag::err_typecheck_call_different_arg_types)
4982 diag::err_typecheck_call_too_few_args_at_least)
4990 unsigned numElements = 0;
5005 unsigned numResElements = TheCall->
getNumArgs() - 2;
5014 diag::err_vec_builtin_incompatible_vector)
5021 diag::err_vec_builtin_incompatible_vector)
5026 }
else if (numElements != numResElements) {
5033 for (
unsigned i = 2; i < TheCall->
getNumArgs(); i++) {
5038 std::optional<llvm::APSInt>
Result;
5041 diag::err_shufflevector_nonconstant_argument)
5048 if (
Result->getActiveBits() > 64 ||
5049 Result->getZExtValue() >= numElements * 2)
5051 diag::err_shufflevector_argument_too_large)
5057 for (
unsigned i = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5058 exprs.push_back(TheCall->
getArg(i));
5059 TheCall->
setArg(i,
nullptr);
5077 diag::err_convertvector_non_vector)
5080 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5082 <<
"__builtin_convertvector");
5087 if (SrcElts != DstElts)
5089 diag::err_convertvector_incompatible_vector)
5094 BuiltinLoc, RParenLoc);
5097bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5102 diag::err_typecheck_call_too_many_args_at_most)
5103 << 0 << 3 << NumArgs << 0
5108 for (
unsigned i = 1; i != NumArgs; ++i)
5115bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5117 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5127 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5137bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5144 << cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5149bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5155 if (
const auto *UE =
5157 if (UE->getKind() == UETT_AlignOf ||
5158 UE->getKind() == UETT_PreferredAlignOf)
5164 if (!
Result.isPowerOf2())
5165 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5172 if (
Result > std::numeric_limits<int32_t>::max())
5180bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5193 TheCall->
setArg(0, FirstArgResult.
get());
5205 if (!
Result.isPowerOf2())
5206 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5218 TheCall->
setArg(2, ThirdArg);
5224bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5225 unsigned BuiltinID =
5226 cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5227 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5230 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5231 if (NumArgs < NumRequiredArgs) {
5232 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5233 << 0 << NumRequiredArgs << NumArgs
5236 if (NumArgs >= NumRequiredArgs + 0x100) {
5238 diag::err_typecheck_call_too_many_args_at_most)
5239 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5250 if (Arg.isInvalid())
5252 TheCall->
setArg(i, Arg.get());
5257 unsigned FormatIdx = i;
5267 unsigned FirstDataArg = i;
5268 while (i < NumArgs) {
5286 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5288 bool Success = CheckFormatArguments(
5312 std::optional<llvm::APSInt> R;
5314 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5321 int High,
bool RangeIsError) {
5335 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
5343 PDiag(diag::warn_argument_invalid_range)
5364 if (
Result.getSExtValue() % Num != 0)
5388 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5393 if (
Value.isNegative())
5404 if ((
Value & 0xFF) != 0)
5429 Result.setIsUnsigned(
true);
5434 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
5453 Result.setIsUnsigned(
true);
5461 diag::err_argument_not_shifted_byte_or_xxff)
5465bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
5467 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
5478 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
5484bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
5486 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
5493class UncoveredArgHandler {
5494 enum {
Unknown = -1, AllCovered = -2 };
5496 signed FirstUncoveredArg =
Unknown;
5500 UncoveredArgHandler() =
default;
5502 bool hasUncoveredArg()
const {
5503 return (FirstUncoveredArg >= 0);
5506 unsigned getUncoveredArg()
const {
5507 assert(hasUncoveredArg() &&
"no uncovered argument");
5508 return FirstUncoveredArg;
5511 void setAllCovered() {
5514 DiagnosticExprs.clear();
5515 FirstUncoveredArg = AllCovered;
5518 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
5519 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
5522 if (FirstUncoveredArg == AllCovered)
5527 if (NewFirstUncoveredArg == FirstUncoveredArg)
5528 DiagnosticExprs.push_back(StrExpr);
5529 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
5530 DiagnosticExprs.clear();
5531 DiagnosticExprs.push_back(StrExpr);
5532 FirstUncoveredArg = NewFirstUncoveredArg;
5536 void Diagnose(
Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
5539enum StringLiteralCheckType {
5541 SLCT_UncheckedLiteral,
5549 bool AddendIsRight) {
5550 unsigned BitWidth = Offset.getBitWidth();
5551 unsigned AddendBitWidth = Addend.getBitWidth();
5553 if (Addend.isUnsigned()) {
5554 Addend = Addend.zext(++AddendBitWidth);
5555 Addend.setIsSigned(
true);
5558 if (AddendBitWidth > BitWidth) {
5559 Offset = Offset.sext(AddendBitWidth);
5560 BitWidth = AddendBitWidth;
5561 }
else if (BitWidth > AddendBitWidth) {
5562 Addend = Addend.sext(BitWidth);
5566 llvm::APSInt ResOffset = Offset;
5567 if (BinOpKind == BO_Add)
5568 ResOffset = Offset.sadd_ov(Addend, Ov);
5570 assert(AddendIsRight && BinOpKind == BO_Sub &&
5571 "operator must be add or sub with addend on the right");
5572 ResOffset = Offset.ssub_ov(Addend, Ov);
5578 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
5579 "index (intermediate) result too big");
5580 Offset = Offset.sext(2 * BitWidth);
5581 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
5593class FormatStringLiteral {
5598 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
5599 : FExpr(fexpr), Offset(Offset) {}
5601 StringRef getString()
const {
5602 return FExpr->
getString().drop_front(Offset);
5605 unsigned getByteLength()
const {
5606 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
5609 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
5616 bool isAscii()
const {
return FExpr->
isOrdinary(); }
5617 bool isWide()
const {
return FExpr->
isWide(); }
5618 bool isUTF8()
const {
return FExpr->
isUTF8(); }
5619 bool isUTF16()
const {
return FExpr->
isUTF16(); }
5620 bool isUTF32()
const {
return FExpr->
isUTF32(); }
5621 bool isPascal()
const {
return FExpr->
isPascal(); }
5626 unsigned *StartTokenByteOffset =
nullptr)
const {
5628 StartToken, StartTokenByteOffset);
5641 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
5645 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
5646 bool IgnoreStringsWithoutSpecifiers);
5655static StringLiteralCheckType
5660 llvm::SmallBitVector &CheckedVarArgs,
5661 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
5662 bool IgnoreStringsWithoutSpecifiers =
false) {
5664 return SLCT_NotALiteral;
5666 assert(Offset.isSigned() &&
"invalid offset");
5669 return SLCT_NotALiteral;
5678 return SLCT_UncheckedLiteral;
5681 case Stmt::InitListExprClass:
5685 Type, CallType,
false,
5686 CheckedVarArgs, UncoveredArg, Offset,
5687 IgnoreStringsWithoutSpecifiers);
5689 return SLCT_NotALiteral;
5690 case Stmt::BinaryConditionalOperatorClass:
5691 case Stmt::ConditionalOperatorClass: {
5695 cast<AbstractConditionalOperator>(
E);
5700 bool CheckLeft =
true, CheckRight =
true;
5703 if (
C->getCond()->EvaluateAsBooleanCondition(
5715 StringLiteralCheckType Left;
5717 Left = SLCT_UncheckedLiteral;
5720 firstDataArg,
Type, CallType, InFunctionCall,
5721 CheckedVarArgs, UncoveredArg, Offset,
5722 IgnoreStringsWithoutSpecifiers);
5723 if (Left == SLCT_NotALiteral || !CheckRight) {
5729 S,
C->getFalseExpr(), Args, APK, format_idx, firstDataArg,
Type,
5730 CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5731 IgnoreStringsWithoutSpecifiers);
5733 return (CheckLeft && Left < Right) ? Left : Right;
5736 case Stmt::ImplicitCastExprClass:
5737 E = cast<ImplicitCastExpr>(
E)->getSubExpr();
5740 case Stmt::OpaqueValueExprClass:
5741 if (
const Expr *src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
5745 return SLCT_NotALiteral;
5747 case Stmt::PredefinedExprClass:
5751 return SLCT_UncheckedLiteral;
5753 case Stmt::DeclRefExprClass: {
5759 bool isConstant =
false;
5763 isConstant = AT->getElementType().isConstant(S.
Context);
5765 isConstant =
T.isConstant(S.
Context) &&
5770 isConstant =
T.isConstant(S.
Context);
5774 if (
const Expr *
Init = VD->getAnyInitializer()) {
5777 if (InitList->isStringLiteralInit())
5778 Init = InitList->getInit(0)->IgnoreParenImpCasts();
5781 S,
Init, Args, APK, format_idx, firstDataArg,
Type, CallType,
5782 false, CheckedVarArgs, UncoveredArg, Offset);
5823 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
5824 if (
const auto *
D = dyn_cast<Decl>(PV->getDeclContext())) {
5826 bool IsCXXMember =
false;
5827 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D))
5828 IsCXXMember = MD->isInstance();
5830 bool IsVariadic =
false;
5832 IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();
5833 else if (
const auto *BD = dyn_cast<BlockDecl>(
D))
5834 IsVariadic = BD->isVariadic();
5835 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D))
5836 IsVariadic = OMD->isVariadic();
5843 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx &&
5856 return SLCT_UncheckedLiteral;
5865 return SLCT_NotALiteral;
5868 case Stmt::CallExprClass:
5869 case Stmt::CXXMemberCallExprClass: {
5872 bool IsFirst =
true;
5873 StringLiteralCheckType CommonResult;
5874 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
5875 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
5877 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
5878 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5879 IgnoreStringsWithoutSpecifiers);
5886 return CommonResult;
5888 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
5890 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
5891 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
5894 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
5895 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5896 IgnoreStringsWithoutSpecifiers);
5902 Type, CallType,
false,
5903 CheckedVarArgs, UncoveredArg, Offset,
5904 IgnoreStringsWithoutSpecifiers);
5905 return SLCT_NotALiteral;
5907 case Stmt::ObjCMessageExprClass: {
5908 const auto *ME = cast<ObjCMessageExpr>(
E);
5909 if (
const auto *MD = ME->getMethodDecl()) {
5910 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
5919 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
5921 MD->getSelector().isKeywordSelector(
5922 {
"localizedStringForKey",
"value",
"table"})) {
5923 IgnoreStringsWithoutSpecifiers =
true;
5926 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
5928 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
5929 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5930 IgnoreStringsWithoutSpecifiers);
5934 return SLCT_NotALiteral;
5936 case Stmt::ObjCStringLiteralClass:
5937 case Stmt::StringLiteralClass: {
5943 StrE = cast<StringLiteral>(
E);
5946 if (Offset.isNegative() || Offset > StrE->
getLength()) {
5949 return SLCT_NotALiteral;
5951 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
5953 InFunctionCall, CallType, CheckedVarArgs, UncoveredArg,
5954 IgnoreStringsWithoutSpecifiers);
5955 return SLCT_CheckedLiteral;
5958 return SLCT_NotALiteral;
5960 case Stmt::BinaryOperatorClass: {
5974 if (LIsInt != RIsInt) {
5978 if (BinOpKind == BO_Add) {
5991 return SLCT_NotALiteral;
5993 case Stmt::UnaryOperatorClass: {
5995 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
5996 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
5998 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6008 return SLCT_NotALiteral;
6012 return SLCT_NotALiteral;
6023 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6024 if (isa_and_nonnull<StringLiteral>(LVE))
6031 return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
6037 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
FST_Kprintf)
6044bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6048 llvm::SmallBitVector &CheckedVarArgs) {
6049 FormatStringInfo FSI;
6052 return CheckFormatArguments(Args, FSI.ArgPassingKind, FSI.FormatIdx,
6054 CallType,
Loc,
Range, CheckedVarArgs);
6060 unsigned format_idx,
unsigned firstDataArg,
6061 FormatStringType
Type,
6064 llvm::SmallBitVector &CheckedVarArgs) {
6066 if (format_idx >= Args.size()) {
6071 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6085 UncoveredArgHandler UncoveredArg;
6087 *
this, OrigFormatExpr, Args, APK, format_idx, firstDataArg,
Type,
6089 true, CheckedVarArgs, UncoveredArg,
6090 llvm::APSInt(64,
false) = 0);
6093 if (UncoveredArg.hasUncoveredArg()) {
6094 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6095 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6096 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6099 if (CT != SLCT_NotALiteral)
6101 return CT == SLCT_CheckedLiteral;
6118 if (Args.size() == firstDataArg) {
6119 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6127 Diag(FormatLoc, diag::note_format_security_fixit)
6131 Diag(FormatLoc, diag::note_format_security_fixit)
6136 Diag(FormatLoc, diag::warn_format_nonliteral)
6147 const FormatStringLiteral *FExpr;
6148 const Expr *OrigFormatExpr;
6150 const unsigned FirstDataArg;
6151 const unsigned NumDataArgs;
6156 llvm::SmallBitVector CoveredArgs;
6157 bool usesPositionalArgs =
false;
6158 bool atFirstArg =
true;
6159 bool inFunctionCall;
6161 llvm::SmallBitVector &CheckedVarArgs;
6162 UncoveredArgHandler &UncoveredArg;
6165 CheckFormatHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6166 const Expr *origFormatExpr,
6168 unsigned numDataArgs,
const char *beg,
6172 llvm::SmallBitVector &CheckedVarArgs,
6173 UncoveredArgHandler &UncoveredArg)
6174 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6175 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6176 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6177 inFunctionCall(inFunctionCall), CallType(callType),
6178 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6179 CoveredArgs.resize(numDataArgs);
6180 CoveredArgs.reset();
6183 void DoneProcessing();
6185 void HandleIncompleteSpecifier(
const char *startSpecifier,
6186 unsigned specifierLen)
override;
6188 void HandleInvalidLengthModifier(
6191 const char *startSpecifier,
unsigned specifierLen,
6194 void HandleNonStandardLengthModifier(
6196 const char *startSpecifier,
unsigned specifierLen);
6198 void HandleNonStandardConversionSpecifier(
6200 const char *startSpecifier,
unsigned specifierLen);
6202 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
6204 void HandleInvalidPosition(
const char *startSpecifier,
6205 unsigned specifierLen,
6208 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
6210 void HandleNullChar(
const char *nullCharacter)
override;
6212 template <
typename Range>
6214 EmitFormatDiagnostic(
Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
6216 bool IsStringLocation,
Range StringRange,
6221 const char *startSpec,
6222 unsigned specifierLen,
6223 const char *csStart,
unsigned csLen);
6226 const char *startSpec,
6227 unsigned specifierLen);
6231 unsigned specifierLen);
6234 const Expr *getDataArg(
unsigned i)
const;
6238 const char *startSpecifier,
unsigned specifierLen,
6241 template <
typename Range>
6243 bool IsStringLocation,
Range StringRange,
6249SourceRange CheckFormatHandler::getFormatStringRange() {
6254getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
6256 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
6259 End = End.getLocWithOffset(1);
6264SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
6269void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
6270 unsigned specifierLen){
6271 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
6272 getLocationOfByte(startSpecifier),
6274 getSpecifierRange(startSpecifier, specifierLen));
6277void CheckFormatHandler::HandleInvalidLengthModifier(
6280 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
6281 using namespace analyze_format_string;
6283 const LengthModifier &LM = FS.getLengthModifier();
6284 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6287 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6289 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6290 getLocationOfByte(LM.getStart()),
6292 getSpecifierRange(startSpecifier, specifierLen));
6294 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6295 << FixedLM->toString()
6300 if (DiagID == diag::warn_format_nonsensical_length)
6303 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6304 getLocationOfByte(LM.getStart()),
6306 getSpecifierRange(startSpecifier, specifierLen),
6311void CheckFormatHandler::HandleNonStandardLengthModifier(
6313 const char *startSpecifier,
unsigned specifierLen) {
6314 using namespace analyze_format_string;
6316 const LengthModifier &LM = FS.getLengthModifier();
6317 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6320 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6322 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6323 << LM.toString() << 0,
6324 getLocationOfByte(LM.getStart()),
6326 getSpecifierRange(startSpecifier, specifierLen));
6328 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6329 << FixedLM->toString()
6333 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6334 << LM.toString() << 0,
6335 getLocationOfByte(LM.getStart()),
6337 getSpecifierRange(startSpecifier, specifierLen));
6341void CheckFormatHandler::HandleNonStandardConversionSpecifier(
6343 const char *startSpecifier,
unsigned specifierLen) {
6344 using namespace analyze_format_string;
6349 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6353 getSpecifierRange(startSpecifier, specifierLen));
6356 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
6357 << FixedCS->toString()
6360 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6364 getSpecifierRange(startSpecifier, specifierLen));
6368void CheckFormatHandler::HandlePosition(
const char *startPos,
6370 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
6371 getLocationOfByte(startPos),
6373 getSpecifierRange(startPos, posLen));
6376void CheckFormatHandler::HandleInvalidPosition(
6377 const char *startSpecifier,
unsigned specifierLen,
6379 EmitFormatDiagnostic(
6380 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
6381 getLocationOfByte(startSpecifier),
true,
6382 getSpecifierRange(startSpecifier, specifierLen));
6385void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
6387 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
6388 getLocationOfByte(startPos),
6390 getSpecifierRange(startPos, posLen));
6393void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
6394 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {
6396 EmitFormatDiagnostic(
6397 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
6398 getLocationOfByte(nullCharacter),
true,
6399 getFormatStringRange());
6405const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
6406 return Args[FirstDataArg + i];
6409void CheckFormatHandler::DoneProcessing() {
6415 signed notCoveredArg = CoveredArgs.find_first();
6416 if (notCoveredArg >= 0) {
6417 assert((
unsigned)notCoveredArg < NumDataArgs);
6418 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
6420 UncoveredArg.setAllCovered();
6425void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
6426 const Expr *ArgExpr) {
6427 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
6439 for (
auto E : DiagnosticExprs)
6442 CheckFormatHandler::EmitFormatDiagnostic(
6443 S, IsFunctionCall, DiagnosticExprs[0],
6449CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
6451 const char *startSpec,
6452 unsigned specifierLen,
6453 const char *csStart,
6455 bool keepGoing =
true;
6456 if (argIndex < NumDataArgs) {
6459 CoveredArgs.set(argIndex);
6475 std::string CodePointStr;
6476 if (!llvm::sys::locale::isPrint(*csStart)) {
6477 llvm::UTF32 CodePoint;
6478 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
6479 const llvm::UTF8 *
E =
6480 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
6481 llvm::ConversionResult
Result =
6482 llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
6484 if (
Result != llvm::conversionOK) {
6485 unsigned char FirstChar = *csStart;
6486 CodePoint = (llvm::UTF32)FirstChar;
6489 llvm::raw_string_ostream OS(CodePointStr);
6490 if (CodePoint < 256)
6491 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
6492 else if (CodePoint <= 0xFFFF)
6493 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
6495 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
6500 EmitFormatDiagnostic(
6501 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier,
Loc,
6502 true, getSpecifierRange(startSpec, specifierLen));
6509 const char *startSpec,
6510 unsigned specifierLen) {
6511 EmitFormatDiagnostic(
6512 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
6513 Loc,
true, getSpecifierRange(startSpec, specifierLen));
6517CheckFormatHandler::CheckNumArgs(
6520 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
6522 if (argIndex >= NumDataArgs) {
6524 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
6525 << (argIndex+1) << NumDataArgs)
6526 : S.
PDiag(diag::warn_printf_insufficient_data_args);
6527 EmitFormatDiagnostic(
6528 PDiag, getLocationOfByte(CS.
getStart()),
true,
6529 getSpecifierRange(startSpecifier, specifierLen));
6533 UncoveredArg.setAllCovered();
6539template<
typename Range>
6542 bool IsStringLocation,
6545 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
6546 Loc, IsStringLocation, StringRange, FixIt);
6576template <
typename Range>
6577void CheckFormatHandler::EmitFormatDiagnostic(
6578 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
6581 if (InFunctionCall) {
6590 S.
Diag(IsStringLocation ?
Loc : StringRange.getBegin(),
6591 diag::note_format_string_defined);
6593 Note << StringRange;
6602class CheckPrintfHandler :
public CheckFormatHandler {
6604 CheckPrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6605 const Expr *origFormatExpr,
6607 unsigned numDataArgs,
bool isObjC,
const char *beg,
6611 llvm::SmallBitVector &CheckedVarArgs,
6612 UncoveredArgHandler &UncoveredArg)
6613 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
6614 numDataArgs, beg, APK, Args, formatIdx,
6615 inFunctionCall, CallType, CheckedVarArgs,
6621 bool allowsObjCArg()
const {
6626 bool HandleInvalidPrintfConversionSpecifier(
6628 const char *startSpecifier,
6629 unsigned specifierLen)
override;
6631 void handleInvalidMaskType(StringRef MaskType)
override;
6634 const char *startSpecifier,
unsigned specifierLen,
6637 const char *StartSpecifier,
6638 unsigned SpecifierLen,
6642 const char *startSpecifier,
unsigned specifierLen);
6646 const char *startSpecifier,
unsigned specifierLen);
6649 const char *startSpecifier,
unsigned specifierLen);
6653 const char *startSpecifier,
unsigned specifierLen);
6657 void HandleEmptyObjCModifierFlag(
const char *startFlag,
6658 unsigned flagLen)
override;
6660 void HandleInvalidObjCModifierFlag(
const char *startFlag,
6661 unsigned flagLen)
override;
6663 void HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
6664 const char *flagsEnd,
6665 const char *conversionPosition)
6671bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
6673 const char *startSpecifier,
6674 unsigned specifierLen) {
6676 FS.getConversionSpecifier();
6678 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
6680 startSpecifier, specifierLen,
6684void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
6685 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
6688bool CheckPrintfHandler::HandleAmount(
6690 const char *startSpecifier,
unsigned specifierLen) {
6694 if (argIndex >= NumDataArgs) {
6695 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
6699 getSpecifierRange(startSpecifier, specifierLen));
6709 CoveredArgs.set(argIndex);
6710 const Expr *Arg = getDataArg(argIndex);
6720 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
6725 getSpecifierRange(startSpecifier, specifierLen));
6735void CheckPrintfHandler::HandleInvalidAmount(
6739 const char *startSpecifier,
6740 unsigned specifierLen) {
6742 FS.getConversionSpecifier();
6750 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
6754 getSpecifierRange(startSpecifier, specifierLen),
6760 const char *startSpecifier,
6761 unsigned specifierLen) {
6764 FS.getConversionSpecifier();
6765 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
6769 getSpecifierRange(startSpecifier, specifierLen),
6774void CheckPrintfHandler::HandleIgnoredFlag(
6778 const char *startSpecifier,
6779 unsigned specifierLen) {
6781 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
6785 getSpecifierRange(startSpecifier, specifierLen),
6787 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
6790void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
6793 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
6794 getLocationOfByte(startFlag),
6796 getSpecifierRange(startFlag, flagLen));
6799void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
6802 auto Range = getSpecifierRange(startFlag, flagLen);
6803 StringRef flag(startFlag, flagLen);
6804 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
6805 getLocationOfByte(startFlag),
6810void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
6811 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
6813 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
6814 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
6815 EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
6816 getLocationOfByte(conversionPosition),
6824template<
typename MemberKind>
6845 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
6859 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
6860 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
6862 if ((*MI)->getMinRequiredArguments() == 0)
6870bool CheckPrintfHandler::checkForCStrMembers(
6875 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
6877 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
6893bool CheckPrintfHandler::HandlePrintfSpecifier(
6896 using namespace analyze_format_string;
6897 using namespace analyze_printf;
6899 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
6901 if (FS.consumesDataArgument()) {
6904 usesPositionalArgs = FS.usesPositionalArg();
6906 else if (usesPositionalArgs != FS.usesPositionalArg()) {
6907 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
6908 startSpecifier, specifierLen);
6915 if (!HandleAmount(FS.getFieldWidth(), 0,
6916 startSpecifier, specifierLen)) {
6920 if (!HandleAmount(FS.getPrecision(), 1,
6921 startSpecifier, specifierLen)) {
6925 if (!CS.consumesDataArgument()) {
6932 unsigned argIndex = FS.getArgIndex();
6933 if (argIndex < NumDataArgs) {
6937 CoveredArgs.set(argIndex);
6941 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
6942 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
6944 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
6948 CoveredArgs.set(argIndex + 1);
6951 const Expr *Ex = getDataArg(argIndex);
6953 (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
6956 EmitFormatDiagnostic(
6957 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
6961 getSpecifierRange(startSpecifier, specifierLen));
6964 Ex = getDataArg(argIndex + 1);
6967 EmitFormatDiagnostic(
6968 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
6972 getSpecifierRange(startSpecifier, specifierLen));
6979 if (!allowsObjCArg() && CS.isObjCArg()) {
6980 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
6985 if (FSType !=
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::PArg) {
6986 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
6991 if (FSType ==
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::nArg) {
6992 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
6993 getLocationOfByte(CS.getStart()),
6995 getSpecifierRange(startSpecifier, specifierLen));
7002 (CS.getKind() == ConversionSpecifier::PArg ||
7003 CS.getKind() == ConversionSpecifier::sArg ||
7004 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
7005 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7011 if (FS.isPublic().isSet()) {
7012 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7014 getLocationOfByte(FS.isPublic().getPosition()),
7016 getSpecifierRange(startSpecifier, specifierLen));
7018 if (FS.isPrivate().isSet()) {
7019 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7021 getLocationOfByte(FS.isPrivate().getPosition()),
7023 getSpecifierRange(startSpecifier, specifierLen));
7027 const llvm::Triple &Triple =
Target.getTriple();
7028 if (CS.getKind() == ConversionSpecifier::nArg &&
7029 (Triple.isAndroid() || Triple.isOSFuchsia())) {
7030 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
7031 getLocationOfByte(CS.getStart()),
7033 getSpecifierRange(startSpecifier, specifierLen));
7037 if (!FS.hasValidFieldWidth()) {
7038 HandleInvalidAmount(FS, FS.getFieldWidth(), 0,
7039 startSpecifier, specifierLen);
7043 if (!FS.hasValidPrecision()) {
7044 HandleInvalidAmount(FS, FS.getPrecision(), 1,
7045 startSpecifier, specifierLen);
7049 if (CS.getKind() == ConversionSpecifier::PArg &&
7050 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
7051 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
7052 getLocationOfByte(startSpecifier),
7054 getSpecifierRange(startSpecifier, specifierLen));
7058 if (!FS.hasValidThousandsGroupingPrefix())
7059 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
7060 if (!FS.hasValidLeadingZeros())
7061 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
7062 if (!FS.hasValidPlusPrefix())
7063 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
7064 if (!FS.hasValidSpacePrefix())
7065 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
7066 if (!FS.hasValidAlternativeForm())
7067 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
7068 if (!FS.hasValidLeftJustified())
7069 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
7072 if (FS.hasSpacePrefix() && FS.hasPlusPrefix())
7073 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
7074 startSpecifier, specifierLen);
7075 if (FS.hasLeadingZeros() && FS.isLeftJustified())
7076 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
7077 startSpecifier, specifierLen);
7082 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7083 diag::warn_format_nonsensical_length);
7084 else if (!FS.hasStandardLengthModifier())
7085 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7086 else if (!FS.hasStandardLengthConversionCombination())
7087 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7088 diag::warn_format_non_standard_conversion_spec);
7090 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7091 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7097 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7100 const Expr *Arg = getDataArg(argIndex);
7104 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
7116 case Stmt::ArraySubscriptExprClass:
7117 case Stmt::CallExprClass:
7118 case Stmt::CharacterLiteralClass:
7119 case Stmt::CXXBoolLiteralExprClass:
7120 case Stmt::DeclRefExprClass:
7121 case Stmt::FloatingLiteralClass:
7122 case Stmt::IntegerLiteralClass:
7123 case Stmt::MemberExprClass:
7124 case Stmt::ObjCArrayLiteralClass:
7125 case Stmt::ObjCBoolLiteralExprClass:
7126 case Stmt::ObjCBoxedExprClass:
7127 case Stmt::ObjCDictionaryLiteralClass:
7128 case Stmt::ObjCEncodeExprClass:
7129 case Stmt::ObjCIvarRefExprClass:
7130 case Stmt::ObjCMessageExprClass:
7131 case Stmt::ObjCPropertyRefExprClass:
7132 case Stmt::ObjCStringLiteralClass:
7133 case Stmt::ObjCSubscriptRefExprClass:
7134 case Stmt::ParenExprClass:
7135 case Stmt::StringLiteralClass:
7136 case Stmt::UnaryOperatorClass:
7143static std::pair<QualType, StringRef>
7150 StringRef Name = UserTy->getDecl()->getName();
7151 QualType CastTy = llvm::StringSwitch<QualType>(Name)
7155 .Case(
"SInt32", Context.
IntTy)
7160 return std::make_pair(CastTy, Name);
7162 TyTy = UserTy->desugar();
7166 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(
E))
7168 PE->getSubExpr()->getType(),
7177 StringRef TrueName, FalseName;
7179 std::tie(TrueTy, TrueName) =
7181 CO->getTrueExpr()->getType(),
7183 std::tie(FalseTy, FalseName) =
7185 CO->getFalseExpr()->getType(),
7186 CO->getFalseExpr());
7188 if (TrueTy == FalseTy)
7189 return std::make_pair(TrueTy, TrueName);
7190 else if (TrueTy.
isNull())
7191 return std::make_pair(FalseTy, FalseName);
7192 else if (FalseTy.
isNull())
7193 return std::make_pair(TrueTy, TrueName);
7196 return std::make_pair(
QualType(), StringRef());
7215 From = VecTy->getElementType();
7217 To = VecTy->getElementType();
7229 diag::warn_format_conversion_argument_type_mismatch_signedness,
Loc)
7238 const char *StartSpecifier,
7239 unsigned SpecifierLen,
7241 using namespace analyze_format_string;
7242 using namespace analyze_printf;
7251 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
7252 ExprTy = TET->getUnderlyingExpr()->getType();
7264 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
7267 getSpecifierRange(StartSpecifier, SpecifierLen);
7269 llvm::raw_svector_ostream os(FSString);
7271 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
7279 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
7282 getSpecifierRange(StartSpecifier, SpecifierLen);
7283 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
7288 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
7290 ArgType::MatchKind OrigMatch = Match;
7293 if (Match == ArgType::Match)
7297 assert(Match != ArgType::NoMatchPromotionTypeConfusion);
7306 E = ICE->getSubExpr();
7316 if (OrigMatch == ArgType::NoMatchSignedness &&
7317 ImplicitMatch != ArgType::NoMatchSignedness)
7324 if (ImplicitMatch == ArgType::Match)
7335 FS.getLengthModifier().getKind() != LengthModifier::AsChar)
7342 if (Match == ArgType::MatchPromotion)
7343 Match = ArgType::NoMatch;
7346 if (Match == ArgType::MatchPromotion) {
7350 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
7351 ImplicitMatch != ArgType::NoMatchTypeConfusion)
7353 Match = ArgType::NoMatch;
7355 if (ImplicitMatch == ArgType::NoMatchPedantic ||
7356 ImplicitMatch == ArgType::NoMatchTypeConfusion)
7357 Match = ImplicitMatch;
7358 assert(Match != ArgType::MatchPromotion);
7361 bool IsEnum =
false;
7362 bool IsScopedEnum =
false;
7365 IntendedTy = EnumTy->getDecl()->getIntegerType();
7366 if (EnumTy->isUnscopedEnumerationType()) {
7367 ExprTy = IntendedTy;
7372 IsScopedEnum =
true;
7379 if (isObjCContext() &&
7380 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
7390 const llvm::APInt &
V = IL->getValue();
7400 if (TD->getUnderlyingType() == IntendedTy)
7408 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
7416 if (!IsScopedEnum &&
7417 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
7420 Match = ArgType::NoMatchPedantic;
7421 IntendedTy = CastTy;
7422 ShouldNotPrintDirectly =
true;
7427 PrintfSpecifier fixedFS = FS;
7434 llvm::raw_svector_ostream os(buf);
7435 fixedFS.toString(os);
7437 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
7439 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
7442 case ArgType::Match:
7443 case ArgType::MatchPromotion:
7444 case ArgType::NoMatchPromotionTypeConfusion:
7445 case ArgType::NoMatchSignedness:
7446 llvm_unreachable(
"expected non-matching");
7447 case ArgType::NoMatchPedantic:
7448 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7450 case ArgType::NoMatchTypeConfusion:
7451 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7453 case ArgType::NoMatch:
7454 Diag = diag::warn_format_conversion_argument_type_mismatch;
7475 llvm::raw_svector_ostream CastFix(CastBuf);
7476 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
7478 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
7484 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
7489 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
7511 if (ShouldNotPrintDirectly && !IsScopedEnum) {
7517 Name = TypedefTy->getDecl()->getName();
7520 unsigned Diag = Match == ArgType::NoMatchPedantic
7521 ? diag::warn_format_argument_needs_cast_pedantic
7522 : diag::warn_format_argument_needs_cast;
7523 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
7534 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
7535 : diag::warn_format_conversion_argument_type_mismatch;
7537 EmitFormatDiagnostic(
7549 bool EmitTypeMismatch =
false;
7555 case ArgType::Match:
7556 case ArgType::MatchPromotion:
7557 case ArgType::NoMatchPromotionTypeConfusion:
7558 case ArgType::NoMatchSignedness:
7559 llvm_unreachable(
"expected non-matching");
7560 case ArgType::NoMatchPedantic:
7561 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7563 case ArgType::NoMatchTypeConfusion:
7564 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7566 case ArgType::NoMatch:
7567 Diag = diag::warn_format_conversion_argument_type_mismatch;
7571 EmitFormatDiagnostic(
7580 EmitTypeMismatch =
true;
7582 EmitFormatDiagnostic(
7583 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
7584 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7588 checkForCStrMembers(AT,
E);
7594 EmitTypeMismatch =
true;
7596 EmitFormatDiagnostic(
7597 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
7598 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7606 << isa<InitListExpr>(
E) << ExprTy << CallType
7611 if (EmitTypeMismatch) {
7617 EmitFormatDiagnostic(
7618 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7624 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
7625 "format string specifier index out of range");
7626 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
7636class CheckScanfHandler :
public CheckFormatHandler {
7638 CheckScanfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7640 unsigned firstDataArg,
unsigned numDataArgs,
7644 llvm::SmallBitVector &CheckedVarArgs,
7645 UncoveredArgHandler &UncoveredArg)
7646 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7647 numDataArgs, beg, APK, Args, formatIdx,
7648 inFunctionCall, CallType, CheckedVarArgs,
7652 const char *startSpecifier,
7653 unsigned specifierLen)
override;
7655 bool HandleInvalidScanfConversionSpecifier(
7657 const char *startSpecifier,
7658 unsigned specifierLen)
override;
7660 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
7665void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
7667 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
7668 getLocationOfByte(end),
true,
7669 getSpecifierRange(start, end - start));
7672bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
7674 const char *startSpecifier,
7675 unsigned specifierLen) {
7677 FS.getConversionSpecifier();
7679 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
7681 startSpecifier, specifierLen,
7685bool CheckScanfHandler::HandleScanfSpecifier(
7687 const char *startSpecifier,
7688 unsigned specifierLen) {
7689 using namespace analyze_scanf;
7690 using namespace analyze_format_string;
7692 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
7696 if (FS.consumesDataArgument()) {
7699 usesPositionalArgs = FS.usesPositionalArg();
7701 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7702 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7703 startSpecifier, specifierLen);
7709 const OptionalAmount &Amt = FS.getFieldWidth();
7710 if (Amt.getHowSpecified() == OptionalAmount::Constant) {
7711 if (Amt.getConstantAmount() == 0) {
7713 Amt.getConstantLength());
7714 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
7715 getLocationOfByte(Amt.getStart()),
7721 if (!FS.consumesDataArgument()) {
7728 unsigned argIndex = FS.getArgIndex();
7729 if (argIndex < NumDataArgs) {
7733 CoveredArgs.set(argIndex);
7739 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7740 diag::warn_format_nonsensical_length);
7741 else if (!FS.hasStandardLengthModifier())
7742 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7743 else if (!FS.hasStandardLengthConversionCombination())
7744 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7745 diag::warn_format_non_standard_conversion_spec);
7747 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7748 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7754 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7758 const Expr *Ex = getDataArg(argIndex);
7775 ScanfSpecifier fixedFS = FS;
7780 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
7781 : diag::warn_format_conversion_argument_type_mismatch;
7786 llvm::raw_svector_ostream os(buf);
7787 fixedFS.toString(os);
7789 EmitFormatDiagnostic(
7794 getSpecifierRange(startSpecifier, specifierLen),
7796 getSpecifierRange(startSpecifier, specifierLen), os.str()));
7803 getSpecifierRange(startSpecifier, specifierLen));
7810 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
7814 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7815 bool IgnoreStringsWithoutSpecifiers) {
7817 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
7818 CheckFormatHandler::EmitFormatDiagnostic(
7819 S, inFunctionCall, Args[format_idx],
7820 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
7826 StringRef StrRef = FExpr->getString();
7827 const char *Str = StrRef.data();
7831 assert(
T &&
"String literal not of constant array type!");
7832 size_t TypeSize =
T->getZExtSize();
7833 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
7834 const unsigned numDataArgs = Args.size() - firstDataArg;
7836 if (IgnoreStringsWithoutSpecifiers &&
7843 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
7844 CheckFormatHandler::EmitFormatDiagnostic(
7845 S, inFunctionCall, Args[format_idx],
7846 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
7847 FExpr->getBeginLoc(),
7853 if (StrLen == 0 && numDataArgs > 0) {
7854 CheckFormatHandler::EmitFormatDiagnostic(
7855 S, inFunctionCall, Args[format_idx],
7856 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
7864 CheckPrintfHandler H(
7865 S, FExpr, OrigFormatExpr,
Type, firstDataArg, numDataArgs,
7867 Args, format_idx, inFunctionCall, CallType, CheckedVarArgs,
7875 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
7876 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
7877 CallType, CheckedVarArgs, UncoveredArg);
7888 const char *Str = StrRef.data();
7891 assert(
T &&
"String literal not of constant array type!");
7892 size_t TypeSize =
T->getZExtSize();
7893 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
7904 switch (AbsFunction) {
7908 case Builtin::BI__builtin_abs:
7909 return Builtin::BI__builtin_labs;
7910 case Builtin::BI__builtin_labs:
7911 return Builtin::BI__builtin_llabs;
7912 case Builtin::BI__builtin_llabs:
7915 case Builtin::BI__builtin_fabsf:
7916 return Builtin::BI__builtin_fabs;
7917 case Builtin::BI__builtin_fabs:
7918 return Builtin::BI__builtin_fabsl;
7919 case Builtin::BI__builtin_fabsl:
7922 case Builtin::BI__builtin_cabsf:
7923 return Builtin::BI__builtin_cabs;
7924 case Builtin::BI__builtin_cabs:
7925 return Builtin::BI__builtin_cabsl;
7926 case Builtin::BI__builtin_cabsl:
7929 case Builtin::BIabs:
7930 return Builtin::BIlabs;
7931 case Builtin::BIlabs:
7932 return Builtin::BIllabs;
7933 case Builtin::BIllabs:
7936 case Builtin::BIfabsf:
7937 return Builtin::BIfabs;
7938 case Builtin::BIfabs:
7939 return Builtin::BIfabsl;
7940 case Builtin::BIfabsl:
7943 case Builtin::BIcabsf:
7944 return Builtin::BIcabs;
7945 case Builtin::BIcabs:
7946 return Builtin::BIcabsl;
7947 case Builtin::BIcabsl:
7976 unsigned AbsFunctionKind) {
7977 unsigned BestKind = 0;
7979 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
7985 else if (Context.
hasSameType(ParamType, ArgType)) {
8008 llvm_unreachable(
"Type not integer, floating, or complex");
8015 switch (ValueKind) {
8020 case Builtin::BI__builtin_fabsf:
8021 case Builtin::BI__builtin_fabs:
8022 case Builtin::BI__builtin_fabsl:
8023 case Builtin::BI__builtin_cabsf:
8024 case Builtin::BI__builtin_cabs:
8025 case Builtin::BI__builtin_cabsl:
8026 return Builtin::BI__builtin_abs;
8027 case Builtin::BIfabsf:
8028 case Builtin::BIfabs:
8029 case Builtin::BIfabsl:
8030 case Builtin::BIcabsf:
8031 case Builtin::BIcabs:
8032 case Builtin::BIcabsl:
8033 return Builtin::BIabs;
8039 case Builtin::BI__builtin_abs:
8040 case Builtin::BI__builtin_labs:
8041 case Builtin::BI__builtin_llabs:
8042 case Builtin::BI__builtin_cabsf:
8043 case Builtin::BI__builtin_cabs:
8044 case Builtin::BI__builtin_cabsl:
8045 return Builtin::BI__builtin_fabsf;
8046 case Builtin::BIabs:
8047 case Builtin::BIlabs:
8048 case Builtin::BIllabs:
8049 case Builtin::BIcabsf:
8050 case Builtin::BIcabs:
8051 case Builtin::BIcabsl:
8052 return Builtin::BIfabsf;
8058 case Builtin::BI__builtin_abs:
8059 case Builtin::BI__builtin_labs:
8060 case Builtin::BI__builtin_llabs:
8061 case Builtin::BI__builtin_fabsf:
8062 case Builtin::BI__builtin_fabs:
8063 case Builtin::BI__builtin_fabsl:
8064 return Builtin::BI__builtin_cabsf;
8065 case Builtin::BIabs:
8066 case Builtin::BIlabs:
8067 case Builtin::BIllabs:
8068 case Builtin::BIfabsf:
8069 case Builtin::BIfabs:
8070 case Builtin::BIfabsl:
8071 return Builtin::BIcabsf;
8074 llvm_unreachable(
"Unable to convert function");
8085 case Builtin::BI__builtin_abs:
8086 case Builtin::BI__builtin_fabs:
8087 case Builtin::BI__builtin_fabsf:
8088 case Builtin::BI__builtin_fabsl:
8089 case Builtin::BI__builtin_labs:
8090 case Builtin::BI__builtin_llabs:
8091 case Builtin::BI__builtin_cabs:
8092 case Builtin::BI__builtin_cabsf:
8093 case Builtin::BI__builtin_cabsl:
8094 case Builtin::BIabs:
8095 case Builtin::BIlabs:
8096 case Builtin::BIllabs:
8097 case Builtin::BIfabs:
8098 case Builtin::BIfabsf:
8099 case Builtin::BIfabsl:
8100 case Builtin::BIcabs:
8101 case Builtin::BIcabsf:
8102 case Builtin::BIcabsl:
8105 llvm_unreachable(
"Unknown Builtin type");
8111 unsigned AbsKind,
QualType ArgType) {
8112 bool EmitHeaderHint =
true;
8113 const char *HeaderName =
nullptr;
8114 StringRef FunctionName;
8116 FunctionName =
"std::abs";
8118 HeaderName =
"cstdlib";
8120 HeaderName =
"cmath";
8122 llvm_unreachable(
"Invalid Type");
8131 for (
const auto *I : R) {
8134 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
8136 FDecl = dyn_cast<FunctionDecl>(I);
8151 EmitHeaderHint =
false;
8169 EmitHeaderHint =
false;
8173 }
else if (!R.
empty()) {
8179 S.
Diag(
Loc, diag::note_replace_abs_function)
8185 if (!EmitHeaderHint)
8188 S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
8192template <std::
size_t StrLen>
8194 const char (&Str)[StrLen]) {
8209 (
Call->getBuiltinCallee() == Builtin::BI__builtin_nanf)) &&
8210 FPO.getNoHonorNaNs())
8211 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8212 << 1 << 0 <<
Call->getSourceRange();
8216 FPO.getNoHonorInfs())
8217 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8218 << 0 << 0 <<
Call->getSourceRange();
8221void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
8223 if (
Call->getNumArgs() != 1)
8228 if (AbsKind == 0 && !IsStdAbs)
8231 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8237 StringRef FunctionName =
8239 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
8240 Diag(
Call->getExprLoc(), diag::note_remove_abs)
8249 unsigned DiagType = 0;
8255 Diag(
Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
8269 if (ArgValueKind == ParamValueKind) {
8274 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
8275 << FDecl << ArgType << ParamType;
8277 if (NewAbsKind == 0)
8281 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8290 if (NewAbsKind == 0)
8293 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
8294 << FDecl << ParamValueKind << ArgValueKind;
8297 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8303 if (!
Call || !FDecl)
return;
8307 if (
Call->getExprLoc().isMacroID())
return;
8310 if (
Call->getNumArgs() != 2)
return;
8313 if (!ArgList)
return;
8314 if (ArgList->size() != 1)
return;
8317 const auto& TA = ArgList->
get(0);
8323 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
8324 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
8325 if (!MTE)
return false;
8326 const auto *Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
8327 if (!Num)
return false;
8328 if (Num->getValue() != 0)
return false;
8332 const Expr *FirstArg =
Call->getArg(0);
8333 const Expr *SecondArg =
Call->getArg(1);
8334 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
8335 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
8338 if (IsFirstArgZero == IsSecondArgZero)
return;
8343 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
8345 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
8346 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
8350 if (IsFirstArgZero) {
8358 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
8378 if (!Size->isComparisonOp() && !Size->isLogicalOp())
8382 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
8383 << SizeRange << FnName;
8384 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
8389 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
8400 bool &IsContained) {
8403 IsContained =
false;
8416 for (
auto *FD : RD->
fields()) {
8429 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
8430 if (Unary->getKind() == UETT_SizeOf)
8439 if (!
SizeOf->isArgumentType())
8440 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
8447 return SizeOf->getTypeOfArgument();
8453struct SearchNonTrivialToInitializeField
8458 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8462 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8463 asDerived().visitArray(PDIK, AT, SL);
8467 Super::visitWithKind(PDIK, FT, SL);
8482 visit(getContext().getBaseElementType(AT), SL);
8487 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
8496struct SearchNonTrivialToCopyField
8500 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8504 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8505 asDerived().visitArray(PCK, AT, SL);
8509 Super::visitWithKind(PCK, FT, SL);
8524 visit(getContext().getBaseElementType(AT), SL);
8547 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
8548 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
8572 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
8574 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
8575 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
8581 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
8584 const Expr *SizeArg =
8585 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
8587 auto isLiteralZero = [](
const Expr *
E) {
8588 return (isa<IntegerLiteral>(
E) &&
8589 cast<IntegerLiteral>(
E)->getValue() == 0) ||
8590 (isa<CharacterLiteral>(
E) &&
8591 cast<CharacterLiteral>(
E)->getValue() == 0);
8597 if (isLiteralZero(SizeArg) &&
8604 if (BId == Builtin::BIbzero ||
8607 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
8608 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
8609 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
8610 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
8611 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
8619 if (BId == Builtin::BImemset &&
8623 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
8624 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
8629void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
8636 unsigned ExpectedNumArgs =
8637 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
8638 if (
Call->getNumArgs() < ExpectedNumArgs)
8641 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
8642 BId == Builtin::BIstrndup ? 1 : 2);
8644 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
8645 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
8648 Call->getBeginLoc(),
Call->getRParenLoc()))
8657 llvm::FoldingSetNodeID SizeOfArgID;
8662 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8666 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
8667 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
8689 if (SizeOfArgID == llvm::FoldingSetNodeID())
8691 llvm::FoldingSetNodeID DestID;
8693 if (DestID == SizeOfArgID) {
8696 unsigned ActionIdx = 0;
8697 StringRef ReadableName = FnName->
getName();
8699 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
8700 if (UnaryOp->getOpcode() == UO_AddrOf)
8714 if (
SM.isMacroArgExpansion(SL)) {
8716 SL =
SM.getSpellingLoc(SL);
8724 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
8731 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
8746 PDiag(diag::warn_sizeof_pointer_type_memaccess)
8747 << FnName << SizeOfArgTy << ArgIdx
8765 unsigned OperationType = 0;
8766 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
8769 if (ArgIdx != 0 || IsCmp) {
8770 if (BId == Builtin::BImemcpy)
8772 else if(BId == Builtin::BImemmove)
8779 PDiag(diag::warn_dyn_class_memaccess)
8780 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
8781 << IsContained << ContainedRD << OperationType
8782 <<
Call->getCallee()->getSourceRange());
8784 BId != Builtin::BImemset)
8787 PDiag(diag::warn_arc_object_memaccess)
8788 << ArgIdx << FnName << PointeeTy
8789 <<
Call->getCallee()->getSourceRange());
8791 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
8792 RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
8794 PDiag(diag::warn_cstruct_memaccess)
8795 << ArgIdx << FnName << PointeeTy << 0);
8796 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
8797 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
8798 RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
8800 PDiag(diag::warn_cstruct_memaccess)
8801 << ArgIdx << FnName << PointeeTy << 1);
8802 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
8811 PDiag(diag::note_bad_memaccess_silence)
8831 if (isa<IntegerLiteral>(RHS))
8833 else if (isa<IntegerLiteral>(LHS))
8847 if (CAT->getZExtSize() <= 1)
8855void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
8859 unsigned NumArgs =
Call->getNumArgs();
8860 if ((NumArgs != 3) && (NumArgs != 4))
8865 const Expr *CompareWithSrc =
nullptr;
8868 Call->getBeginLoc(),
Call->getRParenLoc()))
8873 CompareWithSrc = Ex;
8876 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
8877 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
8878 SizeCall->getNumArgs() == 1)
8883 if (!CompareWithSrc)
8890 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
8894 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
8895 if (!CompareWithSrcDRE ||
8899 const Expr *OriginalSizeArg =
Call->getArg(2);
8900 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
8907 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
8912 llvm::raw_svector_ostream
OS(sizeString);
8917 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
8924 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
8925 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
8926 return D1->getDecl() == D2->getDecl();
8931 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
8935 return CE->getArg(0)->IgnoreParenCasts();
8940void Sema::CheckStrncatArguments(
const CallExpr *CE,
8955 unsigned PatternType = 0;
8963 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
8964 if (BE->getOpcode() == BO_Sub) {
8977 if (PatternType == 0)
8986 if (
SM.isMacroArgExpansion(SL)) {
8987 SL =
SM.getSpellingLoc(SL);
8996 if (!isKnownSizeArray) {
8997 if (PatternType == 1)
8998 Diag(SL, diag::warn_strncat_wrong_size) << SR;
9000 Diag(SL, diag::warn_strncat_src_size) << SR;
9004 if (PatternType == 1)
9005 Diag(SL, diag::warn_strncat_large_size) << SR;
9007 Diag(SL, diag::warn_strncat_src_size) << SR;
9010 llvm::raw_svector_ostream
OS(sizeString);
9018 Diag(SL, diag::note_strncat_wrong_size)
9023void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
9025 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
9027 << CalleeName << 0 << cast<NamedDecl>(
D);
9032void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
9034 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
9035 const Decl *
D = Lvalue->getDecl();
9036 if (isa<DeclaratorDecl>(
D))
9037 if (!dyn_cast<DeclaratorDecl>(
D)->getType()->isReferenceType())
9038 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
9041 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
9042 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
9043 Lvalue->getMemberDecl());
9046void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
9048 const auto *Lambda = dyn_cast<LambdaExpr>(
9053 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
9054 << CalleeName << 2 ;
9057void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
9059 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
9064 << CalleeName << 0 << Var;
9067void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
9070 llvm::raw_svector_ostream OS(SizeString);
9073 if (Kind == clang::CK_BitCast &&
9074 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
9076 if (Kind == clang::CK_IntegralToPointer &&
9077 !isa<IntegerLiteral>(
9078 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
9081 switch (
Cast->getCastKind()) {
9082 case clang::CK_BitCast:
9083 case clang::CK_IntegralToPointer:
9084 case clang::CK_FunctionToPointerDecay:
9093 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
9094 << CalleeName << 0 << OS.str();
9098void Sema::CheckFreeArguments(
const CallExpr *
E) {
9099 const std::string CalleeName =
9100 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
9104 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
9106 case UnaryOperator::Opcode::UO_AddrOf:
9107 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
9108 case UnaryOperator::Opcode::UO_Plus:
9109 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
9114 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
9116 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
9118 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
9119 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
9120 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
9124 if (isa<BlockExpr>(Arg)) {
9126 << CalleeName << 1 ;
9131 if (
const auto *Cast = dyn_cast<CastExpr>(
E->getArg(0)))
9132 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
9136Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
9142 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
9145 Diag(ReturnLoc, diag::warn_null_ret)
9155 if (Op == OO_New || Op == OO_Array_New) {
9160 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
9166 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
9183 auto getCastAndLiteral = [&FPLiteral, &FPCast](
Expr *L,
Expr *R) {
9184 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
9186 return FPLiteral && FPCast;
9189 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
9195 llvm::APFloat TargetC = FPLiteral->
getValue();
9197 llvm::APFloat::rmNearestTiesToEven, &Lossy);
9201 Diag(
Loc, diag::warn_float_compare_literal)
9202 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
9215 if (
auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
9216 if (
auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
9217 if (DRL->getDecl() == DRR->getDecl())
9225 if (
FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
9229 if (
FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
9234 if (
CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
9235 if (CL->getBuiltinCallee())
9238 if (
CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
9239 if (CR->getBuiltinCallee())
9243 Diag(
Loc, diag::warn_floatingpoint_eq)
9264 IntRange(
unsigned Width,
bool NonNegative)
9265 : Width(Width), NonNegative(NonNegative) {}
9268 unsigned valueBits()
const {
9269 return NonNegative ? Width : Width - 1;
9273 static IntRange forBoolType() {
9274 return IntRange(1,
true);
9279 return forValueOfCanonicalType(
C,
9287 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9288 T = VT->getElementType().getTypePtr();
9290 T = CT->getElementType().getTypePtr();
9291 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9292 T = AT->getValueType().getTypePtr();
9294 if (!
C.getLangOpts().CPlusPlus) {
9296 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9297 T = ET->getDecl()->getIntegerType().getDesugaredType(
C).getTypePtr();
9298 }
else if (
const EnumType *ET = dyn_cast<EnumType>(
T)) {
9303 if (
Enum->isFixed()) {
9304 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
9305 !ET->isSignedIntegerOrEnumerationType());
9308 unsigned NumPositive =
Enum->getNumPositiveBits();
9309 unsigned NumNegative =
Enum->getNumNegativeBits();
9311 if (NumNegative == 0)
9312 return IntRange(NumPositive,
true);
9314 return IntRange(std::max(NumPositive + 1, NumNegative),
9318 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9319 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9335 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9336 T = VT->getElementType().getTypePtr();
9338 T = CT->getElementType().getTypePtr();
9339 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9340 T = AT->getValueType().getTypePtr();
9341 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9342 T =
C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
9344 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9345 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9354 static IntRange join(IntRange L, IntRange R) {
9355 bool Unsigned = L.NonNegative && R.NonNegative;
9356 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
9357 L.NonNegative && R.NonNegative);
9361 static IntRange bit_and(IntRange L, IntRange R) {
9362 unsigned Bits = std::max(L.Width, R.Width);
9363 bool NonNegative =
false;
9364 if (L.NonNegative) {
9365 Bits = std::min(Bits, L.Width);
9368 if (R.NonNegative) {
9369 Bits = std::min(Bits, R.Width);
9372 return IntRange(Bits, NonNegative);
9376 static IntRange sum(IntRange L, IntRange R) {
9377 bool Unsigned = L.NonNegative && R.NonNegative;
9378 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
9383 static IntRange difference(IntRange L, IntRange R) {
9387 bool CanWiden = !L.NonNegative || !R.NonNegative;
9388 bool Unsigned = L.NonNegative && R.Width == 0;
9389 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
9395 static IntRange product(IntRange L, IntRange R) {
9399 bool CanWiden = !L.NonNegative && !R.NonNegative;
9400 bool Unsigned = L.NonNegative && R.NonNegative;
9401 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
9406 static IntRange rem(IntRange L, IntRange R) {
9410 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
9418 unsigned MaxWidth) {
9419 if (value.isSigned() && value.isNegative())
9420 return IntRange(value.getSignificantBits(),
false);
9422 if (value.getBitWidth() > MaxWidth)
9423 value = value.trunc(MaxWidth);
9427 return IntRange(value.getActiveBits(),
true);
9431 unsigned MaxWidth) {
9439 R = IntRange::join(R, El);
9447 return IntRange::join(R, I);
9462 Ty = AtomicRHS->getValueType();
9475 bool InConstantContext,
bool Approximate) {
9486 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
9487 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
9488 return GetExprRange(
C, CE->getSubExpr(), MaxWidth, InConstantContext,
9491 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
9493 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
9494 CE->getCastKind() == CK_BooleanToSignedIntegral;
9498 return OutputTypeRange;
9501 std::min(MaxWidth, OutputTypeRange.Width),
9502 InConstantContext, Approximate);
9505 if (SubRange.Width >= OutputTypeRange.Width)
9506 return OutputTypeRange;
9510 return IntRange(SubRange.Width,
9511 SubRange.NonNegative || OutputTypeRange.NonNegative);
9514 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
9517 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
9519 CondResult ? CO->getTrueExpr() : CO->getFalseExpr(),
9520 MaxWidth, InConstantContext, Approximate);
9525 Expr *
E = CO->getTrueExpr();
9529 E = CO->getFalseExpr();
9533 return IntRange::join(L, R);
9536 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
9537 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
9539 switch (BO->getOpcode()) {
9541 llvm_unreachable(
"builtin <=> should have class type");
9552 return IntRange::forBoolType();
9570 return GetExprRange(
C, BO->getRHS(), MaxWidth, InConstantContext,
9581 Combine = IntRange::bit_and;
9589 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
9590 if (I->getValue() == 1) {
9592 return IntRange(R.Width,
true);
9602 case BO_ShrAssign: {
9603 IntRange L =
GetExprRange(
C, BO->getLHS(), MaxWidth, InConstantContext,
9608 if (std::optional<llvm::APSInt> shift =
9609 BO->getRHS()->getIntegerConstantExpr(
C)) {
9610 if (shift->isNonNegative()) {
9611 if (shift->uge(L.Width))
9612 L.Width = (L.NonNegative ? 0 : 1);
9614 L.Width -= shift->getZExtValue();
9623 return GetExprRange(
C, BO->getRHS(), MaxWidth, InConstantContext,
9628 Combine = IntRange::sum;
9632 if (BO->getLHS()->getType()->isPointerType())
9635 Combine = IntRange::difference;
9640 Combine = IntRange::product;
9648 IntRange L =
GetExprRange(
C, BO->getLHS(), opWidth, InConstantContext,
9652 if (std::optional<llvm::APSInt> divisor =
9653 BO->getRHS()->getIntegerConstantExpr(
C)) {
9654 unsigned log2 = divisor->logBase2();
9655 if (
log2 >= L.Width)
9656 L.Width = (L.NonNegative ? 0 : 1);
9658 L.Width = std::min(L.Width -
log2, MaxWidth);
9665 IntRange R =
GetExprRange(
C, BO->getRHS(), opWidth, InConstantContext,
9667 return IntRange(L.Width, L.NonNegative && R.NonNegative);
9671 Combine = IntRange::rem;
9683 unsigned opWidth =
C.getIntWidth(
T);
9685 GetExprRange(
C, BO->getLHS(), opWidth, InConstantContext, Approximate);
9687 GetExprRange(
C, BO->getRHS(), opWidth, InConstantContext, Approximate);
9688 IntRange
C = Combine(L, R);
9690 C.Width = std::min(
C.Width, MaxWidth);
9694 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
9695 switch (UO->getOpcode()) {
9698 return IntRange::forBoolType();
9706 return GetExprRange(
C, UO->getSubExpr(), MaxWidth, InConstantContext,
9711 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
9712 return GetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
9716 return IntRange(BitField->getBitWidthValue(
C),
9717 BitField->getType()->isUnsignedIntegerOrEnumerationType());
9723 bool InConstantContext,
bool Approximate) {
9732 const llvm::fltSemantics &Src,
9733 const llvm::fltSemantics &Tgt) {
9734 llvm::APFloat truncated = value;
9737 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
9738 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
9740 return truncated.bitwiseIsEqual(value);
9749 const llvm::fltSemantics &Src,
9750 const llvm::fltSemantics &Tgt) {
9767 bool IsListInit =
false);
9773 if (isa<EnumConstantDecl>(DR->getDecl()))
9783 return MacroName !=
"YES" && MacroName !=
"NO" &&
9784 MacroName !=
"true" && MacroName !=
"false";
9807struct PromotedRange {
9809 llvm::APSInt PromotedMin;
9811 llvm::APSInt PromotedMax;
9813 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
9815 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
9816 else if (R.Width >= BitWidth && !
Unsigned) {
9820 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
9821 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
9823 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
9824 .extOrTrunc(BitWidth);
9825 PromotedMin.setIsUnsigned(
Unsigned);
9827 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
9828 .extOrTrunc(BitWidth);
9829 PromotedMax.setIsUnsigned(
Unsigned);
9834 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
9847 Min =
LE | InRangeFlag,
9849 Max =
GE | InRangeFlag,
9852 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
9857 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
9858 Value.isUnsigned() == PromotedMin.isUnsigned());
9859 if (!isContiguous()) {
9860 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
9861 if (
Value.isMinValue())
return Min;
9862 if (
Value.isMaxValue())
return Max;
9868 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
9869 case -1:
return Less;
9870 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
9872 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
9879 llvm_unreachable(
"impossible compare result");
9882 static std::optional<StringRef>
9886 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
9888 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
9889 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
9890 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
9891 return std::nullopt;
9898 }
else if (Op == BO_NE) {
9902 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
9909 if (Op == BO_GE || Op == BO_LE)
9910 std::swap(TrueFlag, FalseFlag);
9913 return StringRef(
"true");
9915 return StringRef(
"false");
9916 return std::nullopt;
9924 if (ICE->getCastKind() != CK_IntegralCast &&
9925 ICE->getCastKind() != CK_NoOp)
9927 E = ICE->getSubExpr();
9936 enum ConstantValueKind {
9941 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
9942 return BL->getValue() ? ConstantValueKind::LiteralTrue
9943 : ConstantValueKind::LiteralFalse;
9944 return ConstantValueKind::Miscellaneous;
9949 const llvm::APSInt &
Value,
9975 OtherT = AT->getValueType();
9976 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
9980 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
9986 bool OtherIsBooleanDespiteType =
9988 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
9989 OtherTypeRange = OtherValueRange = IntRange::forBoolType();
9993 PromotedRange OtherPromotedValueRange(OtherValueRange,
Value.getBitWidth(),
9994 Value.isUnsigned());
9995 auto Cmp = OtherPromotedValueRange.compare(
Value);
9996 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
10002 bool TautologicalTypeCompare =
false;
10004 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
10005 Value.isUnsigned());
10006 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
10007 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
10009 TautologicalTypeCompare =
true;
10017 if (!TautologicalTypeCompare && OtherValueRange.Width == 0)
10026 bool InRange = Cmp & PromotedRange::InRangeFlag;
10032 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
10033 Other->getType()->isUnsignedIntegerOrEnumerationType())
10034 TautologicalTypeCompare =
true;
10039 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant))
10040 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
10044 llvm::raw_svector_ostream OS(PrettySourceValue);
10046 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
10047 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
10049 OS << (BL->getValue() ?
"YES" :
"NO");
10054 if (!TautologicalTypeCompare) {
10055 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
10056 << RhsConstant << OtherValueRange.Width << OtherValueRange.NonNegative
10057 <<
E->getOpcodeStr() << OS.str() << *
Result
10062 if (IsObjCSignedCharBool) {
10064 S.
PDiag(diag::warn_tautological_compare_objc_bool)
10065 << OS.str() << *
Result);
10072 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
10075 E->getOperatorLoc(),
E,
10076 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
10077 : diag::warn_tautological_bool_compare)
10079 << OtherIsBooleanDespiteType << *
Result
10086 ? diag::warn_unsigned_enum_always_true_comparison
10087 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
10088 : diag::warn_unsigned_always_true_comparison)
10089 : diag::warn_tautological_constant_compare;
10092 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result
10122 Expr *LHS =
E->getLHS();
10123 Expr *RHS =
E->getRHS();
10126 std::optional<llvm::APSInt> RHSValue =
10128 std::optional<llvm::APSInt> LHSValue =
10132 if (RHSValue && LHSValue)
10136 if ((
bool)RHSValue ^ (
bool)LHSValue) {
10138 const bool RhsConstant = (
bool)RHSValue;
10139 Expr *Const = RhsConstant ? RHS : LHS;
10141 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
10164 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
10166 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
10172 Expr *signedOperand, *unsignedOperand;
10175 "unsigned comparison between two signed integer expressions?");
10176 signedOperand = LHS;
10177 unsignedOperand = RHS;
10179 signedOperand = RHS;
10180 unsignedOperand = LHS;
10186 IntRange signedRange =
10196 if (signedRange.NonNegative)
10203 if (
E->isEqualityOp()) {
10205 IntRange unsignedRange =
10211 assert(unsignedRange.NonNegative &&
"unsigned range includes negative?");
10213 if (unsignedRange.Width < comparisonWidth)
10218 S.
PDiag(diag::warn_mixed_sign_comparison)
10246 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
10247 << BitfieldEnumDecl;
10254 Init->isValueDependent() ||
10255 Init->isTypeDependent())
10258 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
10281 unsigned DiagID = 0;
10282 if (SignedEnum && !SignedBitfield) {
10283 DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
10284 }
else if (SignedBitfield && !SignedEnum &&
10286 DiagID = diag::warn_signed_bitfield_enum_conversion;
10290 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
10295 << SignedEnum << TypeRange;
10306 if (BitsNeeded > FieldWidth) {
10308 S.
Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
10320 unsigned OriginalWidth =
Value.getBitWidth();
10326 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
10327 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
10334 if (!
Value.isSigned() ||
Value.isNegative())
10335 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
10336 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
10337 OriginalWidth =
Value.getSignificantBits();
10339 if (OriginalWidth <= FieldWidth)
10343 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
10347 TruncatedValue = TruncatedValue.extend(OriginalWidth);
10348 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
10352 std::string PrettyTrunc =
toString(TruncatedValue, 10);
10354 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
10355 ? diag::warn_impcast_single_bit_bitield_precision_constant
10356 : diag::warn_impcast_bitfield_precision_constant)
10357 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
10358 <<
Init->getSourceRange();
10373 E->getOperatorLoc())) {
10376 E->getOperatorLoc());
10390 bool pruneControlFlow =
false) {
10391 if (pruneControlFlow) {
10405 unsigned diag,
bool pruneControlFlow =
false) {
10418 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
10421 const bool IsLiteral =
10422 isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
10424 llvm::APFloat
Value(0.0);
10430 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10435 diag::warn_impcast_float_integer, PruneWarnings);
10438 bool isExact =
false;
10442 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
10443 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
10451 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
10452 precision = (precision * 59 + 195) / 196;
10453 Value.toString(PrettySourceValue, precision);
10457 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10458 << PrettySourceValue);
10461 if (
Result == llvm::APFloat::opOK && isExact) {
10462 if (IsLiteral)
return;
10469 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
10472 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
10473 : diag::warn_impcast_float_to_integer_out_of_range,
10476 unsigned DiagID = 0;
10479 DiagID = diag::warn_impcast_literal_float_to_integer;
10480 }
else if (IntegerValue == 0) {
10481 if (
Value.isZero()) {
10483 diag::warn_impcast_float_integer, PruneWarnings);
10486 DiagID = diag::warn_impcast_float_to_integer_zero;
10488 if (IntegerValue.isUnsigned()) {
10489 if (!IntegerValue.isMaxValue()) {
10491 diag::warn_impcast_float_integer, PruneWarnings);
10494 if (!IntegerValue.isMaxSignedValue() &&
10495 !IntegerValue.isMinSignedValue()) {
10497 diag::warn_impcast_float_integer, PruneWarnings);
10501 DiagID = diag::warn_impcast_float_to_integer;
10506 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
10508 IntegerValue.toString(PrettyTargetValue);
10510 if (PruneWarnings) {
10513 <<
E->
getType() <<
T.getUnqualifiedType()
10514 << PrettySourceValue << PrettyTargetValue
10518 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
10526 assert(isa<CompoundAssignOperator>(
E) &&
10527 "Must be compound assignment operation");
10533 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
10537 const auto *RBT = cast<CompoundAssignOperator>(
E)
10538 ->getComputationResultType()
10545 if (ResultBT->isInteger())
10547 E->
getExprLoc(), diag::warn_impcast_float_integer);
10549 if (!ResultBT->isFloatingPoint())
10558 diag::warn_impcast_float_result_precision);
10563 if (!
Range.Width)
return "0";
10565 llvm::APSInt ValueInRange =
Value;
10566 ValueInRange.setIsSigned(!
Range.NonNegative);
10567 ValueInRange = ValueInRange.trunc(
Range.Width);
10568 return toString(ValueInRange, 10);
10572 if (!isa<ImplicitCastExpr>(Ex))
10577 const Type *Source =
10579 if (
Target->isDependentType())
10583 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
10584 const Type *BoolCandidateType = ToBool ?
Target : Source;
10593 for (
unsigned i = 0; i < NumArgs; ++i) {
10598 bool IsSwapped = ((i > 0) &&
10600 IsSwapped |= ((i < (NumArgs - 1)) &&
10606 diag::warn_impcast_floating_point_to_bool);
10613 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
10618 if (isa<CallExpr>(
E))
10623 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
10625 if (!IsGNUNullExpr && !HasNullPtrType)
10645 if (MacroName ==
"NULL")
10653 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
10667 const char FirstLiteralCharacter =
10669 if (FirstLiteralCharacter ==
'0')
10676 const char FirstContextCharacter =
10678 if (FirstContextCharacter ==
'{')
10686 const auto *IL = dyn_cast<IntegerLiteral>(
E);
10688 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
10689 if (UO->getOpcode() == UO_Minus)
10690 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
10701 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
10705 if (Opc == BO_Shl) {
10708 if (LHS && LHS->getValue() == 0)
10709 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
10711 RHS->getValue().isNonNegative() &&
10713 S.
Diag(ExprLoc, diag::warn_left_shift_always)
10714 << (
Result.Val.getInt() != 0);
10716 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context) <<
E;
10720 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
10725 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
10726 (RHS->getValue() == 0 || RHS->getValue() == 1))
10729 if (LHS->getValue() != 0 && RHS->getValue() != 0)
10730 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
10735 bool *ICContext,
bool IsListInit) {
10740 if (Source ==
Target)
return;
10741 if (
Target->isDependentType())
return;
10755 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
10756 if (isa<StringLiteral>(
E))
10761 diag::warn_impcast_string_literal_to_bool);
10762 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
10763 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
10767 diag::warn_impcast_objective_c_literal_to_bool);
10782 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
10784 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
10793 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
10795 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
10799 if (isa<VectorType>(Source)) {
10800 if (
Target->isSveVLSBuiltinType() &&
10807 if (
Target->isRVVVLSBuiltinType() &&
10814 if (!isa<VectorType>(
Target)) {
10824 diag::warn_hlsl_impcast_vector_truncation);
10833 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
10834 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
10836 if (
auto VecTy = dyn_cast<VectorType>(
Target))
10837 Target = VecTy->getElementType().getTypePtr();
10840 if (isa<ComplexType>(Source)) {
10841 if (!isa<ComplexType>(
Target)) {
10847 ? diag::err_impcast_complex_scalar
10848 : diag::warn_impcast_complex_scalar);
10851 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
10852 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
10855 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
10908 else if (Order < 0) {
10918 if (TargetBT && TargetBT->
isInteger()) {
10933 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
10941 if (isa<ImplicitCastExpr>(LastA) &&
10945 diag::warn_impcast_floating_point_to_bool);
10954 if (
Target->isUnsaturatedFixedPointType()) {
10958 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
10963 PDiag(diag::warn_impcast_fixed_point_range)
10964 <<
Value.toString() <<
T
10970 }
else if (
Target->isIntegerType()) {
10974 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
10977 llvm::APSInt IntResult = FXResult.convertToInt(
10983 PDiag(diag::warn_impcast_fixed_point_range)
10984 << FXResult.toString() <<
T
10991 }
else if (
Target->isUnsaturatedFixedPointType()) {
10999 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
11004 PDiag(diag::warn_impcast_fixed_point_range)
11023 unsigned int SourcePrecision =
SourceRange.Width;
11027 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
11030 if (SourcePrecision > 0 && TargetPrecision > 0 &&
11031 SourcePrecision > TargetPrecision) {
11033 if (std::optional<llvm::APSInt> SourceInt =
11038 llvm::APFloat TargetFloatValue(
11040 llvm::APFloat::opStatus ConversionStatus =
11041 TargetFloatValue.convertFromAPInt(
11043 llvm::APFloat::rmNearestTiesToEven);
11045 if (ConversionStatus != llvm::APFloat::opOK) {
11047 SourceInt->toString(PrettySourceValue, 10);
11049 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
11053 PDiag(diag::warn_impcast_integer_float_precision_constant)
11054 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11060 diag::warn_impcast_integer_float_precision);
11069 if (
Target->isBooleanType())
11077 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
11083 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11087 IntRange SourceTypeRange =
11088 IntRange::forTargetOfCanonicalType(
Context, Source);
11091 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
11093 if (LikelySourceRange.Width > TargetRange.Width) {
11099 llvm::APSInt
Value(32);
11109 PDiag(diag::warn_impcast_integer_precision_constant)
11110 << PrettySourceValue << PrettyTargetValue
11124 diag::warn_impcast_integer_precision);
11127 if (TargetRange.Width > SourceTypeRange.Width) {
11128 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
11129 if (UO->getOpcode() == UO_Minus)
11131 if (
Target->isUnsignedIntegerType())
11133 diag::warn_impcast_high_order_zero_bits);
11134 if (
Target->isSignedIntegerType())
11136 diag::warn_impcast_nonnegative_result);
11140 if (TargetRange.Width == LikelySourceRange.Width &&
11141 !TargetRange.NonNegative && LikelySourceRange.NonNegative &&
11156 PDiag(diag::warn_impcast_integer_precision_constant)
11157 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11166 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
11167 ((TargetRange.NonNegative && !LikelySourceRange.NonNegative) ||
11168 (!TargetRange.NonNegative && LikelySourceRange.NonNegative &&
11169 LikelySourceRange.Width == TargetRange.Width))) {
11173 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
11179 unsigned DiagID = diag::warn_impcast_integer_sign;
11187 DiagID = diag::warn_impcast_integer_sign_conditional;
11202 if (SourceEnum->getDecl()->hasNameForLinkage() &&
11203 TargetEnum->getDecl()->hasNameForLinkage() &&
11204 SourceEnum != TargetEnum) {
11209 diag::warn_impcast_different_enum_types);
11223 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
11235 Expr *TrueExpr =
E->getTrueExpr();
11236 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
11237 TrueExpr = BCO->getCommon();
11239 bool Suspicious =
false;
11248 if (!Suspicious)
return;
11251 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
11258 Suspicious =
false;
11280struct AnalyzeImplicitConversionsWorkItem {
11290 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
11292 Expr *OrigE = Item.E;
11301 bool IsListInit = Item.IsListInit ||
11302 (isa<InitListExpr>(OrigE) && S.
getLangOpts().CPlusPlus);
11307 Expr *SourceExpr =
E;
11312 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11313 if (
auto *Src = OVE->getSourceExpr())
11316 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
11317 if (UO->getOpcode() == UO_Not &&
11318 UO->getSubExpr()->isKnownToHaveBooleanValue())
11319 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
11323 if (
const auto *BO = dyn_cast<BinaryOperator>(SourceExpr))
11324 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
11325 BO->getLHS()->isKnownToHaveBooleanValue() &&
11326 BO->getRHS()->isKnownToHaveBooleanValue() &&
11327 BO->getLHS()->HasSideEffects(S.
Context) &&
11328 BO->getRHS()->HasSideEffects(S.
Context)) {
11339 if (SR.str() ==
"&" || SR.str() ==
"|") {
11341 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
11342 << (BO->getOpcode() == BO_And ?
"&" :
"|")
11345 BO->getOperatorLoc(),
11346 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
11347 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
11353 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
11374 for (
auto *SE : POE->semantics())
11375 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
11376 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
11380 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
11384 WorkList.push_back({
E, CC, IsListInit});
11390 if (BO->isComparisonOp())
11394 if (BO->getOpcode() == BO_Assign)
11397 if (BO->isAssignmentOp())
11405 if (isa<StmtExpr>(
E))
return;
11408 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
11413 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
11415 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
11419 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
11420 if (ChildExpr == CSE->getOperand())
11426 if (IsLogicalAndOperator &&
11431 WorkList.push_back({ChildExpr, CC, IsListInit});
11436 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11440 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11445 if (
U->getOpcode() == UO_LNot) {
11447 }
else if (
U->getOpcode() != UO_AddrOf) {
11448 if (
U->getSubExpr()->getType()->isAtomicType())
11449 S.
Diag(
U->getSubExpr()->getBeginLoc(),
11450 diag::warn_atomic_implicit_seq_cst);
11461 WorkList.push_back({OrigE, CC, IsListInit});
11462 while (!WorkList.empty())
11474 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
11477 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11478 if (!M->getMemberDecl()->getType()->isReferenceType())
11481 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
11483 FD =
Call->getDirectCallee();
11492 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
11506 if (
SM.isMacroBodyExpansion(
Loc))
11508 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
11531 if (isa<CXXThisExpr>(
E)) {
11532 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
11533 : diag::warn_this_bool_conversion;
11538 bool IsAddressOf =
false;
11540 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
11541 if (UO->getOpcode() != UO_AddrOf)
11543 IsAddressOf =
true;
11544 E = UO->getSubExpr();
11548 unsigned DiagID = IsCompare
11549 ? diag::warn_address_of_reference_null_compare
11550 : diag::warn_address_of_reference_bool_conversion;
11558 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
11559 bool IsParam = isa<NonNullAttr>(NonnullAttr);
11561 llvm::raw_string_ostream S(Str);
11563 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
11564 : diag::warn_cast_nonnull_to_bool;
11567 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
11572 if (
auto *Callee =
Call->getDirectCallee()) {
11573 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
11574 ComplainAboutNonnullParamOrCall(A);
11583 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
11584 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
11585 MRecordDecl && MRecordDecl->isLambda()) {
11588 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
11598 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11599 D = M->getMemberDecl();
11603 if (!
D ||
D->isWeak())
11607 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
11610 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
11611 ComplainAboutNonnullParamOrCall(A);
11615 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
11619 auto ParamIter = llvm::find(FD->
parameters(), PV);
11621 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
11625 ComplainAboutNonnullParamOrCall(
NonNull);
11630 if (ArgNo.getASTIndex() == ParamNo) {
11631 ComplainAboutNonnullParamOrCall(
NonNull);
11645 if (IsAddressOf && IsFunction) {
11650 if (!IsAddressOf && !IsFunction && !IsArray)
11655 llvm::raw_string_ostream S(Str);
11658 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
11659 : diag::warn_impcast_pointer_to_bool;
11666 DiagType = AddressOf;
11667 else if (IsFunction)
11668 DiagType = FunctionPointer;
11670 DiagType = ArrayPointer;
11672 llvm_unreachable(
"Could not determine diagnostic.");
11674 <<
Range << IsEqual;
11687 if (ReturnType.
isNull())
11725 CheckArrayAccess(
E);
11732 ::CheckBoolLikeConversion(*
this,
E, CC);
11735void Sema::CheckForIntOverflow (
const Expr *
E) {
11740 const Expr *OriginalE = Exprs.pop_back_val();
11743 if (isa<BinaryOperator, UnaryOperator>(
E)) {
11748 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
11749 Exprs.append(InitList->inits().begin(), InitList->inits().end());
11750 else if (isa<ObjCBoxedExpr>(OriginalE))
11752 else if (
const auto *
Call = dyn_cast<CallExpr>(
E))
11753 Exprs.append(
Call->arg_begin(),
Call->arg_end());
11754 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
11755 Exprs.append(Message->arg_begin(), Message->arg_end());
11756 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
11757 Exprs.append(Construct->arg_begin(), Construct->arg_end());
11758 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
11759 Exprs.push_back(Temporary->getSubExpr());
11760 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
11761 Exprs.push_back(Array->getIdx());
11762 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
11763 Exprs.push_back(Compound->getInitializer());
11764 else if (
const auto *New = dyn_cast<CXXNewExpr>(
E);
11765 New && New->isArray()) {
11766 if (
auto ArraySize = New->getArraySize())
11767 Exprs.push_back(*ArraySize);
11769 }
while (!Exprs.empty());
11784 class SequenceTree {
11788 LLVM_PREFERRED_TYPE(
bool)
11789 unsigned Merged : 1;
11797 friend class SequenceTree;
11801 explicit Seq(
unsigned N) : Index(N) {}
11804 Seq() : Index(0) {}
11807 SequenceTree() { Values.push_back(
Value(0)); }
11808 Seq root()
const {
return Seq(0); }
11815 return Seq(Values.size() - 1);
11819 void merge(
Seq S) {
11820 Values[S.Index].Merged =
true;
11826 bool isUnsequenced(
Seq Cur,
Seq Old) {
11827 unsigned C = representative(Cur.Index);
11828 unsigned Target = representative(Old.Index);
11832 C = Values[
C].Parent;
11839 unsigned representative(
unsigned K) {
11840 if (Values[K].Merged)
11842 return Values[K].Parent = representative(Values[K].
Parent);
11862 UK_ModAsSideEffect,
11864 UK_Count = UK_ModAsSideEffect + 1
11870 const Expr *UsageExpr =
nullptr;
11871 SequenceTree::Seq
Seq;
11877 Usage Uses[UK_Count];
11880 bool Diagnosed =
false;
11884 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
11892 UsageInfoMap UsageMap;
11895 SequenceTree::Seq Region;
11910 struct SequencedSubexpression {
11911 SequencedSubexpression(SequenceChecker &Self)
11912 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
11913 Self.ModAsSideEffect = &ModAsSideEffect;
11916 ~SequencedSubexpression() {
11917 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
11921 UsageInfo &UI = Self.UsageMap[M.first];
11922 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
11923 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
11924 SideEffectUsage = M.second;
11926 Self.ModAsSideEffect = OldModAsSideEffect;
11929 SequenceChecker &Self;
11938 class EvaluationTracker {
11940 EvaluationTracker(SequenceChecker &Self)
11941 : Self(Self), Prev(Self.EvalTracker) {
11942 Self.EvalTracker =
this;
11945 ~EvaluationTracker() {
11946 Self.EvalTracker = Prev;
11948 Prev->EvalOK &= EvalOK;
11951 bool evaluate(
const Expr *
E,
bool &Result) {
11955 Result, Self.SemaRef.Context,
11956 Self.SemaRef.isConstantEvaluatedContext());
11961 SequenceChecker &Self;
11962 EvaluationTracker *Prev;
11963 bool EvalOK =
true;
11964 } *EvalTracker =
nullptr;
11968 Object getObject(
const Expr *
E,
bool Mod)
const {
11971 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
11972 return getObject(UO->getSubExpr(), Mod);
11974 if (BO->getOpcode() == BO_Comma)
11975 return getObject(BO->getRHS(), Mod);
11976 if (Mod && BO->isAssignmentOp())
11977 return getObject(BO->getLHS(), Mod);
11978 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
11980 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
11981 return ME->getMemberDecl();
11982 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
11991 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
11993 Usage &
U = UI.Uses[UK];
11994 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
11998 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
11999 ModAsSideEffect->push_back(std::make_pair(O,
U));
12001 U.UsageExpr = UsageExpr;
12011 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
12012 UsageKind OtherKind,
bool IsModMod) {
12016 const Usage &
U = UI.Uses[OtherKind];
12017 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
12020 const Expr *Mod =
U.UsageExpr;
12021 const Expr *ModOrUse = UsageExpr;
12022 if (OtherKind == UK_Use)
12023 std::swap(Mod, ModOrUse);
12027 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
12028 : diag::warn_unsequenced_mod_use)
12030 UI.Diagnosed =
true;
12059 void notePreUse(Object O,
const Expr *UseExpr) {
12060 UsageInfo &UI = UsageMap[O];
12062 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
12065 void notePostUse(Object O,
const Expr *UseExpr) {
12066 UsageInfo &UI = UsageMap[O];
12067 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
12069 addUsage(O, UI, UseExpr, UK_Use);
12072 void notePreMod(Object O,
const Expr *ModExpr) {
12073 UsageInfo &UI = UsageMap[O];
12075 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
12076 checkUsage(O, UI, ModExpr, UK_Use,
false);
12079 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
12080 UsageInfo &UI = UsageMap[O];
12081 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
12083 addUsage(O, UI, ModExpr, UK);
12087 SequenceChecker(
Sema &S,
const Expr *
E,
12089 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
12093 (void)this->WorkList;
12096 void VisitStmt(
const Stmt *S) {
12100 void VisitExpr(
const Expr *
E) {
12102 Base::VisitStmt(
E);
12106 for (
auto *Sub : CSE->
children()) {
12107 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
12122 void VisitCastExpr(
const CastExpr *
E) {
12124 if (
E->getCastKind() == CK_LValueToRValue)
12125 O = getObject(
E->getSubExpr(),
false);
12134 void VisitSequencedExpressions(
const Expr *SequencedBefore,
12135 const Expr *SequencedAfter) {
12136 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
12137 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
12138 SequenceTree::Seq OldRegion = Region;
12141 SequencedSubexpression SeqBefore(*
this);
12142 Region = BeforeRegion;
12143 Visit(SequencedBefore);
12146 Region = AfterRegion;
12147 Visit(SequencedAfter);
12149 Region = OldRegion;
12151 Tree.merge(BeforeRegion);
12152 Tree.merge(AfterRegion);
12160 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
12167 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12168 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12174 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12181 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12182 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12187 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12199 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12203 SequenceTree::Seq RHSRegion;
12204 SequenceTree::Seq LHSRegion;
12206 RHSRegion =
Tree.allocate(Region);
12207 LHSRegion =
Tree.allocate(Region);
12209 RHSRegion = Region;
12210 LHSRegion = Region;
12212 SequenceTree::Seq OldRegion = Region;
12228 SequencedSubexpression SeqBefore(*
this);
12229 Region = RHSRegion;
12233 Region = LHSRegion;
12236 if (O && isa<CompoundAssignOperator>(BO))
12237 notePostUse(O, BO);
12241 Region = LHSRegion;
12244 if (O && isa<CompoundAssignOperator>(BO))
12245 notePostUse(O, BO);
12247 Region = RHSRegion;
12255 Region = OldRegion;
12259 : UK_ModAsSideEffect);
12261 Tree.merge(RHSRegion);
12262 Tree.merge(LHSRegion);
12267 VisitBinAssign(CAO);
12270 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12271 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12275 return VisitExpr(UO);
12283 : UK_ModAsSideEffect);
12286 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12287 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12291 return VisitExpr(UO);
12295 notePostMod(O, UO, UK_ModAsSideEffect);
12304 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12305 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12306 SequenceTree::Seq OldRegion = Region;
12308 EvaluationTracker Eval(*
this);
12310 SequencedSubexpression Sequenced(*
this);
12311 Region = LHSRegion;
12318 bool EvalResult =
false;
12319 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12320 bool ShouldVisitRHS = !EvalOK || !EvalResult;
12321 if (ShouldVisitRHS) {
12322 Region = RHSRegion;
12326 Region = OldRegion;
12327 Tree.merge(LHSRegion);
12328 Tree.merge(RHSRegion);
12337 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12338 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12339 SequenceTree::Seq OldRegion = Region;
12341 EvaluationTracker Eval(*
this);
12343 SequencedSubexpression Sequenced(*
this);
12344 Region = LHSRegion;
12350 bool EvalResult =
false;
12351 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12352 bool ShouldVisitRHS = !EvalOK || EvalResult;
12353 if (ShouldVisitRHS) {
12354 Region = RHSRegion;
12358 Region = OldRegion;
12359 Tree.merge(LHSRegion);
12360 Tree.merge(RHSRegion);
12368 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
12384 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
12385 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
12386 SequenceTree::Seq OldRegion = Region;
12388 EvaluationTracker Eval(*
this);
12390 SequencedSubexpression Sequenced(*
this);
12391 Region = ConditionRegion;
12401 bool EvalResult =
false;
12402 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
12403 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
12404 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
12405 if (ShouldVisitTrueExpr) {
12406 Region = TrueRegion;
12409 if (ShouldVisitFalseExpr) {
12410 Region = FalseRegion;
12414 Region = OldRegion;
12415 Tree.merge(ConditionRegion);
12416 Tree.merge(TrueRegion);
12417 Tree.merge(FalseRegion);
12420 void VisitCallExpr(
const CallExpr *CE) {
12432 SequencedSubexpression Sequenced(*
this);
12437 SequenceTree::Seq CalleeRegion;
12438 SequenceTree::Seq OtherRegion;
12439 if (SemaRef.getLangOpts().CPlusPlus17) {
12440 CalleeRegion = Tree.allocate(Region);
12441 OtherRegion = Tree.allocate(Region);
12443 CalleeRegion = Region;
12444 OtherRegion = Region;
12446 SequenceTree::Seq OldRegion = Region;
12449 Region = CalleeRegion;
12451 SequencedSubexpression Sequenced(*this);
12452 Visit(CE->getCallee());
12454 Visit(CE->getCallee());
12458 Region = OtherRegion;
12462 Region = OldRegion;
12464 Tree.merge(CalleeRegion);
12465 Tree.merge(OtherRegion);
12483 return VisitCallExpr(CXXOCE);
12494 case OO_MinusEqual:
12496 case OO_SlashEqual:
12497 case OO_PercentEqual:
12498 case OO_CaretEqual:
12501 case OO_LessLessEqual:
12502 case OO_GreaterGreaterEqual:
12503 SequencingKind = RHSBeforeLHS;
12507 case OO_GreaterGreater:
12513 SequencingKind = LHSBeforeRHS;
12517 SequencingKind = LHSBeforeRest;
12521 SequencingKind = NoSequencing;
12525 if (SequencingKind == NoSequencing)
12526 return VisitCallExpr(CXXOCE);
12529 SequencedSubexpression Sequenced(*
this);
12532 assert(SemaRef.getLangOpts().CPlusPlus17 &&
12533 "Should only get there with C++17 and above!");
12534 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
12535 "Should only get there with an overloaded binary operator"
12536 " or an overloaded call operator!");
12538 if (SequencingKind == LHSBeforeRest) {
12539 assert(CXXOCE->getOperator() == OO_Call &&
12540 "We should only have an overloaded call operator here!");
12549 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
12550 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
12551 SequenceTree::Seq OldRegion = Region;
12553 assert(CXXOCE->getNumArgs() >= 1 &&
12554 "An overloaded call operator must have at least one argument"
12555 " for the postfix-expression!");
12556 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
12557 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
12558 CXXOCE->getNumArgs() - 1);
12562 Region = PostfixExprRegion;
12563 SequencedSubexpression Sequenced(*this);
12564 Visit(PostfixExpr);
12568 Region = ArgsRegion;
12569 for (const Expr *Arg : Args)
12572 Region = OldRegion;
12573 Tree.merge(PostfixExprRegion);
12574 Tree.merge(ArgsRegion);
12576 assert(CXXOCE->getNumArgs() == 2 &&
12577 "Should only have two arguments here!");
12578 assert((SequencingKind == LHSBeforeRHS ||
12579 SequencingKind == RHSBeforeLHS) &&
12580 "Unexpected sequencing kind!");
12584 const Expr *E1 = CXXOCE->getArg(0);
12585 const Expr *E2 = CXXOCE->getArg(1);
12586 if (SequencingKind == RHSBeforeLHS)
12589 return VisitSequencedExpressions(E1, E2);
12596 SequencedSubexpression Sequenced(*
this);
12599 return VisitExpr(CCE);
12602 SequenceExpressionsInOrder(
12608 return VisitExpr(ILE);
12611 SequenceExpressionsInOrder(ILE->
inits());
12623 SequenceTree::Seq
Parent = Region;
12624 for (
const Expr *
E : ExpressionList) {
12628 Elts.push_back(Region);
12634 for (
unsigned I = 0; I < Elts.size(); ++I)
12635 Tree.merge(Elts[I]);
12639SequenceChecker::UsageInfo::UsageInfo() =
default;
12643void Sema::CheckUnsequencedOperations(
const Expr *
E) {
12645 WorkList.push_back(
E);
12646 while (!WorkList.empty()) {
12647 const Expr *Item = WorkList.pop_back_val();
12648 SequenceChecker(*
this, Item, WorkList);
12653 bool IsConstexpr) {
12655 IsConstexpr || isa<ConstantExpr>(
E));
12656 CheckImplicitConversions(
E, CheckLoc);
12658 CheckUnsequencedOperations(
E);
12660 CheckForIntOverflow(
E);
12674 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
12678 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
12682 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
12696 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
12700 bool CheckParameterNames) {
12701 bool HasInvalidParm =
false;
12703 assert(Param &&
"null in a parameter list");
12712 if (!Param->isInvalidDecl() &&
12714 diag::err_typecheck_decl_incomplete_type) ||
12716 diag::err_abstract_type_in_decl,
12718 Param->setInvalidDecl();
12719 HasInvalidParm =
true;
12724 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
12728 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
12736 QualType PType = Param->getOriginalType();
12744 if (!Param->isInvalidDecl()) {
12746 if (!ClassDecl->isInvalidDecl() &&
12747 !ClassDecl->hasIrrelevantDestructor() &&
12748 !ClassDecl->isDependentContext() &&
12749 ClassDecl->isParamDestroyedInCallee()) {
12761 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
12762 if (!Param->getType().isConstQualified())
12763 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
12767 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
12772 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
12773 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
12778 if (!Param->isInvalidDecl() &&
12780 Param->setInvalidDecl();
12781 HasInvalidParm =
true;
12782 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
12786 return HasInvalidParm;
12789std::optional<std::pair<
12798static std::pair<CharUnits, CharUnits>
12806 if (
Base->isVirtual()) {
12813 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
12820 DerivedType =
Base->getType();
12823 return std::make_pair(BaseAlignment, Offset);
12827static std::optional<std::pair<CharUnits, CharUnits>>
12833 return std::nullopt;
12838 return std::nullopt;
12842 CharUnits Offset = EltSize * IdxRes->getExtValue();
12845 return std::make_pair(
P->first,
P->second + Offset);
12851 return std::make_pair(
12852 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
12858std::optional<std::pair<
12866 case Stmt::CStyleCastExprClass:
12867 case Stmt::CXXStaticCastExprClass:
12868 case Stmt::ImplicitCastExprClass: {
12869 auto *CE = cast<CastExpr>(
E);
12870 const Expr *From = CE->getSubExpr();
12871 switch (CE->getCastKind()) {
12876 case CK_UncheckedDerivedToBase:
12877 case CK_DerivedToBase: {
12887 case Stmt::ArraySubscriptExprClass: {
12888 auto *ASE = cast<ArraySubscriptExpr>(
E);
12892 case Stmt::DeclRefExprClass: {
12893 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
12896 if (!VD->getType()->isReferenceType()) {
12898 if (VD->hasDependentAlignment())
12907 case Stmt::MemberExprClass: {
12908 auto *ME = cast<MemberExpr>(
E);
12909 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
12913 std::optional<std::pair<CharUnits, CharUnits>>
P;
12922 return std::make_pair(
P->first,
12925 case Stmt::UnaryOperatorClass: {
12926 auto *UO = cast<UnaryOperator>(
E);
12935 case Stmt::BinaryOperatorClass: {
12936 auto *BO = cast<BinaryOperator>(
E);
12947 return std::nullopt;
12952std::optional<std::pair<
12961 case Stmt::CStyleCastExprClass:
12962 case Stmt::CXXStaticCastExprClass:
12963 case Stmt::ImplicitCastExprClass: {
12964 auto *CE = cast<CastExpr>(
E);
12965 const Expr *From = CE->getSubExpr();
12966 switch (CE->getCastKind()) {
12971 case CK_ArrayToPointerDecay:
12973 case CK_UncheckedDerivedToBase:
12974 case CK_DerivedToBase: {
12984 case Stmt::CXXThisExprClass: {
12989 case Stmt::UnaryOperatorClass: {
12990 auto *UO = cast<UnaryOperator>(
E);
12995 case Stmt::BinaryOperatorClass: {
12996 auto *BO = cast<BinaryOperator>(
E);
13004 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
13005 std::swap(LHS, RHS);
13015 return std::nullopt;
13020 std::optional<std::pair<CharUnits, CharUnits>>
P =
13024 return P->first.alignmentAtOffset(
P->second);
13042 if (!DestPtr)
return;
13048 if (DestAlign.
isOne())
return;
13052 if (!SrcPtr)
return;
13063 if (SrcAlign >= DestAlign)
return;
13068 <<
static_cast<unsigned>(DestAlign.
getQuantity())
13072void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
13074 bool AllowOnePastEnd,
bool IndexNegated) {
13083 const Type *EffectiveType =
13090 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
13092 const Type *BaseType =
13094 bool IsUnboundedArray =
13096 Context, StrictFlexArraysLevel,
13106 llvm::APSInt index =
Result.Val.getInt();
13107 if (IndexNegated) {
13108 index.setIsUnsigned(
false);
13112 if (IsUnboundedArray) {
13115 if (index.isUnsigned() || !index.isNegative()) {
13117 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
13119 if (index.getBitWidth() < AddrBits)
13120 index = index.zext(AddrBits);
13121 std::optional<CharUnits> ElemCharUnits =
13122 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
13125 if (!ElemCharUnits || ElemCharUnits->isZero())
13127 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
13132 if (index.getActiveBits() <= AddrBits) {
13134 llvm::APInt Product(index);
13136 Product = Product.umul_ov(ElemBytes, Overflow);
13137 if (!Overflow && Product.getActiveBits() <= AddrBits)
13143 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
13144 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
13146 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
13147 MaxElems = MaxElems.udiv(ElemBytes);
13150 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
13151 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
13157 <<
toString(index, 10,
true) << AddrBits
13158 << (
unsigned)ASTC.toBits(*ElemCharUnits)
13161 << (
unsigned)MaxElems.getLimitedValue(~0
U)
13166 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13168 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13170 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13171 ND = ME->getMemberDecl();
13175 PDiag(diag::note_array_declared_here) << ND);
13180 if (index.isUnsigned() || !index.isNegative()) {
13190 llvm::APInt size = ArrayTy->
getSize();
13192 if (BaseType != EffectiveType) {
13200 if (!ptrarith_typesize)
13203 if (ptrarith_typesize != array_typesize) {
13205 uint64_t ratio = array_typesize / ptrarith_typesize;
13209 if (ptrarith_typesize * ratio == array_typesize)
13210 size *= llvm::APInt(size.getBitWidth(), ratio);
13214 if (size.getBitWidth() > index.getBitWidth())
13215 index = index.zext(size.getBitWidth());
13216 else if (size.getBitWidth() < index.getBitWidth())
13217 size = size.zext(index.getBitWidth());
13223 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
13240 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
13241 : diag::warn_ptr_arith_exceeds_bounds;
13242 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
13250 unsigned DiagID = diag::warn_array_index_precedes_bounds;
13252 DiagID = diag::warn_ptr_arith_precedes_bounds;
13253 if (index.isNegative()) index = -index;
13263 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13265 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13267 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13268 ND = ME->getMemberDecl();
13272 PDiag(diag::note_array_declared_here) << ND);
13275void Sema::CheckArrayAccess(
const Expr *
expr) {
13276 int AllowOnePastEnd = 0;
13278 expr =
expr->IgnoreParenImpCasts();
13279 switch (
expr->getStmtClass()) {
13280 case Stmt::ArraySubscriptExprClass: {
13283 AllowOnePastEnd > 0);
13287 case Stmt::MemberExprClass: {
13288 expr = cast<MemberExpr>(
expr)->getBase();
13291 case Stmt::ArraySectionExprClass: {
13297 nullptr, AllowOnePastEnd > 0);
13300 case Stmt::UnaryOperatorClass: {
13316 case Stmt::ConditionalOperatorClass: {
13319 CheckArrayAccess(lhs);
13321 CheckArrayAccess(rhs);
13324 case Stmt::CXXOperatorCallExprClass: {
13325 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
13326 for (
const auto *Arg : OCE->arguments())
13327 CheckArrayAccess(Arg);
13337 Expr *RHS,
bool isProperty) {
13349 S.
Diag(
Loc, diag::warn_arc_literal_assign)
13351 << (isProperty ? 0 : 1)
13359 Expr *RHS,
bool isProperty) {
13362 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13363 S.
Diag(
Loc, diag::warn_arc_retained_assign)
13365 << (isProperty ? 0 : 1)
13369 RHS =
cast->getSubExpr();
13440 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13441 Diag(
Loc, diag::warn_arc_retained_property_assign)
13445 RHS =
cast->getSubExpr();
13468 bool StmtLineInvalid;
13471 if (StmtLineInvalid)
13474 bool BodyLineInvalid;
13477 if (BodyLineInvalid)
13481 if (StmtLine != BodyLine)
13496 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13505 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13509 const Stmt *PossibleBody) {
13515 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
13516 StmtLoc = FS->getRParenLoc();
13517 Body = FS->getBody();
13518 DiagID = diag::warn_empty_for_body;
13519 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
13520 StmtLoc = WS->getRParenLoc();
13521 Body = WS->getBody();
13522 DiagID = diag::warn_empty_while_body;
13527 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13550 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
13551 if (!ProbableTypo) {
13552 bool BodyColInvalid;
13555 if (BodyColInvalid)
13558 bool StmtColInvalid;
13561 if (StmtColInvalid)
13564 if (BodyCol > StmtCol)
13565 ProbableTypo =
true;
13568 if (ProbableTypo) {
13570 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13578 if (
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
13590 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
13592 RHSExpr = CE->
getArg(0);
13593 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
13594 CXXSCE && CXXSCE->isXValue())
13595 RHSExpr = CXXSCE->getSubExpr();
13599 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
13600 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
13603 if (LHSDeclRef && RHSDeclRef) {
13610 auto D =
Diag(OpLoc, diag::warn_self_move)
13626 const Expr *LHSBase = LHSExpr;
13627 const Expr *RHSBase = RHSExpr;
13628 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
13629 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
13630 if (!LHSME || !RHSME)
13633 while (LHSME && RHSME) {
13640 LHSME = dyn_cast<MemberExpr>(LHSBase);
13641 RHSME = dyn_cast<MemberExpr>(RHSBase);
13644 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
13645 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
13646 if (LHSDeclRef && RHSDeclRef) {
13653 Diag(OpLoc, diag::warn_self_move)
13659 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
13660 Diag(OpLoc, diag::warn_self_move)
13683 bool AreUnionMembers =
false) {
13684 [[maybe_unused]]
const Type *Field1Parent =
13686 [[maybe_unused]]
const Type *Field2Parent =
13691 "Can't evaluate layout compatibility between a struct field and a "
13694 (AreUnionMembers && Field1Parent->
isUnionType())) &&
13695 "AreUnionMembers should be 'true' for union fields (only).");
13708 if (Bits1 != Bits2)
13712 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
13713 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
13716 if (!AreUnionMembers &&
13728 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1)) {
13733 if (D1CXX->getNumBases() != D2CXX->
getNumBases())
13738 Base1 = D1CXX->bases_begin(),
13739 BaseEnd1 = D1CXX->bases_end(),
13742 ++Base1, ++Base2) {
13746 }
else if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2)) {
13748 if (D2CXX->getNumBases() > 0)
13757 for ( ; Field1 != Field1End && Field2 != Field2End; ++Field1, ++Field2) {
13761 if (Field1 != Field1End || Field2 != Field2End)
13772 for (
auto *Field2 : RD2->
fields())
13773 UnmatchedFields.insert(Field2);
13775 for (
auto *Field1 : RD1->
fields()) {
13777 I = UnmatchedFields.begin(),
13778 E = UnmatchedFields.end();
13780 for ( ; I !=
E; ++I) {
13782 bool Result = UnmatchedFields.erase(*I);
13792 return UnmatchedFields.empty();
13818 if (
C.hasSameType(T1, T2))
13827 if (TC1 == Type::Enum) {
13829 cast<EnumType>(T1)->getDecl(),
13830 cast<EnumType>(T2)->getDecl());
13831 }
else if (TC1 == Type::Record) {
13836 cast<RecordType>(T1)->getDecl(),
13837 cast<RecordType>(T2)->getDecl());
13851 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
13882 const ValueDecl **VD, uint64_t *MagicValue,
13883 bool isConstantEvaluated) {
13891 case Stmt::UnaryOperatorClass: {
13900 case Stmt::DeclRefExprClass: {
13901 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
13906 case Stmt::IntegerLiteralClass: {
13908 llvm::APInt MagicValueAPInt = IL->
getValue();
13909 if (MagicValueAPInt.getActiveBits() <= 64) {
13910 *MagicValue = MagicValueAPInt.getZExtValue();
13916 case Stmt::BinaryConditionalOperatorClass:
13917 case Stmt::ConditionalOperatorClass: {
13919 cast<AbstractConditionalOperator>(TypeExpr);
13922 isConstantEvaluated)) {
13932 case Stmt::BinaryOperatorClass: {
13935 TypeExpr = BO->
getRHS();
13965 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
13968 bool isConstantEvaluated) {
13969 FoundWrongKind =
false;
13974 uint64_t MagicValue;
13976 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
13980 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
13981 if (I->getArgumentKind() != ArgumentKind) {
13982 FoundWrongKind =
true;
13985 TypeInfo.Type = I->getMatchingCType();
13986 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
13987 TypeInfo.MustBeNull = I->getMustBeNull();
13998 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
13999 if (I == MagicValues->end())
14008 bool LayoutCompatible,
14010 if (!TypeTagForDatatypeMagicValues)
14011 TypeTagForDatatypeMagicValues.reset(
14012 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
14015 (*TypeTagForDatatypeMagicValues)[Magic] =
14031 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
14032 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
14033 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
14034 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
14037void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
14041 bool IsPointerAttr =
Attr->getIsPointer();
14044 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
14045 if (TypeTagIdxAST >= ExprArgs.size()) {
14046 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14047 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
14050 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
14051 bool FoundWrongKind;
14054 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
14056 if (FoundWrongKind)
14058 diag::warn_type_tag_for_datatype_wrong_kind)
14064 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
14065 if (ArgumentIdxAST >= ExprArgs.size()) {
14066 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14067 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
14070 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
14071 if (IsPointerAttr) {
14073 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
14074 if (ICE->getType()->isVoidPointerType() &&
14075 ICE->getCastKind() == CK_BitCast)
14076 ArgumentExpr = ICE->getSubExpr();
14089 diag::warn_type_safety_null_pointer_required)
14101 bool mismatch =
false;
14124 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
14125 << ArgumentType << ArgumentKind
14126 <<
TypeInfo.LayoutCompatible << RequiredType
14133 MisalignedMembers.emplace_back(
E, RD, MD, Alignment);
14137 for (MisalignedMember &m : MisalignedMembers) {
14143 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
14146 MisalignedMembers.clear();
14153 if (isa<UnaryOperator>(
E) &&
14154 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
14155 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
14156 if (isa<MemberExpr>(Op)) {
14157 auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
14158 if (MA != MisalignedMembers.end() &&
14163 MisalignedMembers.erase(MA);
14172 const auto *ME = dyn_cast<MemberExpr>(
E);
14184 bool AnyIsPacked =
false;
14186 QualType BaseType = ME->getBase()->getType();
14196 auto *FD = dyn_cast<FieldDecl>(MD);
14202 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
14203 ReverseMemberChain.push_back(FD);
14206 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
14208 assert(TopME &&
"We did not compute a topmost MemberExpr!");
14215 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
14219 if (!DRE && !isa<CXXThisExpr>(TopBase))
14226 if (ExpectedAlignment.
isOne())
14231 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
14236 ReverseMemberChain.back()->getParent()->getTypeForDecl());
14240 if (DRE && !TopME->
isArrow()) {
14243 CompleteObjectAlignment =
14248 if (Offset % ExpectedAlignment != 0 ||
14251 CompleteObjectAlignment < ExpectedAlignment) {
14262 for (
FieldDecl *FDI : ReverseMemberChain) {
14263 if (FDI->hasAttr<PackedAttr>() ||
14264 FDI->getParent()->hasAttr<PackedAttr>()) {
14266 Alignment = std::min(
14272 assert(FD &&
"We did not find a packed FieldDecl!");
14277void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
14278 using namespace std::placeholders;
14281 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
14303bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall) {
14317 TheCall->
setType(VecTy0->getElementType());
14341 diag::err_typecheck_call_different_arg_types)
14353 bool CheckForFloatArgs) {
14358 for (
int I = 0; I < 3; ++I) {
14362 Args[I] = Converted.
get();
14365 if (CheckForFloatArgs) {
14366 int ArgOrdinal = 1;
14367 for (
Expr *Arg : Args) {
14369 Arg->
getType(), ArgOrdinal++))
14373 int ArgOrdinal = 1;
14374 for (
Expr *Arg : Args) {
14381 for (
int I = 1; I < 3; ++I) {
14382 if (Args[0]->getType().getCanonicalType() !=
14383 Args[I]->getType().getCanonicalType()) {
14384 return Diag(Args[0]->getBeginLoc(),
14385 diag::err_typecheck_call_different_arg_types)
14389 TheCall->
setArg(I, Args[I]);
14392 TheCall->
setType(Args[0]->getType());
14396bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
14408bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
14417 << 1 << 0 << TyArg;
14431 Expr *Matrix = MatrixArg.
get();
14436 << 1 << 1 << Matrix->
getType();
14443 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
14446 TheCall->
setType(ResultType);
14449 TheCall->
setArg(0, Matrix);
14454static std::optional<unsigned>
14457 std::optional<llvm::APSInt>
Value =
14464 uint64_t Dim =
Value->getZExtValue();
14483 unsigned PtrArgIdx = 0;
14489 bool ArgError =
false;
14496 PtrExpr = PtrConv.
get();
14497 TheCall->
setArg(0, PtrExpr);
14508 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14515 << PtrArgIdx + 1 << 2
14522 auto ApplyArgumentConversions = [
this](
Expr *
E) {
14531 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
14533 RowsExpr = RowsConv.
get();
14534 TheCall->
setArg(1, RowsExpr);
14536 RowsExpr =
nullptr;
14538 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
14540 ColumnsExpr = ColumnsConv.
get();
14541 TheCall->
setArg(2, ColumnsExpr);
14543 ColumnsExpr =
nullptr;
14554 std::optional<unsigned> MaybeRows;
14558 std::optional<unsigned> MaybeColumns;
14563 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
14566 StrideExpr = StrideConv.
get();
14567 TheCall->
setArg(3, StrideExpr);
14570 if (std::optional<llvm::APSInt>
Value =
14573 if (Stride < *MaybeRows) {
14575 diag::err_builtin_matrix_stride_too_small);
14581 if (ArgError || !MaybeRows || !MaybeColumns)
14594 unsigned PtrArgIdx = 1;
14599 bool ArgError =
false;
14605 MatrixExpr = MatrixConv.
get();
14606 TheCall->
setArg(0, MatrixExpr);
14616 << 1 << 1 << MatrixExpr->
getType();
14624 PtrExpr = PtrConv.
get();
14625 TheCall->
setArg(1, PtrExpr);
14636 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14641 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
14648 diag::err_builtin_matrix_pointer_arg_mismatch)
14649 << ElementTy << MatrixTy->getElementType();
14664 StrideExpr = StrideConv.
get();
14665 TheCall->
setArg(2, StrideExpr);
14670 if (std::optional<llvm::APSInt>
Value =
14673 if (Stride < MatrixTy->getNumRows()) {
14675 diag::err_builtin_matrix_stride_too_small);
14695 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
14700 llvm::StringSet<> CalleeTCBs;
14701 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
14702 CalleeTCBs.insert(A->getTCBName());
14703 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
14704 CalleeTCBs.insert(A->getTCBName());
14708 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
14709 StringRef CallerTCB = A->getTCBName();
14710 if (CalleeTCBs.count(CallerTCB) == 0) {
14711 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
14712 << 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 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 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 isLayoutCompatibleStruct(ASTContext &C, RecordDecl *RD1, RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
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 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 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 bool isLayoutCompatible(ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
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 checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool CheckBuiltinTargetInSupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
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 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 bool isLayoutCompatibleUnion(ASTContext &C, RecordDecl *RD1, RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
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
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
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)
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
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 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_iterator field_end() const
field_range fields() const
field_iterator field_begin() 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.