77#include "llvm/ADT/APFloat.h"
78#include "llvm/ADT/APInt.h"
79#include "llvm/ADT/APSInt.h"
80#include "llvm/ADT/ArrayRef.h"
81#include "llvm/ADT/DenseMap.h"
82#include "llvm/ADT/FoldingSet.h"
83#include "llvm/ADT/STLExtras.h"
84#include "llvm/ADT/SmallBitVector.h"
85#include "llvm/ADT/SmallPtrSet.h"
86#include "llvm/ADT/SmallString.h"
87#include "llvm/ADT/SmallVector.h"
88#include "llvm/ADT/StringExtras.h"
89#include "llvm/ADT/StringRef.h"
90#include "llvm/ADT/StringSet.h"
91#include "llvm/ADT/StringSwitch.h"
92#include "llvm/Support/AtomicOrdering.h"
93#include "llvm/Support/Compiler.h"
94#include "llvm/Support/ConvertUTF.h"
95#include "llvm/Support/ErrorHandling.h"
96#include "llvm/Support/Format.h"
97#include "llvm/Support/Locale.h"
98#include "llvm/Support/MathExtras.h"
99#include "llvm/Support/SaveAndRestore.h"
100#include "llvm/Support/raw_ostream.h"
101#include "llvm/TargetParser/RISCVTargetParser.h"
102#include "llvm/TargetParser/Triple.h"
115using namespace clang;
119 unsigned ByteNo)
const {
130 unsigned ArgCount =
Call->getNumArgs();
131 if (ArgCount >= MinArgCount)
134 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
135 << 0 << MinArgCount << ArgCount
136 << 0 <<
Call->getSourceRange();
140 unsigned ArgCount =
Call->getNumArgs();
141 if (ArgCount <= MaxArgCount)
143 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
144 << 0 << MaxArgCount << ArgCount
145 << 0 <<
Call->getSourceRange();
149 unsigned MaxArgCount) {
155 unsigned ArgCount =
Call->getNumArgs();
156 if (ArgCount == DesiredArgCount)
161 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
165 Call->getArg(ArgCount - 1)->getEndLoc());
168 << 0 << DesiredArgCount << ArgCount
169 << 0 <<
Call->getArg(1)->getSourceRange();
173 bool HasError =
false;
175 for (
unsigned I = 0; I <
Call->getNumArgs(); ++I) {
182 int DiagMsgKind = -1;
184 if (!ArgString.has_value())
186 else if (ArgString->find(
'$') != std::string::npos)
189 if (DiagMsgKind >= 0) {
200 if (
Value->isTypeDependent())
231 if (!Literal || !Literal->isOrdinary()) {
244 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
252 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
253 if (!Literal || !Literal->isWide()) {
254 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
255 << Arg->getSourceRange();
289 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
320 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
322 auto IsValidIntegerType = [](
QualType Ty) {
323 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
330 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
334 S.
Diag(Source->
getExprLoc(), diag::err_typecheck_expect_scalar_operand)
340 if (!IsValidIntegerType(AlignOp->
getType())) {
351 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
352 llvm::APSInt MaxValue(
353 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
354 if (AlignValue < 1) {
355 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
358 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
363 if (!AlignValue.isPowerOf2()) {
364 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
367 if (AlignValue == 1) {
368 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
369 << IsBooleanAlignBuiltin;
397 std::pair<unsigned, const char *> Builtins[] = {
398 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
399 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
400 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
403 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
405 return BuiltinID ==
P.first && TheCall->
getExprLoc().isMacroID() &&
410 auto ValidCkdIntType = [](
QualType QT) {
413 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
414 return (BT->getKind() >= BuiltinType::Short &&
415 BT->getKind() <= BuiltinType::Int128) || (
416 BT->getKind() >= BuiltinType::UShort &&
417 BT->getKind() <= BuiltinType::UInt128) ||
418 BT->getKind() == BuiltinType::UChar ||
419 BT->getKind() == BuiltinType::SChar;
424 for (
unsigned I = 0; I < 2; ++I) {
430 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
449 !PtrTy->getPointeeType()->isIntegerType() ||
450 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
451 PtrTy->getPointeeType().isConstQualified()) {
453 diag::err_overflow_builtin_must_be_ptr_int)
461 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
462 for (
unsigned I = 0; I < 3; ++I) {
463 const auto Arg = TheCall->
getArg(I);
466 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
468 return S.
Diag(Arg->getBeginLoc(),
469 diag::err_overflow_builtin_bit_int_max_size)
478struct BuiltinDumpStructGenerator {
487 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
488 Policy(S.Context.getPrintingPolicy()) {
492 Expr *makeOpaqueValueExpr(
Expr *Inner) {
495 Inner->getObjectKind(), Inner);
496 Actions.push_back(OVE);
500 Expr *getStringLiteral(llvm::StringRef Str) {
506 bool callPrintFunction(llvm::StringRef Format,
510 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
512 Args.push_back(getStringLiteral(Format));
513 Args.insert(Args.end(), Exprs.begin(), Exprs.end());
518 Ctx.PointOfInstantiation =
Loc;
519 Ctx.CallArgs = Args.data();
520 Ctx.NumCallArgs = Args.size();
529 Actions.push_back(RealCall.
get());
535 Expr *getIndentString(
unsigned Depth) {
541 return getStringLiteral(Indent);
545 return getStringLiteral(
T.getAsString(Policy));
549 llvm::raw_svector_ostream OS(Str);
554 switch (BT->getKind()) {
555 case BuiltinType::Bool:
558 case BuiltinType::Char_U:
559 case BuiltinType::UChar:
562 case BuiltinType::Char_S:
563 case BuiltinType::SChar:
575 analyze_printf::PrintfConversionSpecifier::sArg) {
601 bool dumpUnnamedRecord(
const RecordDecl *RD,
Expr *
E,
unsigned Depth) {
602 Expr *IndentLit = getIndentString(Depth);
604 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
605 : callPrintFunction(
"%s", {TypeLit}))
608 return dumpRecordValue(RD,
E, IndentLit, Depth);
621 Expr *RecordArg = makeOpaqueValueExpr(
E);
624 if (callPrintFunction(
" {\n"))
628 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
629 for (
const auto &
Base : CXXRD->bases()) {
637 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
643 Expr *FieldIndentArg = getIndentString(Depth + 1);
646 for (
auto *
D : RD->
decls()) {
647 auto *IFD = dyn_cast<IndirectFieldDecl>(
D);
648 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(
D);
649 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
655 getStringLiteral(FD->getName())};
657 if (FD->isBitField()) {
661 FD->getBitWidthValue());
675 if (
Field.isInvalid())
678 auto *InnerRD = FD->getType()->getAsRecordDecl();
679 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
680 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
682 if (callPrintFunction(Format, Args) ||
683 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
687 if (appendFormatSpecifier(FD->getType(), Format)) {
689 Args.push_back(
Field.get());
699 Args.push_back(FieldAddr.
get());
702 if (callPrintFunction(Format, Args))
707 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
708 : callPrintFunction(
"}\n");
711 Expr *buildWrapper() {
714 TheCall->
setType(Wrapper->getType());
735 diag::err_expected_struct_pointer_argument)
744 diag::err_incomplete_type))
753 switch (BT ? BT->getKind() : BuiltinType::Void) {
754 case BuiltinType::Dependent:
755 case BuiltinType::Overload:
756 case BuiltinType::BoundMember:
757 case BuiltinType::PseudoObject:
758 case BuiltinType::UnknownAny:
759 case BuiltinType::BuiltinFn:
765 diag::err_expected_callable_argument)
771 BuiltinDumpStructGenerator Generator(S, TheCall);
777 Expr *PtrArg = PtrArgResult.
get();
781 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
784 return Generator.buildWrapper();
796 if (
Call->getStmtClass() != Stmt::CallExprClass) {
797 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
798 <<
Call->getSourceRange();
802 auto CE = cast<CallExpr>(
Call);
803 if (CE->getCallee()->getType()->isBlockPointerType()) {
804 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
805 <<
Call->getSourceRange();
809 const Decl *TargetDecl = CE->getCalleeDecl();
810 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
811 if (FD->getBuiltinID()) {
812 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
813 <<
Call->getSourceRange();
817 if (isa<CXXPseudoDestructorExpr>(CE->getCallee()->IgnoreParens())) {
818 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
819 <<
Call->getSourceRange();
827 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
841 BuiltinCall->
setType(CE->getType());
845 BuiltinCall->
setArg(1, ChainResult.
get());
852class ScanfDiagnosticFormatHandler
856 using ComputeSizeFunction =
857 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
861 using DiagnoseFunction =
862 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
864 ComputeSizeFunction ComputeSizeArgument;
865 DiagnoseFunction Diagnose;
868 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
869 DiagnoseFunction Diagnose)
870 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
873 const char *StartSpecifier,
874 unsigned specifierLen)
override {
875 if (!FS.consumesDataArgument())
878 unsigned NulByte = 0;
879 switch ((FS.getConversionSpecifier().getKind())) {
892 analyze_format_string::OptionalAmount::HowSpecified::Constant)
897 std::optional<llvm::APSInt> DestSizeAPS =
898 ComputeSizeArgument(FS.getArgIndex());
902 unsigned DestSize = DestSizeAPS->getZExtValue();
904 if (DestSize < SourceSize)
905 Diagnose(FS.getArgIndex(), DestSize, SourceSize);
911class EstimateSizeFormatHandler
916 bool IsKernelCompatible =
true;
919 EstimateSizeFormatHandler(StringRef Format)
920 :
Size(
std::
min(Format.find(0), Format.size()) +
924 const char *,
unsigned SpecifierLen,
927 const size_t FieldWidth = computeFieldWidth(FS);
928 const size_t Precision = computePrecision(FS);
931 switch (FS.getConversionSpecifier().getKind()) {
935 Size += std::max(FieldWidth, (
size_t)1);
947 Size += std::max(FieldWidth, Precision);
963 Size += std::max(FieldWidth, 1 +
964 (Precision ? 1 + Precision
974 (Precision ? 1 + Precision : 0) +
984 (Precision ? 1 + Precision : 0) +
999 IsKernelCompatible =
false;
1000 Size += std::max(FieldWidth, 2 + Precision);
1012 Size += FS.hasPlusPrefix() || FS.hasSpacePrefix();
1014 if (FS.hasAlternativeForm()) {
1015 switch (FS.getConversionSpecifier().getKind()) {
1044 Size += (Precision ? 0 : 1);
1051 assert(SpecifierLen <= Size &&
"no underflow");
1052 Size -= SpecifierLen;
1056 size_t getSizeLowerBound()
const {
return Size; }
1057 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1062 size_t FieldWidth = 0;
1070 size_t Precision = 0;
1075 switch (FS.getConversionSpecifier().getKind()) {
1117 StringRef &FormatStrRef,
size_t &StrLen,
1119 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1120 Format && (Format->isOrdinary() || Format->isUTF8())) {
1121 FormatStrRef = Format->getString();
1124 assert(
T &&
"String literal not of constant array type!");
1125 size_t TypeSize =
T->getZExtSize();
1127 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1133void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1139 bool UseDABAttr =
false;
1142 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1144 UseDecl = DABAttr->getFunction();
1145 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1157 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1164 unsigned DABIndices = DABAttr->argIndices_size();
1165 unsigned NewIndex = Index < DABIndices
1166 ? DABAttr->argIndices_begin()[Index]
1169 return std::nullopt;
1173 auto ComputeExplicitObjectSizeArgument =
1174 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1175 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1177 return std::nullopt;
1178 unsigned NewIndex = *IndexOptional;
1182 return std::nullopt;
1188 auto ComputeSizeArgument =
1189 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1195 if (Index < FD->getNumParams()) {
1196 if (
const auto *POS =
1198 BOSType = POS->getType();
1201 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1203 return std::nullopt;
1204 unsigned NewIndex = *IndexOptional;
1207 return std::nullopt;
1209 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1212 return std::nullopt;
1215 return llvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1218 auto ComputeStrLenArgument =
1219 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1220 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1222 return std::nullopt;
1223 unsigned NewIndex = *IndexOptional;
1225 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1228 return std::nullopt;
1230 return llvm::APSInt::getUnsigned(
Result + 1).extOrTrunc(SizeTypeWidth);
1233 std::optional<llvm::APSInt> SourceSize;
1234 std::optional<llvm::APSInt> DestinationSize;
1235 unsigned DiagID = 0;
1236 bool IsChkVariant =
false;
1238 auto GetFunctionName = [&]() {
1244 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1245 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1247 FunctionName.consume_front(
"__builtin_");
1249 return FunctionName;
1252 switch (BuiltinID) {
1255 case Builtin::BI__builtin_strcpy:
1256 case Builtin::BIstrcpy: {
1257 DiagID = diag::warn_fortify_strlen_overflow;
1258 SourceSize = ComputeStrLenArgument(1);
1259 DestinationSize = ComputeSizeArgument(0);
1263 case Builtin::BI__builtin___strcpy_chk: {
1264 DiagID = diag::warn_fortify_strlen_overflow;
1265 SourceSize = ComputeStrLenArgument(1);
1266 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1267 IsChkVariant =
true;
1271 case Builtin::BIscanf:
1272 case Builtin::BIfscanf:
1273 case Builtin::BIsscanf: {
1274 unsigned FormatIndex = 1;
1275 unsigned DataIndex = 2;
1276 if (BuiltinID == Builtin::BIscanf) {
1281 const auto *FormatExpr =
1284 StringRef FormatStrRef;
1289 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1290 unsigned SourceSize) {
1291 DiagID = diag::warn_fortify_scanf_overflow;
1292 unsigned Index = ArgIndex + DataIndex;
1293 StringRef FunctionName = GetFunctionName();
1295 PDiag(DiagID) << FunctionName << (Index + 1)
1296 << DestSize << SourceSize);
1299 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1300 return ComputeSizeArgument(Index + DataIndex);
1302 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1303 const char *FormatBytes = FormatStrRef.data();
1314 case Builtin::BIsprintf:
1315 case Builtin::BI__builtin___sprintf_chk: {
1316 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1319 StringRef FormatStrRef;
1322 EstimateSizeFormatHandler H(FormatStrRef);
1323 const char *FormatBytes = FormatStrRef.data();
1325 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1327 DiagID = H.isKernelCompatible()
1328 ? diag::warn_format_overflow
1329 : diag::warn_format_overflow_non_kprintf;
1330 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1331 .extOrTrunc(SizeTypeWidth);
1332 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1333 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1334 IsChkVariant =
true;
1336 DestinationSize = ComputeSizeArgument(0);
1343 case Builtin::BI__builtin___memcpy_chk:
1344 case Builtin::BI__builtin___memmove_chk:
1345 case Builtin::BI__builtin___memset_chk:
1346 case Builtin::BI__builtin___strlcat_chk:
1347 case Builtin::BI__builtin___strlcpy_chk:
1348 case Builtin::BI__builtin___strncat_chk:
1349 case Builtin::BI__builtin___strncpy_chk:
1350 case Builtin::BI__builtin___stpncpy_chk:
1351 case Builtin::BI__builtin___memccpy_chk:
1352 case Builtin::BI__builtin___mempcpy_chk: {
1353 DiagID = diag::warn_builtin_chk_overflow;
1354 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1356 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1357 IsChkVariant =
true;
1361 case Builtin::BI__builtin___snprintf_chk:
1362 case Builtin::BI__builtin___vsnprintf_chk: {
1363 DiagID = diag::warn_builtin_chk_overflow;
1364 SourceSize = ComputeExplicitObjectSizeArgument(1);
1365 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1366 IsChkVariant =
true;
1370 case Builtin::BIstrncat:
1371 case Builtin::BI__builtin_strncat:
1372 case Builtin::BIstrncpy:
1373 case Builtin::BI__builtin_strncpy:
1374 case Builtin::BIstpncpy:
1375 case Builtin::BI__builtin_stpncpy: {
1381 DiagID = diag::warn_fortify_source_size_mismatch;
1382 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1383 DestinationSize = ComputeSizeArgument(0);
1387 case Builtin::BImemcpy:
1388 case Builtin::BI__builtin_memcpy:
1389 case Builtin::BImemmove:
1390 case Builtin::BI__builtin_memmove:
1391 case Builtin::BImemset:
1392 case Builtin::BI__builtin_memset:
1393 case Builtin::BImempcpy:
1394 case Builtin::BI__builtin_mempcpy: {
1395 DiagID = diag::warn_fortify_source_overflow;
1396 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1397 DestinationSize = ComputeSizeArgument(0);
1400 case Builtin::BIsnprintf:
1401 case Builtin::BI__builtin_snprintf:
1402 case Builtin::BIvsnprintf:
1403 case Builtin::BI__builtin_vsnprintf: {
1404 DiagID = diag::warn_fortify_source_size_mismatch;
1405 SourceSize = ComputeExplicitObjectSizeArgument(1);
1407 StringRef FormatStrRef;
1411 EstimateSizeFormatHandler H(FormatStrRef);
1412 const char *FormatBytes = FormatStrRef.data();
1414 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1416 llvm::APSInt FormatSize =
1417 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1418 .extOrTrunc(SizeTypeWidth);
1419 if (FormatSize > *SourceSize && *SourceSize != 0) {
1420 unsigned TruncationDiagID =
1421 H.isKernelCompatible() ? diag::warn_format_truncation
1422 : diag::warn_format_truncation_non_kprintf;
1425 SourceSize->toString(SpecifiedSizeStr, 10);
1426 FormatSize.toString(FormatSizeStr, 10);
1428 PDiag(TruncationDiagID)
1429 << GetFunctionName() << SpecifiedSizeStr
1434 DestinationSize = ComputeSizeArgument(0);
1438 if (!SourceSize || !DestinationSize ||
1439 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1442 StringRef FunctionName = GetFunctionName();
1446 DestinationSize->toString(DestinationStr, 10);
1447 SourceSize->toString(SourceStr, 10);
1450 << FunctionName << DestinationStr << SourceStr);
1463 while (S && !S->isSEHExceptScope())
1465 if (!S || !(S->getFlags() & NeededScopeFlags)) {
1468 << DRE->getDecl()->getIdentifier();
1480 "__builtin_alloca has invalid address space");
1488enum PointerAuthOpKind {
1537 llvm::raw_svector_ostream Str(
Value);
1546 Result = KeyValue->getZExtValue();
1550static std::pair<const ValueDecl *, CharUnits>
1557 const auto *BaseDecl =
1562 return {BaseDecl,
Result.Val.getLValueOffset()};
1566 bool RequireConstant =
false) {
1574 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1575 return OpKind != PAO_BlendInteger;
1577 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1578 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1579 OpKind == PAO_SignGeneric;
1588 }
else if (AllowsInteger(OpKind) &&
1595 <<
unsigned(OpKind == PAO_Discriminator ? 1
1596 : OpKind == PAO_BlendPointer ? 2
1597 : OpKind == PAO_BlendInteger ? 3
1599 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1609 if (!RequireConstant) {
1611 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1614 ? diag::warn_ptrauth_sign_null_pointer
1615 : diag::warn_ptrauth_auth_null_pointer)
1625 if (OpKind == PAO_Sign) {
1635 else if (isa<FunctionDecl>(BaseDecl))
1643 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1648 assert(OpKind == PAO_Discriminator);
1654 if (
Call->getBuiltinCallee() ==
1655 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1670 assert(
Pointer->getType()->isPointerType());
1676 if (!BaseDecl || !isa<VarDecl>(BaseDecl))
1682 assert(
Integer->getType()->isIntegerType());
1688 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1701 Call->setType(
Call->getArgs()[0]->getType());
1732 PointerAuthOpKind OpKind,
1733 bool RequireConstant) {
1744 Call->setType(
Call->getArgs()[0]->getType());
1760 Call->setType(
Call->getArgs()[0]->getType());
1769 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1772 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1773 if (!Literal || Literal->getCharByteWidth() != 1) {
1803 auto DiagSelect = [&]() -> std::optional<unsigned> {
1810 return std::optional<unsigned>{};
1825 diag::err_incomplete_type))
1829 "Unhandled non-object pointer case");
1857 if (PT->getPointeeType()->isFunctionType()) {
1859 diag::err_builtin_is_within_lifetime_invalid_arg)
1865 if (PT->getPointeeType()->isVariableArrayType()) {
1867 << 1 <<
"__builtin_is_within_lifetime";
1872 diag::err_builtin_is_within_lifetime_invalid_arg)
1885 llvm::Triple::ObjectFormatType CurObjFormat =
1887 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
1900 llvm::Triple::ArchType CurArch =
1902 if (llvm::is_contained(SupportedArchs, CurArch))
1912bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
1919 case llvm::Triple::arm:
1920 case llvm::Triple::armeb:
1921 case llvm::Triple::thumb:
1922 case llvm::Triple::thumbeb:
1924 case llvm::Triple::aarch64:
1925 case llvm::Triple::aarch64_32:
1926 case llvm::Triple::aarch64_be:
1928 case llvm::Triple::bpfeb:
1929 case llvm::Triple::bpfel:
1931 case llvm::Triple::hexagon:
1933 case llvm::Triple::mips:
1934 case llvm::Triple::mipsel:
1935 case llvm::Triple::mips64:
1936 case llvm::Triple::mips64el:
1938 case llvm::Triple::spirv:
1940 case llvm::Triple::systemz:
1942 case llvm::Triple::x86:
1943 case llvm::Triple::x86_64:
1945 case llvm::Triple::ppc:
1946 case llvm::Triple::ppcle:
1947 case llvm::Triple::ppc64:
1948 case llvm::Triple::ppc64le:
1950 case llvm::Triple::amdgcn:
1952 case llvm::Triple::riscv32:
1953 case llvm::Triple::riscv64:
1955 case llvm::Triple::loongarch32:
1956 case llvm::Triple::loongarch64:
1959 case llvm::Triple::wasm32:
1960 case llvm::Triple::wasm64:
1962 case llvm::Triple::nvptx:
1963 case llvm::Triple::nvptx64:
1975 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1976 << ArgIndex << 0 << ArgTy;
1986 EltTy = VecTy->getElementType();
1989 return S.
Diag(
Loc, diag::err_builtin_invalid_arg_type)
1990 << ArgIndex << 5 << ArgTy;
2000 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2001 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2002 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2003 "Expecting __builtin_cpu_...");
2005 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2007 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2008 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2009 (!IsCPUSupports && TInfo->supportsCpuIs()));
2011 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2018 ? diag::err_builtin_aix_os_unsupported
2019 : diag::err_builtin_target_unsupported)
2024 if (!isa<StringLiteral>(Arg))
2025 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2029 StringRef Feature = cast<StringLiteral>(Arg)->getString();
2076 TheCall->
setArg(0, Arg0);
2082 << 1 << 7 << Arg0Ty;
2092 TheCall->
setArg(1, Arg1);
2098 << 2 << 8 << Arg1Ty;
2107Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2112 unsigned ICEArguments = 0;
2119 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2121 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2126 if (ArgNo < TheCall->getNumArgs() &&
2129 ICEArguments &= ~(1 << ArgNo);
2133 switch (BuiltinID) {
2134 case Builtin::BI__builtin_cpu_supports:
2135 case Builtin::BI__builtin_cpu_is:
2140 case Builtin::BI__builtin_cpu_init:
2147 case Builtin::BI__builtin___CFStringMakeConstantString:
2151 *
this, BuiltinID, TheCall,
2152 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2155 "Wrong # arguments to builtin CFStringMakeConstantString");
2156 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2159 case Builtin::BI__builtin_ms_va_start:
2160 case Builtin::BI__builtin_stdarg_start:
2161 case Builtin::BI__builtin_va_start:
2162 if (BuiltinVAStart(BuiltinID, TheCall))
2165 case Builtin::BI__va_start: {
2167 case llvm::Triple::aarch64:
2168 case llvm::Triple::arm:
2169 case llvm::Triple::thumb:
2170 if (BuiltinVAStartARMMicrosoft(TheCall))
2174 if (BuiltinVAStart(BuiltinID, TheCall))
2182 case Builtin::BI_interlockedbittestandset_acq:
2183 case Builtin::BI_interlockedbittestandset_rel:
2184 case Builtin::BI_interlockedbittestandset_nf:
2185 case Builtin::BI_interlockedbittestandreset_acq:
2186 case Builtin::BI_interlockedbittestandreset_rel:
2187 case Builtin::BI_interlockedbittestandreset_nf:
2190 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2195 case Builtin::BI_bittest64:
2196 case Builtin::BI_bittestandcomplement64:
2197 case Builtin::BI_bittestandreset64:
2198 case Builtin::BI_bittestandset64:
2199 case Builtin::BI_interlockedbittestandreset64:
2200 case Builtin::BI_interlockedbittestandset64:
2203 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2204 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2208 case Builtin::BI__builtin_set_flt_rounds:
2211 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2212 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2213 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2214 llvm::Triple::ppc64le}))
2218 case Builtin::BI__builtin_isgreater:
2219 case Builtin::BI__builtin_isgreaterequal:
2220 case Builtin::BI__builtin_isless:
2221 case Builtin::BI__builtin_islessequal:
2222 case Builtin::BI__builtin_islessgreater:
2223 case Builtin::BI__builtin_isunordered:
2224 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2227 case Builtin::BI__builtin_fpclassify:
2228 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2231 case Builtin::BI__builtin_isfpclass:
2232 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2235 case Builtin::BI__builtin_isfinite:
2236 case Builtin::BI__builtin_isinf:
2237 case Builtin::BI__builtin_isinf_sign:
2238 case Builtin::BI__builtin_isnan:
2239 case Builtin::BI__builtin_issignaling:
2240 case Builtin::BI__builtin_isnormal:
2241 case Builtin::BI__builtin_issubnormal:
2242 case Builtin::BI__builtin_iszero:
2243 case Builtin::BI__builtin_signbit:
2244 case Builtin::BI__builtin_signbitf:
2245 case Builtin::BI__builtin_signbitl:
2246 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2249 case Builtin::BI__builtin_shufflevector:
2253 case Builtin::BI__builtin_prefetch:
2254 if (BuiltinPrefetch(TheCall))
2257 case Builtin::BI__builtin_alloca_with_align:
2258 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2259 if (BuiltinAllocaWithAlign(TheCall))
2262 case Builtin::BI__builtin_alloca:
2263 case Builtin::BI__builtin_alloca_uninitialized:
2270 case Builtin::BI__arithmetic_fence:
2271 if (BuiltinArithmeticFence(TheCall))
2274 case Builtin::BI__assume:
2275 case Builtin::BI__builtin_assume:
2276 if (BuiltinAssume(TheCall))
2279 case Builtin::BI__builtin_assume_aligned:
2280 if (BuiltinAssumeAligned(TheCall))
2283 case Builtin::BI__builtin_dynamic_object_size:
2284 case Builtin::BI__builtin_object_size:
2288 case Builtin::BI__builtin_longjmp:
2289 if (BuiltinLongjmp(TheCall))
2292 case Builtin::BI__builtin_setjmp:
2293 if (BuiltinSetjmp(TheCall))
2296 case Builtin::BI__builtin_classify_type:
2301 case Builtin::BI__builtin_complex:
2302 if (BuiltinComplex(TheCall))
2305 case Builtin::BI__builtin_constant_p: {
2314 case Builtin::BI__builtin_launder:
2316 case Builtin::BI__builtin_is_within_lifetime:
2318 case Builtin::BI__sync_fetch_and_add:
2319 case Builtin::BI__sync_fetch_and_add_1:
2320 case Builtin::BI__sync_fetch_and_add_2:
2321 case Builtin::BI__sync_fetch_and_add_4:
2322 case Builtin::BI__sync_fetch_and_add_8:
2323 case Builtin::BI__sync_fetch_and_add_16:
2324 case Builtin::BI__sync_fetch_and_sub:
2325 case Builtin::BI__sync_fetch_and_sub_1:
2326 case Builtin::BI__sync_fetch_and_sub_2:
2327 case Builtin::BI__sync_fetch_and_sub_4:
2328 case Builtin::BI__sync_fetch_and_sub_8:
2329 case Builtin::BI__sync_fetch_and_sub_16:
2330 case Builtin::BI__sync_fetch_and_or:
2331 case Builtin::BI__sync_fetch_and_or_1:
2332 case Builtin::BI__sync_fetch_and_or_2:
2333 case Builtin::BI__sync_fetch_and_or_4:
2334 case Builtin::BI__sync_fetch_and_or_8:
2335 case Builtin::BI__sync_fetch_and_or_16:
2336 case Builtin::BI__sync_fetch_and_and:
2337 case Builtin::BI__sync_fetch_and_and_1:
2338 case Builtin::BI__sync_fetch_and_and_2:
2339 case Builtin::BI__sync_fetch_and_and_4:
2340 case Builtin::BI__sync_fetch_and_and_8:
2341 case Builtin::BI__sync_fetch_and_and_16:
2342 case Builtin::BI__sync_fetch_and_xor:
2343 case Builtin::BI__sync_fetch_and_xor_1:
2344 case Builtin::BI__sync_fetch_and_xor_2:
2345 case Builtin::BI__sync_fetch_and_xor_4:
2346 case Builtin::BI__sync_fetch_and_xor_8:
2347 case Builtin::BI__sync_fetch_and_xor_16:
2348 case Builtin::BI__sync_fetch_and_nand:
2349 case Builtin::BI__sync_fetch_and_nand_1:
2350 case Builtin::BI__sync_fetch_and_nand_2:
2351 case Builtin::BI__sync_fetch_and_nand_4:
2352 case Builtin::BI__sync_fetch_and_nand_8:
2353 case Builtin::BI__sync_fetch_and_nand_16:
2354 case Builtin::BI__sync_add_and_fetch:
2355 case Builtin::BI__sync_add_and_fetch_1:
2356 case Builtin::BI__sync_add_and_fetch_2:
2357 case Builtin::BI__sync_add_and_fetch_4:
2358 case Builtin::BI__sync_add_and_fetch_8:
2359 case Builtin::BI__sync_add_and_fetch_16:
2360 case Builtin::BI__sync_sub_and_fetch:
2361 case Builtin::BI__sync_sub_and_fetch_1:
2362 case Builtin::BI__sync_sub_and_fetch_2:
2363 case Builtin::BI__sync_sub_and_fetch_4:
2364 case Builtin::BI__sync_sub_and_fetch_8:
2365 case Builtin::BI__sync_sub_and_fetch_16:
2366 case Builtin::BI__sync_and_and_fetch:
2367 case Builtin::BI__sync_and_and_fetch_1:
2368 case Builtin::BI__sync_and_and_fetch_2:
2369 case Builtin::BI__sync_and_and_fetch_4:
2370 case Builtin::BI__sync_and_and_fetch_8:
2371 case Builtin::BI__sync_and_and_fetch_16:
2372 case Builtin::BI__sync_or_and_fetch:
2373 case Builtin::BI__sync_or_and_fetch_1:
2374 case Builtin::BI__sync_or_and_fetch_2:
2375 case Builtin::BI__sync_or_and_fetch_4:
2376 case Builtin::BI__sync_or_and_fetch_8:
2377 case Builtin::BI__sync_or_and_fetch_16:
2378 case Builtin::BI__sync_xor_and_fetch:
2379 case Builtin::BI__sync_xor_and_fetch_1:
2380 case Builtin::BI__sync_xor_and_fetch_2:
2381 case Builtin::BI__sync_xor_and_fetch_4:
2382 case Builtin::BI__sync_xor_and_fetch_8:
2383 case Builtin::BI__sync_xor_and_fetch_16:
2384 case Builtin::BI__sync_nand_and_fetch:
2385 case Builtin::BI__sync_nand_and_fetch_1:
2386 case Builtin::BI__sync_nand_and_fetch_2:
2387 case Builtin::BI__sync_nand_and_fetch_4:
2388 case Builtin::BI__sync_nand_and_fetch_8:
2389 case Builtin::BI__sync_nand_and_fetch_16:
2390 case Builtin::BI__sync_val_compare_and_swap:
2391 case Builtin::BI__sync_val_compare_and_swap_1:
2392 case Builtin::BI__sync_val_compare_and_swap_2:
2393 case Builtin::BI__sync_val_compare_and_swap_4:
2394 case Builtin::BI__sync_val_compare_and_swap_8:
2395 case Builtin::BI__sync_val_compare_and_swap_16:
2396 case Builtin::BI__sync_bool_compare_and_swap:
2397 case Builtin::BI__sync_bool_compare_and_swap_1:
2398 case Builtin::BI__sync_bool_compare_and_swap_2:
2399 case Builtin::BI__sync_bool_compare_and_swap_4:
2400 case Builtin::BI__sync_bool_compare_and_swap_8:
2401 case Builtin::BI__sync_bool_compare_and_swap_16:
2402 case Builtin::BI__sync_lock_test_and_set:
2403 case Builtin::BI__sync_lock_test_and_set_1:
2404 case Builtin::BI__sync_lock_test_and_set_2:
2405 case Builtin::BI__sync_lock_test_and_set_4:
2406 case Builtin::BI__sync_lock_test_and_set_8:
2407 case Builtin::BI__sync_lock_test_and_set_16:
2408 case Builtin::BI__sync_lock_release:
2409 case Builtin::BI__sync_lock_release_1:
2410 case Builtin::BI__sync_lock_release_2:
2411 case Builtin::BI__sync_lock_release_4:
2412 case Builtin::BI__sync_lock_release_8:
2413 case Builtin::BI__sync_lock_release_16:
2414 case Builtin::BI__sync_swap:
2415 case Builtin::BI__sync_swap_1:
2416 case Builtin::BI__sync_swap_2:
2417 case Builtin::BI__sync_swap_4:
2418 case Builtin::BI__sync_swap_8:
2419 case Builtin::BI__sync_swap_16:
2420 return BuiltinAtomicOverloaded(TheCallResult);
2421 case Builtin::BI__sync_synchronize:
2425 case Builtin::BI__builtin_nontemporal_load:
2426 case Builtin::BI__builtin_nontemporal_store:
2427 return BuiltinNontemporalOverloaded(TheCallResult);
2428 case Builtin::BI__builtin_memcpy_inline: {
2441 case Builtin::BI__builtin_memset_inline: {
2452#define BUILTIN(ID, TYPE, ATTRS)
2453#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
2454 case Builtin::BI##ID: \
2455 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
2456#include "clang/Basic/Builtins.inc"
2457 case Builtin::BI__annotation:
2461 case Builtin::BI__builtin_annotation:
2465 case Builtin::BI__builtin_addressof:
2469 case Builtin::BI__builtin_function_start:
2473 case Builtin::BI__builtin_is_aligned:
2474 case Builtin::BI__builtin_align_up:
2475 case Builtin::BI__builtin_align_down:
2479 case Builtin::BI__builtin_add_overflow:
2480 case Builtin::BI__builtin_sub_overflow:
2481 case Builtin::BI__builtin_mul_overflow:
2485 case Builtin::BI__builtin_operator_new:
2486 case Builtin::BI__builtin_operator_delete: {
2487 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
2489 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
2494 case Builtin::BI__builtin_dump_struct:
2496 case Builtin::BI__builtin_expect_with_probability: {
2507 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
2514 bool LoseInfo =
false;
2515 Probability.convert(llvm::APFloat::IEEEdouble(),
2516 llvm::RoundingMode::Dynamic, &LoseInfo);
2517 if (!(Probability >= llvm::APFloat(0.0) &&
2518 Probability <= llvm::APFloat(1.0))) {
2525 case Builtin::BI__builtin_preserve_access_index:
2529 case Builtin::BI__builtin_call_with_static_chain:
2533 case Builtin::BI__exception_code:
2534 case Builtin::BI_exception_code:
2536 diag::err_seh___except_block))
2539 case Builtin::BI__exception_info:
2540 case Builtin::BI_exception_info:
2542 diag::err_seh___except_filter))
2545 case Builtin::BI__GetExceptionInfo:
2557 case Builtin::BIaddressof:
2558 case Builtin::BI__addressof:
2559 case Builtin::BIforward:
2560 case Builtin::BIforward_like:
2561 case Builtin::BImove:
2562 case Builtin::BImove_if_noexcept:
2563 case Builtin::BIas_const: {
2571 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
2572 BuiltinID == Builtin::BI__addressof;
2574 (ReturnsPointer ?
Result->isAnyPointerType()
2575 :
Result->isReferenceType()) &&
2577 Result->getPointeeType()))) {
2578 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
2584 case Builtin::BI__builtin_ptrauth_strip:
2586 case Builtin::BI__builtin_ptrauth_blend_discriminator:
2588 case Builtin::BI__builtin_ptrauth_sign_constant:
2591 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
2594 case Builtin::BI__builtin_ptrauth_auth:
2597 case Builtin::BI__builtin_ptrauth_sign_generic_data:
2599 case Builtin::BI__builtin_ptrauth_auth_and_resign:
2601 case Builtin::BI__builtin_ptrauth_string_discriminator:
2604 case Builtin::BIread_pipe:
2605 case Builtin::BIwrite_pipe:
2608 if (
OpenCL().checkBuiltinRWPipe(TheCall))
2611 case Builtin::BIreserve_read_pipe:
2612 case Builtin::BIreserve_write_pipe:
2613 case Builtin::BIwork_group_reserve_read_pipe:
2614 case Builtin::BIwork_group_reserve_write_pipe:
2615 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
2618 case Builtin::BIsub_group_reserve_read_pipe:
2619 case Builtin::BIsub_group_reserve_write_pipe:
2620 if (
OpenCL().checkSubgroupExt(TheCall) ||
2621 OpenCL().checkBuiltinReserveRWPipe(TheCall))
2624 case Builtin::BIcommit_read_pipe:
2625 case Builtin::BIcommit_write_pipe:
2626 case Builtin::BIwork_group_commit_read_pipe:
2627 case Builtin::BIwork_group_commit_write_pipe:
2628 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
2631 case Builtin::BIsub_group_commit_read_pipe:
2632 case Builtin::BIsub_group_commit_write_pipe:
2633 if (
OpenCL().checkSubgroupExt(TheCall) ||
2634 OpenCL().checkBuiltinCommitRWPipe(TheCall))
2637 case Builtin::BIget_pipe_num_packets:
2638 case Builtin::BIget_pipe_max_packets:
2639 if (
OpenCL().checkBuiltinPipePackets(TheCall))
2642 case Builtin::BIto_global:
2643 case Builtin::BIto_local:
2644 case Builtin::BIto_private:
2645 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
2649 case Builtin::BIenqueue_kernel:
2650 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
2653 case Builtin::BIget_kernel_work_group_size:
2654 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
2655 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
2658 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
2659 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
2660 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
2663 case Builtin::BI__builtin_os_log_format:
2666 case Builtin::BI__builtin_os_log_format_buffer_size:
2667 if (BuiltinOSLogFormat(TheCall))
2670 case Builtin::BI__builtin_frame_address:
2671 case Builtin::BI__builtin_return_address: {
2680 Result.Val.getInt() != 0)
2682 << ((BuiltinID == Builtin::BI__builtin_return_address)
2683 ?
"__builtin_return_address"
2684 :
"__builtin_frame_address")
2689 case Builtin::BI__builtin_nondeterministic_value: {
2690 if (BuiltinNonDeterministicValue(TheCall))
2697 case Builtin::BI__builtin_elementwise_abs: {
2705 EltTy = VecTy->getElementType();
2708 diag::err_builtin_invalid_arg_type)
2717 case Builtin::BI__builtin_elementwise_acos:
2718 case Builtin::BI__builtin_elementwise_asin:
2719 case Builtin::BI__builtin_elementwise_atan:
2720 case Builtin::BI__builtin_elementwise_ceil:
2721 case Builtin::BI__builtin_elementwise_cos:
2722 case Builtin::BI__builtin_elementwise_cosh:
2723 case Builtin::BI__builtin_elementwise_exp:
2724 case Builtin::BI__builtin_elementwise_exp2:
2725 case Builtin::BI__builtin_elementwise_floor:
2726 case Builtin::BI__builtin_elementwise_log:
2727 case Builtin::BI__builtin_elementwise_log2:
2728 case Builtin::BI__builtin_elementwise_log10:
2729 case Builtin::BI__builtin_elementwise_roundeven:
2730 case Builtin::BI__builtin_elementwise_round:
2731 case Builtin::BI__builtin_elementwise_rint:
2732 case Builtin::BI__builtin_elementwise_nearbyint:
2733 case Builtin::BI__builtin_elementwise_sin:
2734 case Builtin::BI__builtin_elementwise_sinh:
2735 case Builtin::BI__builtin_elementwise_sqrt:
2736 case Builtin::BI__builtin_elementwise_tan:
2737 case Builtin::BI__builtin_elementwise_tanh:
2738 case Builtin::BI__builtin_elementwise_trunc:
2739 case Builtin::BI__builtin_elementwise_canonicalize: {
2749 case Builtin::BI__builtin_elementwise_fma: {
2757 case Builtin::BI__builtin_elementwise_minimum:
2758 case Builtin::BI__builtin_elementwise_maximum:
2759 case Builtin::BI__builtin_elementwise_atan2:
2760 case Builtin::BI__builtin_elementwise_fmod:
2761 case Builtin::BI__builtin_elementwise_pow: {
2762 if (BuiltinElementwiseMath(TheCall,
true))
2769 case Builtin::BI__builtin_elementwise_add_sat:
2770 case Builtin::BI__builtin_elementwise_sub_sat: {
2771 if (BuiltinElementwiseMath(TheCall))
2779 EltTy = VecTy->getElementType();
2789 case Builtin::BI__builtin_elementwise_min:
2790 case Builtin::BI__builtin_elementwise_max:
2791 if (BuiltinElementwiseMath(TheCall))
2794 case Builtin::BI__builtin_elementwise_popcount:
2795 case Builtin::BI__builtin_elementwise_bitreverse: {
2804 EltTy = VecTy->getElementType();
2814 case Builtin::BI__builtin_elementwise_copysign: {
2834 diag::err_typecheck_call_different_arg_types)
2835 << MagnitudeTy << SignTy;
2843 case Builtin::BI__builtin_reduce_max:
2844 case Builtin::BI__builtin_reduce_min: {
2845 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2853 ElTy = TyA->getElementType();
2857 if (ElTy.isNull()) {
2866 case Builtin::BI__builtin_reduce_maximum:
2867 case Builtin::BI__builtin_reduce_minimum: {
2868 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2876 ElTy = TyA->getElementType();
2880 if (ElTy.isNull() || !ElTy->isFloatingType()) {
2892 case Builtin::BI__builtin_reduce_add:
2893 case Builtin::BI__builtin_reduce_mul:
2894 case Builtin::BI__builtin_reduce_xor:
2895 case Builtin::BI__builtin_reduce_or:
2896 case Builtin::BI__builtin_reduce_and: {
2897 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
2905 ElTy = TyA->getElementType();
2909 if (ElTy.isNull() || !ElTy->isIntegerType()) {
2919 case Builtin::BI__builtin_matrix_transpose:
2920 return BuiltinMatrixTranspose(TheCall, TheCallResult);
2922 case Builtin::BI__builtin_matrix_column_major_load:
2923 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
2925 case Builtin::BI__builtin_matrix_column_major_store:
2926 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
2928 case Builtin::BI__builtin_verbose_trap:
2933 case Builtin::BI__builtin_get_device_side_mangled_name: {
2934 auto Check = [](
CallExpr *TheCall) {
2940 auto *
D = DRE->getDecl();
2941 if (!isa<FunctionDecl>(
D) && !isa<VarDecl>(
D))
2946 if (!Check(TheCall)) {
2948 diag::err_hip_invalid_args_builtin_mangled_name);
2953 case Builtin::BI__builtin_popcountg:
2957 case Builtin::BI__builtin_clzg:
2958 case Builtin::BI__builtin_ctzg:
2963 case Builtin::BI__builtin_allow_runtime_check: {
2973 case Builtin::BI__builtin_counted_by_ref:
2974 if (BuiltinCountedByRef(TheCall))
2987 "Aux Target Builtin, but not an aux target?");
2989 if (CheckTSBuiltinFunctionCall(
3000 return TheCallResult;
3015 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3019 diag::err_argument_not_contiguous_bit_field)
3025 if (Format->getFirstArg() == 0)
3027 else if (IsVariadic)
3031 FSI->
FormatIdx = Format->getFormatIdx() - 1;
3055 if (isa<CXXNullPtrLiteralExpr>(
3070 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3071 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3072 Expr = ILE->getInit(0);
3082 const Expr *ArgExpr,
3086 S.
PDiag(diag::warn_null_arg)
3092 if (
auto nullability =
type->getNullability())
3103 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3109 llvm::SmallBitVector NonNullArgs;
3115 for (
const auto *Arg : Args)
3122 unsigned IdxAST = Idx.getASTIndex();
3123 if (IdxAST >= Args.size())
3125 if (NonNullArgs.empty())
3126 NonNullArgs.resize(Args.size());
3127 NonNullArgs.set(IdxAST);
3132 if (FDecl && (isa<FunctionDecl>(FDecl) || isa<ObjCMethodDecl>(FDecl))) {
3136 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3139 parms = cast<ObjCMethodDecl>(FDecl)->parameters();
3141 unsigned ParamIndex = 0;
3143 I !=
E; ++I, ++ParamIndex) {
3146 if (NonNullArgs.empty())
3147 NonNullArgs.resize(Args.size());
3149 NonNullArgs.set(ParamIndex);
3156 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3161 type = blockType->getPointeeType();
3175 if (NonNullArgs.empty())
3176 NonNullArgs.resize(Args.size());
3178 NonNullArgs.set(Index);
3187 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3188 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3189 if (NonNullArgs[ArgIndex])
3195 StringRef ParamName,
QualType ArgTy,
3223 if (ArgAlign < ParamAlign)
3224 Diag(
Loc, diag::warn_param_mismatched_alignment)
3226 << ParamName << (FDecl !=
nullptr) << FDecl;
3230 const Expr *ThisArg,
3232 if (!FD || Args.empty())
3234 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3235 if (Idx == LifetimeCaptureByAttr::GLOBAL ||
3236 Idx == LifetimeCaptureByAttr::UNKNOWN)
3238 if (IsMemberFunction && Idx == 0)
3240 return Args[Idx - IsMemberFunction];
3242 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3247 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3248 for (
int CapturingParamIdx :
Attr->params()) {
3251 if (CapturingParamIdx == LifetimeCaptureByAttr::THIS &&
3252 isa<CXXConstructorDecl>(FD))
3254 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3262 I + IsMemberFunction);
3264 if (IsMemberFunction) {
3272 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3285 llvm::SmallBitVector CheckedVarArgs;
3289 CheckedVarArgs.resize(Args.size());
3291 CheckFormatArguments(I, Args, IsMemberFunction, CallType,
Loc,
Range,
3298 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3302 : isa_and_nonnull<FunctionDecl>(FDecl)
3303 ? cast<FunctionDecl>(FDecl)->getNumParams()
3304 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3305 ? cast<ObjCMethodDecl>(FDecl)->param_size()
3308 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3310 if (
const Expr *Arg = Args[ArgIdx]) {
3311 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3318 if (FDecl || Proto) {
3323 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3324 CheckArgumentWithTypeTag(I, Args,
Loc);
3330 if (!Proto && FDecl) {
3332 if (isa_and_nonnull<FunctionProtoType>(FT))
3338 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3340 bool IsScalableArg =
false;
3341 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3343 if (
const Expr *Arg = Args[ArgIdx]) {
3355 IsScalableArg =
true;
3357 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
3366 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
3367 llvm::StringMap<bool> CallerFeatureMap;
3369 if (!CallerFeatureMap.contains(
"sme"))
3370 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3372 Diag(
Loc, diag::err_sme_call_in_non_sme_target);
3379 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
3381 (IsScalableArg || IsScalableRet)) {
3382 bool IsCalleeStreaming =
3384 bool IsCalleeStreamingCompatible =
3388 if (!IsCalleeStreamingCompatible &&
3392 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3395 Diag(
Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
3406 bool CallerHasZAState =
false;
3407 bool CallerHasZT0State =
false;
3409 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
3411 CallerHasZAState =
true;
3413 CallerHasZT0State =
true;
3417 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3419 CallerHasZT0State |=
3421 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
3427 Diag(
Loc, diag::err_sme_za_call_no_za_state);
3430 Diag(
Loc, diag::err_sme_zt0_call_no_zt0_state);
3434 Diag(
Loc, diag::err_sme_unimplemented_za_save_restore);
3435 Diag(
Loc, diag::note_sme_use_preserves_za);
3440 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
3441 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
3442 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
3443 if (!Arg->isValueDependent()) {
3445 if (Arg->EvaluateAsInt(Align,
Context)) {
3446 const llvm::APSInt &I = Align.
Val.
getInt();
3447 if (!I.isPowerOf2())
3448 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
3449 << Arg->getSourceRange();
3452 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
3475 auto *Ctor = cast<CXXConstructorDecl>(FDecl);
3480 checkCall(FDecl, Proto,
nullptr, Args,
true,
3486 bool IsMemberOperatorCall = isa<CXXOperatorCallExpr>(TheCall) &&
3487 isa<CXXMethodDecl>(FDecl);
3488 bool IsMemberFunction = isa<CXXMemberCallExpr>(TheCall) ||
3489 IsMemberOperatorCall;
3495 Expr *ImplicitThis =
nullptr;
3500 ImplicitThis = Args[0];
3503 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
3506 cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument();
3518 cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType());
3520 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
3538 CheckAbsoluteValueFunction(TheCall, FDecl);
3539 CheckMaxUnsignedZero(TheCall, FDecl);
3540 CheckInfNaNFunction(TheCall, FDecl);
3551 case Builtin::BIstrlcpy:
3552 case Builtin::BIstrlcat:
3553 CheckStrlcpycatArguments(TheCall, FnInfo);
3555 case Builtin::BIstrncat:
3556 CheckStrncatArguments(TheCall, FnInfo);
3558 case Builtin::BIfree:
3559 CheckFreeArguments(TheCall);
3562 CheckMemaccessArguments(TheCall, CMId, FnInfo);
3571 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
3572 Ty =
V->getType().getNonReferenceType();
3573 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
3574 Ty = F->getType().getNonReferenceType();
3611 if (!llvm::isValidAtomicOrderingCABI(Ordering))
3614 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
3616 case AtomicExpr::AO__c11_atomic_init:
3617 case AtomicExpr::AO__opencl_atomic_init:
3618 llvm_unreachable(
"There is no ordering argument for an init");
3620 case AtomicExpr::AO__c11_atomic_load:
3621 case AtomicExpr::AO__opencl_atomic_load:
3622 case AtomicExpr::AO__hip_atomic_load:
3623 case AtomicExpr::AO__atomic_load_n:
3624 case AtomicExpr::AO__atomic_load:
3625 case AtomicExpr::AO__scoped_atomic_load_n:
3626 case AtomicExpr::AO__scoped_atomic_load:
3627 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
3628 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3630 case AtomicExpr::AO__c11_atomic_store:
3631 case AtomicExpr::AO__opencl_atomic_store:
3632 case AtomicExpr::AO__hip_atomic_store:
3633 case AtomicExpr::AO__atomic_store:
3634 case AtomicExpr::AO__atomic_store_n:
3635 case AtomicExpr::AO__scoped_atomic_store:
3636 case AtomicExpr::AO__scoped_atomic_store_n:
3637 case AtomicExpr::AO__atomic_clear:
3638 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
3639 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
3640 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
3649 CallExpr *TheCall = cast<CallExpr>(TheCallResult.
get());
3699 const unsigned NumForm = ClearByte + 1;
3700 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
3701 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
3709 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
3710 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
3711 "need to update code for modified forms");
3712 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
3713 AtomicExpr::AO__atomic_xor_fetch + 1 ==
3714 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
3715 "need to update code for modified C11 atomics");
3716 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
3717 Op <= AtomicExpr::AO__opencl_atomic_store;
3718 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
3719 Op <= AtomicExpr::AO__hip_atomic_store;
3720 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
3721 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
3722 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
3723 Op <= AtomicExpr::AO__c11_atomic_store) ||
3725 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
3726 Op == AtomicExpr::AO__atomic_store_n ||
3727 Op == AtomicExpr::AO__atomic_exchange_n ||
3728 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
3729 Op == AtomicExpr::AO__scoped_atomic_load_n ||
3730 Op == AtomicExpr::AO__scoped_atomic_store_n ||
3731 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
3732 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
3736 enum ArithOpExtraValueType {
3741 unsigned ArithAllows = AOEVT_None;
3744 case AtomicExpr::AO__c11_atomic_init:
3745 case AtomicExpr::AO__opencl_atomic_init:
3749 case AtomicExpr::AO__c11_atomic_load:
3750 case AtomicExpr::AO__opencl_atomic_load:
3751 case AtomicExpr::AO__hip_atomic_load:
3752 case AtomicExpr::AO__atomic_load_n:
3753 case AtomicExpr::AO__scoped_atomic_load_n:
3757 case AtomicExpr::AO__atomic_load:
3758 case AtomicExpr::AO__scoped_atomic_load:
3762 case AtomicExpr::AO__c11_atomic_store:
3763 case AtomicExpr::AO__opencl_atomic_store:
3764 case AtomicExpr::AO__hip_atomic_store:
3765 case AtomicExpr::AO__atomic_store:
3766 case AtomicExpr::AO__atomic_store_n:
3767 case AtomicExpr::AO__scoped_atomic_store:
3768 case AtomicExpr::AO__scoped_atomic_store_n:
3771 case AtomicExpr::AO__atomic_fetch_add:
3772 case AtomicExpr::AO__atomic_fetch_sub:
3773 case AtomicExpr::AO__atomic_add_fetch:
3774 case AtomicExpr::AO__atomic_sub_fetch:
3775 case AtomicExpr::AO__scoped_atomic_fetch_add:
3776 case AtomicExpr::AO__scoped_atomic_fetch_sub:
3777 case AtomicExpr::AO__scoped_atomic_add_fetch:
3778 case AtomicExpr::AO__scoped_atomic_sub_fetch:
3779 case AtomicExpr::AO__c11_atomic_fetch_add:
3780 case AtomicExpr::AO__c11_atomic_fetch_sub:
3781 case AtomicExpr::AO__opencl_atomic_fetch_add:
3782 case AtomicExpr::AO__opencl_atomic_fetch_sub:
3783 case AtomicExpr::AO__hip_atomic_fetch_add:
3784 case AtomicExpr::AO__hip_atomic_fetch_sub:
3785 ArithAllows = AOEVT_Pointer | AOEVT_FP;
3788 case AtomicExpr::AO__atomic_fetch_max:
3789 case AtomicExpr::AO__atomic_fetch_min:
3790 case AtomicExpr::AO__atomic_max_fetch:
3791 case AtomicExpr::AO__atomic_min_fetch:
3792 case AtomicExpr::AO__scoped_atomic_fetch_max:
3793 case AtomicExpr::AO__scoped_atomic_fetch_min:
3794 case AtomicExpr::AO__scoped_atomic_max_fetch:
3795 case AtomicExpr::AO__scoped_atomic_min_fetch:
3796 case AtomicExpr::AO__c11_atomic_fetch_max:
3797 case AtomicExpr::AO__c11_atomic_fetch_min:
3798 case AtomicExpr::AO__opencl_atomic_fetch_max:
3799 case AtomicExpr::AO__opencl_atomic_fetch_min:
3800 case AtomicExpr::AO__hip_atomic_fetch_max:
3801 case AtomicExpr::AO__hip_atomic_fetch_min:
3802 ArithAllows = AOEVT_FP;
3805 case AtomicExpr::AO__c11_atomic_fetch_and:
3806 case AtomicExpr::AO__c11_atomic_fetch_or:
3807 case AtomicExpr::AO__c11_atomic_fetch_xor:
3808 case AtomicExpr::AO__hip_atomic_fetch_and:
3809 case AtomicExpr::AO__hip_atomic_fetch_or:
3810 case AtomicExpr::AO__hip_atomic_fetch_xor:
3811 case AtomicExpr::AO__c11_atomic_fetch_nand:
3812 case AtomicExpr::AO__opencl_atomic_fetch_and:
3813 case AtomicExpr::AO__opencl_atomic_fetch_or:
3814 case AtomicExpr::AO__opencl_atomic_fetch_xor:
3815 case AtomicExpr::AO__atomic_fetch_and:
3816 case AtomicExpr::AO__atomic_fetch_or:
3817 case AtomicExpr::AO__atomic_fetch_xor:
3818 case AtomicExpr::AO__atomic_fetch_nand:
3819 case AtomicExpr::AO__atomic_and_fetch:
3820 case AtomicExpr::AO__atomic_or_fetch:
3821 case AtomicExpr::AO__atomic_xor_fetch:
3822 case AtomicExpr::AO__atomic_nand_fetch:
3823 case AtomicExpr::AO__scoped_atomic_fetch_and:
3824 case AtomicExpr::AO__scoped_atomic_fetch_or:
3825 case AtomicExpr::AO__scoped_atomic_fetch_xor:
3826 case AtomicExpr::AO__scoped_atomic_fetch_nand:
3827 case AtomicExpr::AO__scoped_atomic_and_fetch:
3828 case AtomicExpr::AO__scoped_atomic_or_fetch:
3829 case AtomicExpr::AO__scoped_atomic_xor_fetch:
3830 case AtomicExpr::AO__scoped_atomic_nand_fetch:
3834 case AtomicExpr::AO__c11_atomic_exchange:
3835 case AtomicExpr::AO__hip_atomic_exchange:
3836 case AtomicExpr::AO__opencl_atomic_exchange:
3837 case AtomicExpr::AO__atomic_exchange_n:
3838 case AtomicExpr::AO__scoped_atomic_exchange_n:
3842 case AtomicExpr::AO__atomic_exchange:
3843 case AtomicExpr::AO__scoped_atomic_exchange:
3847 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
3848 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
3849 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
3850 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
3851 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
3852 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
3856 case AtomicExpr::AO__atomic_compare_exchange:
3857 case AtomicExpr::AO__atomic_compare_exchange_n:
3858 case AtomicExpr::AO__scoped_atomic_compare_exchange:
3859 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
3863 case AtomicExpr::AO__atomic_test_and_set:
3864 Form = TestAndSetByte;
3867 case AtomicExpr::AO__atomic_clear:
3872 unsigned AdjustedNumArgs = NumArgs[Form];
3873 if ((IsOpenCL || IsHIP || IsScoped) &&
3874 Op != AtomicExpr::AO__opencl_atomic_init)
3877 if (Args.size() < AdjustedNumArgs) {
3878 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
3879 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3882 }
else if (Args.size() > AdjustedNumArgs) {
3883 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
3884 diag::err_typecheck_call_too_many_args)
3885 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
3891 Expr *Ptr = Args[0];
3896 Ptr = ConvertedPtr.
get();
3899 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3909 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
3915 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
3921 }
else if (Form != Load && Form != LoadCopy) {
3923 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
3929 if (Form != TestAndSetByte && Form != ClearByte) {
3932 diag::err_incomplete_type))
3936 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
3946 pointerType->getPointeeType().getCVRQualifiers());
3954 if (Form == Arithmetic) {
3957 auto IsAllowedValueType = [&](
QualType ValType,
3958 unsigned AllowedType) ->
bool {
3962 return AllowedType & AOEVT_Pointer;
3968 &llvm::APFloat::x87DoubleExtended())
3972 if (!IsAllowedValueType(ValType, ArithAllows)) {
3973 auto DID = ArithAllows & AOEVT_FP
3974 ? (ArithAllows & AOEVT_Pointer
3975 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
3976 : diag::err_atomic_op_needs_atomic_int_or_fp)
3977 : diag::err_atomic_op_needs_atomic_int;
3984 diag::err_incomplete_type)) {
3990 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4001 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4017 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4029 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4032 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4038 bool IsPassedByAddress =
false;
4039 if (!IsC11 && !IsHIP && !IsN) {
4041 IsPassedByAddress =
true;
4046 APIOrderedArgs.push_back(Args[0]);
4050 APIOrderedArgs.push_back(Args[1]);
4056 APIOrderedArgs.push_back(Args[2]);
4057 APIOrderedArgs.push_back(Args[1]);
4060 APIOrderedArgs.push_back(Args[2]);
4061 APIOrderedArgs.push_back(Args[3]);
4062 APIOrderedArgs.push_back(Args[1]);
4065 APIOrderedArgs.push_back(Args[2]);
4066 APIOrderedArgs.push_back(Args[4]);
4067 APIOrderedArgs.push_back(Args[1]);
4068 APIOrderedArgs.push_back(Args[3]);
4071 APIOrderedArgs.push_back(Args[2]);
4072 APIOrderedArgs.push_back(Args[4]);
4073 APIOrderedArgs.push_back(Args[5]);
4074 APIOrderedArgs.push_back(Args[1]);
4075 APIOrderedArgs.push_back(Args[3]);
4077 case TestAndSetByte:
4079 APIOrderedArgs.push_back(Args[1]);
4083 APIOrderedArgs.append(Args.begin(), Args.end());
4090 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4092 if (i < NumVals[Form] + 1) {
4105 assert(Form != Load);
4108 else if (Form ==
Init || Form == Arithmetic)
4110 else if (Form ==
Copy || Form == Xchg) {
4111 if (IsPassedByAddress) {
4118 Expr *ValArg = APIOrderedArgs[i];
4125 AS = PtrTy->getPointeeType().getAddressSpace();
4134 if (IsPassedByAddress)
4154 APIOrderedArgs[i] = Arg.
get();
4159 SubExprs.push_back(Ptr);
4163 SubExprs.push_back(APIOrderedArgs[1]);
4166 case TestAndSetByte:
4168 SubExprs.push_back(APIOrderedArgs[1]);
4174 SubExprs.push_back(APIOrderedArgs[2]);
4175 SubExprs.push_back(APIOrderedArgs[1]);
4179 SubExprs.push_back(APIOrderedArgs[3]);
4180 SubExprs.push_back(APIOrderedArgs[1]);
4181 SubExprs.push_back(APIOrderedArgs[2]);
4184 SubExprs.push_back(APIOrderedArgs[3]);
4185 SubExprs.push_back(APIOrderedArgs[1]);
4186 SubExprs.push_back(APIOrderedArgs[4]);
4187 SubExprs.push_back(APIOrderedArgs[2]);
4190 SubExprs.push_back(APIOrderedArgs[4]);
4191 SubExprs.push_back(APIOrderedArgs[1]);
4192 SubExprs.push_back(APIOrderedArgs[5]);
4193 SubExprs.push_back(APIOrderedArgs[2]);
4194 SubExprs.push_back(APIOrderedArgs[3]);
4199 if (SubExprs.size() >= 2 && Form !=
Init) {
4200 std::optional<llvm::APSInt>
Success =
4201 SubExprs[1]->getIntegerConstantExpr(
Context);
4203 Diag(SubExprs[1]->getBeginLoc(),
4204 diag::warn_atomic_op_has_invalid_memory_order)
4205 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4206 << SubExprs[1]->getSourceRange();
4208 if (SubExprs.size() >= 5) {
4209 if (std::optional<llvm::APSInt> Failure =
4210 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4211 if (!llvm::is_contained(
4212 {llvm::AtomicOrderingCABI::relaxed,
4213 llvm::AtomicOrderingCABI::consume,
4214 llvm::AtomicOrderingCABI::acquire,
4215 llvm::AtomicOrderingCABI::seq_cst},
4216 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4217 Diag(SubExprs[3]->getBeginLoc(),
4218 diag::warn_atomic_op_has_invalid_memory_order)
4219 << 2 << SubExprs[3]->getSourceRange();
4226 auto *
Scope = Args[Args.size() - 1];
4227 if (std::optional<llvm::APSInt>
Result =
4229 if (!ScopeModel->isValid(
Result->getZExtValue()))
4230 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_synch_scope)
4231 <<
Scope->getSourceRange();
4233 SubExprs.push_back(
Scope);
4239 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4240 Op == AtomicExpr::AO__c11_atomic_store ||
4241 Op == AtomicExpr::AO__opencl_atomic_load ||
4242 Op == AtomicExpr::AO__hip_atomic_load ||
4243 Op == AtomicExpr::AO__opencl_atomic_store ||
4244 Op == AtomicExpr::AO__hip_atomic_store) &&
4247 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4248 Op == AtomicExpr::AO__opencl_atomic_load ||
4249 Op == AtomicExpr::AO__hip_atomic_load)
4254 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4270 assert(Fn &&
"builtin call without direct callee!");
4281 E->setArg(ArgIndex, Arg.
get());
4293 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4295 <<
Callee->getSourceRange();
4308 FirstArg = FirstArgResult.
get();
4309 TheCall->
setArg(0, FirstArg);
4321 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4356#define BUILTIN_ROW(x) \
4357 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
4358 Builtin::BI##x##_8, Builtin::BI##x##_16 }
4360 static const unsigned BuiltinIndices[][5] = {
4386 case 1: SizeIndex = 0;
break;
4387 case 2: SizeIndex = 1;
break;
4388 case 4: SizeIndex = 2;
break;
4389 case 8: SizeIndex = 3;
break;
4390 case 16: SizeIndex = 4;
break;
4402 unsigned BuiltinIndex, NumFixed = 1;
4403 bool WarnAboutSemanticsChange =
false;
4404 switch (BuiltinID) {
4405 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
4406 case Builtin::BI__sync_fetch_and_add:
4407 case Builtin::BI__sync_fetch_and_add_1:
4408 case Builtin::BI__sync_fetch_and_add_2:
4409 case Builtin::BI__sync_fetch_and_add_4:
4410 case Builtin::BI__sync_fetch_and_add_8:
4411 case Builtin::BI__sync_fetch_and_add_16:
4415 case Builtin::BI__sync_fetch_and_sub:
4416 case Builtin::BI__sync_fetch_and_sub_1:
4417 case Builtin::BI__sync_fetch_and_sub_2:
4418 case Builtin::BI__sync_fetch_and_sub_4:
4419 case Builtin::BI__sync_fetch_and_sub_8:
4420 case Builtin::BI__sync_fetch_and_sub_16:
4424 case Builtin::BI__sync_fetch_and_or:
4425 case Builtin::BI__sync_fetch_and_or_1:
4426 case Builtin::BI__sync_fetch_and_or_2:
4427 case Builtin::BI__sync_fetch_and_or_4:
4428 case Builtin::BI__sync_fetch_and_or_8:
4429 case Builtin::BI__sync_fetch_and_or_16:
4433 case Builtin::BI__sync_fetch_and_and:
4434 case Builtin::BI__sync_fetch_and_and_1:
4435 case Builtin::BI__sync_fetch_and_and_2:
4436 case Builtin::BI__sync_fetch_and_and_4:
4437 case Builtin::BI__sync_fetch_and_and_8:
4438 case Builtin::BI__sync_fetch_and_and_16:
4442 case Builtin::BI__sync_fetch_and_xor:
4443 case Builtin::BI__sync_fetch_and_xor_1:
4444 case Builtin::BI__sync_fetch_and_xor_2:
4445 case Builtin::BI__sync_fetch_and_xor_4:
4446 case Builtin::BI__sync_fetch_and_xor_8:
4447 case Builtin::BI__sync_fetch_and_xor_16:
4451 case Builtin::BI__sync_fetch_and_nand:
4452 case Builtin::BI__sync_fetch_and_nand_1:
4453 case Builtin::BI__sync_fetch_and_nand_2:
4454 case Builtin::BI__sync_fetch_and_nand_4:
4455 case Builtin::BI__sync_fetch_and_nand_8:
4456 case Builtin::BI__sync_fetch_and_nand_16:
4458 WarnAboutSemanticsChange =
true;
4461 case Builtin::BI__sync_add_and_fetch:
4462 case Builtin::BI__sync_add_and_fetch_1:
4463 case Builtin::BI__sync_add_and_fetch_2:
4464 case Builtin::BI__sync_add_and_fetch_4:
4465 case Builtin::BI__sync_add_and_fetch_8:
4466 case Builtin::BI__sync_add_and_fetch_16:
4470 case Builtin::BI__sync_sub_and_fetch:
4471 case Builtin::BI__sync_sub_and_fetch_1:
4472 case Builtin::BI__sync_sub_and_fetch_2:
4473 case Builtin::BI__sync_sub_and_fetch_4:
4474 case Builtin::BI__sync_sub_and_fetch_8:
4475 case Builtin::BI__sync_sub_and_fetch_16:
4479 case Builtin::BI__sync_and_and_fetch:
4480 case Builtin::BI__sync_and_and_fetch_1:
4481 case Builtin::BI__sync_and_and_fetch_2:
4482 case Builtin::BI__sync_and_and_fetch_4:
4483 case Builtin::BI__sync_and_and_fetch_8:
4484 case Builtin::BI__sync_and_and_fetch_16:
4488 case Builtin::BI__sync_or_and_fetch:
4489 case Builtin::BI__sync_or_and_fetch_1:
4490 case Builtin::BI__sync_or_and_fetch_2:
4491 case Builtin::BI__sync_or_and_fetch_4:
4492 case Builtin::BI__sync_or_and_fetch_8:
4493 case Builtin::BI__sync_or_and_fetch_16:
4497 case Builtin::BI__sync_xor_and_fetch:
4498 case Builtin::BI__sync_xor_and_fetch_1:
4499 case Builtin::BI__sync_xor_and_fetch_2:
4500 case Builtin::BI__sync_xor_and_fetch_4:
4501 case Builtin::BI__sync_xor_and_fetch_8:
4502 case Builtin::BI__sync_xor_and_fetch_16:
4506 case Builtin::BI__sync_nand_and_fetch:
4507 case Builtin::BI__sync_nand_and_fetch_1:
4508 case Builtin::BI__sync_nand_and_fetch_2:
4509 case Builtin::BI__sync_nand_and_fetch_4:
4510 case Builtin::BI__sync_nand_and_fetch_8:
4511 case Builtin::BI__sync_nand_and_fetch_16:
4513 WarnAboutSemanticsChange =
true;
4516 case Builtin::BI__sync_val_compare_and_swap:
4517 case Builtin::BI__sync_val_compare_and_swap_1:
4518 case Builtin::BI__sync_val_compare_and_swap_2:
4519 case Builtin::BI__sync_val_compare_and_swap_4:
4520 case Builtin::BI__sync_val_compare_and_swap_8:
4521 case Builtin::BI__sync_val_compare_and_swap_16:
4526 case Builtin::BI__sync_bool_compare_and_swap:
4527 case Builtin::BI__sync_bool_compare_and_swap_1:
4528 case Builtin::BI__sync_bool_compare_and_swap_2:
4529 case Builtin::BI__sync_bool_compare_and_swap_4:
4530 case Builtin::BI__sync_bool_compare_and_swap_8:
4531 case Builtin::BI__sync_bool_compare_and_swap_16:
4537 case Builtin::BI__sync_lock_test_and_set:
4538 case Builtin::BI__sync_lock_test_and_set_1:
4539 case Builtin::BI__sync_lock_test_and_set_2:
4540 case Builtin::BI__sync_lock_test_and_set_4:
4541 case Builtin::BI__sync_lock_test_and_set_8:
4542 case Builtin::BI__sync_lock_test_and_set_16:
4546 case Builtin::BI__sync_lock_release:
4547 case Builtin::BI__sync_lock_release_1:
4548 case Builtin::BI__sync_lock_release_2:
4549 case Builtin::BI__sync_lock_release_4:
4550 case Builtin::BI__sync_lock_release_8:
4551 case Builtin::BI__sync_lock_release_16:
4557 case Builtin::BI__sync_swap:
4558 case Builtin::BI__sync_swap_1:
4559 case Builtin::BI__sync_swap_2:
4560 case Builtin::BI__sync_swap_4:
4561 case Builtin::BI__sync_swap_8:
4562 case Builtin::BI__sync_swap_16:
4570 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4571 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
4572 <<
Callee->getSourceRange();
4576 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
4577 <<
Callee->getSourceRange();
4579 if (WarnAboutSemanticsChange) {
4580 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
4581 <<
Callee->getSourceRange();
4586 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
4589 if (NewBuiltinID == BuiltinID)
4590 NewBuiltinDecl = FDecl;
4596 assert(Res.getFoundDecl());
4597 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
4598 if (!NewBuiltinDecl)
4605 for (
unsigned i = 0; i != NumFixed; ++i) {
4636 CK_BuiltinFnToFnPtr);
4648 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
4649 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
4653 return TheCallResult;
4662 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
4663 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
4664 "Unexpected nontemporal load/store builtin!");
4665 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
4666 unsigned numArgs = isStore ? 2 : 1;
4676 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
4682 PointerArg = PointerArgResult.
get();
4683 TheCall->
setArg(numArgs - 1, PointerArg);
4687 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
4700 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
4707 return TheCallResult;
4719 return TheCallResult;
4726 auto *
Literal = dyn_cast<StringLiteral>(Arg);
4728 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
4729 Literal = ObjcLiteral->getString();
4733 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
4751 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
4752 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
4753 TT.getArch() == llvm::Triple::aarch64_32);
4754 bool IsWindows = TT.isOSWindows();
4755 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
4756 if (IsX64 || IsAArch64) {
4763 return S.
Diag(Fn->getBeginLoc(),
4764 diag::err_ms_va_start_used_in_sysv_function);
4772 return S.
Diag(Fn->getBeginLoc(),
4773 diag::err_va_start_used_in_wrong_abi_function)
4780 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
4788 bool IsVariadic =
false;
4791 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
4792 IsVariadic =
Block->isVariadic();
4793 Params =
Block->parameters();
4794 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
4797 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
4798 IsVariadic = MD->isVariadic();
4800 Params = MD->parameters();
4801 }
else if (isa<CapturedDecl>(Caller)) {
4803 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
4807 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
4812 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
4817 *LastParam = Params.empty() ? nullptr : Params.back();
4822bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
4847 bool SecondArgIsLastNamedArgument =
false;
4849 if (std::optional<llvm::APSInt> Val =
4858 bool IsCRegister =
false;
4860 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
4861 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
4862 SecondArgIsLastNamedArgument = PV == LastParam;
4864 Type = PV->getType();
4865 ParamLoc = PV->getLocation();
4871 if (!SecondArgIsLastNamedArgument)
4873 diag::warn_second_arg_of_va_start_not_last_named_param);
4878 if (!Context.isPromotableIntegerType(Type))
4880 if (!Type->isEnumeralType())
4882 const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();
4884 Context.typesAreCompatible(ED->getPromotionType(), Type));
4886 unsigned Reason = 0;
4888 else if (IsCRegister) Reason = 2;
4889 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
4890 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
4897 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
4917 if (
Call->getNumArgs() < 3)
4919 diag::err_typecheck_call_too_few_args_at_least)
4920 << 0 << 3 <<
Call->getNumArgs()
4933 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
4936 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
4941 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
4943 << Arg1->
getType() << ConstCharPtrTy << 1
4946 << 2 << Arg1->
getType() << ConstCharPtrTy;
4951 << Arg2->
getType() << SizeTy << 1
4954 << 3 << Arg2->
getType() << SizeTy;
4959bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
4963 if (BuiltinID == Builtin::BI__builtin_isunordered &&
4991 diag::err_typecheck_call_invalid_ordered_compare)
4999bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5000 unsigned BuiltinID) {
5005 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5006 BuiltinID == Builtin::BI__builtin_isinf ||
5007 BuiltinID == Builtin::BI__builtin_isinf_sign))
5011 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5012 BuiltinID == Builtin::BI__builtin_isunordered))
5016 bool IsFPClass = NumArgs == 2;
5019 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5023 for (
unsigned i = 0; i < FPArgNo; ++i) {
5050 OrigArg = Res.
get();
5056 OrigArg = Res.
get();
5058 TheCall->
setArg(FPArgNo, OrigArg);
5072 diag::err_typecheck_call_invalid_unary_fp)
5084 if (!VectorResultTy.
isNull())
5085 ResultTy = VectorResultTy;
5094bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5099 for (
unsigned I = 0; I != 2; ++I) {
5110 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5129 diag::err_typecheck_call_different_arg_types)
5153 diag::err_typecheck_call_too_few_args_at_least)
5161 unsigned numElements = 0;
5176 unsigned numResElements = TheCall->
getNumArgs() - 2;
5185 diag::err_vec_builtin_incompatible_vector)
5192 diag::err_vec_builtin_incompatible_vector)
5197 }
else if (numElements != numResElements) {
5204 for (
unsigned i = 2; i < TheCall->
getNumArgs(); i++) {
5209 std::optional<llvm::APSInt>
Result;
5212 diag::err_shufflevector_nonconstant_argument)
5219 if (
Result->getActiveBits() > 64 ||
5220 Result->getZExtValue() >= numElements * 2)
5222 diag::err_shufflevector_argument_too_large)
5228 for (
unsigned i = 0, e = TheCall->
getNumArgs(); i != e; i++) {
5229 exprs.push_back(TheCall->
getArg(i));
5230 TheCall->
setArg(i,
nullptr);
5248 diag::err_convertvector_non_vector)
5251 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5253 <<
"__builtin_convertvector");
5258 if (SrcElts != DstElts)
5260 diag::err_convertvector_incompatible_vector)
5265 BuiltinLoc, RParenLoc);
5268bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5273 diag::err_typecheck_call_too_many_args_at_most)
5274 << 0 << 3 << NumArgs << 0
5279 for (
unsigned i = 1; i != NumArgs; ++i)
5286bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5288 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5298 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5308bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5315 << cast<FunctionDecl>(TheCall->
getCalleeDecl())->getIdentifier();
5320bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
5326 if (
const auto *UE =
5328 if (UE->getKind() == UETT_AlignOf ||
5329 UE->getKind() == UETT_PreferredAlignOf)
5335 if (!
Result.isPowerOf2())
5336 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5343 if (
Result > std::numeric_limits<int32_t>::max())
5351bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
5362 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
5366 TheCall->
setArg(0, FirstArgResult.
get());
5378 if (!
Result.isPowerOf2())
5379 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
5391 TheCall->
setArg(2, ThirdArg);
5397bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
5398 unsigned BuiltinID =
5399 cast<FunctionDecl>(TheCall->
getCalleeDecl())->getBuiltinID();
5400 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
5403 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
5404 if (NumArgs < NumRequiredArgs) {
5405 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
5406 << 0 << NumRequiredArgs << NumArgs
5409 if (NumArgs >= NumRequiredArgs + 0x100) {
5411 diag::err_typecheck_call_too_many_args_at_most)
5412 << 0 << (NumRequiredArgs + 0xff) << NumArgs
5423 if (Arg.isInvalid())
5425 TheCall->
setArg(i, Arg.get());
5430 unsigned FormatIdx = i;
5440 unsigned FirstDataArg = i;
5441 while (i < NumArgs) {
5459 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
5461 bool Success = CheckFormatArguments(
5485 std::optional<llvm::APSInt> R;
5487 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
5494 int High,
bool RangeIsError) {
5508 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
5516 PDiag(diag::warn_argument_invalid_range)
5561 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
5566 if (
Value.isNegative())
5577 if ((
Value & 0xFF) != 0)
5602 Result.setIsUnsigned(
true);
5607 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
5626 Result.setIsUnsigned(
true);
5634 diag::err_argument_not_shifted_byte_or_xxff)
5638bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
5640 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
5651 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
5657bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
5659 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
5664bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
5679 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5684 diag::err_builtin_counted_by_ref_has_side_effects)
5687 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
5688 if (!ME->isFlexibleArrayMemberLike(
5691 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5697 const auto *FAMDecl = cast<FieldDecl>(ME->getMemberDecl());
5705 diag::err_builtin_counted_by_ref_must_be_flex_array_member)
5715bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *
E,
5716 BuiltinCountedByRefKind K) {
5723 case AssignmentKind:
5724 case InitializerKind:
5726 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5729 case FunctionArgKind:
5731 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5736 diag::err_builtin_counted_by_ref_cannot_leak_reference)
5739 case ArraySubscriptKind:
5743 case BinaryExprKind:
5754class UncoveredArgHandler {
5755 enum {
Unknown = -1, AllCovered = -2 };
5757 signed FirstUncoveredArg =
Unknown;
5761 UncoveredArgHandler() =
default;
5763 bool hasUncoveredArg()
const {
5764 return (FirstUncoveredArg >= 0);
5767 unsigned getUncoveredArg()
const {
5768 assert(hasUncoveredArg() &&
"no uncovered argument");
5769 return FirstUncoveredArg;
5772 void setAllCovered() {
5775 DiagnosticExprs.clear();
5776 FirstUncoveredArg = AllCovered;
5779 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
5780 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
5783 if (FirstUncoveredArg == AllCovered)
5788 if (NewFirstUncoveredArg == FirstUncoveredArg)
5789 DiagnosticExprs.push_back(StrExpr);
5790 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
5791 DiagnosticExprs.clear();
5792 DiagnosticExprs.push_back(StrExpr);
5793 FirstUncoveredArg = NewFirstUncoveredArg;
5797 void Diagnose(
Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
5800enum StringLiteralCheckType {
5802 SLCT_UncheckedLiteral,
5810 bool AddendIsRight) {
5811 unsigned BitWidth = Offset.getBitWidth();
5812 unsigned AddendBitWidth = Addend.getBitWidth();
5814 if (Addend.isUnsigned()) {
5815 Addend = Addend.zext(++AddendBitWidth);
5816 Addend.setIsSigned(
true);
5819 if (AddendBitWidth > BitWidth) {
5820 Offset = Offset.sext(AddendBitWidth);
5821 BitWidth = AddendBitWidth;
5822 }
else if (BitWidth > AddendBitWidth) {
5823 Addend = Addend.sext(BitWidth);
5827 llvm::APSInt ResOffset = Offset;
5828 if (BinOpKind == BO_Add)
5829 ResOffset = Offset.sadd_ov(Addend, Ov);
5831 assert(AddendIsRight && BinOpKind == BO_Sub &&
5832 "operator must be add or sub with addend on the right");
5833 ResOffset = Offset.ssub_ov(Addend, Ov);
5839 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
5840 "index (intermediate) result too big");
5841 Offset = Offset.sext(2 * BitWidth);
5842 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
5854class FormatStringLiteral {
5859 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
5860 : FExpr(fexpr), Offset(Offset) {}
5862 StringRef getString()
const {
5863 return FExpr->
getString().drop_front(Offset);
5866 unsigned getByteLength()
const {
5867 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
5870 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
5877 bool isAscii()
const {
return FExpr->
isOrdinary(); }
5878 bool isWide()
const {
return FExpr->
isWide(); }
5879 bool isUTF8()
const {
return FExpr->
isUTF8(); }
5880 bool isUTF16()
const {
return FExpr->
isUTF16(); }
5881 bool isUTF32()
const {
return FExpr->
isUTF32(); }
5882 bool isPascal()
const {
return FExpr->
isPascal(); }
5887 unsigned *StartTokenByteOffset =
nullptr)
const {
5889 StartToken, StartTokenByteOffset);
5902 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
5906 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
5907 bool IgnoreStringsWithoutSpecifiers);
5916static StringLiteralCheckType
5921 llvm::SmallBitVector &CheckedVarArgs,
5922 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
5923 bool IgnoreStringsWithoutSpecifiers =
false) {
5925 return SLCT_NotALiteral;
5927 assert(Offset.isSigned() &&
"invalid offset");
5930 return SLCT_NotALiteral;
5939 return SLCT_UncheckedLiteral;
5942 case Stmt::InitListExprClass:
5946 Type, CallType,
false,
5947 CheckedVarArgs, UncoveredArg, Offset,
5948 IgnoreStringsWithoutSpecifiers);
5950 return SLCT_NotALiteral;
5951 case Stmt::BinaryConditionalOperatorClass:
5952 case Stmt::ConditionalOperatorClass: {
5956 cast<AbstractConditionalOperator>(
E);
5961 bool CheckLeft =
true, CheckRight =
true;
5964 if (
C->getCond()->EvaluateAsBooleanCondition(
5976 StringLiteralCheckType Left;
5978 Left = SLCT_UncheckedLiteral;
5981 firstDataArg,
Type, CallType, InFunctionCall,
5982 CheckedVarArgs, UncoveredArg, Offset,
5983 IgnoreStringsWithoutSpecifiers);
5984 if (Left == SLCT_NotALiteral || !CheckRight) {
5990 S,
C->getFalseExpr(), Args, APK, format_idx, firstDataArg,
Type,
5991 CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
5992 IgnoreStringsWithoutSpecifiers);
5994 return (CheckLeft && Left < Right) ? Left : Right;
5997 case Stmt::ImplicitCastExprClass:
5998 E = cast<ImplicitCastExpr>(
E)->getSubExpr();
6001 case Stmt::OpaqueValueExprClass:
6002 if (
const Expr *src = cast<OpaqueValueExpr>(
E)->getSourceExpr()) {
6006 return SLCT_NotALiteral;
6008 case Stmt::PredefinedExprClass:
6012 return SLCT_UncheckedLiteral;
6014 case Stmt::DeclRefExprClass: {
6020 bool isConstant =
false;
6024 isConstant = AT->getElementType().isConstant(S.
Context);
6026 isConstant =
T.isConstant(S.
Context) &&
6031 isConstant =
T.isConstant(S.
Context);
6035 if (
const Expr *
Init = VD->getAnyInitializer()) {
6038 if (InitList->isStringLiteralInit())
6039 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6042 S,
Init, Args, APK, format_idx, firstDataArg,
Type, CallType,
6043 false, CheckedVarArgs, UncoveredArg, Offset);
6084 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6085 if (
const auto *
D = dyn_cast<Decl>(PV->getDeclContext())) {
6087 bool IsCXXMember =
false;
6088 if (
const auto *MD = dyn_cast<CXXMethodDecl>(
D))
6089 IsCXXMember = MD->isInstance();
6091 bool IsVariadic =
false;
6093 IsVariadic = cast<FunctionProtoType>(FnTy)->isVariadic();
6094 else if (
const auto *BD = dyn_cast<BlockDecl>(
D))
6095 IsVariadic = BD->isVariadic();
6096 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(
D))
6097 IsVariadic = OMD->isVariadic();
6104 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx &&
6117 return SLCT_UncheckedLiteral;
6126 return SLCT_NotALiteral;
6129 case Stmt::CallExprClass:
6130 case Stmt::CXXMemberCallExprClass: {
6133 bool IsFirst =
true;
6134 StringLiteralCheckType CommonResult;
6135 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6136 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6138 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6139 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6140 IgnoreStringsWithoutSpecifiers);
6147 return CommonResult;
6149 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6151 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6152 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6155 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6156 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6157 IgnoreStringsWithoutSpecifiers);
6163 Type, CallType,
false,
6164 CheckedVarArgs, UncoveredArg, Offset,
6165 IgnoreStringsWithoutSpecifiers);
6166 return SLCT_NotALiteral;
6168 case Stmt::ObjCMessageExprClass: {
6169 const auto *ME = cast<ObjCMessageExpr>(
E);
6170 if (
const auto *MD = ME->getMethodDecl()) {
6171 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6180 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6182 MD->getSelector().isKeywordSelector(
6183 {
"localizedStringForKey",
"value",
"table"})) {
6184 IgnoreStringsWithoutSpecifiers =
true;
6187 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6189 S, Arg, Args, APK, format_idx, firstDataArg,
Type, CallType,
6190 InFunctionCall, CheckedVarArgs, UncoveredArg, Offset,
6191 IgnoreStringsWithoutSpecifiers);
6195 return SLCT_NotALiteral;
6197 case Stmt::ObjCStringLiteralClass:
6198 case Stmt::StringLiteralClass: {
6204 StrE = cast<StringLiteral>(
E);
6207 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6210 return SLCT_NotALiteral;
6212 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6214 InFunctionCall, CallType, CheckedVarArgs, UncoveredArg,
6215 IgnoreStringsWithoutSpecifiers);
6216 return SLCT_CheckedLiteral;
6219 return SLCT_NotALiteral;
6221 case Stmt::BinaryOperatorClass: {
6235 if (LIsInt != RIsInt) {
6239 if (BinOpKind == BO_Add) {
6252 return SLCT_NotALiteral;
6254 case Stmt::UnaryOperatorClass: {
6256 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6257 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
6259 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
6269 return SLCT_NotALiteral;
6273 return SLCT_NotALiteral;
6284 const auto *LVE =
Result.Val.getLValueBase().dyn_cast<
const Expr *>();
6285 if (isa_and_nonnull<StringLiteral>(LVE))
6292 return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
6294 .Cases(
"printf",
"printf0",
"syslog",
FST_Printf)
6298 .Cases(
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err",
FST_Kprintf)
6305bool Sema::CheckFormatArguments(
const FormatAttr *Format,
6309 llvm::SmallBitVector &CheckedVarArgs) {
6310 FormatStringInfo FSI;
6313 return CheckFormatArguments(Args, FSI.ArgPassingKind, FSI.FormatIdx,
6315 CallType,
Loc,
Range, CheckedVarArgs);
6321 unsigned format_idx,
unsigned firstDataArg,
6322 FormatStringType
Type,
6325 llvm::SmallBitVector &CheckedVarArgs) {
6327 if (format_idx >= Args.size()) {
6332 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
6346 UncoveredArgHandler UncoveredArg;
6348 *
this, OrigFormatExpr, Args, APK, format_idx, firstDataArg,
Type,
6350 true, CheckedVarArgs, UncoveredArg,
6351 llvm::APSInt(64,
false) = 0);
6354 if (UncoveredArg.hasUncoveredArg()) {
6355 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
6356 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
6357 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
6360 if (CT != SLCT_NotALiteral)
6362 return CT == SLCT_CheckedLiteral;
6379 if (Args.size() == firstDataArg) {
6380 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
6389 Diag(FormatLoc, diag::note_format_security_fixit)
6393 Diag(FormatLoc, diag::note_format_security_fixit)
6398 Diag(FormatLoc, diag::warn_format_nonliteral)
6409 const FormatStringLiteral *FExpr;
6410 const Expr *OrigFormatExpr;
6412 const unsigned FirstDataArg;
6413 const unsigned NumDataArgs;
6418 llvm::SmallBitVector CoveredArgs;
6419 bool usesPositionalArgs =
false;
6420 bool atFirstArg =
true;
6421 bool inFunctionCall;
6423 llvm::SmallBitVector &CheckedVarArgs;
6424 UncoveredArgHandler &UncoveredArg;
6427 CheckFormatHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6428 const Expr *origFormatExpr,
6430 unsigned numDataArgs,
const char *beg,
6434 llvm::SmallBitVector &CheckedVarArgs,
6435 UncoveredArgHandler &UncoveredArg)
6436 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
6437 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
6438 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
6439 inFunctionCall(inFunctionCall), CallType(callType),
6440 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
6441 CoveredArgs.resize(numDataArgs);
6442 CoveredArgs.reset();
6445 void DoneProcessing();
6447 void HandleIncompleteSpecifier(
const char *startSpecifier,
6448 unsigned specifierLen)
override;
6450 void HandleInvalidLengthModifier(
6453 const char *startSpecifier,
unsigned specifierLen,
6456 void HandleNonStandardLengthModifier(
6458 const char *startSpecifier,
unsigned specifierLen);
6460 void HandleNonStandardConversionSpecifier(
6462 const char *startSpecifier,
unsigned specifierLen);
6464 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
6466 void HandleInvalidPosition(
const char *startSpecifier,
6467 unsigned specifierLen,
6470 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
6472 void HandleNullChar(
const char *nullCharacter)
override;
6474 template <
typename Range>
6476 EmitFormatDiagnostic(
Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
6478 bool IsStringLocation,
Range StringRange,
6483 const char *startSpec,
6484 unsigned specifierLen,
6485 const char *csStart,
unsigned csLen);
6488 const char *startSpec,
6489 unsigned specifierLen);
6493 unsigned specifierLen);
6496 const Expr *getDataArg(
unsigned i)
const;
6500 const char *startSpecifier,
unsigned specifierLen,
6503 template <
typename Range>
6505 bool IsStringLocation,
Range StringRange,
6511SourceRange CheckFormatHandler::getFormatStringRange() {
6516getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
6518 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
6521 End = End.getLocWithOffset(1);
6526SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
6531void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
6532 unsigned specifierLen){
6533 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
6534 getLocationOfByte(startSpecifier),
6536 getSpecifierRange(startSpecifier, specifierLen));
6539void CheckFormatHandler::HandleInvalidLengthModifier(
6542 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
6543 using namespace analyze_format_string;
6545 const LengthModifier &LM = FS.getLengthModifier();
6546 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6549 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6551 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6552 getLocationOfByte(LM.getStart()),
6554 getSpecifierRange(startSpecifier, specifierLen));
6556 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6557 << FixedLM->toString()
6562 if (DiagID == diag::warn_format_nonsensical_length)
6565 EmitFormatDiagnostic(S.
PDiag(DiagID) << LM.toString() << CS.
toString(),
6566 getLocationOfByte(LM.getStart()),
6568 getSpecifierRange(startSpecifier, specifierLen),
6573void CheckFormatHandler::HandleNonStandardLengthModifier(
6575 const char *startSpecifier,
unsigned specifierLen) {
6576 using namespace analyze_format_string;
6578 const LengthModifier &LM = FS.getLengthModifier();
6579 CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
6582 std::optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
6584 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6585 << LM.toString() << 0,
6586 getLocationOfByte(LM.getStart()),
6588 getSpecifierRange(startSpecifier, specifierLen));
6590 S.
Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
6591 << FixedLM->toString()
6595 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6596 << LM.toString() << 0,
6597 getLocationOfByte(LM.getStart()),
6599 getSpecifierRange(startSpecifier, specifierLen));
6603void CheckFormatHandler::HandleNonStandardConversionSpecifier(
6605 const char *startSpecifier,
unsigned specifierLen) {
6606 using namespace analyze_format_string;
6611 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6615 getSpecifierRange(startSpecifier, specifierLen));
6618 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
6619 << FixedCS->toString()
6622 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
6626 getSpecifierRange(startSpecifier, specifierLen));
6630void CheckFormatHandler::HandlePosition(
const char *startPos,
6633 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
6634 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
6635 getLocationOfByte(startPos),
6637 getSpecifierRange(startPos, posLen));
6640void CheckFormatHandler::HandleInvalidPosition(
6641 const char *startSpecifier,
unsigned specifierLen,
6644 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
6645 EmitFormatDiagnostic(
6646 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
6647 getLocationOfByte(startSpecifier),
true,
6648 getSpecifierRange(startSpecifier, specifierLen));
6651void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
6655 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
6656 getLocationOfByte(startPos),
6658 getSpecifierRange(startPos, posLen));
6661void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
6662 if (!isa<ObjCStringLiteral>(OrigFormatExpr)) {
6664 EmitFormatDiagnostic(
6665 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
6666 getLocationOfByte(nullCharacter),
true,
6667 getFormatStringRange());
6673const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
6674 return Args[FirstDataArg + i];
6677void CheckFormatHandler::DoneProcessing() {
6683 signed notCoveredArg = CoveredArgs.find_first();
6684 if (notCoveredArg >= 0) {
6685 assert((
unsigned)notCoveredArg < NumDataArgs);
6686 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
6688 UncoveredArg.setAllCovered();
6693void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
6694 const Expr *ArgExpr) {
6695 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
6707 for (
auto E : DiagnosticExprs)
6710 CheckFormatHandler::EmitFormatDiagnostic(
6711 S, IsFunctionCall, DiagnosticExprs[0],
6717CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
6719 const char *startSpec,
6720 unsigned specifierLen,
6721 const char *csStart,
6723 bool keepGoing =
true;
6724 if (argIndex < NumDataArgs) {
6727 CoveredArgs.set(argIndex);
6743 std::string CodePointStr;
6744 if (!llvm::sys::locale::isPrint(*csStart)) {
6745 llvm::UTF32 CodePoint;
6746 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
6747 const llvm::UTF8 *
E =
6748 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
6749 llvm::ConversionResult
Result =
6750 llvm::convertUTF8Sequence(B,
E, &CodePoint, llvm::strictConversion);
6752 if (
Result != llvm::conversionOK) {
6753 unsigned char FirstChar = *csStart;
6754 CodePoint = (llvm::UTF32)FirstChar;
6757 llvm::raw_string_ostream OS(CodePointStr);
6758 if (CodePoint < 256)
6759 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
6760 else if (CodePoint <= 0xFFFF)
6761 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
6763 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
6767 EmitFormatDiagnostic(
6768 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier,
Loc,
6769 true, getSpecifierRange(startSpec, specifierLen));
6776 const char *startSpec,
6777 unsigned specifierLen) {
6778 EmitFormatDiagnostic(
6779 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
6780 Loc,
true, getSpecifierRange(startSpec, specifierLen));
6784CheckFormatHandler::CheckNumArgs(
6787 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
6789 if (argIndex >= NumDataArgs) {
6791 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
6792 << (argIndex+1) << NumDataArgs)
6793 : S.
PDiag(diag::warn_printf_insufficient_data_args);
6794 EmitFormatDiagnostic(
6795 PDiag, getLocationOfByte(CS.
getStart()),
true,
6796 getSpecifierRange(startSpecifier, specifierLen));
6800 UncoveredArg.setAllCovered();
6806template<
typename Range>
6809 bool IsStringLocation,
6812 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
6813 Loc, IsStringLocation, StringRange, FixIt);
6843template <
typename Range>
6844void CheckFormatHandler::EmitFormatDiagnostic(
6845 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
6848 if (InFunctionCall) {
6857 S.
Diag(IsStringLocation ?
Loc : StringRange.getBegin(),
6858 diag::note_format_string_defined);
6860 Note << StringRange;
6869class CheckPrintfHandler :
public CheckFormatHandler {
6871 CheckPrintfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
6872 const Expr *origFormatExpr,
6874 unsigned numDataArgs,
bool isObjC,
const char *beg,
6878 llvm::SmallBitVector &CheckedVarArgs,
6879 UncoveredArgHandler &UncoveredArg)
6880 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
6881 numDataArgs, beg, APK, Args, formatIdx,
6882 inFunctionCall, CallType, CheckedVarArgs,
6888 bool allowsObjCArg()
const {
6893 bool HandleInvalidPrintfConversionSpecifier(
6895 const char *startSpecifier,
6896 unsigned specifierLen)
override;
6898 void handleInvalidMaskType(StringRef MaskType)
override;
6901 const char *startSpecifier,
unsigned specifierLen,
6904 const char *StartSpecifier,
6905 unsigned SpecifierLen,
6909 const char *startSpecifier,
unsigned specifierLen);
6913 const char *startSpecifier,
unsigned specifierLen);
6916 const char *startSpecifier,
unsigned specifierLen);
6920 const char *startSpecifier,
unsigned specifierLen);
6924 void HandleEmptyObjCModifierFlag(
const char *startFlag,
6925 unsigned flagLen)
override;
6927 void HandleInvalidObjCModifierFlag(
const char *startFlag,
6928 unsigned flagLen)
override;
6930 void HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
6931 const char *flagsEnd,
6932 const char *conversionPosition)
6938bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
6940 const char *startSpecifier,
6941 unsigned specifierLen) {
6943 FS.getConversionSpecifier();
6945 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
6947 startSpecifier, specifierLen,
6951void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
6952 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
6955bool CheckPrintfHandler::HandleAmount(
6957 const char *startSpecifier,
unsigned specifierLen) {
6961 if (argIndex >= NumDataArgs) {
6962 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
6966 getSpecifierRange(startSpecifier, specifierLen));
6976 CoveredArgs.set(argIndex);
6977 const Expr *Arg = getDataArg(argIndex);
6987 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_wrong_type)
6992 getSpecifierRange(startSpecifier, specifierLen));
7002void CheckPrintfHandler::HandleInvalidAmount(
7006 const char *startSpecifier,
7007 unsigned specifierLen) {
7009 FS.getConversionSpecifier();
7017 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
7021 getSpecifierRange(startSpecifier, specifierLen),
7027 const char *startSpecifier,
7028 unsigned specifierLen) {
7031 FS.getConversionSpecifier();
7032 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
7036 getSpecifierRange(startSpecifier, specifierLen),
7041void CheckPrintfHandler::HandleIgnoredFlag(
7045 const char *startSpecifier,
7046 unsigned specifierLen) {
7048 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
7052 getSpecifierRange(startSpecifier, specifierLen),
7054 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
7057void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
7060 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
7061 getLocationOfByte(startFlag),
7063 getSpecifierRange(startFlag, flagLen));
7066void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
7069 auto Range = getSpecifierRange(startFlag, flagLen);
7070 StringRef flag(startFlag, flagLen);
7071 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
7072 getLocationOfByte(startFlag),
7077void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
7078 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
7080 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
7081 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
7082 EmitFormatDiagnostic(S.
PDiag(diag) << StringRef(conversionPosition, 1),
7083 getLocationOfByte(conversionPosition),
7091template<
typename MemberKind>
7112 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
7126 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", *
this,
E->
getType());
7127 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7129 if ((*MI)->getMinRequiredArguments() == 0)
7137bool CheckPrintfHandler::checkForCStrMembers(
7142 CXXRecordMembersNamed<CXXMethodDecl>(
"c_str", S,
E->
getType());
7144 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
7160bool CheckPrintfHandler::HandlePrintfSpecifier(
7163 using namespace analyze_format_string;
7164 using namespace analyze_printf;
7166 const PrintfConversionSpecifier &CS = FS.getConversionSpecifier();
7168 if (FS.consumesDataArgument()) {
7171 usesPositionalArgs = FS.usesPositionalArg();
7173 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7174 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7175 startSpecifier, specifierLen);
7182 if (!HandleAmount(FS.getFieldWidth(), 0,
7183 startSpecifier, specifierLen)) {
7187 if (!HandleAmount(FS.getPrecision(), 1,
7188 startSpecifier, specifierLen)) {
7192 if (!CS.consumesDataArgument()) {
7199 unsigned argIndex = FS.getArgIndex();
7200 if (argIndex < NumDataArgs) {
7204 CoveredArgs.set(argIndex);
7208 if (CS.getKind() == ConversionSpecifier::FreeBSDbArg ||
7209 CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
7211 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
7215 CoveredArgs.set(argIndex + 1);
7218 const Expr *Ex = getDataArg(argIndex);
7220 (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
7223 EmitFormatDiagnostic(
7224 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7228 getSpecifierRange(startSpecifier, specifierLen));
7231 Ex = getDataArg(argIndex + 1);
7234 EmitFormatDiagnostic(
7235 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7239 getSpecifierRange(startSpecifier, specifierLen));
7246 if (!allowsObjCArg() && CS.isObjCArg()) {
7247 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7252 if (FSType !=
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::PArg) {
7253 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7258 if (FSType ==
Sema::FST_OSLog && CS.getKind() == ConversionSpecifier::nArg) {
7259 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
7260 getLocationOfByte(CS.getStart()),
7262 getSpecifierRange(startSpecifier, specifierLen));
7269 (CS.getKind() == ConversionSpecifier::PArg ||
7270 CS.getKind() == ConversionSpecifier::sArg ||
7271 CS.getKind() == ConversionSpecifier::ObjCObjArg)) {
7272 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
7278 if (FS.isPublic().isSet()) {
7279 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7281 getLocationOfByte(FS.isPublic().getPosition()),
7283 getSpecifierRange(startSpecifier, specifierLen));
7285 if (FS.isPrivate().isSet()) {
7286 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
7288 getLocationOfByte(FS.isPrivate().getPosition()),
7290 getSpecifierRange(startSpecifier, specifierLen));
7294 const llvm::Triple &Triple =
Target.getTriple();
7295 if (CS.getKind() == ConversionSpecifier::nArg &&
7296 (Triple.isAndroid() || Triple.isOSFuchsia())) {
7297 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
7298 getLocationOfByte(CS.getStart()),
7300 getSpecifierRange(startSpecifier, specifierLen));
7304 if (!FS.hasValidFieldWidth()) {
7305 HandleInvalidAmount(FS, FS.getFieldWidth(), 0,
7306 startSpecifier, specifierLen);
7310 if (!FS.hasValidPrecision()) {
7311 HandleInvalidAmount(FS, FS.getPrecision(), 1,
7312 startSpecifier, specifierLen);
7316 if (CS.getKind() == ConversionSpecifier::PArg &&
7317 FS.getPrecision().getHowSpecified() == OptionalAmount::NotSpecified) {
7318 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
7319 getLocationOfByte(startSpecifier),
7321 getSpecifierRange(startSpecifier, specifierLen));
7325 if (!FS.hasValidThousandsGroupingPrefix())
7326 HandleFlag(FS, FS.hasThousandsGrouping(), startSpecifier, specifierLen);
7327 if (!FS.hasValidLeadingZeros())
7328 HandleFlag(FS, FS.hasLeadingZeros(), startSpecifier, specifierLen);
7329 if (!FS.hasValidPlusPrefix())
7330 HandleFlag(FS, FS.hasPlusPrefix(), startSpecifier, specifierLen);
7331 if (!FS.hasValidSpacePrefix())
7332 HandleFlag(FS, FS.hasSpacePrefix(), startSpecifier, specifierLen);
7333 if (!FS.hasValidAlternativeForm())
7334 HandleFlag(FS, FS.hasAlternativeForm(), startSpecifier, specifierLen);
7335 if (!FS.hasValidLeftJustified())
7336 HandleFlag(FS, FS.isLeftJustified(), startSpecifier, specifierLen);
7339 if (FS.hasSpacePrefix() && FS.hasPlusPrefix())
7340 HandleIgnoredFlag(FS, FS.hasSpacePrefix(), FS.hasPlusPrefix(),
7341 startSpecifier, specifierLen);
7342 if (FS.hasLeadingZeros() && FS.isLeftJustified())
7343 HandleIgnoredFlag(FS, FS.hasLeadingZeros(), FS.isLeftJustified(),
7344 startSpecifier, specifierLen);
7349 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7350 diag::warn_format_nonsensical_length);
7351 else if (!FS.hasStandardLengthModifier())
7352 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
7353 else if (!FS.hasStandardLengthConversionCombination())
7354 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
7355 diag::warn_format_non_standard_conversion_spec);
7357 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
7358 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
7364 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
7367 const Expr *Arg = getDataArg(argIndex);
7371 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
7383 case Stmt::ArraySubscriptExprClass:
7384 case Stmt::CallExprClass:
7385 case Stmt::CharacterLiteralClass:
7386 case Stmt::CXXBoolLiteralExprClass:
7387 case Stmt::DeclRefExprClass:
7388 case Stmt::FloatingLiteralClass:
7389 case Stmt::IntegerLiteralClass:
7390 case Stmt::MemberExprClass:
7391 case Stmt::ObjCArrayLiteralClass:
7392 case Stmt::ObjCBoolLiteralExprClass:
7393 case Stmt::ObjCBoxedExprClass:
7394 case Stmt::ObjCDictionaryLiteralClass:
7395 case Stmt::ObjCEncodeExprClass:
7396 case Stmt::ObjCIvarRefExprClass:
7397 case Stmt::ObjCMessageExprClass:
7398 case Stmt::ObjCPropertyRefExprClass:
7399 case Stmt::ObjCStringLiteralClass:
7400 case Stmt::ObjCSubscriptRefExprClass:
7401 case Stmt::ParenExprClass:
7402 case Stmt::StringLiteralClass:
7403 case Stmt::UnaryOperatorClass:
7410static std::pair<QualType, StringRef>
7417 StringRef Name = UserTy->getDecl()->getName();
7418 QualType CastTy = llvm::StringSwitch<QualType>(Name)
7422 .Case(
"SInt32", Context.
IntTy)
7427 return std::make_pair(CastTy, Name);
7429 TyTy = UserTy->desugar();
7433 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(
E))
7435 PE->getSubExpr()->getType(),
7444 StringRef TrueName, FalseName;
7446 std::tie(TrueTy, TrueName) =
7448 CO->getTrueExpr()->getType(),
7450 std::tie(FalseTy, FalseName) =
7452 CO->getFalseExpr()->getType(),
7453 CO->getFalseExpr());
7455 if (TrueTy == FalseTy)
7456 return std::make_pair(TrueTy, TrueName);
7457 else if (TrueTy.
isNull())
7458 return std::make_pair(FalseTy, FalseName);
7459 else if (FalseTy.
isNull())
7460 return std::make_pair(TrueTy, TrueName);
7463 return std::make_pair(
QualType(), StringRef());
7482 From = VecTy->getElementType();
7484 To = VecTy->getElementType();
7496 diag::warn_format_conversion_argument_type_mismatch_signedness,
Loc)
7505 const char *StartSpecifier,
7506 unsigned SpecifierLen,
7508 using namespace analyze_format_string;
7509 using namespace analyze_printf;
7518 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
7519 ExprTy = TET->getUnderlyingExpr()->getType();
7531 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::cArg &&
7534 getSpecifierRange(StartSpecifier, SpecifierLen);
7536 llvm::raw_svector_ostream os(FSString);
7538 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
7546 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::PArg &&
7549 getSpecifierRange(StartSpecifier, SpecifierLen);
7550 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
7555 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
7557 ArgType::MatchKind OrigMatch = Match;
7560 if (Match == ArgType::Match)
7564 assert(Match != ArgType::NoMatchPromotionTypeConfusion);
7573 E = ICE->getSubExpr();
7583 if (OrigMatch == ArgType::NoMatchSignedness &&
7584 ImplicitMatch != ArgType::NoMatchSignedness)
7591 if (ImplicitMatch == ArgType::Match)
7602 FS.getLengthModifier().getKind() != LengthModifier::AsChar)
7609 if (Match == ArgType::MatchPromotion)
7610 Match = ArgType::NoMatch;
7613 if (Match == ArgType::MatchPromotion) {
7617 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
7618 ImplicitMatch != ArgType::NoMatchTypeConfusion)
7620 Match = ArgType::NoMatch;
7622 if (ImplicitMatch == ArgType::NoMatchPedantic ||
7623 ImplicitMatch == ArgType::NoMatchTypeConfusion)
7624 Match = ImplicitMatch;
7625 assert(Match != ArgType::MatchPromotion);
7628 bool IsEnum =
false;
7629 bool IsScopedEnum =
false;
7632 IntendedTy = EnumTy->getDecl()->getIntegerType();
7633 if (EnumTy->isUnscopedEnumerationType()) {
7634 ExprTy = IntendedTy;
7639 IsScopedEnum =
true;
7646 if (isObjCContext() &&
7647 FS.getConversionSpecifier().getKind() == ConversionSpecifier::CArg) {
7657 const llvm::APInt &
V = IL->getValue();
7667 if (TD->getUnderlyingType() == IntendedTy)
7675 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
7683 if (!IsScopedEnum &&
7684 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
7687 Match = ArgType::NoMatchPedantic;
7688 IntendedTy = CastTy;
7689 ShouldNotPrintDirectly =
true;
7694 PrintfSpecifier fixedFS = FS;
7701 llvm::raw_svector_ostream os(buf);
7702 fixedFS.toString(os);
7704 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
7706 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
7709 case ArgType::Match:
7710 case ArgType::MatchPromotion:
7711 case ArgType::NoMatchPromotionTypeConfusion:
7712 case ArgType::NoMatchSignedness:
7713 llvm_unreachable(
"expected non-matching");
7714 case ArgType::NoMatchPedantic:
7715 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7717 case ArgType::NoMatchTypeConfusion:
7718 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7720 case ArgType::NoMatch:
7721 Diag = diag::warn_format_conversion_argument_type_mismatch;
7742 llvm::raw_svector_ostream CastFix(CastBuf);
7743 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
7745 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
7751 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
7756 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
7778 if (ShouldNotPrintDirectly && !IsScopedEnum) {
7784 Name = TypedefTy->getDecl()->getName();
7787 unsigned Diag = Match == ArgType::NoMatchPedantic
7788 ? diag::warn_format_argument_needs_cast_pedantic
7789 : diag::warn_format_argument_needs_cast;
7790 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
7801 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
7802 : diag::warn_format_conversion_argument_type_mismatch;
7804 EmitFormatDiagnostic(
7816 bool EmitTypeMismatch =
false;
7822 case ArgType::Match:
7823 case ArgType::MatchPromotion:
7824 case ArgType::NoMatchPromotionTypeConfusion:
7825 case ArgType::NoMatchSignedness:
7826 llvm_unreachable(
"expected non-matching");
7827 case ArgType::NoMatchPedantic:
7828 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
7830 case ArgType::NoMatchTypeConfusion:
7831 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
7833 case ArgType::NoMatch:
7834 Diag = diag::warn_format_conversion_argument_type_mismatch;
7838 EmitFormatDiagnostic(
7847 EmitTypeMismatch =
true;
7849 EmitFormatDiagnostic(
7850 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
7851 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7855 checkForCStrMembers(AT,
E);
7861 EmitTypeMismatch =
true;
7863 EmitFormatDiagnostic(
7864 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
7865 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
7873 << isa<InitListExpr>(
E) << ExprTy << CallType
7878 if (EmitTypeMismatch) {
7884 EmitFormatDiagnostic(
7885 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
7891 assert(FirstDataArg + FS.getArgIndex() < CheckedVarArgs.size() &&
7892 "format string specifier index out of range");
7893 CheckedVarArgs[FirstDataArg + FS.getArgIndex()] =
true;
7903class CheckScanfHandler :
public CheckFormatHandler {
7905 CheckScanfHandler(
Sema &
s,
const FormatStringLiteral *fexpr,
7907 unsigned firstDataArg,
unsigned numDataArgs,
7911 llvm::SmallBitVector &CheckedVarArgs,
7912 UncoveredArgHandler &UncoveredArg)
7913 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7914 numDataArgs, beg, APK, Args, formatIdx,
7915 inFunctionCall, CallType, CheckedVarArgs,
7919 const char *startSpecifier,
7920 unsigned specifierLen)
override;
7922 bool HandleInvalidScanfConversionSpecifier(
7924 const char *startSpecifier,
7925 unsigned specifierLen)
override;
7927 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
7932void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
7934 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
7935 getLocationOfByte(end),
true,
7936 getSpecifierRange(start, end - start));
7939bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
7941 const char *startSpecifier,
7942 unsigned specifierLen) {
7944 FS.getConversionSpecifier();
7946 return HandleInvalidConversionSpecifier(FS.getArgIndex(),
7948 startSpecifier, specifierLen,
7952bool CheckScanfHandler::HandleScanfSpecifier(
7954 const char *startSpecifier,
7955 unsigned specifierLen) {
7956 using namespace analyze_scanf;
7957 using namespace analyze_format_string;
7959 const ScanfConversionSpecifier &CS = FS.getConversionSpecifier();
7963 if (FS.consumesDataArgument()) {
7966 usesPositionalArgs = FS.usesPositionalArg();
7968 else if (usesPositionalArgs != FS.usesPositionalArg()) {
7969 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
7970 startSpecifier, specifierLen);
7976 const OptionalAmount &Amt = FS.getFieldWidth();
7977 if (Amt.getHowSpecified() == OptionalAmount::Constant) {
7978 if (Amt.getConstantAmount() == 0) {
7980 Amt.getConstantLength());
7981 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
7982 getLocationOfByte(Amt.getStart()),
7988 if (!FS.consumesDataArgument()) {
7995 unsigned argIndex = FS.getArgIndex();
7996 if (argIndex < NumDataArgs) {
8000 CoveredArgs.set(argIndex);
8006 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8007 diag::warn_format_nonsensical_length);
8008 else if (!FS.hasStandardLengthModifier())
8009 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8010 else if (!FS.hasStandardLengthConversionCombination())
8011 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8012 diag::warn_format_non_standard_conversion_spec);
8014 if (!FS.hasStandardConversionSpecifier(S.
getLangOpts()))
8015 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8021 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8025 const Expr *Ex = getDataArg(argIndex);
8042 ScanfSpecifier fixedFS = FS;
8047 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
8048 : diag::warn_format_conversion_argument_type_mismatch;
8053 llvm::raw_svector_ostream os(buf);
8054 fixedFS.toString(os);
8056 EmitFormatDiagnostic(
8061 getSpecifierRange(startSpecifier, specifierLen),
8063 getSpecifierRange(startSpecifier, specifierLen), os.str()));
8070 getSpecifierRange(startSpecifier, specifierLen));
8077 Sema &S,
const FormatStringLiteral *FExpr,
const Expr *OrigFormatExpr,
8081 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
8082 bool IgnoreStringsWithoutSpecifiers) {
8084 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
8085 CheckFormatHandler::EmitFormatDiagnostic(
8086 S, inFunctionCall, Args[format_idx],
8087 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
8093 StringRef StrRef = FExpr->getString();
8094 const char *Str = StrRef.data();
8098 assert(
T &&
"String literal not of constant array type!");
8099 size_t TypeSize =
T->getZExtSize();
8100 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8101 const unsigned numDataArgs = Args.size() - firstDataArg;
8103 if (IgnoreStringsWithoutSpecifiers &&
8110 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
8111 CheckFormatHandler::EmitFormatDiagnostic(
8112 S, inFunctionCall, Args[format_idx],
8113 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
8114 FExpr->getBeginLoc(),
8120 if (StrLen == 0 && numDataArgs > 0) {
8121 CheckFormatHandler::EmitFormatDiagnostic(
8122 S, inFunctionCall, Args[format_idx],
8123 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
8132 CheckPrintfHandler H(
8133 S, FExpr, OrigFormatExpr,
Type, firstDataArg, numDataArgs,
8135 Args, format_idx, inFunctionCall, CallType, CheckedVarArgs,
8143 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
8144 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
8145 CallType, CheckedVarArgs, UncoveredArg);
8156 const char *Str = StrRef.data();
8159 assert(
T &&
"String literal not of constant array type!");
8160 size_t TypeSize =
T->getZExtSize();
8161 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
8172 switch (AbsFunction) {
8176 case Builtin::BI__builtin_abs:
8177 return Builtin::BI__builtin_labs;
8178 case Builtin::BI__builtin_labs:
8179 return Builtin::BI__builtin_llabs;
8180 case Builtin::BI__builtin_llabs:
8183 case Builtin::BI__builtin_fabsf:
8184 return Builtin::BI__builtin_fabs;
8185 case Builtin::BI__builtin_fabs:
8186 return Builtin::BI__builtin_fabsl;
8187 case Builtin::BI__builtin_fabsl:
8190 case Builtin::BI__builtin_cabsf:
8191 return Builtin::BI__builtin_cabs;
8192 case Builtin::BI__builtin_cabs:
8193 return Builtin::BI__builtin_cabsl;
8194 case Builtin::BI__builtin_cabsl:
8197 case Builtin::BIabs:
8198 return Builtin::BIlabs;
8199 case Builtin::BIlabs:
8200 return Builtin::BIllabs;
8201 case Builtin::BIllabs:
8204 case Builtin::BIfabsf:
8205 return Builtin::BIfabs;
8206 case Builtin::BIfabs:
8207 return Builtin::BIfabsl;
8208 case Builtin::BIfabsl:
8211 case Builtin::BIcabsf:
8212 return Builtin::BIcabs;
8213 case Builtin::BIcabs:
8214 return Builtin::BIcabsl;
8215 case Builtin::BIcabsl:
8244 unsigned AbsFunctionKind) {
8245 unsigned BestKind = 0;
8247 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
8253 else if (Context.
hasSameType(ParamType, ArgType)) {
8276 llvm_unreachable(
"Type not integer, floating, or complex");
8283 switch (ValueKind) {
8288 case Builtin::BI__builtin_fabsf:
8289 case Builtin::BI__builtin_fabs:
8290 case Builtin::BI__builtin_fabsl:
8291 case Builtin::BI__builtin_cabsf:
8292 case Builtin::BI__builtin_cabs:
8293 case Builtin::BI__builtin_cabsl:
8294 return Builtin::BI__builtin_abs;
8295 case Builtin::BIfabsf:
8296 case Builtin::BIfabs:
8297 case Builtin::BIfabsl:
8298 case Builtin::BIcabsf:
8299 case Builtin::BIcabs:
8300 case Builtin::BIcabsl:
8301 return Builtin::BIabs;
8307 case Builtin::BI__builtin_abs:
8308 case Builtin::BI__builtin_labs:
8309 case Builtin::BI__builtin_llabs:
8310 case Builtin::BI__builtin_cabsf:
8311 case Builtin::BI__builtin_cabs:
8312 case Builtin::BI__builtin_cabsl:
8313 return Builtin::BI__builtin_fabsf;
8314 case Builtin::BIabs:
8315 case Builtin::BIlabs:
8316 case Builtin::BIllabs:
8317 case Builtin::BIcabsf:
8318 case Builtin::BIcabs:
8319 case Builtin::BIcabsl:
8320 return Builtin::BIfabsf;
8326 case Builtin::BI__builtin_abs:
8327 case Builtin::BI__builtin_labs:
8328 case Builtin::BI__builtin_llabs:
8329 case Builtin::BI__builtin_fabsf:
8330 case Builtin::BI__builtin_fabs:
8331 case Builtin::BI__builtin_fabsl:
8332 return Builtin::BI__builtin_cabsf;
8333 case Builtin::BIabs:
8334 case Builtin::BIlabs:
8335 case Builtin::BIllabs:
8336 case Builtin::BIfabsf:
8337 case Builtin::BIfabs:
8338 case Builtin::BIfabsl:
8339 return Builtin::BIcabsf;
8342 llvm_unreachable(
"Unable to convert function");
8353 case Builtin::BI__builtin_abs:
8354 case Builtin::BI__builtin_fabs:
8355 case Builtin::BI__builtin_fabsf:
8356 case Builtin::BI__builtin_fabsl:
8357 case Builtin::BI__builtin_labs:
8358 case Builtin::BI__builtin_llabs:
8359 case Builtin::BI__builtin_cabs:
8360 case Builtin::BI__builtin_cabsf:
8361 case Builtin::BI__builtin_cabsl:
8362 case Builtin::BIabs:
8363 case Builtin::BIlabs:
8364 case Builtin::BIllabs:
8365 case Builtin::BIfabs:
8366 case Builtin::BIfabsf:
8367 case Builtin::BIfabsl:
8368 case Builtin::BIcabs:
8369 case Builtin::BIcabsf:
8370 case Builtin::BIcabsl:
8373 llvm_unreachable(
"Unknown Builtin type");
8379 unsigned AbsKind,
QualType ArgType) {
8380 bool EmitHeaderHint =
true;
8381 const char *HeaderName =
nullptr;
8382 StringRef FunctionName;
8384 FunctionName =
"std::abs";
8386 HeaderName =
"cstdlib";
8388 HeaderName =
"cmath";
8390 llvm_unreachable(
"Invalid Type");
8399 for (
const auto *I : R) {
8402 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
8404 FDecl = dyn_cast<FunctionDecl>(I);
8419 EmitHeaderHint =
false;
8437 EmitHeaderHint =
false;
8441 }
else if (!R.
empty()) {
8447 S.
Diag(
Loc, diag::note_replace_abs_function)
8453 if (!EmitHeaderHint)
8456 S.
Diag(
Loc, diag::note_include_header_or_declare) << HeaderName
8460template <std::
size_t StrLen>
8462 const char (&Str)[StrLen]) {
8475 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
8476 return std::any_of(names.begin(), names.end(), [&](llvm::StringRef name) {
8477 return calleeName == name;
8482 case MathCheck::NaN:
8483 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
8484 "__builtin_nanf16",
"__builtin_nanf128"});
8485 case MathCheck::Inf:
8486 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
8487 "__builtin_inff16",
"__builtin_inff128"});
8489 llvm_unreachable(
"unknown MathCheck");
8493 if (FDecl->
getName() !=
"infinity")
8496 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
8498 if (RDecl->
getName() !=
"numeric_limits")
8515 if (FPO.getNoHonorNaNs() &&
8518 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8519 << 1 << 0 <<
Call->getSourceRange();
8523 if (FPO.getNoHonorInfs() &&
8527 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
8528 << 0 << 0 <<
Call->getSourceRange();
8532void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
8534 if (
Call->getNumArgs() != 1)
8539 if (AbsKind == 0 && !IsStdAbs)
8542 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8548 StringRef FunctionName =
8550 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
8551 Diag(
Call->getExprLoc(), diag::note_remove_abs)
8560 unsigned DiagType = 0;
8566 Diag(
Call->getExprLoc(), diag::warn_pointer_abs) << DiagType << ArgType;
8580 if (ArgValueKind == ParamValueKind) {
8585 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
8586 << FDecl << ArgType << ParamType;
8588 if (NewAbsKind == 0)
8592 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8601 if (NewAbsKind == 0)
8604 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
8605 << FDecl << ParamValueKind << ArgValueKind;
8608 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
8614 if (!
Call || !FDecl)
return;
8618 if (
Call->getExprLoc().isMacroID())
return;
8621 if (
Call->getNumArgs() != 2)
return;
8624 if (!ArgList)
return;
8625 if (ArgList->size() != 1)
return;
8628 const auto& TA = ArgList->
get(0);
8634 auto IsLiteralZeroArg = [](
const Expr*
E) ->
bool {
8635 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(
E);
8636 if (!MTE)
return false;
8637 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
8638 if (!
Num)
return false;
8639 if (
Num->getValue() != 0)
return false;
8643 const Expr *FirstArg =
Call->getArg(0);
8644 const Expr *SecondArg =
Call->getArg(1);
8645 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
8646 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
8649 if (IsFirstArgZero == IsSecondArgZero)
return;
8654 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
8656 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
8657 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
8661 if (IsFirstArgZero) {
8669 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
8689 if (!Size->isComparisonOp() && !Size->isLogicalOp())
8693 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
8694 << SizeRange << FnName;
8695 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
8700 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
8711 bool &IsContained) {
8714 IsContained =
false;
8727 for (
auto *FD : RD->
fields()) {
8740 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(
E))
8741 if (Unary->getKind() == UETT_SizeOf)
8750 if (!
SizeOf->isArgumentType())
8751 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
8758 return SizeOf->getTypeOfArgument();
8764struct SearchNonTrivialToInitializeField
8769 SearchNonTrivialToInitializeField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8773 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8774 asDerived().visitArray(PDIK, AT, SL);
8778 Super::visitWithKind(PDIK, FT, SL);
8793 visit(getContext().getBaseElementType(AT), SL);
8798 SearchNonTrivialToInitializeField(
E, S).visitStruct(RT,
SourceLocation());
8807struct SearchNonTrivialToCopyField
8811 SearchNonTrivialToCopyField(
const Expr *
E,
Sema &S) :
E(
E), S(S) {}
8815 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
8816 asDerived().visitArray(PCK, AT, SL);
8820 Super::visitWithKind(PCK, FT, SL);
8835 visit(getContext().getBaseElementType(AT), SL);
8858 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
8859 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
8883 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
8885 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
8886 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
8892 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
8895 const Expr *SizeArg =
8896 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
8898 auto isLiteralZero = [](
const Expr *
E) {
8899 return (isa<IntegerLiteral>(
E) &&
8900 cast<IntegerLiteral>(
E)->getValue() == 0) ||
8901 (isa<CharacterLiteral>(
E) &&
8902 cast<CharacterLiteral>(
E)->getValue() == 0);
8908 if (isLiteralZero(SizeArg) &&
8915 if (BId == Builtin::BIbzero ||
8918 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
8919 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
8920 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
8921 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
8922 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
8930 if (BId == Builtin::BImemset &&
8934 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
8935 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
8940void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
8947 unsigned ExpectedNumArgs =
8948 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
8949 if (
Call->getNumArgs() < ExpectedNumArgs)
8952 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
8953 BId == Builtin::BIstrndup ? 1 : 2);
8955 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
8956 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
8959 Call->getBeginLoc(),
Call->getRParenLoc()))
8968 llvm::FoldingSetNodeID SizeOfArgID;
8973 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
8977 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
8978 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
9000 if (SizeOfArgID == llvm::FoldingSetNodeID())
9002 llvm::FoldingSetNodeID DestID;
9004 if (DestID == SizeOfArgID) {
9007 unsigned ActionIdx = 0;
9008 StringRef ReadableName = FnName->
getName();
9010 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
9011 if (UnaryOp->getOpcode() == UO_AddrOf)
9025 if (
SM.isMacroArgExpansion(SL)) {
9027 SL =
SM.getSpellingLoc(SL);
9035 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
9042 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
9057 PDiag(diag::warn_sizeof_pointer_type_memaccess)
9058 << FnName << SizeOfArgTy << ArgIdx
9076 unsigned OperationType = 0;
9077 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
9080 if (ArgIdx != 0 || IsCmp) {
9081 if (BId == Builtin::BImemcpy)
9083 else if(BId == Builtin::BImemmove)
9090 PDiag(diag::warn_dyn_class_memaccess)
9091 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
9092 << IsContained << ContainedRD << OperationType
9093 <<
Call->getCallee()->getSourceRange());
9095 BId != Builtin::BImemset)
9098 PDiag(diag::warn_arc_object_memaccess)
9099 << ArgIdx << FnName << PointeeTy
9100 <<
Call->getCallee()->getSourceRange());
9107 bool MayBeTriviallyCopyableCXXRecord =
9109 RT->desugar().isTriviallyCopyableType(
Context);
9111 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9112 RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
9114 PDiag(diag::warn_cstruct_memaccess)
9115 << ArgIdx << FnName << PointeeTy << 0);
9116 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
9117 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
9118 !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9122 PDiag(diag::warn_cxxstruct_memaccess)
9123 << FnName << PointeeTy);
9124 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9125 RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
9127 PDiag(diag::warn_cstruct_memaccess)
9128 << ArgIdx << FnName << PointeeTy << 1);
9129 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
9130 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
9131 !MayBeTriviallyCopyableCXXRecord && ArgIdx == 0) {
9135 PDiag(diag::warn_cxxstruct_memaccess)
9136 << FnName << PointeeTy);
9145 PDiag(diag::note_bad_memaccess_silence)
9165 if (isa<IntegerLiteral>(RHS))
9167 else if (isa<IntegerLiteral>(LHS))
9181 if (CAT->getZExtSize() <= 1)
9189void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
9193 unsigned NumArgs =
Call->getNumArgs();
9194 if ((NumArgs != 3) && (NumArgs != 4))
9199 const Expr *CompareWithSrc =
nullptr;
9202 Call->getBeginLoc(),
Call->getRParenLoc()))
9207 CompareWithSrc = Ex;
9210 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
9211 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
9212 SizeCall->getNumArgs() == 1)
9217 if (!CompareWithSrc)
9224 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
9228 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
9229 if (!CompareWithSrcDRE ||
9233 const Expr *OriginalSizeArg =
Call->getArg(2);
9234 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
9241 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
9246 llvm::raw_svector_ostream
OS(sizeString);
9251 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
9258 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
9259 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
9260 return D1->getDecl() == D2->getDecl();
9265 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
9274void Sema::CheckStrncatArguments(
const CallExpr *CE,
9289 unsigned PatternType = 0;
9297 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
9298 if (BE->getOpcode() == BO_Sub) {
9311 if (PatternType == 0)
9320 if (
SM.isMacroArgExpansion(SL)) {
9321 SL =
SM.getSpellingLoc(SL);
9330 if (!isKnownSizeArray) {
9331 if (PatternType == 1)
9332 Diag(SL, diag::warn_strncat_wrong_size) << SR;
9334 Diag(SL, diag::warn_strncat_src_size) << SR;
9338 if (PatternType == 1)
9339 Diag(SL, diag::warn_strncat_large_size) << SR;
9341 Diag(SL, diag::warn_strncat_src_size) << SR;
9344 llvm::raw_svector_ostream
OS(sizeString);
9352 Diag(SL, diag::note_strncat_wrong_size)
9357void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
9359 if (isa<FieldDecl, FunctionDecl, VarDecl>(
D)) {
9361 << CalleeName << 0 << cast<NamedDecl>(
D);
9366void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
9368 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
9369 const Decl *
D = Lvalue->getDecl();
9370 if (isa<DeclaratorDecl>(
D))
9371 if (!dyn_cast<DeclaratorDecl>(
D)->getType()->isReferenceType())
9372 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
D);
9375 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
9376 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
9377 Lvalue->getMemberDecl());
9380void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
9382 const auto *Lambda = dyn_cast<LambdaExpr>(
9387 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
9388 << CalleeName << 2 ;
9391void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
9393 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
9398 << CalleeName << 0 << Var;
9401void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
9404 llvm::raw_svector_ostream OS(SizeString);
9407 if (Kind == clang::CK_BitCast &&
9408 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
9410 if (Kind == clang::CK_IntegralToPointer &&
9411 !isa<IntegerLiteral>(
9412 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
9415 switch (
Cast->getCastKind()) {
9416 case clang::CK_BitCast:
9417 case clang::CK_IntegralToPointer:
9418 case clang::CK_FunctionToPointerDecay:
9427 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
9428 << CalleeName << 0 << OS.str();
9432void Sema::CheckFreeArguments(
const CallExpr *
E) {
9433 const std::string CalleeName =
9434 cast<FunctionDecl>(
E->getCalleeDecl())->getQualifiedNameAsString();
9438 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
9440 case UnaryOperator::Opcode::UO_AddrOf:
9441 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
9442 case UnaryOperator::Opcode::UO_Plus:
9443 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
9448 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
9450 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
9452 if (
const auto *
Label = dyn_cast<AddrLabelExpr>(Arg)) {
9453 Diag(
Label->getBeginLoc(), diag::warn_free_nonheap_object)
9454 << CalleeName << 0 <<
Label->getLabel()->getIdentifier();
9458 if (isa<BlockExpr>(Arg)) {
9460 << CalleeName << 1 ;
9465 if (
const auto *Cast = dyn_cast<CastExpr>(
E->getArg(0)))
9466 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
9470Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
9476 if (((Attrs && hasSpecificAttr<ReturnsNonNullAttr>(*Attrs)) ||
9479 Diag(ReturnLoc, diag::warn_null_ret)
9489 if (Op == OO_New || Op == OO_Array_New) {
9494 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
9500 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
9517 auto getCastAndLiteral = [&FPLiteral, &FPCast](
Expr *L,
Expr *R) {
9518 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
9520 return FPLiteral && FPCast;
9523 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
9529 llvm::APFloat TargetC = FPLiteral->
getValue();
9531 llvm::APFloat::rmNearestTiesToEven, &Lossy);
9535 Diag(
Loc, diag::warn_float_compare_literal)
9536 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
9549 if (
auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
9550 if (
auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
9551 if (DRL->getDecl() == DRR->getDecl())
9559 if (
FloatingLiteral* FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
9563 if (
FloatingLiteral* FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
9568 if (
CallExpr* CL = dyn_cast<CallExpr>(LeftExprSansParen))
9569 if (CL->getBuiltinCallee())
9572 if (
CallExpr* CR = dyn_cast<CallExpr>(RightExprSansParen))
9573 if (CR->getBuiltinCallee())
9577 Diag(
Loc, diag::warn_floatingpoint_eq)
9598 IntRange(
unsigned Width,
bool NonNegative)
9599 : Width(Width), NonNegative(NonNegative) {}
9602 unsigned valueBits()
const {
9603 return NonNegative ? Width : Width - 1;
9607 static IntRange forBoolType() {
9608 return IntRange(1,
true);
9613 return forValueOfCanonicalType(
C,
9621 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9622 T = VT->getElementType().getTypePtr();
9624 T = CT->getElementType().getTypePtr();
9625 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9626 T = AT->getValueType().getTypePtr();
9628 if (!
C.getLangOpts().CPlusPlus) {
9630 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9631 T = ET->getDecl()->getIntegerType().getDesugaredType(
C).getTypePtr();
9632 }
else if (
const EnumType *ET = dyn_cast<EnumType>(
T)) {
9637 if (
Enum->isFixed()) {
9638 return IntRange(
C.getIntWidth(
QualType(
T, 0)),
9639 !ET->isSignedIntegerOrEnumerationType());
9642 unsigned NumPositive =
Enum->getNumPositiveBits();
9643 unsigned NumNegative =
Enum->getNumNegativeBits();
9645 if (NumNegative == 0)
9646 return IntRange(NumPositive,
true);
9648 return IntRange(std::max(NumPositive + 1, NumNegative),
9652 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9653 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9669 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
9670 T = VT->getElementType().getTypePtr();
9672 T = CT->getElementType().getTypePtr();
9673 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
9674 T = AT->getValueType().getTypePtr();
9675 if (
const EnumType *ET = dyn_cast<EnumType>(
T))
9676 T =
C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
9678 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
9679 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
9688 static IntRange join(IntRange L, IntRange R) {
9689 bool Unsigned = L.NonNegative && R.NonNegative;
9690 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
9691 L.NonNegative && R.NonNegative);
9695 static IntRange bit_and(IntRange L, IntRange R) {
9696 unsigned Bits = std::max(L.Width, R.Width);
9697 bool NonNegative =
false;
9698 if (L.NonNegative) {
9699 Bits = std::min(Bits, L.Width);
9702 if (R.NonNegative) {
9703 Bits = std::min(Bits, R.Width);
9706 return IntRange(Bits, NonNegative);
9710 static IntRange sum(IntRange L, IntRange R) {
9711 bool Unsigned = L.NonNegative && R.NonNegative;
9712 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
9717 static IntRange difference(IntRange L, IntRange R) {
9721 bool CanWiden = !L.NonNegative || !R.NonNegative;
9722 bool Unsigned = L.NonNegative && R.Width == 0;
9723 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
9729 static IntRange product(IntRange L, IntRange R) {
9733 bool CanWiden = !L.NonNegative && !R.NonNegative;
9734 bool Unsigned = L.NonNegative && R.NonNegative;
9735 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
9740 static IntRange rem(IntRange L, IntRange R) {
9744 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
9752 unsigned MaxWidth) {
9753 if (value.isSigned() && value.isNegative())
9754 return IntRange(value.getSignificantBits(),
false);
9756 if (value.getBitWidth() > MaxWidth)
9757 value = value.trunc(MaxWidth);
9761 return IntRange(value.getActiveBits(),
true);
9765 unsigned MaxWidth) {
9773 R = IntRange::join(R, El);
9781 return IntRange::join(R, I);
9796 Ty = AtomicRHS->getValueType();
9815 bool InConstantContext,
9827 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(
E)) {
9828 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
9832 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
9834 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
9835 CE->getCastKind() == CK_BooleanToSignedIntegral;
9839 return OutputTypeRange;
9842 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
9843 InConstantContext, Approximate);
9845 return std::nullopt;
9848 if (SubRange->Width >= OutputTypeRange.Width)
9849 return OutputTypeRange;
9853 return IntRange(SubRange->Width,
9854 SubRange->NonNegative || OutputTypeRange.NonNegative);
9857 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
9860 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
9862 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
9863 InConstantContext, Approximate);
9868 Expr *TrueExpr = CO->getTrueExpr();
9870 return std::nullopt;
9872 std::optional<IntRange> L =
9875 return std::nullopt;
9877 Expr *FalseExpr = CO->getFalseExpr();
9879 return std::nullopt;
9881 std::optional<IntRange> R =
9884 return std::nullopt;
9886 return IntRange::join(*L, *R);
9889 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
9890 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
9892 switch (BO->getOpcode()) {
9894 llvm_unreachable(
"builtin <=> should have class type");
9905 return IntRange::forBoolType();
9934 Combine = IntRange::bit_and;
9942 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
9943 if (I->getValue() == 1) {
9945 return IntRange(R.Width,
true);
9955 case BO_ShrAssign: {
9957 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
9959 return std::nullopt;
9963 if (std::optional<llvm::APSInt> shift =
9964 BO->getRHS()->getIntegerConstantExpr(
C)) {
9965 if (shift->isNonNegative()) {
9966 if (shift->uge(L->Width))
9967 L->Width = (L->NonNegative ? 0 : 1);
9969 L->Width -= shift->getZExtValue();
9983 Combine = IntRange::sum;
9987 if (BO->getLHS()->getType()->isPointerType())
9990 Combine = IntRange::difference;
9995 Combine = IntRange::product;
10004 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
10006 return std::nullopt;
10009 if (std::optional<llvm::APSInt> divisor =
10010 BO->getRHS()->getIntegerConstantExpr(
C)) {
10011 unsigned log2 = divisor->logBase2();
10012 if (
log2 >= L->Width)
10013 L->Width = (L->NonNegative ? 0 : 1);
10015 L->Width = std::min(L->Width -
log2, MaxWidth);
10023 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
10025 return std::nullopt;
10027 return IntRange(L->Width, L->NonNegative && R->NonNegative);
10031 Combine = IntRange::rem;
10043 unsigned opWidth =
C.getIntWidth(
T);
10045 InConstantContext, Approximate);
10047 return std::nullopt;
10050 InConstantContext, Approximate);
10052 return std::nullopt;
10054 IntRange
C = Combine(*L, *R);
10056 C.Width = std::min(
C.Width, MaxWidth);
10060 if (
const auto *UO = dyn_cast<UnaryOperator>(
E)) {
10061 switch (UO->getOpcode()) {
10064 return IntRange::forBoolType();
10077 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
10078 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
10082 return IntRange(BitField->getBitWidthValue(),
10083 BitField->getType()->isUnsignedIntegerOrEnumerationType());
10086 return std::nullopt;
10092 bool InConstantContext,
10093 bool Approximate) {
10102 const llvm::fltSemantics &Src,
10103 const llvm::fltSemantics &Tgt) {
10104 llvm::APFloat truncated = value;
10107 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
10108 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
10110 return truncated.bitwiseIsEqual(value);
10119 const llvm::fltSemantics &Src,
10120 const llvm::fltSemantics &Tgt) {
10137 bool IsListInit =
false);
10143 if (isa<EnumConstantDecl>(DR->getDecl()))
10153 return MacroName !=
"YES" && MacroName !=
"NO" &&
10154 MacroName !=
"true" && MacroName !=
"false";
10177struct PromotedRange {
10179 llvm::APSInt PromotedMin;
10181 llvm::APSInt PromotedMax;
10183 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
10185 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
10186 else if (R.Width >= BitWidth && !
Unsigned) {
10190 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
10191 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
10193 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
10194 .extOrTrunc(BitWidth);
10195 PromotedMin.setIsUnsigned(
Unsigned);
10197 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
10198 .extOrTrunc(BitWidth);
10199 PromotedMax.setIsUnsigned(
Unsigned);
10204 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
10214 InRangeFlag = 0x40,
10217 Min =
LE | InRangeFlag,
10219 Max =
GE | InRangeFlag,
10222 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
10227 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
10228 Value.isUnsigned() == PromotedMin.isUnsigned());
10229 if (!isContiguous()) {
10230 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
10231 if (
Value.isMinValue())
return Min;
10232 if (
Value.isMaxValue())
return Max;
10238 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
10239 case -1:
return Less;
10240 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
10242 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
10244 case 0:
return Max;
10249 llvm_unreachable(
"impossible compare result");
10252 static std::optional<StringRef>
10254 if (Op == BO_Cmp) {
10256 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
10258 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
10259 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
10260 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
10261 return std::nullopt;
10268 }
else if (Op == BO_NE) {
10272 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
10279 if (Op == BO_GE || Op == BO_LE)
10280 std::swap(TrueFlag, FalseFlag);
10283 return StringRef(
"true");
10285 return StringRef(
"false");
10286 return std::nullopt;
10294 if (ICE->getCastKind() != CK_IntegralCast &&
10295 ICE->getCastKind() != CK_NoOp)
10297 E = ICE->getSubExpr();
10306 enum ConstantValueKind {
10311 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
10312 return BL->getValue() ? ConstantValueKind::LiteralTrue
10313 : ConstantValueKind::LiteralFalse;
10314 return ConstantValueKind::Miscellaneous;
10319 const llvm::APSInt &
Value,
10320 bool RhsConstant) {
10342 if (!OtherValueRange)
10347 OtherT = AT->getValueType();
10348 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
10352 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
10358 bool OtherIsBooleanDespiteType =
10360 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
10361 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
10365 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
10366 Value.isUnsigned());
10367 auto Cmp = OtherPromotedValueRange.compare(
Value);
10368 auto Result = PromotedRange::constantValue(
E->getOpcode(), Cmp, RhsConstant);
10374 bool TautologicalTypeCompare =
false;
10376 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
10377 Value.isUnsigned());
10378 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
10379 if (
auto TypeResult = PromotedRange::constantValue(
E->getOpcode(), TypeCmp,
10381 TautologicalTypeCompare =
true;
10389 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
10398 bool InRange = Cmp & PromotedRange::InRangeFlag;
10404 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
10405 Other->getType()->isUnsignedIntegerOrEnumerationType())
10406 TautologicalTypeCompare =
true;
10411 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Constant))
10412 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
10416 llvm::raw_svector_ostream OS(PrettySourceValue);
10418 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
10419 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
10421 OS << (BL->getValue() ?
"YES" :
"NO");
10426 if (!TautologicalTypeCompare) {
10427 S.
Diag(
E->getOperatorLoc(), diag::warn_tautological_compare_value_range)
10428 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
10429 <<
E->getOpcodeStr() << OS.str() << *
Result
10434 if (IsObjCSignedCharBool) {
10436 S.
PDiag(diag::warn_tautological_compare_objc_bool)
10437 << OS.str() << *
Result);
10444 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
10447 E->getOperatorLoc(),
E,
10448 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
10449 : diag::warn_tautological_bool_compare)
10451 << OtherIsBooleanDespiteType << *
Result
10458 ? diag::warn_unsigned_enum_always_true_comparison
10459 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
10460 : diag::warn_unsigned_always_true_comparison)
10461 : diag::warn_tautological_constant_compare;
10464 << RhsConstant << OtherT <<
E->getOpcodeStr() << OS.str() << *
Result
10494 Expr *LHS =
E->getLHS();
10495 Expr *RHS =
E->getRHS();
10498 std::optional<llvm::APSInt> RHSValue =
10500 std::optional<llvm::APSInt> LHSValue =
10504 if (RHSValue && LHSValue)
10508 if ((
bool)RHSValue ^ (
bool)LHSValue) {
10510 const bool RhsConstant = (
bool)RHSValue;
10511 Expr *Const = RhsConstant ? RHS : LHS;
10513 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
10536 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
10538 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
10544 Expr *signedOperand, *unsignedOperand;
10547 "unsigned comparison between two signed integer expressions?");
10548 signedOperand = LHS;
10549 unsignedOperand = RHS;
10551 signedOperand = RHS;
10552 unsignedOperand = LHS;
10558 std::optional<IntRange> signedRange =
10570 if (signedRange->NonNegative)
10577 if (
E->isEqualityOp()) {
10582 if (!unsignedRange)
10587 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
10589 if (unsignedRange->Width < comparisonWidth)
10594 S.
PDiag(diag::warn_mixed_sign_comparison)
10622 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
10623 << BitfieldEnumDecl;
10630 Init->isValueDependent() ||
10631 Init->isTypeDependent())
10634 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
10657 unsigned DiagID = 0;
10658 if (SignedEnum && !SignedBitfield) {
10659 DiagID = diag::warn_unsigned_bitfield_assigned_signed_enum;
10660 }
else if (SignedBitfield && !SignedEnum &&
10662 DiagID = diag::warn_signed_bitfield_enum_conversion;
10666 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
10671 << SignedEnum << TypeRange;
10682 if (BitsNeeded > FieldWidth) {
10684 S.
Diag(InitLoc, diag::warn_bitfield_too_small_for_enum)
10696 unsigned OriginalWidth =
Value.getBitWidth();
10702 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
10703 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
10710 if (!
Value.isSigned() ||
Value.isNegative())
10711 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
10712 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
10713 OriginalWidth =
Value.getSignificantBits();
10715 if (OriginalWidth <= FieldWidth)
10719 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
10723 TruncatedValue = TruncatedValue.extend(OriginalWidth);
10724 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
10728 std::string PrettyTrunc =
toString(TruncatedValue, 10);
10730 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
10731 ? diag::warn_impcast_single_bit_bitield_precision_constant
10732 : diag::warn_impcast_bitfield_precision_constant)
10733 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
10734 <<
Init->getSourceRange();
10749 E->getOperatorLoc())) {
10752 E->getOperatorLoc());
10766 bool pruneControlFlow =
false) {
10767 if (pruneControlFlow) {
10781 unsigned diag,
bool pruneControlFlow =
false) {
10794 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
10797 const bool IsLiteral =
10798 isa<FloatingLiteral>(
E) || isa<FloatingLiteral>(InnerE);
10800 llvm::APFloat
Value(0.0);
10806 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
10811 diag::warn_impcast_float_integer, PruneWarnings);
10814 bool isExact =
false;
10818 llvm::APFloat::opStatus
Result =
Value.convertToInteger(
10819 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
10827 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
10828 precision = (precision * 59 + 195) / 196;
10829 Value.toString(PrettySourceValue, precision);
10833 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
10834 << PrettySourceValue);
10837 if (
Result == llvm::APFloat::opOK && isExact) {
10838 if (IsLiteral)
return;
10845 if (!IsBool &&
Result == llvm::APFloat::opInvalidOp)
10848 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
10849 : diag::warn_impcast_float_to_integer_out_of_range,
10852 unsigned DiagID = 0;
10855 DiagID = diag::warn_impcast_literal_float_to_integer;
10856 }
else if (IntegerValue == 0) {
10857 if (
Value.isZero()) {
10859 diag::warn_impcast_float_integer, PruneWarnings);
10862 DiagID = diag::warn_impcast_float_to_integer_zero;
10864 if (IntegerValue.isUnsigned()) {
10865 if (!IntegerValue.isMaxValue()) {
10867 diag::warn_impcast_float_integer, PruneWarnings);
10870 if (!IntegerValue.isMaxSignedValue() &&
10871 !IntegerValue.isMinSignedValue()) {
10873 diag::warn_impcast_float_integer, PruneWarnings);
10877 DiagID = diag::warn_impcast_float_to_integer;
10882 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
10884 IntegerValue.toString(PrettyTargetValue);
10886 if (PruneWarnings) {
10889 <<
E->
getType() <<
T.getUnqualifiedType()
10890 << PrettySourceValue << PrettyTargetValue
10894 <<
E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
10902 assert(isa<CompoundAssignOperator>(
E) &&
10903 "Must be compound assignment operation");
10909 S.
Diag(
E->getOperatorLoc(), diag::warn_atomic_implicit_seq_cst);
10913 const auto *RBT = cast<CompoundAssignOperator>(
E)
10914 ->getComputationResultType()
10921 if (ResultBT->isInteger())
10923 E->
getExprLoc(), diag::warn_impcast_float_integer);
10925 if (!ResultBT->isFloatingPoint())
10934 diag::warn_impcast_float_result_precision);
10939 if (!
Range.Width)
return "0";
10941 llvm::APSInt ValueInRange =
Value;
10942 ValueInRange.setIsSigned(!
Range.NonNegative);
10943 ValueInRange = ValueInRange.trunc(
Range.Width);
10944 return toString(ValueInRange, 10);
10948 if (!isa<ImplicitCastExpr>(Ex))
10953 const Type *Source =
10955 if (
Target->isDependentType())
10959 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
10960 const Type *BoolCandidateType = ToBool ?
Target : Source;
10969 for (
unsigned i = 0; i < NumArgs; ++i) {
10974 bool IsSwapped = ((i > 0) &&
10976 IsSwapped |= ((i < (NumArgs - 1)) &&
10982 diag::warn_impcast_floating_point_to_bool);
10989 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
10994 if (isa<CallExpr>(
E))
10999 bool IsGNUNullExpr = isa<GNUNullExpr>(NewE);
11001 if (!IsGNUNullExpr && !HasNullPtrType)
11021 if (MacroName ==
"NULL")
11029 S.
Diag(
Loc, diag::warn_impcast_null_pointer_to_integer)
11043 const char FirstLiteralCharacter =
11045 if (FirstLiteralCharacter ==
'0')
11052 const char FirstContextCharacter =
11054 if (FirstContextCharacter ==
'{')
11062 const auto *IL = dyn_cast<IntegerLiteral>(
E);
11064 if (
auto *UO = dyn_cast<UnaryOperator>(
E)) {
11065 if (UO->getOpcode() == UO_Minus)
11066 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
11077 if (
const auto *BO = dyn_cast<BinaryOperator>(
E)) {
11081 if (Opc == BO_Shl) {
11084 if (LHS && LHS->getValue() == 0)
11085 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
11087 RHS->getValue().isNonNegative() &&
11089 S.
Diag(ExprLoc, diag::warn_left_shift_always)
11090 << (
Result.Val.getInt() != 0);
11092 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context) <<
E;
11096 if (
const auto *CO = dyn_cast<ConditionalOperator>(
E)) {
11101 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
11102 (RHS->getValue() == 0 || RHS->getValue() == 1))
11105 if (LHS->getValue() != 0 && RHS->getValue() != 0)
11106 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
11111 bool *ICContext,
bool IsListInit) {
11116 if (Source ==
Target)
return;
11117 if (
Target->isDependentType())
return;
11131 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
11132 if (isa<StringLiteral>(
E))
11137 diag::warn_impcast_string_literal_to_bool);
11138 if (isa<ObjCStringLiteral>(
E) || isa<ObjCArrayLiteral>(
E) ||
11139 isa<ObjCDictionaryLiteral>(
E) || isa<ObjCBoxedExpr>(
E)) {
11143 diag::warn_impcast_objective_c_literal_to_bool);
11158 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
11160 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
11169 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(
E))
11171 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(
E))
11175 if (isa<VectorType>(Source)) {
11176 if (
Target->isSveVLSBuiltinType() &&
11183 if (
Target->isRVVVLSBuiltinType() &&
11190 if (!isa<VectorType>(
Target)) {
11200 diag::warn_hlsl_impcast_vector_truncation);
11209 Source = cast<VectorType>(Source)->getElementType().getTypePtr();
11210 Target = cast<VectorType>(
Target)->getElementType().getTypePtr();
11212 if (
auto VecTy = dyn_cast<VectorType>(
Target))
11213 Target = VecTy->getElementType().getTypePtr();
11216 if (isa<ComplexType>(Source)) {
11217 if (!isa<ComplexType>(
Target)) {
11223 ? diag::err_impcast_complex_scalar
11224 : diag::warn_impcast_complex_scalar);
11227 Source = cast<ComplexType>(Source)->getElementType().getTypePtr();
11228 Target = cast<ComplexType>(
Target)->getElementType().getTypePtr();
11231 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
11284 else if (Order < 0) {
11294 if (TargetBT && TargetBT->
isInteger()) {
11309 if (
Target->isBooleanType() && isa<CallExpr>(
E)) {
11317 if (isa<ImplicitCastExpr>(LastA) &&
11321 diag::warn_impcast_floating_point_to_bool);
11330 if (
Target->isUnsaturatedFixedPointType()) {
11334 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
11339 PDiag(diag::warn_impcast_fixed_point_range)
11340 <<
Value.toString() <<
T
11346 }
else if (
Target->isIntegerType()) {
11350 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
11353 llvm::APSInt IntResult = FXResult.convertToInt(
11359 PDiag(diag::warn_impcast_fixed_point_range)
11360 << FXResult.toString() <<
T
11367 }
else if (
Target->isUnsaturatedFixedPointType()) {
11375 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
11380 PDiag(diag::warn_impcast_fixed_point_range)
11401 unsigned int SourcePrecision =
SourceRange->Width;
11405 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
11408 if (SourcePrecision > 0 && TargetPrecision > 0 &&
11409 SourcePrecision > TargetPrecision) {
11411 if (std::optional<llvm::APSInt> SourceInt =
11416 llvm::APFloat TargetFloatValue(
11418 llvm::APFloat::opStatus ConversionStatus =
11419 TargetFloatValue.convertFromAPInt(
11421 llvm::APFloat::rmNearestTiesToEven);
11423 if (ConversionStatus != llvm::APFloat::opOK) {
11425 SourceInt->toString(PrettySourceValue, 10);
11427 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
11431 PDiag(diag::warn_impcast_integer_float_precision_constant)
11432 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11438 diag::warn_impcast_integer_float_precision);
11447 if (
Target->isBooleanType())
11455 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
11461 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
11466 if (!LikelySourceRange)
11469 IntRange SourceTypeRange =
11470 IntRange::forTargetOfCanonicalType(
Context, Source);
11471 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
11473 if (LikelySourceRange->Width > TargetRange.Width) {
11479 llvm::APSInt
Value(32);
11489 PDiag(diag::warn_impcast_integer_precision_constant)
11490 << PrettySourceValue << PrettyTargetValue
11504 diag::warn_impcast_integer_precision);
11507 if (TargetRange.Width > SourceTypeRange.Width) {
11508 if (
auto *UO = dyn_cast<UnaryOperator>(
E))
11509 if (UO->getOpcode() == UO_Minus)
11511 if (
Target->isUnsignedIntegerType())
11513 diag::warn_impcast_high_order_zero_bits);
11514 if (
Target->isSignedIntegerType())
11516 diag::warn_impcast_nonnegative_result);
11520 if (TargetRange.Width == LikelySourceRange->Width &&
11521 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11536 PDiag(diag::warn_impcast_integer_precision_constant)
11537 << PrettySourceValue << PrettyTargetValue <<
E->
getType() <<
T
11546 if ((!isa<EnumType>(
Target) || !isa<EnumType>(Source)) &&
11547 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
11548 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
11549 LikelySourceRange->Width == TargetRange.Width))) {
11553 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
11559 unsigned DiagID = diag::warn_impcast_integer_sign;
11567 DiagID = diag::warn_impcast_integer_sign_conditional;
11582 if (SourceEnum->getDecl()->hasNameForLinkage() &&
11583 TargetEnum->getDecl()->hasNameForLinkage() &&
11584 SourceEnum != TargetEnum) {
11589 diag::warn_impcast_different_enum_types);
11603 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(
E))
11615 Expr *TrueExpr =
E->getTrueExpr();
11616 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(
E))
11617 TrueExpr = BCO->getCommon();
11619 bool Suspicious =
false;
11628 if (!Suspicious)
return;
11631 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
11638 Suspicious =
false;
11660struct AnalyzeImplicitConversionsWorkItem {
11670 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
11672 Expr *OrigE = Item.E;
11681 bool IsListInit = Item.IsListInit ||
11682 (isa<InitListExpr>(OrigE) && S.
getLangOpts().CPlusPlus);
11687 Expr *SourceExpr =
E;
11692 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(
E))
11693 if (
auto *Src = OVE->getSourceExpr())
11696 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
11697 if (UO->getOpcode() == UO_Not &&
11698 UO->getSubExpr()->isKnownToHaveBooleanValue())
11699 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
11703 if (
const auto *BO = dyn_cast<BinaryOperator>(SourceExpr))
11704 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
11705 BO->getLHS()->isKnownToHaveBooleanValue() &&
11706 BO->getRHS()->isKnownToHaveBooleanValue() &&
11707 BO->getLHS()->HasSideEffects(S.
Context) &&
11708 BO->getRHS()->HasSideEffects(S.
Context)) {
11719 if (SR.str() ==
"&" || SR.str() ==
"|") {
11721 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
11722 << (BO->getOpcode() == BO_And ?
"&" :
"|")
11725 BO->getOperatorLoc(),
11726 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
11727 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
11733 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
11754 for (
auto *SE : POE->semantics())
11755 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
11756 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
11760 if (
auto *CE = dyn_cast<ExplicitCastExpr>(
E)) {
11764 WorkList.push_back({
E, CC, IsListInit});
11768 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(
E)) {
11769 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
11773 if (OutArgE->isInOut())
11774 WorkList.push_back(
11775 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
11776 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
11782 if (BO->isComparisonOp())
11786 if (BO->getOpcode() == BO_Assign)
11789 if (BO->isAssignmentOp())
11797 if (isa<StmtExpr>(
E))
return;
11800 if (isa<UnaryExprOrTypeTraitExpr>(
E))
return;
11805 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
11807 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
11811 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(
E))
11812 if (ChildExpr == CSE->getOperand())
11818 if (IsLogicalAndOperator &&
11823 WorkList.push_back({ChildExpr, CC, IsListInit});
11828 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11832 if (!IsLogicalAndOperator || !isa<StringLiteral>(SubExpr))
11837 if (
U->getOpcode() == UO_LNot) {
11839 }
else if (
U->getOpcode() != UO_AddrOf) {
11840 if (
U->getSubExpr()->getType()->isAtomicType())
11841 S.
Diag(
U->getSubExpr()->getBeginLoc(),
11842 diag::warn_atomic_implicit_seq_cst);
11853 WorkList.push_back({OrigE, CC, IsListInit});
11854 while (!WorkList.empty())
11866 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E)) {
11869 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11870 if (!M->getMemberDecl()->getType()->isReferenceType())
11873 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
11875 FD =
Call->getDirectCallee();
11884 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
11898 if (
SM.isMacroBodyExpansion(
Loc))
11900 Loc =
SM.getImmediateMacroCallerLoc(
Loc);
11923 if (isa<CXXThisExpr>(
E)) {
11924 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
11925 : diag::warn_this_bool_conversion;
11930 bool IsAddressOf =
false;
11932 if (
auto *UO = dyn_cast<UnaryOperator>(
E->
IgnoreParens())) {
11933 if (UO->getOpcode() != UO_AddrOf)
11935 IsAddressOf =
true;
11936 E = UO->getSubExpr();
11940 unsigned DiagID = IsCompare
11941 ? diag::warn_address_of_reference_null_compare
11942 : diag::warn_address_of_reference_bool_conversion;
11950 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
11951 bool IsParam = isa<NonNullAttr>(NonnullAttr);
11953 llvm::raw_string_ostream S(Str);
11955 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
11956 : diag::warn_cast_nonnull_to_bool;
11959 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
11964 if (
auto *Callee =
Call->getDirectCallee()) {
11965 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
11966 ComplainAboutNonnullParamOrCall(A);
11975 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(
E)) {
11976 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
11977 MRecordDecl && MRecordDecl->isLambda()) {
11980 << MRecordDecl->getSourceRange() <<
Range << IsEqual;
11990 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(
E)) {
11991 D = M->getMemberDecl();
11995 if (!
D ||
D->isWeak())
11999 if (
const auto* PV = dyn_cast<ParmVarDecl>(
D)) {
12002 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
12003 ComplainAboutNonnullParamOrCall(A);
12007 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
12011 auto ParamIter = llvm::find(FD->
parameters(), PV);
12013 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
12017 ComplainAboutNonnullParamOrCall(
NonNull);
12022 if (ArgNo.getASTIndex() == ParamNo) {
12023 ComplainAboutNonnullParamOrCall(
NonNull);
12037 if (IsAddressOf && IsFunction) {
12042 if (!IsAddressOf && !IsFunction && !IsArray)
12047 llvm::raw_string_ostream S(Str);
12050 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
12051 : diag::warn_impcast_pointer_to_bool;
12058 DiagType = AddressOf;
12059 else if (IsFunction)
12060 DiagType = FunctionPointer;
12062 DiagType = ArrayPointer;
12064 llvm_unreachable(
"Could not determine diagnostic.");
12066 <<
Range << IsEqual;
12079 if (ReturnType.
isNull())
12117 CheckArrayAccess(
E);
12124 ::CheckBoolLikeConversion(*
this,
E, CC);
12127void Sema::CheckForIntOverflow (
const Expr *
E) {
12132 const Expr *OriginalE = Exprs.pop_back_val();
12135 if (isa<BinaryOperator, UnaryOperator>(
E)) {
12140 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
12141 Exprs.append(InitList->inits().begin(), InitList->inits().end());
12142 else if (isa<ObjCBoxedExpr>(OriginalE))
12144 else if (
const auto *
Call = dyn_cast<CallExpr>(
E))
12145 Exprs.append(
Call->arg_begin(),
Call->arg_end());
12146 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(
E))
12147 Exprs.append(Message->arg_begin(), Message->arg_end());
12148 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(
E))
12149 Exprs.append(Construct->arg_begin(), Construct->arg_end());
12150 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(
E))
12151 Exprs.push_back(Temporary->getSubExpr());
12152 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(
E))
12153 Exprs.push_back(Array->getIdx());
12154 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(
E))
12155 Exprs.push_back(Compound->getInitializer());
12156 else if (
const auto *New = dyn_cast<CXXNewExpr>(
E);
12157 New && New->isArray()) {
12158 if (
auto ArraySize = New->getArraySize())
12159 Exprs.push_back(*ArraySize);
12160 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
12161 Exprs.push_back(MTE->getSubExpr());
12162 }
while (!Exprs.empty());
12177 class SequenceTree {
12181 LLVM_PREFERRED_TYPE(
bool)
12182 unsigned Merged : 1;
12190 friend class SequenceTree;
12194 explicit Seq(
unsigned N) : Index(N) {}
12197 Seq() : Index(0) {}
12200 SequenceTree() { Values.push_back(
Value(0)); }
12201 Seq root()
const {
return Seq(0); }
12208 return Seq(Values.size() - 1);
12212 void merge(
Seq S) {
12213 Values[S.Index].Merged =
true;
12219 bool isUnsequenced(
Seq Cur,
Seq Old) {
12220 unsigned C = representative(Cur.Index);
12221 unsigned Target = representative(Old.Index);
12225 C = Values[
C].Parent;
12232 unsigned representative(
unsigned K) {
12233 if (Values[K].Merged)
12235 return Values[K].Parent = representative(Values[K].
Parent);
12255 UK_ModAsSideEffect,
12257 UK_Count = UK_ModAsSideEffect + 1
12263 const Expr *UsageExpr =
nullptr;
12264 SequenceTree::Seq
Seq;
12270 Usage Uses[UK_Count];
12273 bool Diagnosed =
false;
12277 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
12285 UsageInfoMap UsageMap;
12288 SequenceTree::Seq Region;
12303 struct SequencedSubexpression {
12304 SequencedSubexpression(SequenceChecker &Self)
12305 : Self(Self), OldModAsSideEffect(Self.ModAsSideEffect) {
12306 Self.ModAsSideEffect = &ModAsSideEffect;
12309 ~SequencedSubexpression() {
12310 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
12314 UsageInfo &UI = Self.UsageMap[M.first];
12315 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
12316 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
12317 SideEffectUsage = M.second;
12319 Self.ModAsSideEffect = OldModAsSideEffect;
12322 SequenceChecker &Self;
12331 class EvaluationTracker {
12333 EvaluationTracker(SequenceChecker &Self)
12334 : Self(Self), Prev(Self.EvalTracker) {
12335 Self.EvalTracker =
this;
12338 ~EvaluationTracker() {
12339 Self.EvalTracker = Prev;
12341 Prev->EvalOK &= EvalOK;
12344 bool evaluate(
const Expr *
E,
bool &Result) {
12348 Result, Self.SemaRef.Context,
12349 Self.SemaRef.isConstantEvaluatedContext());
12354 SequenceChecker &Self;
12355 EvaluationTracker *Prev;
12356 bool EvalOK =
true;
12357 } *EvalTracker =
nullptr;
12361 Object getObject(
const Expr *
E,
bool Mod)
const {
12364 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
12365 return getObject(UO->getSubExpr(), Mod);
12367 if (BO->getOpcode() == BO_Comma)
12368 return getObject(BO->getRHS(), Mod);
12369 if (Mod && BO->isAssignmentOp())
12370 return getObject(BO->getLHS(), Mod);
12371 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(
E)) {
12373 if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts()))
12374 return ME->getMemberDecl();
12375 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(
E))
12384 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
12386 Usage &
U = UI.Uses[UK];
12387 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq)) {
12391 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
12392 ModAsSideEffect->push_back(std::make_pair(O,
U));
12394 U.UsageExpr = UsageExpr;
12404 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
12405 UsageKind OtherKind,
bool IsModMod) {
12409 const Usage &
U = UI.Uses[OtherKind];
12410 if (!
U.UsageExpr || !
Tree.isUnsequenced(Region,
U.Seq))
12413 const Expr *Mod =
U.UsageExpr;
12414 const Expr *ModOrUse = UsageExpr;
12415 if (OtherKind == UK_Use)
12416 std::swap(Mod, ModOrUse);
12420 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
12421 : diag::warn_unsequenced_mod_use)
12423 UI.Diagnosed =
true;
12452 void notePreUse(Object O,
const Expr *UseExpr) {
12453 UsageInfo &UI = UsageMap[O];
12455 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
12458 void notePostUse(Object O,
const Expr *UseExpr) {
12459 UsageInfo &UI = UsageMap[O];
12460 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
12462 addUsage(O, UI, UseExpr, UK_Use);
12465 void notePreMod(Object O,
const Expr *ModExpr) {
12466 UsageInfo &UI = UsageMap[O];
12468 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
12469 checkUsage(O, UI, ModExpr, UK_Use,
false);
12472 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
12473 UsageInfo &UI = UsageMap[O];
12474 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
12476 addUsage(O, UI, ModExpr, UK);
12480 SequenceChecker(
Sema &S,
const Expr *
E,
12482 :
Base(S.Context), SemaRef(S), Region(
Tree.root()), WorkList(WorkList) {
12486 (void)this->WorkList;
12489 void VisitStmt(
const Stmt *S) {
12493 void VisitExpr(
const Expr *
E) {
12495 Base::VisitStmt(
E);
12499 for (
auto *Sub : CSE->
children()) {
12500 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
12515 void VisitCastExpr(
const CastExpr *
E) {
12517 if (
E->getCastKind() == CK_LValueToRValue)
12518 O = getObject(
E->getSubExpr(),
false);
12527 void VisitSequencedExpressions(
const Expr *SequencedBefore,
12528 const Expr *SequencedAfter) {
12529 SequenceTree::Seq BeforeRegion =
Tree.allocate(Region);
12530 SequenceTree::Seq AfterRegion =
Tree.allocate(Region);
12531 SequenceTree::Seq OldRegion = Region;
12534 SequencedSubexpression SeqBefore(*
this);
12535 Region = BeforeRegion;
12536 Visit(SequencedBefore);
12539 Region = AfterRegion;
12540 Visit(SequencedAfter);
12542 Region = OldRegion;
12544 Tree.merge(BeforeRegion);
12545 Tree.merge(AfterRegion);
12553 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
12560 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12561 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
12567 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12574 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12575 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
12580 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12592 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
12596 SequenceTree::Seq RHSRegion;
12597 SequenceTree::Seq LHSRegion;
12599 RHSRegion =
Tree.allocate(Region);
12600 LHSRegion =
Tree.allocate(Region);
12602 RHSRegion = Region;
12603 LHSRegion = Region;
12605 SequenceTree::Seq OldRegion = Region;
12621 SequencedSubexpression SeqBefore(*
this);
12622 Region = RHSRegion;
12626 Region = LHSRegion;
12629 if (O && isa<CompoundAssignOperator>(BO))
12630 notePostUse(O, BO);
12634 Region = LHSRegion;
12637 if (O && isa<CompoundAssignOperator>(BO))
12638 notePostUse(O, BO);
12640 Region = RHSRegion;
12648 Region = OldRegion;
12652 : UK_ModAsSideEffect);
12654 Tree.merge(RHSRegion);
12655 Tree.merge(LHSRegion);
12660 VisitBinAssign(CAO);
12663 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12664 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
12668 return VisitExpr(UO);
12676 : UK_ModAsSideEffect);
12679 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12680 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
12684 return VisitExpr(UO);
12688 notePostMod(O, UO, UK_ModAsSideEffect);
12697 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12698 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12699 SequenceTree::Seq OldRegion = Region;
12701 EvaluationTracker Eval(*
this);
12703 SequencedSubexpression Sequenced(*
this);
12704 Region = LHSRegion;
12711 bool EvalResult =
false;
12712 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12713 bool ShouldVisitRHS = !EvalOK || !EvalResult;
12714 if (ShouldVisitRHS) {
12715 Region = RHSRegion;
12719 Region = OldRegion;
12720 Tree.merge(LHSRegion);
12721 Tree.merge(RHSRegion);
12730 SequenceTree::Seq LHSRegion =
Tree.allocate(Region);
12731 SequenceTree::Seq RHSRegion =
Tree.allocate(Region);
12732 SequenceTree::Seq OldRegion = Region;
12734 EvaluationTracker Eval(*
this);
12736 SequencedSubexpression Sequenced(*
this);
12737 Region = LHSRegion;
12743 bool EvalResult =
false;
12744 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
12745 bool ShouldVisitRHS = !EvalOK || EvalResult;
12746 if (ShouldVisitRHS) {
12747 Region = RHSRegion;
12751 Region = OldRegion;
12752 Tree.merge(LHSRegion);
12753 Tree.merge(RHSRegion);
12761 SequenceTree::Seq ConditionRegion =
Tree.allocate(Region);
12777 SequenceTree::Seq TrueRegion =
Tree.allocate(Region);
12778 SequenceTree::Seq FalseRegion =
Tree.allocate(Region);
12779 SequenceTree::Seq OldRegion = Region;
12781 EvaluationTracker Eval(*
this);
12783 SequencedSubexpression Sequenced(*
this);
12784 Region = ConditionRegion;
12794 bool EvalResult =
false;
12795 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
12796 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
12797 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
12798 if (ShouldVisitTrueExpr) {
12799 Region = TrueRegion;
12802 if (ShouldVisitFalseExpr) {
12803 Region = FalseRegion;
12807 Region = OldRegion;
12808 Tree.merge(ConditionRegion);
12809 Tree.merge(TrueRegion);
12810 Tree.merge(FalseRegion);
12813 void VisitCallExpr(
const CallExpr *CE) {
12825 SequencedSubexpression Sequenced(*
this);
12830 SequenceTree::Seq CalleeRegion;
12831 SequenceTree::Seq OtherRegion;
12832 if (SemaRef.getLangOpts().CPlusPlus17) {
12833 CalleeRegion = Tree.allocate(Region);
12834 OtherRegion = Tree.allocate(Region);
12836 CalleeRegion = Region;
12837 OtherRegion = Region;
12839 SequenceTree::Seq OldRegion = Region;
12842 Region = CalleeRegion;
12844 SequencedSubexpression Sequenced(*this);
12845 Visit(CE->getCallee());
12847 Visit(CE->getCallee());
12851 Region = OtherRegion;
12855 Region = OldRegion;
12857 Tree.merge(CalleeRegion);
12858 Tree.merge(OtherRegion);
12876 return VisitCallExpr(CXXOCE);
12887 case OO_MinusEqual:
12889 case OO_SlashEqual:
12890 case OO_PercentEqual:
12891 case OO_CaretEqual:
12894 case OO_LessLessEqual:
12895 case OO_GreaterGreaterEqual:
12896 SequencingKind = RHSBeforeLHS;
12900 case OO_GreaterGreater:
12906 SequencingKind = LHSBeforeRHS;
12910 SequencingKind = LHSBeforeRest;
12914 SequencingKind = NoSequencing;
12918 if (SequencingKind == NoSequencing)
12919 return VisitCallExpr(CXXOCE);
12922 SequencedSubexpression Sequenced(*
this);
12925 assert(SemaRef.getLangOpts().CPlusPlus17 &&
12926 "Should only get there with C++17 and above!");
12927 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
12928 "Should only get there with an overloaded binary operator"
12929 " or an overloaded call operator!");
12931 if (SequencingKind == LHSBeforeRest) {
12932 assert(CXXOCE->getOperator() == OO_Call &&
12933 "We should only have an overloaded call operator here!");
12942 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
12943 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
12944 SequenceTree::Seq OldRegion = Region;
12946 assert(CXXOCE->getNumArgs() >= 1 &&
12947 "An overloaded call operator must have at least one argument"
12948 " for the postfix-expression!");
12949 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
12950 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
12951 CXXOCE->getNumArgs() - 1);
12955 Region = PostfixExprRegion;
12956 SequencedSubexpression Sequenced(*this);
12957 Visit(PostfixExpr);
12961 Region = ArgsRegion;
12962 for (const Expr *Arg : Args)
12965 Region = OldRegion;
12966 Tree.merge(PostfixExprRegion);
12967 Tree.merge(ArgsRegion);
12969 assert(CXXOCE->getNumArgs() == 2 &&
12970 "Should only have two arguments here!");
12971 assert((SequencingKind == LHSBeforeRHS ||
12972 SequencingKind == RHSBeforeLHS) &&
12973 "Unexpected sequencing kind!");
12977 const Expr *E1 = CXXOCE->getArg(0);
12978 const Expr *E2 = CXXOCE->getArg(1);
12979 if (SequencingKind == RHSBeforeLHS)
12982 return VisitSequencedExpressions(E1, E2);
12989 SequencedSubexpression Sequenced(*
this);
12992 return VisitExpr(CCE);
12995 SequenceExpressionsInOrder(
13001 return VisitExpr(ILE);
13004 SequenceExpressionsInOrder(ILE->
inits());
13016 SequenceTree::Seq
Parent = Region;
13017 for (
const Expr *
E : ExpressionList) {
13021 Elts.push_back(Region);
13027 for (
unsigned I = 0; I < Elts.size(); ++I)
13028 Tree.merge(Elts[I]);
13032SequenceChecker::UsageInfo::UsageInfo() =
default;
13036void Sema::CheckUnsequencedOperations(
const Expr *
E) {
13038 WorkList.push_back(
E);
13039 while (!WorkList.empty()) {
13040 const Expr *Item = WorkList.pop_back_val();
13041 SequenceChecker(*
this, Item, WorkList);
13046 bool IsConstexpr) {
13048 IsConstexpr || isa<ConstantExpr>(
E));
13049 CheckImplicitConversions(
E, CheckLoc);
13051 CheckUnsequencedOperations(
E);
13053 CheckForIntOverflow(
E);
13067 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
13071 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
13075 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
13089 S.
Diag(
Loc, diag::err_array_star_in_function_definition);
13093 bool CheckParameterNames) {
13094 bool HasInvalidParm =
false;
13096 assert(Param &&
"null in a parameter list");
13105 if (!Param->isInvalidDecl() &&
13107 diag::err_typecheck_decl_incomplete_type) ||
13109 diag::err_abstract_type_in_decl,
13111 Param->setInvalidDecl();
13112 HasInvalidParm =
true;
13117 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
13121 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
13129 QualType PType = Param->getOriginalType();
13137 if (!Param->isInvalidDecl()) {
13139 if (!ClassDecl->isInvalidDecl() &&
13140 !ClassDecl->hasIrrelevantDestructor() &&
13141 !ClassDecl->isDependentContext() &&
13142 ClassDecl->isParamDestroyedInCallee()) {
13154 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
13155 if (!Param->getType().isConstQualified())
13156 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
13160 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
13165 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
13166 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
13171 if (!Param->isInvalidDecl() &&
13173 Param->setInvalidDecl();
13174 HasInvalidParm =
true;
13175 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
13179 return HasInvalidParm;
13182std::optional<std::pair<
13191static std::pair<CharUnits, CharUnits>
13199 if (
Base->isVirtual()) {
13206 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
13213 DerivedType =
Base->getType();
13216 return std::make_pair(BaseAlignment, Offset);
13220static std::optional<std::pair<CharUnits, CharUnits>>
13226 return std::nullopt;
13231 return std::nullopt;
13235 CharUnits Offset = EltSize * IdxRes->getExtValue();
13238 return std::make_pair(
P->first,
P->second + Offset);
13244 return std::make_pair(
13245 P->first.alignmentAtOffset(
P->second).alignmentAtOffset(EltSize),
13251std::optional<std::pair<
13259 case Stmt::CStyleCastExprClass:
13260 case Stmt::CXXStaticCastExprClass:
13261 case Stmt::ImplicitCastExprClass: {
13262 auto *CE = cast<CastExpr>(
E);
13263 const Expr *From = CE->getSubExpr();
13264 switch (CE->getCastKind()) {
13269 case CK_UncheckedDerivedToBase:
13270 case CK_DerivedToBase: {
13280 case Stmt::ArraySubscriptExprClass: {
13281 auto *ASE = cast<ArraySubscriptExpr>(
E);
13285 case Stmt::DeclRefExprClass: {
13286 if (
auto *VD = dyn_cast<VarDecl>(cast<DeclRefExpr>(
E)->getDecl())) {
13289 if (!VD->getType()->isReferenceType()) {
13291 if (VD->hasDependentAlignment())
13300 case Stmt::MemberExprClass: {
13301 auto *ME = cast<MemberExpr>(
E);
13302 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
13306 std::optional<std::pair<CharUnits, CharUnits>>
P;
13315 return std::make_pair(
P->first,
13318 case Stmt::UnaryOperatorClass: {
13319 auto *UO = cast<UnaryOperator>(
E);
13328 case Stmt::BinaryOperatorClass: {
13329 auto *BO = cast<BinaryOperator>(
E);
13340 return std::nullopt;
13345std::optional<std::pair<
13354 case Stmt::CStyleCastExprClass:
13355 case Stmt::CXXStaticCastExprClass:
13356 case Stmt::ImplicitCastExprClass: {
13357 auto *CE = cast<CastExpr>(
E);
13358 const Expr *From = CE->getSubExpr();
13359 switch (CE->getCastKind()) {
13364 case CK_ArrayToPointerDecay:
13366 case CK_UncheckedDerivedToBase:
13367 case CK_DerivedToBase: {
13377 case Stmt::CXXThisExprClass: {
13382 case Stmt::UnaryOperatorClass: {
13383 auto *UO = cast<UnaryOperator>(
E);
13388 case Stmt::BinaryOperatorClass: {
13389 auto *BO = cast<BinaryOperator>(
E);
13397 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
13398 std::swap(LHS, RHS);
13408 return std::nullopt;
13413 std::optional<std::pair<CharUnits, CharUnits>>
P =
13417 return P->first.alignmentAtOffset(
P->second);
13435 if (!DestPtr)
return;
13441 if (DestAlign.
isOne())
return;
13445 if (!SrcPtr)
return;
13456 if (SrcAlign >= DestAlign)
return;
13461 <<
static_cast<unsigned>(DestAlign.
getQuantity())
13465void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
13467 bool AllowOnePastEnd,
bool IndexNegated) {
13476 const Type *EffectiveType =
13483 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
13485 const Type *BaseType =
13487 bool IsUnboundedArray =
13489 Context, StrictFlexArraysLevel,
13499 llvm::APSInt index =
Result.Val.getInt();
13500 if (IndexNegated) {
13501 index.setIsUnsigned(
false);
13505 if (IsUnboundedArray) {
13508 if (index.isUnsigned() || !index.isNegative()) {
13510 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
13512 if (index.getBitWidth() < AddrBits)
13513 index = index.zext(AddrBits);
13514 std::optional<CharUnits> ElemCharUnits =
13515 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
13518 if (!ElemCharUnits || ElemCharUnits->isZero())
13520 llvm::APInt ElemBytes(index.getBitWidth(), ElemCharUnits->getQuantity());
13525 if (index.getActiveBits() <= AddrBits) {
13527 llvm::APInt Product(index);
13529 Product = Product.umul_ov(ElemBytes, Overflow);
13530 if (!Overflow && Product.getActiveBits() <= AddrBits)
13536 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
13537 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
13539 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
13540 MaxElems = MaxElems.udiv(ElemBytes);
13543 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
13544 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
13550 <<
toString(index, 10,
true) << AddrBits
13551 << (
unsigned)ASTC.toBits(*ElemCharUnits)
13554 << (
unsigned)MaxElems.getLimitedValue(~0
U)
13559 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13561 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13563 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13564 ND = ME->getMemberDecl();
13568 PDiag(diag::note_array_declared_here) << ND);
13573 if (index.isUnsigned() || !index.isNegative()) {
13583 llvm::APInt size = ArrayTy->
getSize();
13585 if (BaseType != EffectiveType) {
13593 if (!ptrarith_typesize)
13596 if (ptrarith_typesize != array_typesize) {
13598 uint64_t ratio = array_typesize / ptrarith_typesize;
13602 if (ptrarith_typesize * ratio == array_typesize)
13603 size *= llvm::APInt(size.getBitWidth(), ratio);
13607 if (size.getBitWidth() > index.getBitWidth())
13608 index = index.zext(size.getBitWidth());
13609 else if (size.getBitWidth() < index.getBitWidth())
13610 size = size.zext(index.getBitWidth());
13616 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
13633 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
13634 : diag::warn_ptr_arith_exceeds_bounds;
13635 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
13643 unsigned DiagID = diag::warn_array_index_precedes_bounds;
13645 DiagID = diag::warn_ptr_arith_precedes_bounds;
13646 if (index.isNegative()) index = -index;
13656 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
13658 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
13660 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
13661 ND = ME->getMemberDecl();
13665 PDiag(diag::note_array_declared_here) << ND);
13668void Sema::CheckArrayAccess(
const Expr *
expr) {
13669 int AllowOnePastEnd = 0;
13671 expr =
expr->IgnoreParenImpCasts();
13672 switch (
expr->getStmtClass()) {
13673 case Stmt::ArraySubscriptExprClass: {
13676 AllowOnePastEnd > 0);
13680 case Stmt::MemberExprClass: {
13681 expr = cast<MemberExpr>(
expr)->getBase();
13684 case Stmt::ArraySectionExprClass: {
13690 nullptr, AllowOnePastEnd > 0);
13693 case Stmt::UnaryOperatorClass: {
13709 case Stmt::ConditionalOperatorClass: {
13712 CheckArrayAccess(lhs);
13714 CheckArrayAccess(rhs);
13717 case Stmt::CXXOperatorCallExprClass: {
13718 const auto *OCE = cast<CXXOperatorCallExpr>(
expr);
13719 for (
const auto *Arg : OCE->arguments())
13720 CheckArrayAccess(Arg);
13730 Expr *RHS,
bool isProperty) {
13742 S.
Diag(
Loc, diag::warn_arc_literal_assign)
13744 << (isProperty ? 0 : 1)
13752 Expr *RHS,
bool isProperty) {
13755 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13756 S.
Diag(
Loc, diag::warn_arc_retained_assign)
13758 << (isProperty ? 0 : 1)
13762 RHS =
cast->getSubExpr();
13833 if (
cast->getCastKind() == CK_ARCConsumeObject) {
13834 Diag(
Loc, diag::warn_arc_retained_property_assign)
13838 RHS =
cast->getSubExpr();
13861 bool StmtLineInvalid;
13864 if (StmtLineInvalid)
13867 bool BodyLineInvalid;
13870 if (BodyLineInvalid)
13874 if (StmtLine != BodyLine)
13889 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13898 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13902 const Stmt *PossibleBody) {
13908 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
13909 StmtLoc = FS->getRParenLoc();
13910 Body = FS->getBody();
13911 DiagID = diag::warn_empty_for_body;
13912 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
13913 StmtLoc = WS->getRParenLoc();
13914 Body = WS->getBody();
13915 DiagID = diag::warn_empty_while_body;
13920 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
13943 bool ProbableTypo = isa<CompoundStmt>(PossibleBody);
13944 if (!ProbableTypo) {
13945 bool BodyColInvalid;
13948 if (BodyColInvalid)
13951 bool StmtColInvalid;
13954 if (StmtColInvalid)
13957 if (BodyCol > StmtCol)
13958 ProbableTypo =
true;
13961 if (ProbableTypo) {
13963 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
13971 if (
Diags.
isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
13983 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
13985 RHSExpr = CE->
getArg(0);
13986 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
13987 CXXSCE && CXXSCE->isXValue())
13988 RHSExpr = CXXSCE->getSubExpr();
13992 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
13993 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
13996 if (LHSDeclRef && RHSDeclRef) {
14003 auto D =
Diag(OpLoc, diag::warn_self_move)
14019 const Expr *LHSBase = LHSExpr;
14020 const Expr *RHSBase = RHSExpr;
14021 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
14022 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
14023 if (!LHSME || !RHSME)
14026 while (LHSME && RHSME) {
14033 LHSME = dyn_cast<MemberExpr>(LHSBase);
14034 RHSME = dyn_cast<MemberExpr>(RHSBase);
14037 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
14038 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
14039 if (LHSDeclRef && RHSDeclRef) {
14046 Diag(OpLoc, diag::warn_self_move)
14052 if (isa<CXXThisExpr>(LHSBase) && isa<CXXThisExpr>(RHSBase))
14053 Diag(OpLoc, diag::warn_self_move)
14077 bool AreUnionMembers =
false) {
14078 [[maybe_unused]]
const Type *Field1Parent =
14080 [[maybe_unused]]
const Type *Field2Parent =
14085 "Can't evaluate layout compatibility between a struct field and a "
14088 (AreUnionMembers && Field1Parent->
isUnionType())) &&
14089 "AreUnionMembers should be 'true' for union fields (only).");
14102 if (Bits1 != Bits2)
14106 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
14107 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
14110 if (!AreUnionMembers &&
14122 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
14123 RD1 = D1CXX->getStandardLayoutBaseWithFields();
14125 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
14126 RD2 = D2CXX->getStandardLayoutBaseWithFields();
14131 return isLayoutCompatible(C, F1, F2);
14140 for (
auto *Field2 : RD2->
fields())
14141 UnmatchedFields.insert(Field2);
14143 for (
auto *Field1 : RD1->
fields()) {
14144 auto I = UnmatchedFields.begin();
14145 auto E = UnmatchedFields.end();
14147 for ( ; I !=
E; ++I) {
14149 bool Result = UnmatchedFields.erase(*I);
14159 return UnmatchedFields.empty();
14185 if (
C.hasSameType(T1, T2))
14194 if (TC1 == Type::Enum) {
14196 cast<EnumType>(T1)->getDecl(),
14197 cast<EnumType>(T2)->getDecl());
14198 }
else if (TC1 == Type::Record) {
14203 cast<RecordType>(T1)->getDecl(),
14204 cast<RecordType>(T2)->getDecl());
14218 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
14249 const ValueDecl **VD, uint64_t *MagicValue,
14250 bool isConstantEvaluated) {
14258 case Stmt::UnaryOperatorClass: {
14267 case Stmt::DeclRefExprClass: {
14268 const DeclRefExpr *DRE = cast<DeclRefExpr>(TypeExpr);
14273 case Stmt::IntegerLiteralClass: {
14275 llvm::APInt MagicValueAPInt = IL->
getValue();
14276 if (MagicValueAPInt.getActiveBits() <= 64) {
14277 *MagicValue = MagicValueAPInt.getZExtValue();
14283 case Stmt::BinaryConditionalOperatorClass:
14284 case Stmt::ConditionalOperatorClass: {
14286 cast<AbstractConditionalOperator>(TypeExpr);
14289 isConstantEvaluated)) {
14299 case Stmt::BinaryOperatorClass: {
14302 TypeExpr = BO->
getRHS();
14332 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
14335 bool isConstantEvaluated) {
14336 FoundWrongKind =
false;
14341 uint64_t MagicValue;
14343 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
14347 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
14348 if (I->getArgumentKind() != ArgumentKind) {
14349 FoundWrongKind =
true;
14352 TypeInfo.Type = I->getMatchingCType();
14353 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
14354 TypeInfo.MustBeNull = I->getMustBeNull();
14365 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
14366 if (I == MagicValues->end())
14375 bool LayoutCompatible,
14377 if (!TypeTagForDatatypeMagicValues)
14378 TypeTagForDatatypeMagicValues.reset(
14379 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
14382 (*TypeTagForDatatypeMagicValues)[Magic] =
14398 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
14399 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
14400 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
14401 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
14404void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
14408 bool IsPointerAttr =
Attr->getIsPointer();
14411 unsigned TypeTagIdxAST =
Attr->getTypeTagIdx().getASTIndex();
14412 if (TypeTagIdxAST >= ExprArgs.size()) {
14413 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14414 << 0 <<
Attr->getTypeTagIdx().getSourceIndex();
14417 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
14418 bool FoundWrongKind;
14421 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
14423 if (FoundWrongKind)
14425 diag::warn_type_tag_for_datatype_wrong_kind)
14431 unsigned ArgumentIdxAST =
Attr->getArgumentIdx().getASTIndex();
14432 if (ArgumentIdxAST >= ExprArgs.size()) {
14433 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
14434 << 1 <<
Attr->getArgumentIdx().getSourceIndex();
14437 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
14438 if (IsPointerAttr) {
14440 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
14441 if (ICE->getType()->isVoidPointerType() &&
14442 ICE->getCastKind() == CK_BitCast)
14443 ArgumentExpr = ICE->getSubExpr();
14456 diag::warn_type_safety_null_pointer_required)
14468 bool mismatch =
false;
14491 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
14492 << ArgumentType << ArgumentKind
14493 <<
TypeInfo.LayoutCompatible << RequiredType
14500 MisalignedMembers.emplace_back(
E, RD, MD, Alignment);
14504 for (MisalignedMember &m : MisalignedMembers) {
14510 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
14513 MisalignedMembers.clear();
14520 if (isa<UnaryOperator>(
E) &&
14521 cast<UnaryOperator>(
E)->getOpcode() == UO_AddrOf) {
14522 auto *Op = cast<UnaryOperator>(
E)->getSubExpr()->
IgnoreParens();
14523 if (isa<MemberExpr>(Op)) {
14524 auto *MA = llvm::find(MisalignedMembers, MisalignedMember(Op));
14525 if (MA != MisalignedMembers.end() &&
14530 MisalignedMembers.erase(MA);
14539 const auto *ME = dyn_cast<MemberExpr>(
E);
14551 bool AnyIsPacked =
false;
14553 QualType BaseType = ME->getBase()->getType();
14563 auto *FD = dyn_cast<FieldDecl>(MD);
14569 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
14570 ReverseMemberChain.push_back(FD);
14573 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
14575 assert(TopME &&
"We did not compute a topmost MemberExpr!");
14582 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
14586 if (!DRE && !isa<CXXThisExpr>(TopBase))
14593 if (ExpectedAlignment.
isOne())
14598 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
14603 ReverseMemberChain.back()->getParent()->getTypeForDecl());
14607 if (DRE && !TopME->
isArrow()) {
14610 CompleteObjectAlignment =
14615 if (Offset % ExpectedAlignment != 0 ||
14618 CompleteObjectAlignment < ExpectedAlignment) {
14629 for (
FieldDecl *FDI : ReverseMemberChain) {
14630 if (FDI->hasAttr<PackedAttr>() ||
14631 FDI->getParent()->hasAttr<PackedAttr>()) {
14633 Alignment = std::min(
14639 assert(FD &&
"We did not find a packed FieldDecl!");
14644void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
14645 using namespace std::placeholders;
14648 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
14670bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
bool FPOnly) {
14684 TheCall->
setType(VecTy0->getElementType());
14708 diag::err_typecheck_call_different_arg_types)
14725 bool CheckForFloatArgs) {
14730 for (
int I = 0; I < 3; ++I) {
14734 Args[I] = Converted.
get();
14737 if (CheckForFloatArgs) {
14738 int ArgOrdinal = 1;
14739 for (
Expr *Arg : Args) {
14741 Arg->
getType(), ArgOrdinal++))
14745 int ArgOrdinal = 1;
14746 for (
Expr *Arg : Args) {
14753 for (
int I = 1; I < 3; ++I) {
14754 if (Args[0]->getType().getCanonicalType() !=
14755 Args[I]->getType().getCanonicalType()) {
14756 return Diag(Args[0]->getBeginLoc(),
14757 diag::err_typecheck_call_different_arg_types)
14761 TheCall->
setArg(I, Args[I]);
14764 TheCall->
setType(Args[0]->getType());
14768bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
14780bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
14789 << 1 << 0 << TyArg;
14803 Expr *Matrix = MatrixArg.
get();
14808 << 1 << 1 << Matrix->
getType();
14815 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
14818 TheCall->
setType(ResultType);
14821 TheCall->
setArg(0, Matrix);
14826static std::optional<unsigned>
14829 std::optional<llvm::APSInt>
Value =
14836 uint64_t
Dim =
Value->getZExtValue();
14855 unsigned PtrArgIdx = 0;
14861 bool ArgError =
false;
14868 PtrExpr = PtrConv.
get();
14869 TheCall->
setArg(0, PtrExpr);
14880 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
14887 << PtrArgIdx + 1 << 2
14894 auto ApplyArgumentConversions = [
this](
Expr *
E) {
14903 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
14905 RowsExpr = RowsConv.
get();
14906 TheCall->
setArg(1, RowsExpr);
14908 RowsExpr =
nullptr;
14910 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
14912 ColumnsExpr = ColumnsConv.
get();
14913 TheCall->
setArg(2, ColumnsExpr);
14915 ColumnsExpr =
nullptr;
14926 std::optional<unsigned> MaybeRows;
14930 std::optional<unsigned> MaybeColumns;
14935 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
14938 StrideExpr = StrideConv.
get();
14939 TheCall->
setArg(3, StrideExpr);
14942 if (std::optional<llvm::APSInt>
Value =
14945 if (Stride < *MaybeRows) {
14947 diag::err_builtin_matrix_stride_too_small);
14953 if (ArgError || !MaybeRows || !MaybeColumns)
14966 unsigned PtrArgIdx = 1;
14971 bool ArgError =
false;
14977 MatrixExpr = MatrixConv.
get();
14978 TheCall->
setArg(0, MatrixExpr);
14988 << 1 << 1 << MatrixExpr->
getType();
14996 PtrExpr = PtrConv.
get();
14997 TheCall->
setArg(1, PtrExpr);
15008 << PtrArgIdx + 1 << 2 << PtrExpr->
getType();
15013 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
15020 diag::err_builtin_matrix_pointer_arg_mismatch)
15021 << ElementTy << MatrixTy->getElementType();
15036 StrideExpr = StrideConv.
get();
15037 TheCall->
setArg(2, StrideExpr);
15042 if (std::optional<llvm::APSInt>
Value =
15045 if (Stride < MatrixTy->getNumRows()) {
15047 diag::err_builtin_matrix_stride_too_small);
15067 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
15072 llvm::StringSet<> CalleeTCBs;
15073 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
15074 CalleeTCBs.insert(A->getTCBName());
15075 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
15076 CalleeTCBs.insert(A->getTCBName());
15080 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
15081 StringRef CallerTCB = A->getTCBName();
15082 if (CalleeTCBs.count(CallerTCB) == 0) {
15083 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
15084 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
ASTImporterLookupTable & LT
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void DiagnoseFloatingImpCast(Sema &S, Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, bool inFunctionCall, Sema::VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, Sema::FormatStringType Type, Sema::VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, bool IgnoreStringsWithoutSpecifiers=false)
static IntRange GetValueRange(ASTContext &C, llvm::APSInt &value, unsigned MaxWidth)
static bool IsImplicitBoolFloatConversion(Sema &S, Expr *Ex, bool ToBool)
static void DiagnoseImpCast(Sema &S, Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool pruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static void CheckImplicitArgumentConversions(Sema &S, CallExpr *TheCall, SourceLocation CC)
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool isKnownToHaveUnsignedValue(Expr *E)
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool IsSameCharType(QualType T1, QualType T2)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)
static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static int classifyConstantValue(Expr *Constant)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)
static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)
static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)
static bool referToTheSameDecl(const Expr *E1, const Expr *E2)
Check if two expressions refer to the same declaration.
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static bool requiresParensToAddCast(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool IsEnumConstOrFromMacro(Sema &S, Expr *E)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static bool HasEnumType(Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)
Compute the alignment and offset of a binary additive operator.
static bool checkFPMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, int ArgIndex)
static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SPIRV constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
const NestedNameSpecifier * Specifier
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
bool areLaxCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible SVE vector types, false otherwise.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
bool areCompatibleRVVTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an RISC-V vector builtin type and a VectorType that is a fixed-len...
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat 'semantics' for the specified scalar floating point type.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
QualType getRecordType(const RecordDecl *Decl) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
bool areLaxCompatibleRVVTypes(QualType FirstType, QualType SecondType)
Return true if the given vector types are lax-compatible RISC-V vector types as defined by -flax-vect...
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const
Compare the rank of two floating point types as above, but compare equal if both types have the same ...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
const TargetInfo * getAuxTargetInfo() const
llvm::APFixedPoint getFixedPointMin(QualType Ty) const
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
TypeInfoChars getTypeInfoInChars(const Type *T) const
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
llvm::FixedPointSemantics getFixedPointSemantics(QualType Ty) const
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getExceptionObjectType(QualType T) const
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error, unsigned *IntegerConstantArgs=nullptr) const
Return the type for the specified builtin.
CanQualType UnsignedShortTy
bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const
Return a string representing the human readable name for the specified function declaration or file n...
llvm::APFixedPoint getFixedPointMax(QualType Ty) const
QualType getComplexType(QualType T) const
Return the uniqued reference to the type for a complex number with the specified element type.
bool areCompatibleSveTypes(QualType FirstType, QualType SecondType)
Return true if the given types are an SVE builtin and a VectorType that is a fixed-length representat...
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
CanQualType getNSIntegerType() const
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
QualType getTypedefType(const TypedefNameDecl *Decl, QualType Underlying=QualType()) const
Return the unique reference to the type for the specified typedef-name decl.
QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const
Return the unique reference to the matrix type of the specified element type and size.
CanQualType getNSUIntegerType() const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
std::unique_ptr< AtomicScopeModel > getScopeModel() const
Get atomic scope model.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
ConceptDecl * getTypeConstraintConcept() const
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getExprLoc() const
bool isEqualityOp() const
static bool isAdditiveOp(Opcode Opc)
A fixed int type of a specified bitwidth.
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
bool isAuxBuiltinID(unsigned ID) const
Return true if builtin ID belongs to AuxTarget.
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
llvm::StringRef getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
unsigned getAuxBuiltinID(unsigned ID) const
Return real builtin ID (i.e.
bool isTSBuiltin(unsigned ID) const
Return true if this function is a target-specific builtin.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
ArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isDynamicClass() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getRParenLoc() const
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
void setExprNeedsCleanups(bool SideEffects)
Complex values, per C99 6.2.5p11.
CompoundAssignOperator - For compound assignments (e.g.
Declaration of a C++20 concept.
ConditionalOperator - The ?: ternary operator.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
Represents a concrete matrix type with constant number of rows and columns.
static constexpr unsigned getMaxElementsPerDimension()
Returns the maximum number of elements per dimension.
static constexpr bool isDimensionValid(size_t NumElements)
Returns true if NumElements is a valid matrix dimension.
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Represents an expression that might suspend coroutine execution; either a co_await or co_yield expres...
Expr * getOperand() const
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
DynamicCountPointerKind getKind() const
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
bool isStdNamespace() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
SourceLocation getBeginLoc() const LLVM_READONLY
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
RAII class that determines when any errors have occurred between the time the instance was created an...
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
unsigned getNumNegativeBits() const
Returns the width in bits required to store all the negative enumerators of this enum.
bool isComplete() const
Returns true if this can be considered a complete type.
TypeSourceInfo * getIntegerTypeSourceInfo() const
Return the type source info for the underlying integer type, if no type source info exists,...
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
unsigned getNumPositiveBits() const
Returns the width in bits required to store all the non-negative enumerators of this enum.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_NoSideEffects
Strictly evaluate the expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
std::optional< std::string > tryEvaluateString(ASTContext &Ctx) const
If the current Expr can be evaluated to a pointer to a null-terminated constant string,...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isFlexibleArrayMemberLike(ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
const FieldDecl * findCountedByField() const
Find the FieldDecl specified in a FAM's "counted_by" attribute.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to call this function.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isValidElementType(QualType T)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstant(const ASTContext &Ctx) const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
Scope - A scope is a transient data structure that is used while parsing the program.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
bool isSignedCharBool(QualType Ty)
void adornBoolConversionDiagWithTernaryFixit(Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
void CheckFloatComparison(SourceLocation Loc, Expr *LHS, Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
Scope * getCurScope() const
Retrieve the parser's current scope.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
bool BuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
bool BuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, bool IsVariadic, FormatStringInfo *FSI)
Given a FunctionDecl's FormatAttr, attempts to populate the FomatStringInfo parameter with the Format...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
DiagnosticsEngine & getDiagnostics() const
static FormatStringType GetFormatStringType(const FormatAttr *Format)
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall)
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
void pushCodeSynthesisContext(CodeSynthesisContext Ctx)
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
@ ACK_Comparison
A comparison.
bool BuiltinConstantArg(CallExpr *TheCall, int ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, bool CheckForFloatArgs=true)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
bool isConstantEvaluatedContext() const
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
SourceManager & SourceMgr
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
bool BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly=false)
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
bool BuiltinConstantArgRange(CallExpr *TheCall, int ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
unsigned getPresumedLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
unsigned getSpellingLineNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isWrittenInSameFile(SourceLocation Loc1, SourceLocation Loc2) const
Returns true if the spelling locations for both SourceLocations are part of the same file buffer.
unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
Exposes information about the current target.
virtual bool validatePointerAuthKey(const llvm::APSInt &value) const
Determine whether the given pointer-authentication key is valid.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
virtual bool supportsCpuInit() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool useFP16ConversionIntrinsics() const
Check whether llvm intrinsics such as llvm.convert.to.fp16 should be used to convert to and from __fp...
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const llvm::fltSemantics & getLongDoubleFormat() const
virtual bool checkArithmeticFenceSupported() const
Controls if __arithmetic_fence is supported in the targeted backend.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
virtual bool hasSjLjLowering() const
Controls if __builtin_longjmp / __builtin_setjmp can be lowered to llvm.eh.sjlj.longjmp / llvm....
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
const Type * getTypeForDecl() const
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isBlockPointerType() const
bool isBooleanType() const
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isFloat16Type() const
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e....
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isAnyComplexType() const
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
The iterator over UnresolvedSets.
A set of unresolved declarations.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
WhileStmt - This represents a 'while' stmt.
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
Defines the clang::TargetInfo interface.
__inline void unsigned int _2
const AstTypeMatcher< PointerType > pointerType
Matches pointer types, but does not match Objective-C object pointer types.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
ComparisonResult
Indicates the result of a tentative comparison.
uint32_t Literal
Literals are represented as positive integers.
@ After
Like System, but searched after the system directories.
@ FixIt
Parse and apply any fixits to the source.
bool GT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool InRange(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
The JSON file list parser is used to communicate input to InstallAPI.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Result
The result type of a method or function.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
ActionResult< ParsedType > TypeResult
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
const FunctionProtoType * T
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ Success
Template argument deduction was successful.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Other
Other implicit parameter.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
Describes how types, statements, expressions, and declarations should be printed.
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned Indentation
The number of spaces to use to indent each line.
A context in which code is being synthesized (where a source location alone is not sufficient to iden...
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.