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)
5573 diag::err_typecheck_call_too_few_args_at_least)
5581 unsigned numElements = 0;
5596 unsigned numResElements = TheCall->
getNumArgs() - 2;
5605 diag::err_vec_builtin_incompatible_vector)
5612 diag::err_vec_builtin_incompatible_vector)
5617 }
else if (numElements != numResElements) {
5626 for (
unsigned i = 2; i < TheCall->
getNumArgs(); i++) {
5631 std::optional<llvm::APSInt>
Result;
5634 diag::err_shufflevector_nonconstant_argument)
5640 else if (
Result->getActiveBits() > 64 ||
5641 Result->getZExtValue() >= numElements * 2)
5643 diag::err_shufflevector_argument_too_large)
5650 for (
unsigned i = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5651 exprs.push_back(TheCall->
getArg(i));
5652 TheCall->
setArg(i,
nullptr);
5670 diag::err_convertvector_non_vector)
5673 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5675 <<
"__builtin_convertvector");
5680 if (SrcElts != DstElts)
5682 diag::err_convertvector_incompatible_vector)
5690bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5695 diag::err_typecheck_call_too_many_args_at_most)
5696 << 0 << 3 << NumArgs << 0
5701 for (
unsigned i = 1; i != NumArgs; ++i)
5708bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5710 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5720 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5730bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5737 << cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5742bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5748 if (
const auto *UE =
5750 if (UE->getKind() == UETT_AlignOf ||
5751 UE->getKind() == UETT_PreferredAlignOf)
5757 if (!
Result.isPowerOf2())
5758 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5765 if (
Result > std::numeric_limits<int32_t>::max())
5773bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5784 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
5788 TheCall->
setArg(0, FirstArgResult.
get());
5800 if (!
Result.isPowerOf2())
5801 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5813 TheCall->
setArg(2, ThirdArg);
5819bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5820 unsigned BuiltinID =
5821 cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5822 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5825 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5826 if (NumArgs < NumRequiredArgs) {
5827 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5828 << 0 << NumRequiredArgs << NumArgs
5831 if (NumArgs >= NumRequiredArgs + 0x100) {
5833 diag::err_typecheck_call_too_many_args_at_most)
5834 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5845 if (Arg.isInvalid())
5847 TheCall->
setArg(i, Arg.get());
5852 unsigned FormatIdx = i;
5862 unsigned FirstDataArg = i;
5863 while (i < NumArgs) {
5881 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5883 bool Success = CheckFormatArguments(
5907 std::optional<llvm::APSInt> R;
5909 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5916 int High,
bool RangeIsError) {
5930 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
5938 PDiag(diag::warn_argument_invalid_range)
5983 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5988 if (
Value.isNegative())
5999 if ((
Value & 0xFF) != 0)
6024 Result.setIsUnsigned(
true);
6029 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6048 Result.setIsUnsigned(
true);
6056 diag::err_argument_not_shifted_byte_or_xxff)
6060bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6062 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6073 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6079bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6081 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6086bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6101 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6106 diag::err_builtin_counted_by_ref_has_side_effects)
6109 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6110 if (!ME->isFlexibleArrayMemberLike(
6113 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6119 const auto *FAMDecl = cast<FieldDecl>(ME->getMemberDecl());
6127 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
6137bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *
E,
6148 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6153 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6158 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6176class UncoveredArgHandler {
6177 enum {
Unknown = -1, AllCovered = -2 };
6179 signed FirstUncoveredArg =
Unknown;
6183 UncoveredArgHandler() =
default;
6185 bool hasUncoveredArg()
const {
6186 return (FirstUncoveredArg >= 0);
6189 unsigned getUncoveredArg()
const {
6190 assert(hasUncoveredArg() &&
"no uncovered argument");
6191 return FirstUncoveredArg;
6194 void setAllCovered() {
6197 DiagnosticExprs.clear();
6198 FirstUncoveredArg = AllCovered;
6201 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6202 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6205 if (FirstUncoveredArg == AllCovered)
6210 if (NewFirstUncoveredArg == FirstUncoveredArg)
6211 DiagnosticExprs.push_back(StrExpr);
6212 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6213 DiagnosticExprs.clear();
6214 DiagnosticExprs.push_back(StrExpr);
6215 FirstUncoveredArg = NewFirstUncoveredArg;
6219 void Diagnose(
Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6222enum StringLiteralCheckType {
6224 SLCT_UncheckedLiteral,
6232 bool AddendIsRight) {
6233 unsigned BitWidth = Offset.getBitWidth();
6234 unsigned AddendBitWidth = Addend.getBitWidth();
6236 if (Addend.isUnsigned()) {
6237 Addend = Addend.zext(++AddendBitWidth);
6238 Addend.setIsSigned(
true);
6241 if (AddendBitWidth > BitWidth) {
6242 Offset = Offset.sext(AddendBitWidth);
6243 BitWidth = AddendBitWidth;
6244 }
else if (BitWidth > AddendBitWidth) {
6245 Addend = Addend.sext(BitWidth);
6249 llvm::APSInt ResOffset = Offset;
6250 if (BinOpKind == BO_Add)
6251 ResOffset = Offset.sadd_ov(Addend, Ov);
6253 assert(AddendIsRight && BinOpKind == BO_Sub &&
6254 "operator must be add or sub with addend on the right");
6255 ResOffset = Offset.ssub_ov(Addend, Ov);
6261 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6262 "index (intermediate) result too big");
6263 Offset = Offset.sext(2 * BitWidth);
6264 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6276class FormatStringLiteral {
6281 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6282 : FExpr(fexpr), Offset(Offset) {}
6284 const StringLiteral *getFormatString()
const {
return FExpr; }
6286 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6288 unsigned getByteLength()
const {
6289 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6292 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6299 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6300 bool isWide()
const {
return FExpr->
isWide(); }
6301 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6302 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6303 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6304 bool isPascal()
const {
return FExpr->
isPascal(); }
6309 unsigned *StartTokenByteOffset =
nullptr)
const {
6311 StartToken, StartTokenByteOffset);
6324 Sema &S,
const FormatStringLiteral *FExpr,
6329 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6330 bool IgnoreStringsWithoutSpecifiers);
6344 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6345 llvm::APSInt Offset,
bool IgnoreStringsWithoutSpecifiers =
false) {
6347 return SLCT_NotALiteral;
6349 assert(Offset.isSigned() &&
"invalid offset");
6352 return SLCT_NotALiteral;
6361 return SLCT_UncheckedLiteral;
6364 case Stmt::InitListExprClass:
6368 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6369 Type, CallType,
false, CheckedVarArgs,
6370 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6372 return SLCT_NotALiteral;
6373 case Stmt::BinaryConditionalOperatorClass:
6374 case Stmt::ConditionalOperatorClass: {
6378 cast<AbstractConditionalOperator>(
E);
6383 bool CheckLeft =
true, CheckRight =
true;
6386 if (
C->getCond()->EvaluateAsBooleanCondition(
6398 StringLiteralCheckType Left;
6400 Left = SLCT_UncheckedLiteral;
6403 S, ReferenceFormatString,
C->getTrueExpr(), Args, APK, format_idx,
6404 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6405 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6406 if (Left == SLCT_NotALiteral || !CheckRight) {
6412 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6413 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6414 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6416 return (CheckLeft && Left < Right) ? Left : Right;
6419 case Stmt::ImplicitCastExprClass:
6420 E = cast<ImplicitCastExpr>(
E)->getSubExpr();
6423 case Stmt::OpaqueValueExprClass:
6424 if (
const Expr *src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
6428 return SLCT_NotALiteral;
6430 case Stmt::PredefinedExprClass:
6434 return SLCT_UncheckedLiteral;
6436 case Stmt::DeclRefExprClass: {
6442 bool isConstant =
false;
6446 isConstant = AT->getElementType().isConstant(S.
Context);
6448 isConstant =
T.isConstant(S.
Context) &&
6453 isConstant =
T.isConstant(S.
Context);
6457 if (
const Expr *
Init = VD->getAnyInitializer()) {
6460 if (InitList->isStringLiteralInit())
6461 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6464 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6465 firstDataArg,
Type, CallType,
6466 false, CheckedVarArgs, UncoveredArg, Offset);
6517 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6518 if (
const auto *
D = dyn_cast<Decl>(PV->getDeclContext())) {
6519 for (
const auto *PVFormatMatches :
6525 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6529 S.
Diag(Args[format_idx]->getBeginLoc(),
6530 diag::warn_format_string_type_incompatible)
6531 << PVFormatMatches->getType()->getName()
6533 if (!InFunctionCall) {
6534 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6535 diag::note_format_string_defined);
6537 return SLCT_UncheckedLiteral;
6540 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6541 Args, APK, format_idx, firstDataArg,
Type, CallType,
6542 false, CheckedVarArgs, UncoveredArg,
6543 Offset, IgnoreStringsWithoutSpecifiers);
6550 PVFormat->getFirstArg(), &CallerFSI))
6552 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6556 S.
Diag(Args[format_idx]->getBeginLoc(),
6557 diag::warn_format_string_type_incompatible)
6558 << PVFormat->getType()->getName()
6560 if (!InFunctionCall) {
6563 return SLCT_UncheckedLiteral;
6576 return SLCT_UncheckedLiteral;
6584 return SLCT_NotALiteral;
6587 case Stmt::CallExprClass:
6588 case Stmt::CXXMemberCallExprClass: {
6591 bool IsFirst =
true;
6592 StringLiteralCheckType CommonResult;
6593 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6594 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6596 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6597 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6598 Offset, IgnoreStringsWithoutSpecifiers);
6605 return CommonResult;
6607 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6609 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6610 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6613 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6614 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6615 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6621 S, ReferenceFormatString, SLE, Args, APK, format_idx, firstDataArg,
6622 Type, CallType,
false, CheckedVarArgs,
6623 UncoveredArg, Offset, IgnoreStringsWithoutSpecifiers);
6624 return SLCT_NotALiteral;
6626 case Stmt::ObjCMessageExprClass: {
6627 const auto *ME = cast<ObjCMessageExpr>(
E);
6628 if (
const auto *MD = ME->getMethodDecl()) {
6629 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6638 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6640 MD->getSelector().isKeywordSelector(
6641 {
"localizedStringForKey",
"value",
"table"})) {
6642 IgnoreStringsWithoutSpecifiers =
true;
6645 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6647 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6648 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6649 Offset, IgnoreStringsWithoutSpecifiers);
6653 return SLCT_NotALiteral;
6655 case Stmt::ObjCStringLiteralClass:
6656 case Stmt::StringLiteralClass: {
6662 StrE = cast<StringLiteral>(
E);
6665 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6668 return SLCT_NotALiteral;
6670 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6672 format_idx, firstDataArg,
Type, InFunctionCall,
6673 CallType, CheckedVarArgs, UncoveredArg,
6674 IgnoreStringsWithoutSpecifiers);
6675 return SLCT_CheckedLiteral;
6678 return SLCT_NotALiteral;
6680 case Stmt::BinaryOperatorClass: {
6694 if (LIsInt != RIsInt) {
6698 if (BinOpKind == BO_Add) {
6711 return SLCT_NotALiteral;
6713 case Stmt::UnaryOperatorClass: {
6715 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6716 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6718 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6728 return SLCT_NotALiteral;
6732 return SLCT_NotALiteral;
6743 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6744 if (isa_and_nonnull<StringLiteral>(LVE))
6765 return "freebsd_kprintf";
6774 return llvm::StringSwitch<FormatStringType>(Flavor)
6780 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
6796bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6800 llvm::SmallBitVector &CheckedVarArgs) {
6801 FormatStringInfo FSI;
6805 return CheckFormatArguments(
6806 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
6811bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
6815 llvm::SmallBitVector &CheckedVarArgs) {
6816 FormatStringInfo FSI;
6820 return CheckFormatArguments(Args, FSI.ArgPassingKind,
6821 Format->getFormatString(), FSI.FormatIdx,
6823 CallType,
Loc,
Range, CheckedVarArgs);
6831 unsigned format_idx,
unsigned firstDataArg,
6835 llvm::SmallBitVector &CheckedVarArgs) {
6837 if (format_idx >= Args.size()) {
6842 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6856 UncoveredArgHandler UncoveredArg;
6858 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
6859 firstDataArg,
Type, CallType,
6860 true, CheckedVarArgs, UncoveredArg,
6861 llvm::APSInt(64,
false) = 0);
6864 if (UncoveredArg.hasUncoveredArg()) {
6865 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6866 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6867 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6870 if (CT != SLCT_NotALiteral)
6872 return CT == SLCT_CheckedLiteral;
6890 if (Args.size() == firstDataArg) {
6891 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6900 Diag(FormatLoc, diag::note_format_security_fixit)
6904 Diag(FormatLoc, diag::note_format_security_fixit)
6909 Diag(FormatLoc, diag::warn_format_nonliteral)
6920 const FormatStringLiteral *FExpr;
6921 const Expr *OrigFormatExpr;
6923 const unsigned FirstDataArg;
6924 const unsigned NumDataArgs;
6929 llvm::SmallBitVector CoveredArgs;
6930 bool usesPositionalArgs =
false;
6931 bool atFirstArg =
true;
6932 bool inFunctionCall;
6934 llvm::SmallBitVector &CheckedVarArgs;
6935 UncoveredArgHandler &UncoveredArg;
6938 CheckFormatHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6940 unsigned firstDataArg,
unsigned numDataArgs,
6944 llvm::SmallBitVector &CheckedVarArgs,
6945 UncoveredArgHandler &UncoveredArg)
6946 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6947 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6948 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6949 inFunctionCall(inFunctionCall), CallType(callType),
6950 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6951 CoveredArgs.resize(numDataArgs);
6952 CoveredArgs.reset();
6955 bool HasFormatArguments()
const {
6960 void DoneProcessing();
6962 void HandleIncompleteSpecifier(
const char *startSpecifier,
6963 unsigned specifierLen)
override;
6965 void HandleInvalidLengthModifier(
6968 const char *startSpecifier,
unsigned specifierLen,
6971 void HandleNonStandardLengthModifier(
6973 const char *startSpecifier,
unsigned specifierLen);
6975 void HandleNonStandardConversionSpecifier(
6977 const char *startSpecifier,
unsigned specifierLen);
6979 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
6981 void HandleInvalidPosition(
const char *startSpecifier,
6982 unsigned specifierLen,
6985 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
6987 void HandleNullChar(
const char *nullCharacter)
override;
6989 template <
typename Range>
6991 EmitFormatDiagnostic(
Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
6993 bool IsStringLocation,
Range StringRange,
6998 const char *startSpec,
6999 unsigned specifierLen,
7000 const char *csStart,
unsigned csLen);
7003 const char *startSpec,
7004 unsigned specifierLen);
7008 unsigned specifierLen);
7011 const Expr *getDataArg(
unsigned i)
const;
7015 const char *startSpecifier,
unsigned specifierLen,
7018 template <
typename Range>
7020 bool IsStringLocation,
Range StringRange,
7026SourceRange CheckFormatHandler::getFormatStringRange() {
7031getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7033 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7036 End = End.getLocWithOffset(1);
7041SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7046void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7047 unsigned specifierLen){
7048 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7049 getLocationOfByte(startSpecifier),
7051 getSpecifierRange(startSpecifier, specifierLen));
7054void CheckFormatHandler::HandleInvalidLengthModifier(
7057 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7058 using namespace analyze_format_string;
7060 const LengthModifier &LM = FS.getLengthModifier();
7061 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
7064 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
7066 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
7067 getLocationOfByte(LM.getStart()),
7069 getSpecifierRange(startSpecifier, specifierLen));
7071 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
7072 << FixedLM->toString()
7077 if (DiagID == diag::warn_format_nonsensical_length)
7080 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
7081 getLocationOfByte(LM.getStart()),
7083 getSpecifierRange(startSpecifier, specifierLen),
7088void CheckFormatHandler::HandleNonStandardLengthModifier(
7090 const char *startSpecifier,
unsigned specifierLen) {
7091 using namespace analyze_format_string;
7093 const LengthModifier &LM = FS.getLengthModifier();
7094 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
7097 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
7099 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7100 << LM.toString() << 0,
7101 getLocationOfByte(LM.getStart()),
7103 getSpecifierRange(startSpecifier, specifierLen));
7105 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
7106 << FixedLM->toString()
7110 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7111 << LM.toString() << 0,
7112 getLocationOfByte(LM.getStart()),
7114 getSpecifierRange(startSpecifier, specifierLen));
7118void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7120 const char *startSpecifier,
unsigned specifierLen) {
7121 using namespace analyze_format_string;
7126 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7130 getSpecifierRange(startSpecifier, specifierLen));
7133 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7134 << FixedCS->toString()
7137 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7141 getSpecifierRange(startSpecifier, specifierLen));
7145void CheckFormatHandler::HandlePosition(
const char *startPos,
7148 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7149 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7150 getLocationOfByte(startPos),
7152 getSpecifierRange(startPos, posLen));
7155void CheckFormatHandler::HandleInvalidPosition(
7156 const char *startSpecifier,
unsigned specifierLen,
7159 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7160 EmitFormatDiagnostic(
7161 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7162 getLocationOfByte(startSpecifier),
true,
7163 getSpecifierRange(startSpecifier, specifierLen));
7166void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7170 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7171 getLocationOfByte(startPos),
7173 getSpecifierRange(startPos, posLen));
7176void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7177 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {
7179 EmitFormatDiagnostic(
7180 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7181 getLocationOfByte(nullCharacter),
true,
7182 getFormatStringRange());
7188const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7189 return Args[FirstDataArg + i];
7192void CheckFormatHandler::DoneProcessing() {
7195 if (HasFormatArguments()) {
7198 signed notCoveredArg = CoveredArgs.find_first();
7199 if (notCoveredArg >= 0) {
7200 assert((
unsigned)notCoveredArg < NumDataArgs);
7201 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7203 UncoveredArg.setAllCovered();
7208void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7209 const Expr *ArgExpr) {
7210 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7222 for (
auto E : DiagnosticExprs)
7225 CheckFormatHandler::EmitFormatDiagnostic(
7226 S, IsFunctionCall, DiagnosticExprs[0],
7232CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7234 const char *startSpec,
7235 unsigned specifierLen,
7236 const char *csStart,
7238 bool keepGoing =
true;
7239 if (argIndex < NumDataArgs) {
7242 CoveredArgs.set(argIndex);
7258 std::string CodePointStr;
7259 if (!llvm::sys::locale::isPrint(*csStart)) {
7260 llvm::UTF32 CodePoint;
7261 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7262 const llvm::UTF8 *
E =
7263 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7264 llvm::ConversionResult
Result =
7265 llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
7267 if (
Result != llvm::conversionOK) {
7268 unsigned char FirstChar = *csStart;
7269 CodePoint = (llvm::UTF32)FirstChar;
7272 llvm::raw_string_ostream OS(CodePointStr);
7273 if (CodePoint < 256)
7274 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7275 else if (CodePoint <= 0xFFFF)
7276 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7278 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7282 EmitFormatDiagnostic(
7283 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier,
Loc,
7284 true, getSpecifierRange(startSpec, specifierLen));
7291 const char *startSpec,
7292 unsigned specifierLen) {
7293 EmitFormatDiagnostic(
7294 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7295 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7299CheckFormatHandler::CheckNumArgs(
7302 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7304 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7306 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7307 << (argIndex+1) << NumDataArgs)
7308 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7309 EmitFormatDiagnostic(
7310 PDiag, getLocationOfByte(CS.
getStart()),
true,
7311 getSpecifierRange(startSpecifier, specifierLen));
7315 UncoveredArg.setAllCovered();
7321template<
typename Range>
7324 bool IsStringLocation,
7327 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7328 Loc, IsStringLocation, StringRange, FixIt);
7358template <
typename Range>
7359void CheckFormatHandler::EmitFormatDiagnostic(
7360 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7363 if (InFunctionCall) {
7372 S.
Diag(IsStringLocation ?
Loc : StringRange.getBegin(),
7373 diag::note_format_string_defined);
7375 Note << StringRange;
7384class CheckPrintfHandler :
public CheckFormatHandler {
7386 CheckPrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7388 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7392 llvm::SmallBitVector &CheckedVarArgs,
7393 UncoveredArgHandler &UncoveredArg)
7394 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7395 numDataArgs, beg, APK, Args, formatIdx,
7396 inFunctionCall, CallType, CheckedVarArgs,
7399 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7402 bool allowsObjCArg()
const {
7403 return FSType == FormatStringType::NSString ||
7404 FSType == FormatStringType::OSLog ||
7405 FSType == FormatStringType::OSTrace;
7408 bool HandleInvalidPrintfConversionSpecifier(
7410 const char *startSpecifier,
7411 unsigned specifierLen)
override;
7413 void handleInvalidMaskType(StringRef MaskType)
override;
7416 const char *startSpecifier,
unsigned specifierLen,
7419 const char *StartSpecifier,
7420 unsigned SpecifierLen,
7424 const char *startSpecifier,
unsigned specifierLen);
7428 const char *startSpecifier,
unsigned specifierLen);
7431 const char *startSpecifier,
unsigned specifierLen);
7435 const char *startSpecifier,
unsigned specifierLen);
7439 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7440 unsigned flagLen)
override;
7442 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7443 unsigned flagLen)
override;
7446 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7447 const char *flagsEnd,
7448 const char *conversionPosition)
override;
7453class EquatableFormatArgument {
7455 enum SpecifierSensitivity :
unsigned {
7462 enum FormatArgumentRole :
unsigned {
7472 StringRef SpecifierLetter;
7475 FormatArgumentRole Role : 2;
7476 SpecifierSensitivity Sensitivity : 2;
7477 unsigned Position : 14;
7478 unsigned ModifierFor : 14;
7481 bool InFunctionCall)
const;
7486 StringRef SpecifierLetter,
7488 FormatArgumentRole Role,
7489 SpecifierSensitivity Sensitivity,
unsigned Position,
7490 unsigned ModifierFor)
7491 : ArgType(ArgType), LengthMod(LengthMod),
7492 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7493 Role(Role), Sensitivity(Sensitivity), Position(Position),
7494 ModifierFor(ModifierFor) {}
7496 unsigned getPosition()
const {
return Position; }
7502 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7504 std::string buildFormatSpecifier()
const {
7506 llvm::raw_string_ostream(result)
7507 << getLengthModifier().toString() << SpecifierLetter;
7511 bool VerifyCompatible(
Sema &S,
const EquatableFormatArgument &
Other,
7512 const Expr *FmtExpr,
bool InFunctionCall)
const;
7516class DecomposePrintfHandler :
public CheckPrintfHandler {
7520 DecomposePrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7521 const Expr *origFormatExpr,
7523 unsigned numDataArgs,
bool isObjC,
const char *beg,
7527 llvm::SmallBitVector &CheckedVarArgs,
7528 UncoveredArgHandler &UncoveredArg,
7530 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7531 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7532 inFunctionCall, CallType, CheckedVarArgs,
7534 Specs(Specs), HadError(
false) {}
7538 GetSpecifiers(
Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7543 const char *startSpecifier,
7544 unsigned specifierLen,
7550bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7552 unsigned specifierLen) {
7554 FS.getConversionSpecifier();
7556 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
7558 startSpecifier, specifierLen,
7562void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7563 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7566bool CheckPrintfHandler::HandleAmount(
7568 const char *startSpecifier,
unsigned specifierLen) {
7570 if (HasFormatArguments()) {
7572 if (argIndex >= NumDataArgs) {
7573 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
7577 getSpecifierRange(startSpecifier, specifierLen));
7587 CoveredArgs.set(argIndex);
7588 const Expr *Arg = getDataArg(argIndex);
7598 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
7603 getSpecifierRange(startSpecifier, specifierLen));
7613void CheckPrintfHandler::HandleInvalidAmount(
7617 const char *startSpecifier,
7618 unsigned specifierLen) {
7620 FS.getConversionSpecifier();
7628 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7632 getSpecifierRange(startSpecifier, specifierLen),
7638 const char *startSpecifier,
7639 unsigned specifierLen) {
7642 FS.getConversionSpecifier();
7643 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7647 getSpecifierRange(startSpecifier, specifierLen),
7652void CheckPrintfHandler::HandleIgnoredFlag(
7656 const char *startSpecifier,
7657 unsigned specifierLen) {
7659 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7663 getSpecifierRange(startSpecifier, specifierLen),
7665 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7668void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7671 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7672 getLocationOfByte(startFlag),
7674 getSpecifierRange(startFlag, flagLen));
7677void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7680 auto Range = getSpecifierRange(startFlag, flagLen);
7681 StringRef flag(startFlag, flagLen);
7682 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7683 getLocationOfByte(startFlag),
7688void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7689 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7691 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7692 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7693 EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
7694 getLocationOfByte(conversionPosition),
7700 const Expr *FmtExpr,
7701 bool InFunctionCall)
const {
7702 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
7703 ElementLoc,
true,
Range);
7706bool EquatableFormatArgument::VerifyCompatible(
7707 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
7708 bool InFunctionCall)
const {
7710 if (Role !=
Other.Role) {
7713 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) << Role <<
Other.Role,
7714 FmtExpr, InFunctionCall);
7715 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7719 if (Role != FAR_Data) {
7720 if (ModifierFor !=
Other.ModifierFor) {
7723 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
7724 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
7725 FmtExpr, InFunctionCall);
7726 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
7732 bool HadError =
false;
7733 if (Sensitivity !=
Other.Sensitivity) {
7736 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
7737 << Sensitivity <<
Other.Sensitivity,
7738 FmtExpr, InFunctionCall);
7739 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7740 << 0 <<
Other.Range;
7743 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
7747 case MK::MatchPromotion:
7751 case MK::NoMatchTypeConfusion:
7752 case MK::NoMatchPromotionTypeConfusion:
7754 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
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::NoMatchPedantic:
7764 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
7765 << buildFormatSpecifier()
7766 <<
Other.buildFormatSpecifier(),
7767 FmtExpr, InFunctionCall);
7768 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7769 << 0 <<
Other.Range;
7772 case MK::NoMatchSignedness:
7774 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
7775 << buildFormatSpecifier()
7776 <<
Other.buildFormatSpecifier(),
7777 FmtExpr, InFunctionCall);
7778 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
7779 << 0 <<
Other.Range;
7785bool DecomposePrintfHandler::GetSpecifiers(
7786 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7789 StringRef
Data = FSL->getString();
7790 const char *Str =
Data.data();
7791 llvm::SmallBitVector BV;
7792 UncoveredArgHandler UA;
7793 const Expr *PrintfArgs[] = {FSL->getFormatString()};
7794 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
7806 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
7807 const EquatableFormatArgument &B) {
7808 return A.getPosition() < B.getPosition();
7813bool DecomposePrintfHandler::HandlePrintfSpecifier(
7816 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
7826 const auto &CS = FS.getConversionSpecifier();
7831 const unsigned Unset = ~0;
7832 unsigned FieldWidthIndex = Unset;
7833 unsigned PrecisionIndex = Unset;
7836 const auto &FieldWidth = FS.getFieldWidth();
7837 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
7838 FieldWidthIndex = Specs.size();
7839 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
7840 getLocationOfByte(FieldWidth.getStart()),
7842 FieldWidth.getArgType(S.
Context),
7843 EquatableFormatArgument::FAR_FieldWidth,
7844 EquatableFormatArgument::SS_None,
7845 FieldWidth.usesPositionalArg()
7846 ? FieldWidth.getPositionalArgIndex() - 1
7851 const auto &Precision = FS.getPrecision();
7852 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
7853 PrecisionIndex = Specs.size();
7855 getSpecifierRange(startSpecifier, specifierLen),
7856 getLocationOfByte(Precision.getStart()),
7858 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
7859 EquatableFormatArgument::SS_None,
7860 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
7866 unsigned SpecIndex =
7867 FS.usesPositionalArg() ? FS.getPositionalArgIndex() - 1 : Specs.size();
7868 if (FieldWidthIndex != Unset)
7869 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
7870 if (PrecisionIndex != Unset)
7871 Specs[PrecisionIndex].setModifierFor(SpecIndex);
7873 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
7875 Sensitivity = EquatableFormatArgument::SS_Private;
7876 else if (FS.isPublic())
7877 Sensitivity = EquatableFormatArgument::SS_Public;
7878 else if (FS.isSensitive())
7879 Sensitivity = EquatableFormatArgument::SS_Sensitive;
7881 Sensitivity = EquatableFormatArgument::SS_None;
7884 getSpecifierRange(startSpecifier, specifierLen),
7885 getLocationOfByte(CS.
getStart()), FS.getLengthModifier().getKind(),
7887 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
7892 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
7897 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
7898 SpecIndex + 1, SpecIndex);
7906template<
typename MemberKind>
7924 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
7938 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
7939 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7941 if ((*MI)->getMinRequiredArguments() == 0)
7949bool CheckPrintfHandler::checkForCStrMembers(
7954 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
7956 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7959 if (
Method->getMinRequiredArguments() == 0 &&
7972bool CheckPrintfHandler::HandlePrintfSpecifier(
7975 using namespace analyze_format_string;
7976 using namespace analyze_printf;
7978 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
7980 if (FS.consumesDataArgument()) {
7983 usesPositionalArgs = FS.usesPositionalArg();
7985 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7986 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7987 startSpecifier, specifierLen);
7994 if (!HandleAmount(FS.getFieldWidth(), 0,
7995 startSpecifier, specifierLen)) {
7999 if (!HandleAmount(FS.getPrecision(), 1,
8000 startSpecifier, specifierLen)) {
8004 if (!CS.consumesDataArgument()) {
8011 unsigned argIndex = FS.getArgIndex();
8012 if (argIndex < NumDataArgs) {
8016 CoveredArgs.set(argIndex);
8020 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
8021 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
8023 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8026 if (HasFormatArguments()) {
8028 CoveredArgs.set(argIndex + 1);
8031 const Expr *Ex = getDataArg(argIndex);
8033 (CS.getKind() == ConversionSpecifier::FreeBSDbArg)
8035 : ArgType::CPointerTy;
8037 EmitFormatDiagnostic(
8038 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8042 getSpecifierRange(startSpecifier, specifierLen));
8045 Ex = getDataArg(argIndex + 1);
8048 EmitFormatDiagnostic(
8049 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8053 getSpecifierRange(startSpecifier, specifierLen));
8060 if (!allowsObjCArg() && CS.isObjCArg()) {
8061 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8067 CS.getKind() == ConversionSpecifier::PArg) {
8068 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8074 CS.getKind() == ConversionSpecifier::nArg) {
8075 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8076 getLocationOfByte(CS.getStart()),
8078 getSpecifierRange(startSpecifier, specifierLen));
8085 (CS.getKind() == ConversionSpecifier::PArg ||
8086 CS.getKind() == ConversionSpecifier::sArg ||
8087 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
8088 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8094 if (FS.isPublic().isSet()) {
8095 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8097 getLocationOfByte(FS.isPublic().getPosition()),
8099 getSpecifierRange(startSpecifier, specifierLen));
8101 if (FS.isPrivate().isSet()) {
8102 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8104 getLocationOfByte(FS.isPrivate().getPosition()),
8106 getSpecifierRange(startSpecifier, specifierLen));
8110 const llvm::Triple &Triple =
Target.getTriple();
8111 if (CS.getKind() == ConversionSpecifier::nArg &&
8112 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8113 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8114 getLocationOfByte(CS.getStart()),
8116 getSpecifierRange(startSpecifier, specifierLen));
8120 if (!FS.hasValidFieldWidth()) {
8121 HandleInvalidAmount(FS, FS.getFieldWidth(), 0,
8122 startSpecifier, specifierLen);
8126 if (!FS.hasValidPrecision()) {
8127 HandleInvalidAmount(FS, FS.getPrecision(), 1,
8128 startSpecifier, specifierLen);
8132 if (CS.getKind() == ConversionSpecifier::PArg &&
8133 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
8134 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8135 getLocationOfByte(startSpecifier),
8137 getSpecifierRange(startSpecifier, specifierLen));
8141 if (!FS.hasValidThousandsGroupingPrefix())
8142 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
8143 if (!FS.hasValidLeadingZeros())
8144 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
8145 if (!FS.hasValidPlusPrefix())
8146 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
8147 if (!FS.hasValidSpacePrefix())
8148 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
8149 if (!FS.hasValidAlternativeForm())
8150 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
8151 if (!FS.hasValidLeftJustified())
8152 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
8155 if (FS.hasSpacePrefix() && FS.hasPlusPrefix())
8156 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
8157 startSpecifier, specifierLen);
8158 if (FS.hasLeadingZeros() && FS.isLeftJustified())
8159 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
8160 startSpecifier, specifierLen);
8165 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8166 diag::warn_format_nonsensical_length);
8167 else if (!FS.hasStandardLengthModifier())
8168 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8169 else if (!FS.hasStandardLengthConversionCombination())
8170 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8171 diag::warn_format_non_standard_conversion_spec);
8173 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
8174 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8177 if (!HasFormatArguments())
8180 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8183 const Expr *Arg = getDataArg(argIndex);
8187 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8199 case Stmt::ArraySubscriptExprClass:
8200 case Stmt::CallExprClass:
8201 case Stmt::CharacterLiteralClass:
8202 case Stmt::CXXBoolLiteralExprClass:
8203 case Stmt::DeclRefExprClass:
8204 case Stmt::FloatingLiteralClass:
8205 case Stmt::IntegerLiteralClass:
8206 case Stmt::MemberExprClass:
8207 case Stmt::ObjCArrayLiteralClass:
8208 case Stmt::ObjCBoolLiteralExprClass:
8209 case Stmt::ObjCBoxedExprClass:
8210 case Stmt::ObjCDictionaryLiteralClass:
8211 case Stmt::ObjCEncodeExprClass:
8212 case Stmt::ObjCIvarRefExprClass:
8213 case Stmt::ObjCMessageExprClass:
8214 case Stmt::ObjCPropertyRefExprClass:
8215 case Stmt::ObjCStringLiteralClass:
8216 case Stmt::ObjCSubscriptRefExprClass:
8217 case Stmt::ParenExprClass:
8218 case Stmt::StringLiteralClass:
8219 case Stmt::UnaryOperatorClass:
8226static std::pair<QualType, StringRef>
8233 StringRef Name = UserTy->getDecl()->getName();
8234 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8238 .Case(
"SInt32", Context.
IntTy)
8243 return std::make_pair(CastTy, Name);
8245 TyTy = UserTy->desugar();
8249 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(
E))
8251 PE->getSubExpr()->getType(),
8260 StringRef TrueName, FalseName;
8262 std::tie(TrueTy, TrueName) =
8264 CO->getTrueExpr()->getType(),
8266 std::tie(FalseTy, FalseName) =
8268 CO->getFalseExpr()->getType(),
8269 CO->getFalseExpr());
8271 if (TrueTy == FalseTy)
8272 return std::make_pair(TrueTy, TrueName);
8273 else if (TrueTy.
isNull())
8274 return std::make_pair(FalseTy, FalseName);
8275 else if (FalseTy.
isNull())
8276 return std::make_pair(TrueTy, TrueName);
8279 return std::make_pair(
QualType(), StringRef());
8298 From = VecTy->getElementType();
8300 To = VecTy->getElementType();
8311 diag::warn_format_conversion_argument_type_mismatch_signedness,
8315 diag::warn_format_conversion_argument_type_mismatch,
Loc)) {
8324 const char *StartSpecifier,
8325 unsigned SpecifierLen,
8327 using namespace analyze_format_string;
8328 using namespace analyze_printf;
8337 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8338 ExprTy = TET->getUnderlyingExpr()->getType();
8350 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
8353 getSpecifierRange(StartSpecifier, SpecifierLen);
8355 llvm::raw_svector_ostream os(FSString);
8357 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8365 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
8368 getSpecifierRange(StartSpecifier, SpecifierLen);
8369 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8374 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
8376 ArgType::MatchKind OrigMatch =
Match;
8379 if (
Match == ArgType::Match)
8383 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8392 E = ICE->getSubExpr();
8402 if (OrigMatch == ArgType::NoMatchSignedness &&
8403 ImplicitMatch != ArgType::NoMatchSignedness)
8410 if (ImplicitMatch == ArgType::Match)
8421 FS.getLengthModifier().getKind() != LengthModifier::AsChar)
8428 if (
Match == ArgType::MatchPromotion)
8429 Match = ArgType::NoMatch;
8432 if (
Match == ArgType::MatchPromotion) {
8436 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8437 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8439 Match = ArgType::NoMatch;
8441 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8442 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8443 Match = ImplicitMatch;
8444 assert(
Match != ArgType::MatchPromotion);
8447 bool IsEnum =
false;
8448 bool IsScopedEnum =
false;
8451 IntendedTy = ED->getIntegerType();
8452 if (!ED->isScoped()) {
8453 ExprTy = IntendedTy;
8458 IsScopedEnum =
true;
8465 if (isObjCContext() &&
8466 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
8476 const llvm::APInt &
V = IL->getValue();
8486 if (TD->getUnderlyingType() == IntendedTy)
8496 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8504 if (!IsScopedEnum &&
8505 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8508 Match = ArgType::NoMatchPedantic;
8509 IntendedTy = CastTy;
8510 ShouldNotPrintDirectly =
true;
8515 PrintfSpecifier fixedFS = FS;
8522 llvm::raw_svector_ostream os(buf);
8523 fixedFS.toString(os);
8525 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8527 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8530 case ArgType::Match:
8531 case ArgType::MatchPromotion:
8532 case ArgType::NoMatchPromotionTypeConfusion:
8533 llvm_unreachable(
"expected non-matching");
8534 case ArgType::NoMatchSignedness:
8535 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8537 case ArgType::NoMatchPedantic:
8538 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8540 case ArgType::NoMatchTypeConfusion:
8541 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8543 case ArgType::NoMatch:
8544 Diag = diag::warn_format_conversion_argument_type_mismatch;
8565 llvm::raw_svector_ostream CastFix(CastBuf);
8566 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
8568 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
8574 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
8579 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
8601 if (ShouldNotPrintDirectly && !IsScopedEnum) {
8607 Name = TypedefTy->getDecl()->getName();
8610 unsigned Diag =
Match == ArgType::NoMatchPedantic
8611 ? diag::warn_format_argument_needs_cast_pedantic
8612 : diag::warn_format_argument_needs_cast;
8613 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
8624 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8625 : diag::warn_format_conversion_argument_type_mismatch;
8627 EmitFormatDiagnostic(
8639 bool EmitTypeMismatch =
false;
8645 case ArgType::Match:
8646 case ArgType::MatchPromotion:
8647 case ArgType::NoMatchPromotionTypeConfusion:
8648 case ArgType::NoMatchSignedness:
8649 llvm_unreachable(
"expected non-matching");
8650 case ArgType::NoMatchPedantic:
8651 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8653 case ArgType::NoMatchTypeConfusion:
8654 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8656 case ArgType::NoMatch:
8657 Diag = diag::warn_format_conversion_argument_type_mismatch;
8661 EmitFormatDiagnostic(
8670 EmitTypeMismatch =
true;
8672 EmitFormatDiagnostic(
8673 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
8674 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8678 checkForCStrMembers(AT,
E);
8684 EmitTypeMismatch =
true;
8686 EmitFormatDiagnostic(
8687 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
8688 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
8696 << isa<InitListExpr>(
E) << ExprTy << CallType
8701 if (EmitTypeMismatch) {
8707 EmitFormatDiagnostic(
8708 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8714 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
8715 "format string specifier index out of range");
8716 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
8726class CheckScanfHandler :
public CheckFormatHandler {
8728 CheckScanfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
8730 unsigned firstDataArg,
unsigned numDataArgs,
8734 llvm::SmallBitVector &CheckedVarArgs,
8735 UncoveredArgHandler &UncoveredArg)
8736 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8737 numDataArgs, beg, APK, Args, formatIdx,
8738 inFunctionCall, CallType, CheckedVarArgs,
8742 const char *startSpecifier,
8743 unsigned specifierLen)
override;
8745 bool HandleInvalidScanfConversionSpecifier(
8747 const char *startSpecifier,
8748 unsigned specifierLen)
override;
8750 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
8755void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
8757 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
8758 getLocationOfByte(end),
true,
8759 getSpecifierRange(start, end - start));
8762bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
8764 const char *startSpecifier,
8765 unsigned specifierLen) {
8767 FS.getConversionSpecifier();
8769 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
8771 startSpecifier, specifierLen,
8775bool CheckScanfHandler::HandleScanfSpecifier(
8777 const char *startSpecifier,
8778 unsigned specifierLen) {
8779 using namespace analyze_scanf;
8780 using namespace analyze_format_string;
8782 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
8786 if (FS.consumesDataArgument()) {
8789 usesPositionalArgs = FS.usesPositionalArg();
8791 else if (usesPositionalArgs != FS.usesPositionalArg()) {
8792 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8793 startSpecifier, specifierLen);
8799 const OptionalAmount &Amt = FS.getFieldWidth();
8800 if (Amt.getHowSpecified() == OptionalAmount::Constant) {
8801 if (Amt.getConstantAmount() == 0) {
8803 Amt.getConstantLength());
8804 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
8805 getLocationOfByte(Amt.getStart()),
8811 if (!FS.consumesDataArgument()) {
8818 unsigned argIndex = FS.getArgIndex();
8819 if (argIndex < NumDataArgs) {
8823 CoveredArgs.set(argIndex);
8829 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8830 diag::warn_format_nonsensical_length);
8831 else if (!FS.hasStandardLengthModifier())
8832 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8833 else if (!FS.hasStandardLengthConversionCombination())
8834 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8835 diag::warn_format_non_standard_conversion_spec);
8837 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
8838 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8841 if (!HasFormatArguments())
8844 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8848 const Expr *Ex = getDataArg(argIndex);
8866 ScanfSpecifier fixedFS = FS;
8871 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8873 ? diag::warn_format_conversion_argument_type_mismatch_signedness
8874 : diag::warn_format_conversion_argument_type_mismatch;
8879 llvm::raw_svector_ostream os(buf);
8880 fixedFS.toString(os);
8882 EmitFormatDiagnostic(
8887 getSpecifierRange(startSpecifier, specifierLen),
8889 getSpecifierRange(startSpecifier, specifierLen), os.str()));
8896 getSpecifierRange(startSpecifier, specifierLen));
8906 const Expr *FmtExpr,
bool InFunctionCall) {
8907 bool HadError =
false;
8908 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
8909 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
8910 while (FmtIter < FmtEnd && RefIter < RefEnd) {
8922 for (; FmtIter < FmtEnd; ++FmtIter) {
8926 if (FmtIter->getPosition() < RefIter->getPosition())
8930 if (FmtIter->getPosition() > RefIter->getPosition())
8934 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
8938 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
8939 return Arg.getPosition() != RefIter->getPosition();
8943 if (FmtIter < FmtEnd) {
8944 CheckFormatHandler::EmitFormatDiagnostic(
8945 S, InFunctionCall, FmtExpr,
8946 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
8947 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
8948 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
8949 }
else if (RefIter < RefEnd) {
8950 CheckFormatHandler::EmitFormatDiagnostic(
8951 S, InFunctionCall, FmtExpr,
8952 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
8955 << 1 << RefIter->getSourceRange();
8961 Sema &S,
const FormatStringLiteral *FExpr,
8966 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
8967 bool IgnoreStringsWithoutSpecifiers) {
8969 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
8970 CheckFormatHandler::EmitFormatDiagnostic(
8971 S, inFunctionCall, Args[format_idx],
8972 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
8978 StringRef StrRef = FExpr->getString();
8979 const char *Str = StrRef.data();
8983 assert(
T &&
"String literal not of constant array type!");
8984 size_t TypeSize =
T->getZExtSize();
8985 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8986 const unsigned numDataArgs = Args.size() - firstDataArg;
8988 if (IgnoreStringsWithoutSpecifiers &&
8995 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
8996 CheckFormatHandler::EmitFormatDiagnostic(
8997 S, inFunctionCall, Args[format_idx],
8998 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
8999 FExpr->getBeginLoc(),
9005 if (StrLen == 0 && numDataArgs > 0) {
9006 CheckFormatHandler::EmitFormatDiagnostic(
9007 S, inFunctionCall, Args[format_idx],
9008 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9020 if (ReferenceFormatString ==
nullptr) {
9021 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9022 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9023 inFunctionCall, CallType, CheckedVarArgs,
9033 Type, ReferenceFormatString, FExpr->getFormatString(),
9034 inFunctionCall ?
nullptr : Args[format_idx]);
9037 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9038 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9039 CallType, CheckedVarArgs, UncoveredArg);
9060 FormatStringLiteral RefLit = AuthoritativeFormatString;
9061 FormatStringLiteral TestLit = TestedFormatString;
9063 bool DiagAtStringLiteral;
9064 if (FunctionCallArg) {
9065 Arg = FunctionCallArg;
9066 DiagAtStringLiteral =
false;
9068 Arg = TestedFormatString;
9069 DiagAtStringLiteral =
true;
9071 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9072 AuthoritativeFormatString,
Type,
9073 IsObjC,
true, RefArgs) &&
9074 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9075 DiagAtStringLiteral, FmtArgs)) {
9077 TestedFormatString, FmtArgs, Arg,
9078 DiagAtStringLiteral);
9092 FormatStringLiteral RefLit = Str;
9096 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9105 bool HadError =
false;
9106 auto Iter = Args.begin();
9107 auto End = Args.end();
9108 while (
Iter != End) {
9109 const auto &FirstInGroup = *
Iter;
9111 Iter != End &&
Iter->getPosition() == FirstInGroup.getPosition();
9113 HadError |= !
Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9122 const char *Str = StrRef.data();
9125 assert(
T &&
"String literal not of constant array type!");
9126 size_t TypeSize =
T->getZExtSize();
9127 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9138 switch (AbsFunction) {
9142 case Builtin::BI__builtin_abs:
9143 return Builtin::BI__builtin_labs;
9144 case Builtin::BI__builtin_labs:
9145 return Builtin::BI__builtin_llabs;
9146 case Builtin::BI__builtin_llabs:
9149 case Builtin::BI__builtin_fabsf:
9150 return Builtin::BI__builtin_fabs;
9151 case Builtin::BI__builtin_fabs:
9152 return Builtin::BI__builtin_fabsl;
9153 case Builtin::BI__builtin_fabsl:
9156 case Builtin::BI__builtin_cabsf:
9157 return Builtin::BI__builtin_cabs;
9158 case Builtin::BI__builtin_cabs:
9159 return Builtin::BI__builtin_cabsl;
9160 case Builtin::BI__builtin_cabsl:
9163 case Builtin::BIabs:
9164 return Builtin::BIlabs;
9165 case Builtin::BIlabs:
9166 return Builtin::BIllabs;
9167 case Builtin::BIllabs:
9170 case Builtin::BIfabsf:
9171 return Builtin::BIfabs;
9172 case Builtin::BIfabs:
9173 return Builtin::BIfabsl;
9174 case Builtin::BIfabsl:
9177 case Builtin::BIcabsf:
9178 return Builtin::BIcabs;
9179 case Builtin::BIcabs:
9180 return Builtin::BIcabsl;
9181 case Builtin::BIcabsl:
9210 unsigned AbsFunctionKind) {
9211 unsigned BestKind = 0;
9213 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9219 else if (Context.
hasSameType(ParamType, ArgType)) {
9242 llvm_unreachable(
"Type not integer, floating, or complex");
9249 switch (ValueKind) {
9254 case Builtin::BI__builtin_fabsf:
9255 case Builtin::BI__builtin_fabs:
9256 case Builtin::BI__builtin_fabsl:
9257 case Builtin::BI__builtin_cabsf:
9258 case Builtin::BI__builtin_cabs:
9259 case Builtin::BI__builtin_cabsl:
9260 return Builtin::BI__builtin_abs;
9261 case Builtin::BIfabsf:
9262 case Builtin::BIfabs:
9263 case Builtin::BIfabsl:
9264 case Builtin::BIcabsf:
9265 case Builtin::BIcabs:
9266 case Builtin::BIcabsl:
9267 return Builtin::BIabs;
9273 case Builtin::BI__builtin_abs:
9274 case Builtin::BI__builtin_labs:
9275 case Builtin::BI__builtin_llabs:
9276 case Builtin::BI__builtin_cabsf:
9277 case Builtin::BI__builtin_cabs:
9278 case Builtin::BI__builtin_cabsl:
9279 return Builtin::BI__builtin_fabsf;
9280 case Builtin::BIabs:
9281 case Builtin::BIlabs:
9282 case Builtin::BIllabs:
9283 case Builtin::BIcabsf:
9284 case Builtin::BIcabs:
9285 case Builtin::BIcabsl:
9286 return Builtin::BIfabsf;
9292 case Builtin::BI__builtin_abs:
9293 case Builtin::BI__builtin_labs:
9294 case Builtin::BI__builtin_llabs:
9295 case Builtin::BI__builtin_fabsf:
9296 case Builtin::BI__builtin_fabs:
9297 case Builtin::BI__builtin_fabsl:
9298 return Builtin::BI__builtin_cabsf;
9299 case Builtin::BIabs:
9300 case Builtin::BIlabs:
9301 case Builtin::BIllabs:
9302 case Builtin::BIfabsf:
9303 case Builtin::BIfabs:
9304 case Builtin::BIfabsl:
9305 return Builtin::BIcabsf;
9308 llvm_unreachable(
"Unable to convert function");
9319 case Builtin::BI__builtin_abs:
9320 case Builtin::BI__builtin_fabs:
9321 case Builtin::BI__builtin_fabsf:
9322 case Builtin::BI__builtin_fabsl:
9323 case Builtin::BI__builtin_labs:
9324 case Builtin::BI__builtin_llabs:
9325 case Builtin::BI__builtin_cabs:
9326 case Builtin::BI__builtin_cabsf:
9327 case Builtin::BI__builtin_cabsl:
9328 case Builtin::BIabs:
9329 case Builtin::BIlabs:
9330 case Builtin::BIllabs:
9331 case Builtin::BIfabs:
9332 case Builtin::BIfabsf:
9333 case Builtin::BIfabsl:
9334 case Builtin::BIcabs:
9335 case Builtin::BIcabsf:
9336 case Builtin::BIcabsl:
9339 llvm_unreachable(
"Unknown Builtin type");
9345 unsigned AbsKind,
QualType ArgType) {
9346 bool EmitHeaderHint =
true;
9347 const char *HeaderName =
nullptr;
9348 std::string FunctionName;
9350 FunctionName =
"std::abs";
9352 HeaderName =
"cstdlib";
9354 HeaderName =
"cmath";
9356 llvm_unreachable(
"Invalid Type");
9365 for (
const auto *I : R) {
9368 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9370 FDecl = dyn_cast<FunctionDecl>(I);
9385 EmitHeaderHint =
false;
9403 EmitHeaderHint =
false;
9407 }
else if (!R.
empty()) {
9413 S.
Diag(
Loc, diag::note_replace_abs_function)
9419 if (!EmitHeaderHint)
9422 S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
9426template <std::
size_t StrLen>
9428 const char (&Str)[StrLen]) {
9441 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9442 return llvm::is_contained(names, calleeName);
9446 case MathCheck::NaN:
9447 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9448 "__builtin_nanf16",
"__builtin_nanf128"});
9449 case MathCheck::Inf:
9450 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9451 "__builtin_inff16",
"__builtin_inff128"});
9453 llvm_unreachable(
"unknown MathCheck");
9457 if (FDecl->
getName() !=
"infinity")
9460 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9462 if (RDecl->
getName() !=
"numeric_limits")
9479 if (FPO.getNoHonorNaNs() &&
9482 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9483 << 1 << 0 <<
Call->getSourceRange();
9487 if (FPO.getNoHonorInfs() &&
9491 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9492 << 0 << 0 <<
Call->getSourceRange();
9496void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9498 if (
Call->getNumArgs() != 1)
9503 if (AbsKind == 0 && !IsStdAbs)
9506 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9512 std::string FunctionName =
9514 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9515 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9544 if (ArgValueKind == ParamValueKind) {
9549 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9550 << FDecl << ArgType << ParamType;
9552 if (NewAbsKind == 0)
9556 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9565 if (NewAbsKind == 0)
9568 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
9569 << FDecl << ParamValueKind << ArgValueKind;
9572 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9578 if (!
Call || !FDecl)
return;
9582 if (
Call->getExprLoc().isMacroID())
return;
9585 if (
Call->getNumArgs() != 2)
return;
9588 if (!ArgList)
return;
9589 if (ArgList->size() != 1)
return;
9592 const auto& TA = ArgList->
get(0);
9598 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
9599 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
9600 if (!MTE)
return false;
9601 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
9602 if (!
Num)
return false;
9603 if (
Num->getValue() != 0)
return false;
9607 const Expr *FirstArg =
Call->getArg(0);
9608 const Expr *SecondArg =
Call->getArg(1);
9609 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
9610 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
9613 if (IsFirstArgZero == IsSecondArgZero)
return;
9618 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
9620 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
9621 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
9625 if (IsFirstArgZero) {
9633 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
9648 const auto *Size = dyn_cast<BinaryOperator>(
E);
9653 if (!Size->isComparisonOp() && !Size->isLogicalOp())
9657 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
9658 << SizeRange << FnName;
9659 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
9664 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
9675 bool &IsContained) {
9678 IsContained =
false;
9691 for (
auto *FD : RD->
fields()) {
9704 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
9705 if (Unary->getKind() == UETT_SizeOf)
9714 if (!
SizeOf->isArgumentType())
9715 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
9722 return SizeOf->getTypeOfArgument();
9728struct SearchNonTrivialToInitializeField
9733 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
9737 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9738 asDerived().visitArray(PDIK, AT, SL);
9742 Super::visitWithKind(PDIK, FT, SL);
9757 visit(getContext().getBaseElementType(AT), SL);
9762 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
9771struct SearchNonTrivialToCopyField
9775 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
9779 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
9780 asDerived().visitArray(PCK, AT, SL);
9784 Super::visitWithKind(PCK, FT, SL);
9802 visit(getContext().getBaseElementType(AT), SL);
9825 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
9826 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
9850 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
9852 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
9853 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
9859 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
9862 const Expr *SizeArg =
9863 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
9865 auto isLiteralZero = [](
const Expr *
E) {
9866 return (isa<IntegerLiteral>(
E) &&
9867 cast<IntegerLiteral>(
E)->getValue() == 0) ||
9868 (isa<CharacterLiteral>(
E) &&
9869 cast<CharacterLiteral>(
E)->getValue() == 0);
9875 if (isLiteralZero(SizeArg) &&
9882 if (BId == Builtin::BIbzero ||
9885 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
9886 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
9887 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
9888 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
9889 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
9897 if (BId == Builtin::BImemset &&
9901 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
9902 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
9907void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
9914 unsigned ExpectedNumArgs =
9915 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
9916 if (
Call->getNumArgs() < ExpectedNumArgs)
9919 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
9920 BId == Builtin::BIstrndup ? 1 : 2);
9922 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
9923 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
9926 Call->getBeginLoc(),
Call->getRParenLoc()))
9935 llvm::FoldingSetNodeID SizeOfArgID;
9940 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9944 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
9945 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
9967 if (SizeOfArgID == llvm::FoldingSetNodeID())
9969 llvm::FoldingSetNodeID DestID;
9971 if (DestID == SizeOfArgID) {
9974 unsigned ActionIdx = 0;
9975 StringRef ReadableName = FnName->
getName();
9977 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
9978 if (UnaryOp->getOpcode() == UO_AddrOf)
9992 if (
SM.isMacroArgExpansion(SL)) {
9994 SL =
SM.getSpellingLoc(SL);
10002 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10009 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10024 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10025 << FnName << SizeOfArgTy << ArgIdx
10032 PointeeTy = DestTy;
10043 unsigned OperationType = 0;
10044 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10047 if (ArgIdx != 0 || IsCmp) {
10048 if (BId == Builtin::BImemcpy)
10050 else if(BId == Builtin::BImemmove)
10057 PDiag(diag::warn_dyn_class_memaccess)
10058 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10059 << IsContained << ContainedRD << OperationType
10060 <<
Call->getCallee()->getSourceRange());
10062 BId != Builtin::BImemset)
10065 PDiag(diag::warn_arc_object_memaccess)
10066 << ArgIdx << FnName << PointeeTy
10067 <<
Call->getCallee()->getSourceRange());
10074 bool NonTriviallyCopyableCXXRecord =
10078 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10081 PDiag(diag::warn_cstruct_memaccess)
10082 << ArgIdx << FnName << PointeeTy << 0);
10083 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10084 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10085 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10089 PDiag(diag::warn_cxxstruct_memaccess)
10090 << FnName << PointeeTy);
10091 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10094 PDiag(diag::warn_cstruct_memaccess)
10095 << ArgIdx << FnName << PointeeTy << 1);
10096 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10097 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10098 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10102 PDiag(diag::warn_cxxstruct_memaccess)
10103 << FnName << PointeeTy);
10112 PDiag(diag::note_bad_memaccess_silence)
10132 if (isa<IntegerLiteral>(RHS))
10134 else if (isa<IntegerLiteral>(LHS))
10148 if (CAT->getZExtSize() <= 1)
10156void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10160 unsigned NumArgs =
Call->getNumArgs();
10161 if ((NumArgs != 3) && (NumArgs != 4))
10166 const Expr *CompareWithSrc =
nullptr;
10169 Call->getBeginLoc(),
Call->getRParenLoc()))
10174 CompareWithSrc = Ex;
10177 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10178 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10179 SizeCall->getNumArgs() == 1)
10184 if (!CompareWithSrc)
10191 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10195 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10196 if (!CompareWithSrcDRE ||
10200 const Expr *OriginalSizeArg =
Call->getArg(2);
10201 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10208 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10213 llvm::raw_svector_ostream
OS(sizeString);
10218 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10225 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10226 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10227 return D1->getDecl() == D2->getDecl();
10232 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
10241void Sema::CheckStrncatArguments(
const CallExpr *CE,
10256 unsigned PatternType = 0;
10264 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10265 if (BE->getOpcode() == BO_Sub) {
10278 if (PatternType == 0)
10287 if (
SM.isMacroArgExpansion(SL)) {
10288 SL =
SM.getSpellingLoc(SL);
10297 if (!isKnownSizeArray) {
10298 if (PatternType == 1)
10299 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10301 Diag(SL, diag::warn_strncat_src_size) << SR;
10305 if (PatternType == 1)
10306 Diag(SL, diag::warn_strncat_large_size) << SR;
10308 Diag(SL, diag::warn_strncat_src_size) << SR;
10311 llvm::raw_svector_ostream
OS(sizeString);
10319 Diag(SL, diag::note_strncat_wrong_size)
10324void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10326 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
10328 << CalleeName << 0 << cast<NamedDecl>(
D);
10333void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10335 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10336 const Decl *
D = Lvalue->getDecl();
10337 if (
const auto *DD = dyn_cast<DeclaratorDecl>(
D)) {
10338 if (!DD->getType()->isReferenceType())
10339 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
10343 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10344 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10345 Lvalue->getMemberDecl());
10348void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10350 const auto *Lambda = dyn_cast<LambdaExpr>(
10355 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10356 << CalleeName << 2 ;
10359void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10361 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10362 if (Var ==
nullptr)
10366 << CalleeName << 0 << Var;
10369void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10372 llvm::raw_svector_ostream OS(SizeString);
10375 if (Kind == clang::CK_BitCast &&
10376 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10378 if (Kind == clang::CK_IntegralToPointer &&
10379 !isa<IntegerLiteral>(
10380 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10383 switch (
Cast->getCastKind()) {
10384 case clang::CK_BitCast:
10385 case clang::CK_IntegralToPointer:
10386 case clang::CK_FunctionToPointerDecay:
10395 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10396 << CalleeName << 0 << OS.str();
10400void Sema::CheckFreeArguments(
const CallExpr *
E) {
10401 const std::string CalleeName =
10402 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
10406 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10408 case UnaryOperator::Opcode::UO_AddrOf:
10409 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10410 case UnaryOperator::Opcode::UO_Plus:
10411 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10416 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10418 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10420 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
10421 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
10422 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
10426 if (isa<BlockExpr>(Arg)) {
10428 << CalleeName << 1 ;
10433 if (
const auto *Cast = dyn_cast<CastExpr>(
E->getArg(0)))
10434 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10438Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10444 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
10447 Diag(ReturnLoc, diag::warn_null_ret)
10457 if (Op == OO_New || Op == OO_Array_New) {
10462 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10468 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10485 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10486 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10488 return FPLiteral && FPCast;
10491 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10497 llvm::APFloat TargetC = FPLiteral->
getValue();
10499 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10503 Diag(
Loc, diag::warn_float_compare_literal)
10504 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10517 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10518 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10519 if (DRL->getDecl() == DRR->getDecl())
10527 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10528 if (FLL->isExact())
10530 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10531 if (FLR->isExact())
10535 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10536 CL &&
CL->getBuiltinCallee())
10539 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10540 CR && CR->getBuiltinCallee())
10544 Diag(
Loc, diag::warn_floatingpoint_eq)
10565 IntRange(
unsigned Width,
bool NonNegative)
10566 : Width(Width), NonNegative(NonNegative) {}
10569 unsigned valueBits()
const {
10570 return NonNegative ? Width : Width - 1;
10574 static IntRange forBoolType() {
10575 return IntRange(1,
true);
10580 return forValueOfCanonicalType(
C,
10588 if (
const auto *VT = dyn_cast<VectorType>(
T))
10589 T = VT->getElementType().getTypePtr();
10590 if (
const auto *CT = dyn_cast<ComplexType>(
T))
10591 T = CT->getElementType().getTypePtr();
10592 if (
const auto *AT = dyn_cast<AtomicType>(
T))
10593 T = AT->getValueType().getTypePtr();
10595 if (!
C.getLangOpts().CPlusPlus) {
10598 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
10603 if (
Enum->isFixed()) {
10604 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
10605 !
Enum->getIntegerType()->isSignedIntegerType());
10608 unsigned NumPositive =
Enum->getNumPositiveBits();
10609 unsigned NumNegative =
Enum->getNumNegativeBits();
10611 if (NumNegative == 0)
10612 return IntRange(NumPositive,
true);
10614 return IntRange(std::max(NumPositive + 1, NumNegative),
10618 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10619 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10635 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
10636 T = VT->getElementType().getTypePtr();
10638 T = CT->getElementType().getTypePtr();
10639 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
10640 T = AT->getValueType().getTypePtr();
10642 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
10644 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
10645 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
10654 static IntRange join(IntRange L, IntRange R) {
10655 bool Unsigned = L.NonNegative && R.NonNegative;
10656 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
10657 L.NonNegative && R.NonNegative);
10661 static IntRange bit_and(IntRange L, IntRange R) {
10662 unsigned Bits = std::max(L.Width, R.Width);
10663 bool NonNegative =
false;
10664 if (L.NonNegative) {
10665 Bits = std::min(Bits, L.Width);
10666 NonNegative =
true;
10668 if (R.NonNegative) {
10669 Bits = std::min(Bits, R.Width);
10670 NonNegative =
true;
10672 return IntRange(Bits, NonNegative);
10676 static IntRange sum(IntRange L, IntRange R) {
10677 bool Unsigned = L.NonNegative && R.NonNegative;
10678 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
10683 static IntRange difference(IntRange L, IntRange R) {
10687 bool CanWiden = !L.NonNegative || !R.NonNegative;
10688 bool Unsigned = L.NonNegative && R.Width == 0;
10689 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
10695 static IntRange product(IntRange L, IntRange R) {
10699 bool CanWiden = !L.NonNegative && !R.NonNegative;
10700 bool Unsigned = L.NonNegative && R.NonNegative;
10701 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
10706 static IntRange rem(IntRange L, IntRange R) {
10710 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
10718 if (value.isSigned() && value.isNegative())
10719 return IntRange(value.getSignificantBits(),
false);
10721 if (value.getBitWidth() > MaxWidth)
10722 value = value.trunc(MaxWidth);
10726 return IntRange(value.getActiveBits(),
true);
10730 if (result.
isInt())
10737 R = IntRange::join(R, El);
10745 return IntRange::join(R, I);
10760 Ty = AtomicRHS->getValueType();
10779 bool InConstantContext,
10780 bool Approximate) {
10791 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
10792 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
10796 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
10798 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
10799 CE->getCastKind() == CK_BooleanToSignedIntegral;
10802 if (!isIntegerCast)
10803 return OutputTypeRange;
10806 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
10807 InConstantContext, Approximate);
10809 return std::nullopt;
10812 if (SubRange->Width >= OutputTypeRange.Width)
10813 return OutputTypeRange;
10817 return IntRange(SubRange->Width,
10818 SubRange->NonNegative || OutputTypeRange.NonNegative);
10821 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
10824 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
10826 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
10827 InConstantContext, Approximate);
10832 Expr *TrueExpr = CO->getTrueExpr();
10834 return std::nullopt;
10836 std::optional<IntRange> L =
10839 return std::nullopt;
10841 Expr *FalseExpr = CO->getFalseExpr();
10843 return std::nullopt;
10845 std::optional<IntRange> R =
10848 return std::nullopt;
10850 return IntRange::join(*L, *R);
10853 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
10854 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
10856 switch (BO->getOpcode()) {
10858 llvm_unreachable(
"builtin <=> should have class type");
10869 return IntRange::forBoolType();
10898 Combine = IntRange::bit_and;
10906 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
10907 if (I->getValue() == 1) {
10909 return IntRange(R.Width,
true);
10919 case BO_ShrAssign: {
10921 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
10923 return std::nullopt;
10927 if (std::optional<llvm::APSInt> shift =
10928 BO->getRHS()->getIntegerConstantExpr(
C)) {
10929 if (shift->isNonNegative()) {
10930 if (shift->uge(L->Width))
10931 L->Width = (L->NonNegative ? 0 : 1);
10933 L->Width -= shift->getZExtValue();
10947 Combine = IntRange::sum;
10951 if (BO->getLHS()->getType()->isPointerType())
10954 Combine = IntRange::difference;
10959 Combine = IntRange::product;
10968 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
10970 return std::nullopt;
10973 if (std::optional<llvm::APSInt> divisor =
10974 BO->getRHS()->getIntegerConstantExpr(
C)) {
10975 unsigned log2 = divisor->logBase2();
10976 if (
log2 >= L->Width)
10977 L->Width = (L->NonNegative ? 0 : 1);
10979 L->Width = std::min(L->Width -
log2, MaxWidth);
10987 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
10989 return std::nullopt;
10991 return IntRange(L->Width, L->NonNegative && R->NonNegative);
10995 Combine = IntRange::rem;
11007 unsigned opWidth =
C.getIntWidth(
T);
11009 InConstantContext, Approximate);
11011 return std::nullopt;
11014 InConstantContext, Approximate);
11016 return std::nullopt;
11018 IntRange
C = Combine(*L, *R);
11020 C.Width = std::min(
C.Width, MaxWidth);
11024 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
11025 switch (UO->getOpcode()) {
11028 return IntRange::forBoolType();
11042 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11045 return std::nullopt;
11050 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11060 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11063 return std::nullopt;
11068 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11078 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11079 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11083 return IntRange(BitField->getBitWidthValue(),
11084 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11087 return std::nullopt;
11093 bool InConstantContext,
11094 bool Approximate) {
11103 const llvm::fltSemantics &Src,
11104 const llvm::fltSemantics &Tgt) {
11105 llvm::APFloat truncated = value;
11108 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11109 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11111 return truncated.bitwiseIsEqual(value);
11120 const llvm::fltSemantics &Src,
11121 const llvm::fltSemantics &Tgt) {
11138 bool IsListInit =
false);
11143 if (isa<EnumConstantDecl>(DR->getDecl()))
11153 return MacroName !=
"YES" && MacroName !=
"NO" &&
11154 MacroName !=
"true" && MacroName !=
"false";
11177struct PromotedRange {
11179 llvm::APSInt PromotedMin;
11181 llvm::APSInt PromotedMax;
11183 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11185 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11186 else if (R.Width >= BitWidth && !
Unsigned) {
11190 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11191 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11193 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11194 .extOrTrunc(BitWidth);
11195 PromotedMin.setIsUnsigned(
Unsigned);
11197 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11198 .extOrTrunc(BitWidth);
11199 PromotedMax.setIsUnsigned(
Unsigned);
11204 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11214 InRangeFlag = 0x40,
11217 Min =
LE | InRangeFlag,
11218 InRange = InRangeFlag,
11219 Max =
GE | InRangeFlag,
11222 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11227 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11228 Value.isUnsigned() == PromotedMin.isUnsigned());
11229 if (!isContiguous()) {
11230 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11231 if (
Value.isMinValue())
return Min;
11232 if (
Value.isMaxValue())
return Max;
11233 if (
Value >= PromotedMin)
return InRange;
11234 if (
Value <= PromotedMax)
return InRange;
11238 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11239 case -1:
return Less;
11240 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11242 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11243 case -1:
return InRange;
11244 case 0:
return Max;
11249 llvm_unreachable(
"impossible compare result");
11252 static std::optional<StringRef>
11254 if (Op == BO_Cmp) {
11256 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11258 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11259 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11260 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11261 return std::nullopt;
11268 }
else if (Op == BO_NE) {
11272 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11279 if (Op == BO_GE || Op == BO_LE)
11280 std::swap(TrueFlag, FalseFlag);
11283 return StringRef(
"true");
11285 return StringRef(
"false");
11286 return std::nullopt;
11293 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(
E)) {
11294 if (ICE->getCastKind() != CK_IntegralCast &&
11295 ICE->getCastKind() != CK_NoOp)
11297 E = ICE->getSubExpr();
11306 enum ConstantValueKind {
11311 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11312 return BL->getValue() ? ConstantValueKind::LiteralTrue
11313 : ConstantValueKind::LiteralFalse;
11314 return ConstantValueKind::Miscellaneous;
11319 const llvm::APSInt &
Value,
11320 bool RhsConstant) {
11342 if (!OtherValueRange)
11347 OtherT = AT->getValueType();
11348 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11352 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11358 bool OtherIsBooleanDespiteType =
11360 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11361 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11365 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11366 Value.isUnsigned());
11367 auto Cmp = OtherPromotedValueRange.compare(
Value);
11368 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
11374 bool TautologicalTypeCompare =
false;
11376 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11377 Value.isUnsigned());
11378 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11379 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
11381 TautologicalTypeCompare =
true;
11389 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11398 bool InRange = Cmp & PromotedRange::InRangeFlag;
11404 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11405 Other->getType()->isUnsignedIntegerOrEnumerationType())
11406 TautologicalTypeCompare =
true;
11411 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11412 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11416 llvm::raw_svector_ostream OS(PrettySourceValue);
11418 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11419 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11421 OS << (BL->getValue() ?
"YES" :
"NO");
11426 if (!TautologicalTypeCompare) {
11427 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
11428 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11429 <<
E->getOpcodeStr() << OS.str() << *
Result
11434 if (IsObjCSignedCharBool) {
11436 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11437 << OS.str() << *
Result);
11444 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11447 E->getOperatorLoc(),
E,
11448 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11449 : diag::warn_tautological_bool_compare)
11451 << OtherIsBooleanDespiteType << *
Result
11458 ? diag::warn_unsigned_enum_always_true_comparison
11459 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11460 : diag::warn_unsigned_always_true_comparison)
11461 : diag::warn_tautological_constant_compare;
11464 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result
11494 Expr *LHS =
E->getLHS();
11495 Expr *RHS =
E->getRHS();
11498 std::optional<llvm::APSInt> RHSValue =
11500 std::optional<llvm::APSInt> LHSValue =
11504 if (RHSValue && LHSValue)
11508 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11510 const bool RhsConstant = (
bool)RHSValue;
11511 Expr *Const = RhsConstant ? RHS : LHS;
11513 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11536 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11538 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11544 Expr *signedOperand, *unsignedOperand;
11547 "unsigned comparison between two signed integer expressions?");
11548 signedOperand = LHS;
11549 unsignedOperand = RHS;
11551 signedOperand = RHS;
11552 unsignedOperand = LHS;
11558 std::optional<IntRange> signedRange =
11570 if (signedRange->NonNegative)
11577 if (
E->isEqualityOp()) {
11582 if (!unsignedRange)
11587 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
11589 if (unsignedRange->Width < comparisonWidth)
11594 S.
PDiag(diag::warn_mixed_sign_comparison)
11613 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
11618 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
11619 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
11620 BitfieldEnumDecl->getNumNegativeBits() == 0) {
11621 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
11622 << BitfieldEnumDecl;
11629 Init->isValueDependent() ||
11630 Init->isTypeDependent())
11633 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
11643 const PreferredTypeAttr *PTAttr =
nullptr;
11645 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
11647 ED = PTAttr->getType()->getAsEnumDecl();
11655 bool SignedEnum = ED->getNumNegativeBits() > 0;
11662 unsigned DiagID = 0;
11663 if (SignedEnum && !SignedBitfield) {
11666 ? diag::warn_unsigned_bitfield_assigned_signed_enum
11668 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
11669 }
else if (SignedBitfield && !SignedEnum &&
11670 ED->getNumPositiveBits() == FieldWidth) {
11673 ? diag::warn_signed_bitfield_enum_conversion
11674 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
11677 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11682 << SignedEnum << TypeRange;
11684 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11691 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
11692 ED->getNumNegativeBits())
11693 : ED->getNumPositiveBits();
11696 if (BitsNeeded > FieldWidth) {
11700 ? diag::warn_bitfield_too_small_for_enum
11701 : diag::warn_preferred_type_bitfield_too_small_for_enum;
11702 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
11706 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
11716 unsigned OriginalWidth =
Value.getBitWidth();
11722 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
11723 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
11730 if (!
Value.isSigned() ||
Value.isNegative())
11731 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
11732 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
11733 OriginalWidth =
Value.getSignificantBits();
11735 if (OriginalWidth <= FieldWidth)
11739 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
11743 TruncatedValue = TruncatedValue.extend(OriginalWidth);
11744 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
11748 std::string PrettyTrunc =
toString(TruncatedValue, 10);
11750 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
11751 ? diag::warn_impcast_single_bit_bitield_precision_constant
11752 : diag::warn_impcast_bitfield_precision_constant)
11753 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
11754 <<
Init->getSourceRange();
11769 E->getOperatorLoc())) {
11772 E->getOperatorLoc());
11786 bool PruneControlFlow =
false) {
11793 if (
T.hasAddressSpace())
11795 if (PruneControlFlow) {
11809 bool PruneControlFlow =
false) {
11821 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
11822 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
11825 bool IsLiteral = isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
11827 llvm::APFloat
Value(0.0);
11833 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
11838 diag::warn_impcast_float_integer, PruneWarnings);
11841 bool isExact =
false;
11845 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
11846 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
11854 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
11855 precision = (precision * 59 + 195) / 196;
11856 Value.toString(PrettySourceValue, precision);
11860 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
11861 << PrettySourceValue);
11864 if (
Result == llvm::APFloat::opOK && isExact) {
11865 if (IsLiteral)
return;
11872 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
11875 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
11876 : diag::warn_impcast_float_to_integer_out_of_range,
11879 unsigned DiagID = 0;
11882 DiagID = diag::warn_impcast_literal_float_to_integer;
11883 }
else if (IntegerValue == 0) {
11884 if (
Value.isZero()) {
11886 diag::warn_impcast_float_integer, PruneWarnings);
11889 DiagID = diag::warn_impcast_float_to_integer_zero;
11891 if (IntegerValue.isUnsigned()) {
11892 if (!IntegerValue.isMaxValue()) {
11894 diag::warn_impcast_float_integer, PruneWarnings);
11897 if (!IntegerValue.isMaxSignedValue() &&
11898 !IntegerValue.isMinSignedValue()) {
11900 diag::warn_impcast_float_integer, PruneWarnings);
11904 DiagID = diag::warn_impcast_float_to_integer;
11909 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
11911 IntegerValue.toString(PrettyTargetValue);
11913 if (PruneWarnings) {
11916 <<
E->
getType() <<
T.getUnqualifiedType()
11917 << PrettySourceValue << PrettyTargetValue
11921 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
11929 assert(isa<CompoundAssignOperator>(
E) &&
11930 "Must be compound assignment operation");
11936 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
11940 const auto *RBT = cast<CompoundAssignOperator>(
E)
11941 ->getComputationResultType()
11948 if (ResultBT->isInteger())
11950 E->
getExprLoc(), diag::warn_impcast_float_integer);
11952 if (!ResultBT->isFloatingPoint())
11961 diag::warn_impcast_float_result_precision);
11966 if (!
Range.Width)
return "0";
11968 llvm::APSInt ValueInRange =
Value;
11969 ValueInRange.setIsSigned(!
Range.NonNegative);
11970 ValueInRange = ValueInRange.trunc(
Range.Width);
11971 return toString(ValueInRange, 10);
11976 if (!isa<ImplicitCastExpr>(Ex))
11981 const Type *Source =
11983 if (
Target->isDependentType())
11986 const auto *FloatCandidateBT =
11987 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
11988 const Type *BoolCandidateType = ToBool ?
Target : Source;
11991 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
11996 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12002 S, TheCall->
getArg(I - 1),
false));
12004 S, TheCall->
getArg(I + 1),
false));
12009 diag::warn_impcast_floating_point_to_bool);
12017 if (isa<CallExpr>(
E))
12022 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
12024 if (!IsGNUNullExpr && !HasNullPtrType)
12032 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12048 if (MacroName ==
"NULL")
12056 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
12070 const char FirstLiteralCharacter =
12072 if (FirstLiteralCharacter ==
'0')
12079 const char FirstContextCharacter =
12081 if (FirstContextCharacter ==
'{')
12089 const auto *IL = dyn_cast<IntegerLiteral>(
E);
12091 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
12092 if (UO->getOpcode() == UO_Minus)
12093 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12104 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
12108 if (Opc == BO_Shl) {
12111 if (LHS && LHS->getValue() == 0)
12112 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12114 RHS->getValue().isNonNegative() &&
12116 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12117 << (
Result.Val.getInt() != 0);
12119 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12126 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
12131 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12132 (RHS->getValue() == 0 || RHS->getValue() == 1))
12135 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12136 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12149 llvm::APSInt
Value(32);
12151 bool IsASCII =
Value <= 0x7F;
12152 bool IsBMP =
Value <= 0xD7FF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12153 bool ConversionPreservesSemantics =
12156 if (!ConversionPreservesSemantics) {
12157 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12158 const llvm::APSInt &
Value) {
12160 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12162 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12164 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12167 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12176 LosesPrecision ? diag::warn_impcast_unicode_precision
12177 : diag::warn_impcast_unicode_char_type);
12191 From = MaybePointee;
12198 if (FromFn->getCFIUncheckedCalleeAttr() &&
12199 !ToFn->getCFIUncheckedCalleeAttr())
12201 if (!FromFn->getCFIUncheckedCalleeAttr() &&
12202 ToFn->getCFIUncheckedCalleeAttr())
12212 return ::AdjustingCFIUncheckedCallee(From, To) ==
Discarding;
12218 return ::AdjustingCFIUncheckedCallee(From, To) ==
Adding;
12222 bool *ICContext,
bool IsListInit) {
12227 if (Source ==
Target)
return;
12228 if (
Target->isDependentType())
return;
12242 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12243 if (isa<StringLiteral>(
E))
12248 diag::warn_impcast_string_literal_to_bool);
12249 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
12250 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
12254 diag::warn_impcast_objective_c_literal_to_bool);
12269 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12271 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12280 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
12282 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
12286 if (isa<VectorType>(Source)) {
12287 if (
Target->isSveVLSBuiltinType() &&
12294 if (
Target->isRVVVLSBuiltinType() &&
12301 if (!isa<VectorType>(
Target)) {
12311 diag::warn_hlsl_impcast_vector_truncation);
12320 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
12321 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
12323 if (
auto VecTy = dyn_cast<VectorType>(
Target))
12324 Target = VecTy->getElementType().getTypePtr();
12327 if (isa<ComplexType>(Source)) {
12328 if (!isa<ComplexType>(
Target)) {
12334 ? diag::err_impcast_complex_scalar
12335 : diag::warn_impcast_complex_scalar);
12338 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
12339 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
12342 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12351 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12353 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12395 else if (Order < 0) {
12405 if (TargetBT && TargetBT->
isInteger()) {
12420 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
12428 if (isa<ImplicitCastExpr>(LastA) &&
12432 diag::warn_impcast_floating_point_to_bool);
12441 if (
Target->isUnsaturatedFixedPointType()) {
12445 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12450 PDiag(diag::warn_impcast_fixed_point_range)
12451 <<
Value.toString() <<
T
12457 }
else if (
Target->isIntegerType()) {
12461 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12464 llvm::APSInt IntResult = FXResult.convertToInt(
12470 PDiag(diag::warn_impcast_fixed_point_range)
12471 << FXResult.toString() <<
T
12478 }
else if (
Target->isUnsaturatedFixedPointType()) {
12486 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12491 PDiag(diag::warn_impcast_fixed_point_range)
12512 unsigned int SourcePrecision =
SourceRange->Width;
12516 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12519 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12520 SourcePrecision > TargetPrecision) {
12522 if (std::optional<llvm::APSInt> SourceInt =
12527 llvm::APFloat TargetFloatValue(
12529 llvm::APFloat::opStatus ConversionStatus =
12530 TargetFloatValue.convertFromAPInt(
12532 llvm::APFloat::rmNearestTiesToEven);
12534 if (ConversionStatus != llvm::APFloat::opOK) {
12536 SourceInt->toString(PrettySourceValue, 10);
12538 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12542 PDiag(diag::warn_impcast_integer_float_precision_constant)
12543 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
12549 diag::warn_impcast_integer_float_precision);
12563 if (
Target->isBooleanType())
12567 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
12576 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
12582 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
12587 if (!LikelySourceRange)
12590 IntRange SourceTypeRange =
12591 IntRange::forTargetOfCanonicalType(
Context, Source);
12592 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
12594 if (LikelySourceRange->Width > TargetRange.Width) {
12600 llvm::APSInt
Value(32);
12610 PDiag(diag::warn_impcast_integer_precision_constant)
12611 << PrettySourceValue << PrettyTargetValue
12621 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
12622 if (UO->getOpcode() == UO_Minus)
12624 *
this,
E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
12631 diag::warn_impcast_integer_precision);
12634 if (TargetRange.Width > SourceTypeRange.Width) {
12635 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
12636 if (UO->getOpcode() == UO_Minus)
12638 if (
Target->isUnsignedIntegerType())
12640 diag::warn_impcast_high_order_zero_bits);
12641 if (
Target->isSignedIntegerType())
12643 diag::warn_impcast_nonnegative_result);
12647 if (TargetRange.Width == LikelySourceRange->Width &&
12648 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12663 PDiag(diag::warn_impcast_integer_precision_constant)
12664 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
12673 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
12674 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
12675 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
12676 LikelySourceRange->Width == TargetRange.Width))) {
12680 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
12686 unsigned DiagID = diag::warn_impcast_integer_sign;
12694 DiagID = diag::warn_impcast_integer_sign_conditional;
12705 if (CoercedSourceBT && CoercedSourceBT->
isInteger() && isa<EnumType>(
Target))
12715 if (SourceEnum->getOriginalDecl()->hasNameForLinkage() &&
12716 TargetEnum->getOriginalDecl()->hasNameForLinkage() &&
12717 SourceEnum != TargetEnum) {
12722 diag::warn_impcast_different_enum_types);
12736 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
12748 Expr *TrueExpr =
E->getTrueExpr();
12749 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
12750 TrueExpr = BCO->getCommon();
12752 bool Suspicious =
false;
12761 if (!Suspicious)
return;
12764 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
12771 Suspicious =
false;
12793struct AnalyzeImplicitConversionsWorkItem {
12802 bool ExtraCheckForImplicitConversion,
12805 WorkList.push_back({
E, CC,
false});
12807 if (ExtraCheckForImplicitConversion &&
E->
getType() !=
T)
12814 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
12816 Expr *OrigE = Item.E;
12829 Item.IsListInit || (isa<InitListExpr>(OrigE) &&
12835 Expr *SourceExpr =
E;
12840 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
12841 if (
auto *Src = OVE->getSourceExpr())
12844 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
12845 if (UO->getOpcode() == UO_Not &&
12846 UO->getSubExpr()->isKnownToHaveBooleanValue())
12847 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
12851 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
12852 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
12853 BO->getLHS()->isKnownToHaveBooleanValue() &&
12854 BO->getRHS()->isKnownToHaveBooleanValue() &&
12855 BO->getLHS()->HasSideEffects(S.
Context) &&
12856 BO->getRHS()->HasSideEffects(S.
Context)) {
12867 if (SR.str() ==
"&" || SR.str() ==
"|") {
12869 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
12870 << (BO->getOpcode() == BO_And ?
"&" :
"|")
12873 BO->getOperatorLoc(),
12874 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
12875 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
12877 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
12895 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
12901 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
12916 for (
auto *SE : POE->semantics())
12917 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
12918 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
12922 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
12926 WorkList.push_back({
E, CC, IsListInit});
12930 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(
E)) {
12931 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
12935 if (OutArgE->isInOut())
12936 WorkList.push_back(
12937 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
12938 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
12944 if (BO->isComparisonOp())
12948 if (BO->getOpcode() == BO_Assign)
12951 if (BO->isAssignmentOp())
12959 if (isa<StmtExpr>(
E))
return;
12962 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
12967 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
12969 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
12973 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
12974 if (ChildExpr == CSE->getOperand())
12980 if (IsLogicalAndOperator &&
12985 WorkList.push_back({ChildExpr, CC, IsListInit});
12990 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
12994 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
12999 if (
U->getOpcode() == UO_LNot) {
13001 }
else if (
U->getOpcode() != UO_AddrOf) {
13002 if (
U->getSubExpr()->getType()->isAtomicType())
13003 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13004 diag::warn_atomic_implicit_seq_cst);
13015 WorkList.push_back({OrigE, CC, IsListInit});
13016 while (!WorkList.empty())
13028 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
13031 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
13032 if (!M->getMemberDecl()->getType()->isReferenceType())
13035 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13037 FD =
Call->getDirectCallee();
13046 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13060 if (
SM.isMacroBodyExpansion(
Loc))
13062 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
13085 if (isa<CXXThisExpr>(
E)) {
13086 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13087 : diag::warn_this_bool_conversion;
13092 bool IsAddressOf =
false;
13094 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
13095 if (UO->getOpcode() != UO_AddrOf)
13097 IsAddressOf =
true;
13098 E = UO->getSubExpr();
13102 unsigned DiagID = IsCompare
13103 ? diag::warn_address_of_reference_null_compare
13104 : diag::warn_address_of_reference_bool_conversion;
13112 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13113 bool IsParam = isa<NonNullAttr>(NonnullAttr);
13115 llvm::raw_string_ostream S(Str);
13117 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13118 : diag::warn_cast_nonnull_to_bool;
13121 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13126 if (
auto *Callee =
Call->getDirectCallee()) {
13127 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13128 ComplainAboutNonnullParamOrCall(A);
13137 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
13138 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13139 MRecordDecl && MRecordDecl->isLambda()) {
13142 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
13152 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
13153 D = M->getMemberDecl();
13157 if (!
D ||
D->isWeak())
13161 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
13164 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13165 ComplainAboutNonnullParamOrCall(A);
13169 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13173 auto ParamIter = llvm::find(FD->
parameters(), PV);
13175 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13179 ComplainAboutNonnullParamOrCall(
NonNull);
13184 if (ArgNo.getASTIndex() == ParamNo) {
13185 ComplainAboutNonnullParamOrCall(
NonNull);
13199 if (IsAddressOf && IsFunction) {
13204 if (!IsAddressOf && !IsFunction && !IsArray)
13209 llvm::raw_string_ostream S(Str);
13212 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13213 : diag::warn_impcast_pointer_to_bool;
13220 DiagType = AddressOf;
13221 else if (IsFunction)
13222 DiagType = FunctionPointer;
13224 DiagType = ArrayPointer;
13226 llvm_unreachable(
"Could not determine diagnostic.");
13228 <<
Range << IsEqual;
13241 if (ReturnType.
isNull())
13279 CheckArrayAccess(
E);
13286 ::CheckBoolLikeConversion(*
this,
E, CC);
13289void Sema::CheckForIntOverflow (
const Expr *
E) {
13294 const Expr *OriginalE = Exprs.pop_back_val();
13297 if (isa<BinaryOperator, UnaryOperator>(
E)) {
13302 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13303 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13304 else if (isa<ObjCBoxedExpr>(OriginalE))
13306 else if (
const auto *
Call = dyn_cast<CallExpr>(
E))
13307 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13308 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
13309 Exprs.append(Message->arg_begin(), Message->arg_end());
13310 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
13311 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13312 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
13313 Exprs.push_back(Temporary->getSubExpr());
13314 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
13315 Exprs.push_back(Array->getIdx());
13316 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
13317 Exprs.push_back(Compound->getInitializer());
13318 else if (
const auto *
New = dyn_cast<CXXNewExpr>(
E);
13319 New &&
New->isArray()) {
13320 if (
auto ArraySize =
New->getArraySize())
13321 Exprs.push_back(*ArraySize);
13322 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13323 Exprs.push_back(MTE->getSubExpr());
13324 }
while (!Exprs.empty());
13339 class SequenceTree {
13343 LLVM_PREFERRED_TYPE(
bool)
13344 unsigned Merged : 1;
13352 friend class SequenceTree;
13356 explicit Seq(
unsigned N) : Index(N) {}
13359 Seq() : Index(0) {}
13362 SequenceTree() { Values.push_back(
Value(0)); }
13363 Seq root()
const {
return Seq(0); }
13370 return Seq(Values.size() - 1);
13374 void merge(
Seq S) {
13375 Values[S.Index].Merged =
true;
13381 bool isUnsequenced(
Seq Cur,
Seq Old) {
13382 unsigned C = representative(Cur.Index);
13383 unsigned Target = representative(Old.Index);
13387 C = Values[
C].Parent;
13394 unsigned representative(
unsigned K) {
13395 if (Values[K].Merged)
13397 return Values[K].Parent = representative(Values[K].
Parent);
13417 UK_ModAsSideEffect,
13419 UK_Count = UK_ModAsSideEffect + 1
13425 const Expr *UsageExpr =
nullptr;
13426 SequenceTree::Seq
Seq;
13432 Usage Uses[UK_Count];
13435 bool Diagnosed =
false;
13439 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13447 UsageInfoMap UsageMap;
13450 SequenceTree::Seq Region;
13465 struct SequencedSubexpression {
13466 SequencedSubexpression(SequenceChecker &Self)
13467 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
13468 Self.ModAsSideEffect = &ModAsSideEffect;
13471 ~SequencedSubexpression() {
13472 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13476 UsageInfo &UI = Self.UsageMap[M.first];
13477 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13478 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13479 SideEffectUsage = M.second;
13481 Self.ModAsSideEffect = OldModAsSideEffect;
13484 SequenceChecker &Self;
13493 class EvaluationTracker {
13495 EvaluationTracker(SequenceChecker &Self)
13496 : Self(Self), Prev(Self.EvalTracker) {
13497 Self.EvalTracker =
this;
13500 ~EvaluationTracker() {
13501 Self.EvalTracker = Prev;
13503 Prev->EvalOK &= EvalOK;
13506 bool evaluate(
const Expr *
E,
bool &Result) {
13510 Result, Self.SemaRef.Context,
13511 Self.SemaRef.isConstantEvaluatedContext());
13516 SequenceChecker &Self;
13517 EvaluationTracker *Prev;
13518 bool EvalOK =
true;
13519 } *EvalTracker =
nullptr;
13523 Object getObject(
const Expr *
E,
bool Mod)
const {
13526 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13527 return getObject(UO->getSubExpr(), Mod);
13529 if (BO->getOpcode() == BO_Comma)
13530 return getObject(BO->getRHS(), Mod);
13531 if (Mod && BO->isAssignmentOp())
13532 return getObject(BO->getLHS(), Mod);
13533 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
13535 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
13536 return ME->getMemberDecl();
13537 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
13546 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13548 Usage &
U = UI.Uses[UK];
13549 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
13553 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
13554 ModAsSideEffect->push_back(std::make_pair(O,
U));
13556 U.UsageExpr = UsageExpr;
13566 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
13567 UsageKind OtherKind,
bool IsModMod) {
13571 const Usage &
U = UI.Uses[OtherKind];
13572 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
13575 const Expr *Mod =
U.UsageExpr;
13576 const Expr *ModOrUse = UsageExpr;
13577 if (OtherKind == UK_Use)
13578 std::swap(Mod, ModOrUse);
13582 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
13583 : diag::warn_unsequenced_mod_use)
13585 UI.Diagnosed =
true;
13614 void notePreUse(Object O,
const Expr *UseExpr) {
13615 UsageInfo &UI = UsageMap[O];
13617 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
13620 void notePostUse(Object O,
const Expr *UseExpr) {
13621 UsageInfo &UI = UsageMap[O];
13622 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
13624 addUsage(O, UI, UseExpr, UK_Use);
13627 void notePreMod(Object O,
const Expr *ModExpr) {
13628 UsageInfo &UI = UsageMap[O];
13630 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
13631 checkUsage(O, UI, ModExpr, UK_Use,
false);
13634 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
13635 UsageInfo &UI = UsageMap[O];
13636 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
13638 addUsage(O, UI, ModExpr, UK);
13642 SequenceChecker(
Sema &S,
const Expr *
E,
13644 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
13648 (void)this->WorkList;
13651 void VisitStmt(
const Stmt *S) {
13655 void VisitExpr(
const Expr *
E) {
13657 Base::VisitStmt(
E);
13661 for (
auto *Sub : CSE->
children()) {
13662 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
13677 void VisitCastExpr(
const CastExpr *
E) {
13679 if (
E->getCastKind() == CK_LValueToRValue)
13680 O = getObject(
E->getSubExpr(),
false);
13689 void VisitSequencedExpressions(
const Expr *SequencedBefore,
13690 const Expr *SequencedAfter) {
13691 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
13692 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
13693 SequenceTree::Seq OldRegion = Region;
13696 SequencedSubexpression SeqBefore(*
this);
13697 Region = BeforeRegion;
13698 Visit(SequencedBefore);
13701 Region = AfterRegion;
13702 Visit(SequencedAfter);
13704 Region = OldRegion;
13706 Tree.merge(BeforeRegion);
13707 Tree.merge(AfterRegion);
13715 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
13722 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13723 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
13729 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13736 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13737 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
13742 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13754 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
13758 SequenceTree::Seq RHSRegion;
13759 SequenceTree::Seq LHSRegion;
13761 RHSRegion =
Tree.allocate(Region);
13762 LHSRegion =
Tree.allocate(Region);
13764 RHSRegion = Region;
13765 LHSRegion = Region;
13767 SequenceTree::Seq OldRegion = Region;
13783 SequencedSubexpression SeqBefore(*
this);
13784 Region = RHSRegion;
13788 Region = LHSRegion;
13791 if (O && isa<CompoundAssignOperator>(BO))
13792 notePostUse(O, BO);
13796 Region = LHSRegion;
13799 if (O && isa<CompoundAssignOperator>(BO))
13800 notePostUse(O, BO);
13802 Region = RHSRegion;
13810 Region = OldRegion;
13814 : UK_ModAsSideEffect);
13816 Tree.merge(RHSRegion);
13817 Tree.merge(LHSRegion);
13822 VisitBinAssign(CAO);
13825 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
13826 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
13830 return VisitExpr(UO);
13838 : UK_ModAsSideEffect);
13841 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
13842 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
13846 return VisitExpr(UO);
13850 notePostMod(O, UO, UK_ModAsSideEffect);
13859 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
13860 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
13861 SequenceTree::Seq OldRegion = Region;
13863 EvaluationTracker Eval(*
this);
13865 SequencedSubexpression Sequenced(*
this);
13866 Region = LHSRegion;
13873 bool EvalResult =
false;
13874 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
13875 bool ShouldVisitRHS = !EvalOK || !EvalResult;
13876 if (ShouldVisitRHS) {
13877 Region = RHSRegion;
13881 Region = OldRegion;
13882 Tree.merge(LHSRegion);
13883 Tree.merge(RHSRegion);
13892 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
13893 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
13894 SequenceTree::Seq OldRegion = Region;
13896 EvaluationTracker Eval(*
this);
13898 SequencedSubexpression Sequenced(*
this);
13899 Region = LHSRegion;
13905 bool EvalResult =
false;
13906 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
13907 bool ShouldVisitRHS = !EvalOK || EvalResult;
13908 if (ShouldVisitRHS) {
13909 Region = RHSRegion;
13913 Region = OldRegion;
13914 Tree.merge(LHSRegion);
13915 Tree.merge(RHSRegion);
13923 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
13939 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
13940 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
13941 SequenceTree::Seq OldRegion = Region;
13943 EvaluationTracker Eval(*
this);
13945 SequencedSubexpression Sequenced(*
this);
13946 Region = ConditionRegion;
13956 bool EvalResult =
false;
13957 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
13958 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
13959 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
13960 if (ShouldVisitTrueExpr) {
13961 Region = TrueRegion;
13964 if (ShouldVisitFalseExpr) {
13965 Region = FalseRegion;
13969 Region = OldRegion;
13970 Tree.merge(ConditionRegion);
13971 Tree.merge(TrueRegion);
13972 Tree.merge(FalseRegion);
13975 void VisitCallExpr(
const CallExpr *CE) {
13987 SequencedSubexpression Sequenced(*
this);
13992 SequenceTree::Seq CalleeRegion;
13993 SequenceTree::Seq OtherRegion;
13994 if (SemaRef.getLangOpts().CPlusPlus17) {
13995 CalleeRegion = Tree.allocate(Region);
13996 OtherRegion = Tree.allocate(Region);
13998 CalleeRegion = Region;
13999 OtherRegion = Region;
14001 SequenceTree::Seq OldRegion = Region;
14004 Region = CalleeRegion;
14006 SequencedSubexpression Sequenced(*this);
14007 Visit(CE->getCallee());
14009 Visit(CE->getCallee());
14013 Region = OtherRegion;
14017 Region = OldRegion;
14019 Tree.merge(CalleeRegion);
14020 Tree.merge(OtherRegion);
14038 return VisitCallExpr(CXXOCE);
14049 case OO_MinusEqual:
14051 case OO_SlashEqual:
14052 case OO_PercentEqual:
14053 case OO_CaretEqual:
14056 case OO_LessLessEqual:
14057 case OO_GreaterGreaterEqual:
14058 SequencingKind = RHSBeforeLHS;
14062 case OO_GreaterGreater:
14068 SequencingKind = LHSBeforeRHS;
14072 SequencingKind = LHSBeforeRest;
14076 SequencingKind = NoSequencing;
14080 if (SequencingKind == NoSequencing)
14081 return VisitCallExpr(CXXOCE);
14084 SequencedSubexpression Sequenced(*
this);
14087 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14088 "Should only get there with C++17 and above!");
14089 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14090 "Should only get there with an overloaded binary operator"
14091 " or an overloaded call operator!");
14093 if (SequencingKind == LHSBeforeRest) {
14094 assert(CXXOCE->getOperator() == OO_Call &&
14095 "We should only have an overloaded call operator here!");
14104 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14105 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14106 SequenceTree::Seq OldRegion = Region;
14108 assert(CXXOCE->getNumArgs() >= 1 &&
14109 "An overloaded call operator must have at least one argument"
14110 " for the postfix-expression!");
14111 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14112 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14113 CXXOCE->getNumArgs() - 1);
14117 Region = PostfixExprRegion;
14118 SequencedSubexpression Sequenced(*this);
14119 Visit(PostfixExpr);
14123 Region = ArgsRegion;
14124 for (const Expr *Arg : Args)
14127 Region = OldRegion;
14128 Tree.merge(PostfixExprRegion);
14129 Tree.merge(ArgsRegion);
14131 assert(CXXOCE->getNumArgs() == 2 &&
14132 "Should only have two arguments here!");
14133 assert((SequencingKind == LHSBeforeRHS ||
14134 SequencingKind == RHSBeforeLHS) &&
14135 "Unexpected sequencing kind!");
14139 const Expr *E1 = CXXOCE->getArg(0);
14140 const Expr *E2 = CXXOCE->getArg(1);
14141 if (SequencingKind == RHSBeforeLHS)
14144 return VisitSequencedExpressions(E1, E2);
14151 SequencedSubexpression Sequenced(*
this);
14154 return VisitExpr(CCE);
14157 SequenceExpressionsInOrder(
14163 return VisitExpr(ILE);
14166 SequenceExpressionsInOrder(ILE->
inits());
14178 SequenceTree::Seq
Parent = Region;
14179 for (
const Expr *
E : ExpressionList) {
14183 Elts.push_back(Region);
14189 for (
unsigned I = 0; I < Elts.size(); ++I)
14190 Tree.merge(Elts[I]);
14194SequenceChecker::UsageInfo::UsageInfo() =
default;
14198void Sema::CheckUnsequencedOperations(
const Expr *
E) {
14200 WorkList.push_back(
E);
14201 while (!WorkList.empty()) {
14202 const Expr *Item = WorkList.pop_back_val();
14203 SequenceChecker(*
this, Item, WorkList);
14208 bool IsConstexpr) {
14210 IsConstexpr || isa<ConstantExpr>(
E));
14211 CheckImplicitConversions(
E, CheckLoc);
14213 CheckUnsequencedOperations(
E);
14215 CheckForIntOverflow(
E);
14228 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14232 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14236 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14250 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
14254 bool CheckParameterNames) {
14255 bool HasInvalidParm =
false;
14257 assert(Param &&
"null in a parameter list");
14266 if (!Param->isInvalidDecl() &&
14268 diag::err_typecheck_decl_incomplete_type) ||
14270 diag::err_abstract_type_in_decl,
14272 Param->setInvalidDecl();
14273 HasInvalidParm =
true;
14278 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14282 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14290 QualType PType = Param->getOriginalType();
14298 if (!Param->isInvalidDecl()) {
14300 if (!ClassDecl->isInvalidDecl() &&
14301 !ClassDecl->hasIrrelevantDestructor() &&
14302 !ClassDecl->isDependentContext() &&
14303 ClassDecl->isParamDestroyedInCallee()) {
14315 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14316 if (!Param->getType().isConstQualified())
14317 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14321 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14326 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14327 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14332 if (!Param->isInvalidDecl() &&
14334 Param->setInvalidDecl();
14335 HasInvalidParm =
true;
14336 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14340 return HasInvalidParm;
14343std::optional<std::pair<
14352static std::pair<CharUnits, CharUnits>
14360 if (
Base->isVirtual()) {
14367 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14374 DerivedType =
Base->getType();
14377 return std::make_pair(BaseAlignment, Offset);
14381static std::optional<std::pair<CharUnits, CharUnits>>
14387 return std::nullopt;
14392 return std::nullopt;
14396 CharUnits Offset = EltSize * IdxRes->getExtValue();
14399 return std::make_pair(
P->first,
P->second + Offset);
14405 return std::make_pair(
14406 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
14412std::optional<std::pair<
14420 case Stmt::CStyleCastExprClass:
14421 case Stmt::CXXStaticCastExprClass:
14422 case Stmt::ImplicitCastExprClass: {
14423 auto *CE = cast<CastExpr>(
E);
14424 const Expr *From = CE->getSubExpr();
14425 switch (CE->getCastKind()) {
14430 case CK_UncheckedDerivedToBase:
14431 case CK_DerivedToBase: {
14441 case Stmt::ArraySubscriptExprClass: {
14442 auto *ASE = cast<ArraySubscriptExpr>(
E);
14446 case Stmt::DeclRefExprClass: {
14447 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
14450 if (!VD->getType()->isReferenceType()) {
14452 if (VD->hasDependentAlignment())
14461 case Stmt::MemberExprClass: {
14462 auto *ME = cast<MemberExpr>(
E);
14463 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14467 std::optional<std::pair<CharUnits, CharUnits>>
P;
14476 return std::make_pair(
P->first,
14479 case Stmt::UnaryOperatorClass: {
14480 auto *UO = cast<UnaryOperator>(
E);
14489 case Stmt::BinaryOperatorClass: {
14490 auto *BO = cast<BinaryOperator>(
E);
14501 return std::nullopt;
14506std::optional<std::pair<
14515 case Stmt::CStyleCastExprClass:
14516 case Stmt::CXXStaticCastExprClass:
14517 case Stmt::ImplicitCastExprClass: {
14518 auto *CE = cast<CastExpr>(
E);
14519 const Expr *From = CE->getSubExpr();
14520 switch (CE->getCastKind()) {
14525 case CK_ArrayToPointerDecay:
14527 case CK_UncheckedDerivedToBase:
14528 case CK_DerivedToBase: {
14538 case Stmt::CXXThisExprClass: {
14543 case Stmt::UnaryOperatorClass: {
14544 auto *UO = cast<UnaryOperator>(
E);
14549 case Stmt::BinaryOperatorClass: {
14550 auto *BO = cast<BinaryOperator>(
E);
14558 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
14559 std::swap(LHS, RHS);
14569 return std::nullopt;
14574 std::optional<std::pair<CharUnits, CharUnits>>
P =
14578 return P->first.alignmentAtOffset(
P->second);
14596 if (!DestPtr)
return;
14602 if (DestAlign.
isOne())
return;
14606 if (!SrcPtr)
return;
14617 if (SrcAlign >= DestAlign)
return;
14622 <<
static_cast<unsigned>(DestAlign.
getQuantity())
14626void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
14628 bool AllowOnePastEnd,
bool IndexNegated) {
14637 const Type *EffectiveType =
14644 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
14646 const Type *BaseType =
14648 bool IsUnboundedArray =
14650 Context, StrictFlexArraysLevel,
14660 llvm::APSInt index =
Result.Val.getInt();
14661 if (IndexNegated) {
14662 index.setIsUnsigned(
false);
14666 if (IsUnboundedArray) {
14669 if (index.isUnsigned() || !index.isNegative()) {
14671 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
14673 if (index.getBitWidth() < AddrBits)
14674 index = index.zext(AddrBits);
14675 std::optional<CharUnits> ElemCharUnits =
14676 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
14679 if (!ElemCharUnits || ElemCharUnits->isZero())
14681 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
14686 if (index.getActiveBits() <= AddrBits) {
14688 llvm::APInt Product(index);
14690 Product = Product.umul_ov(ElemBytes, Overflow);
14691 if (!Overflow && Product.getActiveBits() <= AddrBits)
14697 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
14698 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
14700 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
14701 MaxElems = MaxElems.udiv(ElemBytes);
14704 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
14705 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
14711 <<
toString(index, 10,
true) << AddrBits
14712 << (
unsigned)ASTC.toBits(*ElemCharUnits)
14715 << (
unsigned)MaxElems.getLimitedValue(~0
U)
14720 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14722 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14724 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14725 ND = ME->getMemberDecl();
14729 PDiag(diag::note_array_declared_here) << ND);
14734 if (index.isUnsigned() || !index.isNegative()) {
14744 llvm::APInt size = ArrayTy->
getSize();
14746 if (BaseType != EffectiveType) {
14754 if (!ptrarith_typesize)
14757 if (ptrarith_typesize != array_typesize) {
14759 uint64_t ratio = array_typesize / ptrarith_typesize;
14763 if (ptrarith_typesize * ratio == array_typesize)
14764 size *= llvm::APInt(size.getBitWidth(), ratio);
14768 if (size.getBitWidth() > index.getBitWidth())
14769 index = index.zext(size.getBitWidth());
14770 else if (size.getBitWidth() < index.getBitWidth())
14771 size = size.zext(index.getBitWidth());
14777 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
14794 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
14795 : diag::warn_ptr_arith_exceeds_bounds;
14796 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
14804 unsigned DiagID = diag::warn_array_index_precedes_bounds;
14806 DiagID = diag::warn_ptr_arith_precedes_bounds;
14807 if (index.isNegative()) index = -index;
14817 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
14819 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
14821 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
14822 ND = ME->getMemberDecl();
14826 PDiag(diag::note_array_declared_here) << ND);
14829void Sema::CheckArrayAccess(
const Expr *
expr) {
14830 int AllowOnePastEnd = 0;
14832 expr =
expr->IgnoreParenImpCasts();
14833 switch (
expr->getStmtClass()) {
14834 case Stmt::ArraySubscriptExprClass: {
14837 AllowOnePastEnd > 0);
14841 case Stmt::MemberExprClass: {
14842 expr = cast<MemberExpr>(
expr)->getBase();
14845 case Stmt::ArraySectionExprClass: {
14851 nullptr, AllowOnePastEnd > 0);
14854 case Stmt::UnaryOperatorClass: {
14870 case Stmt::ConditionalOperatorClass: {
14873 CheckArrayAccess(lhs);
14875 CheckArrayAccess(rhs);
14878 case Stmt::CXXOperatorCallExprClass: {
14879 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
14880 for (
const auto *Arg : OCE->arguments())
14881 CheckArrayAccess(Arg);
14891 Expr *RHS,
bool isProperty) {
14903 S.
Diag(
Loc, diag::warn_arc_literal_assign)
14905 << (isProperty ? 0 : 1)
14913 Expr *RHS,
bool isProperty) {
14916 if (
cast->getCastKind() == CK_ARCConsumeObject) {
14917 S.
Diag(
Loc, diag::warn_arc_retained_assign)
14919 << (isProperty ? 0 : 1)
14923 RHS =
cast->getSubExpr();
14994 if (
cast->getCastKind() == CK_ARCConsumeObject) {
14995 Diag(
Loc, diag::warn_arc_retained_property_assign)
14999 RHS =
cast->getSubExpr();
15022 bool StmtLineInvalid;
15025 if (StmtLineInvalid)
15028 bool BodyLineInvalid;
15031 if (BodyLineInvalid)
15035 if (StmtLine != BodyLine)
15050 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15059 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15063 const Stmt *PossibleBody) {
15069 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15070 StmtLoc = FS->getRParenLoc();
15071 Body = FS->getBody();
15072 DiagID = diag::warn_empty_for_body;
15073 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15074 StmtLoc = WS->getRParenLoc();
15075 Body = WS->getBody();
15076 DiagID = diag::warn_empty_while_body;
15081 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15104 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
15105 if (!ProbableTypo) {
15106 bool BodyColInvalid;
15109 if (BodyColInvalid)
15112 bool StmtColInvalid;
15115 if (StmtColInvalid)
15118 if (BodyCol > StmtCol)
15119 ProbableTypo =
true;
15122 if (ProbableTypo) {
15124 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15132 if (
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15144 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15146 RHSExpr = CE->
getArg(0);
15147 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15148 CXXSCE && CXXSCE->isXValue())
15149 RHSExpr = CXXSCE->getSubExpr();
15153 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15154 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15157 if (LHSDeclRef && RHSDeclRef) {
15164 auto D =
Diag(OpLoc, diag::warn_self_move)
15180 const Expr *LHSBase = LHSExpr;
15181 const Expr *RHSBase = RHSExpr;
15182 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15183 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15184 if (!LHSME || !RHSME)
15187 while (LHSME && RHSME) {
15194 LHSME = dyn_cast<MemberExpr>(LHSBase);
15195 RHSME = dyn_cast<MemberExpr>(RHSBase);
15198 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15199 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15200 if (LHSDeclRef && RHSDeclRef) {
15207 Diag(OpLoc, diag::warn_self_move)
15213 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
15214 Diag(OpLoc, diag::warn_self_move)
15238 bool AreUnionMembers =
false) {
15242 assert(((Field1Parent->isStructureOrClassType() &&
15243 Field2Parent->isStructureOrClassType()) ||
15244 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15245 "Can't evaluate layout compatibility between a struct field and a "
15247 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15248 (AreUnionMembers && Field1Parent->isUnionType())) &&
15249 "AreUnionMembers should be 'true' for union fields (only).");
15263 if (Bits1 != Bits2)
15267 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15268 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15271 if (!AreUnionMembers &&
15283 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15284 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15286 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15287 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15292 return isLayoutCompatible(C, F1, F2);
15303 for (
auto *Field1 : RD1->
fields()) {
15304 auto I = UnmatchedFields.begin();
15305 auto E = UnmatchedFields.end();
15307 for ( ; I !=
E; ++I) {
15309 bool Result = UnmatchedFields.erase(*I);
15319 return UnmatchedFields.empty();
15345 if (
C.hasSameType(T1, T2))
15354 if (TC1 == Type::Enum)
15356 if (TC1 == Type::Record) {
15375 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15406 const ValueDecl **VD, uint64_t *MagicValue,
15407 bool isConstantEvaluated) {
15415 case Stmt::UnaryOperatorClass: {
15424 case Stmt::DeclRefExprClass: {
15425 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
15430 case Stmt::IntegerLiteralClass: {
15432 llvm::APInt MagicValueAPInt = IL->
getValue();
15433 if (MagicValueAPInt.getActiveBits() <= 64) {
15434 *MagicValue = MagicValueAPInt.getZExtValue();
15440 case Stmt::BinaryConditionalOperatorClass:
15441 case Stmt::ConditionalOperatorClass: {
15443 cast<AbstractConditionalOperator>(TypeExpr);
15446 isConstantEvaluated)) {
15456 case Stmt::BinaryOperatorClass: {
15459 TypeExpr = BO->
getRHS();
15489 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15492 bool isConstantEvaluated) {
15493 FoundWrongKind =
false;
15498 uint64_t MagicValue;
15500 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15504 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15505 if (I->getArgumentKind() != ArgumentKind) {
15506 FoundWrongKind =
true;
15509 TypeInfo.Type = I->getMatchingCType();
15510 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15511 TypeInfo.MustBeNull = I->getMustBeNull();
15522 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15523 if (I == MagicValues->end())
15532 bool LayoutCompatible,
15534 if (!TypeTagForDatatypeMagicValues)
15535 TypeTagForDatatypeMagicValues.reset(
15536 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15539 (*TypeTagForDatatypeMagicValues)[Magic] =
15555 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
15556 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
15557 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
15558 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
15561void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
15565 bool IsPointerAttr =
Attr->getIsPointer();
15568 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
15569 if (TypeTagIdxAST >= ExprArgs.size()) {
15570 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15571 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
15574 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
15575 bool FoundWrongKind;
15578 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
15580 if (FoundWrongKind)
15582 diag::warn_type_tag_for_datatype_wrong_kind)
15588 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
15589 if (ArgumentIdxAST >= ExprArgs.size()) {
15590 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
15591 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
15594 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
15595 if (IsPointerAttr) {
15597 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
15598 if (ICE->getType()->isVoidPointerType() &&
15599 ICE->getCastKind() == CK_BitCast)
15600 ArgumentExpr = ICE->getSubExpr();
15613 diag::warn_type_safety_null_pointer_required)
15625 bool mismatch =
false;
15648 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
15649 << ArgumentType << ArgumentKind
15650 <<
TypeInfo.LayoutCompatible << RequiredType
15668 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
15678 if (isa<UnaryOperator>(
E) &&
15679 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
15680 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
15681 if (isa<MemberExpr>(Op)) {
15682 auto &MisalignedMembersForExpr =
15684 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
15685 if (MA != MisalignedMembersForExpr.end() &&
15690 MisalignedMembersForExpr.erase(MA);
15699 const auto *ME = dyn_cast<MemberExpr>(
E);
15711 bool AnyIsPacked =
false;
15713 QualType BaseType = ME->getBase()->getType();
15723 auto *FD = dyn_cast<FieldDecl>(MD);
15729 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
15730 ReverseMemberChain.push_back(FD);
15733 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
15735 assert(TopME &&
"We did not compute a topmost MemberExpr!");
15742 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
15746 if (!DRE && !isa<CXXThisExpr>(TopBase))
15753 if (ExpectedAlignment.
isOne())
15758 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
15767 if (DRE && !TopME->
isArrow()) {
15770 CompleteObjectAlignment =
15775 if (Offset % ExpectedAlignment != 0 ||
15778 CompleteObjectAlignment < ExpectedAlignment) {
15789 for (
FieldDecl *FDI : ReverseMemberChain) {
15790 if (FDI->hasAttr<PackedAttr>() ||
15791 FDI->getParent()->hasAttr<PackedAttr>()) {
15799 assert(FD &&
"We did not find a packed FieldDecl!");
15804void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
15805 using namespace std::placeholders;
15808 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
15844bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
15845 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
15858 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
15859 TheCall->
setType(VecTy0->getElementType());
15872 return S.
Diag(
Loc, diag::err_conv_mixed_enum_types)
15889 assert(!Args.empty() &&
"Should have at least one argument.");
15891 Expr *Arg0 = Args.front();
15894 auto EmitError = [&](
Expr *ArgI) {
15896 diag::err_typecheck_call_different_arg_types)
15897 << Arg0->
getType() << ArgI->getType();
15902 for (
Expr *ArgI : Args.drop_front())
15913 for (
Expr *ArgI : Args.drop_front()) {
15917 VecI->getElementType()) ||
15918 Vec0->getNumElements() != VecI->getNumElements()) {
15927std::optional<QualType>
15931 return std::nullopt;
15935 return std::nullopt;
15938 for (
int I = 0; I < 2; ++I) {
15942 return std::nullopt;
15943 Args[I] = Converted.
get();
15950 return std::nullopt;
15953 return std::nullopt;
15955 TheCall->
setArg(0, Args[0]);
15956 TheCall->
setArg(1, Args[1]);
15973 for (
int I = 0; I < 3; ++I) {
15978 Args[I] = Converted.
get();
15981 int ArgOrdinal = 1;
15982 for (
Expr *Arg : Args) {
15984 ArgTyRestr, ArgOrdinal++))
15991 for (
int I = 0; I < 3; ++I)
15992 TheCall->
setArg(I, Args[I]);
15994 TheCall->
setType(Args[0]->getType());
15998bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16010bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16019 diag::err_builtin_invalid_arg_type)
16020 << 1 << 2 << 1 << 1 << TyArg;
16034 Expr *Matrix = MatrixArg.
get();
16039 << 1 << 3 << 0 << 0
16047 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16050 TheCall->
setType(ResultType);
16053 TheCall->
setArg(0, Matrix);
16058static std::optional<unsigned>
16066 uint64_t
Dim =
Value->getZExtValue();
16085 unsigned PtrArgIdx = 0;
16091 bool ArgError =
false;
16098 PtrExpr = PtrConv.
get();
16099 TheCall->
setArg(0, PtrExpr);
16110 << PtrArgIdx + 1 << 0 << 5 << 0
16118 << PtrArgIdx + 1 << 0 << 5
16125 auto ApplyArgumentConversions = [
this](
Expr *
E) {
16134 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16136 RowsExpr = RowsConv.
get();
16137 TheCall->
setArg(1, RowsExpr);
16139 RowsExpr =
nullptr;
16141 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16143 ColumnsExpr = ColumnsConv.
get();
16144 TheCall->
setArg(2, ColumnsExpr);
16146 ColumnsExpr =
nullptr;
16157 std::optional<unsigned> MaybeRows;
16161 std::optional<unsigned> MaybeColumns;
16166 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16169 StrideExpr = StrideConv.
get();
16170 TheCall->
setArg(3, StrideExpr);
16173 if (std::optional<llvm::APSInt>
Value =
16176 if (Stride < *MaybeRows) {
16178 diag::err_builtin_matrix_stride_too_small);
16184 if (ArgError || !MaybeRows || !MaybeColumns)
16197 unsigned PtrArgIdx = 1;
16202 bool ArgError =
false;
16208 MatrixExpr = MatrixConv.
get();
16209 TheCall->
setArg(0, MatrixExpr);
16219 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16227 PtrExpr = PtrConv.
get();
16228 TheCall->
setArg(1, PtrExpr);
16239 << PtrArgIdx + 1 << 0 << 5 << 0
16245 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16252 diag::err_builtin_matrix_pointer_arg_mismatch)
16253 << ElementTy << MatrixTy->getElementType();
16268 StrideExpr = StrideConv.
get();
16269 TheCall->
setArg(2, StrideExpr);
16274 if (std::optional<llvm::APSInt>
Value =
16277 if (Stride < MatrixTy->getNumRows()) {
16279 diag::err_builtin_matrix_stride_too_small);
16299 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16304 llvm::StringSet<> CalleeTCBs;
16305 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16306 CalleeTCBs.insert(A->getTCBName());
16307 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16308 CalleeTCBs.insert(A->getTCBName());
16312 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16313 StringRef CallerTCB = A->getTCBName();
16314 if (CalleeTCBs.count(CallerTCB) == 0) {
16315 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16316 << 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 isFloat16Type() const
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
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.