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());
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(S.
Context));
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");
8461 bool IsNaNOrIsUnordered =
8465 if ((IsNaNOrIsUnordered || IsSpecialNaN) && FPO.getNoHonorNaNs()) {
8466 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8467 << 1 << 0 <<
Call->getSourceRange();
8469 bool IsInfOrIsFinite =
8471 bool IsInfinityOrIsSpecialInf =
8472 HasIdentifier && ((FDecl->
getName() ==
"infinity") ||
8474 if ((IsInfOrIsFinite || IsInfinityOrIsSpecialInf) && FPO.getNoHonorInfs())
8475 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8476 << 0 << 0 <<
Call->getSourceRange();
8480void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
8482 if (
Call->getNumArgs() != 1)
8487 if (AbsKind == 0 && !IsStdAbs)
8490 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8496 StringRef FunctionName =
8498 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
8499 Diag(
Call->getExprLoc(), diag::note_remove_abs)
8508 unsigned DiagType = 0;
8514 Diag(
Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
8528 if (ArgValueKind == ParamValueKind) {
8533 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
8534 << FDecl << ArgType << ParamType;
8536 if (NewAbsKind == 0)
8540 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8549 if (NewAbsKind == 0)
8552 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
8553 << FDecl << ParamValueKind << ArgValueKind;
8556 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8562 if (!
Call || !FDecl)
return;
8566 if (
Call->getExprLoc().isMacroID())
return;
8569 if (
Call->getNumArgs() != 2)
return;
8572 if (!ArgList)
return;
8573 if (ArgList->size() != 1)
return;
8576 const auto& TA = ArgList->
get(0);
8582 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
8583 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
8584 if (!MTE)
return false;
8585 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
8586 if (!
Num)
return false;
8587 if (
Num->getValue() != 0)
return false;
8591 const Expr *FirstArg =
Call->getArg(0);
8592 const Expr *SecondArg =
Call->getArg(1);
8593 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
8594 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
8597 if (IsFirstArgZero == IsSecondArgZero)
return;
8602 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
8604 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
8605 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
8609 if (IsFirstArgZero) {
8617 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
8637 if (!Size->isComparisonOp() && !Size->isLogicalOp())
8641 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
8642 << SizeRange << FnName;
8643 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
8648 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
8659 bool &IsContained) {
8662 IsContained =
false;
8675 for (
auto *FD : RD->
fields()) {
8688 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
8689 if (Unary->getKind() == UETT_SizeOf)
8698 if (!
SizeOf->isArgumentType())
8699 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
8706 return SizeOf->getTypeOfArgument();
8712struct SearchNonTrivialToInitializeField
8717 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8721 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8722 asDerived().visitArray(PDIK, AT, SL);
8726 Super::visitWithKind(PDIK, FT, SL);
8741 visit(getContext().getBaseElementType(AT), SL);
8746 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
8755struct SearchNonTrivialToCopyField
8759 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8763 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8764 asDerived().visitArray(PCK, AT, SL);
8768 Super::visitWithKind(PCK, FT, SL);
8783 visit(getContext().getBaseElementType(AT), SL);
8806 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
8807 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
8831 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
8833 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
8834 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
8840 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
8843 const Expr *SizeArg =
8844 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
8846 auto isLiteralZero = [](
const Expr *
E) {
8847 return (isa<IntegerLiteral>(
E) &&
8848 cast<IntegerLiteral>(
E)->getValue() == 0) ||
8849 (isa<CharacterLiteral>(
E) &&
8850 cast<CharacterLiteral>(
E)->getValue() == 0);
8856 if (isLiteralZero(SizeArg) &&
8863 if (BId == Builtin::BIbzero ||
8866 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
8867 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
8868 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
8869 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
8870 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
8878 if (BId == Builtin::BImemset &&
8882 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
8883 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
8888void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
8895 unsigned ExpectedNumArgs =
8896 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
8897 if (
Call->getNumArgs() < ExpectedNumArgs)
8900 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
8901 BId == Builtin::BIstrndup ? 1 : 2);
8903 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
8904 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
8907 Call->getBeginLoc(),
Call->getRParenLoc()))
8916 llvm::FoldingSetNodeID SizeOfArgID;
8921 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8925 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
8926 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
8948 if (SizeOfArgID == llvm::FoldingSetNodeID())
8950 llvm::FoldingSetNodeID DestID;
8952 if (DestID == SizeOfArgID) {
8955 unsigned ActionIdx = 0;
8956 StringRef ReadableName = FnName->
getName();
8958 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
8959 if (UnaryOp->getOpcode() == UO_AddrOf)
8973 if (
SM.isMacroArgExpansion(SL)) {
8975 SL =
SM.getSpellingLoc(SL);
8983 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
8990 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
9005 PDiag(diag::warn_sizeof_pointer_type_memaccess)
9006 << FnName << SizeOfArgTy << ArgIdx
9024 unsigned OperationType = 0;
9025 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
9028 if (ArgIdx != 0 || IsCmp) {
9029 if (BId == Builtin::BImemcpy)
9031 else if(BId == Builtin::BImemmove)
9038 PDiag(diag::warn_dyn_class_memaccess)
9039 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
9040 << IsContained << ContainedRD << OperationType
9041 <<
Call->getCallee()->getSourceRange());
9043 BId != Builtin::BImemset)
9046 PDiag(diag::warn_arc_object_memaccess)
9047 << ArgIdx << FnName << PointeeTy
9048 <<
Call->getCallee()->getSourceRange());
9055 bool MayBeTriviallyCopyableCXXRecord =
9057 RT->desugar().isTriviallyCopyableType(
Context);
9059 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9060 RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
9062 PDiag(diag::warn_cstruct_memaccess)
9063 << ArgIdx << FnName << PointeeTy << 0);
9064 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
9065 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9066 !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9070 PDiag(diag::warn_cxxstruct_memaccess)
9071 << FnName << PointeeTy);
9072 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9073 RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
9075 PDiag(diag::warn_cstruct_memaccess)
9076 << ArgIdx << FnName << PointeeTy << 1);
9077 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
9078 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9079 !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9083 PDiag(diag::warn_cxxstruct_memaccess)
9084 << FnName << PointeeTy);
9093 PDiag(diag::note_bad_memaccess_silence)
9113 if (isa<IntegerLiteral>(RHS))
9115 else if (isa<IntegerLiteral>(LHS))
9129 if (CAT->getZExtSize() <= 1)
9137void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
9141 unsigned NumArgs =
Call->getNumArgs();
9142 if ((NumArgs != 3) && (NumArgs != 4))
9147 const Expr *CompareWithSrc =
nullptr;
9150 Call->getBeginLoc(),
Call->getRParenLoc()))
9155 CompareWithSrc = Ex;
9158 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
9159 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
9160 SizeCall->getNumArgs() == 1)
9165 if (!CompareWithSrc)
9172 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
9176 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
9177 if (!CompareWithSrcDRE ||
9181 const Expr *OriginalSizeArg =
Call->getArg(2);
9182 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
9189 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
9194 llvm::raw_svector_ostream
OS(sizeString);
9199 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
9206 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
9207 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
9208 return D1->getDecl() == D2->getDecl();
9213 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
9222void Sema::CheckStrncatArguments(
const CallExpr *CE,
9237 unsigned PatternType = 0;
9245 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
9246 if (BE->getOpcode() == BO_Sub) {
9259 if (PatternType == 0)
9268 if (
SM.isMacroArgExpansion(SL)) {
9269 SL =
SM.getSpellingLoc(SL);
9278 if (!isKnownSizeArray) {
9279 if (PatternType == 1)
9280 Diag(SL, diag::warn_strncat_wrong_size) << SR;
9282 Diag(SL, diag::warn_strncat_src_size) << SR;
9286 if (PatternType == 1)
9287 Diag(SL, diag::warn_strncat_large_size) << SR;
9289 Diag(SL, diag::warn_strncat_src_size) << SR;
9292 llvm::raw_svector_ostream
OS(sizeString);
9300 Diag(SL, diag::note_strncat_wrong_size)
9305void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
9307 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
9309 << CalleeName << 0 << cast<NamedDecl>(
D);
9314void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
9316 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
9317 const Decl *
D = Lvalue->getDecl();
9318 if (isa<DeclaratorDecl>(
D))
9319 if (!dyn_cast<DeclaratorDecl>(
D)->getType()->isReferenceType())
9320 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
9323 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
9324 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
9325 Lvalue->getMemberDecl());
9328void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
9330 const auto *Lambda = dyn_cast<LambdaExpr>(
9335 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
9336 << CalleeName << 2 ;
9339void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
9341 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
9346 << CalleeName << 0 << Var;
9349void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
9352 llvm::raw_svector_ostream OS(SizeString);
9355 if (Kind == clang::CK_BitCast &&
9356 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
9358 if (Kind == clang::CK_IntegralToPointer &&
9359 !isa<IntegerLiteral>(
9360 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
9363 switch (
Cast->getCastKind()) {
9364 case clang::CK_BitCast:
9365 case clang::CK_IntegralToPointer:
9366 case clang::CK_FunctionToPointerDecay:
9375 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
9376 << CalleeName << 0 << OS.str();
9380void Sema::CheckFreeArguments(
const CallExpr *
E) {
9381 const std::string CalleeName =
9382 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
9386 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
9388 case UnaryOperator::Opcode::UO_AddrOf:
9389 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
9390 case UnaryOperator::Opcode::UO_Plus:
9391 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
9396 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
9398 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
9400 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
9401 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
9402 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
9406 if (isa<BlockExpr>(Arg)) {
9408 << CalleeName << 1 ;
9413 if (
const auto *Cast = dyn_cast<CastExpr>(
E->getArg(0)))
9414 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
9418Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
9424 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
9427 Diag(ReturnLoc, diag::warn_null_ret)
9437 if (Op == OO_New || Op == OO_Array_New) {
9442 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
9448 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
9465 auto getCastAndLiteral = [&FPLiteral, &FPCast](
Expr *L,
Expr *R) {
9466 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
9468 return FPLiteral && FPCast;
9471 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
9477 llvm::APFloat TargetC = FPLiteral->
getValue();
9479 llvm::APFloat::rmNearestTiesToEven, &Lossy);
9483 Diag(
Loc, diag::warn_float_compare_literal)
9484 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
9497 if (
auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
9498 if (
auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
9499 if (DRL->getDecl() == DRR->getDecl())
9507 if (
FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
9511 if (
FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
9516 if (
CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
9517 if (CL->getBuiltinCallee())
9520 if (
CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
9521 if (CR->getBuiltinCallee())
9525 Diag(
Loc, diag::warn_floatingpoint_eq)
9546 IntRange(
unsigned Width,
bool NonNegative)
9547 : Width(Width), NonNegative(NonNegative) {}
9550 unsigned valueBits()
const {
9551 return NonNegative ? Width : Width - 1;
9555 static IntRange forBoolType() {
9556 return IntRange(1,
true);
9561 return forValueOfCanonicalType(
C,
9569 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9570 T = VT->getElementType().getTypePtr();
9572 T = CT->getElementType().getTypePtr();
9573 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9574 T = AT->getValueType().getTypePtr();
9576 if (!
C.getLangOpts().CPlusPlus) {
9578 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9579 T = ET->getDecl()->getIntegerType().getDesugaredType(
C).getTypePtr();
9580 }
else if (
const EnumType *ET = dyn_cast<EnumType>(
T)) {
9585 if (
Enum->isFixed()) {
9586 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
9587 !ET->isSignedIntegerOrEnumerationType());
9590 unsigned NumPositive =
Enum->getNumPositiveBits();
9591 unsigned NumNegative =
Enum->getNumNegativeBits();
9593 if (NumNegative == 0)
9594 return IntRange(NumPositive,
true);
9596 return IntRange(std::max(NumPositive + 1, NumNegative),
9600 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9601 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9617 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9618 T = VT->getElementType().getTypePtr();
9620 T = CT->getElementType().getTypePtr();
9621 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9622 T = AT->getValueType().getTypePtr();
9623 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9624 T =
C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
9626 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9627 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9636 static IntRange join(IntRange L, IntRange R) {
9637 bool Unsigned = L.NonNegative && R.NonNegative;
9638 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
9639 L.NonNegative && R.NonNegative);
9643 static IntRange bit_and(IntRange L, IntRange R) {
9644 unsigned Bits = std::max(L.Width, R.Width);
9645 bool NonNegative =
false;
9646 if (L.NonNegative) {
9647 Bits = std::min(Bits, L.Width);
9650 if (R.NonNegative) {
9651 Bits = std::min(Bits, R.Width);
9654 return IntRange(Bits, NonNegative);
9658 static IntRange sum(IntRange L, IntRange R) {
9659 bool Unsigned = L.NonNegative && R.NonNegative;
9660 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
9665 static IntRange difference(IntRange L, IntRange R) {
9669 bool CanWiden = !L.NonNegative || !R.NonNegative;
9670 bool Unsigned = L.NonNegative && R.Width == 0;
9671 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
9677 static IntRange product(IntRange L, IntRange R) {
9681 bool CanWiden = !L.NonNegative && !R.NonNegative;
9682 bool Unsigned = L.NonNegative && R.NonNegative;
9683 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
9688 static IntRange rem(IntRange L, IntRange R) {
9692 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
9700 unsigned MaxWidth) {
9701 if (value.isSigned() && value.isNegative())
9702 return IntRange(value.getSignificantBits(),
false);
9704 if (value.getBitWidth() > MaxWidth)
9705 value = value.trunc(MaxWidth);
9709 return IntRange(value.getActiveBits(),
true);
9713 unsigned MaxWidth) {
9721 R = IntRange::join(R, El);
9729 return IntRange::join(R, I);
9744 Ty = AtomicRHS->getValueType();
9763 bool InConstantContext,
9775 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
9776 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
9780 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
9782 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
9783 CE->getCastKind() == CK_BooleanToSignedIntegral;
9787 return OutputTypeRange;
9790 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
9791 InConstantContext, Approximate);
9793 return std::nullopt;
9796 if (SubRange->Width >= OutputTypeRange.Width)
9797 return OutputTypeRange;
9801 return IntRange(SubRange->Width,
9802 SubRange->NonNegative || OutputTypeRange.NonNegative);
9805 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
9808 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
9810 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
9811 InConstantContext, Approximate);
9816 Expr *TrueExpr = CO->getTrueExpr();
9818 return std::nullopt;
9820 std::optional<IntRange> L =
9823 return std::nullopt;
9825 Expr *FalseExpr = CO->getFalseExpr();
9827 return std::nullopt;
9829 std::optional<IntRange> R =
9832 return std::nullopt;
9834 return IntRange::join(*L, *R);
9837 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
9838 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
9840 switch (BO->getOpcode()) {
9842 llvm_unreachable(
"builtin <=> should have class type");
9853 return IntRange::forBoolType();
9882 Combine = IntRange::bit_and;
9890 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
9891 if (I->getValue() == 1) {
9893 return IntRange(R.Width,
true);
9903 case BO_ShrAssign: {
9905 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
9907 return std::nullopt;
9911 if (std::optional<llvm::APSInt> shift =
9912 BO->getRHS()->getIntegerConstantExpr(
C)) {
9913 if (shift->isNonNegative()) {
9914 if (shift->uge(L->Width))
9915 L->Width = (L->NonNegative ? 0 : 1);
9917 L->Width -= shift->getZExtValue();
9931 Combine = IntRange::sum;
9935 if (BO->getLHS()->getType()->isPointerType())
9938 Combine = IntRange::difference;
9943 Combine = IntRange::product;
9952 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
9954 return std::nullopt;
9957 if (std::optional<llvm::APSInt> divisor =
9958 BO->getRHS()->getIntegerConstantExpr(
C)) {
9959 unsigned log2 = divisor->logBase2();
9960 if (
log2 >= L->Width)
9961 L->Width = (L->NonNegative ? 0 : 1);
9963 L->Width = std::min(L->Width -
log2, MaxWidth);
9971 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
9973 return std::nullopt;
9975 return IntRange(L->Width, L->NonNegative && R->NonNegative);
9979 Combine = IntRange::rem;
9991 unsigned opWidth =
C.getIntWidth(
T);
9993 InConstantContext, Approximate);
9995 return std::nullopt;
9998 InConstantContext, Approximate);
10000 return std::nullopt;
10002 IntRange
C = Combine(*L, *R);
10004 C.Width = std::min(
C.Width, MaxWidth);
10008 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
10009 switch (UO->getOpcode()) {
10012 return IntRange::forBoolType();
10025 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
10026 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
10030 return IntRange(BitField->getBitWidthValue(
C),
10031 BitField->getType()->isUnsignedIntegerOrEnumerationType());
10034 return std::nullopt;
10040 bool InConstantContext,
10041 bool Approximate) {
10050 const llvm::fltSemantics &Src,
10051 const llvm::fltSemantics &Tgt) {
10052 llvm::APFloat truncated = value;
10055 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
10056 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
10058 return truncated.bitwiseIsEqual(value);
10067 const llvm::fltSemantics &Src,
10068 const llvm::fltSemantics &Tgt) {
10085 bool IsListInit =
false);
10091 if (isa<EnumConstantDecl>(DR->getDecl()))
10101 return MacroName !=
"YES" && MacroName !=
"NO" &&
10102 MacroName !=
"true" && MacroName !=
"false";
10125struct PromotedRange {
10127 llvm::APSInt PromotedMin;
10129 llvm::APSInt PromotedMax;
10131 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
10133 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
10134 else if (R.Width >= BitWidth && !
Unsigned) {
10138 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
10139 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
10141 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
10142 .extOrTrunc(BitWidth);
10143 PromotedMin.setIsUnsigned(
Unsigned);
10145 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
10146 .extOrTrunc(BitWidth);
10147 PromotedMax.setIsUnsigned(
Unsigned);
10152 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
10162 InRangeFlag = 0x40,
10165 Min =
LE | InRangeFlag,
10167 Max =
GE | InRangeFlag,
10170 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
10175 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
10176 Value.isUnsigned() == PromotedMin.isUnsigned());
10177 if (!isContiguous()) {
10178 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
10179 if (
Value.isMinValue())
return Min;
10180 if (
Value.isMaxValue())
return Max;
10186 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
10187 case -1:
return Less;
10188 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
10190 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
10192 case 0:
return Max;
10197 llvm_unreachable(
"impossible compare result");
10200 static std::optional<StringRef>
10202 if (Op == BO_Cmp) {
10204 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
10206 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
10207 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
10208 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
10209 return std::nullopt;
10216 }
else if (Op == BO_NE) {
10220 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
10227 if (Op == BO_GE || Op == BO_LE)
10228 std::swap(TrueFlag, FalseFlag);
10231 return StringRef(
"true");
10233 return StringRef(
"false");
10234 return std::nullopt;
10242 if (ICE->getCastKind() != CK_IntegralCast &&
10243 ICE->getCastKind() != CK_NoOp)
10245 E = ICE->getSubExpr();
10254 enum ConstantValueKind {
10259 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
10260 return BL->getValue() ? ConstantValueKind::LiteralTrue
10261 : ConstantValueKind::LiteralFalse;
10262 return ConstantValueKind::Miscellaneous;
10267 const llvm::APSInt &
Value,
10268 bool RhsConstant) {
10290 if (!OtherValueRange)
10295 OtherT = AT->getValueType();
10296 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
10300 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
10306 bool OtherIsBooleanDespiteType =
10308 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
10309 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
10313 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
10314 Value.isUnsigned());
10315 auto Cmp = OtherPromotedValueRange.compare(
Value);
10316 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
10322 bool TautologicalTypeCompare =
false;
10324 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
10325 Value.isUnsigned());
10326 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
10327 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
10329 TautologicalTypeCompare =
true;
10337 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
10346 bool InRange = Cmp & PromotedRange::InRangeFlag;
10352 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
10353 Other->getType()->isUnsignedIntegerOrEnumerationType())
10354 TautologicalTypeCompare =
true;
10359 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant))
10360 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
10364 llvm::raw_svector_ostream OS(PrettySourceValue);
10366 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
10367 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
10369 OS << (BL->getValue() ?
"YES" :
"NO");
10374 if (!TautologicalTypeCompare) {
10375 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
10376 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
10377 <<
E->getOpcodeStr() << OS.str() << *
Result
10382 if (IsObjCSignedCharBool) {
10384 S.
PDiag(diag::warn_tautological_compare_objc_bool)
10385 << OS.str() << *
Result);
10392 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
10395 E->getOperatorLoc(),
E,
10396 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
10397 : diag::warn_tautological_bool_compare)
10399 << OtherIsBooleanDespiteType << *
Result
10406 ? diag::warn_unsigned_enum_always_true_comparison
10407 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
10408 : diag::warn_unsigned_always_true_comparison)
10409 : diag::warn_tautological_constant_compare;
10412 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result
10442 Expr *LHS =
E->getLHS();
10443 Expr *RHS =
E->getRHS();
10446 std::optional<llvm::APSInt> RHSValue =
10448 std::optional<llvm::APSInt> LHSValue =
10452 if (RHSValue && LHSValue)
10456 if ((
bool)RHSValue ^ (
bool)LHSValue) {
10458 const bool RhsConstant = (
bool)RHSValue;
10459 Expr *Const = RhsConstant ? RHS : LHS;
10461 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
10484 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
10486 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
10492 Expr *signedOperand, *unsignedOperand;
10495 "unsigned comparison between two signed integer expressions?");
10496 signedOperand = LHS;
10497 unsignedOperand = RHS;
10499 signedOperand = RHS;
10500 unsignedOperand = LHS;
10506 std::optional<IntRange> signedRange =
10518 if (signedRange->NonNegative)
10525 if (
E->isEqualityOp()) {
10530 if (!unsignedRange)
10535 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
10537 if (unsignedRange->Width < comparisonWidth)
10542 S.
PDiag(diag::warn_mixed_sign_comparison)
10570 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
10571 << BitfieldEnumDecl;
10578 Init->isValueDependent() ||
10579 Init->isTypeDependent())
10582 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
10605 unsigned DiagID = 0;
10606 if (SignedEnum && !SignedBitfield) {
10607 DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
10608 }
else if (SignedBitfield && !SignedEnum &&
10610 DiagID = diag::warn_signed_bitfield_enum_conversion;
10614 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
10619 << SignedEnum << TypeRange;
10630 if (BitsNeeded > FieldWidth) {
10632 S.
Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
10644 unsigned OriginalWidth =
Value.getBitWidth();
10650 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
10651 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
10658 if (!
Value.isSigned() ||
Value.isNegative())
10659 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
10660 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
10661 OriginalWidth =
Value.getSignificantBits();
10663 if (OriginalWidth <= FieldWidth)
10667 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
10671 TruncatedValue = TruncatedValue.extend(OriginalWidth);
10672 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
10676 std::string PrettyTrunc =
toString(TruncatedValue, 10);
10678 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
10679 ? diag::warn_impcast_single_bit_bitield_precision_constant
10680 : diag::warn_impcast_bitfield_precision_constant)
10681 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
10682 <<
Init->getSourceRange();
10697 E->getOperatorLoc())) {
10700 E->getOperatorLoc());
10714 bool pruneControlFlow =
false) {
10715 if (pruneControlFlow) {
10729 unsigned diag,
bool pruneControlFlow =
false) {
10742 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
10745 const bool IsLiteral =
10746 isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
10748 llvm::APFloat
Value(0.0);
10754 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10759 diag::warn_impcast_float_integer, PruneWarnings);
10762 bool isExact =
false;
10766 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
10767 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
10775 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
10776 precision = (precision * 59 + 195) / 196;
10777 Value.toString(PrettySourceValue, precision);
10781 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10782 << PrettySourceValue);
10785 if (
Result == llvm::APFloat::opOK && isExact) {
10786 if (IsLiteral)
return;
10793 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
10796 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
10797 : diag::warn_impcast_float_to_integer_out_of_range,
10800 unsigned DiagID = 0;
10803 DiagID = diag::warn_impcast_literal_float_to_integer;
10804 }
else if (IntegerValue == 0) {
10805 if (
Value.isZero()) {
10807 diag::warn_impcast_float_integer, PruneWarnings);
10810 DiagID = diag::warn_impcast_float_to_integer_zero;
10812 if (IntegerValue.isUnsigned()) {
10813 if (!IntegerValue.isMaxValue()) {
10815 diag::warn_impcast_float_integer, PruneWarnings);
10818 if (!IntegerValue.isMaxSignedValue() &&
10819 !IntegerValue.isMinSignedValue()) {
10821 diag::warn_impcast_float_integer, PruneWarnings);
10825 DiagID = diag::warn_impcast_float_to_integer;
10830 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
10832 IntegerValue.toString(PrettyTargetValue);
10834 if (PruneWarnings) {
10837 <<
E->
getType() <<
T.getUnqualifiedType()
10838 << PrettySourceValue << PrettyTargetValue
10842 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
10850 assert(isa<CompoundAssignOperator>(
E) &&
10851 "Must be compound assignment operation");
10857 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
10861 const auto *RBT = cast<CompoundAssignOperator>(
E)
10862 ->getComputationResultType()
10869 if (ResultBT->isInteger())
10871 E->
getExprLoc(), diag::warn_impcast_float_integer);
10873 if (!ResultBT->isFloatingPoint())
10882 diag::warn_impcast_float_result_precision);
10887 if (!
Range.Width)
return "0";
10889 llvm::APSInt ValueInRange =
Value;
10890 ValueInRange.setIsSigned(!
Range.NonNegative);
10891 ValueInRange = ValueInRange.trunc(
Range.Width);
10892 return toString(ValueInRange, 10);
10896 if (!isa<ImplicitCastExpr>(Ex))
10901 const Type *Source =
10903 if (
Target->isDependentType())
10907 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
10908 const Type *BoolCandidateType = ToBool ?
Target : Source;
10917 for (
unsigned i = 0; i < NumArgs; ++i) {
10922 bool IsSwapped = ((i > 0) &&
10924 IsSwapped |= ((i < (NumArgs - 1)) &&
10930 diag::warn_impcast_floating_point_to_bool);
10937 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
10942 if (isa<CallExpr>(
E))
10947 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
10949 if (!IsGNUNullExpr && !HasNullPtrType)
10969 if (MacroName ==
"NULL")
10977 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
10991 const char FirstLiteralCharacter =
10993 if (FirstLiteralCharacter ==
'0')
11000 const char FirstContextCharacter =
11002 if (FirstContextCharacter ==
'{')
11010 const auto *IL = dyn_cast<IntegerLiteral>(
E);
11012 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
11013 if (UO->getOpcode() == UO_Minus)
11014 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
11025 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
11029 if (Opc == BO_Shl) {
11032 if (LHS && LHS->getValue() == 0)
11033 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
11035 RHS->getValue().isNonNegative() &&
11037 S.
Diag(ExprLoc, diag::warn_left_shift_always)
11038 << (
Result.Val.getInt() != 0);
11040 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context) <<
E;
11044 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
11049 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
11050 (RHS->getValue() == 0 || RHS->getValue() == 1))
11053 if (LHS->getValue() != 0 && RHS->getValue() != 0)
11054 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
11059 bool *ICContext,
bool IsListInit) {
11064 if (Source ==
Target)
return;
11065 if (
Target->isDependentType())
return;
11079 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
11080 if (isa<StringLiteral>(
E))
11085 diag::warn_impcast_string_literal_to_bool);
11086 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
11087 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
11091 diag::warn_impcast_objective_c_literal_to_bool);
11106 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
11108 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
11117 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
11119 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
11123 if (isa<VectorType>(Source)) {
11124 if (
Target->isSveVLSBuiltinType() &&
11131 if (
Target->isRVVVLSBuiltinType() &&
11138 if (!isa<VectorType>(
Target)) {
11148 diag::warn_hlsl_impcast_vector_truncation);
11157 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
11158 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
11160 if (
auto VecTy = dyn_cast<VectorType>(
Target))
11161 Target = VecTy->getElementType().getTypePtr();
11164 if (isa<ComplexType>(Source)) {
11165 if (!isa<ComplexType>(
Target)) {
11171 ? diag::err_impcast_complex_scalar
11172 : diag::warn_impcast_complex_scalar);
11175 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
11176 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
11179 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
11232 else if (Order < 0) {
11242 if (TargetBT && TargetBT->
isInteger()) {
11257 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
11265 if (isa<ImplicitCastExpr>(LastA) &&
11269 diag::warn_impcast_floating_point_to_bool);
11278 if (
Target->isUnsaturatedFixedPointType()) {
11282 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
11287 PDiag(diag::warn_impcast_fixed_point_range)
11288 <<
Value.toString() <<
T
11294 }
else if (
Target->isIntegerType()) {
11298 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
11301 llvm::APSInt IntResult = FXResult.convertToInt(
11307 PDiag(diag::warn_impcast_fixed_point_range)
11308 << FXResult.toString() <<
T
11315 }
else if (
Target->isUnsaturatedFixedPointType()) {
11323 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
11328 PDiag(diag::warn_impcast_fixed_point_range)
11349 unsigned int SourcePrecision =
SourceRange->Width;
11353 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
11356 if (SourcePrecision > 0 && TargetPrecision > 0 &&
11357 SourcePrecision > TargetPrecision) {
11359 if (std::optional<llvm::APSInt> SourceInt =
11364 llvm::APFloat TargetFloatValue(
11366 llvm::APFloat::opStatus ConversionStatus =
11367 TargetFloatValue.convertFromAPInt(
11369 llvm::APFloat::rmNearestTiesToEven);
11371 if (ConversionStatus != llvm::APFloat::opOK) {
11373 SourceInt->toString(PrettySourceValue, 10);
11375 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
11379 PDiag(diag::warn_impcast_integer_float_precision_constant)
11380 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11386 diag::warn_impcast_integer_float_precision);
11395 if (
Target->isBooleanType())
11403 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
11409 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11414 if (!LikelySourceRange)
11417 IntRange SourceTypeRange =
11418 IntRange::forTargetOfCanonicalType(
Context, Source);
11419 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
11421 if (LikelySourceRange->Width > TargetRange.Width) {
11427 llvm::APSInt
Value(32);
11437 PDiag(diag::warn_impcast_integer_precision_constant)
11438 << PrettySourceValue << PrettyTargetValue
11452 diag::warn_impcast_integer_precision);
11455 if (TargetRange.Width > SourceTypeRange.Width) {
11456 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
11457 if (UO->getOpcode() == UO_Minus)
11459 if (
Target->isUnsignedIntegerType())
11461 diag::warn_impcast_high_order_zero_bits);
11462 if (
Target->isSignedIntegerType())
11464 diag::warn_impcast_nonnegative_result);
11468 if (TargetRange.Width == LikelySourceRange->Width &&
11469 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11484 PDiag(diag::warn_impcast_integer_precision_constant)
11485 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11494 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
11495 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
11496 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11497 LikelySourceRange->Width == TargetRange.Width))) {
11501 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
11507 unsigned DiagID = diag::warn_impcast_integer_sign;
11515 DiagID = diag::warn_impcast_integer_sign_conditional;
11530 if (SourceEnum->getDecl()->hasNameForLinkage() &&
11531 TargetEnum->getDecl()->hasNameForLinkage() &&
11532 SourceEnum != TargetEnum) {
11537 diag::warn_impcast_different_enum_types);
11551 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
11563 Expr *TrueExpr =
E->getTrueExpr();
11564 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
11565 TrueExpr = BCO->getCommon();
11567 bool Suspicious =
false;
11576 if (!Suspicious)
return;
11579 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
11586 Suspicious =
false;
11608struct AnalyzeImplicitConversionsWorkItem {
11618 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
11620 Expr *OrigE = Item.E;
11629 bool IsListInit = Item.IsListInit ||
11630 (isa<InitListExpr>(OrigE) && S.
getLangOpts().CPlusPlus);
11635 Expr *SourceExpr =
E;
11640 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11641 if (
auto *Src = OVE->getSourceExpr())
11644 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
11645 if (UO->getOpcode() == UO_Not &&
11646 UO->getSubExpr()->isKnownToHaveBooleanValue())
11647 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
11651 if (
const auto *BO = dyn_cast<BinaryOperator>(SourceExpr))
11652 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
11653 BO->getLHS()->isKnownToHaveBooleanValue() &&
11654 BO->getRHS()->isKnownToHaveBooleanValue() &&
11655 BO->getLHS()->HasSideEffects(S.
Context) &&
11656 BO->getRHS()->HasSideEffects(S.
Context)) {
11667 if (SR.str() ==
"&" || SR.str() ==
"|") {
11669 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
11670 << (BO->getOpcode() == BO_And ?
"&" :
"|")
11673 BO->getOperatorLoc(),
11674 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
11675 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
11681 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
11702 for (
auto *SE : POE->semantics())
11703 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
11704 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
11708 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
11712 WorkList.push_back({
E, CC, IsListInit});
11716 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(
E)) {
11717 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
11721 if (OutArgE->isInOut())
11722 WorkList.push_back(
11723 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
11724 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
11730 if (BO->isComparisonOp())
11734 if (BO->getOpcode() == BO_Assign)
11737 if (BO->isAssignmentOp())
11745 if (isa<StmtExpr>(
E))
return;
11748 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
11753 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
11755 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
11759 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
11760 if (ChildExpr == CSE->getOperand())
11766 if (IsLogicalAndOperator &&
11771 WorkList.push_back({ChildExpr, CC, IsListInit});
11776 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11780 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11785 if (
U->getOpcode() == UO_LNot) {
11787 }
else if (
U->getOpcode() != UO_AddrOf) {
11788 if (
U->getSubExpr()->getType()->isAtomicType())
11789 S.
Diag(
U->getSubExpr()->getBeginLoc(),
11790 diag::warn_atomic_implicit_seq_cst);
11801 WorkList.push_back({OrigE, CC, IsListInit});
11802 while (!WorkList.empty())
11814 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
11817 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11818 if (!M->getMemberDecl()->getType()->isReferenceType())
11821 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
11823 FD =
Call->getDirectCallee();
11832 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
11846 if (
SM.isMacroBodyExpansion(
Loc))
11848 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
11871 if (isa<CXXThisExpr>(
E)) {
11872 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
11873 : diag::warn_this_bool_conversion;
11878 bool IsAddressOf =
false;
11880 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
11881 if (UO->getOpcode() != UO_AddrOf)
11883 IsAddressOf =
true;
11884 E = UO->getSubExpr();
11888 unsigned DiagID = IsCompare
11889 ? diag::warn_address_of_reference_null_compare
11890 : diag::warn_address_of_reference_bool_conversion;
11898 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
11899 bool IsParam = isa<NonNullAttr>(NonnullAttr);
11901 llvm::raw_string_ostream S(Str);
11903 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
11904 : diag::warn_cast_nonnull_to_bool;
11907 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
11912 if (
auto *Callee =
Call->getDirectCallee()) {
11913 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
11914 ComplainAboutNonnullParamOrCall(A);
11923 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
11924 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
11925 MRecordDecl && MRecordDecl->isLambda()) {
11928 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
11938 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11939 D = M->getMemberDecl();
11943 if (!
D ||
D->isWeak())
11947 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
11950 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
11951 ComplainAboutNonnullParamOrCall(A);
11955 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
11959 auto ParamIter = llvm::find(FD->
parameters(), PV);
11961 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
11965 ComplainAboutNonnullParamOrCall(
NonNull);
11970 if (ArgNo.getASTIndex() == ParamNo) {
11971 ComplainAboutNonnullParamOrCall(
NonNull);
11985 if (IsAddressOf && IsFunction) {
11990 if (!IsAddressOf && !IsFunction && !IsArray)
11995 llvm::raw_string_ostream S(Str);
11998 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
11999 : diag::warn_impcast_pointer_to_bool;
12006 DiagType = AddressOf;
12007 else if (IsFunction)
12008 DiagType = FunctionPointer;
12010 DiagType = ArrayPointer;
12012 llvm_unreachable(
"Could not determine diagnostic.");
12014 <<
Range << IsEqual;
12027 if (ReturnType.
isNull())
12065 CheckArrayAccess(
E);
12072 ::CheckBoolLikeConversion(*
this,
E, CC);
12075void Sema::CheckForIntOverflow (
const Expr *
E) {
12080 const Expr *OriginalE = Exprs.pop_back_val();
12083 if (isa<BinaryOperator, UnaryOperator>(
E)) {
12088 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
12089 Exprs.append(InitList->inits().begin(), InitList->inits().end());
12090 else if (isa<ObjCBoxedExpr>(OriginalE))
12092 else if (
const auto *
Call = dyn_cast<CallExpr>(
E))
12093 Exprs.append(
Call->arg_begin(),
Call->arg_end());
12094 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
12095 Exprs.append(Message->arg_begin(), Message->arg_end());
12096 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
12097 Exprs.append(Construct->arg_begin(), Construct->arg_end());
12098 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
12099 Exprs.push_back(Temporary->getSubExpr());
12100 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
12101 Exprs.push_back(Array->getIdx());
12102 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
12103 Exprs.push_back(Compound->getInitializer());
12104 else if (
const auto *New = dyn_cast<CXXNewExpr>(
E);
12105 New && New->isArray()) {
12106 if (
auto ArraySize = New->getArraySize())
12107 Exprs.push_back(*ArraySize);
12108 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
12109 Exprs.push_back(MTE->getSubExpr());
12110 }
while (!Exprs.empty());
12125 class SequenceTree {
12129 LLVM_PREFERRED_TYPE(
bool)
12130 unsigned Merged : 1;
12138 friend class SequenceTree;
12142 explicit Seq(
unsigned N) : Index(N) {}
12145 Seq() : Index(0) {}
12148 SequenceTree() { Values.push_back(
Value(0)); }
12149 Seq root()
const {
return Seq(0); }
12156 return Seq(Values.size() - 1);
12160 void merge(
Seq S) {
12161 Values[S.Index].Merged =
true;
12167 bool isUnsequenced(
Seq Cur,
Seq Old) {
12168 unsigned C = representative(Cur.Index);
12169 unsigned Target = representative(Old.Index);
12173 C = Values[
C].Parent;
12180 unsigned representative(
unsigned K) {
12181 if (Values[K].Merged)
12183 return Values[K].Parent = representative(Values[K].
Parent);
12203 UK_ModAsSideEffect,
12205 UK_Count = UK_ModAsSideEffect + 1
12211 const Expr *UsageExpr =
nullptr;
12212 SequenceTree::Seq
Seq;
12218 Usage Uses[UK_Count];
12221 bool Diagnosed =
false;
12225 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
12233 UsageInfoMap UsageMap;
12236 SequenceTree::Seq Region;
12251 struct SequencedSubexpression {
12252 SequencedSubexpression(SequenceChecker &Self)
12253 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
12254 Self.ModAsSideEffect = &ModAsSideEffect;
12257 ~SequencedSubexpression() {
12258 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
12262 UsageInfo &UI = Self.UsageMap[M.first];
12263 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
12264 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
12265 SideEffectUsage = M.second;
12267 Self.ModAsSideEffect = OldModAsSideEffect;
12270 SequenceChecker &Self;
12279 class EvaluationTracker {
12281 EvaluationTracker(SequenceChecker &Self)
12282 : Self(Self), Prev(Self.EvalTracker) {
12283 Self.EvalTracker =
this;
12286 ~EvaluationTracker() {
12287 Self.EvalTracker = Prev;
12289 Prev->EvalOK &= EvalOK;
12292 bool evaluate(
const Expr *
E,
bool &Result) {
12296 Result, Self.SemaRef.Context,
12297 Self.SemaRef.isConstantEvaluatedContext());
12302 SequenceChecker &Self;
12303 EvaluationTracker *Prev;
12304 bool EvalOK =
true;
12305 } *EvalTracker =
nullptr;
12309 Object getObject(
const Expr *
E,
bool Mod)
const {
12312 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
12313 return getObject(UO->getSubExpr(), Mod);
12315 if (BO->getOpcode() == BO_Comma)
12316 return getObject(BO->getRHS(), Mod);
12317 if (Mod && BO->isAssignmentOp())
12318 return getObject(BO->getLHS(), Mod);
12319 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
12321 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
12322 return ME->getMemberDecl();
12323 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
12332 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
12334 Usage &
U = UI.Uses[UK];
12335 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
12339 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
12340 ModAsSideEffect->push_back(std::make_pair(O,
U));
12342 U.UsageExpr = UsageExpr;
12352 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
12353 UsageKind OtherKind,
bool IsModMod) {
12357 const Usage &
U = UI.Uses[OtherKind];
12358 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
12361 const Expr *Mod =
U.UsageExpr;
12362 const Expr *ModOrUse = UsageExpr;
12363 if (OtherKind == UK_Use)
12364 std::swap(Mod, ModOrUse);
12368 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
12369 : diag::warn_unsequenced_mod_use)
12371 UI.Diagnosed =
true;
12400 void notePreUse(Object O,
const Expr *UseExpr) {
12401 UsageInfo &UI = UsageMap[O];
12403 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
12406 void notePostUse(Object O,
const Expr *UseExpr) {
12407 UsageInfo &UI = UsageMap[O];
12408 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
12410 addUsage(O, UI, UseExpr, UK_Use);
12413 void notePreMod(Object O,
const Expr *ModExpr) {
12414 UsageInfo &UI = UsageMap[O];
12416 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
12417 checkUsage(O, UI, ModExpr, UK_Use,
false);
12420 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
12421 UsageInfo &UI = UsageMap[O];
12422 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
12424 addUsage(O, UI, ModExpr, UK);
12428 SequenceChecker(
Sema &S,
const Expr *
E,
12430 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
12434 (void)this->WorkList;
12437 void VisitStmt(
const Stmt *S) {
12441 void VisitExpr(
const Expr *
E) {
12443 Base::VisitStmt(
E);
12447 for (
auto *Sub : CSE->
children()) {
12448 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
12463 void VisitCastExpr(
const CastExpr *
E) {
12465 if (
E->getCastKind() == CK_LValueToRValue)
12466 O = getObject(
E->getSubExpr(),
false);
12475 void VisitSequencedExpressions(
const Expr *SequencedBefore,
12476 const Expr *SequencedAfter) {
12477 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
12478 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
12479 SequenceTree::Seq OldRegion = Region;
12482 SequencedSubexpression SeqBefore(*
this);
12483 Region = BeforeRegion;
12484 Visit(SequencedBefore);
12487 Region = AfterRegion;
12488 Visit(SequencedAfter);
12490 Region = OldRegion;
12492 Tree.merge(BeforeRegion);
12493 Tree.merge(AfterRegion);
12501 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
12508 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12509 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12515 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12522 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12523 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12528 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12540 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12544 SequenceTree::Seq RHSRegion;
12545 SequenceTree::Seq LHSRegion;
12547 RHSRegion =
Tree.allocate(Region);
12548 LHSRegion =
Tree.allocate(Region);
12550 RHSRegion = Region;
12551 LHSRegion = Region;
12553 SequenceTree::Seq OldRegion = Region;
12569 SequencedSubexpression SeqBefore(*
this);
12570 Region = RHSRegion;
12574 Region = LHSRegion;
12577 if (O && isa<CompoundAssignOperator>(BO))
12578 notePostUse(O, BO);
12582 Region = LHSRegion;
12585 if (O && isa<CompoundAssignOperator>(BO))
12586 notePostUse(O, BO);
12588 Region = RHSRegion;
12596 Region = OldRegion;
12600 : UK_ModAsSideEffect);
12602 Tree.merge(RHSRegion);
12603 Tree.merge(LHSRegion);
12608 VisitBinAssign(CAO);
12611 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12612 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12616 return VisitExpr(UO);
12624 : UK_ModAsSideEffect);
12627 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12628 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12632 return VisitExpr(UO);
12636 notePostMod(O, UO, UK_ModAsSideEffect);
12645 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12646 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12647 SequenceTree::Seq OldRegion = Region;
12649 EvaluationTracker Eval(*
this);
12651 SequencedSubexpression Sequenced(*
this);
12652 Region = LHSRegion;
12659 bool EvalResult =
false;
12660 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12661 bool ShouldVisitRHS = !EvalOK || !EvalResult;
12662 if (ShouldVisitRHS) {
12663 Region = RHSRegion;
12667 Region = OldRegion;
12668 Tree.merge(LHSRegion);
12669 Tree.merge(RHSRegion);
12678 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12679 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12680 SequenceTree::Seq OldRegion = Region;
12682 EvaluationTracker Eval(*
this);
12684 SequencedSubexpression Sequenced(*
this);
12685 Region = LHSRegion;
12691 bool EvalResult =
false;
12692 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12693 bool ShouldVisitRHS = !EvalOK || EvalResult;
12694 if (ShouldVisitRHS) {
12695 Region = RHSRegion;
12699 Region = OldRegion;
12700 Tree.merge(LHSRegion);
12701 Tree.merge(RHSRegion);
12709 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
12725 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
12726 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
12727 SequenceTree::Seq OldRegion = Region;
12729 EvaluationTracker Eval(*
this);
12731 SequencedSubexpression Sequenced(*
this);
12732 Region = ConditionRegion;
12742 bool EvalResult =
false;
12743 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
12744 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
12745 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
12746 if (ShouldVisitTrueExpr) {
12747 Region = TrueRegion;
12750 if (ShouldVisitFalseExpr) {
12751 Region = FalseRegion;
12755 Region = OldRegion;
12756 Tree.merge(ConditionRegion);
12757 Tree.merge(TrueRegion);
12758 Tree.merge(FalseRegion);
12761 void VisitCallExpr(
const CallExpr *CE) {
12773 SequencedSubexpression Sequenced(*
this);
12778 SequenceTree::Seq CalleeRegion;
12779 SequenceTree::Seq OtherRegion;
12780 if (SemaRef.getLangOpts().CPlusPlus17) {
12781 CalleeRegion = Tree.allocate(Region);
12782 OtherRegion = Tree.allocate(Region);
12784 CalleeRegion = Region;
12785 OtherRegion = Region;
12787 SequenceTree::Seq OldRegion = Region;
12790 Region = CalleeRegion;
12792 SequencedSubexpression Sequenced(*this);
12793 Visit(CE->getCallee());
12795 Visit(CE->getCallee());
12799 Region = OtherRegion;
12803 Region = OldRegion;
12805 Tree.merge(CalleeRegion);
12806 Tree.merge(OtherRegion);
12824 return VisitCallExpr(CXXOCE);
12835 case OO_MinusEqual:
12837 case OO_SlashEqual:
12838 case OO_PercentEqual:
12839 case OO_CaretEqual:
12842 case OO_LessLessEqual:
12843 case OO_GreaterGreaterEqual:
12844 SequencingKind = RHSBeforeLHS;
12848 case OO_GreaterGreater:
12854 SequencingKind = LHSBeforeRHS;
12858 SequencingKind = LHSBeforeRest;
12862 SequencingKind = NoSequencing;
12866 if (SequencingKind == NoSequencing)
12867 return VisitCallExpr(CXXOCE);
12870 SequencedSubexpression Sequenced(*
this);
12873 assert(SemaRef.getLangOpts().CPlusPlus17 &&
12874 "Should only get there with C++17 and above!");
12875 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
12876 "Should only get there with an overloaded binary operator"
12877 " or an overloaded call operator!");
12879 if (SequencingKind == LHSBeforeRest) {
12880 assert(CXXOCE->getOperator() == OO_Call &&
12881 "We should only have an overloaded call operator here!");
12890 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
12891 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
12892 SequenceTree::Seq OldRegion = Region;
12894 assert(CXXOCE->getNumArgs() >= 1 &&
12895 "An overloaded call operator must have at least one argument"
12896 " for the postfix-expression!");
12897 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
12898 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
12899 CXXOCE->getNumArgs() - 1);
12903 Region = PostfixExprRegion;
12904 SequencedSubexpression Sequenced(*this);
12905 Visit(PostfixExpr);
12909 Region = ArgsRegion;
12910 for (const Expr *Arg : Args)
12913 Region = OldRegion;
12914 Tree.merge(PostfixExprRegion);
12915 Tree.merge(ArgsRegion);
12917 assert(CXXOCE->getNumArgs() == 2 &&
12918 "Should only have two arguments here!");
12919 assert((SequencingKind == LHSBeforeRHS ||
12920 SequencingKind == RHSBeforeLHS) &&
12921 "Unexpected sequencing kind!");
12925 const Expr *E1 = CXXOCE->getArg(0);
12926 const Expr *E2 = CXXOCE->getArg(1);
12927 if (SequencingKind == RHSBeforeLHS)
12930 return VisitSequencedExpressions(E1, E2);
12937 SequencedSubexpression Sequenced(*
this);
12940 return VisitExpr(CCE);
12943 SequenceExpressionsInOrder(
12949 return VisitExpr(ILE);
12952 SequenceExpressionsInOrder(ILE->
inits());
12964 SequenceTree::Seq
Parent = Region;
12965 for (
const Expr *
E : ExpressionList) {
12969 Elts.push_back(Region);
12975 for (
unsigned I = 0; I < Elts.size(); ++I)
12976 Tree.merge(Elts[I]);
12980SequenceChecker::UsageInfo::UsageInfo() =
default;
12984void Sema::CheckUnsequencedOperations(
const Expr *
E) {
12986 WorkList.push_back(
E);
12987 while (!WorkList.empty()) {
12988 const Expr *Item = WorkList.pop_back_val();
12989 SequenceChecker(*
this, Item, WorkList);
12994 bool IsConstexpr) {
12996 IsConstexpr || isa<ConstantExpr>(
E));
12997 CheckImplicitConversions(
E, CheckLoc);
12999 CheckUnsequencedOperations(
E);
13001 CheckForIntOverflow(
E);
13015 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
13019 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
13023 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
13037 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
13041 bool CheckParameterNames) {
13042 bool HasInvalidParm =
false;
13044 assert(Param &&
"null in a parameter list");
13053 if (!Param->isInvalidDecl() &&
13055 diag::err_typecheck_decl_incomplete_type) ||
13057 diag::err_abstract_type_in_decl,
13059 Param->setInvalidDecl();
13060 HasInvalidParm =
true;
13065 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
13069 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
13077 QualType PType = Param->getOriginalType();
13085 if (!Param->isInvalidDecl()) {
13087 if (!ClassDecl->isInvalidDecl() &&
13088 !ClassDecl->hasIrrelevantDestructor() &&
13089 !ClassDecl->isDependentContext() &&
13090 ClassDecl->isParamDestroyedInCallee()) {
13102 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
13103 if (!Param->getType().isConstQualified())
13104 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
13108 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
13113 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
13114 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
13119 if (!Param->isInvalidDecl() &&
13121 Param->setInvalidDecl();
13122 HasInvalidParm =
true;
13123 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
13127 return HasInvalidParm;
13130std::optional<std::pair<
13139static std::pair<CharUnits, CharUnits>
13147 if (
Base->isVirtual()) {
13154 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
13161 DerivedType =
Base->getType();
13164 return std::make_pair(BaseAlignment, Offset);
13168static std::optional<std::pair<CharUnits, CharUnits>>
13174 return std::nullopt;
13179 return std::nullopt;
13183 CharUnits Offset = EltSize * IdxRes->getExtValue();
13186 return std::make_pair(
P->first,
P->second + Offset);
13192 return std::make_pair(
13193 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
13199std::optional<std::pair<
13207 case Stmt::CStyleCastExprClass:
13208 case Stmt::CXXStaticCastExprClass:
13209 case Stmt::ImplicitCastExprClass: {
13210 auto *CE = cast<CastExpr>(
E);
13211 const Expr *From = CE->getSubExpr();
13212 switch (CE->getCastKind()) {
13217 case CK_UncheckedDerivedToBase:
13218 case CK_DerivedToBase: {
13228 case Stmt::ArraySubscriptExprClass: {
13229 auto *ASE = cast<ArraySubscriptExpr>(
E);
13233 case Stmt::DeclRefExprClass: {
13234 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
13237 if (!VD->getType()->isReferenceType()) {
13239 if (VD->hasDependentAlignment())
13248 case Stmt::MemberExprClass: {
13249 auto *ME = cast<MemberExpr>(
E);
13250 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
13254 std::optional<std::pair<CharUnits, CharUnits>>
P;
13263 return std::make_pair(
P->first,
13266 case Stmt::UnaryOperatorClass: {
13267 auto *UO = cast<UnaryOperator>(
E);
13276 case Stmt::BinaryOperatorClass: {
13277 auto *BO = cast<BinaryOperator>(
E);
13288 return std::nullopt;
13293std::optional<std::pair<
13302 case Stmt::CStyleCastExprClass:
13303 case Stmt::CXXStaticCastExprClass:
13304 case Stmt::ImplicitCastExprClass: {
13305 auto *CE = cast<CastExpr>(
E);
13306 const Expr *From = CE->getSubExpr();
13307 switch (CE->getCastKind()) {
13312 case CK_ArrayToPointerDecay:
13314 case CK_UncheckedDerivedToBase:
13315 case CK_DerivedToBase: {
13325 case Stmt::CXXThisExprClass: {
13330 case Stmt::UnaryOperatorClass: {
13331 auto *UO = cast<UnaryOperator>(
E);
13336 case Stmt::BinaryOperatorClass: {
13337 auto *BO = cast<BinaryOperator>(
E);
13345 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
13346 std::swap(LHS, RHS);
13356 return std::nullopt;
13361 std::optional<std::pair<CharUnits, CharUnits>>
P =
13365 return P->first.alignmentAtOffset(
P->second);
13383 if (!DestPtr)
return;
13389 if (DestAlign.
isOne())
return;
13393 if (!SrcPtr)
return;
13404 if (SrcAlign >= DestAlign)
return;
13409 <<
static_cast<unsigned>(DestAlign.
getQuantity())
13413void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
13415 bool AllowOnePastEnd,
bool IndexNegated) {
13424 const Type *EffectiveType =
13431 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
13433 const Type *BaseType =
13435 bool IsUnboundedArray =
13437 Context, StrictFlexArraysLevel,
13447 llvm::APSInt index =
Result.Val.getInt();
13448 if (IndexNegated) {
13449 index.setIsUnsigned(
false);
13453 if (IsUnboundedArray) {
13456 if (index.isUnsigned() || !index.isNegative()) {
13458 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
13460 if (index.getBitWidth() < AddrBits)
13461 index = index.zext(AddrBits);
13462 std::optional<CharUnits> ElemCharUnits =
13463 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
13466 if (!ElemCharUnits || ElemCharUnits->isZero())
13468 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
13473 if (index.getActiveBits() <= AddrBits) {
13475 llvm::APInt Product(index);
13477 Product = Product.umul_ov(ElemBytes, Overflow);
13478 if (!Overflow && Product.getActiveBits() <= AddrBits)
13484 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
13485 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
13487 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
13488 MaxElems = MaxElems.udiv(ElemBytes);
13491 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
13492 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
13498 <<
toString(index, 10,
true) << AddrBits
13499 << (
unsigned)ASTC.toBits(*ElemCharUnits)
13502 << (
unsigned)MaxElems.getLimitedValue(~0
U)
13507 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13509 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13511 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13512 ND = ME->getMemberDecl();
13516 PDiag(diag::note_array_declared_here) << ND);
13521 if (index.isUnsigned() || !index.isNegative()) {
13531 llvm::APInt size = ArrayTy->
getSize();
13533 if (BaseType != EffectiveType) {
13541 if (!ptrarith_typesize)
13544 if (ptrarith_typesize != array_typesize) {
13546 uint64_t ratio = array_typesize / ptrarith_typesize;
13550 if (ptrarith_typesize * ratio == array_typesize)
13551 size *= llvm::APInt(size.getBitWidth(), ratio);
13555 if (size.getBitWidth() > index.getBitWidth())
13556 index = index.zext(size.getBitWidth());
13557 else if (size.getBitWidth() < index.getBitWidth())
13558 size = size.zext(index.getBitWidth());
13564 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
13581 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
13582 : diag::warn_ptr_arith_exceeds_bounds;
13583 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
13591 unsigned DiagID = diag::warn_array_index_precedes_bounds;
13593 DiagID = diag::warn_ptr_arith_precedes_bounds;
13594 if (index.isNegative()) index = -index;
13604 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13606 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13608 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13609 ND = ME->getMemberDecl();
13613 PDiag(diag::note_array_declared_here) << ND);
13616void Sema::CheckArrayAccess(
const Expr *
expr) {
13617 int AllowOnePastEnd = 0;
13619 expr =
expr->IgnoreParenImpCasts();
13620 switch (
expr->getStmtClass()) {
13621 case Stmt::ArraySubscriptExprClass: {
13624 AllowOnePastEnd > 0);
13628 case Stmt::MemberExprClass: {
13629 expr = cast<MemberExpr>(
expr)->getBase();
13632 case Stmt::ArraySectionExprClass: {
13638 nullptr, AllowOnePastEnd > 0);
13641 case Stmt::UnaryOperatorClass: {
13657 case Stmt::ConditionalOperatorClass: {
13660 CheckArrayAccess(lhs);
13662 CheckArrayAccess(rhs);
13665 case Stmt::CXXOperatorCallExprClass: {
13666 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
13667 for (
const auto *Arg : OCE->arguments())
13668 CheckArrayAccess(Arg);
13678 Expr *RHS,
bool isProperty) {
13690 S.
Diag(
Loc, diag::warn_arc_literal_assign)
13692 << (isProperty ? 0 : 1)
13700 Expr *RHS,
bool isProperty) {
13703 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13704 S.
Diag(
Loc, diag::warn_arc_retained_assign)
13706 << (isProperty ? 0 : 1)
13710 RHS =
cast->getSubExpr();
13781 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13782 Diag(
Loc, diag::warn_arc_retained_property_assign)
13786 RHS =
cast->getSubExpr();
13809 bool StmtLineInvalid;
13812 if (StmtLineInvalid)
13815 bool BodyLineInvalid;
13818 if (BodyLineInvalid)
13822 if (StmtLine != BodyLine)
13837 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13846 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13850 const Stmt *PossibleBody) {
13856 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
13857 StmtLoc = FS->getRParenLoc();
13858 Body = FS->getBody();
13859 DiagID = diag::warn_empty_for_body;
13860 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
13861 StmtLoc = WS->getRParenLoc();
13862 Body = WS->getBody();
13863 DiagID = diag::warn_empty_while_body;
13868 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13891 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
13892 if (!ProbableTypo) {
13893 bool BodyColInvalid;
13896 if (BodyColInvalid)
13899 bool StmtColInvalid;
13902 if (StmtColInvalid)
13905 if (BodyCol > StmtCol)
13906 ProbableTypo =
true;
13909 if (ProbableTypo) {
13911 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13919 if (
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
13931 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
13933 RHSExpr = CE->
getArg(0);
13934 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
13935 CXXSCE && CXXSCE->isXValue())
13936 RHSExpr = CXXSCE->getSubExpr();
13940 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
13941 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
13944 if (LHSDeclRef && RHSDeclRef) {
13951 auto D =
Diag(OpLoc, diag::warn_self_move)
13967 const Expr *LHSBase = LHSExpr;
13968 const Expr *RHSBase = RHSExpr;
13969 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
13970 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
13971 if (!LHSME || !RHSME)
13974 while (LHSME && RHSME) {
13981 LHSME = dyn_cast<MemberExpr>(LHSBase);
13982 RHSME = dyn_cast<MemberExpr>(RHSBase);
13985 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
13986 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
13987 if (LHSDeclRef && RHSDeclRef) {
13994 Diag(OpLoc, diag::warn_self_move)
14000 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
14001 Diag(OpLoc, diag::warn_self_move)
14025 bool AreUnionMembers =
false) {
14026 [[maybe_unused]]
const Type *Field1Parent =
14028 [[maybe_unused]]
const Type *Field2Parent =
14033 "Can't evaluate layout compatibility between a struct field and a "
14036 (AreUnionMembers && Field1Parent->
isUnionType())) &&
14037 "AreUnionMembers should be 'true' for union fields (only).");
14050 if (Bits1 != Bits2)
14054 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
14055 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
14058 if (!AreUnionMembers &&
14070 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
14071 RD1 = D1CXX->getStandardLayoutBaseWithFields();
14073 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
14074 RD2 = D2CXX->getStandardLayoutBaseWithFields();
14079 return isLayoutCompatible(C, F1, F2);
14088 for (
auto *Field2 : RD2->
fields())
14089 UnmatchedFields.insert(Field2);
14091 for (
auto *Field1 : RD1->
fields()) {
14092 auto I = UnmatchedFields.begin();
14093 auto E = UnmatchedFields.end();
14095 for ( ; I !=
E; ++I) {
14097 bool Result = UnmatchedFields.erase(*I);
14107 return UnmatchedFields.empty();
14133 if (
C.hasSameType(T1, T2))
14142 if (TC1 == Type::Enum) {
14144 cast<EnumType>(T1)->getDecl(),
14145 cast<EnumType>(T2)->getDecl());
14146 }
else if (TC1 == Type::Record) {
14151 cast<RecordType>(T1)->getDecl(),
14152 cast<RecordType>(T2)->getDecl());
14166 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
14197 const ValueDecl **VD, uint64_t *MagicValue,
14198 bool isConstantEvaluated) {
14206 case Stmt::UnaryOperatorClass: {
14215 case Stmt::DeclRefExprClass: {
14216 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
14221 case Stmt::IntegerLiteralClass: {
14223 llvm::APInt MagicValueAPInt = IL->
getValue();
14224 if (MagicValueAPInt.getActiveBits() <= 64) {
14225 *MagicValue = MagicValueAPInt.getZExtValue();
14231 case Stmt::BinaryConditionalOperatorClass:
14232 case Stmt::ConditionalOperatorClass: {
14234 cast<AbstractConditionalOperator>(TypeExpr);
14237 isConstantEvaluated)) {
14247 case Stmt::BinaryOperatorClass: {
14250 TypeExpr = BO->
getRHS();
14280 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
14283 bool isConstantEvaluated) {
14284 FoundWrongKind =
false;
14289 uint64_t MagicValue;
14291 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
14295 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
14296 if (I->getArgumentKind() != ArgumentKind) {
14297 FoundWrongKind =
true;
14300 TypeInfo.Type = I->getMatchingCType();
14301 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
14302 TypeInfo.MustBeNull = I->getMustBeNull();
14313 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
14314 if (I == MagicValues->end())
14323 bool LayoutCompatible,
14325 if (!TypeTagForDatatypeMagicValues)
14326 TypeTagForDatatypeMagicValues.reset(
14327 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
14330 (*TypeTagForDatatypeMagicValues)[Magic] =
14346 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
14347 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
14348 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
14349 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
14352void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
14356 bool IsPointerAttr =
Attr->getIsPointer();
14359 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
14360 if (TypeTagIdxAST >= ExprArgs.size()) {
14361 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14362 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
14365 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
14366 bool FoundWrongKind;
14369 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
14371 if (FoundWrongKind)
14373 diag::warn_type_tag_for_datatype_wrong_kind)
14379 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
14380 if (ArgumentIdxAST >= ExprArgs.size()) {
14381 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14382 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
14385 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
14386 if (IsPointerAttr) {
14388 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
14389 if (ICE->getType()->isVoidPointerType() &&
14390 ICE->getCastKind() == CK_BitCast)
14391 ArgumentExpr = ICE->getSubExpr();
14404 diag::warn_type_safety_null_pointer_required)
14416 bool mismatch =
false;
14439 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
14440 << ArgumentType << ArgumentKind
14441 <<
TypeInfo.LayoutCompatible << RequiredType
14448 MisalignedMembers.emplace_back(
E, RD, MD, Alignment);
14452 for (MisalignedMember &m : MisalignedMembers) {
14458 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
14461 MisalignedMembers.clear();
14468 if (isa<UnaryOperator>(
E) &&
14469 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
14470 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
14471 if (isa<MemberExpr>(Op)) {
14472 auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
14473 if (MA != MisalignedMembers.end() &&
14478 MisalignedMembers.erase(MA);
14487 const auto *ME = dyn_cast<MemberExpr>(
E);
14499 bool AnyIsPacked =
false;
14501 QualType BaseType = ME->getBase()->getType();
14511 auto *FD = dyn_cast<FieldDecl>(MD);
14517 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
14518 ReverseMemberChain.push_back(FD);
14521 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
14523 assert(TopME &&
"We did not compute a topmost MemberExpr!");
14530 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
14534 if (!DRE && !isa<CXXThisExpr>(TopBase))
14541 if (ExpectedAlignment.
isOne())
14546 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
14551 ReverseMemberChain.back()->getParent()->getTypeForDecl());
14555 if (DRE && !TopME->
isArrow()) {
14558 CompleteObjectAlignment =
14563 if (Offset % ExpectedAlignment != 0 ||
14566 CompleteObjectAlignment < ExpectedAlignment) {
14577 for (
FieldDecl *FDI : ReverseMemberChain) {
14578 if (FDI->hasAttr<PackedAttr>() ||
14579 FDI->getParent()->hasAttr<PackedAttr>()) {
14581 Alignment = std::min(
14587 assert(FD &&
"We did not find a packed FieldDecl!");
14592void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
14593 using namespace std::placeholders;
14596 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
14618bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
bool FPOnly) {
14632 TheCall->
setType(VecTy0->getElementType());
14656 diag::err_typecheck_call_different_arg_types)
14673 bool CheckForFloatArgs) {
14678 for (
int I = 0; I < 3; ++I) {
14682 Args[I] = Converted.
get();
14685 if (CheckForFloatArgs) {
14686 int ArgOrdinal = 1;
14687 for (
Expr *Arg : Args) {
14689 Arg->
getType(), ArgOrdinal++))
14693 int ArgOrdinal = 1;
14694 for (
Expr *Arg : Args) {
14701 for (
int I = 1; I < 3; ++I) {
14702 if (Args[0]->getType().getCanonicalType() !=
14703 Args[I]->getType().getCanonicalType()) {
14704 return Diag(Args[0]->getBeginLoc(),
14705 diag::err_typecheck_call_different_arg_types)
14709 TheCall->
setArg(I, Args[I]);
14712 TheCall->
setType(Args[0]->getType());
14716bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
14728bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
14737 << 1 << 0 << TyArg;
14751 Expr *Matrix = MatrixArg.
get();
14756 << 1 << 1 << Matrix->
getType();
14763 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
14766 TheCall->
setType(ResultType);
14769 TheCall->
setArg(0, Matrix);
14774static std::optional<unsigned>
14777 std::optional<llvm::APSInt>
Value =
14784 uint64_t
Dim =
Value->getZExtValue();
14803 unsigned PtrArgIdx = 0;
14809 bool ArgError =
false;
14816 PtrExpr = PtrConv.
get();
14817 TheCall->
setArg(0, PtrExpr);
14828 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14835 << PtrArgIdx + 1 << 2
14842 auto ApplyArgumentConversions = [
this](
Expr *
E) {
14851 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
14853 RowsExpr = RowsConv.
get();
14854 TheCall->
setArg(1, RowsExpr);
14856 RowsExpr =
nullptr;
14858 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
14860 ColumnsExpr = ColumnsConv.
get();
14861 TheCall->
setArg(2, ColumnsExpr);
14863 ColumnsExpr =
nullptr;
14874 std::optional<unsigned> MaybeRows;
14878 std::optional<unsigned> MaybeColumns;
14883 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
14886 StrideExpr = StrideConv.
get();
14887 TheCall->
setArg(3, StrideExpr);
14890 if (std::optional<llvm::APSInt>
Value =
14893 if (Stride < *MaybeRows) {
14895 diag::err_builtin_matrix_stride_too_small);
14901 if (ArgError || !MaybeRows || !MaybeColumns)
14914 unsigned PtrArgIdx = 1;
14919 bool ArgError =
false;
14925 MatrixExpr = MatrixConv.
get();
14926 TheCall->
setArg(0, MatrixExpr);
14936 << 1 << 1 << MatrixExpr->
getType();
14944 PtrExpr = PtrConv.
get();
14945 TheCall->
setArg(1, PtrExpr);
14956 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14961 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
14968 diag::err_builtin_matrix_pointer_arg_mismatch)
14969 << ElementTy << MatrixTy->getElementType();
14984 StrideExpr = StrideConv.
get();
14985 TheCall->
setArg(2, StrideExpr);
14990 if (std::optional<llvm::APSInt>
Value =
14993 if (Stride < MatrixTy->getNumRows()) {
14995 diag::err_builtin_matrix_stride_too_small);
15015 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
15020 llvm::StringSet<> CalleeTCBs;
15021 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
15022 CalleeTCBs.insert(A->getTCBName());
15023 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
15024 CalleeTCBs.insert(A->getTCBName());
15028 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
15029 StringRef CallerTCB = A->getTCBName();
15030 if (CalleeTCBs.count(CallerTCB) == 0) {
15031 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
15032 << 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 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.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const LLVM_READONLY
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
unsigned getNumNegativeBits() const
Returns the width in bits required to store all the negative enumerators of this enum.
bool isComplete() const
Returns true if this can be considered a complete type.
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
unsigned getNumPositiveBits() const
Returns the width in bits required to store all the non-negative enumerators of this enum.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_NoSideEffects
Strictly evaluate the expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isFlexibleArrayMemberLike(ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue(const ASTContext &Ctx) const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
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...
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
unsigned NumCallArgs
The number of expressions in CallArgs.
const Expr *const * CallArgs
The list of argument expressions in a synthesized call.
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.