77#include "llvm/ADT/APFloat.h"
78#include "llvm/ADT/APInt.h"
79#include "llvm/ADT/APSInt.h"
80#include "llvm/ADT/ArrayRef.h"
81#include "llvm/ADT/DenseMap.h"
82#include "llvm/ADT/FoldingSet.h"
83#include "llvm/ADT/STLExtras.h"
84#include "llvm/ADT/SmallBitVector.h"
85#include "llvm/ADT/SmallPtrSet.h"
86#include "llvm/ADT/SmallString.h"
87#include "llvm/ADT/SmallVector.h"
88#include "llvm/ADT/StringExtras.h"
89#include "llvm/ADT/StringRef.h"
90#include "llvm/ADT/StringSet.h"
91#include "llvm/ADT/StringSwitch.h"
92#include "llvm/Support/AtomicOrdering.h"
93#include "llvm/Support/Compiler.h"
94#include "llvm/Support/ConvertUTF.h"
95#include "llvm/Support/ErrorHandling.h"
96#include "llvm/Support/Format.h"
97#include "llvm/Support/Locale.h"
98#include "llvm/Support/MathExtras.h"
99#include "llvm/Support/SaveAndRestore.h"
100#include "llvm/Support/raw_ostream.h"
101#include "llvm/TargetParser/RISCVTargetParser.h"
102#include "llvm/TargetParser/Triple.h"
115using namespace clang;
119 unsigned ByteNo)
const {
130 unsigned ArgCount =
Call->getNumArgs();
131 if (ArgCount >= MinArgCount)
134 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
135 << 0 << MinArgCount << ArgCount
136 << 0 <<
Call->getSourceRange();
140 unsigned ArgCount =
Call->getNumArgs();
141 if (ArgCount <= MaxArgCount)
143 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
144 << 0 << MaxArgCount << ArgCount
145 << 0 <<
Call->getSourceRange();
149 unsigned MaxArgCount) {
155 unsigned ArgCount =
Call->getNumArgs();
156 if (ArgCount == DesiredArgCount)
161 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
165 Call->getArg(ArgCount - 1)->getEndLoc());
168 << 0 << DesiredArgCount << ArgCount
169 << 0 <<
Call->getArg(1)->getSourceRange();
173 bool HasError =
false;
175 for (
unsigned I = 0; I <
Call->getNumArgs(); ++I) {
182 int DiagMsgKind = -1;
184 if (!ArgString.has_value())
186 else if (ArgString->find(
'$') != std::string::npos)
189 if (DiagMsgKind >= 0) {
200 if (
Value->isTypeDependent())
231 if (!Literal || !Literal->isOrdinary()) {
244 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
252 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
253 if (!Literal || !Literal->isWide()) {
254 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
255 << Arg->getSourceRange();
289 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
320 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
322 auto IsValidIntegerType = [](
QualType Ty) {
323 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
330 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
334 S.
Diag(Source->
getExprLoc(), diag::err_typecheck_expect_scalar_operand)
340 if (!IsValidIntegerType(AlignOp->
getType())) {
351 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
352 llvm::APSInt MaxValue(
353 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
354 if (AlignValue < 1) {
355 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
358 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
363 if (!AlignValue.isPowerOf2()) {
364 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
367 if (AlignValue == 1) {
368 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
369 << IsBooleanAlignBuiltin;
397 std::pair<unsigned, const char *> Builtins[] = {
398 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
399 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
400 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
403 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
405 return BuiltinID ==
P.first && TheCall->
getExprLoc().isMacroID() &&
410 auto ValidCkdIntType = [](
QualType QT) {
413 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
414 return (BT->getKind() >= BuiltinType::Short &&
415 BT->getKind() <= BuiltinType::Int128) || (
416 BT->getKind() >= BuiltinType::UShort &&
417 BT->getKind() <= BuiltinType::UInt128) ||
418 BT->getKind() == BuiltinType::UChar ||
419 BT->getKind() == BuiltinType::SChar;
424 for (
unsigned I = 0; I < 2; ++I) {
430 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
449 !PtrTy->getPointeeType()->isIntegerType() ||
450 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
451 PtrTy->getPointeeType().isConstQualified()) {
453 diag::err_overflow_builtin_must_be_ptr_int)
461 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
462 for (
unsigned I = 0; I < 3; ++I) {
463 const auto Arg = TheCall->
getArg(I);
466 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
468 return S.
Diag(Arg->getBeginLoc(),
469 diag::err_overflow_builtin_bit_int_max_size)
478struct BuiltinDumpStructGenerator {
487 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
488 Policy(S.Context.getPrintingPolicy()) {
492 Expr *makeOpaqueValueExpr(
Expr *Inner) {
495 Inner->getObjectKind(), Inner);
496 Actions.push_back(OVE);
500 Expr *getStringLiteral(llvm::StringRef Str) {
506 bool callPrintFunction(llvm::StringRef Format,
510 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
512 Args.push_back(getStringLiteral(Format));
513 Args.insert(Args.end(), Exprs.begin(), Exprs.end());
518 Ctx.PointOfInstantiation =
Loc;
519 Ctx.CallArgs = Args.data();
520 Ctx.NumCallArgs = Args.size();
529 Actions.push_back(RealCall.
get());
535 Expr *getIndentString(
unsigned Depth) {
541 return getStringLiteral(Indent);
545 return getStringLiteral(
T.getAsString(Policy));
549 llvm::raw_svector_ostream OS(Str);
554 switch (BT->getKind()) {
555 case BuiltinType::Bool:
558 case BuiltinType::Char_U:
559 case BuiltinType::UChar:
562 case BuiltinType::Char_S:
563 case BuiltinType::SChar:
575 analyze_printf::PrintfConversionSpecifier::sArg) {
601 bool dumpUnnamedRecord(
const RecordDecl *RD,
Expr *
E,
unsigned Depth) {
602 Expr *IndentLit = getIndentString(Depth);
604 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
605 : callPrintFunction(
"%s", {TypeLit}))
608 return dumpRecordValue(RD,
E, IndentLit, Depth);
621 Expr *RecordArg = makeOpaqueValueExpr(
E);
624 if (callPrintFunction(
" {\n"))
628 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
629 for (
const auto &
Base : CXXRD->bases()) {
637 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
643 Expr *FieldIndentArg = getIndentString(Depth + 1);
646 for (
auto *
D : RD->
decls()) {
647 auto *IFD = dyn_cast<IndirectFieldDecl>(
D);
648 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(
D);
649 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
655 getStringLiteral(FD->getName())};
657 if (FD->isBitField()) {
661 FD->getBitWidthValue());
675 if (
Field.isInvalid())
678 auto *InnerRD = FD->getType()->getAsRecordDecl();
679 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
680 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
682 if (callPrintFunction(Format, Args) ||
683 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
687 if (appendFormatSpecifier(FD->getType(), Format)) {
689 Args.push_back(
Field.get());
699 Args.push_back(FieldAddr.
get());
702 if (callPrintFunction(Format, Args))
707 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
708 : callPrintFunction(
"}\n");
711 Expr *buildWrapper() {
714 TheCall->
setType(Wrapper->getType());
735 diag::err_expected_struct_pointer_argument)
744 diag::err_incomplete_type))
753 switch (BT ? BT->getKind() : BuiltinType::Void) {
754 case BuiltinType::Dependent:
755 case BuiltinType::Overload:
756 case BuiltinType::BoundMember:
757 case BuiltinType::PseudoObject:
758 case BuiltinType::UnknownAny:
759 case BuiltinType::BuiltinFn:
765 diag::err_expected_callable_argument)
771 BuiltinDumpStructGenerator Generator(S, TheCall);
777 Expr *PtrArg = PtrArgResult.
get();
781 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
784 return Generator.buildWrapper();
796 if (
Call->getStmtClass() != Stmt::CallExprClass) {
797 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
798 <<
Call->getSourceRange();
802 auto CE = cast<CallExpr>(
Call);
803 if (CE->getCallee()->getType()->isBlockPointerType()) {
804 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
805 <<
Call->getSourceRange();
809 const Decl *TargetDecl = CE->getCalleeDecl();
810 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
811 if (FD->getBuiltinID()) {
812 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
813 <<
Call->getSourceRange();
817 if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {
818 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
819 <<
Call->getSourceRange();
827 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
841 BuiltinCall->
setType(CE->getType());
845 BuiltinCall->
setArg(1, ChainResult.
get());
852class ScanfDiagnosticFormatHandler
856 using ComputeSizeFunction =
857 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
861 using DiagnoseFunction =
862 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
864 ComputeSizeFunction ComputeSizeArgument;
865 DiagnoseFunction Diagnose;
868 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
869 DiagnoseFunction Diagnose)
870 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
873 const char *StartSpecifier,
874 unsigned specifierLen)
override {
875 if (!FS.consumesDataArgument())
878 unsigned NulByte = 0;
879 switch ((FS.getConversionSpecifier().getKind())) {
892 analyze_format_string::OptionalAmount::HowSpecified::Constant)
897 std::optional<llvm::APSInt> DestSizeAPS =
898 ComputeSizeArgument(FS.getArgIndex());
902 unsigned DestSize = DestSizeAPS->getZExtValue();
904 if (DestSize < SourceSize)
905 Diagnose(FS.getArgIndex(), DestSize, SourceSize);
911class EstimateSizeFormatHandler
916 bool IsKernelCompatible =
true;
919 EstimateSizeFormatHandler(StringRef Format)
920 :
Size(
std::
min(Format.find(0), Format.size()) +
924 const char *,
unsigned SpecifierLen,
927 const size_t FieldWidth = computeFieldWidth(FS);
928 const size_t Precision = computePrecision(FS);
931 switch (FS.getConversionSpecifier().getKind()) {
935 Size += std::max(FieldWidth, (
size_t)1);
947 Size += std::max(FieldWidth, Precision);
963 Size += std::max(FieldWidth, 1 +
964 (Precision ? 1 + Precision
974 (Precision ? 1 + Precision : 0) +
984 (Precision ? 1 + Precision : 0) +
999 IsKernelCompatible =
false;
1000 Size += std::max(FieldWidth, 2 + Precision);
1012 Size += FS.hasPlusPrefix() || FS.hasSpacePrefix();
1014 if (FS.hasAlternativeForm()) {
1015 switch (FS.getConversionSpecifier().getKind()) {
1044 Size += (Precision ? 0 : 1);
1051 assert(SpecifierLen <= Size &&
"no underflow");
1052 Size -= SpecifierLen;
1056 size_t getSizeLowerBound()
const {
return Size; }
1057 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1062 size_t FieldWidth = 0;
1070 size_t Precision = 0;
1075 switch (FS.getConversionSpecifier().getKind()) {
1117 StringRef &FormatStrRef,
size_t &StrLen,
1119 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1120 Format && (Format->isOrdinary() || Format->isUTF8())) {
1121 FormatStrRef = Format->getString();
1124 assert(
T &&
"String literal not of constant array type!");
1125 size_t TypeSize =
T->getZExtSize();
1127 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1133void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1139 bool UseDABAttr =
false;
1142 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1144 UseDecl = DABAttr->getFunction();
1145 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1157 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1164 unsigned DABIndices = DABAttr->argIndices_size();
1165 unsigned NewIndex = Index < DABIndices
1166 ? DABAttr->argIndices_begin()[Index]
1169 return std::nullopt;
1173 auto ComputeExplicitObjectSizeArgument =
1174 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1175 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1177 return std::nullopt;
1178 unsigned NewIndex = *IndexOptional;
1182 return std::nullopt;
1188 auto ComputeSizeArgument =
1189 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1195 if (Index < FD->getNumParams()) {
1196 if (
const auto *POS =
1198 BOSType = POS->getType();
1201 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1203 return std::nullopt;
1204 unsigned NewIndex = *IndexOptional;
1207 return std::nullopt;
1209 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1212 return std::nullopt;
1215 return llvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1218 auto ComputeStrLenArgument =
1219 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1220 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1222 return std::nullopt;
1223 unsigned NewIndex = *IndexOptional;
1225 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1228 return std::nullopt;
1230 return llvm::APSInt::getUnsigned(
Result + 1).extOrTrunc(SizeTypeWidth);
1233 std::optional<llvm::APSInt> SourceSize;
1234 std::optional<llvm::APSInt> DestinationSize;
1235 unsigned DiagID = 0;
1236 bool IsChkVariant =
false;
1238 auto GetFunctionName = [&]() {
1244 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1245 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1247 FunctionName.consume_front(
"__builtin_");
1249 return FunctionName;
1252 switch (BuiltinID) {
1255 case Builtin::BI__builtin_strcpy:
1256 case Builtin::BIstrcpy: {
1257 DiagID = diag::warn_fortify_strlen_overflow;
1258 SourceSize = ComputeStrLenArgument(1);
1259 DestinationSize = ComputeSizeArgument(0);
1263 case Builtin::BI__builtin___strcpy_chk: {
1264 DiagID = diag::warn_fortify_strlen_overflow;
1265 SourceSize = ComputeStrLenArgument(1);
1266 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1267 IsChkVariant =
true;
1271 case Builtin::BIscanf:
1272 case Builtin::BIfscanf:
1273 case Builtin::BIsscanf: {
1274 unsigned FormatIndex = 1;
1275 unsigned DataIndex = 2;
1276 if (BuiltinID == Builtin::BIscanf) {
1281 const auto *FormatExpr =
1284 StringRef FormatStrRef;
1289 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1290 unsigned SourceSize) {
1291 DiagID = diag::warn_fortify_scanf_overflow;
1292 unsigned Index = ArgIndex + DataIndex;
1293 StringRef FunctionName = GetFunctionName();
1295 PDiag(DiagID) << FunctionName << (Index + 1)
1296 << DestSize << SourceSize);
1299 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1300 return ComputeSizeArgument(Index + DataIndex);
1302 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1303 const char *FormatBytes = FormatStrRef.data();
1314 case Builtin::BIsprintf:
1315 case Builtin::BI__builtin___sprintf_chk: {
1316 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1319 StringRef FormatStrRef;
1322 EstimateSizeFormatHandler H(FormatStrRef);
1323 const char *FormatBytes = FormatStrRef.data();
1325 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1327 DiagID = H.isKernelCompatible()
1328 ? diag::warn_format_overflow
1329 : diag::warn_format_overflow_non_kprintf;
1330 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1331 .extOrTrunc(SizeTypeWidth);
1332 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1333 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1334 IsChkVariant =
true;
1336 DestinationSize = ComputeSizeArgument(0);
1343 case Builtin::BI__builtin___memcpy_chk:
1344 case Builtin::BI__builtin___memmove_chk:
1345 case Builtin::BI__builtin___memset_chk:
1346 case Builtin::BI__builtin___strlcat_chk:
1347 case Builtin::BI__builtin___strlcpy_chk:
1348 case Builtin::BI__builtin___strncat_chk:
1349 case Builtin::BI__builtin___strncpy_chk:
1350 case Builtin::BI__builtin___stpncpy_chk:
1351 case Builtin::BI__builtin___memccpy_chk:
1352 case Builtin::BI__builtin___mempcpy_chk: {
1353 DiagID = diag::warn_builtin_chk_overflow;
1354 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1356 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1357 IsChkVariant =
true;
1361 case Builtin::BI__builtin___snprintf_chk:
1362 case Builtin::BI__builtin___vsnprintf_chk: {
1363 DiagID = diag::warn_builtin_chk_overflow;
1364 SourceSize = ComputeExplicitObjectSizeArgument(1);
1365 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1366 IsChkVariant =
true;
1370 case Builtin::BIstrncat:
1371 case Builtin::BI__builtin_strncat:
1372 case Builtin::BIstrncpy:
1373 case Builtin::BI__builtin_strncpy:
1374 case Builtin::BIstpncpy:
1375 case Builtin::BI__builtin_stpncpy: {
1381 DiagID = diag::warn_fortify_source_size_mismatch;
1382 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1383 DestinationSize = ComputeSizeArgument(0);
1387 case Builtin::BImemcpy:
1388 case Builtin::BI__builtin_memcpy:
1389 case Builtin::BImemmove:
1390 case Builtin::BI__builtin_memmove:
1391 case Builtin::BImemset:
1392 case Builtin::BI__builtin_memset:
1393 case Builtin::BImempcpy:
1394 case Builtin::BI__builtin_mempcpy: {
1395 DiagID = diag::warn_fortify_source_overflow;
1396 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1397 DestinationSize = ComputeSizeArgument(0);
1400 case Builtin::BIsnprintf:
1401 case Builtin::BI__builtin_snprintf:
1402 case Builtin::BIvsnprintf:
1403 case Builtin::BI__builtin_vsnprintf: {
1404 DiagID = diag::warn_fortify_source_size_mismatch;
1405 SourceSize = ComputeExplicitObjectSizeArgument(1);
1407 StringRef FormatStrRef;
1411 EstimateSizeFormatHandler H(FormatStrRef);
1412 const char *FormatBytes = FormatStrRef.data();
1414 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1416 llvm::APSInt FormatSize =
1417 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1418 .extOrTrunc(SizeTypeWidth);
1419 if (FormatSize > *SourceSize && *SourceSize != 0) {
1420 unsigned TruncationDiagID =
1421 H.isKernelCompatible() ? diag::warn_format_truncation
1422 : diag::warn_format_truncation_non_kprintf;
1425 SourceSize->toString(SpecifiedSizeStr, 10);
1426 FormatSize.toString(FormatSizeStr, 10);
1428 PDiag(TruncationDiagID)
1429 << GetFunctionName() << SpecifiedSizeStr
1434 DestinationSize = ComputeSizeArgument(0);
1438 if (!SourceSize || !DestinationSize ||
1439 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1442 StringRef FunctionName = GetFunctionName();
1446 DestinationSize->toString(DestinationStr, 10);
1447 SourceSize->toString(SourceStr, 10);
1450 << FunctionName << DestinationStr << SourceStr);
1463 while (S && !S->isSEHExceptScope())
1465 if (!S || !(S->getFlags() & NeededScopeFlags)) {
1468 << DRE->getDecl()->getIdentifier();
1480 "__builtin_alloca has invalid address space");
1488enum PointerAuthOpKind {
1537 llvm::raw_svector_ostream Str(
Value);
1546 Result = KeyValue->getZExtValue();
1550static std::pair<const ValueDecl *, CharUnits>
1557 const auto *BaseDecl =
1562 return {BaseDecl,
Result.Val.getLValueOffset()};
1566 bool RequireConstant =
false) {
1574 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1575 return OpKind != PAO_BlendInteger;
1577 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1578 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1579 OpKind == PAO_SignGeneric;
1588 }
else if (AllowsInteger(OpKind) &&
1595 <<
unsigned(OpKind == PAO_Discriminator ? 1
1596 : OpKind == PAO_BlendPointer ? 2
1597 : OpKind == PAO_BlendInteger ? 3
1599 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1609 if (!RequireConstant) {
1611 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1614 ? diag::warn_ptrauth_sign_null_pointer
1615 : diag::warn_ptrauth_auth_null_pointer)
1625 if (OpKind == PAO_Sign) {
1635 else if (isa<FunctionDecl>(BaseDecl))
1643 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1648 assert(OpKind == PAO_Discriminator);
1654 if (
Call->getBuiltinCallee() ==
1655 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1670 assert(
Pointer->getType()->isPointerType());
1676 if (!BaseDecl || !isa<VarDecl>(BaseDecl))
1682 assert(
Integer->getType()->isIntegerType());
1688 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1701 Call->setType(
Call->getArgs()[0]->getType());
1732 PointerAuthOpKind OpKind,
1733 bool RequireConstant) {
1744 Call->setType(
Call->getArgs()[0]->getType());
1760 Call->setType(
Call->getArgs()[0]->getType());
1769 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1772 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1773 if (!Literal || Literal->getCharByteWidth() != 1) {
1803 auto DiagSelect = [&]() -> std::optional<unsigned> {
1810 return std::optional<unsigned>{};
1825 diag::err_incomplete_type))
1829 "Unhandled non-object pointer case");
1857 if (PT->getPointeeType()->isFunctionType()) {
1859 diag::err_builtin_is_within_lifetime_invalid_arg)
1865 if (PT->getPointeeType()->isVariableArrayType()) {
1867 << 1 <<
"__builtin_is_within_lifetime";
1872 diag::err_builtin_is_within_lifetime_invalid_arg)
1885 llvm::Triple::ObjectFormatType CurObjFormat =
1887 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
1900 llvm::Triple::ArchType CurArch =
1902 if (llvm::is_contained(SupportedArchs, CurArch))
1912bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
1919 case llvm::Triple::arm:
1920 case llvm::Triple::armeb:
1921 case llvm::Triple::thumb:
1922 case llvm::Triple::thumbeb:
1924 case llvm::Triple::aarch64:
1925 case llvm::Triple::aarch64_32:
1926 case llvm::Triple::aarch64_be:
1928 case llvm::Triple::bpfeb:
1929 case llvm::Triple::bpfel:
1931 case llvm::Triple::hexagon:
1933 case llvm::Triple::mips:
1934 case llvm::Triple::mipsel:
1935 case llvm::Triple::mips64:
1936 case llvm::Triple::mips64el:
1938 case llvm::Triple::spirv:
1940 case llvm::Triple::systemz:
1942 case llvm::Triple::x86:
1943 case llvm::Triple::x86_64:
1945 case llvm::Triple::ppc:
1946 case llvm::Triple::ppcle:
1947 case llvm::Triple::ppc64:
1948 case llvm::Triple::ppc64le:
1950 case llvm::Triple::amdgcn:
1952 case llvm::Triple::riscv32:
1953 case llvm::Triple::riscv64:
1955 case llvm::Triple::loongarch32:
1956 case llvm::Triple::loongarch64:
1959 case llvm::Triple::wasm32:
1960 case llvm::Triple::wasm64:
1962 case llvm::Triple::nvptx:
1963 case llvm::Triple::nvptx64:
1975 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1976 << ArgIndex << 0 << ArgTy;
1986 EltTy = VecTy->getElementType();
1989 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1990 << ArgIndex << 5 << ArgTy;
2000 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2001 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2002 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2003 "Expecting __builtin_cpu_...");
2005 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2007 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2008 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2009 (!IsCPUSupports && TInfo->supportsCpuIs()));
2011 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2018 ? diag::err_builtin_aix_os_unsupported
2019 : diag::err_builtin_target_unsupported)
2024 if (!isa<StringLiteral>(Arg))
2025 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2029 StringRef Feature = cast<StringLiteral>(Arg)->getString();
2076 TheCall->
setArg(0, Arg0);
2082 << 1 << 7 << Arg0Ty;
2092 TheCall->
setArg(1, Arg1);
2098 << 2 << 8 << Arg1Ty;
2107Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2112 unsigned ICEArguments = 0;
2119 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2121 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2126 if (ArgNo < TheCall->getNumArgs() &&
2129 ICEArguments &= ~(1 << ArgNo);
2133 switch (BuiltinID) {
2134 case Builtin::BI__builtin_cpu_supports:
2135 case Builtin::BI__builtin_cpu_is:
2140 case Builtin::BI__builtin_cpu_init:
2147 case Builtin::BI__builtin___CFStringMakeConstantString:
2151 *
this, BuiltinID, TheCall,
2152 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2155 "Wrong # arguments to builtin CFStringMakeConstantString");
2156 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2159 case Builtin::BI__builtin_ms_va_start:
2160 case Builtin::BI__builtin_stdarg_start:
2161 case Builtin::BI__builtin_va_start:
2162 if (BuiltinVAStart(BuiltinID, TheCall))
2165 case Builtin::BI__va_start: {
2167 case llvm::Triple::aarch64:
2168 case llvm::Triple::arm:
2169 case llvm::Triple::thumb:
2170 if (BuiltinVAStartARMMicrosoft(TheCall))
2174 if (BuiltinVAStart(BuiltinID, TheCall))
2182 case Builtin::BI_interlockedbittestandset_acq:
2183 case Builtin::BI_interlockedbittestandset_rel:
2184 case Builtin::BI_interlockedbittestandset_nf:
2185 case Builtin::BI_interlockedbittestandreset_acq:
2186 case Builtin::BI_interlockedbittestandreset_rel:
2187 case Builtin::BI_interlockedbittestandreset_nf:
2190 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2195 case Builtin::BI_bittest64:
2196 case Builtin::BI_bittestandcomplement64:
2197 case Builtin::BI_bittestandreset64:
2198 case Builtin::BI_bittestandset64:
2199 case Builtin::BI_interlockedbittestandreset64:
2200 case Builtin::BI_interlockedbittestandset64:
2203 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2204 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2208 case Builtin::BI__builtin_set_flt_rounds:
2211 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2212 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2213 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2214 llvm::Triple::ppc64le}))
2218 case Builtin::BI__builtin_isgreater:
2219 case Builtin::BI__builtin_isgreaterequal:
2220 case Builtin::BI__builtin_isless:
2221 case Builtin::BI__builtin_islessequal:
2222 case Builtin::BI__builtin_islessgreater:
2223 case Builtin::BI__builtin_isunordered:
2224 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2227 case Builtin::BI__builtin_fpclassify:
2228 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2231 case Builtin::BI__builtin_isfpclass:
2232 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2235 case Builtin::BI__builtin_isfinite:
2236 case Builtin::BI__builtin_isinf:
2237 case Builtin::BI__builtin_isinf_sign:
2238 case Builtin::BI__builtin_isnan:
2239 case Builtin::BI__builtin_issignaling:
2240 case Builtin::BI__builtin_isnormal:
2241 case Builtin::BI__builtin_issubnormal:
2242 case Builtin::BI__builtin_iszero:
2243 case Builtin::BI__builtin_signbit:
2244 case Builtin::BI__builtin_signbitf:
2245 case Builtin::BI__builtin_signbitl:
2246 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2249 case Builtin::BI__builtin_shufflevector:
2253 case Builtin::BI__builtin_prefetch:
2254 if (BuiltinPrefetch(TheCall))
2257 case Builtin::BI__builtin_alloca_with_align:
2258 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2259 if (BuiltinAllocaWithAlign(TheCall))
2262 case Builtin::BI__builtin_alloca:
2263 case Builtin::BI__builtin_alloca_uninitialized:
2270 case Builtin::BI__arithmetic_fence:
2271 if (BuiltinArithmeticFence(TheCall))
2274 case Builtin::BI__assume:
2275 case Builtin::BI__builtin_assume:
2276 if (BuiltinAssume(TheCall))
2279 case Builtin::BI__builtin_assume_aligned:
2280 if (BuiltinAssumeAligned(TheCall))
2283 case Builtin::BI__builtin_dynamic_object_size:
2284 case Builtin::BI__builtin_object_size:
2288 case Builtin::BI__builtin_longjmp:
2289 if (BuiltinLongjmp(TheCall))
2292 case Builtin::BI__builtin_setjmp:
2293 if (BuiltinSetjmp(TheCall))
2296 case Builtin::BI__builtin_classify_type:
2301 case Builtin::BI__builtin_complex:
2302 if (BuiltinComplex(TheCall))
2305 case Builtin::BI__builtin_constant_p: {
2314 case Builtin::BI__builtin_launder:
2316 case Builtin::BI__builtin_is_within_lifetime:
2318 case Builtin::BI__sync_fetch_and_add:
2319 case Builtin::BI__sync_fetch_and_add_1:
2320 case Builtin::BI__sync_fetch_and_add_2:
2321 case Builtin::BI__sync_fetch_and_add_4:
2322 case Builtin::BI__sync_fetch_and_add_8:
2323 case Builtin::BI__sync_fetch_and_add_16:
2324 case Builtin::BI__sync_fetch_and_sub:
2325 case Builtin::BI__sync_fetch_and_sub_1:
2326 case Builtin::BI__sync_fetch_and_sub_2:
2327 case Builtin::BI__sync_fetch_and_sub_4:
2328 case Builtin::BI__sync_fetch_and_sub_8:
2329 case Builtin::BI__sync_fetch_and_sub_16:
2330 case Builtin::BI__sync_fetch_and_or:
2331 case Builtin::BI__sync_fetch_and_or_1:
2332 case Builtin::BI__sync_fetch_and_or_2:
2333 case Builtin::BI__sync_fetch_and_or_4:
2334 case Builtin::BI__sync_fetch_and_or_8:
2335 case Builtin::BI__sync_fetch_and_or_16:
2336 case Builtin::BI__sync_fetch_and_and:
2337 case Builtin::BI__sync_fetch_and_and_1:
2338 case Builtin::BI__sync_fetch_and_and_2:
2339 case Builtin::BI__sync_fetch_and_and_4:
2340 case Builtin::BI__sync_fetch_and_and_8:
2341 case Builtin::BI__sync_fetch_and_and_16:
2342 case Builtin::BI__sync_fetch_and_xor:
2343 case Builtin::BI__sync_fetch_and_xor_1:
2344 case Builtin::BI__sync_fetch_and_xor_2:
2345 case Builtin::BI__sync_fetch_and_xor_4:
2346 case Builtin::BI__sync_fetch_and_xor_8:
2347 case Builtin::BI__sync_fetch_and_xor_16:
2348 case Builtin::BI__sync_fetch_and_nand:
2349 case Builtin::BI__sync_fetch_and_nand_1:
2350 case Builtin::BI__sync_fetch_and_nand_2:
2351 case Builtin::BI__sync_fetch_and_nand_4:
2352 case Builtin::BI__sync_fetch_and_nand_8:
2353 case Builtin::BI__sync_fetch_and_nand_16:
2354 case Builtin::BI__sync_add_and_fetch:
2355 case Builtin::BI__sync_add_and_fetch_1:
2356 case Builtin::BI__sync_add_and_fetch_2:
2357 case Builtin::BI__sync_add_and_fetch_4:
2358 case Builtin::BI__sync_add_and_fetch_8:
2359 case Builtin::BI__sync_add_and_fetch_16:
2360 case Builtin::BI__sync_sub_and_fetch:
2361 case Builtin::BI__sync_sub_and_fetch_1:
2362 case Builtin::BI__sync_sub_and_fetch_2:
2363 case Builtin::BI__sync_sub_and_fetch_4:
2364 case Builtin::BI__sync_sub_and_fetch_8:
2365 case Builtin::BI__sync_sub_and_fetch_16:
2366 case Builtin::BI__sync_and_and_fetch:
2367 case Builtin::BI__sync_and_and_fetch_1:
2368 case Builtin::BI__sync_and_and_fetch_2:
2369 case Builtin::BI__sync_and_and_fetch_4:
2370 case Builtin::BI__sync_and_and_fetch_8:
2371 case Builtin::BI__sync_and_and_fetch_16:
2372 case Builtin::BI__sync_or_and_fetch:
2373 case Builtin::BI__sync_or_and_fetch_1:
2374 case Builtin::BI__sync_or_and_fetch_2:
2375 case Builtin::BI__sync_or_and_fetch_4:
2376 case Builtin::BI__sync_or_and_fetch_8:
2377 case Builtin::BI__sync_or_and_fetch_16:
2378 case Builtin::BI__sync_xor_and_fetch:
2379 case Builtin::BI__sync_xor_and_fetch_1:
2380 case Builtin::BI__sync_xor_and_fetch_2:
2381 case Builtin::BI__sync_xor_and_fetch_4:
2382 case Builtin::BI__sync_xor_and_fetch_8:
2383 case Builtin::BI__sync_xor_and_fetch_16:
2384 case Builtin::BI__sync_nand_and_fetch:
2385 case Builtin::BI__sync_nand_and_fetch_1:
2386 case Builtin::BI__sync_nand_and_fetch_2:
2387 case Builtin::BI__sync_nand_and_fetch_4:
2388 case Builtin::BI__sync_nand_and_fetch_8:
2389 case Builtin::BI__sync_nand_and_fetch_16:
2390 case Builtin::BI__sync_val_compare_and_swap:
2391 case Builtin::BI__sync_val_compare_and_swap_1:
2392 case Builtin::BI__sync_val_compare_and_swap_2:
2393 case Builtin::BI__sync_val_compare_and_swap_4:
2394 case Builtin::BI__sync_val_compare_and_swap_8:
2395 case Builtin::BI__sync_val_compare_and_swap_16:
2396 case Builtin::BI__sync_bool_compare_and_swap:
2397 case Builtin::BI__sync_bool_compare_and_swap_1:
2398 case Builtin::BI__sync_bool_compare_and_swap_2:
2399 case Builtin::BI__sync_bool_compare_and_swap_4:
2400 case Builtin::BI__sync_bool_compare_and_swap_8:
2401 case Builtin::BI__sync_bool_compare_and_swap_16:
2402 case Builtin::BI__sync_lock_test_and_set:
2403 case Builtin::BI__sync_lock_test_and_set_1:
2404 case Builtin::BI__sync_lock_test_and_set_2:
2405 case Builtin::BI__sync_lock_test_and_set_4:
2406 case Builtin::BI__sync_lock_test_and_set_8:
2407 case Builtin::BI__sync_lock_test_and_set_16:
2408 case Builtin::BI__sync_lock_release:
2409 case Builtin::BI__sync_lock_release_1:
2410 case Builtin::BI__sync_lock_release_2:
2411 case Builtin::BI__sync_lock_release_4:
2412 case Builtin::BI__sync_lock_release_8:
2413 case Builtin::BI__sync_lock_release_16:
2414 case Builtin::BI__sync_swap:
2415 case Builtin::BI__sync_swap_1:
2416 case Builtin::BI__sync_swap_2:
2417 case Builtin::BI__sync_swap_4:
2418 case Builtin::BI__sync_swap_8:
2419 case Builtin::BI__sync_swap_16:
2420 return BuiltinAtomicOverloaded(TheCallResult);
2421 case Builtin::BI__sync_synchronize:
2425 case Builtin::BI__builtin_nontemporal_load:
2426 case Builtin::BI__builtin_nontemporal_store:
2427 return BuiltinNontemporalOverloaded(TheCallResult);
2428 case Builtin::BI__builtin_memcpy_inline: {
2441 case Builtin::BI__builtin_memset_inline: {
2452#define BUILTIN(ID, TYPE, ATTRS)
2453#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2454 case Builtin::BI##ID: \
2455 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2456#include "clang/Basic/Builtins.inc"
2457 case Builtin::BI__annotation:
2461 case Builtin::BI__builtin_annotation:
2465 case Builtin::BI__builtin_addressof:
2469 case Builtin::BI__builtin_function_start:
2473 case Builtin::BI__builtin_is_aligned:
2474 case Builtin::BI__builtin_align_up:
2475 case Builtin::BI__builtin_align_down:
2479 case Builtin::BI__builtin_add_overflow:
2480 case Builtin::BI__builtin_sub_overflow:
2481 case Builtin::BI__builtin_mul_overflow:
2485 case Builtin::BI__builtin_operator_new:
2486 case Builtin::BI__builtin_operator_delete: {
2487 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2489 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2494 case Builtin::BI__builtin_dump_struct:
2496 case Builtin::BI__builtin_expect_with_probability: {
2507 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2514 bool LoseInfo =
false;
2515 Probability.convert(llvm::APFloat::IEEEdouble(),
2516 llvm::RoundingMode::Dynamic, &LoseInfo);
2517 if (!(Probability >= llvm::APFloat(0.0) &&
2518 Probability <= llvm::APFloat(1.0))) {
2525 case Builtin::BI__builtin_preserve_access_index:
2529 case Builtin::BI__builtin_call_with_static_chain:
2533 case Builtin::BI__exception_code:
2534 case Builtin::BI_exception_code:
2536 diag::err_seh___except_block))
2539 case Builtin::BI__exception_info:
2540 case Builtin::BI_exception_info:
2542 diag::err_seh___except_filter))
2545 case Builtin::BI__GetExceptionInfo:
2557 case Builtin::BIaddressof:
2558 case Builtin::BI__addressof:
2559 case Builtin::BIforward:
2560 case Builtin::BIforward_like:
2561 case Builtin::BImove:
2562 case Builtin::BImove_if_noexcept:
2563 case Builtin::BIas_const: {
2571 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
2572 BuiltinID == Builtin::BI__addressof;
2574 (ReturnsPointer ?
Result->isAnyPointerType()
2575 :
Result->isReferenceType()) &&
2577 Result->getPointeeType()))) {
2578 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
2584 case Builtin::BI__builtin_ptrauth_strip:
2586 case Builtin::BI__builtin_ptrauth_blend_discriminator:
2588 case Builtin::BI__builtin_ptrauth_sign_constant:
2591 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
2594 case Builtin::BI__builtin_ptrauth_auth:
2597 case Builtin::BI__builtin_ptrauth_sign_generic_data:
2599 case Builtin::BI__builtin_ptrauth_auth_and_resign:
2601 case Builtin::BI__builtin_ptrauth_string_discriminator:
2604 case Builtin::BIread_pipe:
2605 case Builtin::BIwrite_pipe:
2608 if (
OpenCL().checkBuiltinRWPipe(TheCall))
2611 case Builtin::BIreserve_read_pipe:
2612 case Builtin::BIreserve_write_pipe:
2613 case Builtin::BIwork_group_reserve_read_pipe:
2614 case Builtin::BIwork_group_reserve_write_pipe:
2615 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
2618 case Builtin::BIsub_group_reserve_read_pipe:
2619 case Builtin::BIsub_group_reserve_write_pipe:
2620 if (
OpenCL().checkSubgroupExt(TheCall) ||
2621 OpenCL().checkBuiltinReserveRWPipe(TheCall))
2624 case Builtin::BIcommit_read_pipe:
2625 case Builtin::BIcommit_write_pipe:
2626 case Builtin::BIwork_group_commit_read_pipe:
2627 case Builtin::BIwork_group_commit_write_pipe:
2628 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
2631 case Builtin::BIsub_group_commit_read_pipe:
2632 case Builtin::BIsub_group_commit_write_pipe:
2633 if (
OpenCL().checkSubgroupExt(TheCall) ||
2634 OpenCL().checkBuiltinCommitRWPipe(TheCall))
2637 case Builtin::BIget_pipe_num_packets:
2638 case Builtin::BIget_pipe_max_packets:
2639 if (
OpenCL().checkBuiltinPipePackets(TheCall))
2642 case Builtin::BIto_global:
2643 case Builtin::BIto_local:
2644 case Builtin::BIto_private:
2645 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
2649 case Builtin::BIenqueue_kernel:
2650 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
2653 case Builtin::BIget_kernel_work_group_size:
2654 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
2655 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
2658 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2659 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
2660 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
2663 case Builtin::BI__builtin_os_log_format:
2666 case Builtin::BI__builtin_os_log_format_buffer_size:
2667 if (BuiltinOSLogFormat(TheCall))
2670 case Builtin::BI__builtin_frame_address:
2671 case Builtin::BI__builtin_return_address: {
2680 Result.Val.getInt() != 0)
2682 << ((BuiltinID == Builtin::BI__builtin_return_address)
2683 ?
"__builtin_return_address"
2684 :
"__builtin_frame_address")
2689 case Builtin::BI__builtin_nondeterministic_value: {
2690 if (BuiltinNonDeterministicValue(TheCall))
2697 case Builtin::BI__builtin_elementwise_abs: {
2705 EltTy = VecTy->getElementType();
2708 diag::err_builtin_invalid_arg_type)
2717 case Builtin::BI__builtin_elementwise_acos:
2718 case Builtin::BI__builtin_elementwise_asin:
2719 case Builtin::BI__builtin_elementwise_atan:
2720 case Builtin::BI__builtin_elementwise_ceil:
2721 case Builtin::BI__builtin_elementwise_cos:
2722 case Builtin::BI__builtin_elementwise_cosh:
2723 case Builtin::BI__builtin_elementwise_exp:
2724 case Builtin::BI__builtin_elementwise_exp2:
2725 case Builtin::BI__builtin_elementwise_floor:
2726 case Builtin::BI__builtin_elementwise_log:
2727 case Builtin::BI__builtin_elementwise_log2:
2728 case Builtin::BI__builtin_elementwise_log10:
2729 case Builtin::BI__builtin_elementwise_roundeven:
2730 case Builtin::BI__builtin_elementwise_round:
2731 case Builtin::BI__builtin_elementwise_rint:
2732 case Builtin::BI__builtin_elementwise_nearbyint:
2733 case Builtin::BI__builtin_elementwise_sin:
2734 case Builtin::BI__builtin_elementwise_sinh:
2735 case Builtin::BI__builtin_elementwise_sqrt:
2736 case Builtin::BI__builtin_elementwise_tan:
2737 case Builtin::BI__builtin_elementwise_tanh:
2738 case Builtin::BI__builtin_elementwise_trunc:
2739 case Builtin::BI__builtin_elementwise_canonicalize: {
2749 case Builtin::BI__builtin_elementwise_fma: {
2757 case Builtin::BI__builtin_elementwise_minimum:
2758 case Builtin::BI__builtin_elementwise_maximum:
2759 case Builtin::BI__builtin_elementwise_atan2:
2760 case Builtin::BI__builtin_elementwise_fmod:
2761 case Builtin::BI__builtin_elementwise_pow: {
2762 if (BuiltinElementwiseMath(TheCall,
true))
2769 case Builtin::BI__builtin_elementwise_add_sat:
2770 case Builtin::BI__builtin_elementwise_sub_sat: {
2771 if (BuiltinElementwiseMath(TheCall))
2779 EltTy = VecTy->getElementType();
2789 case Builtin::BI__builtin_elementwise_min:
2790 case Builtin::BI__builtin_elementwise_max:
2791 if (BuiltinElementwiseMath(TheCall))
2794 case Builtin::BI__builtin_elementwise_popcount:
2795 case Builtin::BI__builtin_elementwise_bitreverse: {
2804 EltTy = VecTy->getElementType();
2814 case Builtin::BI__builtin_elementwise_copysign: {
2834 diag::err_typecheck_call_different_arg_types)
2835 << MagnitudeTy << SignTy;
2843 case Builtin::BI__builtin_reduce_max:
2844 case Builtin::BI__builtin_reduce_min: {
2845 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2853 ElTy = TyA->getElementType();
2857 if (ElTy.isNull()) {
2866 case Builtin::BI__builtin_reduce_maximum:
2867 case Builtin::BI__builtin_reduce_minimum: {
2868 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2876 ElTy = TyA->getElementType();
2880 if (ElTy.isNull() || !ElTy->isFloatingType()) {
2892 case Builtin::BI__builtin_reduce_add:
2893 case Builtin::BI__builtin_reduce_mul:
2894 case Builtin::BI__builtin_reduce_xor:
2895 case Builtin::BI__builtin_reduce_or:
2896 case Builtin::BI__builtin_reduce_and: {
2897 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2905 ElTy = TyA->getElementType();
2909 if (ElTy.isNull() || !ElTy->isIntegerType()) {
2919 case Builtin::BI__builtin_matrix_transpose:
2920 return BuiltinMatrixTranspose(TheCall, TheCallResult);
2922 case Builtin::BI__builtin_matrix_column_major_load:
2923 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
2925 case Builtin::BI__builtin_matrix_column_major_store:
2926 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
2928 case Builtin::BI__builtin_verbose_trap:
2933 case Builtin::BI__builtin_get_device_side_mangled_name: {
2934 auto Check = [](
CallExpr *TheCall) {
2940 auto *
D = DRE->getDecl();
2941 if (!isa<FunctionDecl>(
D) && !isa<VarDecl>(
D))
2946 if (!Check(TheCall)) {
2948 diag::err_hip_invalid_args_builtin_mangled_name);
2953 case Builtin::BI__builtin_popcountg:
2957 case Builtin::BI__builtin_clzg:
2958 case Builtin::BI__builtin_ctzg:
2963 case Builtin::BI__builtin_allow_runtime_check: {
2973 case Builtin::BI__builtin_counted_by_ref:
2974 if (BuiltinCountedByRef(TheCall))
2987 "Aux Target Builtin, but not an aux target?");
2989 if (CheckTSBuiltinFunctionCall(
3000 return TheCallResult;
3015 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3019 diag::err_argument_not_contiguous_bit_field)
3025 if (Format->getFirstArg() == 0)
3027 else if (IsVariadic)
3031 FSI->
FormatIdx = Format->getFormatIdx() - 1;
3055 if (isa<CXXNullPtrLiteralExpr>(
3070 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3071 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3072 Expr = ILE->getInit(0);
3082 const Expr *ArgExpr,
3086 S.
PDiag(diag::warn_null_arg)
3092 if (
auto nullability =
type->getNullability())
3103 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3109 llvm::SmallBitVector NonNullArgs;
3115 for (
const auto *Arg : Args)
3122 unsigned IdxAST = Idx.getASTIndex();
3123 if (IdxAST >= Args.size())
3125 if (NonNullArgs.empty())
3126 NonNullArgs.resize(Args.size());
3127 NonNullArgs.set(IdxAST);
3132 if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {
3136 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3139 parms = cast<ObjCMethodDecl>(FDecl)->parameters();
3141 unsigned ParamIndex = 0;
3143 I !=
E; ++I, ++ParamIndex) {
3146 if (NonNullArgs.empty())
3147 NonNullArgs.resize(Args.size());
3149 NonNullArgs.set(ParamIndex);
3156 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3161 type = blockType->getPointeeType();
3175 if (NonNullArgs.empty())
3176 NonNullArgs.resize(Args.size());
3178 NonNullArgs.set(Index);
3187 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3188 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3189 if (NonNullArgs[ArgIndex])
3195 StringRef ParamName,
QualType ArgTy,
3223 if (ArgAlign < ParamAlign)
3224 Diag(
Loc, diag::warn_param_mismatched_alignment)
3226 << ParamName << (FDecl !=
nullptr) << FDecl;
3230 const Expr *ThisArg,
3232 if (!FD || Args.empty())
3234 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3235 if (Idx == LifetimeCaptureByAttr::GLOBAL ||
3236 Idx == LifetimeCaptureByAttr::UNKNOWN)
3238 if (IsMemberFunction && Idx == 0)
3240 return Args[Idx - IsMemberFunction];
3242 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3247 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3248 for (
int CapturingParamIdx :
Attr->params()) {
3251 if (CapturingParamIdx == LifetimeCaptureByAttr::THIS &&
3252 isa<CXXConstructorDecl>(FD))
3254 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3262 I + IsMemberFunction);
3264 if (IsMemberFunction) {
3272 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3285 llvm::SmallBitVector CheckedVarArgs;
3289 CheckedVarArgs.resize(Args.size());
3291 CheckFormatArguments(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3298 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3302 : isa_and_nonnull<FunctionDecl>(FDecl)
3303 ? cast<FunctionDecl>(FDecl)->getNumParams()
3304 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3305 ? cast<ObjCMethodDecl>(FDecl)->param_size()
3308 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3310 if (
const Expr *Arg = Args[ArgIdx]) {
3311 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3318 if (FDecl || Proto) {
3323 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3324 CheckArgumentWithTypeTag(I, Args,
Loc);
3330 if (!Proto && FDecl) {
3332 if (isa_and_nonnull<FunctionProtoType>(FT))
3338 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3340 bool IsScalableArg =
false;
3341 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3343 if (
const Expr *Arg = Args[ArgIdx]) {
3355 IsScalableArg =
true;
3357 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3366 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3367 llvm::StringMap<bool> CallerFeatureMap;
3369 if (!CallerFeatureMap.contains(
"sme"))
3370 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3372 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3379 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3381 (IsScalableArg || IsScalableRet)) {
3382 bool IsCalleeStreaming =
3384 bool IsCalleeStreamingCompatible =
3388 if (!IsCalleeStreamingCompatible &&
3392 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3395 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3406 bool CallerHasZAState =
false;
3407 bool CallerHasZT0State =
false;
3409 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3411 CallerHasZAState =
true;
3413 CallerHasZT0State =
true;
3417 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3419 CallerHasZT0State |=
3421 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3427 Diag(
Loc, diag::err_sme_za_call_no_za_state);
3430 Diag(
Loc, diag::err_sme_zt0_call_no_zt0_state);
3434 Diag(
Loc, diag::err_sme_unimplemented_za_save_restore);
3435 Diag(
Loc, diag::note_sme_use_preserves_za);
3440 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3441 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3442 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3443 if (!Arg->isValueDependent()) {
3445 if (Arg->EvaluateAsInt(Align,
Context)) {
3446 const llvm::APSInt &I = Align.
Val.
getInt();
3447 if (!I.isPowerOf2())
3448 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3449 << Arg->getSourceRange();
3452 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3475 auto *Ctor = cast<CXXConstructorDecl>(FDecl);
3480 checkCall(FDecl, Proto,
nullptr, Args,
true,
3486 bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
3487 isa<CXXMethodDecl>(FDecl);
3488 bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
3489 IsMemberOperatorCall;
3495 Expr *ImplicitThis =
nullptr;
3500 ImplicitThis = Args[0];
3503 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
3506 cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
3518 cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());
3520 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
3538 CheckAbsoluteValueFunction(TheCall, FDecl);
3539 CheckMaxUnsignedZero(TheCall, FDecl);
3540 CheckInfNaNFunction(TheCall, FDecl);
3551 case Builtin::BIstrlcpy:
3552 case Builtin::BIstrlcat:
3553 CheckStrlcpycatArguments(TheCall, FnInfo);
3555 case Builtin::BIstrncat:
3556 CheckStrncatArguments(TheCall, FnInfo);
3558 case Builtin::BIfree:
3559 CheckFreeArguments(TheCall);
3562 CheckMemaccessArguments(TheCall, CMId, FnInfo);
3571 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
3572 Ty =
V->getType().getNonReferenceType();
3573 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
3574 Ty = F->getType().getNonReferenceType();
3611 if (!llvm::isValidAtomicOrderingCABI(Ordering))
3614 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
3616 case AtomicExpr::AO__c11_atomic_init:
3617 case AtomicExpr::AO__opencl_atomic_init:
3618 llvm_unreachable(
"There is no ordering argument for an init");
3620 case AtomicExpr::AO__c11_atomic_load:
3621 case AtomicExpr::AO__opencl_atomic_load:
3622 case AtomicExpr::AO__hip_atomic_load:
3623 case AtomicExpr::AO__atomic_load_n:
3624 case AtomicExpr::AO__atomic_load:
3625 case AtomicExpr::AO__scoped_atomic_load_n:
3626 case AtomicExpr::AO__scoped_atomic_load:
3627 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
3628 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3630 case AtomicExpr::AO__c11_atomic_store:
3631 case AtomicExpr::AO__opencl_atomic_store:
3632 case AtomicExpr::AO__hip_atomic_store:
3633 case AtomicExpr::AO__atomic_store:
3634 case AtomicExpr::AO__atomic_store_n:
3635 case AtomicExpr::AO__scoped_atomic_store:
3636 case AtomicExpr::AO__scoped_atomic_store_n:
3637 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
3638 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
3639 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3648 CallExpr *TheCall = cast<CallExpr>(TheCallResult.
get());
3692 const unsigned NumForm = GNUCmpXchg + 1;
3693 const unsigned NumArgs[] = { 2, 2, 3, 3, 3, 3, 4, 5, 6 };
3694 const unsigned NumVals[] = { 1, 0, 1, 1, 1, 1, 2, 2, 3 };
3702 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
3703 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
3704 "need to update code for modified forms");
3705 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
3706 AtomicExpr::AO__atomic_xor_fetch + 1 ==
3707 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
3708 "need to update code for modified C11 atomics");
3709 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
3710 Op <= AtomicExpr::AO__opencl_atomic_store;
3711 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
3712 Op <= AtomicExpr::AO__hip_atomic_store;
3713 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
3714 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
3715 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
3716 Op <= AtomicExpr::AO__c11_atomic_store) ||
3718 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
3719 Op == AtomicExpr::AO__atomic_store_n ||
3720 Op == AtomicExpr::AO__atomic_exchange_n ||
3721 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
3722 Op == AtomicExpr::AO__scoped_atomic_load_n ||
3723 Op == AtomicExpr::AO__scoped_atomic_store_n ||
3724 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
3725 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
3729 enum ArithOpExtraValueType {
3734 unsigned ArithAllows = AOEVT_None;
3737 case AtomicExpr::AO__c11_atomic_init:
3738 case AtomicExpr::AO__opencl_atomic_init:
3742 case AtomicExpr::AO__c11_atomic_load:
3743 case AtomicExpr::AO__opencl_atomic_load:
3744 case AtomicExpr::AO__hip_atomic_load:
3745 case AtomicExpr::AO__atomic_load_n:
3746 case AtomicExpr::AO__scoped_atomic_load_n:
3750 case AtomicExpr::AO__atomic_load:
3751 case AtomicExpr::AO__scoped_atomic_load:
3755 case AtomicExpr::AO__c11_atomic_store:
3756 case AtomicExpr::AO__opencl_atomic_store:
3757 case AtomicExpr::AO__hip_atomic_store:
3758 case AtomicExpr::AO__atomic_store:
3759 case AtomicExpr::AO__atomic_store_n:
3760 case AtomicExpr::AO__scoped_atomic_store:
3761 case AtomicExpr::AO__scoped_atomic_store_n:
3764 case AtomicExpr::AO__atomic_fetch_add:
3765 case AtomicExpr::AO__atomic_fetch_sub:
3766 case AtomicExpr::AO__atomic_add_fetch:
3767 case AtomicExpr::AO__atomic_sub_fetch:
3768 case AtomicExpr::AO__scoped_atomic_fetch_add:
3769 case AtomicExpr::AO__scoped_atomic_fetch_sub:
3770 case AtomicExpr::AO__scoped_atomic_add_fetch:
3771 case AtomicExpr::AO__scoped_atomic_sub_fetch:
3772 case AtomicExpr::AO__c11_atomic_fetch_add:
3773 case AtomicExpr::AO__c11_atomic_fetch_sub:
3774 case AtomicExpr::AO__opencl_atomic_fetch_add:
3775 case AtomicExpr::AO__opencl_atomic_fetch_sub:
3776 case AtomicExpr::AO__hip_atomic_fetch_add:
3777 case AtomicExpr::AO__hip_atomic_fetch_sub:
3778 ArithAllows = AOEVT_Pointer | AOEVT_FP;
3781 case AtomicExpr::AO__atomic_fetch_max:
3782 case AtomicExpr::AO__atomic_fetch_min:
3783 case AtomicExpr::AO__atomic_max_fetch:
3784 case AtomicExpr::AO__atomic_min_fetch:
3785 case AtomicExpr::AO__scoped_atomic_fetch_max:
3786 case AtomicExpr::AO__scoped_atomic_fetch_min:
3787 case AtomicExpr::AO__scoped_atomic_max_fetch:
3788 case AtomicExpr::AO__scoped_atomic_min_fetch:
3789 case AtomicExpr::AO__c11_atomic_fetch_max:
3790 case AtomicExpr::AO__c11_atomic_fetch_min:
3791 case AtomicExpr::AO__opencl_atomic_fetch_max:
3792 case AtomicExpr::AO__opencl_atomic_fetch_min:
3793 case AtomicExpr::AO__hip_atomic_fetch_max:
3794 case AtomicExpr::AO__hip_atomic_fetch_min:
3795 ArithAllows = AOEVT_FP;
3798 case AtomicExpr::AO__c11_atomic_fetch_and:
3799 case AtomicExpr::AO__c11_atomic_fetch_or:
3800 case AtomicExpr::AO__c11_atomic_fetch_xor:
3801 case AtomicExpr::AO__hip_atomic_fetch_and:
3802 case AtomicExpr::AO__hip_atomic_fetch_or:
3803 case AtomicExpr::AO__hip_atomic_fetch_xor:
3804 case AtomicExpr::AO__c11_atomic_fetch_nand:
3805 case AtomicExpr::AO__opencl_atomic_fetch_and:
3806 case AtomicExpr::AO__opencl_atomic_fetch_or:
3807 case AtomicExpr::AO__opencl_atomic_fetch_xor:
3808 case AtomicExpr::AO__atomic_fetch_and:
3809 case AtomicExpr::AO__atomic_fetch_or:
3810 case AtomicExpr::AO__atomic_fetch_xor:
3811 case AtomicExpr::AO__atomic_fetch_nand:
3812 case AtomicExpr::AO__atomic_and_fetch:
3813 case AtomicExpr::AO__atomic_or_fetch:
3814 case AtomicExpr::AO__atomic_xor_fetch:
3815 case AtomicExpr::AO__atomic_nand_fetch:
3816 case AtomicExpr::AO__scoped_atomic_fetch_and:
3817 case AtomicExpr::AO__scoped_atomic_fetch_or:
3818 case AtomicExpr::AO__scoped_atomic_fetch_xor:
3819 case AtomicExpr::AO__scoped_atomic_fetch_nand:
3820 case AtomicExpr::AO__scoped_atomic_and_fetch:
3821 case AtomicExpr::AO__scoped_atomic_or_fetch:
3822 case AtomicExpr::AO__scoped_atomic_xor_fetch:
3823 case AtomicExpr::AO__scoped_atomic_nand_fetch:
3827 case AtomicExpr::AO__c11_atomic_exchange:
3828 case AtomicExpr::AO__hip_atomic_exchange:
3829 case AtomicExpr::AO__opencl_atomic_exchange:
3830 case AtomicExpr::AO__atomic_exchange_n:
3831 case AtomicExpr::AO__scoped_atomic_exchange_n:
3835 case AtomicExpr::AO__atomic_exchange:
3836 case AtomicExpr::AO__scoped_atomic_exchange:
3840 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
3841 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
3842 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
3843 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
3844 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
3845 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
3849 case AtomicExpr::AO__atomic_compare_exchange:
3850 case AtomicExpr::AO__atomic_compare_exchange_n:
3851 case AtomicExpr::AO__scoped_atomic_compare_exchange:
3852 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
3857 unsigned AdjustedNumArgs = NumArgs[Form];
3858 if ((IsOpenCL || IsHIP || IsScoped) &&
3859 Op != AtomicExpr::AO__opencl_atomic_init)
3862 if (Args.size() < AdjustedNumArgs) {
3863 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
3864 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3867 }
else if (Args.size() > AdjustedNumArgs) {
3868 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
3869 diag::err_typecheck_call_too_many_args)
3870 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3876 Expr *Ptr = Args[0];
3881 Ptr = ConvertedPtr.
get();
3884 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3894 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
3900 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
3906 }
else if (Form != Load && Form != LoadCopy) {
3908 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
3916 diag::err_incomplete_type))
3919 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3925 if (Form == Arithmetic) {
3928 auto IsAllowedValueType = [&](
QualType ValType,
3929 unsigned AllowedType) ->
bool {
3933 return AllowedType & AOEVT_Pointer;
3939 &llvm::APFloat::x87DoubleExtended())
3943 if (!IsAllowedValueType(ValType, ArithAllows)) {
3944 auto DID = ArithAllows & AOEVT_FP
3945 ? (ArithAllows & AOEVT_Pointer
3946 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
3947 : diag::err_atomic_op_needs_atomic_int_or_fp)
3948 : diag::err_atomic_op_needs_atomic_int;
3955 diag::err_incomplete_type)) {
3961 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
3972 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
3988 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4000 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg ||
4003 else if (Form == C11CmpXchg || Form == GNUCmpXchg)
4009 bool IsPassedByAddress =
false;
4010 if (!IsC11 && !IsHIP && !IsN) {
4012 IsPassedByAddress =
true;
4017 APIOrderedArgs.push_back(Args[0]);
4021 APIOrderedArgs.push_back(Args[1]);
4027 APIOrderedArgs.push_back(Args[2]);
4028 APIOrderedArgs.push_back(Args[1]);
4031 APIOrderedArgs.push_back(Args[2]);
4032 APIOrderedArgs.push_back(Args[3]);
4033 APIOrderedArgs.push_back(Args[1]);
4036 APIOrderedArgs.push_back(Args[2]);
4037 APIOrderedArgs.push_back(Args[4]);
4038 APIOrderedArgs.push_back(Args[1]);
4039 APIOrderedArgs.push_back(Args[3]);
4042 APIOrderedArgs.push_back(Args[2]);
4043 APIOrderedArgs.push_back(Args[4]);
4044 APIOrderedArgs.push_back(Args[5]);
4045 APIOrderedArgs.push_back(Args[1]);
4046 APIOrderedArgs.push_back(Args[3]);
4050 APIOrderedArgs.append(Args.begin(), Args.end());
4057 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4059 if (i < NumVals[Form] + 1) {
4072 assert(Form != Load);
4075 else if (Form ==
Init || Form == Arithmetic)
4077 else if (Form ==
Copy || Form == Xchg) {
4078 if (IsPassedByAddress) {
4085 Expr *ValArg = APIOrderedArgs[i];
4092 AS = PtrTy->getPointeeType().getAddressSpace();
4101 if (IsPassedByAddress)
4121 APIOrderedArgs[i] = Arg.
get();
4126 SubExprs.push_back(Ptr);
4130 SubExprs.push_back(APIOrderedArgs[1]);
4133 SubExprs.push_back(APIOrderedArgs[1]);
4139 SubExprs.push_back(APIOrderedArgs[2]);
4140 SubExprs.push_back(APIOrderedArgs[1]);
4144 SubExprs.push_back(APIOrderedArgs[3]);
4145 SubExprs.push_back(APIOrderedArgs[1]);
4146 SubExprs.push_back(APIOrderedArgs[2]);
4149 SubExprs.push_back(APIOrderedArgs[3]);
4150 SubExprs.push_back(APIOrderedArgs[1]);
4151 SubExprs.push_back(APIOrderedArgs[4]);
4152 SubExprs.push_back(APIOrderedArgs[2]);
4155 SubExprs.push_back(APIOrderedArgs[4]);
4156 SubExprs.push_back(APIOrderedArgs[1]);
4157 SubExprs.push_back(APIOrderedArgs[5]);
4158 SubExprs.push_back(APIOrderedArgs[2]);
4159 SubExprs.push_back(APIOrderedArgs[3]);
4164 if (SubExprs.size() >= 2 && Form !=
Init) {
4165 std::optional<llvm::APSInt>
Success =
4166 SubExprs[1]->getIntegerConstantExpr(
Context);
4168 Diag(SubExprs[1]->getBeginLoc(),
4169 diag::warn_atomic_op_has_invalid_memory_order)
4170 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4171 << SubExprs[1]->getSourceRange();
4173 if (SubExprs.size() >= 5) {
4174 if (std::optional<llvm::APSInt> Failure =
4175 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4176 if (!llvm::is_contained(
4177 {llvm::AtomicOrderingCABI::relaxed,
4178 llvm::AtomicOrderingCABI::consume,
4179 llvm::AtomicOrderingCABI::acquire,
4180 llvm::AtomicOrderingCABI::seq_cst},
4181 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4182 Diag(SubExprs[3]->getBeginLoc(),
4183 diag::warn_atomic_op_has_invalid_memory_order)
4184 << 2 << SubExprs[3]->getSourceRange();
4191 auto *
Scope = Args[Args.size() - 1];
4192 if (std::optional<llvm::APSInt>
Result =
4194 if (!ScopeModel->isValid(
Result->getZExtValue()))
4195 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope)
4196 <<
Scope->getSourceRange();
4198 SubExprs.push_back(
Scope);
4204 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4205 Op == AtomicExpr::AO__c11_atomic_store ||
4206 Op == AtomicExpr::AO__opencl_atomic_load ||
4207 Op == AtomicExpr::AO__hip_atomic_load ||
4208 Op == AtomicExpr::AO__opencl_atomic_store ||
4209 Op == AtomicExpr::AO__hip_atomic_store) &&
4212 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4213 Op == AtomicExpr::AO__opencl_atomic_load ||
4214 Op == AtomicExpr::AO__hip_atomic_load)
4219 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4235 assert(Fn &&
"builtin call without direct callee!");
4246 E->setArg(ArgIndex, Arg.
get());
4258 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4260 <<
Callee->getSourceRange();
4273 FirstArg = FirstArgResult.
get();
4274 TheCall->
setArg(0, FirstArg);
4286 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4321#define BUILTIN_ROW(x) \
4322 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4323 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4325 static const unsigned BuiltinIndices[][5] = {
4351 case 1: SizeIndex = 0;
break;
4352 case 2: SizeIndex = 1;
break;
4353 case 4: SizeIndex = 2;
break;
4354 case 8: SizeIndex = 3;
break;
4355 case 16: SizeIndex = 4;
break;
4367 unsigned BuiltinIndex, NumFixed = 1;
4368 bool WarnAboutSemanticsChange =
false;
4369 switch (BuiltinID) {
4370 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4371 case Builtin::BI__sync_fetch_and_add:
4372 case Builtin::BI__sync_fetch_and_add_1:
4373 case Builtin::BI__sync_fetch_and_add_2:
4374 case Builtin::BI__sync_fetch_and_add_4:
4375 case Builtin::BI__sync_fetch_and_add_8:
4376 case Builtin::BI__sync_fetch_and_add_16:
4380 case Builtin::BI__sync_fetch_and_sub:
4381 case Builtin::BI__sync_fetch_and_sub_1:
4382 case Builtin::BI__sync_fetch_and_sub_2:
4383 case Builtin::BI__sync_fetch_and_sub_4:
4384 case Builtin::BI__sync_fetch_and_sub_8:
4385 case Builtin::BI__sync_fetch_and_sub_16:
4389 case Builtin::BI__sync_fetch_and_or:
4390 case Builtin::BI__sync_fetch_and_or_1:
4391 case Builtin::BI__sync_fetch_and_or_2:
4392 case Builtin::BI__sync_fetch_and_or_4:
4393 case Builtin::BI__sync_fetch_and_or_8:
4394 case Builtin::BI__sync_fetch_and_or_16:
4398 case Builtin::BI__sync_fetch_and_and:
4399 case Builtin::BI__sync_fetch_and_and_1:
4400 case Builtin::BI__sync_fetch_and_and_2:
4401 case Builtin::BI__sync_fetch_and_and_4:
4402 case Builtin::BI__sync_fetch_and_and_8:
4403 case Builtin::BI__sync_fetch_and_and_16:
4407 case Builtin::BI__sync_fetch_and_xor:
4408 case Builtin::BI__sync_fetch_and_xor_1:
4409 case Builtin::BI__sync_fetch_and_xor_2:
4410 case Builtin::BI__sync_fetch_and_xor_4:
4411 case Builtin::BI__sync_fetch_and_xor_8:
4412 case Builtin::BI__sync_fetch_and_xor_16:
4416 case Builtin::BI__sync_fetch_and_nand:
4417 case Builtin::BI__sync_fetch_and_nand_1:
4418 case Builtin::BI__sync_fetch_and_nand_2:
4419 case Builtin::BI__sync_fetch_and_nand_4:
4420 case Builtin::BI__sync_fetch_and_nand_8:
4421 case Builtin::BI__sync_fetch_and_nand_16:
4423 WarnAboutSemanticsChange =
true;
4426 case Builtin::BI__sync_add_and_fetch:
4427 case Builtin::BI__sync_add_and_fetch_1:
4428 case Builtin::BI__sync_add_and_fetch_2:
4429 case Builtin::BI__sync_add_and_fetch_4:
4430 case Builtin::BI__sync_add_and_fetch_8:
4431 case Builtin::BI__sync_add_and_fetch_16:
4435 case Builtin::BI__sync_sub_and_fetch:
4436 case Builtin::BI__sync_sub_and_fetch_1:
4437 case Builtin::BI__sync_sub_and_fetch_2:
4438 case Builtin::BI__sync_sub_and_fetch_4:
4439 case Builtin::BI__sync_sub_and_fetch_8:
4440 case Builtin::BI__sync_sub_and_fetch_16:
4444 case Builtin::BI__sync_and_and_fetch:
4445 case Builtin::BI__sync_and_and_fetch_1:
4446 case Builtin::BI__sync_and_and_fetch_2:
4447 case Builtin::BI__sync_and_and_fetch_4:
4448 case Builtin::BI__sync_and_and_fetch_8:
4449 case Builtin::BI__sync_and_and_fetch_16:
4453 case Builtin::BI__sync_or_and_fetch:
4454 case Builtin::BI__sync_or_and_fetch_1:
4455 case Builtin::BI__sync_or_and_fetch_2:
4456 case Builtin::BI__sync_or_and_fetch_4:
4457 case Builtin::BI__sync_or_and_fetch_8:
4458 case Builtin::BI__sync_or_and_fetch_16:
4462 case Builtin::BI__sync_xor_and_fetch:
4463 case Builtin::BI__sync_xor_and_fetch_1:
4464 case Builtin::BI__sync_xor_and_fetch_2:
4465 case Builtin::BI__sync_xor_and_fetch_4:
4466 case Builtin::BI__sync_xor_and_fetch_8:
4467 case Builtin::BI__sync_xor_and_fetch_16:
4471 case Builtin::BI__sync_nand_and_fetch:
4472 case Builtin::BI__sync_nand_and_fetch_1:
4473 case Builtin::BI__sync_nand_and_fetch_2:
4474 case Builtin::BI__sync_nand_and_fetch_4:
4475 case Builtin::BI__sync_nand_and_fetch_8:
4476 case Builtin::BI__sync_nand_and_fetch_16:
4478 WarnAboutSemanticsChange =
true;
4481 case Builtin::BI__sync_val_compare_and_swap:
4482 case Builtin::BI__sync_val_compare_and_swap_1:
4483 case Builtin::BI__sync_val_compare_and_swap_2:
4484 case Builtin::BI__sync_val_compare_and_swap_4:
4485 case Builtin::BI__sync_val_compare_and_swap_8:
4486 case Builtin::BI__sync_val_compare_and_swap_16:
4491 case Builtin::BI__sync_bool_compare_and_swap:
4492 case Builtin::BI__sync_bool_compare_and_swap_1:
4493 case Builtin::BI__sync_bool_compare_and_swap_2:
4494 case Builtin::BI__sync_bool_compare_and_swap_4:
4495 case Builtin::BI__sync_bool_compare_and_swap_8:
4496 case Builtin::BI__sync_bool_compare_and_swap_16:
4502 case Builtin::BI__sync_lock_test_and_set:
4503 case Builtin::BI__sync_lock_test_and_set_1:
4504 case Builtin::BI__sync_lock_test_and_set_2:
4505 case Builtin::BI__sync_lock_test_and_set_4:
4506 case Builtin::BI__sync_lock_test_and_set_8:
4507 case Builtin::BI__sync_lock_test_and_set_16:
4511 case Builtin::BI__sync_lock_release:
4512 case Builtin::BI__sync_lock_release_1:
4513 case Builtin::BI__sync_lock_release_2:
4514 case Builtin::BI__sync_lock_release_4:
4515 case Builtin::BI__sync_lock_release_8:
4516 case Builtin::BI__sync_lock_release_16:
4522 case Builtin::BI__sync_swap:
4523 case Builtin::BI__sync_swap_1:
4524 case Builtin::BI__sync_swap_2:
4525 case Builtin::BI__sync_swap_4:
4526 case Builtin::BI__sync_swap_8:
4527 case Builtin::BI__sync_swap_16:
4535 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4536 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
4537 <<
Callee->getSourceRange();
4541 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
4542 <<
Callee->getSourceRange();
4544 if (WarnAboutSemanticsChange) {
4545 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
4546 <<
Callee->getSourceRange();
4551 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
4554 if (NewBuiltinID == BuiltinID)
4555 NewBuiltinDecl = FDecl;
4561 assert(Res.getFoundDecl());
4562 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
4563 if (!NewBuiltinDecl)
4570 for (
unsigned i = 0; i != NumFixed; ++i) {
4601 CK_BuiltinFnToFnPtr);
4613 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
4614 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
4618 return TheCallResult;
4627 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
4628 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
4629 "Unexpected nontemporal load/store builtin!");
4630 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
4631 unsigned numArgs = isStore ? 2 : 1;
4641 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
4647 PointerArg = PointerArgResult.
get();
4648 TheCall->
setArg(numArgs - 1, PointerArg);
4652 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
4665 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
4672 return TheCallResult;
4684 return TheCallResult;
4691 auto *
Literal = dyn_cast<StringLiteral>(Arg);
4693 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
4694 Literal = ObjcLiteral->getString();
4698 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
4716 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
4717 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
4718 TT.getArch() == llvm::Triple::aarch64_32);
4719 bool IsWindows = TT.isOSWindows();
4720 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
4721 if (IsX64 || IsAArch64) {
4728 return S.
Diag(Fn->getBeginLoc(),
4729 diag::err_ms_va_start_used_in_sysv_function);
4737 return S.
Diag(Fn->getBeginLoc(),
4738 diag::err_va_start_used_in_wrong_abi_function)
4745 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
4753 bool IsVariadic =
false;
4756 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
4757 IsVariadic =
Block->isVariadic();
4758 Params =
Block->parameters();
4759 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
4762 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
4763 IsVariadic = MD->isVariadic();
4765 Params = MD->parameters();
4766 }
else if (isa<CapturedDecl>(Caller)) {
4768 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
4772 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
4777 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
4782 *LastParam = Params.empty() ? nullptr : Params.back();
4787bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
4812 bool SecondArgIsLastNamedArgument =
false;
4814 if (std::optional<llvm::APSInt> Val =
4823 bool IsCRegister =
false;
4825 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
4826 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
4827 SecondArgIsLastNamedArgument = PV == LastParam;
4829 Type = PV->getType();
4830 ParamLoc = PV->getLocation();
4836 if (!SecondArgIsLastNamedArgument)
4838 diag::warn_second_arg_of_va_start_not_last_named_param);
4843 if (!Context.isPromotableIntegerType(Type))
4845 if (!Type->isEnumeralType())
4847 const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();
4849 Context.typesAreCompatible(ED->getPromotionType(), Type));
4851 unsigned Reason = 0;
4853 else if (IsCRegister) Reason = 2;
4854 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
4855 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
4862 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
4882 if (
Call->getNumArgs() < 3)
4884 diag::err_typecheck_call_too_few_args_at_least)
4885 << 0 << 3 <<
Call->getNumArgs()
4898 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
4901 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
4906 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
4908 << Arg1->
getType() << ConstCharPtrTy << 1
4911 << 2 << Arg1->
getType() << ConstCharPtrTy;
4916 << Arg2->
getType() << SizeTy << 1
4919 << 3 << Arg2->
getType() << SizeTy;
4924bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
4928 if (BuiltinID == Builtin::BI__builtin_isunordered &&
4956 diag::err_typecheck_call_invalid_ordered_compare)
4964bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
4965 unsigned BuiltinID) {
4970 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
4971 BuiltinID == Builtin::BI__builtin_isinf ||
4972 BuiltinID == Builtin::BI__builtin_isinf_sign))
4976 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
4977 BuiltinID == Builtin::BI__builtin_isunordered))
4981 bool IsFPClass = NumArgs == 2;
4984 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
4988 for (
unsigned i = 0; i < FPArgNo; ++i) {
5015 OrigArg = Res.
get();
5021 OrigArg = Res.
get();
5023 TheCall->
setArg(FPArgNo, OrigArg);
5037 diag::err_typecheck_call_invalid_unary_fp)
5049 if (!VectorResultTy.
isNull())
5050 ResultTy = VectorResultTy;
5059bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5064 for (
unsigned I = 0; I != 2; ++I) {
5075 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5094 diag::err_typecheck_call_different_arg_types)
5118 diag::err_typecheck_call_too_few_args_at_least)
5126 unsigned numElements = 0;
5141 unsigned numResElements = TheCall->
getNumArgs() - 2;
5150 diag::err_vec_builtin_incompatible_vector)
5157 diag::err_vec_builtin_incompatible_vector)
5162 }
else if (numElements != numResElements) {
5169 for (
unsigned i = 2; i < TheCall->
getNumArgs(); i++) {
5174 std::optional<llvm::APSInt>
Result;
5177 diag::err_shufflevector_nonconstant_argument)
5184 if (
Result->getActiveBits() > 64 ||
5185 Result->getZExtValue() >= numElements * 2)
5187 diag::err_shufflevector_argument_too_large)
5193 for (
unsigned i = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5194 exprs.push_back(TheCall->
getArg(i));
5195 TheCall->
setArg(i,
nullptr);
5213 diag::err_convertvector_non_vector)
5216 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5218 <<
"__builtin_convertvector");
5223 if (SrcElts != DstElts)
5225 diag::err_convertvector_incompatible_vector)
5230 BuiltinLoc, RParenLoc);
5233bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5238 diag::err_typecheck_call_too_many_args_at_most)
5239 << 0 << 3 << NumArgs << 0
5244 for (
unsigned i = 1; i != NumArgs; ++i)
5251bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5253 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5263 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5273bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5280 << cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5285bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5291 if (
const auto *UE =
5293 if (UE->getKind() == UETT_AlignOf ||
5294 UE->getKind() == UETT_PreferredAlignOf)
5300 if (!
Result.isPowerOf2())
5301 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5308 if (
Result > std::numeric_limits<int32_t>::max())
5316bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5327 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
5331 TheCall->
setArg(0, FirstArgResult.
get());
5343 if (!
Result.isPowerOf2())
5344 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5356 TheCall->
setArg(2, ThirdArg);
5362bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5363 unsigned BuiltinID =
5364 cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5365 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5368 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5369 if (NumArgs < NumRequiredArgs) {
5370 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5371 << 0 << NumRequiredArgs << NumArgs
5374 if (NumArgs >= NumRequiredArgs + 0x100) {
5376 diag::err_typecheck_call_too_many_args_at_most)
5377 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5388 if (Arg.isInvalid())
5390 TheCall->
setArg(i, Arg.get());
5395 unsigned FormatIdx = i;
5405 unsigned FirstDataArg = i;
5406 while (i < NumArgs) {
5424 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5426 bool Success = CheckFormatArguments(
5450 std::optional<llvm::APSInt> R;
5452 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5459 int High,
bool RangeIsError) {
5473 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
5481 PDiag(diag::warn_argument_invalid_range)
5526 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5531 if (
Value.isNegative())
5542 if ((
Value & 0xFF) != 0)
5567 Result.setIsUnsigned(
true);
5572 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
5591 Result.setIsUnsigned(
true);
5599 diag::err_argument_not_shifted_byte_or_xxff)
5603bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
5605 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
5616 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
5622bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
5624 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
5629bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
5644 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5649 diag::err_builtin_counted_by_ref_has_side_effects)
5652 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
5653 if (!ME->isFlexibleArrayMemberLike(
5656 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5662 const auto *FAMDecl = cast<FieldDecl>(ME->getMemberDecl());
5670 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5680bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *
E,
5681 BuiltinCountedByRefKind K) {
5688 case AssignmentKind:
5689 case InitializerKind:
5691 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5694 case FunctionArgKind:
5696 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5701 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5704 case ArraySubscriptKind:
5708 case BinaryExprKind:
5719class UncoveredArgHandler {
5720 enum {
Unknown = -1, AllCovered = -2 };
5722 signed FirstUncoveredArg =
Unknown;
5726 UncoveredArgHandler() =
default;
5728 bool hasUncoveredArg()
const {
5729 return (FirstUncoveredArg >= 0);
5732 unsigned getUncoveredArg()
const {
5733 assert(hasUncoveredArg() &&
"no uncovered argument");
5734 return FirstUncoveredArg;
5737 void setAllCovered() {
5740 DiagnosticExprs.clear();
5741 FirstUncoveredArg = AllCovered;
5744 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
5745 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
5748 if (FirstUncoveredArg == AllCovered)
5753 if (NewFirstUncoveredArg == FirstUncoveredArg)
5754 DiagnosticExprs.push_back(StrExpr);
5755 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
5756 DiagnosticExprs.clear();
5757 DiagnosticExprs.push_back(StrExpr);
5758 FirstUncoveredArg = NewFirstUncoveredArg;
5762 void Diagnose(
Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
5765enum StringLiteralCheckType {
5767 SLCT_UncheckedLiteral,
5775 bool AddendIsRight) {
5776 unsigned BitWidth = Offset.getBitWidth();
5777 unsigned AddendBitWidth = Addend.getBitWidth();
5779 if (Addend.isUnsigned()) {
5780 Addend = Addend.zext(++AddendBitWidth);
5781 Addend.setIsSigned(
true);
5784 if (AddendBitWidth > BitWidth) {
5785 Offset = Offset.sext(AddendBitWidth);
5786 BitWidth = AddendBitWidth;
5787 }
else if (BitWidth > AddendBitWidth) {
5788 Addend = Addend.sext(BitWidth);
5792 llvm::APSInt ResOffset = Offset;
5793 if (BinOpKind == BO_Add)
5794 ResOffset = Offset.sadd_ov(Addend, Ov);
5796 assert(AddendIsRight && BinOpKind == BO_Sub &&
5797 "operator must be add or sub with addend on the right");
5798 ResOffset = Offset.ssub_ov(Addend, Ov);
5804 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
5805 "index (intermediate) result too big");
5806 Offset = Offset.sext(2 * BitWidth);
5807 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
5819class FormatStringLiteral {
5824 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
5825 : FExpr(fexpr), Offset(Offset) {}
5827 StringRef getString()
const {
5828 return FExpr->
getString().drop_front(Offset);
5831 unsigned getByteLength()
const {
5832 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
5835 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
5842 bool isAscii()
const {
return FExpr->
isOrdinary(); }
5843 bool isWide()
const {
return FExpr->
isWide(); }
5844 bool isUTF8()
const {
return FExpr->
isUTF8(); }
5845 bool isUTF16()
const {
return FExpr->
isUTF16(); }
5846 bool isUTF32()
const {
return FExpr->
isUTF32(); }
5847 bool isPascal()
const {
return FExpr->
isPascal(); }
5852 unsigned *StartTokenByteOffset =
nullptr)
const {
5854 StartToken, StartTokenByteOffset);
5867 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
5871 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
5872 bool IgnoreStringsWithoutSpecifiers);
5881static StringLiteralCheckType
5886 llvm::SmallBitVector &CheckedVarArgs,
5887 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
5888 bool IgnoreStringsWithoutSpecifiers =
false) {
5890 return SLCT_NotALiteral;
5892 assert(Offset.isSigned() &&
"invalid offset");
5895 return SLCT_NotALiteral;
5904 return SLCT_UncheckedLiteral;
5907 case Stmt::InitListExprClass:
5911 Type, CallType,
false,
5912 CheckedVarArgs, UncoveredArg, Offset,
5913 IgnoreStringsWithoutSpecifiers);
5915 return SLCT_NotALiteral;
5916 case Stmt::BinaryConditionalOperatorClass:
5917 case Stmt::ConditionalOperatorClass: {
5921 cast<AbstractConditionalOperator>(
E);
5926 bool CheckLeft =
true, CheckRight =
true;
5929 if (
C->getCond()->EvaluateAsBooleanCondition(
5941 StringLiteralCheckType Left;
5943 Left = SLCT_UncheckedLiteral;
5946 firstDataArg,
Type, CallType, InFunctionCall,
5947 CheckedVarArgs, UncoveredArg, Offset,
5948 IgnoreStringsWithoutSpecifiers);
5949 if (Left == SLCT_NotALiteral || !CheckRight) {
5955 S,
C->getFalseExpr(), Args, APK, format_idx, firstDataArg,
Type,
5956 CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5957 IgnoreStringsWithoutSpecifiers);
5959 return (CheckLeft && Left < Right) ? Left : Right;
5962 case Stmt::ImplicitCastExprClass:
5963 E = cast<ImplicitCastExpr>(
E)->getSubExpr();
5966 case Stmt::OpaqueValueExprClass:
5967 if (
const Expr *src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
5971 return SLCT_NotALiteral;
5973 case Stmt::PredefinedExprClass:
5977 return SLCT_UncheckedLiteral;
5979 case Stmt::DeclRefExprClass: {
5985 bool isConstant =
false;
5989 isConstant = AT->getElementType().isConstant(S.
Context);
5991 isConstant =
T.isConstant(S.
Context) &&
5996 isConstant =
T.isConstant(S.
Context);
6000 if (
const Expr *
Init = VD->getAnyInitializer()) {
6003 if (InitList->isStringLiteralInit())
6004 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6007 S,
Init, Args, APK, format_idx, firstDataArg,
Type, CallType,
6008 false, CheckedVarArgs, UncoveredArg, Offset);
6049 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6050 if (
const auto *
D = dyn_cast<Decl>(PV->getDeclContext())) {
6052 bool IsCXXMember =
false;
6053 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D))
6054 IsCXXMember = MD->isInstance();
6056 bool IsVariadic =
false;
6058 IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();
6059 else if (
const auto *BD = dyn_cast<BlockDecl>(
D))
6060 IsVariadic = BD->isVariadic();
6061 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D))
6062 IsVariadic = OMD->isVariadic();
6069 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx &&
6082 return SLCT_UncheckedLiteral;
6091 return SLCT_NotALiteral;
6094 case Stmt::CallExprClass:
6095 case Stmt::CXXMemberCallExprClass: {
6098 bool IsFirst =
true;
6099 StringLiteralCheckType CommonResult;
6100 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6101 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6103 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6104 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6105 IgnoreStringsWithoutSpecifiers);
6112 return CommonResult;
6114 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6116 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6117 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6120 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6121 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6122 IgnoreStringsWithoutSpecifiers);
6128 Type, CallType,
false,
6129 CheckedVarArgs, UncoveredArg, Offset,
6130 IgnoreStringsWithoutSpecifiers);
6131 return SLCT_NotALiteral;
6133 case Stmt::ObjCMessageExprClass: {
6134 const auto *ME = cast<ObjCMessageExpr>(
E);
6135 if (
const auto *MD = ME->getMethodDecl()) {
6136 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6145 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6147 MD->getSelector().isKeywordSelector(
6148 {
"localizedStringForKey",
"value",
"table"})) {
6149 IgnoreStringsWithoutSpecifiers =
true;
6152 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6154 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6155 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6156 IgnoreStringsWithoutSpecifiers);
6160 return SLCT_NotALiteral;
6162 case Stmt::ObjCStringLiteralClass:
6163 case Stmt::StringLiteralClass: {
6169 StrE = cast<StringLiteral>(
E);
6172 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6175 return SLCT_NotALiteral;
6177 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6179 InFunctionCall, CallType, CheckedVarArgs, UncoveredArg,
6180 IgnoreStringsWithoutSpecifiers);
6181 return SLCT_CheckedLiteral;
6184 return SLCT_NotALiteral;
6186 case Stmt::BinaryOperatorClass: {
6200 if (LIsInt != RIsInt) {
6204 if (BinOpKind == BO_Add) {
6217 return SLCT_NotALiteral;
6219 case Stmt::UnaryOperatorClass: {
6221 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6222 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6224 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6234 return SLCT_NotALiteral;
6238 return SLCT_NotALiteral;
6249 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6250 if (isa_and_nonnull<StringLiteral>(LVE))
6257 return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
6259 .Cases(
"printf",
"printf0",
"syslog",
FST_Printf)
6263 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
FST_Kprintf)
6270bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6274 llvm::SmallBitVector &CheckedVarArgs) {
6275 FormatStringInfo FSI;
6278 return CheckFormatArguments(Args, FSI.ArgPassingKind, FSI.FormatIdx,
6280 CallType,
Loc,
Range, CheckedVarArgs);
6286 unsigned format_idx,
unsigned firstDataArg,
6287 FormatStringType
Type,
6290 llvm::SmallBitVector &CheckedVarArgs) {
6292 if (format_idx >= Args.size()) {
6297 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6311 UncoveredArgHandler UncoveredArg;
6313 *
this, OrigFormatExpr, Args, APK, format_idx, firstDataArg,
Type,
6315 true, CheckedVarArgs, UncoveredArg,
6316 llvm::APSInt(64,
false) = 0);
6319 if (UncoveredArg.hasUncoveredArg()) {
6320 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6321 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6322 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6325 if (CT != SLCT_NotALiteral)
6327 return CT == SLCT_CheckedLiteral;
6344 if (Args.size() == firstDataArg) {
6345 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6354 Diag(FormatLoc, diag::note_format_security_fixit)
6358 Diag(FormatLoc, diag::note_format_security_fixit)
6363 Diag(FormatLoc, diag::warn_format_nonliteral)
6374 const FormatStringLiteral *FExpr;
6375 const Expr *OrigFormatExpr;
6377 const unsigned FirstDataArg;
6378 const unsigned NumDataArgs;
6383 llvm::SmallBitVector CoveredArgs;
6384 bool usesPositionalArgs =
false;
6385 bool atFirstArg =
true;
6386 bool inFunctionCall;
6388 llvm::SmallBitVector &CheckedVarArgs;
6389 UncoveredArgHandler &UncoveredArg;
6392 CheckFormatHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6393 const Expr *origFormatExpr,
6395 unsigned numDataArgs,
const char *beg,
6399 llvm::SmallBitVector &CheckedVarArgs,
6400 UncoveredArgHandler &UncoveredArg)
6401 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6402 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6403 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6404 inFunctionCall(inFunctionCall), CallType(callType),
6405 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6406 CoveredArgs.resize(numDataArgs);
6407 CoveredArgs.reset();
6410 void DoneProcessing();
6412 void HandleIncompleteSpecifier(
const char *startSpecifier,
6413 unsigned specifierLen)
override;
6415 void HandleInvalidLengthModifier(
6418 const char *startSpecifier,
unsigned specifierLen,
6421 void HandleNonStandardLengthModifier(
6423 const char *startSpecifier,
unsigned specifierLen);
6425 void HandleNonStandardConversionSpecifier(
6427 const char *startSpecifier,
unsigned specifierLen);
6429 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
6431 void HandleInvalidPosition(
const char *startSpecifier,
6432 unsigned specifierLen,
6435 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
6437 void HandleNullChar(
const char *nullCharacter)
override;
6439 template <
typename Range>
6441 EmitFormatDiagnostic(
Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
6443 bool IsStringLocation,
Range StringRange,
6448 const char *startSpec,
6449 unsigned specifierLen,
6450 const char *csStart,
unsigned csLen);
6453 const char *startSpec,
6454 unsigned specifierLen);
6458 unsigned specifierLen);
6461 const Expr *getDataArg(
unsigned i)
const;
6465 const char *startSpecifier,
unsigned specifierLen,
6468 template <
typename Range>
6470 bool IsStringLocation,
Range StringRange,
6476SourceRange CheckFormatHandler::getFormatStringRange() {
6481getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
6483 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
6486 End = End.getLocWithOffset(1);
6491SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
6496void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
6497 unsigned specifierLen){
6498 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
6499 getLocationOfByte(startSpecifier),
6501 getSpecifierRange(startSpecifier, specifierLen));
6504void CheckFormatHandler::HandleInvalidLengthModifier(
6507 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
6508 using namespace analyze_format_string;
6510 const LengthModifier &LM = FS.getLengthModifier();
6511 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6514 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6516 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6517 getLocationOfByte(LM.getStart()),
6519 getSpecifierRange(startSpecifier, specifierLen));
6521 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6522 << FixedLM->toString()
6527 if (DiagID == diag::warn_format_nonsensical_length)
6530 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6531 getLocationOfByte(LM.getStart()),
6533 getSpecifierRange(startSpecifier, specifierLen),
6538void CheckFormatHandler::HandleNonStandardLengthModifier(
6540 const char *startSpecifier,
unsigned specifierLen) {
6541 using namespace analyze_format_string;
6543 const LengthModifier &LM = FS.getLengthModifier();
6544 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6547 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6549 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6550 << LM.toString() << 0,
6551 getLocationOfByte(LM.getStart()),
6553 getSpecifierRange(startSpecifier, specifierLen));
6555 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6556 << FixedLM->toString()
6560 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6561 << LM.toString() << 0,
6562 getLocationOfByte(LM.getStart()),
6564 getSpecifierRange(startSpecifier, specifierLen));
6568void CheckFormatHandler::HandleNonStandardConversionSpecifier(
6570 const char *startSpecifier,
unsigned specifierLen) {
6571 using namespace analyze_format_string;
6576 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6580 getSpecifierRange(startSpecifier, specifierLen));
6583 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
6584 << FixedCS->toString()
6587 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6591 getSpecifierRange(startSpecifier, specifierLen));
6595void CheckFormatHandler::HandlePosition(
const char *startPos,
6598 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
6599 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
6600 getLocationOfByte(startPos),
6602 getSpecifierRange(startPos, posLen));
6605void CheckFormatHandler::HandleInvalidPosition(
6606 const char *startSpecifier,
unsigned specifierLen,
6609 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
6610 EmitFormatDiagnostic(
6611 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
6612 getLocationOfByte(startSpecifier),
true,
6613 getSpecifierRange(startSpecifier, specifierLen));
6616void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
6620 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
6621 getLocationOfByte(startPos),
6623 getSpecifierRange(startPos, posLen));
6626void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
6627 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {
6629 EmitFormatDiagnostic(
6630 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
6631 getLocationOfByte(nullCharacter),
true,
6632 getFormatStringRange());
6638const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
6639 return Args[FirstDataArg + i];
6642void CheckFormatHandler::DoneProcessing() {
6648 signed notCoveredArg = CoveredArgs.find_first();
6649 if (notCoveredArg >= 0) {
6650 assert((
unsigned)notCoveredArg < NumDataArgs);
6651 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
6653 UncoveredArg.setAllCovered();
6658void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
6659 const Expr *ArgExpr) {
6660 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
6672 for (
auto E : DiagnosticExprs)
6675 CheckFormatHandler::EmitFormatDiagnostic(
6676 S, IsFunctionCall, DiagnosticExprs[0],
6682CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
6684 const char *startSpec,
6685 unsigned specifierLen,
6686 const char *csStart,
6688 bool keepGoing =
true;
6689 if (argIndex < NumDataArgs) {
6692 CoveredArgs.set(argIndex);
6708 std::string CodePointStr;
6709 if (!llvm::sys::locale::isPrint(*csStart)) {
6710 llvm::UTF32 CodePoint;
6711 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
6712 const llvm::UTF8 *
E =
6713 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
6714 llvm::ConversionResult
Result =
6715 llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
6717 if (
Result != llvm::conversionOK) {
6718 unsigned char FirstChar = *csStart;
6719 CodePoint = (llvm::UTF32)FirstChar;
6722 llvm::raw_string_ostream OS(CodePointStr);
6723 if (CodePoint < 256)
6724 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
6725 else if (CodePoint <= 0xFFFF)
6726 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
6728 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
6732 EmitFormatDiagnostic(
6733 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier,
Loc,
6734 true, getSpecifierRange(startSpec, specifierLen));
6741 const char *startSpec,
6742 unsigned specifierLen) {
6743 EmitFormatDiagnostic(
6744 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
6745 Loc,
true, getSpecifierRange(startSpec, specifierLen));
6749CheckFormatHandler::CheckNumArgs(
6752 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
6754 if (argIndex >= NumDataArgs) {
6756 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
6757 << (argIndex+1) << NumDataArgs)
6758 : S.
PDiag(diag::warn_printf_insufficient_data_args);
6759 EmitFormatDiagnostic(
6760 PDiag, getLocationOfByte(CS.
getStart()),
true,
6761 getSpecifierRange(startSpecifier, specifierLen));
6765 UncoveredArg.setAllCovered();
6771template<
typename Range>
6774 bool IsStringLocation,
6777 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
6778 Loc, IsStringLocation, StringRange, FixIt);
6808template <
typename Range>
6809void CheckFormatHandler::EmitFormatDiagnostic(
6810 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
6813 if (InFunctionCall) {
6822 S.
Diag(IsStringLocation ?
Loc : StringRange.getBegin(),
6823 diag::note_format_string_defined);
6825 Note << StringRange;
6834class CheckPrintfHandler :
public CheckFormatHandler {
6836 CheckPrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6837 const Expr *origFormatExpr,
6839 unsigned numDataArgs,
bool isObjC,
const char *beg,
6843 llvm::SmallBitVector &CheckedVarArgs,
6844 UncoveredArgHandler &UncoveredArg)
6845 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
6846 numDataArgs, beg, APK, Args, formatIdx,
6847 inFunctionCall, CallType, CheckedVarArgs,
6853 bool allowsObjCArg()
const {
6858 bool HandleInvalidPrintfConversionSpecifier(
6860 const char *startSpecifier,
6861 unsigned specifierLen)
override;
6863 void handleInvalidMaskType(StringRef MaskType)
override;
6866 const char *startSpecifier,
unsigned specifierLen,
6869 const char *StartSpecifier,
6870 unsigned SpecifierLen,
6874 const char *startSpecifier,
unsigned specifierLen);
6878 const char *startSpecifier,
unsigned specifierLen);
6881 const char *startSpecifier,
unsigned specifierLen);
6885 const char *startSpecifier,
unsigned specifierLen);
6889 void HandleEmptyObjCModifierFlag(
const char *startFlag,
6890 unsigned flagLen)
override;
6892 void HandleInvalidObjCModifierFlag(
const char *startFlag,
6893 unsigned flagLen)
override;
6895 void HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
6896 const char *flagsEnd,
6897 const char *conversionPosition)
6903bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
6905 const char *startSpecifier,
6906 unsigned specifierLen) {
6908 FS.getConversionSpecifier();
6910 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
6912 startSpecifier, specifierLen,
6916void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
6917 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
6920bool CheckPrintfHandler::HandleAmount(
6922 const char *startSpecifier,
unsigned specifierLen) {
6926 if (argIndex >= NumDataArgs) {
6927 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
6931 getSpecifierRange(startSpecifier, specifierLen));
6941 CoveredArgs.set(argIndex);
6942 const Expr *Arg = getDataArg(argIndex);
6952 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
6957 getSpecifierRange(startSpecifier, specifierLen));
6967void CheckPrintfHandler::HandleInvalidAmount(
6971 const char *startSpecifier,
6972 unsigned specifierLen) {
6974 FS.getConversionSpecifier();
6982 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
6986 getSpecifierRange(startSpecifier, specifierLen),
6992 const char *startSpecifier,
6993 unsigned specifierLen) {
6996 FS.getConversionSpecifier();
6997 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7001 getSpecifierRange(startSpecifier, specifierLen),
7006void CheckPrintfHandler::HandleIgnoredFlag(
7010 const char *startSpecifier,
7011 unsigned specifierLen) {
7013 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7017 getSpecifierRange(startSpecifier, specifierLen),
7019 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7022void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7025 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7026 getLocationOfByte(startFlag),
7028 getSpecifierRange(startFlag, flagLen));
7031void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7034 auto Range = getSpecifierRange(startFlag, flagLen);
7035 StringRef flag(startFlag, flagLen);
7036 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7037 getLocationOfByte(startFlag),
7042void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7043 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7045 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7046 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7047 EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
7048 getLocationOfByte(conversionPosition),
7056template<
typename MemberKind>
7077 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
7091 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
7092 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7094 if ((*MI)->getMinRequiredArguments() == 0)
7102bool CheckPrintfHandler::checkForCStrMembers(
7107 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
7109 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7125bool CheckPrintfHandler::HandlePrintfSpecifier(
7128 using namespace analyze_format_string;
7129 using namespace analyze_printf;
7131 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
7133 if (FS.consumesDataArgument()) {
7136 usesPositionalArgs = FS.usesPositionalArg();
7138 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7139 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7140 startSpecifier, specifierLen);
7147 if (!HandleAmount(FS.getFieldWidth(), 0,
7148 startSpecifier, specifierLen)) {
7152 if (!HandleAmount(FS.getPrecision(), 1,
7153 startSpecifier, specifierLen)) {
7157 if (!CS.consumesDataArgument()) {
7164 unsigned argIndex = FS.getArgIndex();
7165 if (argIndex < NumDataArgs) {
7169 CoveredArgs.set(argIndex);
7173 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
7174 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
7176 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
7180 CoveredArgs.set(argIndex + 1);
7183 const Expr *Ex = getDataArg(argIndex);
7185 (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
7188 EmitFormatDiagnostic(
7189 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7193 getSpecifierRange(startSpecifier, specifierLen));
7196 Ex = getDataArg(argIndex + 1);
7199 EmitFormatDiagnostic(
7200 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7204 getSpecifierRange(startSpecifier, specifierLen));
7211 if (!allowsObjCArg() && CS.isObjCArg()) {
7212 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7217 if (FSType !=
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::PArg) {
7218 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7223 if (FSType ==
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::nArg) {
7224 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
7225 getLocationOfByte(CS.getStart()),
7227 getSpecifierRange(startSpecifier, specifierLen));
7234 (CS.getKind() == ConversionSpecifier::PArg ||
7235 CS.getKind() == ConversionSpecifier::sArg ||
7236 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
7237 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7243 if (FS.isPublic().isSet()) {
7244 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7246 getLocationOfByte(FS.isPublic().getPosition()),
7248 getSpecifierRange(startSpecifier, specifierLen));
7250 if (FS.isPrivate().isSet()) {
7251 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7253 getLocationOfByte(FS.isPrivate().getPosition()),
7255 getSpecifierRange(startSpecifier, specifierLen));
7259 const llvm::Triple &Triple =
Target.getTriple();
7260 if (CS.getKind() == ConversionSpecifier::nArg &&
7261 (Triple.isAndroid() || Triple.isOSFuchsia())) {
7262 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
7263 getLocationOfByte(CS.getStart()),
7265 getSpecifierRange(startSpecifier, specifierLen));
7269 if (!FS.hasValidFieldWidth()) {
7270 HandleInvalidAmount(FS, FS.getFieldWidth(), 0,
7271 startSpecifier, specifierLen);
7275 if (!FS.hasValidPrecision()) {
7276 HandleInvalidAmount(FS, FS.getPrecision(), 1,
7277 startSpecifier, specifierLen);
7281 if (CS.getKind() == ConversionSpecifier::PArg &&
7282 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
7283 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
7284 getLocationOfByte(startSpecifier),
7286 getSpecifierRange(startSpecifier, specifierLen));
7290 if (!FS.hasValidThousandsGroupingPrefix())
7291 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
7292 if (!FS.hasValidLeadingZeros())
7293 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
7294 if (!FS.hasValidPlusPrefix())
7295 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
7296 if (!FS.hasValidSpacePrefix())
7297 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
7298 if (!FS.hasValidAlternativeForm())
7299 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
7300 if (!FS.hasValidLeftJustified())
7301 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
7304 if (FS.hasSpacePrefix() && FS.hasPlusPrefix())
7305 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
7306 startSpecifier, specifierLen);
7307 if (FS.hasLeadingZeros() && FS.isLeftJustified())
7308 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
7309 startSpecifier, specifierLen);
7314 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7315 diag::warn_format_nonsensical_length);
7316 else if (!FS.hasStandardLengthModifier())
7317 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7318 else if (!FS.hasStandardLengthConversionCombination())
7319 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7320 diag::warn_format_non_standard_conversion_spec);
7322 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7323 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7329 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7332 const Expr *Arg = getDataArg(argIndex);
7336 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
7348 case Stmt::ArraySubscriptExprClass:
7349 case Stmt::CallExprClass:
7350 case Stmt::CharacterLiteralClass:
7351 case Stmt::CXXBoolLiteralExprClass:
7352 case Stmt::DeclRefExprClass:
7353 case Stmt::FloatingLiteralClass:
7354 case Stmt::IntegerLiteralClass:
7355 case Stmt::MemberExprClass:
7356 case Stmt::ObjCArrayLiteralClass:
7357 case Stmt::ObjCBoolLiteralExprClass:
7358 case Stmt::ObjCBoxedExprClass:
7359 case Stmt::ObjCDictionaryLiteralClass:
7360 case Stmt::ObjCEncodeExprClass:
7361 case Stmt::ObjCIvarRefExprClass:
7362 case Stmt::ObjCMessageExprClass:
7363 case Stmt::ObjCPropertyRefExprClass:
7364 case Stmt::ObjCStringLiteralClass:
7365 case Stmt::ObjCSubscriptRefExprClass:
7366 case Stmt::ParenExprClass:
7367 case Stmt::StringLiteralClass:
7368 case Stmt::UnaryOperatorClass:
7375static std::pair<QualType, StringRef>
7382 StringRef Name = UserTy->getDecl()->getName();
7383 QualType CastTy = llvm::StringSwitch<QualType>(Name)
7387 .Case(
"SInt32", Context.
IntTy)
7392 return std::make_pair(CastTy, Name);
7394 TyTy = UserTy->desugar();
7398 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(
E))
7400 PE->getSubExpr()->getType(),
7409 StringRef TrueName, FalseName;
7411 std::tie(TrueTy, TrueName) =
7413 CO->getTrueExpr()->getType(),
7415 std::tie(FalseTy, FalseName) =
7417 CO->getFalseExpr()->getType(),
7418 CO->getFalseExpr());
7420 if (TrueTy == FalseTy)
7421 return std::make_pair(TrueTy, TrueName);
7422 else if (TrueTy.
isNull())
7423 return std::make_pair(FalseTy, FalseName);
7424 else if (FalseTy.
isNull())
7425 return std::make_pair(TrueTy, TrueName);
7428 return std::make_pair(
QualType(), StringRef());
7447 From = VecTy->getElementType();
7449 To = VecTy->getElementType();
7461 diag::warn_format_conversion_argument_type_mismatch_signedness,
Loc)
7470 const char *StartSpecifier,
7471 unsigned SpecifierLen,
7473 using namespace analyze_format_string;
7474 using namespace analyze_printf;
7483 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
7484 ExprTy = TET->getUnderlyingExpr()->getType();
7496 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
7499 getSpecifierRange(StartSpecifier, SpecifierLen);
7501 llvm::raw_svector_ostream os(FSString);
7503 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
7511 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
7514 getSpecifierRange(StartSpecifier, SpecifierLen);
7515 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
7520 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
7522 ArgType::MatchKind OrigMatch = Match;
7525 if (Match == ArgType::Match)
7529 assert(Match != ArgType::NoMatchPromotionTypeConfusion);
7538 E = ICE->getSubExpr();
7548 if (OrigMatch == ArgType::NoMatchSignedness &&
7549 ImplicitMatch != ArgType::NoMatchSignedness)
7556 if (ImplicitMatch == ArgType::Match)
7567 FS.getLengthModifier().getKind() != LengthModifier::AsChar)
7574 if (Match == ArgType::MatchPromotion)
7575 Match = ArgType::NoMatch;
7578 if (Match == ArgType::MatchPromotion) {
7582 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
7583 ImplicitMatch != ArgType::NoMatchTypeConfusion)
7585 Match = ArgType::NoMatch;
7587 if (ImplicitMatch == ArgType::NoMatchPedantic ||
7588 ImplicitMatch == ArgType::NoMatchTypeConfusion)
7589 Match = ImplicitMatch;
7590 assert(Match != ArgType::MatchPromotion);
7593 bool IsEnum =
false;
7594 bool IsScopedEnum =
false;
7597 IntendedTy = EnumTy->getDecl()->getIntegerType();
7598 if (EnumTy->isUnscopedEnumerationType()) {
7599 ExprTy = IntendedTy;
7604 IsScopedEnum =
true;
7611 if (isObjCContext() &&
7612 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
7622 const llvm::APInt &
V = IL->getValue();
7632 if (TD->getUnderlyingType() == IntendedTy)
7640 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
7648 if (!IsScopedEnum &&
7649 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
7652 Match = ArgType::NoMatchPedantic;
7653 IntendedTy = CastTy;
7654 ShouldNotPrintDirectly =
true;
7659 PrintfSpecifier fixedFS = FS;
7666 llvm::raw_svector_ostream os(buf);
7667 fixedFS.toString(os);
7669 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
7671 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
7674 case ArgType::Match:
7675 case ArgType::MatchPromotion:
7676 case ArgType::NoMatchPromotionTypeConfusion:
7677 case ArgType::NoMatchSignedness:
7678 llvm_unreachable(
"expected non-matching");
7679 case ArgType::NoMatchPedantic:
7680 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7682 case ArgType::NoMatchTypeConfusion:
7683 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7685 case ArgType::NoMatch:
7686 Diag = diag::warn_format_conversion_argument_type_mismatch;
7707 llvm::raw_svector_ostream CastFix(CastBuf);
7708 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
7710 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
7716 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
7721 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
7743 if (ShouldNotPrintDirectly && !IsScopedEnum) {
7749 Name = TypedefTy->getDecl()->getName();
7752 unsigned Diag = Match == ArgType::NoMatchPedantic
7753 ? diag::warn_format_argument_needs_cast_pedantic
7754 : diag::warn_format_argument_needs_cast;
7755 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
7766 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
7767 : diag::warn_format_conversion_argument_type_mismatch;
7769 EmitFormatDiagnostic(
7781 bool EmitTypeMismatch =
false;
7787 case ArgType::Match:
7788 case ArgType::MatchPromotion:
7789 case ArgType::NoMatchPromotionTypeConfusion:
7790 case ArgType::NoMatchSignedness:
7791 llvm_unreachable(
"expected non-matching");
7792 case ArgType::NoMatchPedantic:
7793 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7795 case ArgType::NoMatchTypeConfusion:
7796 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7798 case ArgType::NoMatch:
7799 Diag = diag::warn_format_conversion_argument_type_mismatch;
7803 EmitFormatDiagnostic(
7812 EmitTypeMismatch =
true;
7814 EmitFormatDiagnostic(
7815 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
7816 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7820 checkForCStrMembers(AT,
E);
7826 EmitTypeMismatch =
true;
7828 EmitFormatDiagnostic(
7829 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
7830 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7838 << isa<InitListExpr>(
E) << ExprTy << CallType
7843 if (EmitTypeMismatch) {
7849 EmitFormatDiagnostic(
7850 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7856 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
7857 "format string specifier index out of range");
7858 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
7868class CheckScanfHandler :
public CheckFormatHandler {
7870 CheckScanfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7872 unsigned firstDataArg,
unsigned numDataArgs,
7876 llvm::SmallBitVector &CheckedVarArgs,
7877 UncoveredArgHandler &UncoveredArg)
7878 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7879 numDataArgs, beg, APK, Args, formatIdx,
7880 inFunctionCall, CallType, CheckedVarArgs,
7884 const char *startSpecifier,
7885 unsigned specifierLen)
override;
7887 bool HandleInvalidScanfConversionSpecifier(
7889 const char *startSpecifier,
7890 unsigned specifierLen)
override;
7892 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
7897void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
7899 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
7900 getLocationOfByte(end),
true,
7901 getSpecifierRange(start, end - start));
7904bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
7906 const char *startSpecifier,
7907 unsigned specifierLen) {
7909 FS.getConversionSpecifier();
7911 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
7913 startSpecifier, specifierLen,
7917bool CheckScanfHandler::HandleScanfSpecifier(
7919 const char *startSpecifier,
7920 unsigned specifierLen) {
7921 using namespace analyze_scanf;
7922 using namespace analyze_format_string;
7924 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
7928 if (FS.consumesDataArgument()) {
7931 usesPositionalArgs = FS.usesPositionalArg();
7933 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7934 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7935 startSpecifier, specifierLen);
7941 const OptionalAmount &Amt = FS.getFieldWidth();
7942 if (Amt.getHowSpecified() == OptionalAmount::Constant) {
7943 if (Amt.getConstantAmount() == 0) {
7945 Amt.getConstantLength());
7946 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
7947 getLocationOfByte(Amt.getStart()),
7953 if (!FS.consumesDataArgument()) {
7960 unsigned argIndex = FS.getArgIndex();
7961 if (argIndex < NumDataArgs) {
7965 CoveredArgs.set(argIndex);
7971 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7972 diag::warn_format_nonsensical_length);
7973 else if (!FS.hasStandardLengthModifier())
7974 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7975 else if (!FS.hasStandardLengthConversionCombination())
7976 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7977 diag::warn_format_non_standard_conversion_spec);
7979 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7980 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7986 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7990 const Expr *Ex = getDataArg(argIndex);
8007 ScanfSpecifier fixedFS = FS;
8012 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8013 : diag::warn_format_conversion_argument_type_mismatch;
8018 llvm::raw_svector_ostream os(buf);
8019 fixedFS.toString(os);
8021 EmitFormatDiagnostic(
8026 getSpecifierRange(startSpecifier, specifierLen),
8028 getSpecifierRange(startSpecifier, specifierLen), os.str()));
8035 getSpecifierRange(startSpecifier, specifierLen));
8042 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
8046 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
8047 bool IgnoreStringsWithoutSpecifiers) {
8049 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
8050 CheckFormatHandler::EmitFormatDiagnostic(
8051 S, inFunctionCall, Args[format_idx],
8052 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
8058 StringRef StrRef = FExpr->getString();
8059 const char *Str = StrRef.data();
8063 assert(
T &&
"String literal not of constant array type!");
8064 size_t TypeSize =
T->getZExtSize();
8065 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8066 const unsigned numDataArgs = Args.size() - firstDataArg;
8068 if (IgnoreStringsWithoutSpecifiers &&
8075 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
8076 CheckFormatHandler::EmitFormatDiagnostic(
8077 S, inFunctionCall, Args[format_idx],
8078 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
8079 FExpr->getBeginLoc(),
8085 if (StrLen == 0 && numDataArgs > 0) {
8086 CheckFormatHandler::EmitFormatDiagnostic(
8087 S, inFunctionCall, Args[format_idx],
8088 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
8097 CheckPrintfHandler H(
8098 S, FExpr, OrigFormatExpr,
Type, firstDataArg, numDataArgs,
8100 Args, format_idx, inFunctionCall, CallType, CheckedVarArgs,
8108 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
8109 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
8110 CallType, CheckedVarArgs, UncoveredArg);
8121 const char *Str = StrRef.data();
8124 assert(
T &&
"String literal not of constant array type!");
8125 size_t TypeSize =
T->getZExtSize();
8126 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8137 switch (AbsFunction) {
8141 case Builtin::BI__builtin_abs:
8142 return Builtin::BI__builtin_labs;
8143 case Builtin::BI__builtin_labs:
8144 return Builtin::BI__builtin_llabs;
8145 case Builtin::BI__builtin_llabs:
8148 case Builtin::BI__builtin_fabsf:
8149 return Builtin::BI__builtin_fabs;
8150 case Builtin::BI__builtin_fabs:
8151 return Builtin::BI__builtin_fabsl;
8152 case Builtin::BI__builtin_fabsl:
8155 case Builtin::BI__builtin_cabsf:
8156 return Builtin::BI__builtin_cabs;
8157 case Builtin::BI__builtin_cabs:
8158 return Builtin::BI__builtin_cabsl;
8159 case Builtin::BI__builtin_cabsl:
8162 case Builtin::BIabs:
8163 return Builtin::BIlabs;
8164 case Builtin::BIlabs:
8165 return Builtin::BIllabs;
8166 case Builtin::BIllabs:
8169 case Builtin::BIfabsf:
8170 return Builtin::BIfabs;
8171 case Builtin::BIfabs:
8172 return Builtin::BIfabsl;
8173 case Builtin::BIfabsl:
8176 case Builtin::BIcabsf:
8177 return Builtin::BIcabs;
8178 case Builtin::BIcabs:
8179 return Builtin::BIcabsl;
8180 case Builtin::BIcabsl:
8209 unsigned AbsFunctionKind) {
8210 unsigned BestKind = 0;
8212 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
8218 else if (Context.
hasSameType(ParamType, ArgType)) {
8241 llvm_unreachable(
"Type not integer, floating, or complex");
8248 switch (ValueKind) {
8253 case Builtin::BI__builtin_fabsf:
8254 case Builtin::BI__builtin_fabs:
8255 case Builtin::BI__builtin_fabsl:
8256 case Builtin::BI__builtin_cabsf:
8257 case Builtin::BI__builtin_cabs:
8258 case Builtin::BI__builtin_cabsl:
8259 return Builtin::BI__builtin_abs;
8260 case Builtin::BIfabsf:
8261 case Builtin::BIfabs:
8262 case Builtin::BIfabsl:
8263 case Builtin::BIcabsf:
8264 case Builtin::BIcabs:
8265 case Builtin::BIcabsl:
8266 return Builtin::BIabs;
8272 case Builtin::BI__builtin_abs:
8273 case Builtin::BI__builtin_labs:
8274 case Builtin::BI__builtin_llabs:
8275 case Builtin::BI__builtin_cabsf:
8276 case Builtin::BI__builtin_cabs:
8277 case Builtin::BI__builtin_cabsl:
8278 return Builtin::BI__builtin_fabsf;
8279 case Builtin::BIabs:
8280 case Builtin::BIlabs:
8281 case Builtin::BIllabs:
8282 case Builtin::BIcabsf:
8283 case Builtin::BIcabs:
8284 case Builtin::BIcabsl:
8285 return Builtin::BIfabsf;
8291 case Builtin::BI__builtin_abs:
8292 case Builtin::BI__builtin_labs:
8293 case Builtin::BI__builtin_llabs:
8294 case Builtin::BI__builtin_fabsf:
8295 case Builtin::BI__builtin_fabs:
8296 case Builtin::BI__builtin_fabsl:
8297 return Builtin::BI__builtin_cabsf;
8298 case Builtin::BIabs:
8299 case Builtin::BIlabs:
8300 case Builtin::BIllabs:
8301 case Builtin::BIfabsf:
8302 case Builtin::BIfabs:
8303 case Builtin::BIfabsl:
8304 return Builtin::BIcabsf;
8307 llvm_unreachable(
"Unable to convert function");
8318 case Builtin::BI__builtin_abs:
8319 case Builtin::BI__builtin_fabs:
8320 case Builtin::BI__builtin_fabsf:
8321 case Builtin::BI__builtin_fabsl:
8322 case Builtin::BI__builtin_labs:
8323 case Builtin::BI__builtin_llabs:
8324 case Builtin::BI__builtin_cabs:
8325 case Builtin::BI__builtin_cabsf:
8326 case Builtin::BI__builtin_cabsl:
8327 case Builtin::BIabs:
8328 case Builtin::BIlabs:
8329 case Builtin::BIllabs:
8330 case Builtin::BIfabs:
8331 case Builtin::BIfabsf:
8332 case Builtin::BIfabsl:
8333 case Builtin::BIcabs:
8334 case Builtin::BIcabsf:
8335 case Builtin::BIcabsl:
8338 llvm_unreachable(
"Unknown Builtin type");
8344 unsigned AbsKind,
QualType ArgType) {
8345 bool EmitHeaderHint =
true;
8346 const char *HeaderName =
nullptr;
8347 StringRef FunctionName;
8349 FunctionName =
"std::abs";
8351 HeaderName =
"cstdlib";
8353 HeaderName =
"cmath";
8355 llvm_unreachable(
"Invalid Type");
8364 for (
const auto *I : R) {
8367 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
8369 FDecl = dyn_cast<FunctionDecl>(I);
8384 EmitHeaderHint =
false;
8402 EmitHeaderHint =
false;
8406 }
else if (!R.
empty()) {
8412 S.
Diag(
Loc, diag::note_replace_abs_function)
8418 if (!EmitHeaderHint)
8421 S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
8425template <std::
size_t StrLen>
8427 const char (&Str)[StrLen]) {
8440 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
8441 return std::any_of(names.begin(), names.end(), [&](llvm::StringRef name) {
8442 return calleeName == name;
8447 case MathCheck::NaN:
8448 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
8449 "__builtin_nanf16",
"__builtin_nanf128"});
8450 case MathCheck::Inf:
8451 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
8452 "__builtin_inff16",
"__builtin_inff128"});
8454 llvm_unreachable(
"unknown MathCheck");
8458 if (FDecl->
getName() !=
"infinity")
8461 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
8463 if (RDecl->
getName() !=
"numeric_limits")
8480 if (FPO.getNoHonorNaNs() &&
8483 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8484 << 1 << 0 <<
Call->getSourceRange();
8488 if (FPO.getNoHonorInfs() &&
8492 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8493 << 0 << 0 <<
Call->getSourceRange();
8497void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
8499 if (
Call->getNumArgs() != 1)
8504 if (AbsKind == 0 && !IsStdAbs)
8507 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8513 StringRef FunctionName =
8515 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
8516 Diag(
Call->getExprLoc(), diag::note_remove_abs)
8525 unsigned DiagType = 0;
8531 Diag(
Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
8545 if (ArgValueKind == ParamValueKind) {
8550 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
8551 << FDecl << ArgType << ParamType;
8553 if (NewAbsKind == 0)
8557 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8566 if (NewAbsKind == 0)
8569 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
8570 << FDecl << ParamValueKind << ArgValueKind;
8573 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8579 if (!
Call || !FDecl)
return;
8583 if (
Call->getExprLoc().isMacroID())
return;
8586 if (
Call->getNumArgs() != 2)
return;
8589 if (!ArgList)
return;
8590 if (ArgList->size() != 1)
return;
8593 const auto& TA = ArgList->
get(0);
8599 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
8600 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
8601 if (!MTE)
return false;
8602 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
8603 if (!
Num)
return false;
8604 if (
Num->getValue() != 0)
return false;
8608 const Expr *FirstArg =
Call->getArg(0);
8609 const Expr *SecondArg =
Call->getArg(1);
8610 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
8611 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
8614 if (IsFirstArgZero == IsSecondArgZero)
return;
8619 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
8621 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
8622 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
8626 if (IsFirstArgZero) {
8634 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
8654 if (!Size->isComparisonOp() && !Size->isLogicalOp())
8658 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
8659 << SizeRange << FnName;
8660 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
8665 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
8676 bool &IsContained) {
8679 IsContained =
false;
8692 for (
auto *FD : RD->
fields()) {
8705 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
8706 if (Unary->getKind() == UETT_SizeOf)
8715 if (!
SizeOf->isArgumentType())
8716 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
8723 return SizeOf->getTypeOfArgument();
8729struct SearchNonTrivialToInitializeField
8734 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8738 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8739 asDerived().visitArray(PDIK, AT, SL);
8743 Super::visitWithKind(PDIK, FT, SL);
8758 visit(getContext().getBaseElementType(AT), SL);
8763 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
8772struct SearchNonTrivialToCopyField
8776 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8780 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8781 asDerived().visitArray(PCK, AT, SL);
8785 Super::visitWithKind(PCK, FT, SL);
8800 visit(getContext().getBaseElementType(AT), SL);
8823 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
8824 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
8848 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
8850 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
8851 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
8857 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
8860 const Expr *SizeArg =
8861 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
8863 auto isLiteralZero = [](
const Expr *
E) {
8864 return (isa<IntegerLiteral>(
E) &&
8865 cast<IntegerLiteral>(
E)->getValue() == 0) ||
8866 (isa<CharacterLiteral>(
E) &&
8867 cast<CharacterLiteral>(
E)->getValue() == 0);
8873 if (isLiteralZero(SizeArg) &&
8880 if (BId == Builtin::BIbzero ||
8883 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
8884 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
8885 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
8886 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
8887 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
8895 if (BId == Builtin::BImemset &&
8899 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
8900 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
8905void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
8912 unsigned ExpectedNumArgs =
8913 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
8914 if (
Call->getNumArgs() < ExpectedNumArgs)
8917 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
8918 BId == Builtin::BIstrndup ? 1 : 2);
8920 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
8921 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
8924 Call->getBeginLoc(),
Call->getRParenLoc()))
8933 llvm::FoldingSetNodeID SizeOfArgID;
8938 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8942 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
8943 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
8965 if (SizeOfArgID == llvm::FoldingSetNodeID())
8967 llvm::FoldingSetNodeID DestID;
8969 if (DestID == SizeOfArgID) {
8972 unsigned ActionIdx = 0;
8973 StringRef ReadableName = FnName->
getName();
8975 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
8976 if (UnaryOp->getOpcode() == UO_AddrOf)
8990 if (
SM.isMacroArgExpansion(SL)) {
8992 SL =
SM.getSpellingLoc(SL);
9000 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
9007 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
9022 PDiag(diag::warn_sizeof_pointer_type_memaccess)
9023 << FnName << SizeOfArgTy << ArgIdx
9041 unsigned OperationType = 0;
9042 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
9045 if (ArgIdx != 0 || IsCmp) {
9046 if (BId == Builtin::BImemcpy)
9048 else if(BId == Builtin::BImemmove)
9055 PDiag(diag::warn_dyn_class_memaccess)
9056 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
9057 << IsContained << ContainedRD << OperationType
9058 <<
Call->getCallee()->getSourceRange());
9060 BId != Builtin::BImemset)
9063 PDiag(diag::warn_arc_object_memaccess)
9064 << ArgIdx << FnName << PointeeTy
9065 <<
Call->getCallee()->getSourceRange());
9072 bool MayBeTriviallyCopyableCXXRecord =
9074 RT->desugar().isTriviallyCopyableType(
Context);
9076 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9077 RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
9079 PDiag(diag::warn_cstruct_memaccess)
9080 << ArgIdx << FnName << PointeeTy << 0);
9081 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
9082 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9083 !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9087 PDiag(diag::warn_cxxstruct_memaccess)
9088 << FnName << PointeeTy);
9089 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9090 RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
9092 PDiag(diag::warn_cstruct_memaccess)
9093 << ArgIdx << FnName << PointeeTy << 1);
9094 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
9095 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9096 !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9100 PDiag(diag::warn_cxxstruct_memaccess)
9101 << FnName << PointeeTy);
9110 PDiag(diag::note_bad_memaccess_silence)
9130 if (isa<IntegerLiteral>(RHS))
9132 else if (isa<IntegerLiteral>(LHS))
9146 if (CAT->getZExtSize() <= 1)
9154void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
9158 unsigned NumArgs =
Call->getNumArgs();
9159 if ((NumArgs != 3) && (NumArgs != 4))
9164 const Expr *CompareWithSrc =
nullptr;
9167 Call->getBeginLoc(),
Call->getRParenLoc()))
9172 CompareWithSrc = Ex;
9175 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
9176 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
9177 SizeCall->getNumArgs() == 1)
9182 if (!CompareWithSrc)
9189 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
9193 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
9194 if (!CompareWithSrcDRE ||
9198 const Expr *OriginalSizeArg =
Call->getArg(2);
9199 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
9206 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
9211 llvm::raw_svector_ostream
OS(sizeString);
9216 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
9223 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
9224 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
9225 return D1->getDecl() == D2->getDecl();
9230 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
9239void Sema::CheckStrncatArguments(
const CallExpr *CE,
9254 unsigned PatternType = 0;
9262 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
9263 if (BE->getOpcode() == BO_Sub) {
9276 if (PatternType == 0)
9285 if (
SM.isMacroArgExpansion(SL)) {
9286 SL =
SM.getSpellingLoc(SL);
9295 if (!isKnownSizeArray) {
9296 if (PatternType == 1)
9297 Diag(SL, diag::warn_strncat_wrong_size) << SR;
9299 Diag(SL, diag::warn_strncat_src_size) << SR;
9303 if (PatternType == 1)
9304 Diag(SL, diag::warn_strncat_large_size) << SR;
9306 Diag(SL, diag::warn_strncat_src_size) << SR;
9309 llvm::raw_svector_ostream
OS(sizeString);
9317 Diag(SL, diag::note_strncat_wrong_size)
9322void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
9324 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
9326 << CalleeName << 0 << cast<NamedDecl>(
D);
9331void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
9333 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
9334 const Decl *
D = Lvalue->getDecl();
9335 if (isa<DeclaratorDecl>(
D))
9336 if (!dyn_cast<DeclaratorDecl>(
D)->getType()->isReferenceType())
9337 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
9340 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
9341 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
9342 Lvalue->getMemberDecl());
9345void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
9347 const auto *Lambda = dyn_cast<LambdaExpr>(
9352 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
9353 << CalleeName << 2 ;
9356void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
9358 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
9363 << CalleeName << 0 << Var;
9366void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
9369 llvm::raw_svector_ostream OS(SizeString);
9372 if (Kind == clang::CK_BitCast &&
9373 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
9375 if (Kind == clang::CK_IntegralToPointer &&
9376 !isa<IntegerLiteral>(
9377 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
9380 switch (
Cast->getCastKind()) {
9381 case clang::CK_BitCast:
9382 case clang::CK_IntegralToPointer:
9383 case clang::CK_FunctionToPointerDecay:
9392 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
9393 << CalleeName << 0 << OS.str();
9397void Sema::CheckFreeArguments(
const CallExpr *
E) {
9398 const std::string CalleeName =
9399 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
9403 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
9405 case UnaryOperator::Opcode::UO_AddrOf:
9406 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
9407 case UnaryOperator::Opcode::UO_Plus:
9408 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
9413 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
9415 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
9417 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
9418 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
9419 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
9423 if (isa<BlockExpr>(Arg)) {
9425 << CalleeName << 1 ;
9430 if (
const auto *Cast = dyn_cast<CastExpr>(
E->getArg(0)))
9431 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
9435Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
9441 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
9444 Diag(ReturnLoc, diag::warn_null_ret)
9454 if (Op == OO_New || Op == OO_Array_New) {
9459 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
9465 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
9482 auto getCastAndLiteral = [&FPLiteral, &FPCast](
Expr *L,
Expr *R) {
9483 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
9485 return FPLiteral && FPCast;
9488 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
9494 llvm::APFloat TargetC = FPLiteral->
getValue();
9496 llvm::APFloat::rmNearestTiesToEven, &Lossy);
9500 Diag(
Loc, diag::warn_float_compare_literal)
9501 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
9514 if (
auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
9515 if (
auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
9516 if (DRL->getDecl() == DRR->getDecl())
9524 if (
FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
9528 if (
FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
9533 if (
CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
9534 if (CL->getBuiltinCallee())
9537 if (
CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
9538 if (CR->getBuiltinCallee())
9542 Diag(
Loc, diag::warn_floatingpoint_eq)
9563 IntRange(
unsigned Width,
bool NonNegative)
9564 : Width(Width), NonNegative(NonNegative) {}
9567 unsigned valueBits()
const {
9568 return NonNegative ? Width : Width - 1;
9572 static IntRange forBoolType() {
9573 return IntRange(1,
true);
9578 return forValueOfCanonicalType(
C,
9586 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9587 T = VT->getElementType().getTypePtr();
9589 T = CT->getElementType().getTypePtr();
9590 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9591 T = AT->getValueType().getTypePtr();
9593 if (!
C.getLangOpts().CPlusPlus) {
9595 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9596 T = ET->getDecl()->getIntegerType().getDesugaredType(
C).getTypePtr();
9597 }
else if (
const EnumType *ET = dyn_cast<EnumType>(
T)) {
9602 if (
Enum->isFixed()) {
9603 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
9604 !ET->isSignedIntegerOrEnumerationType());
9607 unsigned NumPositive =
Enum->getNumPositiveBits();
9608 unsigned NumNegative =
Enum->getNumNegativeBits();
9610 if (NumNegative == 0)
9611 return IntRange(NumPositive,
true);
9613 return IntRange(std::max(NumPositive + 1, NumNegative),
9617 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9618 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9634 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9635 T = VT->getElementType().getTypePtr();
9637 T = CT->getElementType().getTypePtr();
9638 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9639 T = AT->getValueType().getTypePtr();
9640 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9641 T =
C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
9643 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9644 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9653 static IntRange join(IntRange L, IntRange R) {
9654 bool Unsigned = L.NonNegative && R.NonNegative;
9655 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
9656 L.NonNegative && R.NonNegative);
9660 static IntRange bit_and(IntRange L, IntRange R) {
9661 unsigned Bits = std::max(L.Width, R.Width);
9662 bool NonNegative =
false;
9663 if (L.NonNegative) {
9664 Bits = std::min(Bits, L.Width);
9667 if (R.NonNegative) {
9668 Bits = std::min(Bits, R.Width);
9671 return IntRange(Bits, NonNegative);
9675 static IntRange sum(IntRange L, IntRange R) {
9676 bool Unsigned = L.NonNegative && R.NonNegative;
9677 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
9682 static IntRange difference(IntRange L, IntRange R) {
9686 bool CanWiden = !L.NonNegative || !R.NonNegative;
9687 bool Unsigned = L.NonNegative && R.Width == 0;
9688 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
9694 static IntRange product(IntRange L, IntRange R) {
9698 bool CanWiden = !L.NonNegative && !R.NonNegative;
9699 bool Unsigned = L.NonNegative && R.NonNegative;
9700 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
9705 static IntRange rem(IntRange L, IntRange R) {
9709 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
9717 unsigned MaxWidth) {
9718 if (value.isSigned() && value.isNegative())
9719 return IntRange(value.getSignificantBits(),
false);
9721 if (value.getBitWidth() > MaxWidth)
9722 value = value.trunc(MaxWidth);
9726 return IntRange(value.getActiveBits(),
true);
9730 unsigned MaxWidth) {
9738 R = IntRange::join(R, El);
9746 return IntRange::join(R, I);
9761 Ty = AtomicRHS->getValueType();
9780 bool InConstantContext,
9792 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
9793 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
9797 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
9799 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
9800 CE->getCastKind() == CK_BooleanToSignedIntegral;
9804 return OutputTypeRange;
9807 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
9808 InConstantContext, Approximate);
9810 return std::nullopt;
9813 if (SubRange->Width >= OutputTypeRange.Width)
9814 return OutputTypeRange;
9818 return IntRange(SubRange->Width,
9819 SubRange->NonNegative || OutputTypeRange.NonNegative);
9822 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
9825 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
9827 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
9828 InConstantContext, Approximate);
9833 Expr *TrueExpr = CO->getTrueExpr();
9835 return std::nullopt;
9837 std::optional<IntRange> L =
9840 return std::nullopt;
9842 Expr *FalseExpr = CO->getFalseExpr();
9844 return std::nullopt;
9846 std::optional<IntRange> R =
9849 return std::nullopt;
9851 return IntRange::join(*L, *R);
9854 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
9855 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
9857 switch (BO->getOpcode()) {
9859 llvm_unreachable(
"builtin <=> should have class type");
9870 return IntRange::forBoolType();
9899 Combine = IntRange::bit_and;
9907 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
9908 if (I->getValue() == 1) {
9910 return IntRange(R.Width,
true);
9920 case BO_ShrAssign: {
9922 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
9924 return std::nullopt;
9928 if (std::optional<llvm::APSInt> shift =
9929 BO->getRHS()->getIntegerConstantExpr(
C)) {
9930 if (shift->isNonNegative()) {
9931 if (shift->uge(L->Width))
9932 L->Width = (L->NonNegative ? 0 : 1);
9934 L->Width -= shift->getZExtValue();
9948 Combine = IntRange::sum;
9952 if (BO->getLHS()->getType()->isPointerType())
9955 Combine = IntRange::difference;
9960 Combine = IntRange::product;
9969 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
9971 return std::nullopt;
9974 if (std::optional<llvm::APSInt> divisor =
9975 BO->getRHS()->getIntegerConstantExpr(
C)) {
9976 unsigned log2 = divisor->logBase2();
9977 if (
log2 >= L->Width)
9978 L->Width = (L->NonNegative ? 0 : 1);
9980 L->Width = std::min(L->Width -
log2, MaxWidth);
9988 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
9990 return std::nullopt;
9992 return IntRange(L->Width, L->NonNegative && R->NonNegative);
9996 Combine = IntRange::rem;
10008 unsigned opWidth =
C.getIntWidth(
T);
10010 InConstantContext, Approximate);
10012 return std::nullopt;
10015 InConstantContext, Approximate);
10017 return std::nullopt;
10019 IntRange
C = Combine(*L, *R);
10021 C.Width = std::min(
C.Width, MaxWidth);
10025 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
10026 switch (UO->getOpcode()) {
10029 return IntRange::forBoolType();
10042 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
10043 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
10047 return IntRange(BitField->getBitWidthValue(),
10048 BitField->getType()->isUnsignedIntegerOrEnumerationType());
10051 return std::nullopt;
10057 bool InConstantContext,
10058 bool Approximate) {
10067 const llvm::fltSemantics &Src,
10068 const llvm::fltSemantics &Tgt) {
10069 llvm::APFloat truncated = value;
10072 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
10073 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
10075 return truncated.bitwiseIsEqual(value);
10084 const llvm::fltSemantics &Src,
10085 const llvm::fltSemantics &Tgt) {
10102 bool IsListInit =
false);
10108 if (isa<EnumConstantDecl>(DR->getDecl()))
10118 return MacroName !=
"YES" && MacroName !=
"NO" &&
10119 MacroName !=
"true" && MacroName !=
"false";
10142struct PromotedRange {
10144 llvm::APSInt PromotedMin;
10146 llvm::APSInt PromotedMax;
10148 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
10150 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
10151 else if (R.Width >= BitWidth && !
Unsigned) {
10155 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
10156 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
10158 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
10159 .extOrTrunc(BitWidth);
10160 PromotedMin.setIsUnsigned(
Unsigned);
10162 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
10163 .extOrTrunc(BitWidth);
10164 PromotedMax.setIsUnsigned(
Unsigned);
10169 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
10179 InRangeFlag = 0x40,
10182 Min =
LE | InRangeFlag,
10184 Max =
GE | InRangeFlag,
10187 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
10192 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
10193 Value.isUnsigned() == PromotedMin.isUnsigned());
10194 if (!isContiguous()) {
10195 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
10196 if (
Value.isMinValue())
return Min;
10197 if (
Value.isMaxValue())
return Max;
10203 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
10204 case -1:
return Less;
10205 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
10207 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
10209 case 0:
return Max;
10214 llvm_unreachable(
"impossible compare result");
10217 static std::optional<StringRef>
10219 if (Op == BO_Cmp) {
10221 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
10223 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
10224 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
10225 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
10226 return std::nullopt;
10233 }
else if (Op == BO_NE) {
10237 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
10244 if (Op == BO_GE || Op == BO_LE)
10245 std::swap(TrueFlag, FalseFlag);
10248 return StringRef(
"true");
10250 return StringRef(
"false");
10251 return std::nullopt;
10259 if (ICE->getCastKind() != CK_IntegralCast &&
10260 ICE->getCastKind() != CK_NoOp)
10262 E = ICE->getSubExpr();
10271 enum ConstantValueKind {
10276 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
10277 return BL->getValue() ? ConstantValueKind::LiteralTrue
10278 : ConstantValueKind::LiteralFalse;
10279 return ConstantValueKind::Miscellaneous;
10284 const llvm::APSInt &
Value,
10285 bool RhsConstant) {
10307 if (!OtherValueRange)
10312 OtherT = AT->getValueType();
10313 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
10317 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
10323 bool OtherIsBooleanDespiteType =
10325 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
10326 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
10330 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
10331 Value.isUnsigned());
10332 auto Cmp = OtherPromotedValueRange.compare(
Value);
10333 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
10339 bool TautologicalTypeCompare =
false;
10341 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
10342 Value.isUnsigned());
10343 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
10344 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
10346 TautologicalTypeCompare =
true;
10354 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
10363 bool InRange = Cmp & PromotedRange::InRangeFlag;
10369 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
10370 Other->getType()->isUnsignedIntegerOrEnumerationType())
10371 TautologicalTypeCompare =
true;
10376 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant))
10377 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
10381 llvm::raw_svector_ostream OS(PrettySourceValue);
10383 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
10384 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
10386 OS << (BL->getValue() ?
"YES" :
"NO");
10391 if (!TautologicalTypeCompare) {
10392 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
10393 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
10394 <<
E->getOpcodeStr() << OS.str() << *
Result
10399 if (IsObjCSignedCharBool) {
10401 S.
PDiag(diag::warn_tautological_compare_objc_bool)
10402 << OS.str() << *
Result);
10409 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
10412 E->getOperatorLoc(),
E,
10413 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
10414 : diag::warn_tautological_bool_compare)
10416 << OtherIsBooleanDespiteType << *
Result
10423 ? diag::warn_unsigned_enum_always_true_comparison
10424 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
10425 : diag::warn_unsigned_always_true_comparison)
10426 : diag::warn_tautological_constant_compare;
10429 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result
10459 Expr *LHS =
E->getLHS();
10460 Expr *RHS =
E->getRHS();
10463 std::optional<llvm::APSInt> RHSValue =
10465 std::optional<llvm::APSInt> LHSValue =
10469 if (RHSValue && LHSValue)
10473 if ((
bool)RHSValue ^ (
bool)LHSValue) {
10475 const bool RhsConstant = (
bool)RHSValue;
10476 Expr *Const = RhsConstant ? RHS : LHS;
10478 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
10501 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
10503 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
10509 Expr *signedOperand, *unsignedOperand;
10512 "unsigned comparison between two signed integer expressions?");
10513 signedOperand = LHS;
10514 unsignedOperand = RHS;
10516 signedOperand = RHS;
10517 unsignedOperand = LHS;
10523 std::optional<IntRange> signedRange =
10535 if (signedRange->NonNegative)
10542 if (
E->isEqualityOp()) {
10547 if (!unsignedRange)
10552 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
10554 if (unsignedRange->Width < comparisonWidth)
10559 S.
PDiag(diag::warn_mixed_sign_comparison)
10587 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
10588 << BitfieldEnumDecl;
10595 Init->isValueDependent() ||
10596 Init->isTypeDependent())
10599 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
10622 unsigned DiagID = 0;
10623 if (SignedEnum && !SignedBitfield) {
10624 DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
10625 }
else if (SignedBitfield && !SignedEnum &&
10627 DiagID = diag::warn_signed_bitfield_enum_conversion;
10631 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
10636 << SignedEnum << TypeRange;
10647 if (BitsNeeded > FieldWidth) {
10649 S.
Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
10661 unsigned OriginalWidth =
Value.getBitWidth();
10667 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
10668 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
10675 if (!
Value.isSigned() ||
Value.isNegative())
10676 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
10677 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
10678 OriginalWidth =
Value.getSignificantBits();
10680 if (OriginalWidth <= FieldWidth)
10684 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
10688 TruncatedValue = TruncatedValue.extend(OriginalWidth);
10689 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
10693 std::string PrettyTrunc =
toString(TruncatedValue, 10);
10695 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
10696 ? diag::warn_impcast_single_bit_bitield_precision_constant
10697 : diag::warn_impcast_bitfield_precision_constant)
10698 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
10699 <<
Init->getSourceRange();
10714 E->getOperatorLoc())) {
10717 E->getOperatorLoc());
10731 bool pruneControlFlow =
false) {
10732 if (pruneControlFlow) {
10746 unsigned diag,
bool pruneControlFlow =
false) {
10759 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
10762 const bool IsLiteral =
10763 isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
10765 llvm::APFloat
Value(0.0);
10771 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10776 diag::warn_impcast_float_integer, PruneWarnings);
10779 bool isExact =
false;
10783 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
10784 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
10792 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
10793 precision = (precision * 59 + 195) / 196;
10794 Value.toString(PrettySourceValue, precision);
10798 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10799 << PrettySourceValue);
10802 if (
Result == llvm::APFloat::opOK && isExact) {
10803 if (IsLiteral)
return;
10810 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
10813 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
10814 : diag::warn_impcast_float_to_integer_out_of_range,
10817 unsigned DiagID = 0;
10820 DiagID = diag::warn_impcast_literal_float_to_integer;
10821 }
else if (IntegerValue == 0) {
10822 if (
Value.isZero()) {
10824 diag::warn_impcast_float_integer, PruneWarnings);
10827 DiagID = diag::warn_impcast_float_to_integer_zero;
10829 if (IntegerValue.isUnsigned()) {
10830 if (!IntegerValue.isMaxValue()) {
10832 diag::warn_impcast_float_integer, PruneWarnings);
10835 if (!IntegerValue.isMaxSignedValue() &&
10836 !IntegerValue.isMinSignedValue()) {
10838 diag::warn_impcast_float_integer, PruneWarnings);
10842 DiagID = diag::warn_impcast_float_to_integer;
10847 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
10849 IntegerValue.toString(PrettyTargetValue);
10851 if (PruneWarnings) {
10854 <<
E->
getType() <<
T.getUnqualifiedType()
10855 << PrettySourceValue << PrettyTargetValue
10859 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
10867 assert(isa<CompoundAssignOperator>(
E) &&
10868 "Must be compound assignment operation");
10874 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
10878 const auto *RBT = cast<CompoundAssignOperator>(
E)
10879 ->getComputationResultType()
10886 if (ResultBT->isInteger())
10888 E->
getExprLoc(), diag::warn_impcast_float_integer);
10890 if (!ResultBT->isFloatingPoint())
10899 diag::warn_impcast_float_result_precision);
10904 if (!
Range.Width)
return "0";
10906 llvm::APSInt ValueInRange =
Value;
10907 ValueInRange.setIsSigned(!
Range.NonNegative);
10908 ValueInRange = ValueInRange.trunc(
Range.Width);
10909 return toString(ValueInRange, 10);
10913 if (!isa<ImplicitCastExpr>(Ex))
10918 const Type *Source =
10920 if (
Target->isDependentType())
10924 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
10925 const Type *BoolCandidateType = ToBool ?
Target : Source;
10934 for (
unsigned i = 0; i < NumArgs; ++i) {
10939 bool IsSwapped = ((i > 0) &&
10941 IsSwapped |= ((i < (NumArgs - 1)) &&
10947 diag::warn_impcast_floating_point_to_bool);
10954 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
10959 if (isa<CallExpr>(
E))
10964 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
10966 if (!IsGNUNullExpr && !HasNullPtrType)
10986 if (MacroName ==
"NULL")
10994 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
11008 const char FirstLiteralCharacter =
11010 if (FirstLiteralCharacter ==
'0')
11017 const char FirstContextCharacter =
11019 if (FirstContextCharacter ==
'{')
11027 const auto *IL = dyn_cast<IntegerLiteral>(
E);
11029 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
11030 if (UO->getOpcode() == UO_Minus)
11031 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
11042 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
11046 if (Opc == BO_Shl) {
11049 if (LHS && LHS->getValue() == 0)
11050 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
11052 RHS->getValue().isNonNegative() &&
11054 S.
Diag(ExprLoc, diag::warn_left_shift_always)
11055 << (
Result.Val.getInt() != 0);
11057 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context) <<
E;
11061 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
11066 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
11067 (RHS->getValue() == 0 || RHS->getValue() == 1))
11070 if (LHS->getValue() != 0 && RHS->getValue() != 0)
11071 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
11076 bool *ICContext,
bool IsListInit) {
11081 if (Source ==
Target)
return;
11082 if (
Target->isDependentType())
return;
11096 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
11097 if (isa<StringLiteral>(
E))
11102 diag::warn_impcast_string_literal_to_bool);
11103 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
11104 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
11108 diag::warn_impcast_objective_c_literal_to_bool);
11123 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
11125 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
11134 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
11136 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
11140 if (isa<VectorType>(Source)) {
11141 if (
Target->isSveVLSBuiltinType() &&
11148 if (
Target->isRVVVLSBuiltinType() &&
11155 if (!isa<VectorType>(
Target)) {
11165 diag::warn_hlsl_impcast_vector_truncation);
11174 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
11175 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
11177 if (
auto VecTy = dyn_cast<VectorType>(
Target))
11178 Target = VecTy->getElementType().getTypePtr();
11181 if (isa<ComplexType>(Source)) {
11182 if (!isa<ComplexType>(
Target)) {
11188 ? diag::err_impcast_complex_scalar
11189 : diag::warn_impcast_complex_scalar);
11192 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
11193 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
11196 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
11249 else if (Order < 0) {
11259 if (TargetBT && TargetBT->
isInteger()) {
11274 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
11282 if (isa<ImplicitCastExpr>(LastA) &&
11286 diag::warn_impcast_floating_point_to_bool);
11295 if (
Target->isUnsaturatedFixedPointType()) {
11299 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
11304 PDiag(diag::warn_impcast_fixed_point_range)
11305 <<
Value.toString() <<
T
11311 }
else if (
Target->isIntegerType()) {
11315 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
11318 llvm::APSInt IntResult = FXResult.convertToInt(
11324 PDiag(diag::warn_impcast_fixed_point_range)
11325 << FXResult.toString() <<
T
11332 }
else if (
Target->isUnsaturatedFixedPointType()) {
11340 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
11345 PDiag(diag::warn_impcast_fixed_point_range)
11366 unsigned int SourcePrecision =
SourceRange->Width;
11370 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
11373 if (SourcePrecision > 0 && TargetPrecision > 0 &&
11374 SourcePrecision > TargetPrecision) {
11376 if (std::optional<llvm::APSInt> SourceInt =
11381 llvm::APFloat TargetFloatValue(
11383 llvm::APFloat::opStatus ConversionStatus =
11384 TargetFloatValue.convertFromAPInt(
11386 llvm::APFloat::rmNearestTiesToEven);
11388 if (ConversionStatus != llvm::APFloat::opOK) {
11390 SourceInt->toString(PrettySourceValue, 10);
11392 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
11396 PDiag(diag::warn_impcast_integer_float_precision_constant)
11397 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11403 diag::warn_impcast_integer_float_precision);
11412 if (
Target->isBooleanType())
11420 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
11426 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11431 if (!LikelySourceRange)
11434 IntRange SourceTypeRange =
11435 IntRange::forTargetOfCanonicalType(
Context, Source);
11436 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
11438 if (LikelySourceRange->Width > TargetRange.Width) {
11444 llvm::APSInt
Value(32);
11454 PDiag(diag::warn_impcast_integer_precision_constant)
11455 << PrettySourceValue << PrettyTargetValue
11469 diag::warn_impcast_integer_precision);
11472 if (TargetRange.Width > SourceTypeRange.Width) {
11473 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
11474 if (UO->getOpcode() == UO_Minus)
11476 if (
Target->isUnsignedIntegerType())
11478 diag::warn_impcast_high_order_zero_bits);
11479 if (
Target->isSignedIntegerType())
11481 diag::warn_impcast_nonnegative_result);
11485 if (TargetRange.Width == LikelySourceRange->Width &&
11486 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11501 PDiag(diag::warn_impcast_integer_precision_constant)
11502 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11511 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
11512 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
11513 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11514 LikelySourceRange->Width == TargetRange.Width))) {
11518 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
11524 unsigned DiagID = diag::warn_impcast_integer_sign;
11532 DiagID = diag::warn_impcast_integer_sign_conditional;
11547 if (SourceEnum->getDecl()->hasNameForLinkage() &&
11548 TargetEnum->getDecl()->hasNameForLinkage() &&
11549 SourceEnum != TargetEnum) {
11554 diag::warn_impcast_different_enum_types);
11568 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
11580 Expr *TrueExpr =
E->getTrueExpr();
11581 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
11582 TrueExpr = BCO->getCommon();
11584 bool Suspicious =
false;
11593 if (!Suspicious)
return;
11596 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
11603 Suspicious =
false;
11625struct AnalyzeImplicitConversionsWorkItem {
11635 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
11637 Expr *OrigE = Item.E;
11646 bool IsListInit = Item.IsListInit ||
11647 (isa<InitListExpr>(OrigE) && S.
getLangOpts().CPlusPlus);
11652 Expr *SourceExpr =
E;
11657 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11658 if (
auto *Src = OVE->getSourceExpr())
11661 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
11662 if (UO->getOpcode() == UO_Not &&
11663 UO->getSubExpr()->isKnownToHaveBooleanValue())
11664 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
11668 if (
const auto *BO = dyn_cast<BinaryOperator>(SourceExpr))
11669 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
11670 BO->getLHS()->isKnownToHaveBooleanValue() &&
11671 BO->getRHS()->isKnownToHaveBooleanValue() &&
11672 BO->getLHS()->HasSideEffects(S.
Context) &&
11673 BO->getRHS()->HasSideEffects(S.
Context)) {
11684 if (SR.str() ==
"&" || SR.str() ==
"|") {
11686 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
11687 << (BO->getOpcode() == BO_And ?
"&" :
"|")
11690 BO->getOperatorLoc(),
11691 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
11692 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
11698 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
11719 for (
auto *SE : POE->semantics())
11720 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
11721 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
11725 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
11729 WorkList.push_back({
E, CC, IsListInit});
11733 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(
E)) {
11734 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
11738 if (OutArgE->isInOut())
11739 WorkList.push_back(
11740 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
11741 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
11747 if (BO->isComparisonOp())
11751 if (BO->getOpcode() == BO_Assign)
11754 if (BO->isAssignmentOp())
11762 if (isa<StmtExpr>(
E))
return;
11765 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
11770 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
11772 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
11776 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
11777 if (ChildExpr == CSE->getOperand())
11783 if (IsLogicalAndOperator &&
11788 WorkList.push_back({ChildExpr, CC, IsListInit});
11793 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11797 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11802 if (
U->getOpcode() == UO_LNot) {
11804 }
else if (
U->getOpcode() != UO_AddrOf) {
11805 if (
U->getSubExpr()->getType()->isAtomicType())
11806 S.
Diag(
U->getSubExpr()->getBeginLoc(),
11807 diag::warn_atomic_implicit_seq_cst);
11818 WorkList.push_back({OrigE, CC, IsListInit});
11819 while (!WorkList.empty())
11831 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
11834 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11835 if (!M->getMemberDecl()->getType()->isReferenceType())
11838 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
11840 FD =
Call->getDirectCallee();
11849 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
11863 if (
SM.isMacroBodyExpansion(
Loc))
11865 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
11888 if (isa<CXXThisExpr>(
E)) {
11889 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
11890 : diag::warn_this_bool_conversion;
11895 bool IsAddressOf =
false;
11897 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
11898 if (UO->getOpcode() != UO_AddrOf)
11900 IsAddressOf =
true;
11901 E = UO->getSubExpr();
11905 unsigned DiagID = IsCompare
11906 ? diag::warn_address_of_reference_null_compare
11907 : diag::warn_address_of_reference_bool_conversion;
11915 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
11916 bool IsParam = isa<NonNullAttr>(NonnullAttr);
11918 llvm::raw_string_ostream S(Str);
11920 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
11921 : diag::warn_cast_nonnull_to_bool;
11924 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
11929 if (
auto *Callee =
Call->getDirectCallee()) {
11930 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
11931 ComplainAboutNonnullParamOrCall(A);
11940 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
11941 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
11942 MRecordDecl && MRecordDecl->isLambda()) {
11945 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
11955 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11956 D = M->getMemberDecl();
11960 if (!
D ||
D->isWeak())
11964 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
11967 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
11968 ComplainAboutNonnullParamOrCall(A);
11972 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
11976 auto ParamIter = llvm::find(FD->
parameters(), PV);
11978 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
11982 ComplainAboutNonnullParamOrCall(
NonNull);
11987 if (ArgNo.getASTIndex() == ParamNo) {
11988 ComplainAboutNonnullParamOrCall(
NonNull);
12002 if (IsAddressOf && IsFunction) {
12007 if (!IsAddressOf && !IsFunction && !IsArray)
12012 llvm::raw_string_ostream S(Str);
12015 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
12016 : diag::warn_impcast_pointer_to_bool;
12023 DiagType = AddressOf;
12024 else if (IsFunction)
12025 DiagType = FunctionPointer;
12027 DiagType = ArrayPointer;
12029 llvm_unreachable(
"Could not determine diagnostic.");
12031 <<
Range << IsEqual;
12044 if (ReturnType.
isNull())
12082 CheckArrayAccess(
E);
12089 ::CheckBoolLikeConversion(*
this,
E, CC);
12092void Sema::CheckForIntOverflow (
const Expr *
E) {
12097 const Expr *OriginalE = Exprs.pop_back_val();
12100 if (isa<BinaryOperator, UnaryOperator>(
E)) {
12105 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
12106 Exprs.append(InitList->inits().begin(), InitList->inits().end());
12107 else if (isa<ObjCBoxedExpr>(OriginalE))
12109 else if (
const auto *
Call = dyn_cast<CallExpr>(
E))
12110 Exprs.append(
Call->arg_begin(),
Call->arg_end());
12111 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
12112 Exprs.append(Message->arg_begin(), Message->arg_end());
12113 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
12114 Exprs.append(Construct->arg_begin(), Construct->arg_end());
12115 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
12116 Exprs.push_back(Temporary->getSubExpr());
12117 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
12118 Exprs.push_back(Array->getIdx());
12119 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
12120 Exprs.push_back(Compound->getInitializer());
12121 else if (
const auto *New = dyn_cast<CXXNewExpr>(
E);
12122 New && New->isArray()) {
12123 if (
auto ArraySize = New->getArraySize())
12124 Exprs.push_back(*ArraySize);
12125 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
12126 Exprs.push_back(MTE->getSubExpr());
12127 }
while (!Exprs.empty());
12142 class SequenceTree {
12146 LLVM_PREFERRED_TYPE(
bool)
12147 unsigned Merged : 1;
12155 friend class SequenceTree;
12159 explicit Seq(
unsigned N) : Index(N) {}
12162 Seq() : Index(0) {}
12165 SequenceTree() { Values.push_back(
Value(0)); }
12166 Seq root()
const {
return Seq(0); }
12173 return Seq(Values.size() - 1);
12177 void merge(
Seq S) {
12178 Values[S.Index].Merged =
true;
12184 bool isUnsequenced(
Seq Cur,
Seq Old) {
12185 unsigned C = representative(Cur.Index);
12186 unsigned Target = representative(Old.Index);
12190 C = Values[
C].Parent;
12197 unsigned representative(
unsigned K) {
12198 if (Values[K].Merged)
12200 return Values[K].Parent = representative(Values[K].
Parent);
12220 UK_ModAsSideEffect,
12222 UK_Count = UK_ModAsSideEffect + 1
12228 const Expr *UsageExpr =
nullptr;
12229 SequenceTree::Seq
Seq;
12235 Usage Uses[UK_Count];
12238 bool Diagnosed =
false;
12242 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
12250 UsageInfoMap UsageMap;
12253 SequenceTree::Seq Region;
12268 struct SequencedSubexpression {
12269 SequencedSubexpression(SequenceChecker &Self)
12270 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
12271 Self.ModAsSideEffect = &ModAsSideEffect;
12274 ~SequencedSubexpression() {
12275 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
12279 UsageInfo &UI = Self.UsageMap[M.first];
12280 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
12281 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
12282 SideEffectUsage = M.second;
12284 Self.ModAsSideEffect = OldModAsSideEffect;
12287 SequenceChecker &Self;
12296 class EvaluationTracker {
12298 EvaluationTracker(SequenceChecker &Self)
12299 : Self(Self), Prev(Self.EvalTracker) {
12300 Self.EvalTracker =
this;
12303 ~EvaluationTracker() {
12304 Self.EvalTracker = Prev;
12306 Prev->EvalOK &= EvalOK;
12309 bool evaluate(
const Expr *
E,
bool &Result) {
12313 Result, Self.SemaRef.Context,
12314 Self.SemaRef.isConstantEvaluatedContext());
12319 SequenceChecker &Self;
12320 EvaluationTracker *Prev;
12321 bool EvalOK =
true;
12322 } *EvalTracker =
nullptr;
12326 Object getObject(
const Expr *
E,
bool Mod)
const {
12329 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
12330 return getObject(UO->getSubExpr(), Mod);
12332 if (BO->getOpcode() == BO_Comma)
12333 return getObject(BO->getRHS(), Mod);
12334 if (Mod && BO->isAssignmentOp())
12335 return getObject(BO->getLHS(), Mod);
12336 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
12338 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
12339 return ME->getMemberDecl();
12340 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
12349 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
12351 Usage &
U = UI.Uses[UK];
12352 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
12356 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
12357 ModAsSideEffect->push_back(std::make_pair(O,
U));
12359 U.UsageExpr = UsageExpr;
12369 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
12370 UsageKind OtherKind,
bool IsModMod) {
12374 const Usage &
U = UI.Uses[OtherKind];
12375 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
12378 const Expr *Mod =
U.UsageExpr;
12379 const Expr *ModOrUse = UsageExpr;
12380 if (OtherKind == UK_Use)
12381 std::swap(Mod, ModOrUse);
12385 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
12386 : diag::warn_unsequenced_mod_use)
12388 UI.Diagnosed =
true;
12417 void notePreUse(Object O,
const Expr *UseExpr) {
12418 UsageInfo &UI = UsageMap[O];
12420 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
12423 void notePostUse(Object O,
const Expr *UseExpr) {
12424 UsageInfo &UI = UsageMap[O];
12425 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
12427 addUsage(O, UI, UseExpr, UK_Use);
12430 void notePreMod(Object O,
const Expr *ModExpr) {
12431 UsageInfo &UI = UsageMap[O];
12433 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
12434 checkUsage(O, UI, ModExpr, UK_Use,
false);
12437 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
12438 UsageInfo &UI = UsageMap[O];
12439 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
12441 addUsage(O, UI, ModExpr, UK);
12445 SequenceChecker(
Sema &S,
const Expr *
E,
12447 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
12451 (void)this->WorkList;
12454 void VisitStmt(
const Stmt *S) {
12458 void VisitExpr(
const Expr *
E) {
12460 Base::VisitStmt(
E);
12464 for (
auto *Sub : CSE->
children()) {
12465 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
12480 void VisitCastExpr(
const CastExpr *
E) {
12482 if (
E->getCastKind() == CK_LValueToRValue)
12483 O = getObject(
E->getSubExpr(),
false);
12492 void VisitSequencedExpressions(
const Expr *SequencedBefore,
12493 const Expr *SequencedAfter) {
12494 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
12495 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
12496 SequenceTree::Seq OldRegion = Region;
12499 SequencedSubexpression SeqBefore(*
this);
12500 Region = BeforeRegion;
12501 Visit(SequencedBefore);
12504 Region = AfterRegion;
12505 Visit(SequencedAfter);
12507 Region = OldRegion;
12509 Tree.merge(BeforeRegion);
12510 Tree.merge(AfterRegion);
12518 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
12525 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12526 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12532 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12539 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12540 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12545 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12557 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12561 SequenceTree::Seq RHSRegion;
12562 SequenceTree::Seq LHSRegion;
12564 RHSRegion =
Tree.allocate(Region);
12565 LHSRegion =
Tree.allocate(Region);
12567 RHSRegion = Region;
12568 LHSRegion = Region;
12570 SequenceTree::Seq OldRegion = Region;
12586 SequencedSubexpression SeqBefore(*
this);
12587 Region = RHSRegion;
12591 Region = LHSRegion;
12594 if (O && isa<CompoundAssignOperator>(BO))
12595 notePostUse(O, BO);
12599 Region = LHSRegion;
12602 if (O && isa<CompoundAssignOperator>(BO))
12603 notePostUse(O, BO);
12605 Region = RHSRegion;
12613 Region = OldRegion;
12617 : UK_ModAsSideEffect);
12619 Tree.merge(RHSRegion);
12620 Tree.merge(LHSRegion);
12625 VisitBinAssign(CAO);
12628 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12629 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12633 return VisitExpr(UO);
12641 : UK_ModAsSideEffect);
12644 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12645 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12649 return VisitExpr(UO);
12653 notePostMod(O, UO, UK_ModAsSideEffect);
12662 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12663 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12664 SequenceTree::Seq OldRegion = Region;
12666 EvaluationTracker Eval(*
this);
12668 SequencedSubexpression Sequenced(*
this);
12669 Region = LHSRegion;
12676 bool EvalResult =
false;
12677 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12678 bool ShouldVisitRHS = !EvalOK || !EvalResult;
12679 if (ShouldVisitRHS) {
12680 Region = RHSRegion;
12684 Region = OldRegion;
12685 Tree.merge(LHSRegion);
12686 Tree.merge(RHSRegion);
12695 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12696 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12697 SequenceTree::Seq OldRegion = Region;
12699 EvaluationTracker Eval(*
this);
12701 SequencedSubexpression Sequenced(*
this);
12702 Region = LHSRegion;
12708 bool EvalResult =
false;
12709 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12710 bool ShouldVisitRHS = !EvalOK || EvalResult;
12711 if (ShouldVisitRHS) {
12712 Region = RHSRegion;
12716 Region = OldRegion;
12717 Tree.merge(LHSRegion);
12718 Tree.merge(RHSRegion);
12726 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
12742 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
12743 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
12744 SequenceTree::Seq OldRegion = Region;
12746 EvaluationTracker Eval(*
this);
12748 SequencedSubexpression Sequenced(*
this);
12749 Region = ConditionRegion;
12759 bool EvalResult =
false;
12760 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
12761 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
12762 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
12763 if (ShouldVisitTrueExpr) {
12764 Region = TrueRegion;
12767 if (ShouldVisitFalseExpr) {
12768 Region = FalseRegion;
12772 Region = OldRegion;
12773 Tree.merge(ConditionRegion);
12774 Tree.merge(TrueRegion);
12775 Tree.merge(FalseRegion);
12778 void VisitCallExpr(
const CallExpr *CE) {
12790 SequencedSubexpression Sequenced(*
this);
12795 SequenceTree::Seq CalleeRegion;
12796 SequenceTree::Seq OtherRegion;
12797 if (SemaRef.getLangOpts().CPlusPlus17) {
12798 CalleeRegion = Tree.allocate(Region);
12799 OtherRegion = Tree.allocate(Region);
12801 CalleeRegion = Region;
12802 OtherRegion = Region;
12804 SequenceTree::Seq OldRegion = Region;
12807 Region = CalleeRegion;
12809 SequencedSubexpression Sequenced(*this);
12810 Visit(CE->getCallee());
12812 Visit(CE->getCallee());
12816 Region = OtherRegion;
12820 Region = OldRegion;
12822 Tree.merge(CalleeRegion);
12823 Tree.merge(OtherRegion);
12841 return VisitCallExpr(CXXOCE);
12852 case OO_MinusEqual:
12854 case OO_SlashEqual:
12855 case OO_PercentEqual:
12856 case OO_CaretEqual:
12859 case OO_LessLessEqual:
12860 case OO_GreaterGreaterEqual:
12861 SequencingKind = RHSBeforeLHS;
12865 case OO_GreaterGreater:
12871 SequencingKind = LHSBeforeRHS;
12875 SequencingKind = LHSBeforeRest;
12879 SequencingKind = NoSequencing;
12883 if (SequencingKind == NoSequencing)
12884 return VisitCallExpr(CXXOCE);
12887 SequencedSubexpression Sequenced(*
this);
12890 assert(SemaRef.getLangOpts().CPlusPlus17 &&
12891 "Should only get there with C++17 and above!");
12892 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
12893 "Should only get there with an overloaded binary operator"
12894 " or an overloaded call operator!");
12896 if (SequencingKind == LHSBeforeRest) {
12897 assert(CXXOCE->getOperator() == OO_Call &&
12898 "We should only have an overloaded call operator here!");
12907 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
12908 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
12909 SequenceTree::Seq OldRegion = Region;
12911 assert(CXXOCE->getNumArgs() >= 1 &&
12912 "An overloaded call operator must have at least one argument"
12913 " for the postfix-expression!");
12914 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
12915 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
12916 CXXOCE->getNumArgs() - 1);
12920 Region = PostfixExprRegion;
12921 SequencedSubexpression Sequenced(*this);
12922 Visit(PostfixExpr);
12926 Region = ArgsRegion;
12927 for (const Expr *Arg : Args)
12930 Region = OldRegion;
12931 Tree.merge(PostfixExprRegion);
12932 Tree.merge(ArgsRegion);
12934 assert(CXXOCE->getNumArgs() == 2 &&
12935 "Should only have two arguments here!");
12936 assert((SequencingKind == LHSBeforeRHS ||
12937 SequencingKind == RHSBeforeLHS) &&
12938 "Unexpected sequencing kind!");
12942 const Expr *E1 = CXXOCE->getArg(0);
12943 const Expr *E2 = CXXOCE->getArg(1);
12944 if (SequencingKind == RHSBeforeLHS)
12947 return VisitSequencedExpressions(E1, E2);
12954 SequencedSubexpression Sequenced(*
this);
12957 return VisitExpr(CCE);
12960 SequenceExpressionsInOrder(
12966 return VisitExpr(ILE);
12969 SequenceExpressionsInOrder(ILE->
inits());
12981 SequenceTree::Seq
Parent = Region;
12982 for (
const Expr *
E : ExpressionList) {
12986 Elts.push_back(Region);
12992 for (
unsigned I = 0; I < Elts.size(); ++I)
12993 Tree.merge(Elts[I]);
12997SequenceChecker::UsageInfo::UsageInfo() =
default;
13001void Sema::CheckUnsequencedOperations(
const Expr *
E) {
13003 WorkList.push_back(
E);
13004 while (!WorkList.empty()) {
13005 const Expr *Item = WorkList.pop_back_val();
13006 SequenceChecker(*
this, Item, WorkList);
13011 bool IsConstexpr) {
13013 IsConstexpr || isa<ConstantExpr>(
E));
13014 CheckImplicitConversions(
E, CheckLoc);
13016 CheckUnsequencedOperations(
E);
13018 CheckForIntOverflow(
E);
13032 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
13036 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
13040 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
13054 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
13058 bool CheckParameterNames) {
13059 bool HasInvalidParm =
false;
13061 assert(Param &&
"null in a parameter list");
13070 if (!Param->isInvalidDecl() &&
13072 diag::err_typecheck_decl_incomplete_type) ||
13074 diag::err_abstract_type_in_decl,
13076 Param->setInvalidDecl();
13077 HasInvalidParm =
true;
13082 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
13086 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
13094 QualType PType = Param->getOriginalType();
13102 if (!Param->isInvalidDecl()) {
13104 if (!ClassDecl->isInvalidDecl() &&
13105 !ClassDecl->hasIrrelevantDestructor() &&
13106 !ClassDecl->isDependentContext() &&
13107 ClassDecl->isParamDestroyedInCallee()) {
13119 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
13120 if (!Param->getType().isConstQualified())
13121 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
13125 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
13130 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
13131 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
13136 if (!Param->isInvalidDecl() &&
13138 Param->setInvalidDecl();
13139 HasInvalidParm =
true;
13140 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
13144 return HasInvalidParm;
13147std::optional<std::pair<
13156static std::pair<CharUnits, CharUnits>
13164 if (
Base->isVirtual()) {
13171 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
13178 DerivedType =
Base->getType();
13181 return std::make_pair(BaseAlignment, Offset);
13185static std::optional<std::pair<CharUnits, CharUnits>>
13191 return std::nullopt;
13196 return std::nullopt;
13200 CharUnits Offset = EltSize * IdxRes->getExtValue();
13203 return std::make_pair(
P->first,
P->second + Offset);
13209 return std::make_pair(
13210 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
13216std::optional<std::pair<
13224 case Stmt::CStyleCastExprClass:
13225 case Stmt::CXXStaticCastExprClass:
13226 case Stmt::ImplicitCastExprClass: {
13227 auto *CE = cast<CastExpr>(
E);
13228 const Expr *From = CE->getSubExpr();
13229 switch (CE->getCastKind()) {
13234 case CK_UncheckedDerivedToBase:
13235 case CK_DerivedToBase: {
13245 case Stmt::ArraySubscriptExprClass: {
13246 auto *ASE = cast<ArraySubscriptExpr>(
E);
13250 case Stmt::DeclRefExprClass: {
13251 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
13254 if (!VD->getType()->isReferenceType()) {
13256 if (VD->hasDependentAlignment())
13265 case Stmt::MemberExprClass: {
13266 auto *ME = cast<MemberExpr>(
E);
13267 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
13271 std::optional<std::pair<CharUnits, CharUnits>>
P;
13280 return std::make_pair(
P->first,
13283 case Stmt::UnaryOperatorClass: {
13284 auto *UO = cast<UnaryOperator>(
E);
13293 case Stmt::BinaryOperatorClass: {
13294 auto *BO = cast<BinaryOperator>(
E);
13305 return std::nullopt;
13310std::optional<std::pair<
13319 case Stmt::CStyleCastExprClass:
13320 case Stmt::CXXStaticCastExprClass:
13321 case Stmt::ImplicitCastExprClass: {
13322 auto *CE = cast<CastExpr>(
E);
13323 const Expr *From = CE->getSubExpr();
13324 switch (CE->getCastKind()) {
13329 case CK_ArrayToPointerDecay:
13331 case CK_UncheckedDerivedToBase:
13332 case CK_DerivedToBase: {
13342 case Stmt::CXXThisExprClass: {
13347 case Stmt::UnaryOperatorClass: {
13348 auto *UO = cast<UnaryOperator>(
E);
13353 case Stmt::BinaryOperatorClass: {
13354 auto *BO = cast<BinaryOperator>(
E);
13362 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
13363 std::swap(LHS, RHS);
13373 return std::nullopt;
13378 std::optional<std::pair<CharUnits, CharUnits>>
P =
13382 return P->first.alignmentAtOffset(
P->second);
13400 if (!DestPtr)
return;
13406 if (DestAlign.
isOne())
return;
13410 if (!SrcPtr)
return;
13421 if (SrcAlign >= DestAlign)
return;
13426 <<
static_cast<unsigned>(DestAlign.
getQuantity())
13430void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
13432 bool AllowOnePastEnd,
bool IndexNegated) {
13441 const Type *EffectiveType =
13448 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
13450 const Type *BaseType =
13452 bool IsUnboundedArray =
13454 Context, StrictFlexArraysLevel,
13464 llvm::APSInt index =
Result.Val.getInt();
13465 if (IndexNegated) {
13466 index.setIsUnsigned(
false);
13470 if (IsUnboundedArray) {
13473 if (index.isUnsigned() || !index.isNegative()) {
13475 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
13477 if (index.getBitWidth() < AddrBits)
13478 index = index.zext(AddrBits);
13479 std::optional<CharUnits> ElemCharUnits =
13480 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
13483 if (!ElemCharUnits || ElemCharUnits->isZero())
13485 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
13490 if (index.getActiveBits() <= AddrBits) {
13492 llvm::APInt Product(index);
13494 Product = Product.umul_ov(ElemBytes, Overflow);
13495 if (!Overflow && Product.getActiveBits() <= AddrBits)
13501 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
13502 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
13504 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
13505 MaxElems = MaxElems.udiv(ElemBytes);
13508 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
13509 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
13515 <<
toString(index, 10,
true) << AddrBits
13516 << (
unsigned)ASTC.toBits(*ElemCharUnits)
13519 << (
unsigned)MaxElems.getLimitedValue(~0
U)
13524 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13526 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13528 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13529 ND = ME->getMemberDecl();
13533 PDiag(diag::note_array_declared_here) << ND);
13538 if (index.isUnsigned() || !index.isNegative()) {
13548 llvm::APInt size = ArrayTy->
getSize();
13550 if (BaseType != EffectiveType) {
13558 if (!ptrarith_typesize)
13561 if (ptrarith_typesize != array_typesize) {
13563 uint64_t ratio = array_typesize / ptrarith_typesize;
13567 if (ptrarith_typesize * ratio == array_typesize)
13568 size *= llvm::APInt(size.getBitWidth(), ratio);
13572 if (size.getBitWidth() > index.getBitWidth())
13573 index = index.zext(size.getBitWidth());
13574 else if (size.getBitWidth() < index.getBitWidth())
13575 size = size.zext(index.getBitWidth());
13581 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
13598 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
13599 : diag::warn_ptr_arith_exceeds_bounds;
13600 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
13608 unsigned DiagID = diag::warn_array_index_precedes_bounds;
13610 DiagID = diag::warn_ptr_arith_precedes_bounds;
13611 if (index.isNegative()) index = -index;
13621 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13623 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13625 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13626 ND = ME->getMemberDecl();
13630 PDiag(diag::note_array_declared_here) << ND);
13633void Sema::CheckArrayAccess(
const Expr *
expr) {
13634 int AllowOnePastEnd = 0;
13636 expr =
expr->IgnoreParenImpCasts();
13637 switch (
expr->getStmtClass()) {
13638 case Stmt::ArraySubscriptExprClass: {
13641 AllowOnePastEnd > 0);
13645 case Stmt::MemberExprClass: {
13646 expr = cast<MemberExpr>(
expr)->getBase();
13649 case Stmt::ArraySectionExprClass: {
13655 nullptr, AllowOnePastEnd > 0);
13658 case Stmt::UnaryOperatorClass: {
13674 case Stmt::ConditionalOperatorClass: {
13677 CheckArrayAccess(lhs);
13679 CheckArrayAccess(rhs);
13682 case Stmt::CXXOperatorCallExprClass: {
13683 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
13684 for (
const auto *Arg : OCE->arguments())
13685 CheckArrayAccess(Arg);
13695 Expr *RHS,
bool isProperty) {
13707 S.
Diag(
Loc, diag::warn_arc_literal_assign)
13709 << (isProperty ? 0 : 1)
13717 Expr *RHS,
bool isProperty) {
13720 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13721 S.
Diag(
Loc, diag::warn_arc_retained_assign)
13723 << (isProperty ? 0 : 1)
13727 RHS =
cast->getSubExpr();
13798 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13799 Diag(
Loc, diag::warn_arc_retained_property_assign)
13803 RHS =
cast->getSubExpr();
13826 bool StmtLineInvalid;
13829 if (StmtLineInvalid)
13832 bool BodyLineInvalid;
13835 if (BodyLineInvalid)
13839 if (StmtLine != BodyLine)
13854 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13863 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13867 const Stmt *PossibleBody) {
13873 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
13874 StmtLoc = FS->getRParenLoc();
13875 Body = FS->getBody();
13876 DiagID = diag::warn_empty_for_body;
13877 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
13878 StmtLoc = WS->getRParenLoc();
13879 Body = WS->getBody();
13880 DiagID = diag::warn_empty_while_body;
13885 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13908 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
13909 if (!ProbableTypo) {
13910 bool BodyColInvalid;
13913 if (BodyColInvalid)
13916 bool StmtColInvalid;
13919 if (StmtColInvalid)
13922 if (BodyCol > StmtCol)
13923 ProbableTypo =
true;
13926 if (ProbableTypo) {
13928 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13936 if (
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
13948 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
13950 RHSExpr = CE->
getArg(0);
13951 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
13952 CXXSCE && CXXSCE->isXValue())
13953 RHSExpr = CXXSCE->getSubExpr();
13957 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
13958 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
13961 if (LHSDeclRef && RHSDeclRef) {
13968 auto D =
Diag(OpLoc, diag::warn_self_move)
13984 const Expr *LHSBase = LHSExpr;
13985 const Expr *RHSBase = RHSExpr;
13986 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
13987 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
13988 if (!LHSME || !RHSME)
13991 while (LHSME && RHSME) {
13998 LHSME = dyn_cast<MemberExpr>(LHSBase);
13999 RHSME = dyn_cast<MemberExpr>(RHSBase);
14002 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
14003 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
14004 if (LHSDeclRef && RHSDeclRef) {
14011 Diag(OpLoc, diag::warn_self_move)
14017 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
14018 Diag(OpLoc, diag::warn_self_move)
14042 bool AreUnionMembers =
false) {
14043 [[maybe_unused]]
const Type *Field1Parent =
14045 [[maybe_unused]]
const Type *Field2Parent =
14050 "Can't evaluate layout compatibility between a struct field and a "
14053 (AreUnionMembers && Field1Parent->
isUnionType())) &&
14054 "AreUnionMembers should be 'true' for union fields (only).");
14067 if (Bits1 != Bits2)
14071 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
14072 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
14075 if (!AreUnionMembers &&
14087 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
14088 RD1 = D1CXX->getStandardLayoutBaseWithFields();
14090 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
14091 RD2 = D2CXX->getStandardLayoutBaseWithFields();
14096 return isLayoutCompatible(C, F1, F2);
14105 for (
auto *Field2 : RD2->
fields())
14106 UnmatchedFields.insert(Field2);
14108 for (
auto *Field1 : RD1->
fields()) {
14109 auto I = UnmatchedFields.begin();
14110 auto E = UnmatchedFields.end();
14112 for ( ; I !=
E; ++I) {
14114 bool Result = UnmatchedFields.erase(*I);
14124 return UnmatchedFields.empty();
14150 if (
C.hasSameType(T1, T2))
14159 if (TC1 == Type::Enum) {
14161 cast<EnumType>(T1)->getDecl(),
14162 cast<EnumType>(T2)->getDecl());
14163 }
else if (TC1 == Type::Record) {
14168 cast<RecordType>(T1)->getDecl(),
14169 cast<RecordType>(T2)->getDecl());
14183 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
14214 const ValueDecl **VD, uint64_t *MagicValue,
14215 bool isConstantEvaluated) {
14223 case Stmt::UnaryOperatorClass: {
14232 case Stmt::DeclRefExprClass: {
14233 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
14238 case Stmt::IntegerLiteralClass: {
14240 llvm::APInt MagicValueAPInt = IL->
getValue();
14241 if (MagicValueAPInt.getActiveBits() <= 64) {
14242 *MagicValue = MagicValueAPInt.getZExtValue();
14248 case Stmt::BinaryConditionalOperatorClass:
14249 case Stmt::ConditionalOperatorClass: {
14251 cast<AbstractConditionalOperator>(TypeExpr);
14254 isConstantEvaluated)) {
14264 case Stmt::BinaryOperatorClass: {
14267 TypeExpr = BO->
getRHS();
14297 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
14300 bool isConstantEvaluated) {
14301 FoundWrongKind =
false;
14306 uint64_t MagicValue;
14308 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
14312 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
14313 if (I->getArgumentKind() != ArgumentKind) {
14314 FoundWrongKind =
true;
14317 TypeInfo.Type = I->getMatchingCType();
14318 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
14319 TypeInfo.MustBeNull = I->getMustBeNull();
14330 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
14331 if (I == MagicValues->end())
14340 bool LayoutCompatible,
14342 if (!TypeTagForDatatypeMagicValues)
14343 TypeTagForDatatypeMagicValues.reset(
14344 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
14347 (*TypeTagForDatatypeMagicValues)[Magic] =
14363 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
14364 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
14365 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
14366 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
14369void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
14373 bool IsPointerAttr =
Attr->getIsPointer();
14376 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
14377 if (TypeTagIdxAST >= ExprArgs.size()) {
14378 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14379 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
14382 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
14383 bool FoundWrongKind;
14386 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
14388 if (FoundWrongKind)
14390 diag::warn_type_tag_for_datatype_wrong_kind)
14396 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
14397 if (ArgumentIdxAST >= ExprArgs.size()) {
14398 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14399 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
14402 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
14403 if (IsPointerAttr) {
14405 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
14406 if (ICE->getType()->isVoidPointerType() &&
14407 ICE->getCastKind() == CK_BitCast)
14408 ArgumentExpr = ICE->getSubExpr();
14421 diag::warn_type_safety_null_pointer_required)
14433 bool mismatch =
false;
14456 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
14457 << ArgumentType << ArgumentKind
14458 <<
TypeInfo.LayoutCompatible << RequiredType
14465 MisalignedMembers.emplace_back(
E, RD, MD, Alignment);
14469 for (MisalignedMember &m : MisalignedMembers) {
14475 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
14478 MisalignedMembers.clear();
14485 if (isa<UnaryOperator>(
E) &&
14486 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
14487 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
14488 if (isa<MemberExpr>(Op)) {
14489 auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
14490 if (MA != MisalignedMembers.end() &&
14495 MisalignedMembers.erase(MA);
14504 const auto *ME = dyn_cast<MemberExpr>(
E);
14516 bool AnyIsPacked =
false;
14518 QualType BaseType = ME->getBase()->getType();
14528 auto *FD = dyn_cast<FieldDecl>(MD);
14534 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
14535 ReverseMemberChain.push_back(FD);
14538 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
14540 assert(TopME &&
"We did not compute a topmost MemberExpr!");
14547 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
14551 if (!DRE && !isa<CXXThisExpr>(TopBase))
14558 if (ExpectedAlignment.
isOne())
14563 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
14568 ReverseMemberChain.back()->getParent()->getTypeForDecl());
14572 if (DRE && !TopME->
isArrow()) {
14575 CompleteObjectAlignment =
14580 if (Offset % ExpectedAlignment != 0 ||
14583 CompleteObjectAlignment < ExpectedAlignment) {
14594 for (
FieldDecl *FDI : ReverseMemberChain) {
14595 if (FDI->hasAttr<PackedAttr>() ||
14596 FDI->getParent()->hasAttr<PackedAttr>()) {
14598 Alignment = std::min(
14604 assert(FD &&
"We did not find a packed FieldDecl!");
14609void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
14610 using namespace std::placeholders;
14613 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
14635bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
bool FPOnly) {
14649 TheCall->
setType(VecTy0->getElementType());
14673 diag::err_typecheck_call_different_arg_types)
14690 bool CheckForFloatArgs) {
14695 for (
int I = 0; I < 3; ++I) {
14699 Args[I] = Converted.
get();
14702 if (CheckForFloatArgs) {
14703 int ArgOrdinal = 1;
14704 for (
Expr *Arg : Args) {
14706 Arg->
getType(), ArgOrdinal++))
14710 int ArgOrdinal = 1;
14711 for (
Expr *Arg : Args) {
14718 for (
int I = 1; I < 3; ++I) {
14719 if (Args[0]->getType().getCanonicalType() !=
14720 Args[I]->getType().getCanonicalType()) {
14721 return Diag(Args[0]->getBeginLoc(),
14722 diag::err_typecheck_call_different_arg_types)
14726 TheCall->
setArg(I, Args[I]);
14729 TheCall->
setType(Args[0]->getType());
14733bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
14745bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
14754 << 1 << 0 << TyArg;
14768 Expr *Matrix = MatrixArg.
get();
14773 << 1 << 1 << Matrix->
getType();
14780 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
14783 TheCall->
setType(ResultType);
14786 TheCall->
setArg(0, Matrix);
14791static std::optional<unsigned>
14794 std::optional<llvm::APSInt>
Value =
14801 uint64_t
Dim =
Value->getZExtValue();
14820 unsigned PtrArgIdx = 0;
14826 bool ArgError =
false;
14833 PtrExpr = PtrConv.
get();
14834 TheCall->
setArg(0, PtrExpr);
14845 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14852 << PtrArgIdx + 1 << 2
14859 auto ApplyArgumentConversions = [
this](
Expr *
E) {
14868 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
14870 RowsExpr = RowsConv.
get();
14871 TheCall->
setArg(1, RowsExpr);
14873 RowsExpr =
nullptr;
14875 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
14877 ColumnsExpr = ColumnsConv.
get();
14878 TheCall->
setArg(2, ColumnsExpr);
14880 ColumnsExpr =
nullptr;
14891 std::optional<unsigned> MaybeRows;
14895 std::optional<unsigned> MaybeColumns;
14900 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
14903 StrideExpr = StrideConv.
get();
14904 TheCall->
setArg(3, StrideExpr);
14907 if (std::optional<llvm::APSInt>
Value =
14910 if (Stride < *MaybeRows) {
14912 diag::err_builtin_matrix_stride_too_small);
14918 if (ArgError || !MaybeRows || !MaybeColumns)
14931 unsigned PtrArgIdx = 1;
14936 bool ArgError =
false;
14942 MatrixExpr = MatrixConv.
get();
14943 TheCall->
setArg(0, MatrixExpr);
14953 << 1 << 1 << MatrixExpr->
getType();
14961 PtrExpr = PtrConv.
get();
14962 TheCall->
setArg(1, PtrExpr);
14973 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14978 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
14985 diag::err_builtin_matrix_pointer_arg_mismatch)
14986 << ElementTy << MatrixTy->getElementType();
15001 StrideExpr = StrideConv.
get();
15002 TheCall->
setArg(2, StrideExpr);
15007 if (std::optional<llvm::APSInt>
Value =
15010 if (Stride < MatrixTy->getNumRows()) {
15012 diag::err_builtin_matrix_stride_too_small);
15032 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
15037 llvm::StringSet<> CalleeTCBs;
15038 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
15039 CalleeTCBs.insert(A->getTCBName());
15040 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
15041 CalleeTCBs.insert(A->getTCBName());
15045 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
15046 StringRef CallerTCB = A->getTCBName();
15047 if (CalleeTCBs.count(CallerTCB) == 0) {
15048 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
15049 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, bool inFunctionCall, Sema::VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, Sema::VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)
static IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth)
static bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool)
static void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool pruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, SourceLocation CC)
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool isKnownToHaveUnsignedValue(Expr *E)
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool IsSameCharType(QualType T1, QualType T2)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)
static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static int classifyConstantValue(Expr *Constant)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)
static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)
static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)
static bool referToTheSameDecl(const Expr *E1, const Expr *E2)
Check if two expressions refer to the same declaration.
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static bool requiresParensToAddCast(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool IsEnumConstOrFromMacro(Sema &S, Expr *E)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static bool HasEnumType(Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)
Compute the alignment and offset of a binary additive operator.
static bool checkFPMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)
static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis 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.
const NestedNameSpecifier * Specifier
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible SVE vector types, false otherwise.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
bool areCompatibleRVVTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an RISC-V vector builtin type and a VectorType that is a fixed-len...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
QualType getRecordType(const RecordDecl *Decl) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
bool areLaxCompatibleRVVTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible RISC-V vector types as defined by -flax-vect...
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const
Compare the rank of two floating point types as above, but compare equal if both types have the same ...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
const TargetInfo * getAuxTargetInfo() const
llvm::APFixedPoint getFixedPointMin(QualType Ty) const
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
TypeInfoChars getTypeInfoInChars(const Type *T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getExceptionObjectType(QualType T) const
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const
Return the type for the specified builtin.
CanQualType UnsignedShortTy
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const
Return a string representing the human readable name for the specified function declaration or file n...
llvm::APFixedPoint getFixedPointMax(QualType Ty) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
bool areCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an SVE builtin and a VectorType that is a fixed-length representat...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
CanQualType getNSIntegerType() const
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
QualType getTypedefType(const TypedefNameDecl *Decl, QualType Underlying=QualType()) const
Return the unique reference to the type for the specified typedef-name decl.
QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const
Return the unique reference to the matrix type of the specified element type and size.
CanQualType getNSUIntegerType() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
std::unique_ptr< AtomicScopeModel > getScopeModel() const
Get atomic scope model.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
ConceptDecl * getTypeConstraintConcept() const
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getExprLoc() const
bool isEqualityOp() const
static bool isAdditiveOp(Opcode Opc)
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
bool isAuxBuiltinID(unsigned ID) const
Return true if builtin ID belongs to AuxTarget.
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
llvm::StringRef getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
bool isTSBuiltin(unsigned ID) const
Return true if this function is a target-specific builtin.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
ArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isDynamicClass() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getRParenLoc() const
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
void setExprNeedsCleanups(bool SideEffects)
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
Declaration of a C++20 concept.
ConditionalOperator - The ?: ternary operator.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
Represents a concrete matrix type with constant number of rows and columns.
static constexpr unsigned getMaxElementsPerDimension()
Returns the maximum number of elements per dimension.
static constexpr bool isDimensionValid(size_t NumElements)
Returns true if NumElements is a valid matrix dimension.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents an expression that might suspend coroutine execution; either a co_await or co_yield expres...
Expr * getOperand() const
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
DynamicCountPointerKind getKind() const
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
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.
SourceLocation getBeginLoc() const LLVM_READONLY
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
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.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
unsigned getNumNegativeBits() const
Returns the width in bits required to store all the negative enumerators of this enum.
bool isComplete() const
Returns true if this can be considered a complete type.
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
unsigned getNumPositiveBits() const
Returns the width in bits required to store all the non-negative enumerators of this enum.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_NoSideEffects
Strictly evaluate the expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isFlexibleArrayMemberLike(ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
const FieldDecl * findCountedByField() const
Find the FieldDecl specified in a FAM's "counted_by" attribute.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to call this function.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isValidElementType(QualType T)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstant(const ASTContext &Ctx) const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Scope - A scope is a transient data structure that is used while parsing the program.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
bool isSignedCharBool(QualType Ty)
void adornBoolConversionDiagWithTernaryFixit(Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
Scope * getCurScope() const
Retrieve the parser's current scope.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
bool BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI)
Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo parameter with the Format...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
DiagnosticsEngine & getDiagnostics() const
static FormatStringType GetFormatStringType(const FormatAttr *Format)
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall)
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
void pushCodeSynthesisContext(CodeSynthesisContext Ctx)
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
@ ACK_Comparison
A comparison.
bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, bool CheckForFloatArgs=true)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
bool isConstantEvaluatedContext() const
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
SourceManager & SourceMgr
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
bool BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly=false)
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const
Returns true if the spelling locations for both SourceLocations are part of the same file buffer.
unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
Exposes information about the current target.
virtual bool validatePointerAuthKey(const llvm::APSInt &value) const
Determine whether the given pointer-authentication key is valid.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
virtual bool supportsCpuInit() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const llvm::fltSemantics & getLongDoubleFormat() const
virtual bool checkArithmeticFenceSupported() const
Controls if __arithmetic_fence is supported in the targeted backend.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
virtual bool hasSjLjLowering() const
Controls if __builtin_longjmp / __builtin_setjmp can be lowered to llvm.eh.sjlj.longjmp / llvm....
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
const Type * getTypeForDecl() const
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
bool isBooleanType() const
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isFloat16Type() const
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
The iterator over UnresolvedSets.
A set of unresolved declarations.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
WhileStmt - This represents a 'while' stmt.
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
Defines the clang::TargetInfo interface.
__inline void unsigned int _2
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
ComparisonResult
Indicates the result of a tentative comparison.
uint32_t Literal
Literals are represented as positive integers.
@ After
Like System, but searched after the system directories.
@ FixIt
Parse and apply any fixits to the source.
bool GT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool InRange(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Result
The result type of a method or function.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
ActionResult< ParsedType > TypeResult
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
const FunctionProtoType * T
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Success
Template argument deduction was successful.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
Describes how types, statements, expressions, and declarations should be printed.
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned Indentation
The number of spaces to use to indent each line.
A context in which code is being synthesized (where a source location alone is not sufficient to iden...
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.