81#include "llvm/ADT/APFloat.h"
82#include "llvm/ADT/APInt.h"
83#include "llvm/ADT/APSInt.h"
84#include "llvm/ADT/ArrayRef.h"
85#include "llvm/ADT/DenseMap.h"
86#include "llvm/ADT/FoldingSet.h"
87#include "llvm/ADT/STLExtras.h"
88#include "llvm/ADT/STLForwardCompat.h"
89#include "llvm/ADT/SmallBitVector.h"
90#include "llvm/ADT/SmallPtrSet.h"
91#include "llvm/ADT/SmallString.h"
92#include "llvm/ADT/SmallVector.h"
93#include "llvm/ADT/StringExtras.h"
94#include "llvm/ADT/StringRef.h"
95#include "llvm/ADT/StringSet.h"
96#include "llvm/ADT/StringSwitch.h"
97#include "llvm/Support/AtomicOrdering.h"
98#include "llvm/Support/Compiler.h"
99#include "llvm/Support/ConvertUTF.h"
100#include "llvm/Support/ErrorHandling.h"
101#include "llvm/Support/Format.h"
102#include "llvm/Support/Locale.h"
103#include "llvm/Support/MathExtras.h"
104#include "llvm/Support/SaveAndRestore.h"
105#include "llvm/Support/raw_ostream.h"
106#include "llvm/TargetParser/RISCVTargetParser.h"
107#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
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();
297 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
328 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
330 auto IsValidIntegerType = [](
QualType Ty) {
331 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
338 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
342 S.
Diag(Source->
getExprLoc(), diag::err_typecheck_expect_scalar_operand)
348 if (!IsValidIntegerType(AlignOp->
getType())) {
359 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
360 llvm::APSInt MaxValue(
361 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
362 if (AlignValue < 1) {
363 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
366 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
371 if (!AlignValue.isPowerOf2()) {
372 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
375 if (AlignValue == 1) {
376 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
377 << IsBooleanAlignBuiltin;
405 std::pair<unsigned, const char *> Builtins[] = {
406 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
407 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
408 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
411 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
413 return BuiltinID ==
P.first && TheCall->
getExprLoc().isMacroID() &&
418 auto ValidCkdIntType = [](
QualType QT) {
421 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
422 return (BT->getKind() >= BuiltinType::Short &&
423 BT->getKind() <= BuiltinType::Int128) || (
424 BT->getKind() >= BuiltinType::UShort &&
425 BT->getKind() <= BuiltinType::UInt128) ||
426 BT->getKind() == BuiltinType::UChar ||
427 BT->getKind() == BuiltinType::SChar;
432 for (
unsigned I = 0; I < 2; ++I) {
438 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
457 !PtrTy->getPointeeType()->isIntegerType() ||
458 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
459 PtrTy->getPointeeType().isConstQualified()) {
461 diag::err_overflow_builtin_must_be_ptr_int)
469 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
470 for (
unsigned I = 0; I < 3; ++I) {
471 const auto Arg = TheCall->
getArg(I);
474 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
476 return S.
Diag(Arg->getBeginLoc(),
477 diag::err_overflow_builtin_bit_int_max_size)
486struct BuiltinDumpStructGenerator {
495 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
496 Policy(S.Context.getPrintingPolicy()) {
500 Expr *makeOpaqueValueExpr(
Expr *Inner) {
503 Inner->getObjectKind(), Inner);
504 Actions.push_back(OVE);
508 Expr *getStringLiteral(llvm::StringRef Str) {
514 bool callPrintFunction(llvm::StringRef Format,
518 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
520 Args.push_back(getStringLiteral(Format));
521 llvm::append_range(Args, Exprs);
526 Ctx.PointOfInstantiation =
Loc;
527 Ctx.CallArgs = Args.data();
528 Ctx.NumCallArgs = Args.size();
537 Actions.push_back(RealCall.
get());
543 Expr *getIndentString(
unsigned Depth) {
549 return getStringLiteral(Indent);
553 return getStringLiteral(
T.getAsString(Policy));
557 llvm::raw_svector_ostream OS(Str);
562 switch (BT->getKind()) {
563 case BuiltinType::Bool:
566 case BuiltinType::Char_U:
567 case BuiltinType::UChar:
570 case BuiltinType::Char_S:
571 case BuiltinType::SChar:
583 analyze_printf::PrintfConversionSpecifier::sArg) {
609 bool dumpUnnamedRecord(
const RecordDecl *RD,
Expr *
E,
unsigned Depth) {
610 Expr *IndentLit = getIndentString(Depth);
612 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
613 : callPrintFunction(
"%s", {TypeLit}))
616 return dumpRecordValue(RD,
E, IndentLit, Depth);
629 Expr *RecordArg = makeOpaqueValueExpr(
E);
632 if (callPrintFunction(
" {\n"))
636 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
637 for (
const auto &
Base : CXXRD->bases()) {
645 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
651 Expr *FieldIndentArg = getIndentString(Depth + 1);
654 for (
auto *
D : RD->
decls()) {
655 auto *IFD = dyn_cast<IndirectFieldDecl>(
D);
656 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(
D);
657 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
663 getStringLiteral(FD->getName())};
665 if (FD->isBitField()) {
669 FD->getBitWidthValue());
683 if (
Field.isInvalid())
686 auto *InnerRD = FD->getType()->getAsRecordDecl();
687 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
688 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
690 if (callPrintFunction(Format, Args) ||
691 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
695 if (appendFormatSpecifier(FD->getType(), Format)) {
697 Args.push_back(
Field.get());
707 Args.push_back(FieldAddr.
get());
710 if (callPrintFunction(Format, Args))
715 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
716 : callPrintFunction(
"}\n");
719 Expr *buildWrapper() {
722 TheCall->
setType(Wrapper->getType());
743 diag::err_expected_struct_pointer_argument)
752 diag::err_incomplete_type))
761 switch (BT ? BT->getKind() : BuiltinType::Void) {
762 case BuiltinType::Dependent:
763 case BuiltinType::Overload:
764 case BuiltinType::BoundMember:
765 case BuiltinType::PseudoObject:
766 case BuiltinType::UnknownAny:
767 case BuiltinType::BuiltinFn:
773 diag::err_expected_callable_argument)
779 BuiltinDumpStructGenerator Generator(S, TheCall);
785 Expr *PtrArg = PtrArgResult.
get();
789 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
792 return Generator.buildWrapper();
804 if (
Call->getStmtClass() != Stmt::CallExprClass) {
805 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
806 <<
Call->getSourceRange();
810 auto CE = cast<CallExpr>(
Call);
811 if (CE->getCallee()->getType()->isBlockPointerType()) {
812 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
813 <<
Call->getSourceRange();
817 const Decl *TargetDecl = CE->getCalleeDecl();
818 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
819 if (FD->getBuiltinID()) {
820 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
821 <<
Call->getSourceRange();
825 if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {
826 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
827 <<
Call->getSourceRange();
835 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
849 BuiltinCall->
setType(CE->getType());
853 BuiltinCall->
setArg(1, ChainResult.
get());
860class ScanfDiagnosticFormatHandler
864 using ComputeSizeFunction =
865 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
869 using DiagnoseFunction =
870 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
872 ComputeSizeFunction ComputeSizeArgument;
873 DiagnoseFunction Diagnose;
876 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
877 DiagnoseFunction Diagnose)
878 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
881 const char *StartSpecifier,
882 unsigned specifierLen)
override {
883 if (!FS.consumesDataArgument())
886 unsigned NulByte = 0;
887 switch ((FS.getConversionSpecifier().getKind())) {
900 analyze_format_string::OptionalAmount::HowSpecified::Constant)
905 std::optional<llvm::APSInt> DestSizeAPS =
906 ComputeSizeArgument(FS.getArgIndex());
910 unsigned DestSize = DestSizeAPS->getZExtValue();
912 if (DestSize < SourceSize)
913 Diagnose(FS.getArgIndex(), DestSize, SourceSize);
919class EstimateSizeFormatHandler
924 bool IsKernelCompatible =
true;
927 EstimateSizeFormatHandler(StringRef Format)
928 :
Size(
std::
min(Format.find(0), Format.size()) +
932 const char *,
unsigned SpecifierLen,
935 const size_t FieldWidth = computeFieldWidth(FS);
936 const size_t Precision = computePrecision(FS);
939 switch (FS.getConversionSpecifier().getKind()) {
943 Size += std::max(FieldWidth, (
size_t)1);
955 Size += std::max(FieldWidth, Precision);
971 Size += std::max(FieldWidth, 1 +
972 (Precision ? 1 + Precision
982 (Precision ? 1 + Precision : 0) +
992 (Precision ? 1 + Precision : 0) +
1007 IsKernelCompatible =
false;
1008 Size += std::max(FieldWidth, 2 + Precision);
1022 if ((FS.hasPlusPrefix() || FS.hasSpacePrefix()) && FieldWidth == 0)
1025 if (FS.hasAlternativeForm()) {
1026 switch (FS.getConversionSpecifier().getKind()) {
1055 Size += (Precision ? 0 : 1);
1062 assert(SpecifierLen <= Size &&
"no underflow");
1063 Size -= SpecifierLen;
1067 size_t getSizeLowerBound()
const {
return Size; }
1068 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1073 size_t FieldWidth = 0;
1081 size_t Precision = 0;
1086 switch (FS.getConversionSpecifier().getKind()) {
1128 StringRef &FormatStrRef,
size_t &StrLen,
1130 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1131 Format && (Format->isOrdinary() || Format->isUTF8())) {
1132 FormatStrRef = Format->getString();
1135 assert(
T &&
"String literal not of constant array type!");
1136 size_t TypeSize =
T->getZExtSize();
1138 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1144void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1150 bool UseDABAttr =
false;
1153 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1155 UseDecl = DABAttr->getFunction();
1156 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1168 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1175 unsigned DABIndices = DABAttr->argIndices_size();
1176 unsigned NewIndex = Index < DABIndices
1177 ? DABAttr->argIndices_begin()[Index]
1180 return std::nullopt;
1184 auto ComputeExplicitObjectSizeArgument =
1185 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1186 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1188 return std::nullopt;
1189 unsigned NewIndex = *IndexOptional;
1193 return std::nullopt;
1199 auto ComputeSizeArgument =
1200 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1206 if (Index < FD->getNumParams()) {
1207 if (
const auto *POS =
1209 BOSType = POS->getType();
1212 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1214 return std::nullopt;
1215 unsigned NewIndex = *IndexOptional;
1218 return std::nullopt;
1220 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1223 return std::nullopt;
1226 return llvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1229 auto ComputeStrLenArgument =
1230 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1231 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1233 return std::nullopt;
1234 unsigned NewIndex = *IndexOptional;
1236 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1239 return std::nullopt;
1241 return llvm::APSInt::getUnsigned(
Result + 1).extOrTrunc(SizeTypeWidth);
1244 std::optional<llvm::APSInt> SourceSize;
1245 std::optional<llvm::APSInt> DestinationSize;
1246 unsigned DiagID = 0;
1247 bool IsChkVariant =
false;
1249 auto GetFunctionName = [&]() {
1250 std::string FunctionNameStr =
1252 llvm::StringRef FunctionName = FunctionNameStr;
1257 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1258 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1260 FunctionName.consume_front(
"__builtin_");
1262 return FunctionName.str();
1265 switch (BuiltinID) {
1268 case Builtin::BI__builtin_stpcpy:
1269 case Builtin::BIstpcpy:
1270 case Builtin::BI__builtin_strcpy:
1271 case Builtin::BIstrcpy: {
1272 DiagID = diag::warn_fortify_strlen_overflow;
1273 SourceSize = ComputeStrLenArgument(1);
1274 DestinationSize = ComputeSizeArgument(0);
1278 case Builtin::BI__builtin___stpcpy_chk:
1279 case Builtin::BI__builtin___strcpy_chk: {
1280 DiagID = diag::warn_fortify_strlen_overflow;
1281 SourceSize = ComputeStrLenArgument(1);
1282 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1283 IsChkVariant =
true;
1287 case Builtin::BIscanf:
1288 case Builtin::BIfscanf:
1289 case Builtin::BIsscanf: {
1290 unsigned FormatIndex = 1;
1291 unsigned DataIndex = 2;
1292 if (BuiltinID == Builtin::BIscanf) {
1297 const auto *FormatExpr =
1300 StringRef FormatStrRef;
1305 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1306 unsigned SourceSize) {
1307 DiagID = diag::warn_fortify_scanf_overflow;
1308 unsigned Index = ArgIndex + DataIndex;
1309 std::string FunctionName = GetFunctionName();
1311 PDiag(DiagID) << FunctionName << (Index + 1)
1312 << DestSize << SourceSize);
1315 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1316 return ComputeSizeArgument(Index + DataIndex);
1318 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1319 const char *FormatBytes = FormatStrRef.data();
1330 case Builtin::BIsprintf:
1331 case Builtin::BI__builtin___sprintf_chk: {
1332 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1335 StringRef FormatStrRef;
1338 EstimateSizeFormatHandler H(FormatStrRef);
1339 const char *FormatBytes = FormatStrRef.data();
1341 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1343 DiagID = H.isKernelCompatible()
1344 ? diag::warn_format_overflow
1345 : diag::warn_format_overflow_non_kprintf;
1346 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1347 .extOrTrunc(SizeTypeWidth);
1348 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1349 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1350 IsChkVariant =
true;
1352 DestinationSize = ComputeSizeArgument(0);
1359 case Builtin::BI__builtin___memcpy_chk:
1360 case Builtin::BI__builtin___memmove_chk:
1361 case Builtin::BI__builtin___memset_chk:
1362 case Builtin::BI__builtin___strlcat_chk:
1363 case Builtin::BI__builtin___strlcpy_chk:
1364 case Builtin::BI__builtin___strncat_chk:
1365 case Builtin::BI__builtin___strncpy_chk:
1366 case Builtin::BI__builtin___stpncpy_chk:
1367 case Builtin::BI__builtin___memccpy_chk:
1368 case Builtin::BI__builtin___mempcpy_chk: {
1369 DiagID = diag::warn_builtin_chk_overflow;
1370 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1372 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1373 IsChkVariant =
true;
1377 case Builtin::BI__builtin___snprintf_chk:
1378 case Builtin::BI__builtin___vsnprintf_chk: {
1379 DiagID = diag::warn_builtin_chk_overflow;
1380 SourceSize = ComputeExplicitObjectSizeArgument(1);
1381 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1382 IsChkVariant =
true;
1386 case Builtin::BIstrncat:
1387 case Builtin::BI__builtin_strncat:
1388 case Builtin::BIstrncpy:
1389 case Builtin::BI__builtin_strncpy:
1390 case Builtin::BIstpncpy:
1391 case Builtin::BI__builtin_stpncpy: {
1397 DiagID = diag::warn_fortify_source_size_mismatch;
1398 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1399 DestinationSize = ComputeSizeArgument(0);
1403 case Builtin::BImemcpy:
1404 case Builtin::BI__builtin_memcpy:
1405 case Builtin::BImemmove:
1406 case Builtin::BI__builtin_memmove:
1407 case Builtin::BImemset:
1408 case Builtin::BI__builtin_memset:
1409 case Builtin::BImempcpy:
1410 case Builtin::BI__builtin_mempcpy: {
1411 DiagID = diag::warn_fortify_source_overflow;
1412 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1413 DestinationSize = ComputeSizeArgument(0);
1416 case Builtin::BIsnprintf:
1417 case Builtin::BI__builtin_snprintf:
1418 case Builtin::BIvsnprintf:
1419 case Builtin::BI__builtin_vsnprintf: {
1420 DiagID = diag::warn_fortify_source_size_mismatch;
1421 SourceSize = ComputeExplicitObjectSizeArgument(1);
1423 StringRef FormatStrRef;
1427 EstimateSizeFormatHandler H(FormatStrRef);
1428 const char *FormatBytes = FormatStrRef.data();
1430 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1432 llvm::APSInt FormatSize =
1433 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1434 .extOrTrunc(SizeTypeWidth);
1435 if (FormatSize > *SourceSize && *SourceSize != 0) {
1436 unsigned TruncationDiagID =
1437 H.isKernelCompatible() ? diag::warn_format_truncation
1438 : diag::warn_format_truncation_non_kprintf;
1441 SourceSize->toString(SpecifiedSizeStr, 10);
1442 FormatSize.toString(FormatSizeStr, 10);
1444 PDiag(TruncationDiagID)
1445 << GetFunctionName() << SpecifiedSizeStr
1450 DestinationSize = ComputeSizeArgument(0);
1454 if (!SourceSize || !DestinationSize ||
1455 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1458 std::string FunctionName = GetFunctionName();
1462 DestinationSize->toString(DestinationStr, 10);
1463 SourceSize->toString(SourceStr, 10);
1466 << FunctionName << DestinationStr << SourceStr);
1479 while (S && !S->isSEHExceptScope())
1481 if (!S || !(S->getFlags() & NeededScopeFlags)) {
1484 << DRE->getDecl()->getIdentifier();
1496 "__builtin_alloca has invalid address space");
1504enum PointerAuthOpKind {
1553 llvm::raw_svector_ostream Str(
Value);
1562 Result = KeyValue->getZExtValue();
1581 bool IsAddrDiscArg =
false;
1586 IsAddrDiscArg =
true;
1593 if (*Result < 0 || *Result >
Max) {
1595 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1596 <<
Result->getExtValue();
1598 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1604 IntVal =
Result->getZExtValue();
1608static std::pair<const ValueDecl *, CharUnits>
1615 const auto *BaseDecl =
1620 return {BaseDecl,
Result.Val.getLValueOffset()};
1624 bool RequireConstant =
false) {
1632 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1633 return OpKind != PAO_BlendInteger;
1635 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1636 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1637 OpKind == PAO_SignGeneric;
1646 }
else if (AllowsInteger(OpKind) &&
1653 <<
unsigned(OpKind == PAO_Discriminator ? 1
1654 : OpKind == PAO_BlendPointer ? 2
1655 : OpKind == PAO_BlendInteger ? 3
1657 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1667 if (!RequireConstant) {
1669 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1672 ? diag::warn_ptrauth_sign_null_pointer
1673 : diag::warn_ptrauth_auth_null_pointer)
1683 if (OpKind == PAO_Sign) {
1693 else if (isa<FunctionDecl>(BaseDecl))
1701 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1706 assert(OpKind == PAO_Discriminator);
1712 if (
Call->getBuiltinCallee() ==
1713 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1728 assert(
Pointer->getType()->isPointerType());
1734 if (!BaseDecl || !isa<VarDecl>(BaseDecl))
1740 assert(
Integer->getType()->isIntegerType());
1746 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1759 Call->setType(
Call->getArgs()[0]->getType());
1790 PointerAuthOpKind OpKind,
1791 bool RequireConstant) {
1802 Call->setType(
Call->getArgs()[0]->getType());
1818 Call->setType(
Call->getArgs()[0]->getType());
1827 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1830 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1831 if (!Literal || Literal->getCharByteWidth() != 1) {
1847 Call->setArg(0, FirstValue.
get());
1853 if (!FirstArgRecord) {
1854 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1855 << 0 << FirstArgType;
1860 diag::err_get_vtable_pointer_requires_complete_type)) {
1865 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1866 << 1 << FirstArgRecord;
1870 Call->setType(ReturnType);
1895 auto DiagSelect = [&]() -> std::optional<unsigned> {
1902 return std::optional<unsigned>{};
1917 diag::err_incomplete_type))
1921 "Unhandled non-object pointer case");
1949 if (PT->getPointeeType()->isFunctionType()) {
1951 diag::err_builtin_is_within_lifetime_invalid_arg)
1957 if (PT->getPointeeType()->isVariableArrayType()) {
1959 << 1 <<
"__builtin_is_within_lifetime";
1964 diag::err_builtin_is_within_lifetime_invalid_arg)
1978 diag::err_builtin_trivially_relocate_invalid_arg_type)
1985 diag::err_incomplete_type))
1991 diag::err_builtin_trivially_relocate_invalid_arg_type)
1992 << (
T.isConstQualified() ? 1 : 2);
2001 diag::err_builtin_trivially_relocate_invalid_arg_type)
2008 if (Size.isInvalid())
2012 if (Size.isInvalid())
2014 SizeExpr = Size.get();
2015 TheCall->
setArg(2, SizeExpr);
2025 llvm::Triple::ObjectFormatType CurObjFormat =
2027 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2040 llvm::Triple::ArchType CurArch =
2042 if (llvm::is_contained(SupportedArchs, CurArch))
2052bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2059 case llvm::Triple::arm:
2060 case llvm::Triple::armeb:
2061 case llvm::Triple::thumb:
2062 case llvm::Triple::thumbeb:
2064 case llvm::Triple::aarch64:
2065 case llvm::Triple::aarch64_32:
2066 case llvm::Triple::aarch64_be:
2068 case llvm::Triple::bpfeb:
2069 case llvm::Triple::bpfel:
2071 case llvm::Triple::dxil:
2073 case llvm::Triple::hexagon:
2075 case llvm::Triple::mips:
2076 case llvm::Triple::mipsel:
2077 case llvm::Triple::mips64:
2078 case llvm::Triple::mips64el:
2080 case llvm::Triple::spirv:
2081 case llvm::Triple::spirv32:
2082 case llvm::Triple::spirv64:
2083 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2086 case llvm::Triple::systemz:
2088 case llvm::Triple::x86:
2089 case llvm::Triple::x86_64:
2091 case llvm::Triple::ppc:
2092 case llvm::Triple::ppcle:
2093 case llvm::Triple::ppc64:
2094 case llvm::Triple::ppc64le:
2096 case llvm::Triple::amdgcn:
2098 case llvm::Triple::riscv32:
2099 case llvm::Triple::riscv64:
2101 case llvm::Triple::loongarch32:
2102 case llvm::Triple::loongarch64:
2105 case llvm::Triple::wasm32:
2106 case llvm::Triple::wasm64:
2108 case llvm::Triple::nvptx:
2109 case llvm::Triple::nvptx64:
2123 EltTy = VecTy->getElementType();
2125 switch (ArgTyRestr) {
2129 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2130 << ArgOrdinal << 2 << 1 << 1
2136 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2137 << ArgOrdinal << 5 << 0
2143 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2144 << ArgOrdinal << 5 << 1
2150 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
2164 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2165 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2166 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2167 "Expecting __builtin_cpu_...");
2169 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2171 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2172 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2173 (!IsCPUSupports && TInfo->supportsCpuIs()));
2175 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2182 ? diag::err_builtin_aix_os_unsupported
2183 : diag::err_builtin_target_unsupported)
2188 if (!isa<StringLiteral>(Arg))
2189 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2193 StringRef
Feature = cast<StringLiteral>(Arg)->getString();
2241 TheCall->
setArg(0, Arg0);
2258 TheCall->
setArg(1, Arg1);
2264 << 2 << 1 << 4 << 0 << Arg1Ty;
2276 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2282 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2283 << Pos <<
"pointer to vector";
2306 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2315 << MaskTy << PointeeTy);
2337 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2351 << MaskTy << PointeeTy);
2355 diag::err_vec_builtin_incompatible_vector)
2369 if (Args.size() == 0) {
2371 diag::err_typecheck_call_too_few_args_at_least)
2377 QualType FuncT = Args[0]->getType();
2380 if (Args.size() < 2) {
2382 diag::err_typecheck_call_too_few_args_at_least)
2388 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2389 QualType ObjectT = Args[1]->getType();
2391 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2440 tok::periodstar, ObjectArg.
get(), Args[0]);
2444 if (MPT->isMemberDataPointer())
2447 auto *MemCall =
new (S.
Context)
2458Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2463 unsigned ICEArguments = 0;
2470 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2472 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2477 if (ArgNo < TheCall->getNumArgs() &&
2480 ICEArguments &= ~(1 << ArgNo);
2484 switch (BuiltinID) {
2485 case Builtin::BI__builtin_cpu_supports:
2486 case Builtin::BI__builtin_cpu_is:
2491 case Builtin::BI__builtin_cpu_init:
2498 case Builtin::BI__builtin___CFStringMakeConstantString:
2502 *
this, BuiltinID, TheCall,
2503 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2506 "Wrong # arguments to builtin CFStringMakeConstantString");
2507 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2510 case Builtin::BI__builtin_ms_va_start:
2511 case Builtin::BI__builtin_stdarg_start:
2512 case Builtin::BI__builtin_va_start:
2513 case Builtin::BI__builtin_c23_va_start:
2514 if (BuiltinVAStart(BuiltinID, TheCall))
2517 case Builtin::BI__va_start: {
2519 case llvm::Triple::aarch64:
2520 case llvm::Triple::arm:
2521 case llvm::Triple::thumb:
2522 if (BuiltinVAStartARMMicrosoft(TheCall))
2526 if (BuiltinVAStart(BuiltinID, TheCall))
2534 case Builtin::BI_interlockedbittestandset_acq:
2535 case Builtin::BI_interlockedbittestandset_rel:
2536 case Builtin::BI_interlockedbittestandset_nf:
2537 case Builtin::BI_interlockedbittestandreset_acq:
2538 case Builtin::BI_interlockedbittestandreset_rel:
2539 case Builtin::BI_interlockedbittestandreset_nf:
2542 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2547 case Builtin::BI_bittest64:
2548 case Builtin::BI_bittestandcomplement64:
2549 case Builtin::BI_bittestandreset64:
2550 case Builtin::BI_bittestandset64:
2551 case Builtin::BI_interlockedbittestandreset64:
2552 case Builtin::BI_interlockedbittestandset64:
2555 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2556 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2561 case Builtin::BI_interlockedbittestandreset64_acq:
2562 case Builtin::BI_interlockedbittestandreset64_rel:
2563 case Builtin::BI_interlockedbittestandreset64_nf:
2564 case Builtin::BI_interlockedbittestandset64_acq:
2565 case Builtin::BI_interlockedbittestandset64_rel:
2566 case Builtin::BI_interlockedbittestandset64_nf:
2571 case Builtin::BI__builtin_set_flt_rounds:
2574 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2575 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2576 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2577 llvm::Triple::ppc64le}))
2581 case Builtin::BI__builtin_isgreater:
2582 case Builtin::BI__builtin_isgreaterequal:
2583 case Builtin::BI__builtin_isless:
2584 case Builtin::BI__builtin_islessequal:
2585 case Builtin::BI__builtin_islessgreater:
2586 case Builtin::BI__builtin_isunordered:
2587 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2590 case Builtin::BI__builtin_fpclassify:
2591 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2594 case Builtin::BI__builtin_isfpclass:
2595 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2598 case Builtin::BI__builtin_isfinite:
2599 case Builtin::BI__builtin_isinf:
2600 case Builtin::BI__builtin_isinf_sign:
2601 case Builtin::BI__builtin_isnan:
2602 case Builtin::BI__builtin_issignaling:
2603 case Builtin::BI__builtin_isnormal:
2604 case Builtin::BI__builtin_issubnormal:
2605 case Builtin::BI__builtin_iszero:
2606 case Builtin::BI__builtin_signbit:
2607 case Builtin::BI__builtin_signbitf:
2608 case Builtin::BI__builtin_signbitl:
2609 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2612 case Builtin::BI__builtin_shufflevector:
2616 case Builtin::BI__builtin_masked_load:
2617 case Builtin::BI__builtin_masked_expand_load:
2619 case Builtin::BI__builtin_masked_store:
2620 case Builtin::BI__builtin_masked_compress_store:
2622 case Builtin::BI__builtin_invoke:
2624 case Builtin::BI__builtin_prefetch:
2625 if (BuiltinPrefetch(TheCall))
2628 case Builtin::BI__builtin_alloca_with_align:
2629 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2630 if (BuiltinAllocaWithAlign(TheCall))
2633 case Builtin::BI__builtin_alloca:
2634 case Builtin::BI__builtin_alloca_uninitialized:
2641 case Builtin::BI__arithmetic_fence:
2642 if (BuiltinArithmeticFence(TheCall))
2645 case Builtin::BI__assume:
2646 case Builtin::BI__builtin_assume:
2647 if (BuiltinAssume(TheCall))
2650 case Builtin::BI__builtin_assume_aligned:
2651 if (BuiltinAssumeAligned(TheCall))
2654 case Builtin::BI__builtin_dynamic_object_size:
2655 case Builtin::BI__builtin_object_size:
2659 case Builtin::BI__builtin_longjmp:
2660 if (BuiltinLongjmp(TheCall))
2663 case Builtin::BI__builtin_setjmp:
2664 if (BuiltinSetjmp(TheCall))
2667 case Builtin::BI__builtin_classify_type:
2672 case Builtin::BI__builtin_complex:
2673 if (BuiltinComplex(TheCall))
2676 case Builtin::BI__builtin_constant_p: {
2685 case Builtin::BI__builtin_launder:
2687 case Builtin::BI__builtin_is_within_lifetime:
2689 case Builtin::BI__builtin_trivially_relocate:
2692 case Builtin::BI__sync_fetch_and_add:
2693 case Builtin::BI__sync_fetch_and_add_1:
2694 case Builtin::BI__sync_fetch_and_add_2:
2695 case Builtin::BI__sync_fetch_and_add_4:
2696 case Builtin::BI__sync_fetch_and_add_8:
2697 case Builtin::BI__sync_fetch_and_add_16:
2698 case Builtin::BI__sync_fetch_and_sub:
2699 case Builtin::BI__sync_fetch_and_sub_1:
2700 case Builtin::BI__sync_fetch_and_sub_2:
2701 case Builtin::BI__sync_fetch_and_sub_4:
2702 case Builtin::BI__sync_fetch_and_sub_8:
2703 case Builtin::BI__sync_fetch_and_sub_16:
2704 case Builtin::BI__sync_fetch_and_or:
2705 case Builtin::BI__sync_fetch_and_or_1:
2706 case Builtin::BI__sync_fetch_and_or_2:
2707 case Builtin::BI__sync_fetch_and_or_4:
2708 case Builtin::BI__sync_fetch_and_or_8:
2709 case Builtin::BI__sync_fetch_and_or_16:
2710 case Builtin::BI__sync_fetch_and_and:
2711 case Builtin::BI__sync_fetch_and_and_1:
2712 case Builtin::BI__sync_fetch_and_and_2:
2713 case Builtin::BI__sync_fetch_and_and_4:
2714 case Builtin::BI__sync_fetch_and_and_8:
2715 case Builtin::BI__sync_fetch_and_and_16:
2716 case Builtin::BI__sync_fetch_and_xor:
2717 case Builtin::BI__sync_fetch_and_xor_1:
2718 case Builtin::BI__sync_fetch_and_xor_2:
2719 case Builtin::BI__sync_fetch_and_xor_4:
2720 case Builtin::BI__sync_fetch_and_xor_8:
2721 case Builtin::BI__sync_fetch_and_xor_16:
2722 case Builtin::BI__sync_fetch_and_nand:
2723 case Builtin::BI__sync_fetch_and_nand_1:
2724 case Builtin::BI__sync_fetch_and_nand_2:
2725 case Builtin::BI__sync_fetch_and_nand_4:
2726 case Builtin::BI__sync_fetch_and_nand_8:
2727 case Builtin::BI__sync_fetch_and_nand_16:
2728 case Builtin::BI__sync_add_and_fetch:
2729 case Builtin::BI__sync_add_and_fetch_1:
2730 case Builtin::BI__sync_add_and_fetch_2:
2731 case Builtin::BI__sync_add_and_fetch_4:
2732 case Builtin::BI__sync_add_and_fetch_8:
2733 case Builtin::BI__sync_add_and_fetch_16:
2734 case Builtin::BI__sync_sub_and_fetch:
2735 case Builtin::BI__sync_sub_and_fetch_1:
2736 case Builtin::BI__sync_sub_and_fetch_2:
2737 case Builtin::BI__sync_sub_and_fetch_4:
2738 case Builtin::BI__sync_sub_and_fetch_8:
2739 case Builtin::BI__sync_sub_and_fetch_16:
2740 case Builtin::BI__sync_and_and_fetch:
2741 case Builtin::BI__sync_and_and_fetch_1:
2742 case Builtin::BI__sync_and_and_fetch_2:
2743 case Builtin::BI__sync_and_and_fetch_4:
2744 case Builtin::BI__sync_and_and_fetch_8:
2745 case Builtin::BI__sync_and_and_fetch_16:
2746 case Builtin::BI__sync_or_and_fetch:
2747 case Builtin::BI__sync_or_and_fetch_1:
2748 case Builtin::BI__sync_or_and_fetch_2:
2749 case Builtin::BI__sync_or_and_fetch_4:
2750 case Builtin::BI__sync_or_and_fetch_8:
2751 case Builtin::BI__sync_or_and_fetch_16:
2752 case Builtin::BI__sync_xor_and_fetch:
2753 case Builtin::BI__sync_xor_and_fetch_1:
2754 case Builtin::BI__sync_xor_and_fetch_2:
2755 case Builtin::BI__sync_xor_and_fetch_4:
2756 case Builtin::BI__sync_xor_and_fetch_8:
2757 case Builtin::BI__sync_xor_and_fetch_16:
2758 case Builtin::BI__sync_nand_and_fetch:
2759 case Builtin::BI__sync_nand_and_fetch_1:
2760 case Builtin::BI__sync_nand_and_fetch_2:
2761 case Builtin::BI__sync_nand_and_fetch_4:
2762 case Builtin::BI__sync_nand_and_fetch_8:
2763 case Builtin::BI__sync_nand_and_fetch_16:
2764 case Builtin::BI__sync_val_compare_and_swap:
2765 case Builtin::BI__sync_val_compare_and_swap_1:
2766 case Builtin::BI__sync_val_compare_and_swap_2:
2767 case Builtin::BI__sync_val_compare_and_swap_4:
2768 case Builtin::BI__sync_val_compare_and_swap_8:
2769 case Builtin::BI__sync_val_compare_and_swap_16:
2770 case Builtin::BI__sync_bool_compare_and_swap:
2771 case Builtin::BI__sync_bool_compare_and_swap_1:
2772 case Builtin::BI__sync_bool_compare_and_swap_2:
2773 case Builtin::BI__sync_bool_compare_and_swap_4:
2774 case Builtin::BI__sync_bool_compare_and_swap_8:
2775 case Builtin::BI__sync_bool_compare_and_swap_16:
2776 case Builtin::BI__sync_lock_test_and_set:
2777 case Builtin::BI__sync_lock_test_and_set_1:
2778 case Builtin::BI__sync_lock_test_and_set_2:
2779 case Builtin::BI__sync_lock_test_and_set_4:
2780 case Builtin::BI__sync_lock_test_and_set_8:
2781 case Builtin::BI__sync_lock_test_and_set_16:
2782 case Builtin::BI__sync_lock_release:
2783 case Builtin::BI__sync_lock_release_1:
2784 case Builtin::BI__sync_lock_release_2:
2785 case Builtin::BI__sync_lock_release_4:
2786 case Builtin::BI__sync_lock_release_8:
2787 case Builtin::BI__sync_lock_release_16:
2788 case Builtin::BI__sync_swap:
2789 case Builtin::BI__sync_swap_1:
2790 case Builtin::BI__sync_swap_2:
2791 case Builtin::BI__sync_swap_4:
2792 case Builtin::BI__sync_swap_8:
2793 case Builtin::BI__sync_swap_16:
2794 return BuiltinAtomicOverloaded(TheCallResult);
2795 case Builtin::BI__sync_synchronize:
2799 case Builtin::BI__builtin_nontemporal_load:
2800 case Builtin::BI__builtin_nontemporal_store:
2801 return BuiltinNontemporalOverloaded(TheCallResult);
2802 case Builtin::BI__builtin_memcpy_inline: {
2815 case Builtin::BI__builtin_memset_inline: {
2826#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2827 case Builtin::BI##ID: \
2828 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2829#include "clang/Basic/Builtins.inc"
2830 case Builtin::BI__annotation:
2834 case Builtin::BI__builtin_annotation:
2838 case Builtin::BI__builtin_addressof:
2842 case Builtin::BI__builtin_function_start:
2846 case Builtin::BI__builtin_is_aligned:
2847 case Builtin::BI__builtin_align_up:
2848 case Builtin::BI__builtin_align_down:
2852 case Builtin::BI__builtin_add_overflow:
2853 case Builtin::BI__builtin_sub_overflow:
2854 case Builtin::BI__builtin_mul_overflow:
2858 case Builtin::BI__builtin_operator_new:
2859 case Builtin::BI__builtin_operator_delete: {
2860 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2862 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2865 case Builtin::BI__builtin_dump_struct:
2867 case Builtin::BI__builtin_expect_with_probability: {
2878 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2885 bool LoseInfo =
false;
2886 Probability.convert(llvm::APFloat::IEEEdouble(),
2887 llvm::RoundingMode::Dynamic, &LoseInfo);
2888 if (!(Probability >= llvm::APFloat(0.0) &&
2889 Probability <= llvm::APFloat(1.0))) {
2896 case Builtin::BI__builtin_preserve_access_index:
2900 case Builtin::BI__builtin_call_with_static_chain:
2904 case Builtin::BI__exception_code:
2905 case Builtin::BI_exception_code:
2907 diag::err_seh___except_block))
2910 case Builtin::BI__exception_info:
2911 case Builtin::BI_exception_info:
2913 diag::err_seh___except_filter))
2916 case Builtin::BI__GetExceptionInfo:
2928 case Builtin::BIaddressof:
2929 case Builtin::BI__addressof:
2930 case Builtin::BIforward:
2931 case Builtin::BIforward_like:
2932 case Builtin::BImove:
2933 case Builtin::BImove_if_noexcept:
2934 case Builtin::BIas_const: {
2942 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
2943 BuiltinID == Builtin::BI__addressof;
2945 (ReturnsPointer ?
Result->isAnyPointerType()
2946 :
Result->isReferenceType()) &&
2948 Result->getPointeeType()))) {
2949 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
2955 case Builtin::BI__builtin_ptrauth_strip:
2957 case Builtin::BI__builtin_ptrauth_blend_discriminator:
2959 case Builtin::BI__builtin_ptrauth_sign_constant:
2962 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
2965 case Builtin::BI__builtin_ptrauth_auth:
2968 case Builtin::BI__builtin_ptrauth_sign_generic_data:
2970 case Builtin::BI__builtin_ptrauth_auth_and_resign:
2972 case Builtin::BI__builtin_ptrauth_string_discriminator:
2975 case Builtin::BI__builtin_get_vtable_pointer:
2979 case Builtin::BIread_pipe:
2980 case Builtin::BIwrite_pipe:
2983 if (
OpenCL().checkBuiltinRWPipe(TheCall))
2986 case Builtin::BIreserve_read_pipe:
2987 case Builtin::BIreserve_write_pipe:
2988 case Builtin::BIwork_group_reserve_read_pipe:
2989 case Builtin::BIwork_group_reserve_write_pipe:
2990 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
2993 case Builtin::BIsub_group_reserve_read_pipe:
2994 case Builtin::BIsub_group_reserve_write_pipe:
2995 if (
OpenCL().checkSubgroupExt(TheCall) ||
2996 OpenCL().checkBuiltinReserveRWPipe(TheCall))
2999 case Builtin::BIcommit_read_pipe:
3000 case Builtin::BIcommit_write_pipe:
3001 case Builtin::BIwork_group_commit_read_pipe:
3002 case Builtin::BIwork_group_commit_write_pipe:
3003 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3006 case Builtin::BIsub_group_commit_read_pipe:
3007 case Builtin::BIsub_group_commit_write_pipe:
3008 if (
OpenCL().checkSubgroupExt(TheCall) ||
3009 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3012 case Builtin::BIget_pipe_num_packets:
3013 case Builtin::BIget_pipe_max_packets:
3014 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3017 case Builtin::BIto_global:
3018 case Builtin::BIto_local:
3019 case Builtin::BIto_private:
3020 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3024 case Builtin::BIenqueue_kernel:
3025 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3028 case Builtin::BIget_kernel_work_group_size:
3029 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3030 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3033 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3034 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3035 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3038 case Builtin::BI__builtin_os_log_format:
3041 case Builtin::BI__builtin_os_log_format_buffer_size:
3042 if (BuiltinOSLogFormat(TheCall))
3045 case Builtin::BI__builtin_frame_address:
3046 case Builtin::BI__builtin_return_address: {
3055 Result.Val.getInt() != 0)
3057 << ((BuiltinID == Builtin::BI__builtin_return_address)
3058 ?
"__builtin_return_address"
3059 :
"__builtin_frame_address")
3064 case Builtin::BI__builtin_nondeterministic_value: {
3065 if (BuiltinNonDeterministicValue(TheCall))
3072 case Builtin::BI__builtin_elementwise_abs:
3080 case Builtin::BI__builtin_elementwise_acos:
3081 case Builtin::BI__builtin_elementwise_asin:
3082 case Builtin::BI__builtin_elementwise_atan:
3083 case Builtin::BI__builtin_elementwise_ceil:
3084 case Builtin::BI__builtin_elementwise_cos:
3085 case Builtin::BI__builtin_elementwise_cosh:
3086 case Builtin::BI__builtin_elementwise_exp:
3087 case Builtin::BI__builtin_elementwise_exp2:
3088 case Builtin::BI__builtin_elementwise_exp10:
3089 case Builtin::BI__builtin_elementwise_floor:
3090 case Builtin::BI__builtin_elementwise_log:
3091 case Builtin::BI__builtin_elementwise_log2:
3092 case Builtin::BI__builtin_elementwise_log10:
3093 case Builtin::BI__builtin_elementwise_roundeven:
3094 case Builtin::BI__builtin_elementwise_round:
3095 case Builtin::BI__builtin_elementwise_rint:
3096 case Builtin::BI__builtin_elementwise_nearbyint:
3097 case Builtin::BI__builtin_elementwise_sin:
3098 case Builtin::BI__builtin_elementwise_sinh:
3099 case Builtin::BI__builtin_elementwise_sqrt:
3100 case Builtin::BI__builtin_elementwise_tan:
3101 case Builtin::BI__builtin_elementwise_tanh:
3102 case Builtin::BI__builtin_elementwise_trunc:
3103 case Builtin::BI__builtin_elementwise_canonicalize:
3108 case Builtin::BI__builtin_elementwise_fma:
3115 case Builtin::BI__builtin_elementwise_minnum:
3116 case Builtin::BI__builtin_elementwise_maxnum:
3117 case Builtin::BI__builtin_elementwise_minimum:
3118 case Builtin::BI__builtin_elementwise_maximum:
3119 case Builtin::BI__builtin_elementwise_minimumnum:
3120 case Builtin::BI__builtin_elementwise_maximumnum:
3121 case Builtin::BI__builtin_elementwise_atan2:
3122 case Builtin::BI__builtin_elementwise_fmod:
3123 case Builtin::BI__builtin_elementwise_pow:
3124 if (BuiltinElementwiseMath(TheCall,
3130 case Builtin::BI__builtin_elementwise_add_sat:
3131 case Builtin::BI__builtin_elementwise_sub_sat:
3132 if (BuiltinElementwiseMath(TheCall,
3136 case Builtin::BI__builtin_elementwise_fshl:
3137 case Builtin::BI__builtin_elementwise_fshr:
3142 case Builtin::BI__builtin_elementwise_min:
3143 case Builtin::BI__builtin_elementwise_max:
3144 if (BuiltinElementwiseMath(TheCall))
3147 case Builtin::BI__builtin_elementwise_popcount:
3148 case Builtin::BI__builtin_elementwise_bitreverse:
3153 case Builtin::BI__builtin_elementwise_copysign: {
3175 diag::err_typecheck_call_different_arg_types)
3176 << MagnitudeTy << SignTy;
3184 case Builtin::BI__builtin_elementwise_ctlz:
3185 case Builtin::BI__builtin_elementwise_cttz:
3193 }
else if (BuiltinElementwiseMath(
3197 case Builtin::BI__builtin_reduce_max:
3198 case Builtin::BI__builtin_reduce_min: {
3199 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3207 ElTy = TyA->getElementType();
3211 if (ElTy.isNull()) {
3221 case Builtin::BI__builtin_reduce_maximum:
3222 case Builtin::BI__builtin_reduce_minimum: {
3223 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3231 ElTy = TyA->getElementType();
3235 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3248 case Builtin::BI__builtin_reduce_add:
3249 case Builtin::BI__builtin_reduce_mul:
3250 case Builtin::BI__builtin_reduce_xor:
3251 case Builtin::BI__builtin_reduce_or:
3252 case Builtin::BI__builtin_reduce_and: {
3253 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3261 ElTy = TyA->getElementType();
3265 if (ElTy.isNull() || !ElTy->isIntegerType()) {
3276 case Builtin::BI__builtin_matrix_transpose:
3277 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3279 case Builtin::BI__builtin_matrix_column_major_load:
3280 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3282 case Builtin::BI__builtin_matrix_column_major_store:
3283 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3285 case Builtin::BI__builtin_verbose_trap:
3290 case Builtin::BI__builtin_get_device_side_mangled_name: {
3291 auto Check = [](
CallExpr *TheCall) {
3297 auto *
D = DRE->getDecl();
3298 if (!isa<FunctionDecl>(
D) && !isa<VarDecl>(
D))
3303 if (!Check(TheCall)) {
3305 diag::err_hip_invalid_args_builtin_mangled_name);
3310 case Builtin::BI__builtin_popcountg:
3314 case Builtin::BI__builtin_clzg:
3315 case Builtin::BI__builtin_ctzg:
3320 case Builtin::BI__builtin_allow_runtime_check: {
3330 case Builtin::BI__builtin_counted_by_ref:
3331 if (BuiltinCountedByRef(TheCall))
3344 "Aux Target Builtin, but not an aux target?");
3346 if (CheckTSBuiltinFunctionCall(
3357 return TheCallResult;
3372 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3376 diag::err_argument_not_contiguous_bit_field)
3382 bool IsCXXMember =
false;
3383 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D))
3384 IsCXXMember = MD->isInstance();
3385 bool IsVariadic =
false;
3387 IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();
3388 else if (
const auto *BD = dyn_cast<BlockDecl>(
D))
3389 IsVariadic = BD->isVariadic();
3390 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D))
3391 IsVariadic = OMD->isVariadic();
3397 bool IsCXXMember,
bool IsVariadic,
3401 else if (IsVariadic)
3428 if (isa<CXXNullPtrLiteralExpr>(
3444 ->
hasAttr<TransparentUnionAttr>()) {
3445 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3446 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3447 Expr = ILE->getInit(0);
3457 const Expr *ArgExpr,
3461 S.
PDiag(diag::warn_null_arg)
3467 if (
auto nullability =
type->getNullability())
3478 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3484 llvm::SmallBitVector NonNullArgs;
3490 for (
const auto *Arg : Args)
3497 unsigned IdxAST = Idx.getASTIndex();
3498 if (IdxAST >= Args.size())
3500 if (NonNullArgs.empty())
3501 NonNullArgs.resize(Args.size());
3502 NonNullArgs.set(IdxAST);
3507 if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {
3511 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3514 parms = cast<ObjCMethodDecl>(FDecl)->parameters();
3516 unsigned ParamIndex = 0;
3518 I !=
E; ++I, ++ParamIndex) {
3521 if (NonNullArgs.empty())
3522 NonNullArgs.resize(Args.size());
3524 NonNullArgs.set(ParamIndex);
3531 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3536 type = blockType->getPointeeType();
3550 if (NonNullArgs.empty())
3551 NonNullArgs.resize(Args.size());
3553 NonNullArgs.set(Index);
3562 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3563 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3564 if (NonNullArgs[ArgIndex])
3570 StringRef ParamName,
QualType ArgTy,
3598 if (ArgAlign < ParamAlign)
3599 Diag(
Loc, diag::warn_param_mismatched_alignment)
3601 << ParamName << (FDecl !=
nullptr) << FDecl;
3605 const Expr *ThisArg,
3607 if (!FD || Args.empty())
3609 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3610 if (Idx == LifetimeCaptureByAttr::Global ||
3611 Idx == LifetimeCaptureByAttr::Unknown)
3613 if (IsMemberFunction && Idx == 0)
3615 return Args[Idx - IsMemberFunction];
3617 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3622 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3623 for (
int CapturingParamIdx :
Attr->params()) {
3626 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
3627 isa<CXXConstructorDecl>(FD))
3629 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3637 I + IsMemberFunction);
3639 if (IsMemberFunction) {
3647 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3660 llvm::SmallBitVector CheckedVarArgs;
3662 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
3664 CheckedVarArgs.resize(Args.size());
3665 CheckFormatString(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3670 CheckedVarArgs.resize(Args.size());
3671 CheckFormatArguments(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3678 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3682 : isa_and_nonnull<FunctionDecl>(FDecl)
3683 ? cast<FunctionDecl>(FDecl)->getNumParams()
3684 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3685 ? cast<ObjCMethodDecl>(FDecl)->param_size()
3688 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3690 if (
const Expr *Arg = Args[ArgIdx]) {
3691 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3698 if (FDecl || Proto) {
3703 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3704 CheckArgumentWithTypeTag(I, Args,
Loc);
3710 if (!Proto && FDecl) {
3712 if (isa_and_nonnull<FunctionProtoType>(FT))
3718 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3720 bool IsScalableArg =
false;
3721 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3723 if (
const Expr *Arg = Args[ArgIdx]) {
3735 IsScalableArg =
true;
3737 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3746 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3747 llvm::StringMap<bool> CallerFeatureMap;
3749 if (!CallerFeatureMap.contains(
"sme"))
3750 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3752 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3759 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3761 (IsScalableArg || IsScalableRet)) {
3762 bool IsCalleeStreaming =
3764 bool IsCalleeStreamingCompatible =
3768 if (!IsCalleeStreamingCompatible &&
3772 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3775 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3786 bool CallerHasZAState =
false;
3787 bool CallerHasZT0State =
false;
3789 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3791 CallerHasZAState =
true;
3793 CallerHasZT0State =
true;
3797 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3799 CallerHasZT0State |=
3801 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3807 Diag(
Loc, diag::err_sme_za_call_no_za_state);
3810 Diag(
Loc, diag::err_sme_zt0_call_no_zt0_state);
3814 Diag(
Loc, diag::err_sme_unimplemented_za_save_restore);
3815 Diag(
Loc, diag::note_sme_use_preserves_za);
3820 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3821 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3822 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3823 if (!Arg->isValueDependent()) {
3825 if (Arg->EvaluateAsInt(Align,
Context)) {
3826 const llvm::APSInt &I = Align.
Val.
getInt();
3827 if (!I.isPowerOf2())
3828 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3829 << Arg->getSourceRange();
3832 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3856 auto *Ctor = cast<CXXConstructorDecl>(FDecl);
3861 checkCall(FDecl, Proto,
nullptr, Args,
true,
3867 bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
3868 isa<CXXMethodDecl>(FDecl);
3869 bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
3870 IsMemberOperatorCall;
3876 Expr *ImplicitThis =
nullptr;
3881 ImplicitThis = Args[0];
3884 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
3887 cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
3899 cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());
3901 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
3919 CheckAbsoluteValueFunction(TheCall, FDecl);
3920 CheckMaxUnsignedZero(TheCall, FDecl);
3921 CheckInfNaNFunction(TheCall, FDecl);
3932 case Builtin::BIstrlcpy:
3933 case Builtin::BIstrlcat:
3934 CheckStrlcpycatArguments(TheCall, FnInfo);
3936 case Builtin::BIstrncat:
3937 CheckStrncatArguments(TheCall, FnInfo);
3939 case Builtin::BIfree:
3940 CheckFreeArguments(TheCall);
3943 CheckMemaccessArguments(TheCall, CMId, FnInfo);
3952 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
3953 Ty =
V->getType().getNonReferenceType();
3954 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
3955 Ty = F->getType().getNonReferenceType();
3992 if (!llvm::isValidAtomicOrderingCABI(Ordering))
3995 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
3997 case AtomicExpr::AO__c11_atomic_init:
3998 case AtomicExpr::AO__opencl_atomic_init:
3999 llvm_unreachable(
"There is no ordering argument for an init");
4001 case AtomicExpr::AO__c11_atomic_load:
4002 case AtomicExpr::AO__opencl_atomic_load:
4003 case AtomicExpr::AO__hip_atomic_load:
4004 case AtomicExpr::AO__atomic_load_n:
4005 case AtomicExpr::AO__atomic_load:
4006 case AtomicExpr::AO__scoped_atomic_load_n:
4007 case AtomicExpr::AO__scoped_atomic_load:
4008 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4009 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4011 case AtomicExpr::AO__c11_atomic_store:
4012 case AtomicExpr::AO__opencl_atomic_store:
4013 case AtomicExpr::AO__hip_atomic_store:
4014 case AtomicExpr::AO__atomic_store:
4015 case AtomicExpr::AO__atomic_store_n:
4016 case AtomicExpr::AO__scoped_atomic_store:
4017 case AtomicExpr::AO__scoped_atomic_store_n:
4018 case AtomicExpr::AO__atomic_clear:
4019 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4020 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4021 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4030 CallExpr *TheCall = cast<CallExpr>(TheCallResult.
get());
4080 const unsigned NumForm = ClearByte + 1;
4081 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4082 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4090 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4091 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4092 "need to update code for modified forms");
4093 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4094 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4095 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4096 "need to update code for modified C11 atomics");
4097 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4098 Op <= AtomicExpr::AO__opencl_atomic_store;
4099 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4100 Op <= AtomicExpr::AO__hip_atomic_store;
4101 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4102 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4103 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4104 Op <= AtomicExpr::AO__c11_atomic_store) ||
4106 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4107 Op == AtomicExpr::AO__atomic_store_n ||
4108 Op == AtomicExpr::AO__atomic_exchange_n ||
4109 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4110 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4111 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4112 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4113 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4117 enum ArithOpExtraValueType {
4122 unsigned ArithAllows = AOEVT_None;
4125 case AtomicExpr::AO__c11_atomic_init:
4126 case AtomicExpr::AO__opencl_atomic_init:
4130 case AtomicExpr::AO__c11_atomic_load:
4131 case AtomicExpr::AO__opencl_atomic_load:
4132 case AtomicExpr::AO__hip_atomic_load:
4133 case AtomicExpr::AO__atomic_load_n:
4134 case AtomicExpr::AO__scoped_atomic_load_n:
4138 case AtomicExpr::AO__atomic_load:
4139 case AtomicExpr::AO__scoped_atomic_load:
4143 case AtomicExpr::AO__c11_atomic_store:
4144 case AtomicExpr::AO__opencl_atomic_store:
4145 case AtomicExpr::AO__hip_atomic_store:
4146 case AtomicExpr::AO__atomic_store:
4147 case AtomicExpr::AO__atomic_store_n:
4148 case AtomicExpr::AO__scoped_atomic_store:
4149 case AtomicExpr::AO__scoped_atomic_store_n:
4152 case AtomicExpr::AO__atomic_fetch_add:
4153 case AtomicExpr::AO__atomic_fetch_sub:
4154 case AtomicExpr::AO__atomic_add_fetch:
4155 case AtomicExpr::AO__atomic_sub_fetch:
4156 case AtomicExpr::AO__scoped_atomic_fetch_add:
4157 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4158 case AtomicExpr::AO__scoped_atomic_add_fetch:
4159 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4160 case AtomicExpr::AO__c11_atomic_fetch_add:
4161 case AtomicExpr::AO__c11_atomic_fetch_sub:
4162 case AtomicExpr::AO__opencl_atomic_fetch_add:
4163 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4164 case AtomicExpr::AO__hip_atomic_fetch_add:
4165 case AtomicExpr::AO__hip_atomic_fetch_sub:
4166 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4169 case AtomicExpr::AO__atomic_fetch_max:
4170 case AtomicExpr::AO__atomic_fetch_min:
4171 case AtomicExpr::AO__atomic_max_fetch:
4172 case AtomicExpr::AO__atomic_min_fetch:
4173 case AtomicExpr::AO__scoped_atomic_fetch_max:
4174 case AtomicExpr::AO__scoped_atomic_fetch_min:
4175 case AtomicExpr::AO__scoped_atomic_max_fetch:
4176 case AtomicExpr::AO__scoped_atomic_min_fetch:
4177 case AtomicExpr::AO__c11_atomic_fetch_max:
4178 case AtomicExpr::AO__c11_atomic_fetch_min:
4179 case AtomicExpr::AO__opencl_atomic_fetch_max:
4180 case AtomicExpr::AO__opencl_atomic_fetch_min:
4181 case AtomicExpr::AO__hip_atomic_fetch_max:
4182 case AtomicExpr::AO__hip_atomic_fetch_min:
4183 ArithAllows = AOEVT_FP;
4186 case AtomicExpr::AO__c11_atomic_fetch_and:
4187 case AtomicExpr::AO__c11_atomic_fetch_or:
4188 case AtomicExpr::AO__c11_atomic_fetch_xor:
4189 case AtomicExpr::AO__hip_atomic_fetch_and:
4190 case AtomicExpr::AO__hip_atomic_fetch_or:
4191 case AtomicExpr::AO__hip_atomic_fetch_xor:
4192 case AtomicExpr::AO__c11_atomic_fetch_nand:
4193 case AtomicExpr::AO__opencl_atomic_fetch_and:
4194 case AtomicExpr::AO__opencl_atomic_fetch_or:
4195 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4196 case AtomicExpr::AO__atomic_fetch_and:
4197 case AtomicExpr::AO__atomic_fetch_or:
4198 case AtomicExpr::AO__atomic_fetch_xor:
4199 case AtomicExpr::AO__atomic_fetch_nand:
4200 case AtomicExpr::AO__atomic_and_fetch:
4201 case AtomicExpr::AO__atomic_or_fetch:
4202 case AtomicExpr::AO__atomic_xor_fetch:
4203 case AtomicExpr::AO__atomic_nand_fetch:
4204 case AtomicExpr::AO__scoped_atomic_fetch_and:
4205 case AtomicExpr::AO__scoped_atomic_fetch_or:
4206 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4207 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4208 case AtomicExpr::AO__scoped_atomic_and_fetch:
4209 case AtomicExpr::AO__scoped_atomic_or_fetch:
4210 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4211 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4215 case AtomicExpr::AO__c11_atomic_exchange:
4216 case AtomicExpr::AO__hip_atomic_exchange:
4217 case AtomicExpr::AO__opencl_atomic_exchange:
4218 case AtomicExpr::AO__atomic_exchange_n:
4219 case AtomicExpr::AO__scoped_atomic_exchange_n:
4223 case AtomicExpr::AO__atomic_exchange:
4224 case AtomicExpr::AO__scoped_atomic_exchange:
4228 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4229 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4230 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4231 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4232 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4233 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4237 case AtomicExpr::AO__atomic_compare_exchange:
4238 case AtomicExpr::AO__atomic_compare_exchange_n:
4239 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4240 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4244 case AtomicExpr::AO__atomic_test_and_set:
4245 Form = TestAndSetByte;
4248 case AtomicExpr::AO__atomic_clear:
4253 unsigned AdjustedNumArgs = NumArgs[Form];
4254 if ((IsOpenCL || IsHIP || IsScoped) &&
4255 Op != AtomicExpr::AO__opencl_atomic_init)
4258 if (Args.size() < AdjustedNumArgs) {
4259 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4260 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4263 }
else if (Args.size() > AdjustedNumArgs) {
4264 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4265 diag::err_typecheck_call_too_many_args)
4266 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4272 Expr *Ptr = Args[0];
4277 Ptr = ConvertedPtr.
get();
4280 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4290 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4296 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4302 }
else if (Form != Load && Form != LoadCopy) {
4304 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4310 if (Form != TestAndSetByte && Form != ClearByte) {
4313 diag::err_incomplete_type))
4317 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4327 pointerType->getPointeeType().getCVRQualifiers());
4337 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4346 auto IsAllowedValueType = [&](
QualType ValType,
4347 unsigned AllowedType) ->
bool {
4351 return AllowedType & AOEVT_Pointer;
4357 &llvm::APFloat::x87DoubleExtended())
4361 if (!IsAllowedValueType(ValType, ArithAllows)) {
4362 auto DID = ArithAllows & AOEVT_FP
4363 ? (ArithAllows & AOEVT_Pointer
4364 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4365 : diag::err_atomic_op_needs_atomic_int_or_fp)
4366 : diag::err_atomic_op_needs_atomic_int;
4373 diag::err_incomplete_type)) {
4379 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4390 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4406 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4418 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4421 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4427 bool IsPassedByAddress =
false;
4428 if (!IsC11 && !IsHIP && !IsN) {
4430 IsPassedByAddress =
true;
4435 APIOrderedArgs.push_back(Args[0]);
4439 APIOrderedArgs.push_back(Args[1]);
4445 APIOrderedArgs.push_back(Args[2]);
4446 APIOrderedArgs.push_back(Args[1]);
4449 APIOrderedArgs.push_back(Args[2]);
4450 APIOrderedArgs.push_back(Args[3]);
4451 APIOrderedArgs.push_back(Args[1]);
4454 APIOrderedArgs.push_back(Args[2]);
4455 APIOrderedArgs.push_back(Args[4]);
4456 APIOrderedArgs.push_back(Args[1]);
4457 APIOrderedArgs.push_back(Args[3]);
4460 APIOrderedArgs.push_back(Args[2]);
4461 APIOrderedArgs.push_back(Args[4]);
4462 APIOrderedArgs.push_back(Args[5]);
4463 APIOrderedArgs.push_back(Args[1]);
4464 APIOrderedArgs.push_back(Args[3]);
4466 case TestAndSetByte:
4468 APIOrderedArgs.push_back(Args[1]);
4472 APIOrderedArgs.append(Args.begin(), Args.end());
4479 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4481 if (i < NumVals[Form] + 1) {
4494 assert(Form != Load);
4499 else if (Form ==
Copy || Form == Xchg) {
4500 if (IsPassedByAddress) {
4507 Expr *ValArg = APIOrderedArgs[i];
4514 AS = PtrTy->getPointeeType().getAddressSpace();
4523 if (IsPassedByAddress)
4543 APIOrderedArgs[i] = Arg.
get();
4548 SubExprs.push_back(Ptr);
4552 SubExprs.push_back(APIOrderedArgs[1]);
4555 case TestAndSetByte:
4557 SubExprs.push_back(APIOrderedArgs[1]);
4563 SubExprs.push_back(APIOrderedArgs[2]);
4564 SubExprs.push_back(APIOrderedArgs[1]);
4568 SubExprs.push_back(APIOrderedArgs[3]);
4569 SubExprs.push_back(APIOrderedArgs[1]);
4570 SubExprs.push_back(APIOrderedArgs[2]);
4573 SubExprs.push_back(APIOrderedArgs[3]);
4574 SubExprs.push_back(APIOrderedArgs[1]);
4575 SubExprs.push_back(APIOrderedArgs[4]);
4576 SubExprs.push_back(APIOrderedArgs[2]);
4579 SubExprs.push_back(APIOrderedArgs[4]);
4580 SubExprs.push_back(APIOrderedArgs[1]);
4581 SubExprs.push_back(APIOrderedArgs[5]);
4582 SubExprs.push_back(APIOrderedArgs[2]);
4583 SubExprs.push_back(APIOrderedArgs[3]);
4588 if (SubExprs.size() >= 2 && Form !=
Init) {
4589 std::optional<llvm::APSInt>
Success =
4590 SubExprs[1]->getIntegerConstantExpr(
Context);
4592 Diag(SubExprs[1]->getBeginLoc(),
4593 diag::warn_atomic_op_has_invalid_memory_order)
4594 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4595 << SubExprs[1]->getSourceRange();
4597 if (SubExprs.size() >= 5) {
4598 if (std::optional<llvm::APSInt> Failure =
4599 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4600 if (!llvm::is_contained(
4601 {llvm::AtomicOrderingCABI::relaxed,
4602 llvm::AtomicOrderingCABI::consume,
4603 llvm::AtomicOrderingCABI::acquire,
4604 llvm::AtomicOrderingCABI::seq_cst},
4605 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4606 Diag(SubExprs[3]->getBeginLoc(),
4607 diag::warn_atomic_op_has_invalid_memory_order)
4608 << 2 << SubExprs[3]->getSourceRange();
4615 auto *
Scope = Args[Args.size() - 1];
4616 if (std::optional<llvm::APSInt>
Result =
4618 if (!ScopeModel->isValid(
Result->getZExtValue()))
4619 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
4620 <<
Scope->getSourceRange();
4622 SubExprs.push_back(
Scope);
4628 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4629 Op == AtomicExpr::AO__c11_atomic_store ||
4630 Op == AtomicExpr::AO__opencl_atomic_load ||
4631 Op == AtomicExpr::AO__hip_atomic_load ||
4632 Op == AtomicExpr::AO__opencl_atomic_store ||
4633 Op == AtomicExpr::AO__hip_atomic_store) &&
4636 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4637 Op == AtomicExpr::AO__opencl_atomic_load ||
4638 Op == AtomicExpr::AO__hip_atomic_load)
4643 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4659 assert(Fn &&
"builtin call without direct callee!");
4670 E->setArg(ArgIndex, Arg.
get());
4682 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4684 <<
Callee->getSourceRange();
4697 FirstArg = FirstArgResult.
get();
4698 TheCall->
setArg(0, FirstArg);
4710 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4717 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4752#define BUILTIN_ROW(x) \
4753 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4754 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4756 static const unsigned BuiltinIndices[][5] = {
4782 case 1: SizeIndex = 0;
break;
4783 case 2: SizeIndex = 1;
break;
4784 case 4: SizeIndex = 2;
break;
4785 case 8: SizeIndex = 3;
break;
4786 case 16: SizeIndex = 4;
break;
4798 unsigned BuiltinIndex, NumFixed = 1;
4799 bool WarnAboutSemanticsChange =
false;
4800 switch (BuiltinID) {
4801 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4802 case Builtin::BI__sync_fetch_and_add:
4803 case Builtin::BI__sync_fetch_and_add_1:
4804 case Builtin::BI__sync_fetch_and_add_2:
4805 case Builtin::BI__sync_fetch_and_add_4:
4806 case Builtin::BI__sync_fetch_and_add_8:
4807 case Builtin::BI__sync_fetch_and_add_16:
4811 case Builtin::BI__sync_fetch_and_sub:
4812 case Builtin::BI__sync_fetch_and_sub_1:
4813 case Builtin::BI__sync_fetch_and_sub_2:
4814 case Builtin::BI__sync_fetch_and_sub_4:
4815 case Builtin::BI__sync_fetch_and_sub_8:
4816 case Builtin::BI__sync_fetch_and_sub_16:
4820 case Builtin::BI__sync_fetch_and_or:
4821 case Builtin::BI__sync_fetch_and_or_1:
4822 case Builtin::BI__sync_fetch_and_or_2:
4823 case Builtin::BI__sync_fetch_and_or_4:
4824 case Builtin::BI__sync_fetch_and_or_8:
4825 case Builtin::BI__sync_fetch_and_or_16:
4829 case Builtin::BI__sync_fetch_and_and:
4830 case Builtin::BI__sync_fetch_and_and_1:
4831 case Builtin::BI__sync_fetch_and_and_2:
4832 case Builtin::BI__sync_fetch_and_and_4:
4833 case Builtin::BI__sync_fetch_and_and_8:
4834 case Builtin::BI__sync_fetch_and_and_16:
4838 case Builtin::BI__sync_fetch_and_xor:
4839 case Builtin::BI__sync_fetch_and_xor_1:
4840 case Builtin::BI__sync_fetch_and_xor_2:
4841 case Builtin::BI__sync_fetch_and_xor_4:
4842 case Builtin::BI__sync_fetch_and_xor_8:
4843 case Builtin::BI__sync_fetch_and_xor_16:
4847 case Builtin::BI__sync_fetch_and_nand:
4848 case Builtin::BI__sync_fetch_and_nand_1:
4849 case Builtin::BI__sync_fetch_and_nand_2:
4850 case Builtin::BI__sync_fetch_and_nand_4:
4851 case Builtin::BI__sync_fetch_and_nand_8:
4852 case Builtin::BI__sync_fetch_and_nand_16:
4854 WarnAboutSemanticsChange =
true;
4857 case Builtin::BI__sync_add_and_fetch:
4858 case Builtin::BI__sync_add_and_fetch_1:
4859 case Builtin::BI__sync_add_and_fetch_2:
4860 case Builtin::BI__sync_add_and_fetch_4:
4861 case Builtin::BI__sync_add_and_fetch_8:
4862 case Builtin::BI__sync_add_and_fetch_16:
4866 case Builtin::BI__sync_sub_and_fetch:
4867 case Builtin::BI__sync_sub_and_fetch_1:
4868 case Builtin::BI__sync_sub_and_fetch_2:
4869 case Builtin::BI__sync_sub_and_fetch_4:
4870 case Builtin::BI__sync_sub_and_fetch_8:
4871 case Builtin::BI__sync_sub_and_fetch_16:
4875 case Builtin::BI__sync_and_and_fetch:
4876 case Builtin::BI__sync_and_and_fetch_1:
4877 case Builtin::BI__sync_and_and_fetch_2:
4878 case Builtin::BI__sync_and_and_fetch_4:
4879 case Builtin::BI__sync_and_and_fetch_8:
4880 case Builtin::BI__sync_and_and_fetch_16:
4884 case Builtin::BI__sync_or_and_fetch:
4885 case Builtin::BI__sync_or_and_fetch_1:
4886 case Builtin::BI__sync_or_and_fetch_2:
4887 case Builtin::BI__sync_or_and_fetch_4:
4888 case Builtin::BI__sync_or_and_fetch_8:
4889 case Builtin::BI__sync_or_and_fetch_16:
4893 case Builtin::BI__sync_xor_and_fetch:
4894 case Builtin::BI__sync_xor_and_fetch_1:
4895 case Builtin::BI__sync_xor_and_fetch_2:
4896 case Builtin::BI__sync_xor_and_fetch_4:
4897 case Builtin::BI__sync_xor_and_fetch_8:
4898 case Builtin::BI__sync_xor_and_fetch_16:
4902 case Builtin::BI__sync_nand_and_fetch:
4903 case Builtin::BI__sync_nand_and_fetch_1:
4904 case Builtin::BI__sync_nand_and_fetch_2:
4905 case Builtin::BI__sync_nand_and_fetch_4:
4906 case Builtin::BI__sync_nand_and_fetch_8:
4907 case Builtin::BI__sync_nand_and_fetch_16:
4909 WarnAboutSemanticsChange =
true;
4912 case Builtin::BI__sync_val_compare_and_swap:
4913 case Builtin::BI__sync_val_compare_and_swap_1:
4914 case Builtin::BI__sync_val_compare_and_swap_2:
4915 case Builtin::BI__sync_val_compare_and_swap_4:
4916 case Builtin::BI__sync_val_compare_and_swap_8:
4917 case Builtin::BI__sync_val_compare_and_swap_16:
4922 case Builtin::BI__sync_bool_compare_and_swap:
4923 case Builtin::BI__sync_bool_compare_and_swap_1:
4924 case Builtin::BI__sync_bool_compare_and_swap_2:
4925 case Builtin::BI__sync_bool_compare_and_swap_4:
4926 case Builtin::BI__sync_bool_compare_and_swap_8:
4927 case Builtin::BI__sync_bool_compare_and_swap_16:
4933 case Builtin::BI__sync_lock_test_and_set:
4934 case Builtin::BI__sync_lock_test_and_set_1:
4935 case Builtin::BI__sync_lock_test_and_set_2:
4936 case Builtin::BI__sync_lock_test_and_set_4:
4937 case Builtin::BI__sync_lock_test_and_set_8:
4938 case Builtin::BI__sync_lock_test_and_set_16:
4942 case Builtin::BI__sync_lock_release:
4943 case Builtin::BI__sync_lock_release_1:
4944 case Builtin::BI__sync_lock_release_2:
4945 case Builtin::BI__sync_lock_release_4:
4946 case Builtin::BI__sync_lock_release_8:
4947 case Builtin::BI__sync_lock_release_16:
4953 case Builtin::BI__sync_swap:
4954 case Builtin::BI__sync_swap_1:
4955 case Builtin::BI__sync_swap_2:
4956 case Builtin::BI__sync_swap_4:
4957 case Builtin::BI__sync_swap_8:
4958 case Builtin::BI__sync_swap_16:
4966 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4967 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
4968 <<
Callee->getSourceRange();
4972 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
4973 <<
Callee->getSourceRange();
4975 if (WarnAboutSemanticsChange) {
4976 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
4977 <<
Callee->getSourceRange();
4982 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
4985 if (NewBuiltinID == BuiltinID)
4986 NewBuiltinDecl = FDecl;
4992 assert(Res.getFoundDecl());
4993 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
4994 if (!NewBuiltinDecl)
5001 for (
unsigned i = 0; i != NumFixed; ++i) {
5032 CK_BuiltinFnToFnPtr);
5044 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5045 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5049 return TheCallResult;
5058 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5059 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5060 "Unexpected nontemporal load/store builtin!");
5061 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5062 unsigned numArgs = isStore ? 2 : 1;
5072 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5078 PointerArg = PointerArgResult.
get();
5079 TheCall->
setArg(numArgs - 1, PointerArg);
5083 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5096 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5103 return TheCallResult;
5115 return TheCallResult;
5122 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5124 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5125 Literal = ObjcLiteral->getString();
5129 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5147 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5148 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5149 TT.getArch() == llvm::Triple::aarch64_32);
5150 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5151 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5152 if (IsX64 || IsAArch64) {
5159 return S.
Diag(Fn->getBeginLoc(),
5160 diag::err_ms_va_start_used_in_sysv_function);
5167 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5168 return S.
Diag(Fn->getBeginLoc(),
5169 diag::err_va_start_used_in_wrong_abi_function)
5170 << !IsWindowsOrUEFI;
5176 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5184 bool IsVariadic =
false;
5187 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5188 IsVariadic =
Block->isVariadic();
5189 Params =
Block->parameters();
5190 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5193 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5194 IsVariadic = MD->isVariadic();
5196 Params = MD->parameters();
5197 }
else if (isa<CapturedDecl>(Caller)) {
5199 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5203 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5208 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5213 *LastParam = Params.empty() ? nullptr : Params.back();
5218bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5223 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5258 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5260 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5265 if (std::optional<llvm::APSInt> Val =
5267 Val &&
LangOpts.C23 && *Val == 0 &&
5268 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5269 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5277 bool IsCRegister =
false;
5278 bool SecondArgIsLastNonVariadicArgument =
false;
5279 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5280 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5281 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5283 Type = PV->getType();
5284 ParamLoc = PV->getLocation();
5290 if (!SecondArgIsLastNonVariadicArgument)
5292 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5297 if (!Context.isPromotableIntegerType(Type))
5299 const auto *ED = Type->getAsEnumDecl();
5302 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5304 unsigned Reason = 0;
5306 else if (IsCRegister) Reason = 2;
5307 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5308 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5315 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5335 if (
Call->getNumArgs() < 3)
5337 diag::err_typecheck_call_too_few_args_at_least)
5338 << 0 << 3 <<
Call->getNumArgs()
5351 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5354 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5359 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5361 << Arg1->
getType() << ConstCharPtrTy << 1
5364 << 2 << Arg1->
getType() << ConstCharPtrTy;
5371 << Arg2->
getType() << SizeTy << 1
5374 << 3 << Arg2->
getType() << SizeTy;
5379bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5383 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5411 diag::err_typecheck_call_invalid_ordered_compare)
5419bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5420 unsigned BuiltinID) {
5425 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5426 BuiltinID == Builtin::BI__builtin_isinf ||
5427 BuiltinID == Builtin::BI__builtin_isinf_sign))
5431 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5432 BuiltinID == Builtin::BI__builtin_isunordered))
5436 bool IsFPClass = NumArgs == 2;
5439 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5443 for (
unsigned i = 0; i < FPArgNo; ++i) {
5470 OrigArg = Res.
get();
5476 OrigArg = Res.
get();
5478 TheCall->
setArg(FPArgNo, OrigArg);
5492 diag::err_typecheck_call_invalid_unary_fp)
5504 if (!VectorResultTy.
isNull())
5505 ResultTy = VectorResultTy;
5514bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5519 for (
unsigned I = 0; I != 2; ++I) {
5530 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5549 diag::err_typecheck_call_different_arg_types)
5563 diag::err_typecheck_call_too_few_args_at_least)
5571 unsigned numElements = 0;
5586 unsigned numResElements = TheCall->
getNumArgs() - 2;
5595 diag::err_vec_builtin_incompatible_vector)
5602 diag::err_vec_builtin_incompatible_vector)
5607 }
else if (numElements != numResElements) {
5616 for (
unsigned i = 2; i < TheCall->
getNumArgs(); i++) {
5621 std::optional<llvm::APSInt>
Result;
5624 diag::err_shufflevector_nonconstant_argument)
5630 else if (
Result->getActiveBits() > 64 ||
5631 Result->getZExtValue() >= numElements * 2)
5633 diag::err_shufflevector_argument_too_large)
5640 for (
unsigned i = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5641 exprs.push_back(TheCall->
getArg(i));
5642 TheCall->
setArg(i,
nullptr);
5660 diag::err_convertvector_non_vector)
5663 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5665 <<
"__builtin_convertvector");
5670 if (SrcElts != DstElts)
5672 diag::err_convertvector_incompatible_vector)
5680bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5685 diag::err_typecheck_call_too_many_args_at_most)
5686 << 0 << 3 << NumArgs << 0
5691 for (
unsigned i = 1; i != NumArgs; ++i)
5698bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5700 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5710 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5720bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5727 << cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5732bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5738 if (
const auto *UE =
5740 if (UE->getKind() == UETT_AlignOf ||
5741 UE->getKind() == UETT_PreferredAlignOf)
5747 if (!
Result.isPowerOf2())
5748 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5755 if (
Result > std::numeric_limits<int32_t>::max())
5763bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5774 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
5778 TheCall->
setArg(0, FirstArgResult.
get());
5790 if (!
Result.isPowerOf2())
5791 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5803 TheCall->
setArg(2, ThirdArg);
5809bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5810 unsigned BuiltinID =
5811 cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5812 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5815 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5816 if (NumArgs < NumRequiredArgs) {
5817 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5818 << 0 << NumRequiredArgs << NumArgs
5821 if (NumArgs >= NumRequiredArgs + 0x100) {
5823 diag::err_typecheck_call_too_many_args_at_most)
5824 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5835 if (Arg.isInvalid())
5837 TheCall->
setArg(i, Arg.get());
5842 unsigned FormatIdx = i;
5852 unsigned FirstDataArg = i;
5853 while (i < NumArgs) {
5871 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5873 bool Success = CheckFormatArguments(
5897 std::optional<llvm::APSInt> R;
5899 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5906 int High,
bool RangeIsError) {
5920 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
5928 PDiag(diag::warn_argument_invalid_range)
5973 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5978 if (
Value.isNegative())
5989 if ((
Value & 0xFF) != 0)
6014 Result.setIsUnsigned(
true);
6019 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6038 Result.setIsUnsigned(
true);
6046 diag::err_argument_not_shifted_byte_or_xxff)
6050bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6052 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6063 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6069bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6071 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6076bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6091 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6096 diag::err_builtin_counted_by_ref_has_side_effects)
6099 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6100 if (!ME->isFlexibleArrayMemberLike(
6103 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6109 const auto *FAMDecl = cast<FieldDecl>(ME->getMemberDecl());
6117 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6127bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *
E,
6138 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6143 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6148 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6166class UncoveredArgHandler {
6167 enum {
Unknown = -1, AllCovered = -2 };
6169 signed FirstUncoveredArg =
Unknown;
6173 UncoveredArgHandler() =
default;
6175 bool hasUncoveredArg()
const {
6176 return (FirstUncoveredArg >= 0);
6179 unsigned getUncoveredArg()
const {
6180 assert(hasUncoveredArg() &&
"no uncovered argument");
6181 return FirstUncoveredArg;
6184 void setAllCovered() {
6187 DiagnosticExprs.clear();
6188 FirstUncoveredArg = AllCovered;
6191 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6192 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6195 if (FirstUncoveredArg == AllCovered)
6200 if (NewFirstUncoveredArg == FirstUncoveredArg)
6201 DiagnosticExprs.push_back(StrExpr);
6202 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6203 DiagnosticExprs.clear();
6204 DiagnosticExprs.push_back(StrExpr);
6205 FirstUncoveredArg = NewFirstUncoveredArg;
6209 void Diagnose(
Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6212enum StringLiteralCheckType {
6214 SLCT_UncheckedLiteral,
6222 bool AddendIsRight) {
6223 unsigned BitWidth = Offset.getBitWidth();
6224 unsigned AddendBitWidth = Addend.getBitWidth();
6226 if (Addend.isUnsigned()) {
6227 Addend = Addend.zext(++AddendBitWidth);
6228 Addend.setIsSigned(
true);
6231 if (AddendBitWidth > BitWidth) {
6232 Offset = Offset.sext(AddendBitWidth);
6233 BitWidth = AddendBitWidth;
6234 }
else if (BitWidth > AddendBitWidth) {
6235 Addend = Addend.sext(BitWidth);
6239 llvm::APSInt ResOffset = Offset;
6240 if (BinOpKind == BO_Add)
6241 ResOffset = Offset.sadd_ov(Addend, Ov);
6243 assert(AddendIsRight && BinOpKind == BO_Sub &&
6244 "operator must be add or sub with addend on the right");
6245 ResOffset = Offset.ssub_ov(Addend, Ov);
6251 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6252 "index (intermediate) result too big");
6253 Offset = Offset.sext(2 * BitWidth);
6254 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6266class FormatStringLiteral {
6271 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6272 : FExpr(fexpr), Offset(Offset) {}
6274 const StringLiteral *getFormatString()
const {
return FExpr; }
6276 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6278 unsigned getByteLength()
const {
6279 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6282 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6289 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6290 bool isWide()
const {
return FExpr->
isWide(); }
6291 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6292 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6293 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6294 bool isPascal()
const {
return FExpr->
isPascal(); }
6299 unsigned *StartTokenByteOffset =
nullptr)
const {
6301 StartToken, StartTokenByteOffset);
6314 Sema &S,
const FormatStringLiteral *FExpr,
6319 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6320 bool IgnoreStringsWithoutSpecifiers);
6334 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6335 llvm::APSInt Offset,
bool IgnoreStringsWithoutSpecifiers =
false) {
6337 return SLCT_NotALiteral;
6339 assert(Offset.isSigned() &&
"invalid offset");
6342 return SLCT_NotALiteral;
6351 return SLCT_UncheckedLiteral;
6354 case Stmt::InitListExprClass:
6358 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6359 Type, CallType,
false, CheckedVarArgs,
6360 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6362 return SLCT_NotALiteral;
6363 case Stmt::BinaryConditionalOperatorClass:
6364 case Stmt::ConditionalOperatorClass: {
6368 cast<AbstractConditionalOperator>(
E);
6373 bool CheckLeft =
true, CheckRight =
true;
6376 if (
C->getCond()->EvaluateAsBooleanCondition(
6388 StringLiteralCheckType Left;
6390 Left = SLCT_UncheckedLiteral;
6393 S, ReferenceFormatString,
C->getTrueExpr(), Args, APK, format_idx,
6394 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6395 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6396 if (Left == SLCT_NotALiteral || !CheckRight) {
6402 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6403 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6404 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6406 return (CheckLeft && Left < Right) ? Left : Right;
6409 case Stmt::ImplicitCastExprClass:
6410 E = cast<ImplicitCastExpr>(
E)->getSubExpr();
6413 case Stmt::OpaqueValueExprClass:
6414 if (
const Expr *src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
6418 return SLCT_NotALiteral;
6420 case Stmt::PredefinedExprClass:
6424 return SLCT_UncheckedLiteral;
6426 case Stmt::DeclRefExprClass: {
6432 bool isConstant =
false;
6436 isConstant = AT->getElementType().isConstant(S.
Context);
6438 isConstant =
T.isConstant(S.
Context) &&
6443 isConstant =
T.isConstant(S.
Context);
6447 if (
const Expr *
Init = VD->getAnyInitializer()) {
6450 if (InitList->isStringLiteralInit())
6451 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6454 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6455 firstDataArg,
Type, CallType,
6456 false, CheckedVarArgs, UncoveredArg, Offset);
6507 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6508 if (
const auto *
D = dyn_cast<Decl>(PV->getDeclContext())) {
6509 for (
const auto *PVFormatMatches :
6515 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6519 S.
Diag(Args[format_idx]->getBeginLoc(),
6520 diag::warn_format_string_type_incompatible)
6521 << PVFormatMatches->getType()->getName()
6523 if (!InFunctionCall) {
6524 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6525 diag::note_format_string_defined);
6527 return SLCT_UncheckedLiteral;
6530 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6531 Args, APK, format_idx, firstDataArg,
Type, CallType,
6532 false, CheckedVarArgs, UncoveredArg,
6533 Offset, IgnoreStringsWithoutSpecifiers);
6540 PVFormat->getFirstArg(), &CallerFSI))
6542 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6546 S.
Diag(Args[format_idx]->getBeginLoc(),
6547 diag::warn_format_string_type_incompatible)
6548 << PVFormat->getType()->getName()
6550 if (!InFunctionCall) {
6553 return SLCT_UncheckedLiteral;
6566 return SLCT_UncheckedLiteral;
6574 return SLCT_NotALiteral;
6577 case Stmt::CallExprClass:
6578 case Stmt::CXXMemberCallExprClass: {
6581 bool IsFirst =
true;
6582 StringLiteralCheckType CommonResult;
6583 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6584 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6586 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6587 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6588 Offset, IgnoreStringsWithoutSpecifiers);
6595 return CommonResult;
6597 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6599 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6600 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6603 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6604 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6605 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6611 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6612 Type, CallType,
false, CheckedVarArgs,
6613 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6614 return SLCT_NotALiteral;
6616 case Stmt::ObjCMessageExprClass: {
6617 const auto *ME = cast<ObjCMessageExpr>(
E);
6618 if (
const auto *MD = ME->getMethodDecl()) {
6619 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6628 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6630 MD->getSelector().isKeywordSelector(
6631 {
"localizedStringForKey",
"value",
"table"})) {
6632 IgnoreStringsWithoutSpecifiers =
true;
6635 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6637 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6638 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6639 Offset, IgnoreStringsWithoutSpecifiers);
6643 return SLCT_NotALiteral;
6645 case Stmt::ObjCStringLiteralClass:
6646 case Stmt::StringLiteralClass: {
6652 StrE = cast<StringLiteral>(
E);
6655 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6658 return SLCT_NotALiteral;
6660 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6662 format_idx, firstDataArg,
Type, InFunctionCall,
6663 CallType, CheckedVarArgs, UncoveredArg,
6664 IgnoreStringsWithoutSpecifiers);
6665 return SLCT_CheckedLiteral;
6668 return SLCT_NotALiteral;
6670 case Stmt::BinaryOperatorClass: {
6684 if (LIsInt != RIsInt) {
6688 if (BinOpKind == BO_Add) {
6701 return SLCT_NotALiteral;
6703 case Stmt::UnaryOperatorClass: {
6705 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6706 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6708 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6718 return SLCT_NotALiteral;
6722 return SLCT_NotALiteral;
6733 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6734 if (isa_and_nonnull<StringLiteral>(LVE))
6755 return "freebsd_kprintf";
6764 return llvm::StringSwitch<FormatStringType>(Flavor)
6770 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
6786bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6790 llvm::SmallBitVector &CheckedVarArgs) {
6791 FormatStringInfo FSI;
6795 return CheckFormatArguments(
6796 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
6801bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
6805 llvm::SmallBitVector &CheckedVarArgs) {
6806 FormatStringInfo FSI;
6810 return CheckFormatArguments(Args, FSI.ArgPassingKind,
6811 Format->getFormatString(), FSI.FormatIdx,
6813 CallType,
Loc,
Range, CheckedVarArgs);
6821 unsigned format_idx,
unsigned firstDataArg,
6825 llvm::SmallBitVector &CheckedVarArgs) {
6827 if (format_idx >= Args.size()) {
6832 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6846 UncoveredArgHandler UncoveredArg;
6848 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
6849 firstDataArg,
Type, CallType,
6850 true, CheckedVarArgs, UncoveredArg,
6851 llvm::APSInt(64,
false) = 0);
6854 if (UncoveredArg.hasUncoveredArg()) {
6855 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6856 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6857 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6860 if (CT != SLCT_NotALiteral)
6862 return CT == SLCT_CheckedLiteral;
6880 if (Args.size() == firstDataArg) {
6881 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6890 Diag(FormatLoc, diag::note_format_security_fixit)
6894 Diag(FormatLoc, diag::note_format_security_fixit)
6899 Diag(FormatLoc, diag::warn_format_nonliteral)
6910 const FormatStringLiteral *FExpr;
6911 const Expr *OrigFormatExpr;
6913 const unsigned FirstDataArg;
6914 const unsigned NumDataArgs;
6919 llvm::SmallBitVector CoveredArgs;
6920 bool usesPositionalArgs =
false;
6921 bool atFirstArg =
true;
6922 bool inFunctionCall;
6924 llvm::SmallBitVector &CheckedVarArgs;
6925 UncoveredArgHandler &UncoveredArg;
6928 CheckFormatHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6930 unsigned firstDataArg,
unsigned numDataArgs,
6934 llvm::SmallBitVector &CheckedVarArgs,
6935 UncoveredArgHandler &UncoveredArg)
6936 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6937 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6938 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6939 inFunctionCall(inFunctionCall), CallType(callType),
6940 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6941 CoveredArgs.resize(numDataArgs);
6942 CoveredArgs.reset();
6945 bool HasFormatArguments()
const {
6950 void DoneProcessing();
6952 void HandleIncompleteSpecifier(
const char *startSpecifier,
6953 unsigned specifierLen)
override;
6955 void HandleInvalidLengthModifier(
6958 const char *startSpecifier,
unsigned specifierLen,
6961 void HandleNonStandardLengthModifier(
6963 const char *startSpecifier,
unsigned specifierLen);
6965 void HandleNonStandardConversionSpecifier(
6967 const char *startSpecifier,
unsigned specifierLen);
6969 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
6971 void HandleInvalidPosition(
const char *startSpecifier,
6972 unsigned specifierLen,
6975 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
6977 void HandleNullChar(
const char *nullCharacter)
override;
6979 template <
typename Range>
6981 EmitFormatDiagnostic(
Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
6983 bool IsStringLocation,
Range StringRange,
6988 const char *startSpec,
6989 unsigned specifierLen,
6990 const char *csStart,
unsigned csLen);
6993 const char *startSpec,
6994 unsigned specifierLen);
6998 unsigned specifierLen);
7001 const Expr *getDataArg(
unsigned i)
const;
7005 const char *startSpecifier,
unsigned specifierLen,
7008 template <
typename Range>
7010 bool IsStringLocation,
Range StringRange,
7016SourceRange CheckFormatHandler::getFormatStringRange() {
7021getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7023 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7026 End = End.getLocWithOffset(1);
7031SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7036void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7037 unsigned specifierLen){
7038 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7039 getLocationOfByte(startSpecifier),
7041 getSpecifierRange(startSpecifier, specifierLen));
7044void CheckFormatHandler::HandleInvalidLengthModifier(
7047 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7048 using namespace analyze_format_string;
7050 const LengthModifier &LM = FS.getLengthModifier();
7051 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
7054 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
7056 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
7057 getLocationOfByte(LM.getStart()),
7059 getSpecifierRange(startSpecifier, specifierLen));
7061 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
7062 << FixedLM->toString()
7067 if (DiagID == diag::warn_format_nonsensical_length)
7070 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
7071 getLocationOfByte(LM.getStart()),
7073 getSpecifierRange(startSpecifier, specifierLen),
7078void CheckFormatHandler::HandleNonStandardLengthModifier(
7080 const char *startSpecifier,
unsigned specifierLen) {
7081 using namespace analyze_format_string;
7083 const LengthModifier &LM = FS.getLengthModifier();
7084 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
7087 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
7089 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7090 << LM.toString() << 0,
7091 getLocationOfByte(LM.getStart()),
7093 getSpecifierRange(startSpecifier, specifierLen));
7095 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
7096 << FixedLM->toString()
7100 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7101 << LM.toString() << 0,
7102 getLocationOfByte(LM.getStart()),
7104 getSpecifierRange(startSpecifier, specifierLen));
7108void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7110 const char *startSpecifier,
unsigned specifierLen) {
7111 using namespace analyze_format_string;
7116 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7120 getSpecifierRange(startSpecifier, specifierLen));
7123 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7124 << FixedCS->toString()
7127 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7131 getSpecifierRange(startSpecifier, specifierLen));
7135void CheckFormatHandler::HandlePosition(
const char *startPos,
7138 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7139 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7140 getLocationOfByte(startPos),
7142 getSpecifierRange(startPos, posLen));
7145void CheckFormatHandler::HandleInvalidPosition(
7146 const char *startSpecifier,
unsigned specifierLen,
7149 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7150 EmitFormatDiagnostic(
7151 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7152 getLocationOfByte(startSpecifier),
true,
7153 getSpecifierRange(startSpecifier, specifierLen));
7156void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7160 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7161 getLocationOfByte(startPos),
7163 getSpecifierRange(startPos, posLen));
7166void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7167 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {
7169 EmitFormatDiagnostic(
7170 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7171 getLocationOfByte(nullCharacter),
true,
7172 getFormatStringRange());
7178const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7179 return Args[FirstDataArg + i];
7182void CheckFormatHandler::DoneProcessing() {
7185 if (HasFormatArguments()) {
7188 signed notCoveredArg = CoveredArgs.find_first();
7189 if (notCoveredArg >= 0) {
7190 assert((
unsigned)notCoveredArg < NumDataArgs);
7191 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7193 UncoveredArg.setAllCovered();
7198void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7199 const Expr *ArgExpr) {
7200 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7212 for (
auto E : DiagnosticExprs)
7215 CheckFormatHandler::EmitFormatDiagnostic(
7216 S, IsFunctionCall, DiagnosticExprs[0],
7222CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7224 const char *startSpec,
7225 unsigned specifierLen,
7226 const char *csStart,
7228 bool keepGoing =
true;
7229 if (argIndex < NumDataArgs) {
7232 CoveredArgs.set(argIndex);
7248 std::string CodePointStr;
7249 if (!llvm::sys::locale::isPrint(*csStart)) {
7250 llvm::UTF32 CodePoint;
7251 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7252 const llvm::UTF8 *
E =
7253 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7254 llvm::ConversionResult
Result =
7255 llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
7257 if (
Result != llvm::conversionOK) {
7258 unsigned char FirstChar = *csStart;
7259 CodePoint = (llvm::UTF32)FirstChar;
7262 llvm::raw_string_ostream OS(CodePointStr);
7263 if (CodePoint < 256)
7264 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7265 else if (CodePoint <= 0xFFFF)
7266 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7268 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7272 EmitFormatDiagnostic(
7273 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier,
Loc,
7274 true, getSpecifierRange(startSpec, specifierLen));
7281 const char *startSpec,
7282 unsigned specifierLen) {
7283 EmitFormatDiagnostic(
7284 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7285 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7289CheckFormatHandler::CheckNumArgs(
7292 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7294 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7296 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7297 << (argIndex+1) << NumDataArgs)
7298 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7299 EmitFormatDiagnostic(
7300 PDiag, getLocationOfByte(CS.
getStart()),
true,
7301 getSpecifierRange(startSpecifier, specifierLen));
7305 UncoveredArg.setAllCovered();
7311template<
typename Range>
7314 bool IsStringLocation,
7317 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7318 Loc, IsStringLocation, StringRange, FixIt);
7348template <
typename Range>
7349void CheckFormatHandler::EmitFormatDiagnostic(
7350 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7353 if (InFunctionCall) {
7362 S.
Diag(IsStringLocation ?
Loc : StringRange.getBegin(),
7363 diag::note_format_string_defined);
7365 Note << StringRange;
7374class CheckPrintfHandler :
public CheckFormatHandler {
7376 CheckPrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7378 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7382 llvm::SmallBitVector &CheckedVarArgs,
7383 UncoveredArgHandler &UncoveredArg)
7384 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7385 numDataArgs, beg, APK, Args, formatIdx,
7386 inFunctionCall, CallType, CheckedVarArgs,
7389 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7392 bool allowsObjCArg()
const {
7393 return FSType == FormatStringType::NSString ||
7394 FSType == FormatStringType::OSLog ||
7395 FSType == FormatStringType::OSTrace;
7398 bool HandleInvalidPrintfConversionSpecifier(
7400 const char *startSpecifier,
7401 unsigned specifierLen)
override;
7403 void handleInvalidMaskType(StringRef MaskType)
override;
7406 const char *startSpecifier,
unsigned specifierLen,
7409 const char *StartSpecifier,
7410 unsigned SpecifierLen,
7414 const char *startSpecifier,
unsigned specifierLen);
7418 const char *startSpecifier,
unsigned specifierLen);
7421 const char *startSpecifier,
unsigned specifierLen);
7425 const char *startSpecifier,
unsigned specifierLen);
7429 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7430 unsigned flagLen)
override;
7432 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7433 unsigned flagLen)
override;
7436 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7437 const char *flagsEnd,
7438 const char *conversionPosition)
override;
7443class EquatableFormatArgument {
7445 enum SpecifierSensitivity :
unsigned {
7452 enum FormatArgumentRole :
unsigned {
7462 StringRef SpecifierLetter;
7465 FormatArgumentRole Role : 2;
7466 SpecifierSensitivity Sensitivity : 2;
7467 unsigned Position : 14;
7468 unsigned ModifierFor : 14;
7471 bool InFunctionCall)
const;
7476 StringRef SpecifierLetter,
7478 FormatArgumentRole Role,
7479 SpecifierSensitivity Sensitivity,
unsigned Position,
7480 unsigned ModifierFor)
7481 : ArgType(ArgType), LengthMod(LengthMod),
7482 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7483 Role(Role), Sensitivity(Sensitivity), Position(Position),
7484 ModifierFor(ModifierFor) {}
7486 unsigned getPosition()
const {
return Position; }
7492 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7494 std::string buildFormatSpecifier()
const {
7496 llvm::raw_string_ostream(result)
7497 << getLengthModifier().toString() << SpecifierLetter;
7501 bool VerifyCompatible(
Sema &S,
const EquatableFormatArgument &
Other,
7502 const Expr *FmtExpr,
bool InFunctionCall)
const;
7506class DecomposePrintfHandler :
public CheckPrintfHandler {
7510 DecomposePrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7511 const Expr *origFormatExpr,
7513 unsigned numDataArgs,
bool isObjC,
const char *beg,
7517 llvm::SmallBitVector &CheckedVarArgs,
7518 UncoveredArgHandler &UncoveredArg,
7520 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7521 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7522 inFunctionCall, CallType, CheckedVarArgs,
7524 Specs(Specs), HadError(
false) {}
7528 GetSpecifiers(
Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7533 const char *startSpecifier,
7534 unsigned specifierLen,
7540bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7542 unsigned specifierLen) {
7544 FS.getConversionSpecifier();
7546 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
7548 startSpecifier, specifierLen,
7552void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7553 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7556bool CheckPrintfHandler::HandleAmount(
7558 const char *startSpecifier,
unsigned specifierLen) {
7560 if (HasFormatArguments()) {
7562 if (argIndex >= NumDataArgs) {
7563 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
7567 getSpecifierRange(startSpecifier, specifierLen));
7577 CoveredArgs.set(argIndex);
7578 const Expr *Arg = getDataArg(argIndex);
7588 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
7593 getSpecifierRange(startSpecifier, specifierLen));
7603void CheckPrintfHandler::HandleInvalidAmount(
7607 const char *startSpecifier,
7608 unsigned specifierLen) {
7610 FS.getConversionSpecifier();
7618 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7622 getSpecifierRange(startSpecifier, specifierLen),
7628 const char *startSpecifier,
7629 unsigned specifierLen) {
7632 FS.getConversionSpecifier();
7633 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7637 getSpecifierRange(startSpecifier, specifierLen),
7642void CheckPrintfHandler::HandleIgnoredFlag(
7646 const char *startSpecifier,
7647 unsigned specifierLen) {
7649 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7653 getSpecifierRange(startSpecifier, specifierLen),
7655 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7658void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7661 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7662 getLocationOfByte(startFlag),
7664 getSpecifierRange(startFlag, flagLen));
7667void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7670 auto Range = getSpecifierRange(startFlag, flagLen);
7671 StringRef flag(startFlag, flagLen);
7672 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7673 getLocationOfByte(startFlag),
7678void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7679 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7681 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7682 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7683 EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
7684 getLocationOfByte(conversionPosition),
7690 const Expr *FmtExpr,
7691 bool InFunctionCall)
const {
7692 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
7693 ElementLoc,
true,
Range);
7696bool EquatableFormatArgument::VerifyCompatible(
7697 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
7698 bool InFunctionCall)
const {
7700 if (Role !=
Other.Role) {
7703 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) << Role <<
Other.Role,
7704 FmtExpr, InFunctionCall);
7705 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7709 if (Role != FAR_Data) {
7710 if (ModifierFor !=
Other.ModifierFor) {
7713 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
7714 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
7715 FmtExpr, InFunctionCall);
7716 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7722 bool HadError =
false;
7723 if (Sensitivity !=
Other.Sensitivity) {
7726 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
7727 << Sensitivity <<
Other.Sensitivity,
7728 FmtExpr, InFunctionCall);
7729 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7730 << 0 <<
Other.Range;
7733 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
7737 case MK::MatchPromotion:
7741 case MK::NoMatchTypeConfusion:
7742 case MK::NoMatchPromotionTypeConfusion:
7744 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
7745 << buildFormatSpecifier()
7746 <<
Other.buildFormatSpecifier(),
7747 FmtExpr, InFunctionCall);
7748 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7749 << 0 <<
Other.Range;
7752 case MK::NoMatchPedantic:
7754 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
7755 << buildFormatSpecifier()
7756 <<
Other.buildFormatSpecifier(),
7757 FmtExpr, InFunctionCall);
7758 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7759 << 0 <<
Other.Range;
7762 case MK::NoMatchSignedness:
7764 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
7765 << buildFormatSpecifier()
7766 <<
Other.buildFormatSpecifier(),
7767 FmtExpr, InFunctionCall);
7768 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7769 << 0 <<
Other.Range;
7775bool DecomposePrintfHandler::GetSpecifiers(
7776 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7779 StringRef
Data = FSL->getString();
7780 const char *Str =
Data.data();
7781 llvm::SmallBitVector BV;
7782 UncoveredArgHandler UA;
7783 const Expr *PrintfArgs[] = {FSL->getFormatString()};
7784 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
7796 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
7797 const EquatableFormatArgument &B) {
7798 return A.getPosition() < B.getPosition();
7803bool DecomposePrintfHandler::HandlePrintfSpecifier(
7806 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
7816 const auto &CS = FS.getConversionSpecifier();
7821 const unsigned Unset = ~0;
7822 unsigned FieldWidthIndex = Unset;
7823 unsigned PrecisionIndex = Unset;
7826 const auto &FieldWidth = FS.getFieldWidth();
7827 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
7828 FieldWidthIndex = Specs.size();
7829 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
7830 getLocationOfByte(FieldWidth.getStart()),
7832 FieldWidth.getArgType(S.
Context),
7833 EquatableFormatArgument::FAR_FieldWidth,
7834 EquatableFormatArgument::SS_None,
7835 FieldWidth.usesPositionalArg()
7836 ? FieldWidth.getPositionalArgIndex() - 1
7841 const auto &Precision = FS.getPrecision();
7842 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
7843 PrecisionIndex = Specs.size();
7845 getSpecifierRange(startSpecifier, specifierLen),
7846 getLocationOfByte(Precision.getStart()),
7848 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
7849 EquatableFormatArgument::SS_None,
7850 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
7856 unsigned SpecIndex =
7857 FS.usesPositionalArg() ? FS.getPositionalArgIndex() - 1 : Specs.size();
7858 if (FieldWidthIndex != Unset)
7859 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
7860 if (PrecisionIndex != Unset)
7861 Specs[PrecisionIndex].setModifierFor(SpecIndex);
7863 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
7865 Sensitivity = EquatableFormatArgument::SS_Private;
7866 else if (FS.isPublic())
7867 Sensitivity = EquatableFormatArgument::SS_Public;
7868 else if (FS.isSensitive())
7869 Sensitivity = EquatableFormatArgument::SS_Sensitive;
7871 Sensitivity = EquatableFormatArgument::SS_None;
7874 getSpecifierRange(startSpecifier, specifierLen),
7875 getLocationOfByte(CS.
getStart()), FS.getLengthModifier().getKind(),
7877 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
7882 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
7887 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
7888 SpecIndex + 1, SpecIndex);
7896template<
typename MemberKind>
7914 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
7928 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
7929 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7931 if ((*MI)->getMinRequiredArguments() == 0)
7939bool CheckPrintfHandler::checkForCStrMembers(
7944 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
7946 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7949 if (
Method->getMinRequiredArguments() == 0 &&
7962bool CheckPrintfHandler::HandlePrintfSpecifier(
7965 using namespace analyze_format_string;
7966 using namespace analyze_printf;
7968 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
7970 if (FS.consumesDataArgument()) {
7973 usesPositionalArgs = FS.usesPositionalArg();
7975 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7976 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7977 startSpecifier, specifierLen);
7984 if (!HandleAmount(FS.getFieldWidth(), 0,
7985 startSpecifier, specifierLen)) {
7989 if (!HandleAmount(FS.getPrecision(), 1,
7990 startSpecifier, specifierLen)) {
7994 if (!CS.consumesDataArgument()) {
8001 unsigned argIndex = FS.getArgIndex();
8002 if (argIndex < NumDataArgs) {
8006 CoveredArgs.set(argIndex);
8010 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
8011 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
8013 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8016 if (HasFormatArguments()) {
8018 CoveredArgs.set(argIndex + 1);
8021 const Expr *Ex = getDataArg(argIndex);
8023 (CS.getKind() == ConversionSpecifier::FreeBSDbArg)
8025 : ArgType::CPointerTy;
8027 EmitFormatDiagnostic(
8028 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8032 getSpecifierRange(startSpecifier, specifierLen));
8035 Ex = getDataArg(argIndex + 1);
8038 EmitFormatDiagnostic(
8039 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8043 getSpecifierRange(startSpecifier, specifierLen));
8050 if (!allowsObjCArg() && CS.isObjCArg()) {
8051 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8057 CS.getKind() == ConversionSpecifier::PArg) {
8058 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8064 CS.getKind() == ConversionSpecifier::nArg) {
8065 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8066 getLocationOfByte(CS.getStart()),
8068 getSpecifierRange(startSpecifier, specifierLen));
8075 (CS.getKind() == ConversionSpecifier::PArg ||
8076 CS.getKind() == ConversionSpecifier::sArg ||
8077 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
8078 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8084 if (FS.isPublic().isSet()) {
8085 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8087 getLocationOfByte(FS.isPublic().getPosition()),
8089 getSpecifierRange(startSpecifier, specifierLen));
8091 if (FS.isPrivate().isSet()) {
8092 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8094 getLocationOfByte(FS.isPrivate().getPosition()),
8096 getSpecifierRange(startSpecifier, specifierLen));
8100 const llvm::Triple &Triple =
Target.getTriple();
8101 if (CS.getKind() == ConversionSpecifier::nArg &&
8102 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8103 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8104 getLocationOfByte(CS.getStart()),
8106 getSpecifierRange(startSpecifier, specifierLen));
8110 if (!FS.hasValidFieldWidth()) {
8111 HandleInvalidAmount(FS, FS.getFieldWidth(), 0,
8112 startSpecifier, specifierLen);
8116 if (!FS.hasValidPrecision()) {
8117 HandleInvalidAmount(FS, FS.getPrecision(), 1,
8118 startSpecifier, specifierLen);
8122 if (CS.getKind() == ConversionSpecifier::PArg &&
8123 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
8124 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8125 getLocationOfByte(startSpecifier),
8127 getSpecifierRange(startSpecifier, specifierLen));
8131 if (!FS.hasValidThousandsGroupingPrefix())
8132 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
8133 if (!FS.hasValidLeadingZeros())
8134 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
8135 if (!FS.hasValidPlusPrefix())
8136 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
8137 if (!FS.hasValidSpacePrefix())
8138 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
8139 if (!FS.hasValidAlternativeForm())
8140 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
8141 if (!FS.hasValidLeftJustified())
8142 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
8145 if (FS.hasSpacePrefix() && FS.hasPlusPrefix())
8146 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
8147 startSpecifier, specifierLen);
8148 if (FS.hasLeadingZeros() && FS.isLeftJustified())
8149 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
8150 startSpecifier, specifierLen);
8155 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8156 diag::warn_format_nonsensical_length);
8157 else if (!FS.hasStandardLengthModifier())
8158 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8159 else if (!FS.hasStandardLengthConversionCombination())
8160 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8161 diag::warn_format_non_standard_conversion_spec);
8163 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
8164 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8167 if (!HasFormatArguments())
8170 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8173 const Expr *Arg = getDataArg(argIndex);
8177 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8189 case Stmt::ArraySubscriptExprClass:
8190 case Stmt::CallExprClass:
8191 case Stmt::CharacterLiteralClass:
8192 case Stmt::CXXBoolLiteralExprClass:
8193 case Stmt::DeclRefExprClass:
8194 case Stmt::FloatingLiteralClass:
8195 case Stmt::IntegerLiteralClass:
8196 case Stmt::MemberExprClass:
8197 case Stmt::ObjCArrayLiteralClass:
8198 case Stmt::ObjCBoolLiteralExprClass:
8199 case Stmt::ObjCBoxedExprClass:
8200 case Stmt::ObjCDictionaryLiteralClass:
8201 case Stmt::ObjCEncodeExprClass:
8202 case Stmt::ObjCIvarRefExprClass:
8203 case Stmt::ObjCMessageExprClass:
8204 case Stmt::ObjCPropertyRefExprClass:
8205 case Stmt::ObjCStringLiteralClass:
8206 case Stmt::ObjCSubscriptRefExprClass:
8207 case Stmt::ParenExprClass:
8208 case Stmt::StringLiteralClass:
8209 case Stmt::UnaryOperatorClass:
8216static std::pair<QualType, StringRef>
8223 StringRef Name = UserTy->getDecl()->getName();
8224 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8228 .Case(
"SInt32", Context.
IntTy)
8233 return std::make_pair(CastTy, Name);
8235 TyTy = UserTy->desugar();
8239 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(
E))
8241 PE->getSubExpr()->getType(),
8250 StringRef TrueName, FalseName;
8252 std::tie(TrueTy, TrueName) =
8254 CO->getTrueExpr()->getType(),
8256 std::tie(FalseTy, FalseName) =
8258 CO->getFalseExpr()->getType(),
8259 CO->getFalseExpr());
8261 if (TrueTy == FalseTy)
8262 return std::make_pair(TrueTy, TrueName);
8263 else if (TrueTy.
isNull())
8264 return std::make_pair(FalseTy, FalseName);
8265 else if (FalseTy.
isNull())
8266 return std::make_pair(TrueTy, TrueName);
8269 return std::make_pair(
QualType(), StringRef());
8288 From = VecTy->getElementType();
8290 To = VecTy->getElementType();
8301 diag::warn_format_conversion_argument_type_mismatch_signedness,
8305 diag::warn_format_conversion_argument_type_mismatch,
Loc)) {
8314 const char *StartSpecifier,
8315 unsigned SpecifierLen,
8317 using namespace analyze_format_string;
8318 using namespace analyze_printf;
8327 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8328 ExprTy = TET->getUnderlyingExpr()->getType();
8340 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
8343 getSpecifierRange(StartSpecifier, SpecifierLen);
8345 llvm::raw_svector_ostream os(FSString);
8347 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8355 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
8358 getSpecifierRange(StartSpecifier, SpecifierLen);
8359 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8364 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
8366 ArgType::MatchKind OrigMatch =
Match;
8369 if (
Match == ArgType::Match)
8373 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8382 E = ICE->getSubExpr();
8392 if (OrigMatch == ArgType::NoMatchSignedness &&
8393 ImplicitMatch != ArgType::NoMatchSignedness)
8400 if (ImplicitMatch == ArgType::Match)
8411 FS.getLengthModifier().getKind() != LengthModifier::AsChar)
8418 if (
Match == ArgType::MatchPromotion)
8419 Match = ArgType::NoMatch;
8422 if (
Match == ArgType::MatchPromotion) {
8426 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8427 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8429 Match = ArgType::NoMatch;
8431 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8432 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8433 Match = ImplicitMatch;
8434 assert(
Match != ArgType::MatchPromotion);
8437 bool IsEnum =
false;
8438 bool IsScopedEnum =
false;
8441 IntendedTy = ED->getIntegerType();
8442 if (!ED->isScoped()) {
8443 ExprTy = IntendedTy;
8448 IsScopedEnum =
true;
8455 if (isObjCContext() &&
8456 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
8466 const llvm::APInt &
V = IL->getValue();
8476 if (TD->getUnderlyingType() == IntendedTy)
8486 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8494 if (!IsScopedEnum &&
8495 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8498 Match = ArgType::NoMatchPedantic;
8499 IntendedTy = CastTy;
8500 ShouldNotPrintDirectly =
true;
8505 PrintfSpecifier fixedFS = FS;
8512 llvm::raw_svector_ostream os(buf);
8513 fixedFS.toString(os);
8515 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8517 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8520 case ArgType::Match:
8521 case ArgType::MatchPromotion:
8522 case ArgType::NoMatchPromotionTypeConfusion:
8523 llvm_unreachable(
"expected non-matching");
8524 case ArgType::NoMatchSignedness:
8525 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8527 case ArgType::NoMatchPedantic:
8528 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8530 case ArgType::NoMatchTypeConfusion:
8531 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8533 case ArgType::NoMatch:
8534 Diag = diag::warn_format_conversion_argument_type_mismatch;
8555 llvm::raw_svector_ostream CastFix(CastBuf);
8556 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
8558 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
8564 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
8569 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
8591 if (ShouldNotPrintDirectly && !IsScopedEnum) {
8597 Name = TypedefTy->getDecl()->getName();
8600 unsigned Diag =
Match == ArgType::NoMatchPedantic
8601 ? diag::warn_format_argument_needs_cast_pedantic
8602 : diag::warn_format_argument_needs_cast;
8603 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
8614 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8615 : diag::warn_format_conversion_argument_type_mismatch;
8617 EmitFormatDiagnostic(
8629 bool EmitTypeMismatch =
false;
8635 case ArgType::Match:
8636 case ArgType::MatchPromotion:
8637 case ArgType::NoMatchPromotionTypeConfusion:
8638 case ArgType::NoMatchSignedness:
8639 llvm_unreachable(
"expected non-matching");
8640 case ArgType::NoMatchPedantic:
8641 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8643 case ArgType::NoMatchTypeConfusion:
8644 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8646 case ArgType::NoMatch:
8647 Diag = diag::warn_format_conversion_argument_type_mismatch;
8651 EmitFormatDiagnostic(
8660 EmitTypeMismatch =
true;
8662 EmitFormatDiagnostic(
8663 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
8664 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8668 checkForCStrMembers(AT,
E);
8674 EmitTypeMismatch =
true;
8676 EmitFormatDiagnostic(
8677 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
8678 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8686 << isa<InitListExpr>(
E) << ExprTy << CallType
8691 if (EmitTypeMismatch) {
8697 EmitFormatDiagnostic(
8698 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8704 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
8705 "format string specifier index out of range");
8706 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
8716class CheckScanfHandler :
public CheckFormatHandler {
8718 CheckScanfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
8720 unsigned firstDataArg,
unsigned numDataArgs,
8724 llvm::SmallBitVector &CheckedVarArgs,
8725 UncoveredArgHandler &UncoveredArg)
8726 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8727 numDataArgs, beg, APK, Args, formatIdx,
8728 inFunctionCall, CallType, CheckedVarArgs,
8732 const char *startSpecifier,
8733 unsigned specifierLen)
override;
8735 bool HandleInvalidScanfConversionSpecifier(
8737 const char *startSpecifier,
8738 unsigned specifierLen)
override;
8740 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
8745void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
8747 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
8748 getLocationOfByte(end),
true,
8749 getSpecifierRange(start, end - start));
8752bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
8754 const char *startSpecifier,
8755 unsigned specifierLen) {
8757 FS.getConversionSpecifier();
8759 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
8761 startSpecifier, specifierLen,
8765bool CheckScanfHandler::HandleScanfSpecifier(
8767 const char *startSpecifier,
8768 unsigned specifierLen) {
8769 using namespace analyze_scanf;
8770 using namespace analyze_format_string;
8772 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
8776 if (FS.consumesDataArgument()) {
8779 usesPositionalArgs = FS.usesPositionalArg();
8781 else if (usesPositionalArgs != FS.usesPositionalArg()) {
8782 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8783 startSpecifier, specifierLen);
8789 const OptionalAmount &Amt = FS.getFieldWidth();
8790 if (Amt.getHowSpecified() == OptionalAmount::Constant) {
8791 if (Amt.getConstantAmount() == 0) {
8793 Amt.getConstantLength());
8794 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
8795 getLocationOfByte(Amt.getStart()),
8801 if (!FS.consumesDataArgument()) {
8808 unsigned argIndex = FS.getArgIndex();
8809 if (argIndex < NumDataArgs) {
8813 CoveredArgs.set(argIndex);
8819 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8820 diag::warn_format_nonsensical_length);
8821 else if (!FS.hasStandardLengthModifier())
8822 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8823 else if (!FS.hasStandardLengthConversionCombination())
8824 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8825 diag::warn_format_non_standard_conversion_spec);
8827 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
8828 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8831 if (!HasFormatArguments())
8834 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8838 const Expr *Ex = getDataArg(argIndex);
8856 ScanfSpecifier fixedFS = FS;
8861 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8863 ? diag::warn_format_conversion_argument_type_mismatch_signedness
8864 : diag::warn_format_conversion_argument_type_mismatch;
8869 llvm::raw_svector_ostream os(buf);
8870 fixedFS.toString(os);
8872 EmitFormatDiagnostic(
8877 getSpecifierRange(startSpecifier, specifierLen),
8879 getSpecifierRange(startSpecifier, specifierLen), os.str()));
8886 getSpecifierRange(startSpecifier, specifierLen));
8896 const Expr *FmtExpr,
bool InFunctionCall) {
8897 bool HadError =
false;
8898 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
8899 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
8900 while (FmtIter < FmtEnd && RefIter < RefEnd) {
8912 for (; FmtIter < FmtEnd; ++FmtIter) {
8916 if (FmtIter->getPosition() < RefIter->getPosition())
8920 if (FmtIter->getPosition() > RefIter->getPosition())
8924 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
8928 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
8929 return Arg.getPosition() != RefIter->getPosition();
8933 if (FmtIter < FmtEnd) {
8934 CheckFormatHandler::EmitFormatDiagnostic(
8935 S, InFunctionCall, FmtExpr,
8936 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
8937 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
8938 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
8939 }
else if (RefIter < RefEnd) {
8940 CheckFormatHandler::EmitFormatDiagnostic(
8941 S, InFunctionCall, FmtExpr,
8942 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
8945 << 1 << RefIter->getSourceRange();
8951 Sema &S,
const FormatStringLiteral *FExpr,
8956 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
8957 bool IgnoreStringsWithoutSpecifiers) {
8959 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
8960 CheckFormatHandler::EmitFormatDiagnostic(
8961 S, inFunctionCall, Args[format_idx],
8962 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
8968 StringRef StrRef = FExpr->getString();
8969 const char *Str = StrRef.data();
8973 assert(
T &&
"String literal not of constant array type!");
8974 size_t TypeSize =
T->getZExtSize();
8975 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8976 const unsigned numDataArgs = Args.size() - firstDataArg;
8978 if (IgnoreStringsWithoutSpecifiers &&
8985 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
8986 CheckFormatHandler::EmitFormatDiagnostic(
8987 S, inFunctionCall, Args[format_idx],
8988 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
8989 FExpr->getBeginLoc(),
8995 if (StrLen == 0 && numDataArgs > 0) {
8996 CheckFormatHandler::EmitFormatDiagnostic(
8997 S, inFunctionCall, Args[format_idx],
8998 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9010 if (ReferenceFormatString ==
nullptr) {
9011 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9012 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9013 inFunctionCall, CallType, CheckedVarArgs,
9023 Type, ReferenceFormatString, FExpr->getFormatString(),
9024 inFunctionCall ?
nullptr : Args[format_idx]);
9027 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9028 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9029 CallType, CheckedVarArgs, UncoveredArg);
9050 FormatStringLiteral RefLit = AuthoritativeFormatString;
9051 FormatStringLiteral TestLit = TestedFormatString;
9053 bool DiagAtStringLiteral;
9054 if (FunctionCallArg) {
9055 Arg = FunctionCallArg;
9056 DiagAtStringLiteral =
false;
9058 Arg = TestedFormatString;
9059 DiagAtStringLiteral =
true;
9061 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9062 AuthoritativeFormatString,
Type,
9063 IsObjC,
true, RefArgs) &&
9064 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9065 DiagAtStringLiteral, FmtArgs)) {
9067 TestedFormatString, FmtArgs, Arg,
9068 DiagAtStringLiteral);
9082 FormatStringLiteral RefLit = Str;
9086 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9095 bool HadError =
false;
9096 auto Iter = Args.begin();
9097 auto End = Args.end();
9098 while (
Iter != End) {
9099 const auto &FirstInGroup = *
Iter;
9101 Iter != End &&
Iter->getPosition() == FirstInGroup.getPosition();
9103 HadError |= !
Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9112 const char *Str = StrRef.data();
9115 assert(
T &&
"String literal not of constant array type!");
9116 size_t TypeSize =
T->getZExtSize();
9117 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9128 switch (AbsFunction) {
9132 case Builtin::BI__builtin_abs:
9133 return Builtin::BI__builtin_labs;
9134 case Builtin::BI__builtin_labs:
9135 return Builtin::BI__builtin_llabs;
9136 case Builtin::BI__builtin_llabs:
9139 case Builtin::BI__builtin_fabsf:
9140 return Builtin::BI__builtin_fabs;
9141 case Builtin::BI__builtin_fabs:
9142 return Builtin::BI__builtin_fabsl;
9143 case Builtin::BI__builtin_fabsl:
9146 case Builtin::BI__builtin_cabsf:
9147 return Builtin::BI__builtin_cabs;
9148 case Builtin::BI__builtin_cabs:
9149 return Builtin::BI__builtin_cabsl;
9150 case Builtin::BI__builtin_cabsl:
9153 case Builtin::BIabs:
9154 return Builtin::BIlabs;
9155 case Builtin::BIlabs:
9156 return Builtin::BIllabs;
9157 case Builtin::BIllabs:
9160 case Builtin::BIfabsf:
9161 return Builtin::BIfabs;
9162 case Builtin::BIfabs:
9163 return Builtin::BIfabsl;
9164 case Builtin::BIfabsl:
9167 case Builtin::BIcabsf:
9168 return Builtin::BIcabs;
9169 case Builtin::BIcabs:
9170 return Builtin::BIcabsl;
9171 case Builtin::BIcabsl:
9200 unsigned AbsFunctionKind) {
9201 unsigned BestKind = 0;
9203 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9209 else if (Context.
hasSameType(ParamType, ArgType)) {
9232 llvm_unreachable(
"Type not integer, floating, or complex");
9239 switch (ValueKind) {
9244 case Builtin::BI__builtin_fabsf:
9245 case Builtin::BI__builtin_fabs:
9246 case Builtin::BI__builtin_fabsl:
9247 case Builtin::BI__builtin_cabsf:
9248 case Builtin::BI__builtin_cabs:
9249 case Builtin::BI__builtin_cabsl:
9250 return Builtin::BI__builtin_abs;
9251 case Builtin::BIfabsf:
9252 case Builtin::BIfabs:
9253 case Builtin::BIfabsl:
9254 case Builtin::BIcabsf:
9255 case Builtin::BIcabs:
9256 case Builtin::BIcabsl:
9257 return Builtin::BIabs;
9263 case Builtin::BI__builtin_abs:
9264 case Builtin::BI__builtin_labs:
9265 case Builtin::BI__builtin_llabs:
9266 case Builtin::BI__builtin_cabsf:
9267 case Builtin::BI__builtin_cabs:
9268 case Builtin::BI__builtin_cabsl:
9269 return Builtin::BI__builtin_fabsf;
9270 case Builtin::BIabs:
9271 case Builtin::BIlabs:
9272 case Builtin::BIllabs:
9273 case Builtin::BIcabsf:
9274 case Builtin::BIcabs:
9275 case Builtin::BIcabsl:
9276 return Builtin::BIfabsf;
9282 case Builtin::BI__builtin_abs:
9283 case Builtin::BI__builtin_labs:
9284 case Builtin::BI__builtin_llabs:
9285 case Builtin::BI__builtin_fabsf:
9286 case Builtin::BI__builtin_fabs:
9287 case Builtin::BI__builtin_fabsl:
9288 return Builtin::BI__builtin_cabsf;
9289 case Builtin::BIabs:
9290 case Builtin::BIlabs:
9291 case Builtin::BIllabs:
9292 case Builtin::BIfabsf:
9293 case Builtin::BIfabs:
9294 case Builtin::BIfabsl:
9295 return Builtin::BIcabsf;
9298 llvm_unreachable(
"Unable to convert function");
9309 case Builtin::BI__builtin_abs:
9310 case Builtin::BI__builtin_fabs:
9311 case Builtin::BI__builtin_fabsf:
9312 case Builtin::BI__builtin_fabsl:
9313 case Builtin::BI__builtin_labs:
9314 case Builtin::BI__builtin_llabs:
9315 case Builtin::BI__builtin_cabs:
9316 case Builtin::BI__builtin_cabsf:
9317 case Builtin::BI__builtin_cabsl:
9318 case Builtin::BIabs:
9319 case Builtin::BIlabs:
9320 case Builtin::BIllabs:
9321 case Builtin::BIfabs:
9322 case Builtin::BIfabsf:
9323 case Builtin::BIfabsl:
9324 case Builtin::BIcabs:
9325 case Builtin::BIcabsf:
9326 case Builtin::BIcabsl:
9329 llvm_unreachable(
"Unknown Builtin type");
9335 unsigned AbsKind,
QualType ArgType) {
9336 bool EmitHeaderHint =
true;
9337 const char *HeaderName =
nullptr;
9338 std::string FunctionName;
9340 FunctionName =
"std::abs";
9342 HeaderName =
"cstdlib";
9344 HeaderName =
"cmath";
9346 llvm_unreachable(
"Invalid Type");
9355 for (
const auto *I : R) {
9358 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9360 FDecl = dyn_cast<FunctionDecl>(I);
9375 EmitHeaderHint =
false;
9393 EmitHeaderHint =
false;
9397 }
else if (!R.
empty()) {
9403 S.
Diag(
Loc, diag::note_replace_abs_function)
9409 if (!EmitHeaderHint)
9412 S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
9416template <std::
size_t StrLen>
9418 const char (&Str)[StrLen]) {
9431 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9432 return llvm::is_contained(names, calleeName);
9436 case MathCheck::NaN:
9437 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9438 "__builtin_nanf16",
"__builtin_nanf128"});
9439 case MathCheck::Inf:
9440 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9441 "__builtin_inff16",
"__builtin_inff128"});
9443 llvm_unreachable(
"unknown MathCheck");
9447 if (FDecl->
getName() !=
"infinity")
9450 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9452 if (RDecl->
getName() !=
"numeric_limits")
9469 if (FPO.getNoHonorNaNs() &&
9472 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9473 << 1 << 0 <<
Call->getSourceRange();
9477 if (FPO.getNoHonorInfs() &&
9481 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9482 << 0 << 0 <<
Call->getSourceRange();
9486void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9488 if (
Call->getNumArgs() != 1)
9493 if (AbsKind == 0 && !IsStdAbs)
9496 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9502 std::string FunctionName =
9504 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9505 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9534 if (ArgValueKind == ParamValueKind) {
9539 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9540 << FDecl << ArgType << ParamType;
9542 if (NewAbsKind == 0)
9546 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9555 if (NewAbsKind == 0)
9558 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
9559 << FDecl << ParamValueKind << ArgValueKind;
9562 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9568 if (!
Call || !FDecl)
return;
9572 if (
Call->getExprLoc().isMacroID())
return;
9575 if (
Call->getNumArgs() != 2)
return;
9578 if (!ArgList)
return;
9579 if (ArgList->size() != 1)
return;
9582 const auto& TA = ArgList->
get(0);
9588 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
9589 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
9590 if (!MTE)
return false;
9591 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
9592 if (!
Num)
return false;
9593 if (
Num->getValue() != 0)
return false;
9597 const Expr *FirstArg =
Call->getArg(0);
9598 const Expr *SecondArg =
Call->getArg(1);
9599 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
9600 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
9603 if (IsFirstArgZero == IsSecondArgZero)
return;
9608 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
9610 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
9611 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
9615 if (IsFirstArgZero) {
9623 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
9638 const auto *Size = dyn_cast<BinaryOperator>(
E);
9643 if (!Size->isComparisonOp() && !Size->isLogicalOp())
9647 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
9648 << SizeRange << FnName;
9649 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
9654 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
9665 bool &IsContained) {
9668 IsContained =
false;
9681 for (
auto *FD : RD->
fields()) {
9694 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
9695 if (Unary->getKind() == UETT_SizeOf)
9704 if (!
SizeOf->isArgumentType())
9705 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
9712 return SizeOf->getTypeOfArgument();
9718struct SearchNonTrivialToInitializeField
9723 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
9727 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9728 asDerived().visitArray(PDIK, AT, SL);
9732 Super::visitWithKind(PDIK, FT, SL);
9747 visit(getContext().getBaseElementType(AT), SL);
9752 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
9761struct SearchNonTrivialToCopyField
9765 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
9769 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9770 asDerived().visitArray(PCK, AT, SL);
9774 Super::visitWithKind(PCK, FT, SL);
9792 visit(getContext().getBaseElementType(AT), SL);
9815 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
9816 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
9840 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
9842 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
9843 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
9849 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
9852 const Expr *SizeArg =
9853 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
9855 auto isLiteralZero = [](
const Expr *
E) {
9856 return (isa<IntegerLiteral>(
E) &&
9857 cast<IntegerLiteral>(
E)->getValue() == 0) ||
9858 (isa<CharacterLiteral>(
E) &&
9859 cast<CharacterLiteral>(
E)->getValue() == 0);
9865 if (isLiteralZero(SizeArg) &&
9872 if (BId == Builtin::BIbzero ||
9875 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
9876 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
9877 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
9878 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
9879 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
9887 if (BId == Builtin::BImemset &&
9891 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
9892 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
9897void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
9904 unsigned ExpectedNumArgs =
9905 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
9906 if (
Call->getNumArgs() < ExpectedNumArgs)
9909 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
9910 BId == Builtin::BIstrndup ? 1 : 2);
9912 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
9913 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
9916 Call->getBeginLoc(),
Call->getRParenLoc()))
9925 llvm::FoldingSetNodeID SizeOfArgID;
9930 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9934 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
9935 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
9957 if (SizeOfArgID == llvm::FoldingSetNodeID())
9959 llvm::FoldingSetNodeID DestID;
9961 if (DestID == SizeOfArgID) {
9964 unsigned ActionIdx = 0;
9965 StringRef ReadableName = FnName->
getName();
9967 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
9968 if (UnaryOp->getOpcode() == UO_AddrOf)
9982 if (
SM.isMacroArgExpansion(SL)) {
9984 SL =
SM.getSpellingLoc(SL);
9992 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
9999 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10014 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10015 << FnName << SizeOfArgTy << ArgIdx
10022 PointeeTy = DestTy;
10033 unsigned OperationType = 0;
10034 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10037 if (ArgIdx != 0 || IsCmp) {
10038 if (BId == Builtin::BImemcpy)
10040 else if(BId == Builtin::BImemmove)
10047 PDiag(diag::warn_dyn_class_memaccess)
10048 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10049 << IsContained << ContainedRD << OperationType
10050 <<
Call->getCallee()->getSourceRange());
10052 BId != Builtin::BImemset)
10055 PDiag(diag::warn_arc_object_memaccess)
10056 << ArgIdx << FnName << PointeeTy
10057 <<
Call->getCallee()->getSourceRange());
10064 bool NonTriviallyCopyableCXXRecord =
10068 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10071 PDiag(diag::warn_cstruct_memaccess)
10072 << ArgIdx << FnName << PointeeTy << 0);
10073 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10074 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10075 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10079 PDiag(diag::warn_cxxstruct_memaccess)
10080 << FnName << PointeeTy);
10081 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10084 PDiag(diag::warn_cstruct_memaccess)
10085 << ArgIdx << FnName << PointeeTy << 1);
10086 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10087 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10088 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10092 PDiag(diag::warn_cxxstruct_memaccess)
10093 << FnName << PointeeTy);
10102 PDiag(diag::note_bad_memaccess_silence)
10122 if (isa<IntegerLiteral>(RHS))
10124 else if (isa<IntegerLiteral>(LHS))
10138 if (CAT->getZExtSize() <= 1)
10146void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10150 unsigned NumArgs =
Call->getNumArgs();
10151 if ((NumArgs != 3) && (NumArgs != 4))
10156 const Expr *CompareWithSrc =
nullptr;
10159 Call->getBeginLoc(),
Call->getRParenLoc()))
10164 CompareWithSrc = Ex;
10167 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10168 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10169 SizeCall->getNumArgs() == 1)
10174 if (!CompareWithSrc)
10181 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10185 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10186 if (!CompareWithSrcDRE ||
10190 const Expr *OriginalSizeArg =
Call->getArg(2);
10191 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10198 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10203 llvm::raw_svector_ostream
OS(sizeString);
10208 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10215 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10216 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10217 return D1->getDecl() == D2->getDecl();
10222 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
10231void Sema::CheckStrncatArguments(
const CallExpr *CE,
10246 unsigned PatternType = 0;
10254 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10255 if (BE->getOpcode() == BO_Sub) {
10268 if (PatternType == 0)
10277 if (
SM.isMacroArgExpansion(SL)) {
10278 SL =
SM.getSpellingLoc(SL);
10287 if (!isKnownSizeArray) {
10288 if (PatternType == 1)
10289 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10291 Diag(SL, diag::warn_strncat_src_size) << SR;
10295 if (PatternType == 1)
10296 Diag(SL, diag::warn_strncat_large_size) << SR;
10298 Diag(SL, diag::warn_strncat_src_size) << SR;
10301 llvm::raw_svector_ostream
OS(sizeString);
10309 Diag(SL, diag::note_strncat_wrong_size)
10314void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10316 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
10318 << CalleeName << 0 << cast<NamedDecl>(
D);
10323void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10325 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10326 const Decl *
D = Lvalue->getDecl();
10327 if (
const auto *DD = dyn_cast<DeclaratorDecl>(
D)) {
10328 if (!DD->getType()->isReferenceType())
10329 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
10333 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10334 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10335 Lvalue->getMemberDecl());
10338void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10340 const auto *Lambda = dyn_cast<LambdaExpr>(
10345 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10346 << CalleeName << 2 ;
10349void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10351 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10352 if (Var ==
nullptr)
10356 << CalleeName << 0 << Var;
10359void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10362 llvm::raw_svector_ostream OS(SizeString);
10365 if (Kind == clang::CK_BitCast &&
10366 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10368 if (Kind == clang::CK_IntegralToPointer &&
10369 !isa<IntegerLiteral>(
10370 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10373 switch (
Cast->getCastKind()) {
10374 case clang::CK_BitCast:
10375 case clang::CK_IntegralToPointer:
10376 case clang::CK_FunctionToPointerDecay:
10385 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10386 << CalleeName << 0 << OS.str();
10390void Sema::CheckFreeArguments(
const CallExpr *
E) {
10391 const std::string CalleeName =
10392 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
10396 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10398 case UnaryOperator::Opcode::UO_AddrOf:
10399 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10400 case UnaryOperator::Opcode::UO_Plus:
10401 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10406 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10408 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10410 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
10411 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
10412 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
10416 if (isa<BlockExpr>(Arg)) {
10418 << CalleeName << 1 ;
10423 if (
const auto *Cast = dyn_cast<CastExpr>(
E->getArg(0)))
10424 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10428Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10434 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
10437 Diag(ReturnLoc, diag::warn_null_ret)
10447 if (Op == OO_New || Op == OO_Array_New) {
10452 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10458 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10475 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10476 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10478 return FPLiteral && FPCast;
10481 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10487 llvm::APFloat TargetC = FPLiteral->
getValue();
10489 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10493 Diag(
Loc, diag::warn_float_compare_literal)
10494 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10507 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10508 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10509 if (DRL->getDecl() == DRR->getDecl())
10517 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10518 if (FLL->isExact())
10520 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10521 if (FLR->isExact())
10525 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10526 CL &&
CL->getBuiltinCallee())
10529 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10530 CR && CR->getBuiltinCallee())
10534 Diag(
Loc, diag::warn_floatingpoint_eq)
10555 IntRange(
unsigned Width,
bool NonNegative)
10556 : Width(Width), NonNegative(NonNegative) {}
10559 unsigned valueBits()
const {
10560 return NonNegative ? Width : Width - 1;
10564 static IntRange forBoolType() {
10565 return IntRange(1,
true);
10570 return forValueOfCanonicalType(
C,
10578 if (
const auto *VT = dyn_cast<VectorType>(
T))
10579 T = VT->getElementType().getTypePtr();
10580 if (
const auto *CT = dyn_cast<ComplexType>(
T))
10581 T = CT->getElementType().getTypePtr();
10582 if (
const auto *AT = dyn_cast<AtomicType>(
T))
10583 T = AT->getValueType().getTypePtr();
10585 if (!
C.getLangOpts().CPlusPlus) {
10588 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
10593 if (
Enum->isFixed()) {
10594 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
10595 !
Enum->getIntegerType()->isSignedIntegerType());
10598 unsigned NumPositive =
Enum->getNumPositiveBits();
10599 unsigned NumNegative =
Enum->getNumNegativeBits();
10601 if (NumNegative == 0)
10602 return IntRange(NumPositive,
true);
10604 return IntRange(std::max(NumPositive + 1, NumNegative),
10608 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10609 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10625 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
10626 T = VT->getElementType().getTypePtr();
10628 T = CT->getElementType().getTypePtr();
10629 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
10630 T = AT->getValueType().getTypePtr();
10632 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
10634 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10635 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10644 static IntRange join(IntRange L, IntRange R) {
10645 bool Unsigned = L.NonNegative && R.NonNegative;
10646 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
10647 L.NonNegative && R.NonNegative);
10651 static IntRange bit_and(IntRange L, IntRange R) {
10652 unsigned Bits = std::max(L.Width, R.Width);
10653 bool NonNegative =
false;
10654 if (L.NonNegative) {
10655 Bits = std::min(Bits, L.Width);
10656 NonNegative =
true;
10658 if (R.NonNegative) {
10659 Bits = std::min(Bits, R.Width);
10660 NonNegative =
true;
10662 return IntRange(Bits, NonNegative);
10666 static IntRange sum(IntRange L, IntRange R) {
10667 bool Unsigned = L.NonNegative && R.NonNegative;
10668 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
10673 static IntRange difference(IntRange L, IntRange R) {
10677 bool CanWiden = !L.NonNegative || !R.NonNegative;
10678 bool Unsigned = L.NonNegative && R.Width == 0;
10679 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
10685 static IntRange product(IntRange L, IntRange R) {
10689 bool CanWiden = !L.NonNegative && !R.NonNegative;
10690 bool Unsigned = L.NonNegative && R.NonNegative;
10691 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
10696 static IntRange rem(IntRange L, IntRange R) {
10700 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
10708 if (value.isSigned() && value.isNegative())
10709 return IntRange(value.getSignificantBits(),
false);
10711 if (value.getBitWidth() > MaxWidth)
10712 value = value.trunc(MaxWidth);
10716 return IntRange(value.getActiveBits(),
true);
10720 if (result.
isInt())
10727 R = IntRange::join(R, El);
10735 return IntRange::join(R, I);
10750 Ty = AtomicRHS->getValueType();
10769 bool InConstantContext,
10770 bool Approximate) {
10781 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
10782 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
10786 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
10788 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
10789 CE->getCastKind() == CK_BooleanToSignedIntegral;
10792 if (!isIntegerCast)
10793 return OutputTypeRange;
10796 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
10797 InConstantContext, Approximate);
10799 return std::nullopt;
10802 if (SubRange->Width >= OutputTypeRange.Width)
10803 return OutputTypeRange;
10807 return IntRange(SubRange->Width,
10808 SubRange->NonNegative || OutputTypeRange.NonNegative);
10811 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
10814 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
10816 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
10817 InConstantContext, Approximate);
10822 Expr *TrueExpr = CO->getTrueExpr();
10824 return std::nullopt;
10826 std::optional<IntRange> L =
10829 return std::nullopt;
10831 Expr *FalseExpr = CO->getFalseExpr();
10833 return std::nullopt;
10835 std::optional<IntRange> R =
10838 return std::nullopt;
10840 return IntRange::join(*L, *R);
10843 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
10844 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
10846 switch (BO->getOpcode()) {
10848 llvm_unreachable(
"builtin <=> should have class type");
10859 return IntRange::forBoolType();
10888 Combine = IntRange::bit_and;
10896 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
10897 if (I->getValue() == 1) {
10899 return IntRange(R.Width,
true);
10909 case BO_ShrAssign: {
10911 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
10913 return std::nullopt;
10917 if (std::optional<llvm::APSInt> shift =
10918 BO->getRHS()->getIntegerConstantExpr(
C)) {
10919 if (shift->isNonNegative()) {
10920 if (shift->uge(L->Width))
10921 L->Width = (L->NonNegative ? 0 : 1);
10923 L->Width -= shift->getZExtValue();
10937 Combine = IntRange::sum;
10941 if (BO->getLHS()->getType()->isPointerType())
10944 Combine = IntRange::difference;
10949 Combine = IntRange::product;
10958 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
10960 return std::nullopt;
10963 if (std::optional<llvm::APSInt> divisor =
10964 BO->getRHS()->getIntegerConstantExpr(
C)) {
10965 unsigned log2 = divisor->logBase2();
10966 if (
log2 >= L->Width)
10967 L->Width = (L->NonNegative ? 0 : 1);
10969 L->Width = std::min(L->Width -
log2, MaxWidth);
10977 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
10979 return std::nullopt;
10981 return IntRange(L->Width, L->NonNegative && R->NonNegative);
10985 Combine = IntRange::rem;
10997 unsigned opWidth =
C.getIntWidth(
T);
10999 InConstantContext, Approximate);
11001 return std::nullopt;
11004 InConstantContext, Approximate);
11006 return std::nullopt;
11008 IntRange
C = Combine(*L, *R);
11010 C.Width = std::min(
C.Width, MaxWidth);
11014 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
11015 switch (UO->getOpcode()) {
11018 return IntRange::forBoolType();
11032 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11035 return std::nullopt;
11040 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11050 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11053 return std::nullopt;
11058 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11068 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11069 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11073 return IntRange(BitField->getBitWidthValue(),
11074 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11077 return std::nullopt;
11083 bool InConstantContext,
11084 bool Approximate) {
11093 const llvm::fltSemantics &Src,
11094 const llvm::fltSemantics &Tgt) {
11095 llvm::APFloat truncated = value;
11098 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11099 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11101 return truncated.bitwiseIsEqual(value);
11110 const llvm::fltSemantics &Src,
11111 const llvm::fltSemantics &Tgt) {
11128 bool IsListInit =
false);
11133 if (isa<EnumConstantDecl>(DR->getDecl()))
11143 return MacroName !=
"YES" && MacroName !=
"NO" &&
11144 MacroName !=
"true" && MacroName !=
"false";
11167struct PromotedRange {
11169 llvm::APSInt PromotedMin;
11171 llvm::APSInt PromotedMax;
11173 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11175 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11176 else if (R.Width >= BitWidth && !
Unsigned) {
11180 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11181 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11183 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11184 .extOrTrunc(BitWidth);
11185 PromotedMin.setIsUnsigned(
Unsigned);
11187 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11188 .extOrTrunc(BitWidth);
11189 PromotedMax.setIsUnsigned(
Unsigned);
11194 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11204 InRangeFlag = 0x40,
11207 Min =
LE | InRangeFlag,
11208 InRange = InRangeFlag,
11209 Max =
GE | InRangeFlag,
11212 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11217 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11218 Value.isUnsigned() == PromotedMin.isUnsigned());
11219 if (!isContiguous()) {
11220 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11221 if (
Value.isMinValue())
return Min;
11222 if (
Value.isMaxValue())
return Max;
11223 if (
Value >= PromotedMin)
return InRange;
11224 if (
Value <= PromotedMax)
return InRange;
11228 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11229 case -1:
return Less;
11230 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11232 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11233 case -1:
return InRange;
11234 case 0:
return Max;
11239 llvm_unreachable(
"impossible compare result");
11242 static std::optional<StringRef>
11244 if (Op == BO_Cmp) {
11246 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11248 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11249 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11250 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11251 return std::nullopt;
11258 }
else if (Op == BO_NE) {
11262 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11269 if (Op == BO_GE || Op == BO_LE)
11270 std::swap(TrueFlag, FalseFlag);
11273 return StringRef(
"true");
11275 return StringRef(
"false");
11276 return std::nullopt;
11283 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
11284 if (ICE->getCastKind() != CK_IntegralCast &&
11285 ICE->getCastKind() != CK_NoOp)
11287 E = ICE->getSubExpr();
11296 enum ConstantValueKind {
11301 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11302 return BL->getValue() ? ConstantValueKind::LiteralTrue
11303 : ConstantValueKind::LiteralFalse;
11304 return ConstantValueKind::Miscellaneous;
11309 const llvm::APSInt &
Value,
11310 bool RhsConstant) {
11332 if (!OtherValueRange)
11337 OtherT = AT->getValueType();
11338 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11342 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11348 bool OtherIsBooleanDespiteType =
11350 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11351 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11355 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11356 Value.isUnsigned());
11357 auto Cmp = OtherPromotedValueRange.compare(
Value);
11358 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
11364 bool TautologicalTypeCompare =
false;
11366 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11367 Value.isUnsigned());
11368 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11369 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
11371 TautologicalTypeCompare =
true;
11379 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11388 bool InRange = Cmp & PromotedRange::InRangeFlag;
11394 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11395 Other->getType()->isUnsignedIntegerOrEnumerationType())
11396 TautologicalTypeCompare =
true;
11401 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11402 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11406 llvm::raw_svector_ostream OS(PrettySourceValue);
11408 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11409 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11411 OS << (BL->getValue() ?
"YES" :
"NO");
11416 if (!TautologicalTypeCompare) {
11417 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
11418 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11419 <<
E->getOpcodeStr() << OS.str() << *
Result
11424 if (IsObjCSignedCharBool) {
11426 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11427 << OS.str() << *
Result);
11434 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11437 E->getOperatorLoc(),
E,
11438 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11439 : diag::warn_tautological_bool_compare)
11441 << OtherIsBooleanDespiteType << *
Result
11448 ? diag::warn_unsigned_enum_always_true_comparison
11449 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11450 : diag::warn_unsigned_always_true_comparison)
11451 : diag::warn_tautological_constant_compare;
11454 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result
11484 Expr *LHS =
E->getLHS();
11485 Expr *RHS =
E->getRHS();
11488 std::optional<llvm::APSInt> RHSValue =
11490 std::optional<llvm::APSInt> LHSValue =
11494 if (RHSValue && LHSValue)
11498 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11500 const bool RhsConstant = (
bool)RHSValue;
11501 Expr *Const = RhsConstant ? RHS : LHS;
11503 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11526 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11528 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11534 Expr *signedOperand, *unsignedOperand;
11537 "unsigned comparison between two signed integer expressions?");
11538 signedOperand = LHS;
11539 unsignedOperand = RHS;
11541 signedOperand = RHS;
11542 unsignedOperand = LHS;
11548 std::optional<IntRange> signedRange =
11560 if (signedRange->NonNegative)
11567 if (
E->isEqualityOp()) {
11572 if (!unsignedRange)
11577 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
11579 if (unsignedRange->Width < comparisonWidth)
11584 S.
PDiag(diag::warn_mixed_sign_comparison)
11603 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
11608 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
11609 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
11610 BitfieldEnumDecl->getNumNegativeBits() == 0) {
11611 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
11612 << BitfieldEnumDecl;
11619 Init->isValueDependent() ||
11620 Init->isTypeDependent())
11623 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
11633 const PreferredTypeAttr *PTAttr =
nullptr;
11635 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
11637 ED = PTAttr->getType()->getAsEnumDecl();
11645 bool SignedEnum = ED->getNumNegativeBits() > 0;
11652 unsigned DiagID = 0;
11653 if (SignedEnum && !SignedBitfield) {
11656 ? diag::warn_unsigned_bitfield_assigned_signed_enum
11658 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
11659 }
else if (SignedBitfield && !SignedEnum &&
11660 ED->getNumPositiveBits() == FieldWidth) {
11663 ? diag::warn_signed_bitfield_enum_conversion
11664 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
11667 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11672 << SignedEnum << TypeRange;
11674 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11681 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
11682 ED->getNumNegativeBits())
11683 : ED->getNumPositiveBits();
11686 if (BitsNeeded > FieldWidth) {
11690 ? diag::warn_bitfield_too_small_for_enum
11691 : diag::warn_preferred_type_bitfield_too_small_for_enum;
11692 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11696 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11706 unsigned OriginalWidth =
Value.getBitWidth();
11712 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
11713 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
11720 if (!
Value.isSigned() ||
Value.isNegative())
11721 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
11722 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
11723 OriginalWidth =
Value.getSignificantBits();
11725 if (OriginalWidth <= FieldWidth)
11729 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
11733 TruncatedValue = TruncatedValue.extend(OriginalWidth);
11734 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
11738 std::string PrettyTrunc =
toString(TruncatedValue, 10);
11740 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
11741 ? diag::warn_impcast_single_bit_bitield_precision_constant
11742 : diag::warn_impcast_bitfield_precision_constant)
11743 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
11744 <<
Init->getSourceRange();
11759 E->getOperatorLoc())) {
11762 E->getOperatorLoc());
11776 bool PruneControlFlow =
false) {
11783 if (
T.hasAddressSpace())
11785 if (PruneControlFlow) {
11799 bool PruneControlFlow =
false) {
11811 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
11812 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
11815 bool IsLiteral = isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
11817 llvm::APFloat
Value(0.0);
11823 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
11828 diag::warn_impcast_float_integer, PruneWarnings);
11831 bool isExact =
false;
11835 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
11836 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
11844 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
11845 precision = (precision * 59 + 195) / 196;
11846 Value.toString(PrettySourceValue, precision);
11850 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
11851 << PrettySourceValue);
11854 if (
Result == llvm::APFloat::opOK && isExact) {
11855 if (IsLiteral)
return;
11862 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
11865 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
11866 : diag::warn_impcast_float_to_integer_out_of_range,
11869 unsigned DiagID = 0;
11872 DiagID = diag::warn_impcast_literal_float_to_integer;
11873 }
else if (IntegerValue == 0) {
11874 if (
Value.isZero()) {
11876 diag::warn_impcast_float_integer, PruneWarnings);
11879 DiagID = diag::warn_impcast_float_to_integer_zero;
11881 if (IntegerValue.isUnsigned()) {
11882 if (!IntegerValue.isMaxValue()) {
11884 diag::warn_impcast_float_integer, PruneWarnings);
11887 if (!IntegerValue.isMaxSignedValue() &&
11888 !IntegerValue.isMinSignedValue()) {
11890 diag::warn_impcast_float_integer, PruneWarnings);
11894 DiagID = diag::warn_impcast_float_to_integer;
11899 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
11901 IntegerValue.toString(PrettyTargetValue);
11903 if (PruneWarnings) {
11906 <<
E->
getType() <<
T.getUnqualifiedType()
11907 << PrettySourceValue << PrettyTargetValue
11911 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
11919 assert(isa<CompoundAssignOperator>(
E) &&
11920 "Must be compound assignment operation");
11926 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
11930 const auto *RBT = cast<CompoundAssignOperator>(
E)
11931 ->getComputationResultType()
11938 if (ResultBT->isInteger())
11940 E->
getExprLoc(), diag::warn_impcast_float_integer);
11942 if (!ResultBT->isFloatingPoint())
11951 diag::warn_impcast_float_result_precision);
11956 if (!
Range.Width)
return "0";
11958 llvm::APSInt ValueInRange =
Value;
11959 ValueInRange.setIsSigned(!
Range.NonNegative);
11960 ValueInRange = ValueInRange.trunc(
Range.Width);
11961 return toString(ValueInRange, 10);
11966 if (!isa<ImplicitCastExpr>(Ex))
11971 const Type *Source =
11973 if (
Target->isDependentType())
11976 const auto *FloatCandidateBT =
11977 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
11978 const Type *BoolCandidateType = ToBool ?
Target : Source;
11981 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
11986 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
11992 S, TheCall->
getArg(I - 1),
false));
11994 S, TheCall->
getArg(I + 1),
false));
11999 diag::warn_impcast_floating_point_to_bool);
12007 if (isa<CallExpr>(
E))
12012 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
12014 if (!IsGNUNullExpr && !HasNullPtrType)
12022 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12038 if (MacroName ==
"NULL")
12046 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
12060 const char FirstLiteralCharacter =
12062 if (FirstLiteralCharacter ==
'0')
12069 const char FirstContextCharacter =
12071 if (FirstContextCharacter ==
'{')
12079 const auto *IL = dyn_cast<IntegerLiteral>(
E);
12081 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
12082 if (UO->getOpcode() == UO_Minus)
12083 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12094 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
12098 if (Opc == BO_Shl) {
12101 if (LHS && LHS->getValue() == 0)
12102 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12104 RHS->getValue().isNonNegative() &&
12106 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12107 << (
Result.Val.getInt() != 0);
12109 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12116 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
12121 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12122 (RHS->getValue() == 0 || RHS->getValue() == 1))
12125 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12126 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12139 llvm::APSInt
Value(32);
12141 bool IsASCII =
Value <= 0x7F;
12142 bool IsBMP =
Value <= 0xD7FF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12143 bool ConversionPreservesSemantics =
12146 if (!ConversionPreservesSemantics) {
12147 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12148 const llvm::APSInt &
Value) {
12150 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12152 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12154 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12157 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12166 LosesPrecision ? diag::warn_impcast_unicode_precision
12167 : diag::warn_impcast_unicode_char_type);
12181 From = MaybePointee;
12188 if (FromFn->getCFIUncheckedCalleeAttr() &&
12189 !ToFn->getCFIUncheckedCalleeAttr())
12191 if (!FromFn->getCFIUncheckedCalleeAttr() &&
12192 ToFn->getCFIUncheckedCalleeAttr())
12202 return ::AdjustingCFIUncheckedCallee(From, To) ==
Discarding;
12208 return ::AdjustingCFIUncheckedCallee(From, To) ==
Adding;
12212 bool *ICContext,
bool IsListInit) {
12217 if (Source ==
Target)
return;
12218 if (
Target->isDependentType())
return;
12232 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12233 if (isa<StringLiteral>(
E))
12238 diag::warn_impcast_string_literal_to_bool);
12239 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
12240 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
12244 diag::warn_impcast_objective_c_literal_to_bool);
12259 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12261 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12270 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
12272 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
12276 if (isa<VectorType>(Source)) {
12277 if (
Target->isSveVLSBuiltinType() &&
12284 if (
Target->isRVVVLSBuiltinType() &&
12291 if (!isa<VectorType>(
Target)) {
12301 diag::warn_hlsl_impcast_vector_truncation);
12310 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
12311 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
12313 if (
auto VecTy = dyn_cast<VectorType>(
Target))
12314 Target = VecTy->getElementType().getTypePtr();
12317 if (isa<ComplexType>(Source)) {
12318 if (!isa<ComplexType>(
Target)) {
12324 ? diag::err_impcast_complex_scalar
12325 : diag::warn_impcast_complex_scalar);
12328 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
12329 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
12332 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12341 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12343 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12385 else if (Order < 0) {
12395 if (TargetBT && TargetBT->
isInteger()) {
12410 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
12418 if (isa<ImplicitCastExpr>(LastA) &&
12422 diag::warn_impcast_floating_point_to_bool);
12431 if (
Target->isUnsaturatedFixedPointType()) {
12435 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12440 PDiag(diag::warn_impcast_fixed_point_range)
12441 <<
Value.toString() <<
T
12447 }
else if (
Target->isIntegerType()) {
12451 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12454 llvm::APSInt IntResult = FXResult.convertToInt(
12460 PDiag(diag::warn_impcast_fixed_point_range)
12461 << FXResult.toString() <<
T
12468 }
else if (
Target->isUnsaturatedFixedPointType()) {
12476 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12481 PDiag(diag::warn_impcast_fixed_point_range)
12502 unsigned int SourcePrecision =
SourceRange->Width;
12506 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12509 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12510 SourcePrecision > TargetPrecision) {
12512 if (std::optional<llvm::APSInt> SourceInt =
12517 llvm::APFloat TargetFloatValue(
12519 llvm::APFloat::opStatus ConversionStatus =
12520 TargetFloatValue.convertFromAPInt(
12522 llvm::APFloat::rmNearestTiesToEven);
12524 if (ConversionStatus != llvm::APFloat::opOK) {
12526 SourceInt->toString(PrettySourceValue, 10);
12528 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12532 PDiag(diag::warn_impcast_integer_float_precision_constant)
12533 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
12539 diag::warn_impcast_integer_float_precision);
12553 if (
Target->isBooleanType())
12557 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
12566 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
12572 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
12577 if (!LikelySourceRange)
12580 IntRange SourceTypeRange =
12581 IntRange::forTargetOfCanonicalType(
Context, Source);
12582 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
12584 if (LikelySourceRange->Width > TargetRange.Width) {
12590 llvm::APSInt
Value(32);
12600 PDiag(diag::warn_impcast_integer_precision_constant)
12601 << PrettySourceValue << PrettyTargetValue
12611 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
12612 if (UO->getOpcode() == UO_Minus)
12614 *
this,
E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
12621 diag::warn_impcast_integer_precision);
12624 if (TargetRange.Width > SourceTypeRange.Width) {
12625 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
12626 if (UO->getOpcode() == UO_Minus)
12628 if (
Target->isUnsignedIntegerType())
12630 diag::warn_impcast_high_order_zero_bits);
12631 if (
Target->isSignedIntegerType())
12633 diag::warn_impcast_nonnegative_result);
12637 if (TargetRange.Width == LikelySourceRange->Width &&
12638 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12653 PDiag(diag::warn_impcast_integer_precision_constant)
12654 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
12663 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
12664 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
12665 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12666 LikelySourceRange->Width == TargetRange.Width))) {
12670 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
12676 unsigned DiagID = diag::warn_impcast_integer_sign;
12684 DiagID = diag::warn_impcast_integer_sign_conditional;
12695 if (CoercedSourceBT && CoercedSourceBT->
isInteger() && isa<EnumType>(
Target))
12705 if (SourceEnum->getOriginalDecl()->hasNameForLinkage() &&
12706 TargetEnum->getOriginalDecl()->hasNameForLinkage() &&
12707 SourceEnum != TargetEnum) {
12712 diag::warn_impcast_different_enum_types);
12726 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
12738 Expr *TrueExpr =
E->getTrueExpr();
12739 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
12740 TrueExpr = BCO->getCommon();
12742 bool Suspicious =
false;
12751 if (!Suspicious)
return;
12754 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
12761 Suspicious =
false;
12783struct AnalyzeImplicitConversionsWorkItem {
12792 bool ExtraCheckForImplicitConversion,
12795 WorkList.push_back({
E, CC,
false});
12797 if (ExtraCheckForImplicitConversion &&
E->
getType() !=
T)
12804 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
12806 Expr *OrigE = Item.E;
12819 Item.IsListInit || (isa<InitListExpr>(OrigE) &&
12825 Expr *SourceExpr =
E;
12830 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
12831 if (
auto *Src = OVE->getSourceExpr())
12834 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
12835 if (UO->getOpcode() == UO_Not &&
12836 UO->getSubExpr()->isKnownToHaveBooleanValue())
12837 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
12841 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
12842 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
12843 BO->getLHS()->isKnownToHaveBooleanValue() &&
12844 BO->getRHS()->isKnownToHaveBooleanValue() &&
12845 BO->getLHS()->HasSideEffects(S.
Context) &&
12846 BO->getRHS()->HasSideEffects(S.
Context)) {
12857 if (SR.str() ==
"&" || SR.str() ==
"|") {
12859 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
12860 << (BO->getOpcode() == BO_And ?
"&" :
"|")
12863 BO->getOperatorLoc(),
12864 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
12865 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
12867 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
12885 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
12891 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
12906 for (
auto *SE : POE->semantics())
12907 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
12908 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
12912 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
12916 WorkList.push_back({
E, CC, IsListInit});
12920 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(
E)) {
12921 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
12925 if (OutArgE->isInOut())
12926 WorkList.push_back(
12927 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
12928 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
12934 if (BO->isComparisonOp())
12938 if (BO->getOpcode() == BO_Assign)
12941 if (BO->isAssignmentOp())
12949 if (isa<StmtExpr>(
E))
return;
12952 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
12957 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
12959 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
12963 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
12964 if (ChildExpr == CSE->getOperand())
12970 if (IsLogicalAndOperator &&
12975 WorkList.push_back({ChildExpr, CC, IsListInit});
12980 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
12984 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
12989 if (
U->getOpcode() == UO_LNot) {
12991 }
else if (
U->getOpcode() != UO_AddrOf) {
12992 if (
U->getSubExpr()->getType()->isAtomicType())
12993 S.
Diag(
U->getSubExpr()->getBeginLoc(),
12994 diag::warn_atomic_implicit_seq_cst);
13005 WorkList.push_back({OrigE, CC, IsListInit});
13006 while (!WorkList.empty())
13018 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
13021 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
13022 if (!M->getMemberDecl()->getType()->isReferenceType())
13025 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13027 FD =
Call->getDirectCallee();
13036 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13050 if (
SM.isMacroBodyExpansion(
Loc))
13052 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
13075 if (isa<CXXThisExpr>(
E)) {
13076 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13077 : diag::warn_this_bool_conversion;
13082 bool IsAddressOf =
false;
13084 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
13085 if (UO->getOpcode() != UO_AddrOf)
13087 IsAddressOf =
true;
13088 E = UO->getSubExpr();
13092 unsigned DiagID = IsCompare
13093 ? diag::warn_address_of_reference_null_compare
13094 : diag::warn_address_of_reference_bool_conversion;
13102 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13103 bool IsParam = isa<NonNullAttr>(NonnullAttr);
13105 llvm::raw_string_ostream S(Str);
13107 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13108 : diag::warn_cast_nonnull_to_bool;
13111 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13116 if (
auto *Callee =
Call->getDirectCallee()) {
13117 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13118 ComplainAboutNonnullParamOrCall(A);
13127 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
13128 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13129 MRecordDecl && MRecordDecl->isLambda()) {
13132 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
13142 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
13143 D = M->getMemberDecl();
13147 if (!
D ||
D->isWeak())
13151 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
13154 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13155 ComplainAboutNonnullParamOrCall(A);
13159 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13163 auto ParamIter = llvm::find(FD->
parameters(), PV);
13165 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13169 ComplainAboutNonnullParamOrCall(
NonNull);
13174 if (ArgNo.getASTIndex() == ParamNo) {
13175 ComplainAboutNonnullParamOrCall(
NonNull);
13189 if (IsAddressOf && IsFunction) {
13194 if (!IsAddressOf && !IsFunction && !IsArray)
13199 llvm::raw_string_ostream S(Str);
13202 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13203 : diag::warn_impcast_pointer_to_bool;
13210 DiagType = AddressOf;
13211 else if (IsFunction)
13212 DiagType = FunctionPointer;
13214 DiagType = ArrayPointer;
13216 llvm_unreachable(
"Could not determine diagnostic.");
13218 <<
Range << IsEqual;
13231 if (ReturnType.
isNull())
13269 CheckArrayAccess(
E);
13276 ::CheckBoolLikeConversion(*
this,
E, CC);
13279void Sema::CheckForIntOverflow (
const Expr *
E) {
13284 const Expr *OriginalE = Exprs.pop_back_val();
13287 if (isa<BinaryOperator, UnaryOperator>(
E)) {
13292 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13293 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13294 else if (isa<ObjCBoxedExpr>(OriginalE))
13296 else if (
const auto *
Call = dyn_cast<CallExpr>(
E))
13297 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13298 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
13299 Exprs.append(Message->arg_begin(), Message->arg_end());
13300 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
13301 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13302 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
13303 Exprs.push_back(Temporary->getSubExpr());
13304 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
13305 Exprs.push_back(Array->getIdx());
13306 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
13307 Exprs.push_back(Compound->getInitializer());
13308 else if (
const auto *
New = dyn_cast<CXXNewExpr>(
E);
13309 New &&
New->isArray()) {
13310 if (
auto ArraySize =
New->getArraySize())
13311 Exprs.push_back(*ArraySize);
13312 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13313 Exprs.push_back(MTE->getSubExpr());
13314 }
while (!Exprs.empty());
13329 class SequenceTree {
13333 LLVM_PREFERRED_TYPE(
bool)
13334 unsigned Merged : 1;
13342 friend class SequenceTree;
13346 explicit Seq(
unsigned N) : Index(N) {}
13349 Seq() : Index(0) {}
13352 SequenceTree() { Values.push_back(
Value(0)); }
13353 Seq root()
const {
return Seq(0); }
13360 return Seq(Values.size() - 1);
13364 void merge(
Seq S) {
13365 Values[S.Index].Merged =
true;
13371 bool isUnsequenced(
Seq Cur,
Seq Old) {
13372 unsigned C = representative(Cur.Index);
13373 unsigned Target = representative(Old.Index);
13377 C = Values[
C].Parent;
13384 unsigned representative(
unsigned K) {
13385 if (Values[K].Merged)
13387 return Values[K].Parent = representative(Values[K].
Parent);
13407 UK_ModAsSideEffect,
13409 UK_Count = UK_ModAsSideEffect + 1
13415 const Expr *UsageExpr =
nullptr;
13416 SequenceTree::Seq
Seq;
13422 Usage Uses[UK_Count];
13425 bool Diagnosed =
false;
13429 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13437 UsageInfoMap UsageMap;
13440 SequenceTree::Seq Region;
13455 struct SequencedSubexpression {
13456 SequencedSubexpression(SequenceChecker &Self)
13457 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
13458 Self.ModAsSideEffect = &ModAsSideEffect;
13461 ~SequencedSubexpression() {
13462 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13466 UsageInfo &UI = Self.UsageMap[M.first];
13467 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13468 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13469 SideEffectUsage = M.second;
13471 Self.ModAsSideEffect = OldModAsSideEffect;
13474 SequenceChecker &Self;
13483 class EvaluationTracker {
13485 EvaluationTracker(SequenceChecker &Self)
13486 : Self(Self), Prev(Self.EvalTracker) {
13487 Self.EvalTracker =
this;
13490 ~EvaluationTracker() {
13491 Self.EvalTracker = Prev;
13493 Prev->EvalOK &= EvalOK;
13496 bool evaluate(
const Expr *
E,
bool &Result) {
13500 Result, Self.SemaRef.Context,
13501 Self.SemaRef.isConstantEvaluatedContext());
13506 SequenceChecker &Self;
13507 EvaluationTracker *Prev;
13508 bool EvalOK =
true;
13509 } *EvalTracker =
nullptr;
13513 Object getObject(
const Expr *
E,
bool Mod)
const {
13516 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13517 return getObject(UO->getSubExpr(), Mod);
13519 if (BO->getOpcode() == BO_Comma)
13520 return getObject(BO->getRHS(), Mod);
13521 if (Mod && BO->isAssignmentOp())
13522 return getObject(BO->getLHS(), Mod);
13523 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
13525 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
13526 return ME->getMemberDecl();
13527 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
13536 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13538 Usage &
U = UI.Uses[UK];
13539 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
13543 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
13544 ModAsSideEffect->push_back(std::make_pair(O,
U));
13546 U.UsageExpr = UsageExpr;
13556 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
13557 UsageKind OtherKind,
bool IsModMod) {
13561 const Usage &
U = UI.Uses[OtherKind];
13562 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
13565 const Expr *Mod =
U.UsageExpr;
13566 const Expr *ModOrUse = UsageExpr;
13567 if (OtherKind == UK_Use)
13568 std::swap(Mod, ModOrUse);
13572 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
13573 : diag::warn_unsequenced_mod_use)
13575 UI.Diagnosed =
true;
13604 void notePreUse(Object O,
const Expr *UseExpr) {
13605 UsageInfo &UI = UsageMap[O];
13607 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
13610 void notePostUse(Object O,
const Expr *UseExpr) {
13611 UsageInfo &UI = UsageMap[O];
13612 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
13614 addUsage(O, UI, UseExpr, UK_Use);
13617 void notePreMod(Object O,
const Expr *ModExpr) {
13618 UsageInfo &UI = UsageMap[O];
13620 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
13621 checkUsage(O, UI, ModExpr, UK_Use,
false);
13624 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
13625 UsageInfo &UI = UsageMap[O];
13626 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
13628 addUsage(O, UI, ModExpr, UK);
13632 SequenceChecker(
Sema &S,
const Expr *
E,
13634 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
13638 (void)this->WorkList;
13641 void VisitStmt(
const Stmt *S) {
13645 void VisitExpr(
const Expr *
E) {
13647 Base::VisitStmt(
E);
13651 for (
auto *Sub : CSE->
children()) {
13652 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
13667 void VisitCastExpr(
const CastExpr *
E) {
13669 if (
E->getCastKind() == CK_LValueToRValue)
13670 O = getObject(
E->getSubExpr(),
false);
13679 void VisitSequencedExpressions(
const Expr *SequencedBefore,
13680 const Expr *SequencedAfter) {
13681 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
13682 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
13683 SequenceTree::Seq OldRegion = Region;
13686 SequencedSubexpression SeqBefore(*
this);
13687 Region = BeforeRegion;
13688 Visit(SequencedBefore);
13691 Region = AfterRegion;
13692 Visit(SequencedAfter);
13694 Region = OldRegion;
13696 Tree.merge(BeforeRegion);
13697 Tree.merge(AfterRegion);
13705 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
13712 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13713 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13719 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13726 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13727 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13732 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13744 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13748 SequenceTree::Seq RHSRegion;
13749 SequenceTree::Seq LHSRegion;
13751 RHSRegion =
Tree.allocate(Region);
13752 LHSRegion =
Tree.allocate(Region);
13754 RHSRegion = Region;
13755 LHSRegion = Region;
13757 SequenceTree::Seq OldRegion = Region;
13773 SequencedSubexpression SeqBefore(*
this);
13774 Region = RHSRegion;
13778 Region = LHSRegion;
13781 if (O && isa<CompoundAssignOperator>(BO))
13782 notePostUse(O, BO);
13786 Region = LHSRegion;
13789 if (O && isa<CompoundAssignOperator>(BO))
13790 notePostUse(O, BO);
13792 Region = RHSRegion;
13800 Region = OldRegion;
13804 : UK_ModAsSideEffect);
13806 Tree.merge(RHSRegion);
13807 Tree.merge(LHSRegion);
13812 VisitBinAssign(CAO);
13815 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
13816 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
13820 return VisitExpr(UO);
13828 : UK_ModAsSideEffect);
13831 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
13832 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
13836 return VisitExpr(UO);
13840 notePostMod(O, UO, UK_ModAsSideEffect);
13849 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
13850 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
13851 SequenceTree::Seq OldRegion = Region;
13853 EvaluationTracker Eval(*
this);
13855 SequencedSubexpression Sequenced(*
this);
13856 Region = LHSRegion;
13863 bool EvalResult =
false;
13864 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
13865 bool ShouldVisitRHS = !EvalOK || !EvalResult;
13866 if (ShouldVisitRHS) {
13867 Region = RHSRegion;
13871 Region = OldRegion;
13872 Tree.merge(LHSRegion);
13873 Tree.merge(RHSRegion);
13882 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
13883 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
13884 SequenceTree::Seq OldRegion = Region;
13886 EvaluationTracker Eval(*
this);
13888 SequencedSubexpression Sequenced(*
this);
13889 Region = LHSRegion;
13895 bool EvalResult =
false;
13896 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
13897 bool ShouldVisitRHS = !EvalOK || EvalResult;
13898 if (ShouldVisitRHS) {
13899 Region = RHSRegion;
13903 Region = OldRegion;
13904 Tree.merge(LHSRegion);
13905 Tree.merge(RHSRegion);
13913 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
13929 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
13930 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
13931 SequenceTree::Seq OldRegion = Region;
13933 EvaluationTracker Eval(*
this);
13935 SequencedSubexpression Sequenced(*
this);
13936 Region = ConditionRegion;
13946 bool EvalResult =
false;
13947 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
13948 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
13949 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
13950 if (ShouldVisitTrueExpr) {
13951 Region = TrueRegion;
13954 if (ShouldVisitFalseExpr) {
13955 Region = FalseRegion;
13959 Region = OldRegion;
13960 Tree.merge(ConditionRegion);
13961 Tree.merge(TrueRegion);
13962 Tree.merge(FalseRegion);
13965 void VisitCallExpr(
const CallExpr *CE) {
13977 SequencedSubexpression Sequenced(*
this);
13982 SequenceTree::Seq CalleeRegion;
13983 SequenceTree::Seq OtherRegion;
13984 if (SemaRef.getLangOpts().CPlusPlus17) {
13985 CalleeRegion = Tree.allocate(Region);
13986 OtherRegion = Tree.allocate(Region);
13988 CalleeRegion = Region;
13989 OtherRegion = Region;
13991 SequenceTree::Seq OldRegion = Region;
13994 Region = CalleeRegion;
13996 SequencedSubexpression Sequenced(*this);
13997 Visit(CE->getCallee());
13999 Visit(CE->getCallee());
14003 Region = OtherRegion;
14007 Region = OldRegion;
14009 Tree.merge(CalleeRegion);
14010 Tree.merge(OtherRegion);
14028 return VisitCallExpr(CXXOCE);
14039 case OO_MinusEqual:
14041 case OO_SlashEqual:
14042 case OO_PercentEqual:
14043 case OO_CaretEqual:
14046 case OO_LessLessEqual:
14047 case OO_GreaterGreaterEqual:
14048 SequencingKind = RHSBeforeLHS;
14052 case OO_GreaterGreater:
14058 SequencingKind = LHSBeforeRHS;
14062 SequencingKind = LHSBeforeRest;
14066 SequencingKind = NoSequencing;
14070 if (SequencingKind == NoSequencing)
14071 return VisitCallExpr(CXXOCE);
14074 SequencedSubexpression Sequenced(*
this);
14077 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14078 "Should only get there with C++17 and above!");
14079 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14080 "Should only get there with an overloaded binary operator"
14081 " or an overloaded call operator!");
14083 if (SequencingKind == LHSBeforeRest) {
14084 assert(CXXOCE->getOperator() == OO_Call &&
14085 "We should only have an overloaded call operator here!");
14094 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14095 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14096 SequenceTree::Seq OldRegion = Region;
14098 assert(CXXOCE->getNumArgs() >= 1 &&
14099 "An overloaded call operator must have at least one argument"
14100 " for the postfix-expression!");
14101 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14102 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14103 CXXOCE->getNumArgs() - 1);
14107 Region = PostfixExprRegion;
14108 SequencedSubexpression Sequenced(*this);
14109 Visit(PostfixExpr);
14113 Region = ArgsRegion;
14114 for (const Expr *Arg : Args)
14117 Region = OldRegion;
14118 Tree.merge(PostfixExprRegion);
14119 Tree.merge(ArgsRegion);
14121 assert(CXXOCE->getNumArgs() == 2 &&
14122 "Should only have two arguments here!");
14123 assert((SequencingKind == LHSBeforeRHS ||
14124 SequencingKind == RHSBeforeLHS) &&
14125 "Unexpected sequencing kind!");
14129 const Expr *E1 = CXXOCE->getArg(0);
14130 const Expr *E2 = CXXOCE->getArg(1);
14131 if (SequencingKind == RHSBeforeLHS)
14134 return VisitSequencedExpressions(E1, E2);
14141 SequencedSubexpression Sequenced(*
this);
14144 return VisitExpr(CCE);
14147 SequenceExpressionsInOrder(
14153 return VisitExpr(ILE);
14156 SequenceExpressionsInOrder(ILE->
inits());
14168 SequenceTree::Seq
Parent = Region;
14169 for (
const Expr *
E : ExpressionList) {
14173 Elts.push_back(Region);
14179 for (
unsigned I = 0; I < Elts.size(); ++I)
14180 Tree.merge(Elts[I]);
14184SequenceChecker::UsageInfo::UsageInfo() =
default;
14188void Sema::CheckUnsequencedOperations(
const Expr *
E) {
14190 WorkList.push_back(
E);
14191 while (!WorkList.empty()) {
14192 const Expr *Item = WorkList.pop_back_val();
14193 SequenceChecker(*
this, Item, WorkList);
14198 bool IsConstexpr) {
14200 IsConstexpr || isa<ConstantExpr>(
E));
14201 CheckImplicitConversions(
E, CheckLoc);
14203 CheckUnsequencedOperations(
E);
14205 CheckForIntOverflow(
E);
14218 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14222 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14226 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14240 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
14244 bool CheckParameterNames) {
14245 bool HasInvalidParm =
false;
14247 assert(Param &&
"null in a parameter list");
14256 if (!Param->isInvalidDecl() &&
14258 diag::err_typecheck_decl_incomplete_type) ||
14260 diag::err_abstract_type_in_decl,
14262 Param->setInvalidDecl();
14263 HasInvalidParm =
true;
14268 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14272 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14280 QualType PType = Param->getOriginalType();
14288 if (!Param->isInvalidDecl()) {
14290 if (!ClassDecl->isInvalidDecl() &&
14291 !ClassDecl->hasIrrelevantDestructor() &&
14292 !ClassDecl->isDependentContext() &&
14293 ClassDecl->isParamDestroyedInCallee()) {
14305 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14306 if (!Param->getType().isConstQualified())
14307 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14311 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14316 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14317 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14322 if (!Param->isInvalidDecl() &&
14324 Param->setInvalidDecl();
14325 HasInvalidParm =
true;
14326 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14330 return HasInvalidParm;
14333std::optional<std::pair<
14342static std::pair<CharUnits, CharUnits>
14350 if (
Base->isVirtual()) {
14357 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14364 DerivedType =
Base->getType();
14367 return std::make_pair(BaseAlignment, Offset);
14371static std::optional<std::pair<CharUnits, CharUnits>>
14377 return std::nullopt;
14382 return std::nullopt;
14386 CharUnits Offset = EltSize * IdxRes->getExtValue();
14389 return std::make_pair(
P->first,
P->second + Offset);
14395 return std::make_pair(
14396 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
14402std::optional<std::pair<
14410 case Stmt::CStyleCastExprClass:
14411 case Stmt::CXXStaticCastExprClass:
14412 case Stmt::ImplicitCastExprClass: {
14413 auto *CE = cast<CastExpr>(
E);
14414 const Expr *From = CE->getSubExpr();
14415 switch (CE->getCastKind()) {
14420 case CK_UncheckedDerivedToBase:
14421 case CK_DerivedToBase: {
14431 case Stmt::ArraySubscriptExprClass: {
14432 auto *ASE = cast<ArraySubscriptExpr>(
E);
14436 case Stmt::DeclRefExprClass: {
14437 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
14440 if (!VD->getType()->isReferenceType()) {
14442 if (VD->hasDependentAlignment())
14451 case Stmt::MemberExprClass: {
14452 auto *ME = cast<MemberExpr>(
E);
14453 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14457 std::optional<std::pair<CharUnits, CharUnits>>
P;
14466 return std::make_pair(
P->first,
14469 case Stmt::UnaryOperatorClass: {
14470 auto *UO = cast<UnaryOperator>(
E);
14479 case Stmt::BinaryOperatorClass: {
14480 auto *BO = cast<BinaryOperator>(
E);
14491 return std::nullopt;
14496std::optional<std::pair<
14505 case Stmt::CStyleCastExprClass:
14506 case Stmt::CXXStaticCastExprClass:
14507 case Stmt::ImplicitCastExprClass: {
14508 auto *CE = cast<CastExpr>(
E);
14509 const Expr *From = CE->getSubExpr();
14510 switch (CE->getCastKind()) {
14515 case CK_ArrayToPointerDecay:
14517 case CK_UncheckedDerivedToBase:
14518 case CK_DerivedToBase: {
14528 case Stmt::CXXThisExprClass: {
14533 case Stmt::UnaryOperatorClass: {
14534 auto *UO = cast<UnaryOperator>(
E);
14539 case Stmt::BinaryOperatorClass: {
14540 auto *BO = cast<BinaryOperator>(
E);
14548 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
14549 std::swap(LHS, RHS);
14559 return std::nullopt;
14564 std::optional<std::pair<CharUnits, CharUnits>>
P =
14568 return P->first.alignmentAtOffset(
P->second);
14586 if (!DestPtr)
return;
14592 if (DestAlign.
isOne())
return;
14596 if (!SrcPtr)
return;
14607 if (SrcAlign >= DestAlign)
return;
14612 <<
static_cast<unsigned>(DestAlign.
getQuantity())
14616void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
14618 bool AllowOnePastEnd,
bool IndexNegated) {
14627 const Type *EffectiveType =
14634 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
14636 const Type *BaseType =
14638 bool IsUnboundedArray =
14640 Context, StrictFlexArraysLevel,
14650 llvm::APSInt index =
Result.Val.getInt();
14651 if (IndexNegated) {
14652 index.setIsUnsigned(
false);
14656 if (IsUnboundedArray) {
14659 if (index.isUnsigned() || !index.isNegative()) {
14661 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
14663 if (index.getBitWidth() < AddrBits)
14664 index = index.zext(AddrBits);
14665 std::optional<CharUnits> ElemCharUnits =
14666 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
14669 if (!ElemCharUnits || ElemCharUnits->isZero())
14671 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
14676 if (index.getActiveBits() <= AddrBits) {
14678 llvm::APInt Product(index);
14680 Product = Product.umul_ov(ElemBytes, Overflow);
14681 if (!Overflow && Product.getActiveBits() <= AddrBits)
14687 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
14688 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
14690 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
14691 MaxElems = MaxElems.udiv(ElemBytes);
14694 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
14695 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
14701 <<
toString(index, 10,
true) << AddrBits
14702 << (
unsigned)ASTC.toBits(*ElemCharUnits)
14705 << (
unsigned)MaxElems.getLimitedValue(~0
U)
14710 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14712 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14714 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14715 ND = ME->getMemberDecl();
14719 PDiag(diag::note_array_declared_here) << ND);
14724 if (index.isUnsigned() || !index.isNegative()) {
14734 llvm::APInt size = ArrayTy->
getSize();
14736 if (BaseType != EffectiveType) {
14744 if (!ptrarith_typesize)
14747 if (ptrarith_typesize != array_typesize) {
14749 uint64_t ratio = array_typesize / ptrarith_typesize;
14753 if (ptrarith_typesize * ratio == array_typesize)
14754 size *= llvm::APInt(size.getBitWidth(), ratio);
14758 if (size.getBitWidth() > index.getBitWidth())
14759 index = index.zext(size.getBitWidth());
14760 else if (size.getBitWidth() < index.getBitWidth())
14761 size = size.zext(index.getBitWidth());
14767 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
14784 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
14785 : diag::warn_ptr_arith_exceeds_bounds;
14786 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
14794 unsigned DiagID = diag::warn_array_index_precedes_bounds;
14796 DiagID = diag::warn_ptr_arith_precedes_bounds;
14797 if (index.isNegative()) index = -index;
14807 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14809 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14811 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14812 ND = ME->getMemberDecl();
14816 PDiag(diag::note_array_declared_here) << ND);
14819void Sema::CheckArrayAccess(
const Expr *
expr) {
14820 int AllowOnePastEnd = 0;
14822 expr =
expr->IgnoreParenImpCasts();
14823 switch (
expr->getStmtClass()) {
14824 case Stmt::ArraySubscriptExprClass: {
14827 AllowOnePastEnd > 0);
14831 case Stmt::MemberExprClass: {
14832 expr = cast<MemberExpr>(
expr)->getBase();
14835 case Stmt::ArraySectionExprClass: {
14841 nullptr, AllowOnePastEnd > 0);
14844 case Stmt::UnaryOperatorClass: {
14860 case Stmt::ConditionalOperatorClass: {
14863 CheckArrayAccess(lhs);
14865 CheckArrayAccess(rhs);
14868 case Stmt::CXXOperatorCallExprClass: {
14869 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
14870 for (
const auto *Arg : OCE->arguments())
14871 CheckArrayAccess(Arg);
14881 Expr *RHS,
bool isProperty) {
14893 S.
Diag(
Loc, diag::warn_arc_literal_assign)
14895 << (isProperty ? 0 : 1)
14903 Expr *RHS,
bool isProperty) {
14906 if (
cast->getCastKind() == CK_ARCConsumeObject) {
14907 S.
Diag(
Loc, diag::warn_arc_retained_assign)
14909 << (isProperty ? 0 : 1)
14913 RHS =
cast->getSubExpr();
14984 if (
cast->getCastKind() == CK_ARCConsumeObject) {
14985 Diag(
Loc, diag::warn_arc_retained_property_assign)
14989 RHS =
cast->getSubExpr();
15012 bool StmtLineInvalid;
15015 if (StmtLineInvalid)
15018 bool BodyLineInvalid;
15021 if (BodyLineInvalid)
15025 if (StmtLine != BodyLine)
15040 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15049 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15053 const Stmt *PossibleBody) {
15059 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15060 StmtLoc = FS->getRParenLoc();
15061 Body = FS->getBody();
15062 DiagID = diag::warn_empty_for_body;
15063 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15064 StmtLoc = WS->getRParenLoc();
15065 Body = WS->getBody();
15066 DiagID = diag::warn_empty_while_body;
15071 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15094 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
15095 if (!ProbableTypo) {
15096 bool BodyColInvalid;
15099 if (BodyColInvalid)
15102 bool StmtColInvalid;
15105 if (StmtColInvalid)
15108 if (BodyCol > StmtCol)
15109 ProbableTypo =
true;
15112 if (ProbableTypo) {
15114 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15122 if (
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15134 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15136 RHSExpr = CE->
getArg(0);
15137 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15138 CXXSCE && CXXSCE->isXValue())
15139 RHSExpr = CXXSCE->getSubExpr();
15143 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15144 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15147 if (LHSDeclRef && RHSDeclRef) {
15154 auto D =
Diag(OpLoc, diag::warn_self_move)
15170 const Expr *LHSBase = LHSExpr;
15171 const Expr *RHSBase = RHSExpr;
15172 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15173 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15174 if (!LHSME || !RHSME)
15177 while (LHSME && RHSME) {
15184 LHSME = dyn_cast<MemberExpr>(LHSBase);
15185 RHSME = dyn_cast<MemberExpr>(RHSBase);
15188 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15189 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15190 if (LHSDeclRef && RHSDeclRef) {
15197 Diag(OpLoc, diag::warn_self_move)
15203 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
15204 Diag(OpLoc, diag::warn_self_move)
15228 bool AreUnionMembers =
false) {
15232 assert(((Field1Parent->isStructureOrClassType() &&
15233 Field2Parent->isStructureOrClassType()) ||
15234 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15235 "Can't evaluate layout compatibility between a struct field and a "
15237 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15238 (AreUnionMembers && Field1Parent->isUnionType())) &&
15239 "AreUnionMembers should be 'true' for union fields (only).");
15253 if (Bits1 != Bits2)
15257 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15258 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15261 if (!AreUnionMembers &&
15273 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15274 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15276 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15277 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15282 return isLayoutCompatible(C, F1, F2);
15293 for (
auto *Field1 : RD1->
fields()) {
15294 auto I = UnmatchedFields.begin();
15295 auto E = UnmatchedFields.end();
15297 for ( ; I !=
E; ++I) {
15299 bool Result = UnmatchedFields.erase(*I);
15309 return UnmatchedFields.empty();
15335 if (
C.hasSameType(T1, T2))
15344 if (TC1 == Type::Enum)
15346 if (TC1 == Type::Record) {
15365 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15396 const ValueDecl **VD, uint64_t *MagicValue,
15397 bool isConstantEvaluated) {
15405 case Stmt::UnaryOperatorClass: {
15414 case Stmt::DeclRefExprClass: {
15415 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
15420 case Stmt::IntegerLiteralClass: {
15422 llvm::APInt MagicValueAPInt = IL->
getValue();
15423 if (MagicValueAPInt.getActiveBits() <= 64) {
15424 *MagicValue = MagicValueAPInt.getZExtValue();
15430 case Stmt::BinaryConditionalOperatorClass:
15431 case Stmt::ConditionalOperatorClass: {
15433 cast<AbstractConditionalOperator>(TypeExpr);
15436 isConstantEvaluated)) {
15446 case Stmt::BinaryOperatorClass: {
15449 TypeExpr = BO->
getRHS();
15479 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15482 bool isConstantEvaluated) {
15483 FoundWrongKind =
false;
15488 uint64_t MagicValue;
15490 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15494 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15495 if (I->getArgumentKind() != ArgumentKind) {
15496 FoundWrongKind =
true;
15499 TypeInfo.Type = I->getMatchingCType();
15500 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15501 TypeInfo.MustBeNull = I->getMustBeNull();
15512 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15513 if (I == MagicValues->end())
15522 bool LayoutCompatible,
15524 if (!TypeTagForDatatypeMagicValues)
15525 TypeTagForDatatypeMagicValues.reset(
15526 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15529 (*TypeTagForDatatypeMagicValues)[Magic] =
15545 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
15546 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
15547 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
15548 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
15551void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
15555 bool IsPointerAttr =
Attr->getIsPointer();
15558 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
15559 if (TypeTagIdxAST >= ExprArgs.size()) {
15560 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15561 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
15564 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
15565 bool FoundWrongKind;
15568 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
15570 if (FoundWrongKind)
15572 diag::warn_type_tag_for_datatype_wrong_kind)
15578 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
15579 if (ArgumentIdxAST >= ExprArgs.size()) {
15580 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15581 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
15584 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
15585 if (IsPointerAttr) {
15587 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
15588 if (ICE->getType()->isVoidPointerType() &&
15589 ICE->getCastKind() == CK_BitCast)
15590 ArgumentExpr = ICE->getSubExpr();
15603 diag::warn_type_safety_null_pointer_required)
15615 bool mismatch =
false;
15638 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
15639 << ArgumentType << ArgumentKind
15640 <<
TypeInfo.LayoutCompatible << RequiredType
15658 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
15668 if (isa<UnaryOperator>(
E) &&
15669 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
15670 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
15671 if (isa<MemberExpr>(Op)) {
15672 auto &MisalignedMembersForExpr =
15674 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
15675 if (MA != MisalignedMembersForExpr.end() &&
15680 MisalignedMembersForExpr.erase(MA);
15689 const auto *ME = dyn_cast<MemberExpr>(
E);
15701 bool AnyIsPacked =
false;
15703 QualType BaseType = ME->getBase()->getType();
15713 auto *FD = dyn_cast<FieldDecl>(MD);
15719 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
15720 ReverseMemberChain.push_back(FD);
15723 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
15725 assert(TopME &&
"We did not compute a topmost MemberExpr!");
15732 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
15736 if (!DRE && !isa<CXXThisExpr>(TopBase))
15743 if (ExpectedAlignment.
isOne())
15748 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
15757 if (DRE && !TopME->
isArrow()) {
15760 CompleteObjectAlignment =
15765 if (Offset % ExpectedAlignment != 0 ||
15768 CompleteObjectAlignment < ExpectedAlignment) {
15779 for (
FieldDecl *FDI : ReverseMemberChain) {
15780 if (FDI->hasAttr<PackedAttr>() ||
15781 FDI->getParent()->hasAttr<PackedAttr>()) {
15789 assert(FD &&
"We did not find a packed FieldDecl!");
15794void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
15795 using namespace std::placeholders;
15798 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
15834bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
15835 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
15848 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
15849 TheCall->
setType(VecTy0->getElementType());
15862 return S.
Diag(
Loc, diag::err_conv_mixed_enum_types)
15879 assert(!Args.empty() &&
"Should have at least one argument.");
15881 Expr *Arg0 = Args.front();
15884 auto EmitError = [&](
Expr *ArgI) {
15886 diag::err_typecheck_call_different_arg_types)
15887 << Arg0->
getType() << ArgI->getType();
15892 for (
Expr *ArgI : Args.drop_front())
15903 for (
Expr *ArgI : Args.drop_front()) {
15907 VecI->getElementType()) ||
15908 Vec0->getNumElements() != VecI->getNumElements()) {
15917std::optional<QualType>
15921 return std::nullopt;
15925 return std::nullopt;
15928 for (
int I = 0; I < 2; ++I) {
15932 return std::nullopt;
15933 Args[I] = Converted.
get();
15940 return std::nullopt;
15943 return std::nullopt;
15945 TheCall->
setArg(0, Args[0]);
15946 TheCall->
setArg(1, Args[1]);
15963 for (
int I = 0; I < 3; ++I) {
15968 Args[I] = Converted.
get();
15971 int ArgOrdinal = 1;
15972 for (
Expr *Arg : Args) {
15974 ArgTyRestr, ArgOrdinal++))
15981 for (
int I = 0; I < 3; ++I)
15982 TheCall->
setArg(I, Args[I]);
15984 TheCall->
setType(Args[0]->getType());
15988bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16000bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16009 diag::err_builtin_invalid_arg_type)
16010 << 1 << 2 << 1 << 1 << TyArg;
16024 Expr *Matrix = MatrixArg.
get();
16029 << 1 << 3 << 0 << 0
16037 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16040 TheCall->
setType(ResultType);
16043 TheCall->
setArg(0, Matrix);
16048static std::optional<unsigned>
16056 uint64_t
Dim =
Value->getZExtValue();
16075 unsigned PtrArgIdx = 0;
16081 bool ArgError =
false;
16088 PtrExpr = PtrConv.
get();
16089 TheCall->
setArg(0, PtrExpr);
16100 << PtrArgIdx + 1 << 0 << 5 << 0
16108 << PtrArgIdx + 1 << 0 << 5
16115 auto ApplyArgumentConversions = [
this](
Expr *
E) {
16124 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16126 RowsExpr = RowsConv.
get();
16127 TheCall->
setArg(1, RowsExpr);
16129 RowsExpr =
nullptr;
16131 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16133 ColumnsExpr = ColumnsConv.
get();
16134 TheCall->
setArg(2, ColumnsExpr);
16136 ColumnsExpr =
nullptr;
16147 std::optional<unsigned> MaybeRows;
16151 std::optional<unsigned> MaybeColumns;
16156 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16159 StrideExpr = StrideConv.
get();
16160 TheCall->
setArg(3, StrideExpr);
16163 if (std::optional<llvm::APSInt>
Value =
16166 if (Stride < *MaybeRows) {
16168 diag::err_builtin_matrix_stride_too_small);
16174 if (ArgError || !MaybeRows || !MaybeColumns)
16187 unsigned PtrArgIdx = 1;
16192 bool ArgError =
false;
16198 MatrixExpr = MatrixConv.
get();
16199 TheCall->
setArg(0, MatrixExpr);
16209 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16217 PtrExpr = PtrConv.
get();
16218 TheCall->
setArg(1, PtrExpr);
16229 << PtrArgIdx + 1 << 0 << 5 << 0
16235 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16242 diag::err_builtin_matrix_pointer_arg_mismatch)
16243 << ElementTy << MatrixTy->getElementType();
16258 StrideExpr = StrideConv.
get();
16259 TheCall->
setArg(2, StrideExpr);
16264 if (std::optional<llvm::APSInt>
Value =
16267 if (Stride < MatrixTy->getNumRows()) {
16269 diag::err_builtin_matrix_stride_too_small);
16289 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16294 llvm::StringSet<> CalleeTCBs;
16295 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16296 CalleeTCBs.insert(A->getTCBName());
16297 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16298 CalleeTCBs.insert(A->getTCBName());
16302 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16303 StringRef CallerTCB = A->getTCBName();
16304 if (CalleeTCBs.count(CallerTCB) == 0) {
16305 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16306 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static 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 builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const StringLiteral *ReferenceFormatString, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)
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 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 CFIUncheckedCalleeChange AdjustingCFIUncheckedCallee(QualType From, QualType To)
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 bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos)
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 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 bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
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 ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool IsSameCharType(QualType T1, QualType T2)
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth)
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static bool IsEnumConstOrFromMacro(Sema &S, const Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall)
static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall, SourceLocation CC)
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)
static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static void CheckCommaOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool ExtraCheckForImplicitConversion, llvm::SmallVectorImpl< AnalyzeImplicitConversionsWorkItem > &WorkList)
static void DiagnoseFloatingImpCast(Sema &S, const Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static int classifyConstantValue(Expr *Constant)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool PruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
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 ExprResult GetVTablePointer(Sema &S, CallExpr *Call)
static bool requiresParensToAddCast(const Expr *E)
static bool HasEnumType(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, const Type *Target, Expr *E, QualType T, SourceLocation CC)
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 checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr, int ArgOrdinal)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, SourceLocation Loc)
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static 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 BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for DirectX constructs.
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SPIRV constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
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
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.
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,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
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 getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
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.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
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 ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const
Return the unique reference to the matrix type of the specified element type and size.
CanQualType getNSUIntegerType() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
std::unique_ptr< AtomicScopeModel > getScopeModel() const
Get atomic scope model.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
TemplateDecl * 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
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
bool isAuxBuiltinID(unsigned ID) const
Return true if the builtin ID belongs exclusively to the AuxTarget, and false if it belongs to both p...
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
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.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
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.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
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.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
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 getEndLoc() const
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.
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.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
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.
static ConvertVectorExpr * Create(const ASTContext &C, Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc, FPOptionsOverride FPFeatures)
Represents an expression that might suspend coroutine execution; either a co_await or co_yield expres...
Expr * getOperand() const
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
DynamicCountPointerKind getKind() const
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
bool isStdNamespace() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
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 getBeginLoc() const
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
std::string getAsString() const
Retrieve the human-readable string for this name.
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.
bool isComplete() const
Returns true if this can be considered a complete type.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
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.
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 isFlexibleArrayMemberLike(const 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 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...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
const FieldDecl * findCountedByField() const
Find the FieldDecl specified in a FAM's "counted_by" attribute.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned 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.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
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.
A pointer to member type per C++ 8.3.3 - Pointers to members.
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.
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.
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
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)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstant(const ASTContext &Ctx) const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
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.
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
RecordDecl * getMostRecentDecl()
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() 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 CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
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)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(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 DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
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.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
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 checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
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.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
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....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
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...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
FPOptionsOverride CurFPFeatureOverrides()
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)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
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
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.
bool AddingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function without the cfi_unchecked_callee attribut...
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...
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
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
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.
EltwiseBuiltinArgTyRestriction
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,...
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.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
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
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
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 PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
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...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
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.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FomatStringIn...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
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 checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
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...
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
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
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.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
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 isIncompleteArrayType() const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
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
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
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....
bool isExtVectorType() const
bool isExtVectorBoolType() const
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...
RecordDecl * castAsRecordDecl() const
bool isChar16Type() const
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 isChar32Type() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
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.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
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.
bool isUnicodeCharacterType() const
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
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
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.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
@ 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 Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ Arithmetic
An arithmetic operation.
@ Comparison
A comparison.
@ 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...
@ Success
Annotation was successful.
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.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
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.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
The alignment was not explicit in code.
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
Describes how types, statements, expressions, and declarations should be printed.
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned Indentation
The number of spaces to use to indent each line.
A context in which code is being synthesized (where a source location alone is not sufficient to iden...
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.
SmallVector< MisalignedMember, 4 > MisalignedMembers
Small set of gathered accesses to potentially misaligned members due to the packed attribute.