82#include "llvm/ADT/APFloat.h"
83#include "llvm/ADT/APInt.h"
84#include "llvm/ADT/APSInt.h"
85#include "llvm/ADT/ArrayRef.h"
86#include "llvm/ADT/DenseMap.h"
87#include "llvm/ADT/FoldingSet.h"
88#include "llvm/ADT/STLExtras.h"
89#include "llvm/ADT/STLForwardCompat.h"
90#include "llvm/ADT/SmallBitVector.h"
91#include "llvm/ADT/SmallPtrSet.h"
92#include "llvm/ADT/SmallString.h"
93#include "llvm/ADT/SmallVector.h"
94#include "llvm/ADT/StringExtras.h"
95#include "llvm/ADT/StringRef.h"
96#include "llvm/ADT/StringSet.h"
97#include "llvm/ADT/StringSwitch.h"
98#include "llvm/Support/AtomicOrdering.h"
99#include "llvm/Support/Compiler.h"
100#include "llvm/Support/ConvertUTF.h"
101#include "llvm/Support/ErrorHandling.h"
102#include "llvm/Support/Format.h"
103#include "llvm/Support/Locale.h"
104#include "llvm/Support/MathExtras.h"
105#include "llvm/Support/SaveAndRestore.h"
106#include "llvm/Support/raw_ostream.h"
107#include "llvm/TargetParser/RISCVTargetParser.h"
108#include "llvm/TargetParser/Triple.h"
121using namespace clang;
125 unsigned ByteNo)
const {
136 unsigned ArgCount =
Call->getNumArgs();
137 if (ArgCount >= MinArgCount)
140 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_few_args)
141 << 0 << MinArgCount << ArgCount
142 << 0 <<
Call->getSourceRange();
146 unsigned ArgCount =
Call->getNumArgs();
147 if (ArgCount <= MaxArgCount)
149 return Diag(
Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most)
150 << 0 << MaxArgCount << ArgCount
151 << 0 <<
Call->getSourceRange();
155 unsigned MaxArgCount) {
161 unsigned ArgCount =
Call->getNumArgs();
162 if (ArgCount == DesiredArgCount)
167 assert(ArgCount > DesiredArgCount &&
"should have diagnosed this");
171 Call->getArg(ArgCount - 1)->getEndLoc());
173 return Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args)
174 << 0 << DesiredArgCount << ArgCount
179 bool HasError =
false;
181 for (
const Expr *Arg :
Call->arguments()) {
182 if (Arg->isValueDependent())
185 std::optional<std::string> ArgString = Arg->tryEvaluateString(S.
Context);
186 int DiagMsgKind = -1;
188 if (!ArgString.has_value())
190 else if (ArgString->find(
'$') != std::string::npos)
193 if (DiagMsgKind >= 0) {
194 S.
Diag(Arg->getBeginLoc(), diag::err_builtin_verbose_trap_arg)
195 << DiagMsgKind << Arg->getSourceRange();
204 if (
Value->isTypeDependent())
211 if (Result.isInvalid())
213 Value = Result.get();
235 if (!Literal || !Literal->isOrdinary()) {
248 S.
Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
256 auto *Literal = dyn_cast<StringLiteral>(Arg->IgnoreParenCasts());
257 if (!Literal || !Literal->isWide()) {
258 S.
Diag(Arg->getBeginLoc(), diag::err_msvc_annotation_wide_str)
259 << Arg->getSourceRange();
296 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(
327 bool IsBooleanAlignBuiltin = ID == Builtin::BI__builtin_is_aligned;
329 auto IsValidIntegerType = [](
QualType Ty) {
330 return Ty->isIntegerType() && !Ty->isEnumeralType() && !Ty->isBooleanType();
337 if ((!SrcTy->
isPointerType() && !IsValidIntegerType(SrcTy)) ||
339 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
342 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_type);
344 S.
Diag(Source->getExprLoc(), diag::note_alignment_invalid_member_pointer);
346 S.
Diag(Source->getExprLoc(),
347 diag::note_alignment_invalid_function_pointer);
352 if (!IsValidIntegerType(AlignOp->
getType())) {
363 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
364 llvm::APSInt MaxValue(
365 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
366 if (AlignValue < 1) {
367 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
370 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
375 if (!AlignValue.isPowerOf2()) {
376 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
379 if (AlignValue == 1) {
380 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
381 << IsBooleanAlignBuiltin;
409 std::pair<unsigned, const char *> Builtins[] = {
410 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
411 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
412 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
415 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
422 auto ValidCkdIntType = [](
QualType QT) {
425 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
426 return (BT->getKind() >= BuiltinType::Short &&
427 BT->getKind() <= BuiltinType::Int128) || (
428 BT->getKind() >= BuiltinType::UShort &&
429 BT->getKind() <= BuiltinType::UInt128) ||
430 BT->getKind() == BuiltinType::UChar ||
431 BT->getKind() == BuiltinType::SChar;
436 for (
unsigned I = 0; I < 2; ++I) {
442 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
461 !PtrTy->getPointeeType()->isIntegerType() ||
462 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
463 PtrTy->getPointeeType().isConstQualified()) {
465 diag::err_overflow_builtin_must_be_ptr_int)
473 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
474 for (
unsigned I = 0; I < 3; ++I) {
475 const auto Arg = TheCall->
getArg(I);
478 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
480 return S.
Diag(Arg->getBeginLoc(),
481 diag::err_overflow_builtin_bit_int_max_size)
490struct BuiltinDumpStructGenerator {
494 SmallVector<Expr *, 32> Actions;
495 DiagnosticErrorTrap ErrorTracker;
496 PrintingPolicy Policy;
498 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
499 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
500 Policy(S.Context.getPrintingPolicy()) {
502 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
505 Expr *makeOpaqueValueExpr(Expr *Inner) {
509 Actions.push_back(OVE);
513 Expr *getStringLiteral(llvm::StringRef Str) {
516 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
519 bool callPrintFunction(llvm::StringRef Format,
520 llvm::ArrayRef<Expr *> Exprs = {}) {
521 SmallVector<Expr *, 8> Args;
523 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
525 Args.push_back(getStringLiteral(Format));
526 llvm::append_range(Args, Exprs);
529 Sema::CodeSynthesisContext Ctx;
542 Actions.push_back(RealCall.
get());
548 Expr *getIndentString(
unsigned Depth) {
552 llvm::SmallString<32>
Indent;
554 return getStringLiteral(
Indent);
561 bool appendFormatSpecifier(QualType T, llvm::SmallVectorImpl<char> &Str) {
562 llvm::raw_svector_ostream
OS(Str);
566 if (
auto *BT = T->
getAs<BuiltinType>()) {
567 switch (BT->getKind()) {
568 case BuiltinType::Bool:
571 case BuiltinType::Char_U:
572 case BuiltinType::UChar:
575 case BuiltinType::Char_S:
576 case BuiltinType::SChar:
584 analyze_printf::PrintfSpecifier
Specifier;
587 if (
Specifier.getConversionSpecifier().getKind() ==
588 analyze_printf::PrintfConversionSpecifier::sArg) {
594 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
614 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
615 Expr *IndentLit = getIndentString(Depth);
617 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
618 : callPrintFunction(
"%s", {TypeLit}))
621 return dumpRecordValue(RD, E, IndentLit, Depth);
625 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
634 Expr *RecordArg = makeOpaqueValueExpr(E);
637 if (callPrintFunction(
" {\n"))
641 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
642 for (
const auto &Base : CXXRD->bases()) {
650 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
656 Expr *FieldIndentArg = getIndentString(Depth + 1);
659 for (
auto *D : RD->
decls()) {
660 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
661 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
662 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
665 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
666 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
668 getStringLiteral(FD->getName())};
670 if (FD->isBitField()) {
674 FD->getBitWidthValue());
682 CXXScopeSpec(), Loc, IFD,
685 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
687 DeclarationNameInfo(FD->getDeclName(), Loc));
688 if (
Field.isInvalid())
691 auto *InnerRD = FD->getType()->getAsRecordDecl();
692 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
693 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
695 if (callPrintFunction(Format, Args) ||
696 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
700 if (appendFormatSpecifier(FD->getType(), Format)) {
702 Args.push_back(
Field.get());
712 Args.push_back(FieldAddr.
get());
715 if (callPrintFunction(Format, Args))
720 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
721 : callPrintFunction(
"}\n");
724 Expr *buildWrapper() {
727 TheCall->
setType(Wrapper->getType());
748 diag::err_expected_struct_pointer_argument)
757 diag::err_incomplete_type))
766 switch (BT ? BT->getKind() : BuiltinType::Void) {
767 case BuiltinType::Dependent:
768 case BuiltinType::Overload:
769 case BuiltinType::BoundMember:
770 case BuiltinType::PseudoObject:
771 case BuiltinType::UnknownAny:
772 case BuiltinType::BuiltinFn:
778 diag::err_expected_callable_argument)
784 BuiltinDumpStructGenerator Generator(S, TheCall);
790 Expr *PtrArg = PtrArgResult.
get();
794 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
797 return Generator.buildWrapper();
809 if (
Call->getStmtClass() != Stmt::CallExprClass) {
810 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
811 <<
Call->getSourceRange();
816 if (CE->getCallee()->getType()->isBlockPointerType()) {
817 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
818 <<
Call->getSourceRange();
822 const Decl *TargetDecl = CE->getCalleeDecl();
823 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
824 if (FD->getBuiltinID()) {
825 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
826 <<
Call->getSourceRange();
831 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
832 <<
Call->getSourceRange();
840 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
854 BuiltinCall->
setType(CE->getType());
858 BuiltinCall->
setArg(1, ChainResult.
get());
865class ScanfDiagnosticFormatHandler
869 using ComputeSizeFunction =
870 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
874 using DiagnoseFunction =
875 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
877 ComputeSizeFunction ComputeSizeArgument;
878 DiagnoseFunction Diagnose;
881 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
882 DiagnoseFunction Diagnose)
883 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
885 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
886 const char *StartSpecifier,
887 unsigned specifierLen)
override {
891 unsigned NulByte = 0;
903 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
905 analyze_format_string::OptionalAmount::HowSpecified::Constant)
910 std::optional<llvm::APSInt> DestSizeAPS =
915 unsigned DestSize = DestSizeAPS->getZExtValue();
917 if (DestSize < SourceSize)
924class EstimateSizeFormatHandler
929 bool IsKernelCompatible =
true;
932 EstimateSizeFormatHandler(StringRef Format)
933 :
Size(std::
min(Format.find(0), Format.size()) +
936 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
937 const char *,
unsigned SpecifierLen,
938 const TargetInfo &)
override {
940 const size_t FieldWidth = computeFieldWidth(FS);
941 const size_t Precision = computePrecision(FS);
948 Size += std::max(FieldWidth, (
size_t)1);
960 Size += std::max(FieldWidth, Precision);
976 Size += std::max(FieldWidth, 1 +
977 (Precision ? 1 + Precision
987 (Precision ? 1 + Precision : 0) +
997 (Precision ? 1 + Precision : 0) +
1012 IsKernelCompatible =
false;
1013 Size += std::max(FieldWidth, 2 + Precision);
1060 Size += (Precision ? 0 : 1);
1067 assert(SpecifierLen <= Size &&
"no underflow");
1068 Size -= SpecifierLen;
1072 size_t getSizeLowerBound()
const {
return Size; }
1073 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1076 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1077 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1078 size_t FieldWidth = 0;
1084 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1085 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1086 size_t Precision = 0;
1133 StringRef &FormatStrRef,
size_t &StrLen,
1135 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1136 Format && (Format->isOrdinary() || Format->isUTF8())) {
1137 FormatStrRef = Format->getString();
1139 Context.getAsConstantArrayType(Format->getType());
1140 assert(T &&
"String literal not of constant array type!");
1141 size_t TypeSize = T->getZExtSize();
1143 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1149void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1155 bool UseDABAttr =
false;
1156 const FunctionDecl *UseDecl = FD;
1158 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1160 UseDecl = DABAttr->getFunction();
1161 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1173 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1180 unsigned DABIndices = DABAttr->argIndices_size();
1181 unsigned NewIndex = Index < DABIndices
1182 ? DABAttr->argIndices_begin()[Index]
1185 return std::nullopt;
1189 auto ComputeExplicitObjectSizeArgument =
1190 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1191 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1193 return std::nullopt;
1194 unsigned NewIndex = *IndexOptional;
1196 Expr *SizeArg = TheCall->
getArg(NewIndex);
1198 return std::nullopt;
1204 auto ComputeSizeArgument =
1205 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1211 if (Index < FD->getNumParams()) {
1212 if (
const auto *POS =
1214 BOSType = POS->getType();
1217 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1219 return std::nullopt;
1220 unsigned NewIndex = *IndexOptional;
1223 return std::nullopt;
1225 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1226 if (std::optional<uint64_t> ObjSize =
1229 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1231 return std::nullopt;
1234 auto ComputeStrLenArgument =
1235 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1236 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1238 return std::nullopt;
1239 unsigned NewIndex = *IndexOptional;
1241 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1243 if (std::optional<uint64_t>
Result =
1246 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1248 return std::nullopt;
1251 std::optional<llvm::APSInt> SourceSize;
1252 std::optional<llvm::APSInt> DestinationSize;
1253 unsigned DiagID = 0;
1254 bool IsChkVariant =
false;
1256 auto GetFunctionName = [&]() {
1257 std::string FunctionNameStr =
1259 llvm::StringRef FunctionName = FunctionNameStr;
1264 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1265 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1267 FunctionName.consume_front(
"__builtin_");
1269 return FunctionName.str();
1272 switch (BuiltinID) {
1275 case Builtin::BI__builtin_strcat:
1276 case Builtin::BIstrcat:
1277 case Builtin::BI__builtin_stpcpy:
1278 case Builtin::BIstpcpy:
1279 case Builtin::BI__builtin_strcpy:
1280 case Builtin::BIstrcpy: {
1281 DiagID = diag::warn_fortify_strlen_overflow;
1282 SourceSize = ComputeStrLenArgument(1);
1283 DestinationSize = ComputeSizeArgument(0);
1287 case Builtin::BI__builtin___strcat_chk:
1288 case Builtin::BI__builtin___stpcpy_chk:
1289 case Builtin::BI__builtin___strcpy_chk: {
1290 DiagID = diag::warn_fortify_strlen_overflow;
1291 SourceSize = ComputeStrLenArgument(1);
1292 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1293 IsChkVariant =
true;
1297 case Builtin::BIscanf:
1298 case Builtin::BIfscanf:
1299 case Builtin::BIsscanf: {
1300 unsigned FormatIndex = 1;
1301 unsigned DataIndex = 2;
1302 if (BuiltinID == Builtin::BIscanf) {
1307 const auto *FormatExpr =
1310 StringRef FormatStrRef;
1315 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1316 unsigned SourceSize) {
1317 DiagID = diag::warn_fortify_scanf_overflow;
1318 unsigned Index = ArgIndex + DataIndex;
1319 std::string FunctionName = GetFunctionName();
1321 PDiag(DiagID) << FunctionName << (Index + 1)
1322 << DestSize << SourceSize);
1325 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1326 return ComputeSizeArgument(Index + DataIndex);
1328 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1329 const char *FormatBytes = FormatStrRef.data();
1340 case Builtin::BIsprintf:
1341 case Builtin::BI__builtin___sprintf_chk: {
1342 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1345 StringRef FormatStrRef;
1348 EstimateSizeFormatHandler H(FormatStrRef);
1349 const char *FormatBytes = FormatStrRef.data();
1351 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1352 Context.getTargetInfo(),
false)) {
1353 DiagID = H.isKernelCompatible()
1354 ? diag::warn_format_overflow
1355 : diag::warn_format_overflow_non_kprintf;
1356 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1357 .extOrTrunc(SizeTypeWidth);
1358 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1359 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1360 IsChkVariant =
true;
1362 DestinationSize = ComputeSizeArgument(0);
1369 case Builtin::BI__builtin___memcpy_chk:
1370 case Builtin::BI__builtin___memmove_chk:
1371 case Builtin::BI__builtin___memset_chk:
1372 case Builtin::BI__builtin___strlcat_chk:
1373 case Builtin::BI__builtin___strlcpy_chk:
1374 case Builtin::BI__builtin___strncat_chk:
1375 case Builtin::BI__builtin___strncpy_chk:
1376 case Builtin::BI__builtin___stpncpy_chk:
1377 case Builtin::BI__builtin___memccpy_chk:
1378 case Builtin::BI__builtin___mempcpy_chk: {
1379 DiagID = diag::warn_builtin_chk_overflow;
1380 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1382 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1383 IsChkVariant =
true;
1387 case Builtin::BI__builtin___snprintf_chk:
1388 case Builtin::BI__builtin___vsnprintf_chk: {
1389 DiagID = diag::warn_builtin_chk_overflow;
1390 SourceSize = ComputeExplicitObjectSizeArgument(1);
1391 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1392 IsChkVariant =
true;
1396 case Builtin::BIstrncat:
1397 case Builtin::BI__builtin_strncat:
1398 case Builtin::BIstrncpy:
1399 case Builtin::BI__builtin_strncpy:
1400 case Builtin::BIstpncpy:
1401 case Builtin::BI__builtin_stpncpy: {
1407 DiagID = diag::warn_fortify_source_size_mismatch;
1408 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1409 DestinationSize = ComputeSizeArgument(0);
1413 case Builtin::BIbzero:
1414 case Builtin::BI__builtin_bzero:
1415 case Builtin::BImemcpy:
1416 case Builtin::BI__builtin_memcpy:
1417 case Builtin::BImemmove:
1418 case Builtin::BI__builtin_memmove:
1419 case Builtin::BImemset:
1420 case Builtin::BI__builtin_memset:
1421 case Builtin::BImempcpy:
1422 case Builtin::BI__builtin_mempcpy: {
1423 DiagID = diag::warn_fortify_source_overflow;
1424 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1425 DestinationSize = ComputeSizeArgument(0);
1428 case Builtin::BIbcopy:
1429 case Builtin::BI__builtin_bcopy: {
1430 DiagID = diag::warn_fortify_source_overflow;
1431 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1432 DestinationSize = ComputeSizeArgument(1);
1435 case Builtin::BIsnprintf:
1436 case Builtin::BI__builtin_snprintf:
1437 case Builtin::BIvsnprintf:
1438 case Builtin::BI__builtin_vsnprintf: {
1439 DiagID = diag::warn_fortify_source_size_mismatch;
1440 SourceSize = ComputeExplicitObjectSizeArgument(1);
1442 StringRef FormatStrRef;
1446 EstimateSizeFormatHandler H(FormatStrRef);
1447 const char *FormatBytes = FormatStrRef.data();
1449 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1450 Context.getTargetInfo(),
false)) {
1451 llvm::APSInt FormatSize =
1452 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1453 .extOrTrunc(SizeTypeWidth);
1454 if (FormatSize > *SourceSize && *SourceSize != 0) {
1455 unsigned TruncationDiagID =
1456 H.isKernelCompatible() ? diag::warn_format_truncation
1457 : diag::warn_format_truncation_non_kprintf;
1458 SmallString<16> SpecifiedSizeStr;
1459 SmallString<16> FormatSizeStr;
1460 SourceSize->toString(SpecifiedSizeStr, 10);
1461 FormatSize.toString(FormatSizeStr, 10);
1463 PDiag(TruncationDiagID)
1464 << GetFunctionName() << SpecifiedSizeStr
1469 DestinationSize = ComputeSizeArgument(0);
1473 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1477 if (!SourceSize || !DestinationSize ||
1478 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1481 std::string FunctionName = GetFunctionName();
1483 SmallString<16> DestinationStr;
1484 SmallString<16> SourceStr;
1485 DestinationSize->toString(DestinationStr, 10);
1486 SourceSize->toString(SourceStr, 10);
1489 << FunctionName << DestinationStr << SourceStr);
1504 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1507 << DRE->getDecl()->getIdentifier();
1519 "__builtin_alloca has invalid address space");
1532 if (Arg->isTypeDependent() || Arg->isValueDependent())
1535 QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
1537 return S.
Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
1545enum PointerAuthOpKind {
1560 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1591 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1594 llvm::raw_svector_ostream Str(
Value);
1603 Result = KeyValue->getZExtValue();
1622 bool IsAddrDiscArg =
false;
1627 IsAddrDiscArg =
true;
1636 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1637 <<
Result->getExtValue();
1639 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1645 IntVal =
Result->getZExtValue();
1649static std::pair<const ValueDecl *, CharUnits>
1656 const auto *BaseDecl =
1661 return {BaseDecl, Result.Val.getLValueOffset()};
1665 bool RequireConstant =
false) {
1673 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1674 return OpKind != PAO_BlendInteger;
1676 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1677 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1678 OpKind == PAO_SignGeneric;
1687 }
else if (AllowsInteger(OpKind) &&
1694 <<
unsigned(OpKind == PAO_Discriminator ? 1
1695 : OpKind == PAO_BlendPointer ? 2
1696 : OpKind == PAO_BlendInteger ? 3
1698 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1708 if (!RequireConstant) {
1710 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1713 ? diag::warn_ptrauth_sign_null_pointer
1714 : diag::warn_ptrauth_auth_null_pointer)
1724 if (OpKind == PAO_Sign) {
1742 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1747 assert(OpKind == PAO_Discriminator);
1753 if (
Call->getBuiltinCallee() ==
1754 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1769 assert(
Pointer->getType()->isPointerType());
1781 assert(
Integer->getType()->isIntegerType());
1787 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1800 Call->setType(
Call->getArgs()[0]->getType());
1831 PointerAuthOpKind OpKind,
1832 bool RequireConstant) {
1843 Call->setType(
Call->getArgs()[0]->getType());
1859 Call->setType(
Call->getArgs()[0]->getType());
1868 const Expr *AddendExpr =
Call->getArg(5);
1870 if (!AddendIsConstInt) {
1871 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
1885 Call->setType(
Call->getArgs()[0]->getType());
1894 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1897 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1898 if (!Literal || Literal->getCharByteWidth() != 1) {
1914 Call->setArg(0, FirstValue.
get());
1920 if (!FirstArgRecord) {
1921 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1922 << 0 << FirstArgType;
1927 diag::err_get_vtable_pointer_requires_complete_type)) {
1932 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1933 << 1 << FirstArgRecord;
1937 Call->setType(ReturnType);
1962 auto DiagSelect = [&]() -> std::optional<unsigned> {
1969 return std::optional<unsigned>{};
1984 diag::err_incomplete_type))
1988 "Unhandled non-object pointer case");
2016 if (PT->getPointeeType()->isFunctionType()) {
2018 diag::err_builtin_is_within_lifetime_invalid_arg)
2024 if (PT->getPointeeType()->isVariableArrayType()) {
2026 << 1 <<
"__builtin_is_within_lifetime";
2031 diag::err_builtin_is_within_lifetime_invalid_arg)
2045 diag::err_builtin_trivially_relocate_invalid_arg_type)
2052 diag::err_incomplete_type))
2056 T->isIncompleteArrayType()) {
2058 diag::err_builtin_trivially_relocate_invalid_arg_type)
2059 << (T.isConstQualified() ? 1 : 2);
2068 diag::err_builtin_trivially_relocate_invalid_arg_type)
2075 if (Size.isInvalid())
2079 if (Size.isInvalid())
2081 SizeExpr = Size.get();
2082 TheCall->
setArg(2, SizeExpr);
2092 llvm::Triple::ObjectFormatType CurObjFormat =
2094 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2107 llvm::Triple::ArchType CurArch =
2109 if (llvm::is_contained(SupportedArchs, CurArch))
2119bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2126 case llvm::Triple::arm:
2127 case llvm::Triple::armeb:
2128 case llvm::Triple::thumb:
2129 case llvm::Triple::thumbeb:
2131 case llvm::Triple::aarch64:
2132 case llvm::Triple::aarch64_32:
2133 case llvm::Triple::aarch64_be:
2135 case llvm::Triple::bpfeb:
2136 case llvm::Triple::bpfel:
2138 case llvm::Triple::dxil:
2140 case llvm::Triple::hexagon:
2142 case llvm::Triple::mips:
2143 case llvm::Triple::mipsel:
2144 case llvm::Triple::mips64:
2145 case llvm::Triple::mips64el:
2147 case llvm::Triple::spirv:
2148 case llvm::Triple::spirv32:
2149 case llvm::Triple::spirv64:
2150 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2153 case llvm::Triple::systemz:
2155 case llvm::Triple::x86:
2156 case llvm::Triple::x86_64:
2158 case llvm::Triple::ppc:
2159 case llvm::Triple::ppcle:
2160 case llvm::Triple::ppc64:
2161 case llvm::Triple::ppc64le:
2163 case llvm::Triple::amdgcn:
2165 case llvm::Triple::riscv32:
2166 case llvm::Triple::riscv64:
2167 case llvm::Triple::riscv32be:
2168 case llvm::Triple::riscv64be:
2170 case llvm::Triple::loongarch32:
2171 case llvm::Triple::loongarch64:
2174 case llvm::Triple::wasm32:
2175 case llvm::Triple::wasm64:
2177 case llvm::Triple::nvptx:
2178 case llvm::Triple::nvptx64:
2184 return T->isDependentType() ||
2185 (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType());
2200 switch (ArgTyRestr) {
2203 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2204 << ArgOrdinal << 2 << 1 << 1
2211 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2212 << ArgOrdinal << 5 << 0
2218 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2219 << ArgOrdinal << 5 << 1
2225 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2239 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2240 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2241 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2242 "Expecting __builtin_cpu_...");
2244 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2246 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2247 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2248 (!IsCPUSupports && TInfo->supportsCpuIs()));
2250 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2257 ? diag::err_builtin_aix_os_unsupported
2258 : diag::err_builtin_target_unsupported)
2264 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2302 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2303 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2304 BT->getNumBits() != 1) {
2306 << ArgTy << BT->getNumBits();
2382 diag::err_builtin_stdc_invalid_arg_type_bool_or_enum)
2385 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_invalid_arg_type)
2394 if (!llvm::isUIntN(ReturnTypeWidth, ArgWidth))
2395 return S.
Diag(Arg->
getBeginLoc(), diag::err_builtin_stdc_result_overflow)
2415 TheCall->
setArg(0, Arg0);
2432 TheCall->
setArg(1, Arg1);
2438 << 2 << 1 << 4 << 0 << Arg1Ty;
2452 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2454 << (OnlyUnsigned ? 3 : 1)
2462 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2465 return OnlyUnsigned ? T->isUnsignedIntegerType() : T->isIntegerType();
2470 return emitError(S, Loc, T);
2475 return emitError(S, Loc, T);
2481 return emitError(S, Loc, T);
2486 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2491 return emitError(S, Loc, T);
2496 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2502 llvm_unreachable(
"conversion functions are permitted");
2521 TheCall->
setArg(0, Arg0);
2535 TheCall->
setArg(1, Arg1);
2546 unsigned Pos,
bool AllowConst,
2550 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2555 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2556 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2557 << Pos <<
"scalar pointer";
2566 diag::err_typecheck_convert_incompatible)
2575 bool TypeDependent =
false;
2576 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2604 Builtin::BI__builtin_masked_load))
2618 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2641 Builtin::BI__builtin_masked_store))
2649 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2659 diag::err_vec_builtin_incompatible_vector)
2688 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2701 << MaskTy << IdxTy);
2710 diag::err_vec_masked_load_store_ptr)
2739 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2755 << MaskTy << IdxTy);
2761 << MaskTy << ValTy);
2767 diag::err_vec_builtin_incompatible_vector)
2781 if (Args.size() == 0) {
2783 diag::err_typecheck_call_too_few_args_at_least)
2789 QualType FuncT = Args[0]->getType();
2792 if (Args.size() < 2) {
2794 diag::err_typecheck_call_too_few_args_at_least)
2800 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2801 QualType ObjectT = Args[1]->getType();
2803 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2852 tok::periodstar, ObjectArg.
get(), Args[0]);
2856 if (MPT->isMemberDataPointer())
2859 auto *MemCall =
new (S.
Context)
2883 return TyA->getElementType();
2890Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2895 unsigned ICEArguments = 0;
2897 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2902 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2904 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2909 if (ArgNo < TheCall->getNumArgs() &&
2912 ICEArguments &= ~(1 << ArgNo);
2916 switch (BuiltinID) {
2917 case Builtin::BI__builtin_cpu_supports:
2918 case Builtin::BI__builtin_cpu_is:
2920 Context.getAuxTargetInfo(), BuiltinID))
2923 case Builtin::BI__builtin_cpu_init:
2924 if (!
Context.getTargetInfo().supportsCpuInit()) {
2930 case Builtin::BI__builtin___CFStringMakeConstantString:
2934 *
this, BuiltinID, TheCall,
2935 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2938 "Wrong # arguments to builtin CFStringMakeConstantString");
2939 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2942 case Builtin::BI__builtin_ms_va_start:
2943 case Builtin::BI__builtin_stdarg_start:
2944 case Builtin::BI__builtin_va_start:
2945 case Builtin::BI__builtin_c23_va_start:
2946 if (BuiltinVAStart(BuiltinID, TheCall))
2949 case Builtin::BI__va_start: {
2950 switch (
Context.getTargetInfo().getTriple().getArch()) {
2951 case llvm::Triple::aarch64:
2952 case llvm::Triple::arm:
2953 case llvm::Triple::thumb:
2954 if (BuiltinVAStartARMMicrosoft(TheCall))
2958 if (BuiltinVAStart(BuiltinID, TheCall))
2966 case Builtin::BI_interlockedbittestandset_acq:
2967 case Builtin::BI_interlockedbittestandset_rel:
2968 case Builtin::BI_interlockedbittestandset_nf:
2969 case Builtin::BI_interlockedbittestandreset_acq:
2970 case Builtin::BI_interlockedbittestandreset_rel:
2971 case Builtin::BI_interlockedbittestandreset_nf:
2974 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2979 case Builtin::BI_bittest64:
2980 case Builtin::BI_bittestandcomplement64:
2981 case Builtin::BI_bittestandreset64:
2982 case Builtin::BI_bittestandset64:
2983 case Builtin::BI_interlockedbittestandreset64:
2984 case Builtin::BI_interlockedbittestandset64:
2987 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2988 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2993 case Builtin::BI_interlockedbittestandreset64_acq:
2994 case Builtin::BI_interlockedbittestandreset64_rel:
2995 case Builtin::BI_interlockedbittestandreset64_nf:
2996 case Builtin::BI_interlockedbittestandset64_acq:
2997 case Builtin::BI_interlockedbittestandset64_rel:
2998 case Builtin::BI_interlockedbittestandset64_nf:
3003 case Builtin::BI__builtin_set_flt_rounds:
3006 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
3007 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
3008 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
3009 llvm::Triple::ppc64le}))
3013 case Builtin::BI__builtin_isgreater:
3014 case Builtin::BI__builtin_isgreaterequal:
3015 case Builtin::BI__builtin_isless:
3016 case Builtin::BI__builtin_islessequal:
3017 case Builtin::BI__builtin_islessgreater:
3018 case Builtin::BI__builtin_isunordered:
3019 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
3022 case Builtin::BI__builtin_fpclassify:
3023 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
3026 case Builtin::BI__builtin_isfpclass:
3027 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
3030 case Builtin::BI__builtin_isfinite:
3031 case Builtin::BI__builtin_isinf:
3032 case Builtin::BI__builtin_isinf_sign:
3033 case Builtin::BI__builtin_isnan:
3034 case Builtin::BI__builtin_issignaling:
3035 case Builtin::BI__builtin_isnormal:
3036 case Builtin::BI__builtin_issubnormal:
3037 case Builtin::BI__builtin_iszero:
3038 case Builtin::BI__builtin_signbit:
3039 case Builtin::BI__builtin_signbitf:
3040 case Builtin::BI__builtin_signbitl:
3041 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
3044 case Builtin::BI__builtin_shufflevector:
3048 case Builtin::BI__builtin_masked_load:
3049 case Builtin::BI__builtin_masked_expand_load:
3051 case Builtin::BI__builtin_masked_store:
3052 case Builtin::BI__builtin_masked_compress_store:
3054 case Builtin::BI__builtin_masked_gather:
3056 case Builtin::BI__builtin_masked_scatter:
3058 case Builtin::BI__builtin_invoke:
3060 case Builtin::BI__builtin_prefetch:
3061 if (BuiltinPrefetch(TheCall))
3064 case Builtin::BI__builtin_alloca_with_align:
3065 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3066 if (BuiltinAllocaWithAlign(TheCall))
3069 case Builtin::BI__builtin_alloca:
3070 case Builtin::BI__builtin_alloca_uninitialized:
3077 case Builtin::BI__builtin_infer_alloc_token:
3081 case Builtin::BI__arithmetic_fence:
3082 if (BuiltinArithmeticFence(TheCall))
3085 case Builtin::BI__assume:
3086 case Builtin::BI__builtin_assume:
3087 if (BuiltinAssume(TheCall))
3090 case Builtin::BI__builtin_assume_aligned:
3091 if (BuiltinAssumeAligned(TheCall))
3094 case Builtin::BI__builtin_dynamic_object_size:
3095 case Builtin::BI__builtin_object_size:
3099 case Builtin::BI__builtin_longjmp:
3100 if (BuiltinLongjmp(TheCall))
3103 case Builtin::BI__builtin_setjmp:
3104 if (BuiltinSetjmp(TheCall))
3107 case Builtin::BI__builtin_complex:
3108 if (BuiltinComplex(TheCall))
3111 case Builtin::BI__builtin_classify_type:
3112 case Builtin::BI__builtin_constant_p: {
3121 case Builtin::BI__builtin_launder:
3123 case Builtin::BI__builtin_is_within_lifetime:
3125 case Builtin::BI__builtin_trivially_relocate:
3128 case Builtin::BI__sync_fetch_and_add:
3129 case Builtin::BI__sync_fetch_and_add_1:
3130 case Builtin::BI__sync_fetch_and_add_2:
3131 case Builtin::BI__sync_fetch_and_add_4:
3132 case Builtin::BI__sync_fetch_and_add_8:
3133 case Builtin::BI__sync_fetch_and_add_16:
3134 case Builtin::BI__sync_fetch_and_sub:
3135 case Builtin::BI__sync_fetch_and_sub_1:
3136 case Builtin::BI__sync_fetch_and_sub_2:
3137 case Builtin::BI__sync_fetch_and_sub_4:
3138 case Builtin::BI__sync_fetch_and_sub_8:
3139 case Builtin::BI__sync_fetch_and_sub_16:
3140 case Builtin::BI__sync_fetch_and_or:
3141 case Builtin::BI__sync_fetch_and_or_1:
3142 case Builtin::BI__sync_fetch_and_or_2:
3143 case Builtin::BI__sync_fetch_and_or_4:
3144 case Builtin::BI__sync_fetch_and_or_8:
3145 case Builtin::BI__sync_fetch_and_or_16:
3146 case Builtin::BI__sync_fetch_and_and:
3147 case Builtin::BI__sync_fetch_and_and_1:
3148 case Builtin::BI__sync_fetch_and_and_2:
3149 case Builtin::BI__sync_fetch_and_and_4:
3150 case Builtin::BI__sync_fetch_and_and_8:
3151 case Builtin::BI__sync_fetch_and_and_16:
3152 case Builtin::BI__sync_fetch_and_xor:
3153 case Builtin::BI__sync_fetch_and_xor_1:
3154 case Builtin::BI__sync_fetch_and_xor_2:
3155 case Builtin::BI__sync_fetch_and_xor_4:
3156 case Builtin::BI__sync_fetch_and_xor_8:
3157 case Builtin::BI__sync_fetch_and_xor_16:
3158 case Builtin::BI__sync_fetch_and_nand:
3159 case Builtin::BI__sync_fetch_and_nand_1:
3160 case Builtin::BI__sync_fetch_and_nand_2:
3161 case Builtin::BI__sync_fetch_and_nand_4:
3162 case Builtin::BI__sync_fetch_and_nand_8:
3163 case Builtin::BI__sync_fetch_and_nand_16:
3164 case Builtin::BI__sync_add_and_fetch:
3165 case Builtin::BI__sync_add_and_fetch_1:
3166 case Builtin::BI__sync_add_and_fetch_2:
3167 case Builtin::BI__sync_add_and_fetch_4:
3168 case Builtin::BI__sync_add_and_fetch_8:
3169 case Builtin::BI__sync_add_and_fetch_16:
3170 case Builtin::BI__sync_sub_and_fetch:
3171 case Builtin::BI__sync_sub_and_fetch_1:
3172 case Builtin::BI__sync_sub_and_fetch_2:
3173 case Builtin::BI__sync_sub_and_fetch_4:
3174 case Builtin::BI__sync_sub_and_fetch_8:
3175 case Builtin::BI__sync_sub_and_fetch_16:
3176 case Builtin::BI__sync_and_and_fetch:
3177 case Builtin::BI__sync_and_and_fetch_1:
3178 case Builtin::BI__sync_and_and_fetch_2:
3179 case Builtin::BI__sync_and_and_fetch_4:
3180 case Builtin::BI__sync_and_and_fetch_8:
3181 case Builtin::BI__sync_and_and_fetch_16:
3182 case Builtin::BI__sync_or_and_fetch:
3183 case Builtin::BI__sync_or_and_fetch_1:
3184 case Builtin::BI__sync_or_and_fetch_2:
3185 case Builtin::BI__sync_or_and_fetch_4:
3186 case Builtin::BI__sync_or_and_fetch_8:
3187 case Builtin::BI__sync_or_and_fetch_16:
3188 case Builtin::BI__sync_xor_and_fetch:
3189 case Builtin::BI__sync_xor_and_fetch_1:
3190 case Builtin::BI__sync_xor_and_fetch_2:
3191 case Builtin::BI__sync_xor_and_fetch_4:
3192 case Builtin::BI__sync_xor_and_fetch_8:
3193 case Builtin::BI__sync_xor_and_fetch_16:
3194 case Builtin::BI__sync_nand_and_fetch:
3195 case Builtin::BI__sync_nand_and_fetch_1:
3196 case Builtin::BI__sync_nand_and_fetch_2:
3197 case Builtin::BI__sync_nand_and_fetch_4:
3198 case Builtin::BI__sync_nand_and_fetch_8:
3199 case Builtin::BI__sync_nand_and_fetch_16:
3200 case Builtin::BI__sync_val_compare_and_swap:
3201 case Builtin::BI__sync_val_compare_and_swap_1:
3202 case Builtin::BI__sync_val_compare_and_swap_2:
3203 case Builtin::BI__sync_val_compare_and_swap_4:
3204 case Builtin::BI__sync_val_compare_and_swap_8:
3205 case Builtin::BI__sync_val_compare_and_swap_16:
3206 case Builtin::BI__sync_bool_compare_and_swap:
3207 case Builtin::BI__sync_bool_compare_and_swap_1:
3208 case Builtin::BI__sync_bool_compare_and_swap_2:
3209 case Builtin::BI__sync_bool_compare_and_swap_4:
3210 case Builtin::BI__sync_bool_compare_and_swap_8:
3211 case Builtin::BI__sync_bool_compare_and_swap_16:
3212 case Builtin::BI__sync_lock_test_and_set:
3213 case Builtin::BI__sync_lock_test_and_set_1:
3214 case Builtin::BI__sync_lock_test_and_set_2:
3215 case Builtin::BI__sync_lock_test_and_set_4:
3216 case Builtin::BI__sync_lock_test_and_set_8:
3217 case Builtin::BI__sync_lock_test_and_set_16:
3218 case Builtin::BI__sync_lock_release:
3219 case Builtin::BI__sync_lock_release_1:
3220 case Builtin::BI__sync_lock_release_2:
3221 case Builtin::BI__sync_lock_release_4:
3222 case Builtin::BI__sync_lock_release_8:
3223 case Builtin::BI__sync_lock_release_16:
3224 case Builtin::BI__sync_swap:
3225 case Builtin::BI__sync_swap_1:
3226 case Builtin::BI__sync_swap_2:
3227 case Builtin::BI__sync_swap_4:
3228 case Builtin::BI__sync_swap_8:
3229 case Builtin::BI__sync_swap_16:
3230 return BuiltinAtomicOverloaded(TheCallResult);
3231 case Builtin::BI__sync_synchronize:
3235 case Builtin::BI__builtin_nontemporal_load:
3236 case Builtin::BI__builtin_nontemporal_store:
3237 return BuiltinNontemporalOverloaded(TheCallResult);
3238 case Builtin::BI__builtin_memcpy_inline: {
3239 clang::Expr *SizeOp = TheCall->
getArg(2);
3251 case Builtin::BI__builtin_memset_inline: {
3252 clang::Expr *SizeOp = TheCall->
getArg(2);
3262#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3263 case Builtin::BI##ID: \
3264 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3265#include "clang/Basic/Builtins.inc"
3266 case Builtin::BI__annotation:
3270 case Builtin::BI__builtin_annotation:
3274 case Builtin::BI__builtin_addressof:
3278 case Builtin::BI__builtin_function_start:
3282 case Builtin::BI__builtin_is_aligned:
3283 case Builtin::BI__builtin_align_up:
3284 case Builtin::BI__builtin_align_down:
3288 case Builtin::BI__builtin_add_overflow:
3289 case Builtin::BI__builtin_sub_overflow:
3290 case Builtin::BI__builtin_mul_overflow:
3294 case Builtin::BI__builtin_operator_new:
3295 case Builtin::BI__builtin_operator_delete: {
3296 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3298 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3301 case Builtin::BI__builtin_dump_struct:
3303 case Builtin::BI__builtin_expect_with_probability: {
3308 const Expr *ProbArg = TheCall->
getArg(2);
3309 SmallVector<PartialDiagnosticAt, 8> Notes;
3310 Expr::EvalResult Eval;
3314 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3321 bool LoseInfo =
false;
3322 Probability.convert(llvm::APFloat::IEEEdouble(),
3323 llvm::RoundingMode::Dynamic, &LoseInfo);
3324 if (!(Probability >= llvm::APFloat(0.0) &&
3325 Probability <= llvm::APFloat(1.0))) {
3332 case Builtin::BI__builtin_preserve_access_index:
3336 case Builtin::BI__builtin_call_with_static_chain:
3340 case Builtin::BI__exception_code:
3341 case Builtin::BI_exception_code:
3343 diag::err_seh___except_block))
3346 case Builtin::BI__exception_info:
3347 case Builtin::BI_exception_info:
3349 diag::err_seh___except_filter))
3352 case Builtin::BI__GetExceptionInfo:
3364 case Builtin::BIaddressof:
3365 case Builtin::BI__addressof:
3366 case Builtin::BIforward:
3367 case Builtin::BIforward_like:
3368 case Builtin::BImove:
3369 case Builtin::BImove_if_noexcept:
3370 case Builtin::BIas_const: {
3378 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3379 BuiltinID == Builtin::BI__addressof;
3381 (ReturnsPointer ?
Result->isAnyPointerType()
3382 :
Result->isReferenceType()) &&
3385 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3391 case Builtin::BI__builtin_ptrauth_strip:
3393 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3395 case Builtin::BI__builtin_ptrauth_sign_constant:
3398 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3401 case Builtin::BI__builtin_ptrauth_auth:
3404 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3406 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3408 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3410 case Builtin::BI__builtin_ptrauth_string_discriminator:
3413 case Builtin::BI__builtin_get_vtable_pointer:
3417 case Builtin::BIread_pipe:
3418 case Builtin::BIwrite_pipe:
3421 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3424 case Builtin::BIreserve_read_pipe:
3425 case Builtin::BIreserve_write_pipe:
3426 case Builtin::BIwork_group_reserve_read_pipe:
3427 case Builtin::BIwork_group_reserve_write_pipe:
3428 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3431 case Builtin::BIsub_group_reserve_read_pipe:
3432 case Builtin::BIsub_group_reserve_write_pipe:
3433 if (
OpenCL().checkSubgroupExt(TheCall) ||
3434 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3437 case Builtin::BIcommit_read_pipe:
3438 case Builtin::BIcommit_write_pipe:
3439 case Builtin::BIwork_group_commit_read_pipe:
3440 case Builtin::BIwork_group_commit_write_pipe:
3441 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3444 case Builtin::BIsub_group_commit_read_pipe:
3445 case Builtin::BIsub_group_commit_write_pipe:
3446 if (
OpenCL().checkSubgroupExt(TheCall) ||
3447 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3450 case Builtin::BIget_pipe_num_packets:
3451 case Builtin::BIget_pipe_max_packets:
3452 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3455 case Builtin::BIto_global:
3456 case Builtin::BIto_local:
3457 case Builtin::BIto_private:
3458 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3462 case Builtin::BIenqueue_kernel:
3463 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3466 case Builtin::BIget_kernel_work_group_size:
3467 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3468 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3471 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3472 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3473 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3476 case Builtin::BI__builtin_os_log_format:
3477 Cleanup.setExprNeedsCleanups(
true);
3479 case Builtin::BI__builtin_os_log_format_buffer_size:
3480 if (BuiltinOSLogFormat(TheCall))
3483 case Builtin::BI__builtin_frame_address:
3484 case Builtin::BI__builtin_return_address: {
3493 Result.Val.getInt() != 0)
3495 << ((BuiltinID == Builtin::BI__builtin_return_address)
3496 ?
"__builtin_return_address"
3497 :
"__builtin_frame_address")
3502 case Builtin::BI__builtin_nondeterministic_value: {
3503 if (BuiltinNonDeterministicValue(TheCall))
3510 case Builtin::BI__builtin_elementwise_abs:
3518 case Builtin::BI__builtin_elementwise_acos:
3519 case Builtin::BI__builtin_elementwise_asin:
3520 case Builtin::BI__builtin_elementwise_atan:
3521 case Builtin::BI__builtin_elementwise_ceil:
3522 case Builtin::BI__builtin_elementwise_cos:
3523 case Builtin::BI__builtin_elementwise_cosh:
3524 case Builtin::BI__builtin_elementwise_exp:
3525 case Builtin::BI__builtin_elementwise_exp2:
3526 case Builtin::BI__builtin_elementwise_exp10:
3527 case Builtin::BI__builtin_elementwise_floor:
3528 case Builtin::BI__builtin_elementwise_log:
3529 case Builtin::BI__builtin_elementwise_log2:
3530 case Builtin::BI__builtin_elementwise_log10:
3531 case Builtin::BI__builtin_elementwise_roundeven:
3532 case Builtin::BI__builtin_elementwise_round:
3533 case Builtin::BI__builtin_elementwise_rint:
3534 case Builtin::BI__builtin_elementwise_nearbyint:
3535 case Builtin::BI__builtin_elementwise_sin:
3536 case Builtin::BI__builtin_elementwise_sinh:
3537 case Builtin::BI__builtin_elementwise_sqrt:
3538 case Builtin::BI__builtin_elementwise_tan:
3539 case Builtin::BI__builtin_elementwise_tanh:
3540 case Builtin::BI__builtin_elementwise_trunc:
3541 case Builtin::BI__builtin_elementwise_canonicalize:
3546 case Builtin::BI__builtin_elementwise_fma:
3551 case Builtin::BI__builtin_elementwise_ldexp: {
3573 const auto *Vec0 = TyA->
getAs<VectorType>();
3574 const auto *Vec1 = TyExp->
getAs<VectorType>();
3575 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3577 if (Arg0Length != Arg1Length) {
3579 diag::err_typecheck_vector_lengths_not_equal)
3593 case Builtin::BI__builtin_elementwise_minnum:
3594 case Builtin::BI__builtin_elementwise_maxnum:
3595 case Builtin::BI__builtin_elementwise_minimum:
3596 case Builtin::BI__builtin_elementwise_maximum:
3597 case Builtin::BI__builtin_elementwise_minimumnum:
3598 case Builtin::BI__builtin_elementwise_maximumnum:
3599 case Builtin::BI__builtin_elementwise_atan2:
3600 case Builtin::BI__builtin_elementwise_fmod:
3601 case Builtin::BI__builtin_elementwise_pow:
3602 if (BuiltinElementwiseMath(TheCall,
3608 case Builtin::BI__builtin_elementwise_add_sat:
3609 case Builtin::BI__builtin_elementwise_sub_sat:
3610 if (BuiltinElementwiseMath(TheCall,
3614 case Builtin::BI__builtin_elementwise_fshl:
3615 case Builtin::BI__builtin_elementwise_fshr:
3620 case Builtin::BI__builtin_elementwise_min:
3621 case Builtin::BI__builtin_elementwise_max: {
3622 if (BuiltinElementwiseMath(TheCall))
3624 Expr *Arg0 = TheCall->
getArg(0);
3625 Expr *Arg1 = TheCall->
getArg(1);
3626 QualType Ty0 = Arg0->
getType();
3627 QualType Ty1 = Arg1->
getType();
3628 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3629 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3632 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3633 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3634 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3637 case Builtin::BI__builtin_elementwise_popcount:
3638 case Builtin::BI__builtin_elementwise_bitreverse:
3643 case Builtin::BI__builtin_elementwise_copysign: {
3652 QualType MagnitudeTy = Magnitude.
get()->
getType();
3665 diag::err_typecheck_call_different_arg_types)
3666 << MagnitudeTy << SignTy;
3674 case Builtin::BI__builtin_elementwise_clzg:
3675 case Builtin::BI__builtin_elementwise_ctzg:
3683 }
else if (BuiltinElementwiseMath(
3687 case Builtin::BI__builtin_reduce_max:
3688 case Builtin::BI__builtin_reduce_min: {
3689 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3692 const Expr *Arg = TheCall->
getArg(0);
3697 ElTy = TyA->getElementType();
3701 if (ElTy.isNull()) {
3711 case Builtin::BI__builtin_reduce_maximum:
3712 case Builtin::BI__builtin_reduce_minimum: {
3713 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3716 const Expr *Arg = TheCall->
getArg(0);
3721 ElTy = TyA->getElementType();
3725 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3738 case Builtin::BI__builtin_reduce_add:
3739 case Builtin::BI__builtin_reduce_mul:
3740 case Builtin::BI__builtin_reduce_xor:
3741 case Builtin::BI__builtin_reduce_or:
3742 case Builtin::BI__builtin_reduce_and: {
3743 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3746 const Expr *Arg = TheCall->
getArg(0);
3760 case Builtin::BI__builtin_reduce_assoc_fadd:
3761 case Builtin::BI__builtin_reduce_in_order_fadd: {
3763 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
3788 diag::err_builtin_invalid_arg_type)
3800 case Builtin::BI__builtin_matrix_transpose:
3801 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3803 case Builtin::BI__builtin_matrix_column_major_load:
3804 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3806 case Builtin::BI__builtin_matrix_column_major_store:
3807 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3809 case Builtin::BI__builtin_verbose_trap:
3814 case Builtin::BI__builtin_get_device_side_mangled_name: {
3815 auto Check = [](CallExpr *TheCall) {
3821 auto *D = DRE->getDecl();
3824 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3825 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3827 if (!Check(TheCall)) {
3829 diag::err_hip_invalid_args_builtin_mangled_name);
3834 case Builtin::BI__builtin_bswapg:
3838 case Builtin::BI__builtin_bitreverseg:
3842 case Builtin::BI__builtin_popcountg:
3846 case Builtin::BI__builtin_clzg:
3847 case Builtin::BI__builtin_ctzg:
3852 case Builtin::BI__builtin_stdc_rotate_left:
3853 case Builtin::BI__builtin_stdc_rotate_right:
3858 case Builtin::BI__builtin_stdc_bit_floor:
3859 case Builtin::BI__builtin_stdc_bit_ceil:
3860 case Builtin::BIstdc_bit_floor:
3861 case Builtin::BIstdc_bit_ceil:
3865 case Builtin::BI__builtin_stdc_has_single_bit:
3866 case Builtin::BIstdc_has_single_bit:
3870 case Builtin::BI__builtin_stdc_leading_zeros:
3871 case Builtin::BI__builtin_stdc_leading_ones:
3872 case Builtin::BI__builtin_stdc_trailing_zeros:
3873 case Builtin::BI__builtin_stdc_trailing_ones:
3874 case Builtin::BI__builtin_stdc_first_leading_zero:
3875 case Builtin::BI__builtin_stdc_first_leading_one:
3876 case Builtin::BI__builtin_stdc_first_trailing_zero:
3877 case Builtin::BI__builtin_stdc_first_trailing_one:
3878 case Builtin::BI__builtin_stdc_count_zeros:
3879 case Builtin::BI__builtin_stdc_count_ones:
3880 case Builtin::BI__builtin_stdc_bit_width:
3881 case Builtin::BIstdc_leading_zeros:
3882 case Builtin::BIstdc_leading_ones:
3883 case Builtin::BIstdc_trailing_zeros:
3884 case Builtin::BIstdc_trailing_ones:
3885 case Builtin::BIstdc_first_leading_zero:
3886 case Builtin::BIstdc_first_leading_one:
3887 case Builtin::BIstdc_first_trailing_zero:
3888 case Builtin::BIstdc_first_trailing_one:
3889 case Builtin::BIstdc_count_zeros:
3890 case Builtin::BIstdc_count_ones:
3891 case Builtin::BIstdc_bit_width:
3896 case Builtin::BI__builtin_allow_runtime_check: {
3897 Expr *Arg = TheCall->
getArg(0);
3907 case Builtin::BI__builtin_allow_sanitize_check: {
3911 Expr *Arg = TheCall->
getArg(0);
3913 const StringLiteral *SanitizerName =
3915 if (!SanitizerName) {
3921 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
3922 .Cases({
"address",
"thread",
"memory",
"hwaddress",
3923 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
3927 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
3933 case Builtin::BI__builtin_counted_by_ref:
3934 if (BuiltinCountedByRef(TheCall))
3944 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3945 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3946 assert(
Context.getAuxTargetInfo() &&
3947 "Aux Target Builtin, but not an aux target?");
3949 if (CheckTSBuiltinFunctionCall(
3951 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3954 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3960 return TheCallResult;
3975 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3979 diag::err_argument_not_contiguous_bit_field)
3986 bool IsVariadic =
false;
3989 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3990 IsVariadic = BD->isVariadic();
3991 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3992 IsVariadic = OMD->isVariadic();
3999 bool HasImplicitThisParam,
bool IsVariadic,
4003 else if (IsVariadic)
4013 if (HasImplicitThisParam) {
4045 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
4046 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
4047 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
4048 Expr = ILE->getInit(0);
4058 const Expr *ArgExpr,
4062 S.
PDiag(diag::warn_null_arg)
4068 if (
auto nullability =
type->getNullability())
4079 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
4085 llvm::SmallBitVector NonNullArgs;
4091 for (
const auto *Arg : Args)
4098 unsigned IdxAST = Idx.getASTIndex();
4099 if (IdxAST >= Args.size())
4101 if (NonNullArgs.empty())
4102 NonNullArgs.resize(Args.size());
4103 NonNullArgs.set(IdxAST);
4112 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4117 unsigned ParamIndex = 0;
4119 I != E; ++I, ++ParamIndex) {
4122 if (NonNullArgs.empty())
4123 NonNullArgs.resize(Args.size());
4125 NonNullArgs.set(ParamIndex);
4132 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4137 type = blockType->getPointeeType();
4151 if (NonNullArgs.empty())
4152 NonNullArgs.resize(Args.size());
4154 NonNullArgs.set(Index);
4163 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4164 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4165 if (NonNullArgs[ArgIndex])
4171 StringRef ParamName,
QualType ArgTy,
4194 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4195 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4199 if (ArgAlign < ParamAlign)
4200 Diag(Loc, diag::warn_param_mismatched_alignment)
4202 << ParamName << (FDecl !=
nullptr) << FDecl;
4206 const Expr *ThisArg,
4208 if (!FD || Args.empty())
4210 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4211 if (Idx == LifetimeCaptureByAttr::Global ||
4212 Idx == LifetimeCaptureByAttr::Unknown)
4214 if (IsMemberFunction && Idx == 0)
4216 return Args[Idx - IsMemberFunction];
4218 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4223 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4224 for (
int CapturingParamIdx :
Attr->params()) {
4227 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4230 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4238 I + IsMemberFunction);
4240 if (IsMemberFunction) {
4248 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4258 llvm::any_of(Args, [](
const Expr *E) {
4259 return E && E->isInstantiationDependent();
4264 llvm::SmallBitVector CheckedVarArgs;
4266 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4268 CheckedVarArgs.resize(Args.size());
4269 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4274 CheckedVarArgs.resize(Args.size());
4275 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4282 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4286 : isa_and_nonnull<FunctionDecl>(FDecl)
4288 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4292 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4294 if (
const Expr *Arg = Args[ArgIdx]) {
4295 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4302 if (FDecl || Proto) {
4307 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4308 CheckArgumentWithTypeTag(I, Args, Loc);
4314 if (!Proto && FDecl) {
4316 if (isa_and_nonnull<FunctionProtoType>(FT))
4322 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4324 bool IsScalableArg =
false;
4325 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4327 if (
const Expr *Arg = Args[ArgIdx]) {
4331 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4339 IsScalableArg =
true;
4341 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4350 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4351 llvm::StringMap<bool> CallerFeatureMap;
4352 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4353 if (!CallerFeatureMap.contains(
"sme"))
4354 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4355 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4356 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4365 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4367 (IsScalableArg || IsScalableRet)) {
4368 bool IsCalleeStreaming =
4370 bool IsCalleeStreamingCompatible =
4374 if (!IsCalleeStreamingCompatible &&
4378 unsigned VL = LO.VScaleMin * 128;
4379 unsigned SVL = LO.VScaleStreamingMin * 128;
4380 bool IsVLMismatch = VL && SVL && VL != SVL;
4382 auto EmitDiag = [&](
bool IsArg) {
4386 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4387 << IsArg << IsCalleeStreaming << SVL << VL;
4390 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4391 << IsArg << SVL << VL;
4393 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4410 bool CallerHasZAState =
false;
4411 bool CallerHasZT0State =
false;
4413 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4415 CallerHasZAState =
true;
4417 CallerHasZT0State =
true;
4421 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4423 CallerHasZT0State |=
4425 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4431 Diag(Loc, diag::err_sme_za_call_no_za_state);
4434 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4438 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4439 Diag(Loc, diag::note_sme_use_preserves_za);
4444 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4445 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4446 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4447 if (!Arg->isValueDependent()) {
4449 if (Arg->EvaluateAsInt(Align,
Context)) {
4450 const llvm::APSInt &I = Align.
Val.
getInt();
4451 if (!I.isPowerOf2())
4452 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4453 << Arg->getSourceRange();
4456 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4482 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4483 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4485 checkCall(FDecl, Proto,
nullptr, Args,
true,
4494 IsMemberOperatorCall;
4500 Expr *ImplicitThis =
nullptr;
4505 ImplicitThis = Args[0];
4508 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4519 ThisType =
Context.getPointerType(ThisType);
4525 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4543 CheckAbsoluteValueFunction(TheCall, FDecl);
4544 CheckMaxUnsignedZero(TheCall, FDecl);
4545 CheckInfNaNFunction(TheCall, FDecl);
4556 case Builtin::BIstrlcpy:
4557 case Builtin::BIstrlcat:
4558 CheckStrlcpycatArguments(TheCall, FnInfo);
4560 case Builtin::BIstrncat:
4561 CheckStrncatArguments(TheCall, FnInfo);
4563 case Builtin::BIfree:
4564 CheckFreeArguments(TheCall);
4567 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4576 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4577 Ty =
V->getType().getNonReferenceType();
4578 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4579 Ty = F->getType().getNonReferenceType();
4616 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4619 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4621 case AtomicExpr::AO__c11_atomic_init:
4622 case AtomicExpr::AO__opencl_atomic_init:
4623 llvm_unreachable(
"There is no ordering argument for an init");
4625 case AtomicExpr::AO__c11_atomic_load:
4626 case AtomicExpr::AO__opencl_atomic_load:
4627 case AtomicExpr::AO__hip_atomic_load:
4628 case AtomicExpr::AO__atomic_load_n:
4629 case AtomicExpr::AO__atomic_load:
4630 case AtomicExpr::AO__scoped_atomic_load_n:
4631 case AtomicExpr::AO__scoped_atomic_load:
4632 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4633 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4635 case AtomicExpr::AO__c11_atomic_store:
4636 case AtomicExpr::AO__opencl_atomic_store:
4637 case AtomicExpr::AO__hip_atomic_store:
4638 case AtomicExpr::AO__atomic_store:
4639 case AtomicExpr::AO__atomic_store_n:
4640 case AtomicExpr::AO__scoped_atomic_store:
4641 case AtomicExpr::AO__scoped_atomic_store_n:
4642 case AtomicExpr::AO__atomic_clear:
4643 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4644 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4645 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4675#define HIP_ATOMIC_FIXABLE(hip, scoped) \
4676 case AtomicExpr::AO__hip_atomic_##hip: \
4677 OldName = "__hip_atomic_" #hip; \
4678 NewName = "__scoped_atomic_" #scoped; \
4691#undef HIP_ATOMIC_FIXABLE
4692 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4693 OldName =
"__hip_atomic_compare_exchange_weak";
4694 NewName =
"__scoped_atomic_compare_exchange";
4697 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4698 OldName =
"__hip_atomic_compare_exchange_strong";
4699 NewName =
"__scoped_atomic_compare_exchange";
4703 llvm_unreachable(
"unhandled HIP atomic op");
4706 auto DB = S.
Diag(ExprRange.
getBegin(), diag::warn_hip_deprecated_builtin)
4707 << OldName << NewName;
4714 std::optional<llvm::APSInt> ScopeVal =
4719 StringRef ScopeName;
4720 switch (ScopeVal->getZExtValue()) {
4722 ScopeName =
"__MEMORY_SCOPE_SINGLE";
4725 ScopeName =
"__MEMORY_SCOPE_WVFRNT";
4728 ScopeName =
"__MEMORY_SCOPE_WRKGRP";
4731 ScopeName =
"__MEMORY_SCOPE_DEVICE";
4734 ScopeName =
"__MEMORY_SCOPE_SYSTEM";
4737 ScopeName =
"__MEMORY_SCOPE_CLUSTR";
4789 const unsigned NumForm = ClearByte + 1;
4790 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4791 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4799 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4800 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4801 "need to update code for modified forms");
4802 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4803 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4804 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4805 "need to update code for modified C11 atomics");
4806 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4807 Op <= AtomicExpr::AO__opencl_atomic_store;
4808 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4809 Op <= AtomicExpr::AO__hip_atomic_store;
4810 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4811 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4812 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4813 Op <= AtomicExpr::AO__c11_atomic_store) ||
4815 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4816 Op == AtomicExpr::AO__atomic_store_n ||
4817 Op == AtomicExpr::AO__atomic_exchange_n ||
4818 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4819 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4820 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4821 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4822 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4826 enum ArithOpExtraValueType {
4831 unsigned ArithAllows = AOEVT_None;
4834 case AtomicExpr::AO__c11_atomic_init:
4835 case AtomicExpr::AO__opencl_atomic_init:
4839 case AtomicExpr::AO__c11_atomic_load:
4840 case AtomicExpr::AO__opencl_atomic_load:
4841 case AtomicExpr::AO__hip_atomic_load:
4842 case AtomicExpr::AO__atomic_load_n:
4843 case AtomicExpr::AO__scoped_atomic_load_n:
4844 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4848 case AtomicExpr::AO__atomic_load:
4849 case AtomicExpr::AO__scoped_atomic_load:
4850 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4854 case AtomicExpr::AO__c11_atomic_store:
4855 case AtomicExpr::AO__opencl_atomic_store:
4856 case AtomicExpr::AO__hip_atomic_store:
4857 case AtomicExpr::AO__atomic_store:
4858 case AtomicExpr::AO__atomic_store_n:
4859 case AtomicExpr::AO__scoped_atomic_store:
4860 case AtomicExpr::AO__scoped_atomic_store_n:
4861 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4864 case AtomicExpr::AO__atomic_fetch_add:
4865 case AtomicExpr::AO__atomic_fetch_sub:
4866 case AtomicExpr::AO__atomic_add_fetch:
4867 case AtomicExpr::AO__atomic_sub_fetch:
4868 case AtomicExpr::AO__scoped_atomic_fetch_add:
4869 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4870 case AtomicExpr::AO__scoped_atomic_add_fetch:
4871 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4872 case AtomicExpr::AO__c11_atomic_fetch_add:
4873 case AtomicExpr::AO__c11_atomic_fetch_sub:
4874 case AtomicExpr::AO__opencl_atomic_fetch_add:
4875 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4876 case AtomicExpr::AO__hip_atomic_fetch_add:
4877 case AtomicExpr::AO__hip_atomic_fetch_sub:
4878 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4881 case AtomicExpr::AO__atomic_fetch_max:
4882 case AtomicExpr::AO__atomic_fetch_min:
4883 case AtomicExpr::AO__atomic_max_fetch:
4884 case AtomicExpr::AO__atomic_min_fetch:
4885 case AtomicExpr::AO__scoped_atomic_fetch_max:
4886 case AtomicExpr::AO__scoped_atomic_fetch_min:
4887 case AtomicExpr::AO__scoped_atomic_max_fetch:
4888 case AtomicExpr::AO__scoped_atomic_min_fetch:
4889 case AtomicExpr::AO__c11_atomic_fetch_max:
4890 case AtomicExpr::AO__c11_atomic_fetch_min:
4891 case AtomicExpr::AO__opencl_atomic_fetch_max:
4892 case AtomicExpr::AO__opencl_atomic_fetch_min:
4893 case AtomicExpr::AO__hip_atomic_fetch_max:
4894 case AtomicExpr::AO__hip_atomic_fetch_min:
4895 ArithAllows = AOEVT_FP;
4898 case AtomicExpr::AO__c11_atomic_fetch_and:
4899 case AtomicExpr::AO__c11_atomic_fetch_or:
4900 case AtomicExpr::AO__c11_atomic_fetch_xor:
4901 case AtomicExpr::AO__hip_atomic_fetch_and:
4902 case AtomicExpr::AO__hip_atomic_fetch_or:
4903 case AtomicExpr::AO__hip_atomic_fetch_xor:
4904 case AtomicExpr::AO__c11_atomic_fetch_nand:
4905 case AtomicExpr::AO__opencl_atomic_fetch_and:
4906 case AtomicExpr::AO__opencl_atomic_fetch_or:
4907 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4908 case AtomicExpr::AO__atomic_fetch_and:
4909 case AtomicExpr::AO__atomic_fetch_or:
4910 case AtomicExpr::AO__atomic_fetch_xor:
4911 case AtomicExpr::AO__atomic_fetch_nand:
4912 case AtomicExpr::AO__atomic_and_fetch:
4913 case AtomicExpr::AO__atomic_or_fetch:
4914 case AtomicExpr::AO__atomic_xor_fetch:
4915 case AtomicExpr::AO__atomic_nand_fetch:
4916 case AtomicExpr::AO__atomic_fetch_uinc:
4917 case AtomicExpr::AO__atomic_fetch_udec:
4918 case AtomicExpr::AO__scoped_atomic_fetch_and:
4919 case AtomicExpr::AO__scoped_atomic_fetch_or:
4920 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4921 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4922 case AtomicExpr::AO__scoped_atomic_and_fetch:
4923 case AtomicExpr::AO__scoped_atomic_or_fetch:
4924 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4925 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4926 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
4927 case AtomicExpr::AO__scoped_atomic_fetch_udec:
4931 case AtomicExpr::AO__c11_atomic_exchange:
4932 case AtomicExpr::AO__hip_atomic_exchange:
4933 case AtomicExpr::AO__opencl_atomic_exchange:
4934 case AtomicExpr::AO__atomic_exchange_n:
4935 case AtomicExpr::AO__scoped_atomic_exchange_n:
4936 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4940 case AtomicExpr::AO__atomic_exchange:
4941 case AtomicExpr::AO__scoped_atomic_exchange:
4942 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4946 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4947 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4948 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4949 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4950 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4951 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4955 case AtomicExpr::AO__atomic_compare_exchange:
4956 case AtomicExpr::AO__atomic_compare_exchange_n:
4957 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4958 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4959 ArithAllows = AOEVT_Pointer;
4963 case AtomicExpr::AO__atomic_test_and_set:
4964 Form = TestAndSetByte;
4967 case AtomicExpr::AO__atomic_clear:
4972 unsigned AdjustedNumArgs = NumArgs[Form];
4973 if ((IsOpenCL || IsHIP || IsScoped) &&
4974 Op != AtomicExpr::AO__opencl_atomic_init)
4977 if (Args.size() < AdjustedNumArgs) {
4978 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4979 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4982 }
else if (Args.size() > AdjustedNumArgs) {
4983 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4984 diag::err_typecheck_call_too_many_args)
4985 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4991 Expr *Ptr = Args[0];
4996 Ptr = ConvertedPtr.
get();
4999 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5009 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
5015 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
5021 }
else if (Form != Load && Form != LoadCopy) {
5023 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
5029 if (Form != TestAndSetByte && Form != ClearByte) {
5032 diag::err_incomplete_type))
5035 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
5036 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
5046 pointerType->getPointeeType().getCVRQualifiers());
5056 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5066 auto IsAllowedValueType = [&](
QualType ValType,
5067 unsigned AllowedType) ->
bool {
5068 bool IsX87LongDouble =
5070 &
Context.getTargetInfo().getLongDoubleFormat() ==
5071 &llvm::APFloat::x87DoubleExtended();
5075 return AllowedType & AOEVT_Pointer;
5079 if (IsX87LongDouble)
5083 if (!IsAllowedValueType(ValType, ArithAllows)) {
5084 auto DID = ArithAllows & AOEVT_FP
5085 ? (ArithAllows & AOEVT_Pointer
5086 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
5087 : diag::err_atomic_op_needs_atomic_int_or_fp)
5088 : (ArithAllows & AOEVT_Pointer
5089 ? diag::err_atomic_op_needs_atomic_int_or_ptr
5090 : diag::err_atomic_op_needs_atomic_int);
5097 diag::err_incomplete_type)) {
5108 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
5124 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
5136 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
5139 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
5145 bool IsPassedByAddress =
false;
5146 if (!IsC11 && !IsHIP && !IsN) {
5148 IsPassedByAddress =
true;
5153 APIOrderedArgs.push_back(Args[0]);
5157 APIOrderedArgs.push_back(Args[1]);
5163 APIOrderedArgs.push_back(Args[2]);
5164 APIOrderedArgs.push_back(Args[1]);
5167 APIOrderedArgs.push_back(Args[2]);
5168 APIOrderedArgs.push_back(Args[3]);
5169 APIOrderedArgs.push_back(Args[1]);
5172 APIOrderedArgs.push_back(Args[2]);
5173 APIOrderedArgs.push_back(Args[4]);
5174 APIOrderedArgs.push_back(Args[1]);
5175 APIOrderedArgs.push_back(Args[3]);
5178 APIOrderedArgs.push_back(Args[2]);
5179 APIOrderedArgs.push_back(Args[4]);
5180 APIOrderedArgs.push_back(Args[5]);
5181 APIOrderedArgs.push_back(Args[1]);
5182 APIOrderedArgs.push_back(Args[3]);
5184 case TestAndSetByte:
5186 APIOrderedArgs.push_back(Args[1]);
5190 APIOrderedArgs.append(Args.begin(), Args.end());
5197 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5199 if (i < NumVals[Form] + 1) {
5212 assert(Form != Load);
5214 Ty =
Context.getPointerDiffType();
5217 else if (Form ==
Copy || Form == Xchg) {
5218 if (IsPassedByAddress) {
5225 Expr *ValArg = APIOrderedArgs[i];
5232 AS = PtrTy->getPointeeType().getAddressSpace();
5241 if (IsPassedByAddress)
5261 APIOrderedArgs[i] = Arg.
get();
5266 SubExprs.push_back(Ptr);
5270 SubExprs.push_back(APIOrderedArgs[1]);
5273 case TestAndSetByte:
5275 SubExprs.push_back(APIOrderedArgs[1]);
5281 SubExprs.push_back(APIOrderedArgs[2]);
5282 SubExprs.push_back(APIOrderedArgs[1]);
5286 SubExprs.push_back(APIOrderedArgs[3]);
5287 SubExprs.push_back(APIOrderedArgs[1]);
5288 SubExprs.push_back(APIOrderedArgs[2]);
5291 SubExprs.push_back(APIOrderedArgs[3]);
5292 SubExprs.push_back(APIOrderedArgs[1]);
5293 SubExprs.push_back(APIOrderedArgs[4]);
5294 SubExprs.push_back(APIOrderedArgs[2]);
5297 SubExprs.push_back(APIOrderedArgs[4]);
5298 SubExprs.push_back(APIOrderedArgs[1]);
5299 SubExprs.push_back(APIOrderedArgs[5]);
5300 SubExprs.push_back(APIOrderedArgs[2]);
5301 SubExprs.push_back(APIOrderedArgs[3]);
5306 if (SubExprs.size() >= 2 && Form !=
Init) {
5307 std::optional<llvm::APSInt>
Success =
5308 SubExprs[1]->getIntegerConstantExpr(
Context);
5310 Diag(SubExprs[1]->getBeginLoc(),
5311 diag::warn_atomic_op_has_invalid_memory_order)
5312 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5313 << SubExprs[1]->getSourceRange();
5315 if (SubExprs.size() >= 5) {
5316 if (std::optional<llvm::APSInt> Failure =
5317 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5318 if (!llvm::is_contained(
5319 {llvm::AtomicOrderingCABI::relaxed,
5320 llvm::AtomicOrderingCABI::consume,
5321 llvm::AtomicOrderingCABI::acquire,
5322 llvm::AtomicOrderingCABI::seq_cst},
5323 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
5324 Diag(SubExprs[3]->getBeginLoc(),
5325 diag::warn_atomic_op_has_invalid_memory_order)
5326 << 2 << SubExprs[3]->getSourceRange();
5333 auto *
Scope = Args[Args.size() - 1];
5334 if (std::optional<llvm::APSInt>
Result =
5336 if (!ScopeModel->isValid(
Result->getZExtValue()))
5337 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5338 <<
Scope->getSourceRange();
5340 SubExprs.push_back(
Scope);
5349 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5350 Op == AtomicExpr::AO__c11_atomic_store ||
5351 Op == AtomicExpr::AO__opencl_atomic_load ||
5352 Op == AtomicExpr::AO__hip_atomic_load ||
5353 Op == AtomicExpr::AO__opencl_atomic_store ||
5354 Op == AtomicExpr::AO__hip_atomic_store) &&
5355 Context.AtomicUsesUnsupportedLibcall(AE))
5357 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5358 Op == AtomicExpr::AO__opencl_atomic_load ||
5359 Op == AtomicExpr::AO__hip_atomic_load)
5364 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5380 assert(Fn &&
"builtin call without direct callee!");
5396 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5403 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5405 <<
Callee->getSourceRange();
5414 Expr *FirstArg = TheCall->
getArg(0);
5418 FirstArg = FirstArgResult.
get();
5419 TheCall->
setArg(0, FirstArg);
5431 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5438 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5468 QualType ResultType = ValType;
5473#define BUILTIN_ROW(x) \
5474 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5475 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5477 static const unsigned BuiltinIndices[][5] = {
5502 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5503 case 1: SizeIndex = 0;
break;
5504 case 2: SizeIndex = 1;
break;
5505 case 4: SizeIndex = 2;
break;
5506 case 8: SizeIndex = 3;
break;
5507 case 16: SizeIndex = 4;
break;
5519 unsigned BuiltinIndex, NumFixed = 1;
5520 bool WarnAboutSemanticsChange =
false;
5521 switch (BuiltinID) {
5522 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5523 case Builtin::BI__sync_fetch_and_add:
5524 case Builtin::BI__sync_fetch_and_add_1:
5525 case Builtin::BI__sync_fetch_and_add_2:
5526 case Builtin::BI__sync_fetch_and_add_4:
5527 case Builtin::BI__sync_fetch_and_add_8:
5528 case Builtin::BI__sync_fetch_and_add_16:
5532 case Builtin::BI__sync_fetch_and_sub:
5533 case Builtin::BI__sync_fetch_and_sub_1:
5534 case Builtin::BI__sync_fetch_and_sub_2:
5535 case Builtin::BI__sync_fetch_and_sub_4:
5536 case Builtin::BI__sync_fetch_and_sub_8:
5537 case Builtin::BI__sync_fetch_and_sub_16:
5541 case Builtin::BI__sync_fetch_and_or:
5542 case Builtin::BI__sync_fetch_and_or_1:
5543 case Builtin::BI__sync_fetch_and_or_2:
5544 case Builtin::BI__sync_fetch_and_or_4:
5545 case Builtin::BI__sync_fetch_and_or_8:
5546 case Builtin::BI__sync_fetch_and_or_16:
5550 case Builtin::BI__sync_fetch_and_and:
5551 case Builtin::BI__sync_fetch_and_and_1:
5552 case Builtin::BI__sync_fetch_and_and_2:
5553 case Builtin::BI__sync_fetch_and_and_4:
5554 case Builtin::BI__sync_fetch_and_and_8:
5555 case Builtin::BI__sync_fetch_and_and_16:
5559 case Builtin::BI__sync_fetch_and_xor:
5560 case Builtin::BI__sync_fetch_and_xor_1:
5561 case Builtin::BI__sync_fetch_and_xor_2:
5562 case Builtin::BI__sync_fetch_and_xor_4:
5563 case Builtin::BI__sync_fetch_and_xor_8:
5564 case Builtin::BI__sync_fetch_and_xor_16:
5568 case Builtin::BI__sync_fetch_and_nand:
5569 case Builtin::BI__sync_fetch_and_nand_1:
5570 case Builtin::BI__sync_fetch_and_nand_2:
5571 case Builtin::BI__sync_fetch_and_nand_4:
5572 case Builtin::BI__sync_fetch_and_nand_8:
5573 case Builtin::BI__sync_fetch_and_nand_16:
5575 WarnAboutSemanticsChange =
true;
5578 case Builtin::BI__sync_add_and_fetch:
5579 case Builtin::BI__sync_add_and_fetch_1:
5580 case Builtin::BI__sync_add_and_fetch_2:
5581 case Builtin::BI__sync_add_and_fetch_4:
5582 case Builtin::BI__sync_add_and_fetch_8:
5583 case Builtin::BI__sync_add_and_fetch_16:
5587 case Builtin::BI__sync_sub_and_fetch:
5588 case Builtin::BI__sync_sub_and_fetch_1:
5589 case Builtin::BI__sync_sub_and_fetch_2:
5590 case Builtin::BI__sync_sub_and_fetch_4:
5591 case Builtin::BI__sync_sub_and_fetch_8:
5592 case Builtin::BI__sync_sub_and_fetch_16:
5596 case Builtin::BI__sync_and_and_fetch:
5597 case Builtin::BI__sync_and_and_fetch_1:
5598 case Builtin::BI__sync_and_and_fetch_2:
5599 case Builtin::BI__sync_and_and_fetch_4:
5600 case Builtin::BI__sync_and_and_fetch_8:
5601 case Builtin::BI__sync_and_and_fetch_16:
5605 case Builtin::BI__sync_or_and_fetch:
5606 case Builtin::BI__sync_or_and_fetch_1:
5607 case Builtin::BI__sync_or_and_fetch_2:
5608 case Builtin::BI__sync_or_and_fetch_4:
5609 case Builtin::BI__sync_or_and_fetch_8:
5610 case Builtin::BI__sync_or_and_fetch_16:
5614 case Builtin::BI__sync_xor_and_fetch:
5615 case Builtin::BI__sync_xor_and_fetch_1:
5616 case Builtin::BI__sync_xor_and_fetch_2:
5617 case Builtin::BI__sync_xor_and_fetch_4:
5618 case Builtin::BI__sync_xor_and_fetch_8:
5619 case Builtin::BI__sync_xor_and_fetch_16:
5623 case Builtin::BI__sync_nand_and_fetch:
5624 case Builtin::BI__sync_nand_and_fetch_1:
5625 case Builtin::BI__sync_nand_and_fetch_2:
5626 case Builtin::BI__sync_nand_and_fetch_4:
5627 case Builtin::BI__sync_nand_and_fetch_8:
5628 case Builtin::BI__sync_nand_and_fetch_16:
5630 WarnAboutSemanticsChange =
true;
5633 case Builtin::BI__sync_val_compare_and_swap:
5634 case Builtin::BI__sync_val_compare_and_swap_1:
5635 case Builtin::BI__sync_val_compare_and_swap_2:
5636 case Builtin::BI__sync_val_compare_and_swap_4:
5637 case Builtin::BI__sync_val_compare_and_swap_8:
5638 case Builtin::BI__sync_val_compare_and_swap_16:
5643 case Builtin::BI__sync_bool_compare_and_swap:
5644 case Builtin::BI__sync_bool_compare_and_swap_1:
5645 case Builtin::BI__sync_bool_compare_and_swap_2:
5646 case Builtin::BI__sync_bool_compare_and_swap_4:
5647 case Builtin::BI__sync_bool_compare_and_swap_8:
5648 case Builtin::BI__sync_bool_compare_and_swap_16:
5654 case Builtin::BI__sync_lock_test_and_set:
5655 case Builtin::BI__sync_lock_test_and_set_1:
5656 case Builtin::BI__sync_lock_test_and_set_2:
5657 case Builtin::BI__sync_lock_test_and_set_4:
5658 case Builtin::BI__sync_lock_test_and_set_8:
5659 case Builtin::BI__sync_lock_test_and_set_16:
5663 case Builtin::BI__sync_lock_release:
5664 case Builtin::BI__sync_lock_release_1:
5665 case Builtin::BI__sync_lock_release_2:
5666 case Builtin::BI__sync_lock_release_4:
5667 case Builtin::BI__sync_lock_release_8:
5668 case Builtin::BI__sync_lock_release_16:
5674 case Builtin::BI__sync_swap:
5675 case Builtin::BI__sync_swap_1:
5676 case Builtin::BI__sync_swap_2:
5677 case Builtin::BI__sync_swap_4:
5678 case Builtin::BI__sync_swap_8:
5679 case Builtin::BI__sync_swap_16:
5687 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5688 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5689 <<
Callee->getSourceRange();
5693 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5694 <<
Callee->getSourceRange();
5696 if (WarnAboutSemanticsChange) {
5697 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5698 <<
Callee->getSourceRange();
5703 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5704 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5705 FunctionDecl *NewBuiltinDecl;
5706 if (NewBuiltinID == BuiltinID)
5707 NewBuiltinDecl = FDecl;
5710 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5713 assert(Res.getFoundDecl());
5714 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5715 if (!NewBuiltinDecl)
5722 for (
unsigned i = 0; i != NumFixed; ++i) {
5751 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5753 CK_BuiltinFnToFnPtr);
5764 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5765 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5766 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5770 return TheCallResult;
5774 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5779 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5780 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5781 "Unexpected nontemporal load/store builtin!");
5782 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5783 unsigned numArgs = isStore ? 2 : 1;
5793 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5799 PointerArg = PointerArgResult.
get();
5800 TheCall->
setArg(numArgs - 1, PointerArg);
5804 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5817 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5824 return TheCallResult;
5836 return TheCallResult;
5843 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5845 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5846 Literal = ObjcLiteral->getString();
5850 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5857 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5858 InitializedEntity Entity =
5868 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5869 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5870 TT.getArch() == llvm::Triple::aarch64_32);
5871 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5872 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5873 if (IsX64 || IsAArch64) {
5880 return S.
Diag(Fn->getBeginLoc(),
5881 diag::err_ms_va_start_used_in_sysv_function);
5888 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5889 return S.
Diag(Fn->getBeginLoc(),
5890 diag::err_va_start_used_in_wrong_abi_function)
5891 << !IsWindowsOrUEFI;
5897 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5905 bool IsVariadic =
false;
5908 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5909 IsVariadic =
Block->isVariadic();
5910 Params =
Block->parameters();
5911 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5914 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5915 IsVariadic = MD->isVariadic();
5917 Params = MD->parameters();
5920 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5924 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5929 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5934 *LastParam = Params.empty() ?
nullptr : Params.back();
5939bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5944 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5968 ParmVarDecl *LastParam;
5979 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5981 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5986 if (std::optional<llvm::APSInt> Val =
5988 Val &&
LangOpts.C23 && *Val == 0 &&
5989 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5990 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5997 SourceLocation ParamLoc;
5998 bool IsCRegister =
false;
5999 bool SecondArgIsLastNonVariadicArgument =
false;
6000 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
6001 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
6002 SecondArgIsLastNonVariadicArgument = PV == LastParam;
6005 ParamLoc = PV->getLocation();
6011 if (!SecondArgIsLastNonVariadicArgument)
6013 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
6014 else if (IsCRegister ||
Type->isReferenceType() ||
6015 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
6018 if (!Context.isPromotableIntegerType(Type))
6020 const auto *ED = Type->getAsEnumDecl();
6023 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
6025 unsigned Reason = 0;
6026 if (
Type->isReferenceType()) Reason = 1;
6027 else if (IsCRegister) Reason = 2;
6028 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
6029 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
6036 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
6056 if (
Call->getNumArgs() < 3)
6058 diag::err_typecheck_call_too_few_args_at_least)
6059 << 0 << 3 <<
Call->getNumArgs()
6075 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
6078 const QualType &ConstCharPtrTy =
6080 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
6082 << Arg1->
getType() << ConstCharPtrTy << 1
6085 << 2 << Arg1->
getType() << ConstCharPtrTy;
6087 const QualType SizeTy =
Context.getSizeType();
6092 << Arg2->
getType() << SizeTy << 1
6095 << 3 << Arg2->
getType() << SizeTy;
6100bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
6104 if (BuiltinID == Builtin::BI__builtin_isunordered &&
6132 diag::err_typecheck_call_invalid_ordered_compare)
6140bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
6141 unsigned BuiltinID) {
6146 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
6147 BuiltinID == Builtin::BI__builtin_isinf ||
6148 BuiltinID == Builtin::BI__builtin_isinf_sign))
6152 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
6153 BuiltinID == Builtin::BI__builtin_isunordered))
6157 bool IsFPClass = NumArgs == 2;
6160 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
6164 for (
unsigned i = 0; i < FPArgNo; ++i) {
6165 Expr *Arg = TheCall->
getArg(i);
6178 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6186 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
6191 OrigArg = Res.
get();
6197 OrigArg = Res.
get();
6199 TheCall->
setArg(FPArgNo, OrigArg);
6201 QualType VectorResultTy;
6202 QualType ElementTy = OrigArg->
getType();
6207 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6213 diag::err_typecheck_call_invalid_unary_fp)
6225 if (!VectorResultTy.
isNull())
6226 ResultTy = VectorResultTy;
6235bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6240 for (
unsigned I = 0; I != 2; ++I) {
6241 Expr *Arg = TheCall->
getArg(I);
6251 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6266 Expr *Real = TheCall->
getArg(0);
6267 Expr *Imag = TheCall->
getArg(1);
6270 diag::err_typecheck_call_different_arg_types)
6285 diag::err_typecheck_call_too_few_args_at_least)
6286 << 0 << 2 << NumArgs
6293 unsigned NumElements = 0;
6308 unsigned NumResElements = NumArgs - 2;
6317 diag::err_vec_builtin_incompatible_vector)
6322 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6324 diag::err_vec_builtin_incompatible_vector)
6329 }
else if (NumElements != NumResElements) {
6332 ?
Context.getExtVectorType(EltType, NumResElements)
6333 :
Context.getVectorType(EltType, NumResElements,
6338 for (
unsigned I = 2; I != NumArgs; ++I) {
6346 diag::err_shufflevector_nonconstant_argument)
6352 else if (
Result->getActiveBits() > 64 ||
6353 Result->getZExtValue() >= NumElements * 2)
6355 diag::err_shufflevector_argument_too_large)
6380 diag::err_convertvector_non_vector)
6383 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6385 <<
"__builtin_convertvector");
6390 if (SrcElts != DstElts)
6392 diag::err_convertvector_incompatible_vector)
6400bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6405 diag::err_typecheck_call_too_many_args_at_most)
6406 << 0 << 3 << NumArgs << 0
6411 for (
unsigned i = 1; i != NumArgs; ++i)
6418bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6419 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6420 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6430 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6440bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6441 Expr *Arg = TheCall->
getArg(0);
6452bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6454 Expr *Arg = TheCall->
getArg(1);
6458 if (
const auto *UE =
6460 if (UE->getKind() == UETT_AlignOf ||
6461 UE->getKind() == UETT_PreferredAlignOf)
6467 if (!
Result.isPowerOf2())
6468 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6475 if (
Result > std::numeric_limits<int32_t>::max())
6483bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6488 Expr *FirstArg = TheCall->
getArg(0);
6494 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6498 TheCall->
setArg(0, FirstArgResult.
get());
6502 Expr *SecondArg = TheCall->
getArg(1);
6510 if (!
Result.isPowerOf2())
6511 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6523 Expr *ThirdArg = TheCall->
getArg(2);
6526 TheCall->
setArg(2, ThirdArg);
6532bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6533 unsigned BuiltinID =
6535 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6538 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6539 if (NumArgs < NumRequiredArgs) {
6540 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6541 << 0 << NumRequiredArgs << NumArgs
6544 if (NumArgs >= NumRequiredArgs + 0x100) {
6546 diag::err_typecheck_call_too_many_args_at_most)
6547 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6558 if (Arg.isInvalid())
6560 TheCall->
setArg(i, Arg.get());
6565 unsigned FormatIdx = i;
6575 unsigned FirstDataArg = i;
6576 while (i < NumArgs) {
6594 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6596 bool Success = CheckFormatArguments(
6599 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6623 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6632 int High,
bool RangeIsError) {
6646 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6654 PDiag(diag::warn_argument_invalid_range)
6697 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6702 if (
Value.isNegative())
6713 if ((
Value & 0xFF) != 0)
6738 Result.setIsUnsigned(
true);
6743 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6763 Result.setIsUnsigned(
true);
6771 diag::err_argument_not_shifted_byte_or_xxff)
6775bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6776 if (!Context.getTargetInfo().hasSjLjLowering())
6777 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6788 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6794bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6795 if (!Context.getTargetInfo().hasSjLjLowering())
6796 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6801bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6816 diag::err_builtin_counted_by_ref_invalid_arg)
6821 diag::err_builtin_counted_by_ref_has_side_effects)
6824 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6826 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6831 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6838 QualType MemberTy = ME->getMemberDecl()->getType();
6841 diag::err_builtin_counted_by_ref_invalid_arg)
6845 diag::err_builtin_counted_by_ref_invalid_arg)
6855bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6857 const CallExpr *CE =
6866 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6871 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6876 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6880 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6884 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6894class UncoveredArgHandler {
6895 enum {
Unknown = -1, AllCovered = -2 };
6897 signed FirstUncoveredArg =
Unknown;
6898 SmallVector<const Expr *, 4> DiagnosticExprs;
6901 UncoveredArgHandler() =
default;
6903 bool hasUncoveredArg()
const {
6904 return (FirstUncoveredArg >= 0);
6907 unsigned getUncoveredArg()
const {
6908 assert(hasUncoveredArg() &&
"no uncovered argument");
6909 return FirstUncoveredArg;
6912 void setAllCovered() {
6915 DiagnosticExprs.clear();
6916 FirstUncoveredArg = AllCovered;
6919 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6920 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6923 if (FirstUncoveredArg == AllCovered)
6928 if (NewFirstUncoveredArg == FirstUncoveredArg)
6929 DiagnosticExprs.push_back(StrExpr);
6930 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6931 DiagnosticExprs.clear();
6932 DiagnosticExprs.push_back(StrExpr);
6933 FirstUncoveredArg = NewFirstUncoveredArg;
6937 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6940enum StringLiteralCheckType {
6942 SLCT_UncheckedLiteral,
6950 bool AddendIsRight) {
6951 unsigned BitWidth = Offset.getBitWidth();
6952 unsigned AddendBitWidth = Addend.getBitWidth();
6954 if (Addend.isUnsigned()) {
6955 Addend = Addend.zext(++AddendBitWidth);
6956 Addend.setIsSigned(
true);
6959 if (AddendBitWidth > BitWidth) {
6960 Offset = Offset.sext(AddendBitWidth);
6961 BitWidth = AddendBitWidth;
6962 }
else if (BitWidth > AddendBitWidth) {
6963 Addend = Addend.sext(BitWidth);
6967 llvm::APSInt ResOffset = Offset;
6968 if (BinOpKind == BO_Add)
6969 ResOffset = Offset.sadd_ov(Addend, Ov);
6971 assert(AddendIsRight && BinOpKind == BO_Sub &&
6972 "operator must be add or sub with addend on the right");
6973 ResOffset = Offset.ssub_ov(Addend, Ov);
6979 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6980 "index (intermediate) result too big");
6981 Offset = Offset.sext(2 * BitWidth);
6982 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6986 Offset = std::move(ResOffset);
6994class FormatStringLiteral {
6995 const StringLiteral *FExpr;
6999 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
7000 : FExpr(fexpr), Offset(Offset) {}
7002 const StringLiteral *getFormatString()
const {
return FExpr; }
7004 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
7006 unsigned getByteLength()
const {
7007 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
7010 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
7017 bool isAscii()
const {
return FExpr->
isOrdinary(); }
7018 bool isWide()
const {
return FExpr->
isWide(); }
7019 bool isUTF8()
const {
return FExpr->
isUTF8(); }
7020 bool isUTF16()
const {
return FExpr->
isUTF16(); }
7021 bool isUTF32()
const {
return FExpr->
isUTF32(); }
7022 bool isPascal()
const {
return FExpr->
isPascal(); }
7024 SourceLocation getLocationOfByte(
7025 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
7026 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
7027 unsigned *StartTokenByteOffset =
nullptr)
const {
7029 StartToken, StartTokenByteOffset);
7032 SourceLocation getBeginLoc() const LLVM_READONLY {
7036 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
7042 Sema &S,
const FormatStringLiteral *FExpr,
7047 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
7048 bool IgnoreStringsWithoutSpecifiers);
7057static StringLiteralCheckType
7063 llvm::SmallBitVector &CheckedVarArgs,
7064 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
7065 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
7066 bool IgnoreStringsWithoutSpecifiers =
false) {
7068 return SLCT_NotALiteral;
7070 assert(Offset.isSigned() &&
"invalid offset");
7073 return SLCT_NotALiteral;
7082 return SLCT_UncheckedLiteral;
7085 case Stmt::InitListExprClass:
7089 format_idx, firstDataArg,
Type, CallType,
7090 false, CheckedVarArgs,
7091 UncoveredArg, Offset, CallerFormatParamIdx,
7092 IgnoreStringsWithoutSpecifiers);
7094 return SLCT_NotALiteral;
7095 case Stmt::BinaryConditionalOperatorClass:
7096 case Stmt::ConditionalOperatorClass: {
7105 bool CheckLeft =
true, CheckRight =
true;
7108 if (
C->getCond()->EvaluateAsBooleanCondition(
7120 StringLiteralCheckType Left;
7122 Left = SLCT_UncheckedLiteral;
7125 Args, APK, format_idx, firstDataArg,
Type,
7126 CallType, InFunctionCall, CheckedVarArgs,
7127 UncoveredArg, Offset, CallerFormatParamIdx,
7128 IgnoreStringsWithoutSpecifiers);
7129 if (Left == SLCT_NotALiteral || !CheckRight) {
7135 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
7136 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7137 UncoveredArg, Offset, CallerFormatParamIdx,
7138 IgnoreStringsWithoutSpecifiers);
7140 return (CheckLeft && Left < Right) ? Left : Right;
7143 case Stmt::ImplicitCastExprClass:
7147 case Stmt::OpaqueValueExprClass:
7152 return SLCT_NotALiteral;
7154 case Stmt::PredefinedExprClass:
7158 return SLCT_UncheckedLiteral;
7160 case Stmt::DeclRefExprClass: {
7166 bool isConstant =
false;
7170 isConstant = AT->getElementType().isConstant(S.
Context);
7172 isConstant = T.isConstant(S.
Context) &&
7173 PT->getPointeeType().isConstant(S.
Context);
7174 }
else if (T->isObjCObjectPointerType()) {
7177 isConstant = T.isConstant(S.
Context);
7181 if (
const Expr *
Init = VD->getAnyInitializer()) {
7184 if (InitList->isStringLiteralInit())
7185 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7188 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7189 firstDataArg,
Type, CallType,
false,
7190 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7241 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7242 if (CallerFormatParamIdx)
7243 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7244 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7245 for (
const auto *PVFormatMatches :
7246 D->specific_attrs<FormatMatchesAttr>()) {
7251 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7255 S.
Diag(Args[format_idx]->getBeginLoc(),
7256 diag::warn_format_string_type_incompatible)
7257 << PVFormatMatches->getType()->getName()
7259 if (!InFunctionCall) {
7260 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7261 diag::note_format_string_defined);
7263 return SLCT_UncheckedLiteral;
7266 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7267 Args, APK, format_idx, firstDataArg,
Type, CallType,
7268 false, CheckedVarArgs, UncoveredArg,
7269 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7273 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7276 PVFormat->getFirstArg(), &CallerFSI))
7278 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7282 S.
Diag(Args[format_idx]->getBeginLoc(),
7283 diag::warn_format_string_type_incompatible)
7284 << PVFormat->getType()->getName()
7286 if (!InFunctionCall) {
7289 return SLCT_UncheckedLiteral;
7302 return SLCT_UncheckedLiteral;
7310 return SLCT_NotALiteral;
7313 case Stmt::CallExprClass:
7314 case Stmt::CXXMemberCallExprClass: {
7318 StringLiteralCheckType CommonResult;
7319 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7320 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7322 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7323 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7324 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7326 CommonResult = Result;
7331 return CommonResult;
7333 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7335 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7336 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7339 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7340 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7341 UncoveredArg, Offset, CallerFormatParamIdx,
7342 IgnoreStringsWithoutSpecifiers);
7348 format_idx, firstDataArg,
Type, CallType,
7349 false, CheckedVarArgs,
7350 UncoveredArg, Offset, CallerFormatParamIdx,
7351 IgnoreStringsWithoutSpecifiers);
7352 return SLCT_NotALiteral;
7354 case Stmt::ObjCMessageExprClass: {
7356 if (
const auto *MD = ME->getMethodDecl()) {
7357 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7366 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7368 MD->getSelector().isKeywordSelector(
7369 {
"localizedStringForKey",
"value",
"table"})) {
7370 IgnoreStringsWithoutSpecifiers =
true;
7373 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7375 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7376 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7377 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7381 return SLCT_NotALiteral;
7383 case Stmt::ObjCStringLiteralClass:
7384 case Stmt::StringLiteralClass: {
7393 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7396 return SLCT_NotALiteral;
7398 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7400 format_idx, firstDataArg,
Type, InFunctionCall,
7401 CallType, CheckedVarArgs, UncoveredArg,
7402 IgnoreStringsWithoutSpecifiers);
7403 return SLCT_CheckedLiteral;
7406 return SLCT_NotALiteral;
7408 case Stmt::BinaryOperatorClass: {
7422 if (LIsInt != RIsInt) {
7426 if (BinOpKind == BO_Add) {
7439 return SLCT_NotALiteral;
7441 case Stmt::UnaryOperatorClass: {
7443 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7444 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7446 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7456 return SLCT_NotALiteral;
7460 return SLCT_NotALiteral;
7471 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7472 if (isa_and_nonnull<StringLiteral>(LVE))
7493 return "freebsd_kprintf";
7502 return llvm::StringSwitch<FormatStringType>(Flavor)
7504 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7509 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7525bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7529 llvm::SmallBitVector &CheckedVarArgs) {
7530 FormatStringInfo FSI;
7534 return CheckFormatArguments(
7535 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7540bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7544 llvm::SmallBitVector &CheckedVarArgs) {
7545 FormatStringInfo FSI;
7549 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7550 Format->getFormatString(), FSI.FormatIdx,
7552 CallType, Loc, Range, CheckedVarArgs);
7560 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7573 unsigned CallerArgumentIndexOffset =
7576 unsigned FirstArgumentIndex = -1;
7586 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7587 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7591 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7592 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7594 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7597 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7598 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7601 FirstArgumentIndex =
7602 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7608 ? (NumCallerParams + CallerArgumentIndexOffset)
7613 if (!ReferenceFormatString)
7619 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7621 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7623 std::string
Attr, Fixit;
7624 llvm::raw_string_ostream AttrOS(
Attr);
7626 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7627 << FirstArgumentIndex <<
")";
7629 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7631 AttrOS.write_escaped(ReferenceFormatString->
getString());
7635 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7646 llvm::raw_string_ostream IS(Fixit);
7654 if (LO.C23 || LO.CPlusPlus11)
7655 IS <<
"[[gnu::" <<
Attr <<
"]]";
7656 else if (LO.ObjC || LO.GNUMode)
7657 IS <<
"__attribute__((" <<
Attr <<
"))";
7671 Caller->
addAttr(FormatAttr::CreateImplicit(
7673 FormatStringIndex, FirstArgumentIndex));
7675 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7677 FormatStringIndex, ReferenceFormatString));
7681 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7693 unsigned format_idx,
unsigned firstDataArg,
7697 llvm::SmallBitVector &CheckedVarArgs) {
7699 if (format_idx >= Args.size()) {
7700 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7704 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7718 UncoveredArgHandler UncoveredArg;
7719 std::optional<unsigned> CallerParamIdx;
7721 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7722 firstDataArg,
Type, CallType,
7723 true, CheckedVarArgs, UncoveredArg,
7724 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7727 if (UncoveredArg.hasUncoveredArg()) {
7728 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7729 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7730 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7733 if (CT != SLCT_NotALiteral)
7735 return CT == SLCT_CheckedLiteral;
7741 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7747 this, Args, APK, ReferenceFormatString, format_idx,
7748 firstDataArg,
Type, *CallerParamIdx, Loc))
7758 if (Args.size() == firstDataArg) {
7759 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7767 Diag(FormatLoc, diag::note_format_security_fixit)
7771 Diag(FormatLoc, diag::note_format_security_fixit)
7776 Diag(FormatLoc, diag::warn_format_nonliteral)
7787 const FormatStringLiteral *FExpr;
7788 const Expr *OrigFormatExpr;
7790 const unsigned FirstDataArg;
7791 const unsigned NumDataArgs;
7794 ArrayRef<const Expr *> Args;
7796 llvm::SmallBitVector CoveredArgs;
7797 bool usesPositionalArgs =
false;
7798 bool atFirstArg =
true;
7799 bool inFunctionCall;
7801 llvm::SmallBitVector &CheckedVarArgs;
7802 UncoveredArgHandler &UncoveredArg;
7805 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7807 unsigned firstDataArg,
unsigned numDataArgs,
7809 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7811 llvm::SmallBitVector &CheckedVarArgs,
7812 UncoveredArgHandler &UncoveredArg)
7813 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7814 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7815 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7816 inFunctionCall(inFunctionCall), CallType(callType),
7817 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7818 CoveredArgs.resize(numDataArgs);
7819 CoveredArgs.reset();
7822 bool HasFormatArguments()
const {
7827 void DoneProcessing();
7829 void HandleIncompleteSpecifier(
const char *startSpecifier,
7830 unsigned specifierLen)
override;
7832 void HandleInvalidLengthModifier(
7833 const analyze_format_string::FormatSpecifier &FS,
7834 const analyze_format_string::ConversionSpecifier &CS,
7835 const char *startSpecifier,
unsigned specifierLen,
7838 void HandleNonStandardLengthModifier(
7839 const analyze_format_string::FormatSpecifier &FS,
7840 const char *startSpecifier,
unsigned specifierLen);
7842 void HandleNonStandardConversionSpecifier(
7843 const analyze_format_string::ConversionSpecifier &CS,
7844 const char *startSpecifier,
unsigned specifierLen);
7846 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7848 void HandleInvalidPosition(
const char *startSpecifier,
7849 unsigned specifierLen,
7852 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7854 void HandleNullChar(
const char *nullCharacter)
override;
7856 template <
typename Range>
7858 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7859 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7860 bool IsStringLocation, Range StringRange,
7861 ArrayRef<FixItHint> Fixit = {});
7864 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7865 const char *startSpec,
7866 unsigned specifierLen,
7867 const char *csStart,
unsigned csLen);
7869 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7870 const char *startSpec,
7871 unsigned specifierLen);
7873 SourceRange getFormatStringRange();
7874 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7875 unsigned specifierLen);
7876 SourceLocation getLocationOfByte(
const char *x);
7878 const Expr *getDataArg(
unsigned i)
const;
7880 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7881 const analyze_format_string::ConversionSpecifier &CS,
7882 const char *startSpecifier,
unsigned specifierLen,
7885 template <
typename Range>
7886 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7887 bool IsStringLocation, Range StringRange,
7888 ArrayRef<FixItHint> Fixit = {});
7893SourceRange CheckFormatHandler::getFormatStringRange() {
7898getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7900 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7908SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7913void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7914 unsigned specifierLen){
7915 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7916 getLocationOfByte(startSpecifier),
7918 getSpecifierRange(startSpecifier, specifierLen));
7921void CheckFormatHandler::HandleInvalidLengthModifier(
7924 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7936 getSpecifierRange(startSpecifier, specifierLen));
7938 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7939 << FixedLM->toString()
7944 if (DiagID == diag::warn_format_nonsensical_length)
7950 getSpecifierRange(startSpecifier, specifierLen),
7955void CheckFormatHandler::HandleNonStandardLengthModifier(
7957 const char *startSpecifier,
unsigned specifierLen) {
7966 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7970 getSpecifierRange(startSpecifier, specifierLen));
7972 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7973 << FixedLM->toString()
7977 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7981 getSpecifierRange(startSpecifier, specifierLen));
7985void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7987 const char *startSpecifier,
unsigned specifierLen) {
7993 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7997 getSpecifierRange(startSpecifier, specifierLen));
8000 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
8001 << FixedCS->toString()
8004 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
8008 getSpecifierRange(startSpecifier, specifierLen));
8012void CheckFormatHandler::HandlePosition(
const char *startPos,
8015 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
8016 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
8017 getLocationOfByte(startPos),
8019 getSpecifierRange(startPos, posLen));
8022void CheckFormatHandler::HandleInvalidPosition(
8023 const char *startSpecifier,
unsigned specifierLen,
8026 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
8027 EmitFormatDiagnostic(
8028 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
8029 getLocationOfByte(startSpecifier),
true,
8030 getSpecifierRange(startSpecifier, specifierLen));
8033void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
8037 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
8038 getLocationOfByte(startPos),
8040 getSpecifierRange(startPos, posLen));
8043void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
8046 EmitFormatDiagnostic(
8047 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
8048 getLocationOfByte(nullCharacter),
true,
8049 getFormatStringRange());
8055const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
8056 return Args[FirstDataArg + i];
8059void CheckFormatHandler::DoneProcessing() {
8062 if (HasFormatArguments()) {
8065 signed notCoveredArg = CoveredArgs.find_first();
8066 if (notCoveredArg >= 0) {
8067 assert((
unsigned)notCoveredArg < NumDataArgs);
8068 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
8070 UncoveredArg.setAllCovered();
8075void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
8076 const Expr *ArgExpr) {
8077 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
8089 for (
auto E : DiagnosticExprs)
8092 CheckFormatHandler::EmitFormatDiagnostic(
8093 S, IsFunctionCall, DiagnosticExprs[0],
8099CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
8101 const char *startSpec,
8102 unsigned specifierLen,
8103 const char *csStart,
8105 bool keepGoing =
true;
8106 if (argIndex < NumDataArgs) {
8109 CoveredArgs.set(argIndex);
8125 std::string CodePointStr;
8126 if (!llvm::sys::locale::isPrint(*csStart)) {
8127 llvm::UTF32 CodePoint;
8128 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
8129 const llvm::UTF8 *E =
8130 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
8131 llvm::ConversionResult
Result =
8132 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
8134 if (
Result != llvm::conversionOK) {
8135 unsigned char FirstChar = *csStart;
8136 CodePoint = (llvm::UTF32)FirstChar;
8139 llvm::raw_string_ostream
OS(CodePointStr);
8140 if (CodePoint < 256)
8141 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
8142 else if (CodePoint <= 0xFFFF)
8143 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
8145 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
8149 EmitFormatDiagnostic(
8150 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
8151 true, getSpecifierRange(startSpec, specifierLen));
8157CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
8158 const char *startSpec,
8159 unsigned specifierLen) {
8160 EmitFormatDiagnostic(
8161 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
8162 Loc,
true, getSpecifierRange(startSpec, specifierLen));
8166CheckFormatHandler::CheckNumArgs(
8169 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
8171 if (HasFormatArguments() && argIndex >= NumDataArgs) {
8173 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
8174 << (argIndex+1) << NumDataArgs)
8175 : S.
PDiag(diag::warn_printf_insufficient_data_args);
8176 EmitFormatDiagnostic(
8177 PDiag, getLocationOfByte(CS.
getStart()),
true,
8178 getSpecifierRange(startSpecifier, specifierLen));
8182 UncoveredArg.setAllCovered();
8188template<
typename Range>
8191 bool IsStringLocation,
8194 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
8195 Loc, IsStringLocation, StringRange, FixIt);
8225template <
typename Range>
8226void CheckFormatHandler::EmitFormatDiagnostic(
8227 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8230 if (InFunctionCall) {
8235 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8239 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8240 diag::note_format_string_defined);
8242 Note << StringRange;
8251class CheckPrintfHandler :
public CheckFormatHandler {
8253 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8255 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8257 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8259 llvm::SmallBitVector &CheckedVarArgs,
8260 UncoveredArgHandler &UncoveredArg)
8261 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8262 numDataArgs, beg, APK, Args, formatIdx,
8263 inFunctionCall, CallType, CheckedVarArgs,
8266 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8269 bool allowsObjCArg()
const {
8270 return FSType == FormatStringType::NSString ||
8271 FSType == FormatStringType::OSLog ||
8272 FSType == FormatStringType::OSTrace;
8275 bool HandleInvalidPrintfConversionSpecifier(
8276 const analyze_printf::PrintfSpecifier &FS,
8277 const char *startSpecifier,
8278 unsigned specifierLen)
override;
8280 void handleInvalidMaskType(StringRef MaskType)
override;
8282 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8283 const char *startSpecifier,
unsigned specifierLen,
8284 const TargetInfo &
Target)
override;
8285 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8286 const char *StartSpecifier,
8287 unsigned SpecifierLen,
8290 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
8291 const char *startSpecifier,
unsigned specifierLen);
8292 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8293 const analyze_printf::OptionalAmount &Amt,
8295 const char *startSpecifier,
unsigned specifierLen);
8296 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8297 const analyze_printf::OptionalFlag &flag,
8298 const char *startSpecifier,
unsigned specifierLen);
8299 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8300 const analyze_printf::OptionalFlag &ignoredFlag,
8301 const analyze_printf::OptionalFlag &flag,
8302 const char *startSpecifier,
unsigned specifierLen);
8303 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
8306 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8307 unsigned flagLen)
override;
8309 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8310 unsigned flagLen)
override;
8313 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8314 const char *flagsEnd,
8315 const char *conversionPosition)
override;
8320class EquatableFormatArgument {
8322 enum SpecifierSensitivity :
unsigned {
8329 enum FormatArgumentRole :
unsigned {
8337 analyze_format_string::ArgType ArgType;
8339 StringRef SpecifierLetter;
8340 CharSourceRange
Range;
8341 SourceLocation ElementLoc;
8342 FormatArgumentRole
Role : 2;
8343 SpecifierSensitivity Sensitivity : 2;
8344 unsigned Position : 14;
8345 unsigned ModifierFor : 14;
8347 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8348 bool InFunctionCall)
const;
8351 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8353 StringRef SpecifierLetter,
8354 analyze_format_string::ArgType ArgType,
8355 FormatArgumentRole
Role,
8356 SpecifierSensitivity Sensitivity,
unsigned Position,
8357 unsigned ModifierFor)
8358 : ArgType(ArgType), LengthMod(LengthMod),
8359 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8360 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8361 ModifierFor(ModifierFor) {}
8363 unsigned getPosition()
const {
return Position; }
8364 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8366 analyze_format_string::LengthModifier getLengthModifier()
const {
8367 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
8369 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8371 std::string buildFormatSpecifier()
const {
8373 llvm::raw_string_ostream(result)
8374 << getLengthModifier().toString() << SpecifierLetter;
8378 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8379 const Expr *FmtExpr,
bool InFunctionCall)
const;
8383class DecomposePrintfHandler :
public CheckPrintfHandler {
8384 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8387 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8388 const Expr *origFormatExpr,
8390 unsigned numDataArgs,
bool isObjC,
const char *beg,
8392 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8394 llvm::SmallBitVector &CheckedVarArgs,
8395 UncoveredArgHandler &UncoveredArg,
8396 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8397 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8398 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8399 inFunctionCall, CallType, CheckedVarArgs,
8401 Specs(Specs), HadError(
false) {}
8405 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8407 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8409 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8410 const char *startSpecifier,
8411 unsigned specifierLen,
8412 const TargetInfo &
Target)
override;
8417bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8419 unsigned specifierLen) {
8423 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
8425 startSpecifier, specifierLen,
8429void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8430 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8438 return T->isRecordType() || T->isComplexType();
8441bool CheckPrintfHandler::HandleAmount(
8443 const char *startSpecifier,
unsigned specifierLen) {
8445 if (HasFormatArguments()) {
8447 if (argIndex >= NumDataArgs) {
8448 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8452 getSpecifierRange(startSpecifier, specifierLen));
8462 CoveredArgs.set(argIndex);
8463 const Expr *Arg = getDataArg(argIndex);
8474 ? diag::err_printf_asterisk_wrong_type
8475 : diag::warn_printf_asterisk_wrong_type;
8476 EmitFormatDiagnostic(S.
PDiag(DiagID)
8481 getSpecifierRange(startSpecifier, specifierLen));
8491void CheckPrintfHandler::HandleInvalidAmount(
8495 const char *startSpecifier,
8496 unsigned specifierLen) {
8506 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8510 getSpecifierRange(startSpecifier, specifierLen),
8516 const char *startSpecifier,
8517 unsigned specifierLen) {
8521 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
8525 getSpecifierRange(startSpecifier, specifierLen),
8530void CheckPrintfHandler::HandleIgnoredFlag(
8534 const char *startSpecifier,
8535 unsigned specifierLen) {
8537 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8541 getSpecifierRange(startSpecifier, specifierLen),
8543 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8546void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8549 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
8550 getLocationOfByte(startFlag),
8552 getSpecifierRange(startFlag, flagLen));
8555void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8558 auto Range = getSpecifierRange(startFlag, flagLen);
8559 StringRef flag(startFlag, flagLen);
8560 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8561 getLocationOfByte(startFlag),
8566void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8567 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
8569 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8570 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8571 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8572 getLocationOfByte(conversionPosition),
8578 const Expr *FmtExpr,
8579 bool InFunctionCall)
const {
8580 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8581 ElementLoc,
true, Range);
8584bool EquatableFormatArgument::VerifyCompatible(
8585 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8586 bool InFunctionCall)
const {
8591 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8592 FmtExpr, InFunctionCall);
8593 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8597 if (
Role != FAR_Data) {
8598 if (ModifierFor !=
Other.ModifierFor) {
8601 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8602 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8603 FmtExpr, InFunctionCall);
8604 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8610 bool HadError =
false;
8611 if (Sensitivity !=
Other.Sensitivity) {
8614 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8615 << Sensitivity <<
Other.Sensitivity,
8616 FmtExpr, InFunctionCall);
8617 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8618 << 0 <<
Other.Range;
8621 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8625 case MK::MatchPromotion:
8629 case MK::NoMatchTypeConfusion:
8630 case MK::NoMatchPromotionTypeConfusion:
8632 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8633 << buildFormatSpecifier()
8634 <<
Other.buildFormatSpecifier(),
8635 FmtExpr, InFunctionCall);
8636 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8637 << 0 <<
Other.Range;
8640 case MK::NoMatchPedantic:
8642 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8643 << buildFormatSpecifier()
8644 <<
Other.buildFormatSpecifier(),
8645 FmtExpr, InFunctionCall);
8646 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8647 << 0 <<
Other.Range;
8650 case MK::NoMatchSignedness:
8652 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8653 << buildFormatSpecifier()
8654 <<
Other.buildFormatSpecifier(),
8655 FmtExpr, InFunctionCall);
8656 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8657 << 0 <<
Other.Range;
8663bool DecomposePrintfHandler::GetSpecifiers(
8664 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8667 StringRef
Data = FSL->getString();
8668 const char *Str =
Data.data();
8669 llvm::SmallBitVector BV;
8670 UncoveredArgHandler UA;
8671 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8672 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8684 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8685 const EquatableFormatArgument &B) {
8686 return A.getPosition() < B.getPosition();
8691bool DecomposePrintfHandler::HandlePrintfSpecifier(
8694 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8709 const unsigned Unset = ~0;
8710 unsigned FieldWidthIndex = Unset;
8711 unsigned PrecisionIndex = Unset;
8715 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8716 FieldWidthIndex = Specs.size();
8717 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8718 getLocationOfByte(FieldWidth.getStart()),
8720 FieldWidth.getArgType(S.
Context),
8721 EquatableFormatArgument::FAR_FieldWidth,
8722 EquatableFormatArgument::SS_None,
8723 FieldWidth.usesPositionalArg()
8724 ? FieldWidth.getPositionalArgIndex() - 1
8730 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8731 PrecisionIndex = Specs.size();
8733 getSpecifierRange(startSpecifier, specifierLen),
8734 getLocationOfByte(Precision.getStart()),
8736 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8737 EquatableFormatArgument::SS_None,
8738 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8744 unsigned SpecIndex =
8746 if (FieldWidthIndex != Unset)
8747 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8748 if (PrecisionIndex != Unset)
8749 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8751 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8753 Sensitivity = EquatableFormatArgument::SS_Private;
8755 Sensitivity = EquatableFormatArgument::SS_Public;
8757 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8759 Sensitivity = EquatableFormatArgument::SS_None;
8762 getSpecifierRange(startSpecifier, specifierLen),
8765 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8770 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8775 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8776 SpecIndex + 1, SpecIndex);
8784template<
typename MemberKind>
8795 R.suppressDiagnostics();
8802 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8817 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8819 if ((*MI)->getMinRequiredArguments() == 0)
8827bool CheckPrintfHandler::checkForCStrMembers(
8834 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8837 if (
Method->getMinRequiredArguments() == 0 &&
8850bool CheckPrintfHandler::HandlePrintfSpecifier(
8864 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8865 startSpecifier, specifierLen);
8873 startSpecifier, specifierLen)) {
8878 startSpecifier, specifierLen)) {
8882 if (!CS.consumesDataArgument()) {
8890 if (argIndex < NumDataArgs) {
8894 CoveredArgs.set(argIndex);
8901 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8904 if (HasFormatArguments()) {
8906 CoveredArgs.set(argIndex + 1);
8909 const Expr *Ex = getDataArg(argIndex);
8913 : ArgType::CPointerTy;
8915 EmitFormatDiagnostic(
8916 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8920 getSpecifierRange(startSpecifier, specifierLen));
8923 Ex = getDataArg(argIndex + 1);
8926 EmitFormatDiagnostic(
8927 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8931 getSpecifierRange(startSpecifier, specifierLen));
8938 if (!allowsObjCArg() && CS.isObjCArg()) {
8939 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8946 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8953 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8954 getLocationOfByte(CS.getStart()),
8956 getSpecifierRange(startSpecifier, specifierLen));
8966 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8973 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8977 getSpecifierRange(startSpecifier, specifierLen));
8980 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8984 getSpecifierRange(startSpecifier, specifierLen));
8988 const llvm::Triple &Triple =
Target.getTriple();
8990 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8991 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8992 getLocationOfByte(CS.getStart()),
8994 getSpecifierRange(startSpecifier, specifierLen));
9000 startSpecifier, specifierLen);
9006 startSpecifier, specifierLen);
9012 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
9013 getLocationOfByte(startSpecifier),
9015 getSpecifierRange(startSpecifier, specifierLen));
9024 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
9026 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
9035 startSpecifier, specifierLen);
9038 startSpecifier, specifierLen);
9043 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9044 diag::warn_format_nonsensical_length);
9046 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9048 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9049 diag::warn_format_non_standard_conversion_spec);
9052 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9055 if (!HasFormatArguments())
9058 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9061 const Expr *Arg = getDataArg(argIndex);
9065 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
9077 case Stmt::ArraySubscriptExprClass:
9078 case Stmt::CallExprClass:
9079 case Stmt::CharacterLiteralClass:
9080 case Stmt::CXXBoolLiteralExprClass:
9081 case Stmt::DeclRefExprClass:
9082 case Stmt::FloatingLiteralClass:
9083 case Stmt::IntegerLiteralClass:
9084 case Stmt::MemberExprClass:
9085 case Stmt::ObjCArrayLiteralClass:
9086 case Stmt::ObjCBoolLiteralExprClass:
9087 case Stmt::ObjCBoxedExprClass:
9088 case Stmt::ObjCDictionaryLiteralClass:
9089 case Stmt::ObjCEncodeExprClass:
9090 case Stmt::ObjCIvarRefExprClass:
9091 case Stmt::ObjCMessageExprClass:
9092 case Stmt::ObjCPropertyRefExprClass:
9093 case Stmt::ObjCStringLiteralClass:
9094 case Stmt::ObjCSubscriptRefExprClass:
9095 case Stmt::ParenExprClass:
9096 case Stmt::StringLiteralClass:
9097 case Stmt::UnaryOperatorClass:
9104static std::pair<QualType, StringRef>
9111 StringRef Name = UserTy->getDecl()->getName();
9112 QualType CastTy = llvm::StringSwitch<QualType>(Name)
9113 .Case(
"CFIndex", Context.getNSIntegerType())
9114 .Case(
"NSInteger", Context.getNSIntegerType())
9115 .Case(
"NSUInteger", Context.getNSUIntegerType())
9116 .Case(
"SInt32", Context.IntTy)
9117 .Case(
"UInt32", Context.UnsignedIntTy)
9121 return std::make_pair(CastTy, Name);
9123 TyTy = UserTy->desugar();
9127 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
9129 PE->getSubExpr()->getType(),
9138 StringRef TrueName, FalseName;
9140 std::tie(TrueTy, TrueName) =
9142 CO->getTrueExpr()->getType(),
9144 std::tie(FalseTy, FalseName) =
9146 CO->getFalseExpr()->getType(),
9147 CO->getFalseExpr());
9149 if (TrueTy == FalseTy)
9150 return std::make_pair(TrueTy, TrueName);
9151 else if (TrueTy.
isNull())
9152 return std::make_pair(FalseTy, FalseName);
9153 else if (FalseTy.
isNull())
9154 return std::make_pair(TrueTy, TrueName);
9157 return std::make_pair(
QualType(), StringRef());
9176 From = VecTy->getElementType();
9178 To = VecTy->getElementType();
9189 diag::warn_format_conversion_argument_type_mismatch_signedness,
9193 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9202 const char *StartSpecifier,
9203 unsigned SpecifierLen,
9215 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9216 ExprTy = TET->getUnderlyingExpr()->getType();
9219 if (
const OverflowBehaviorType *OBT =
9221 ExprTy = OBT->getUnderlyingType();
9235 getSpecifierRange(StartSpecifier, SpecifierLen);
9237 llvm::raw_svector_ostream os(FSString);
9239 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9250 getSpecifierRange(StartSpecifier, SpecifierLen);
9251 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9261 if (
Match == ArgType::Match)
9265 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9274 E = ICE->getSubExpr();
9284 if (OrigMatch == ArgType::NoMatchSignedness &&
9285 ImplicitMatch != ArgType::NoMatchSignedness)
9292 if (ImplicitMatch == ArgType::Match)
9310 if (
Match == ArgType::MatchPromotion)
9314 if (
Match == ArgType::MatchPromotion) {
9318 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9319 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9323 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9324 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9325 Match = ImplicitMatch;
9326 assert(
Match != ArgType::MatchPromotion);
9329 bool IsEnum =
false;
9330 bool IsScopedEnum =
false;
9333 IntendedTy = ED->getIntegerType();
9334 if (!ED->isScoped()) {
9335 ExprTy = IntendedTy;
9340 IsScopedEnum =
true;
9347 if (isObjCContext() &&
9358 const llvm::APInt &
V = IL->getValue();
9368 if (TD->getUnderlyingType() == IntendedTy)
9378 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
9386 if (!IsScopedEnum &&
9387 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9391 IntendedTy = CastTy;
9392 ShouldNotPrintDirectly =
true;
9397 PrintfSpecifier fixedFS = FS;
9404 llvm::raw_svector_ostream os(buf);
9407 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9409 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9415 llvm_unreachable(
"expected non-matching");
9417 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9420 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9423 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9426 Diag = diag::warn_format_conversion_argument_type_mismatch;
9447 llvm::raw_svector_ostream CastFix(CastBuf);
9448 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9450 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9456 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9461 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9483 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9489 Name = TypedefTy->getDecl()->getName();
9493 ? diag::warn_format_argument_needs_cast_pedantic
9494 : diag::warn_format_argument_needs_cast;
9495 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9506 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9507 : diag::warn_format_conversion_argument_type_mismatch;
9509 EmitFormatDiagnostic(
9521 bool EmitTypeMismatch =
false;
9530 llvm_unreachable(
"expected non-matching");
9532 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9535 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9538 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9542 ? diag::err_format_conversion_argument_type_mismatch
9543 : diag::warn_format_conversion_argument_type_mismatch;
9547 EmitFormatDiagnostic(
9556 EmitTypeMismatch =
true;
9558 EmitFormatDiagnostic(
9559 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9560 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9564 checkForCStrMembers(AT, E);
9570 EmitTypeMismatch =
true;
9572 EmitFormatDiagnostic(
9573 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9574 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9587 if (EmitTypeMismatch) {
9593 EmitFormatDiagnostic(
9594 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9600 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9601 "format string specifier index out of range");
9602 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9612class CheckScanfHandler :
public CheckFormatHandler {
9614 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9616 unsigned firstDataArg,
unsigned numDataArgs,
9618 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9620 llvm::SmallBitVector &CheckedVarArgs,
9621 UncoveredArgHandler &UncoveredArg)
9622 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9623 numDataArgs, beg, APK, Args, formatIdx,
9624 inFunctionCall, CallType, CheckedVarArgs,
9627 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9628 const char *startSpecifier,
9629 unsigned specifierLen)
override;
9631 bool HandleInvalidScanfConversionSpecifier(
9632 const analyze_scanf::ScanfSpecifier &FS,
9633 const char *startSpecifier,
9634 unsigned specifierLen)
override;
9636 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9641void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9643 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9644 getLocationOfByte(end),
true,
9645 getSpecifierRange(start, end - start));
9648bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9650 const char *startSpecifier,
9651 unsigned specifierLen) {
9655 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9657 startSpecifier, specifierLen,
9661bool CheckScanfHandler::HandleScanfSpecifier(
9663 const char *startSpecifier,
9664 unsigned specifierLen) {
9678 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9679 startSpecifier, specifierLen);
9690 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9705 if (argIndex < NumDataArgs) {
9709 CoveredArgs.set(argIndex);
9715 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9716 diag::warn_format_nonsensical_length);
9718 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9720 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9721 diag::warn_format_non_standard_conversion_spec);
9724 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9727 if (!HasFormatArguments())
9730 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9734 const Expr *Ex = getDataArg(argIndex);
9752 ScanfSpecifier fixedFS = FS;
9757 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9759 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9760 : diag::warn_format_conversion_argument_type_mismatch;
9765 llvm::raw_svector_ostream os(buf);
9768 EmitFormatDiagnostic(
9773 getSpecifierRange(startSpecifier, specifierLen),
9775 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9782 getSpecifierRange(startSpecifier, specifierLen));
9792 const Expr *FmtExpr,
bool InFunctionCall) {
9793 bool HadError =
false;
9794 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9795 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9796 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9808 for (; FmtIter < FmtEnd; ++FmtIter) {
9812 if (FmtIter->getPosition() < RefIter->getPosition())
9816 if (FmtIter->getPosition() > RefIter->getPosition())
9820 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9824 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9825 return Arg.getPosition() != RefIter->getPosition();
9829 if (FmtIter < FmtEnd) {
9830 CheckFormatHandler::EmitFormatDiagnostic(
9831 S, InFunctionCall, FmtExpr,
9832 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9833 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9834 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9835 }
else if (RefIter < RefEnd) {
9836 CheckFormatHandler::EmitFormatDiagnostic(
9837 S, InFunctionCall, FmtExpr,
9838 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9841 << 1 << RefIter->getSourceRange();
9847 Sema &S,
const FormatStringLiteral *FExpr,
9852 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9853 bool IgnoreStringsWithoutSpecifiers) {
9855 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9856 CheckFormatHandler::EmitFormatDiagnostic(
9857 S, inFunctionCall, Args[format_idx],
9858 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9864 StringRef StrRef = FExpr->getString();
9865 const char *Str = StrRef.data();
9869 assert(T &&
"String literal not of constant array type!");
9870 size_t TypeSize = T->getZExtSize();
9871 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9872 const unsigned numDataArgs = Args.size() - firstDataArg;
9874 if (IgnoreStringsWithoutSpecifiers &&
9881 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9882 CheckFormatHandler::EmitFormatDiagnostic(
9883 S, inFunctionCall, Args[format_idx],
9884 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9885 FExpr->getBeginLoc(),
9891 if (StrLen == 0 && numDataArgs > 0) {
9892 CheckFormatHandler::EmitFormatDiagnostic(
9893 S, inFunctionCall, Args[format_idx],
9894 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9905 if (ReferenceFormatString ==
nullptr) {
9906 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9907 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9908 inFunctionCall, CallType, CheckedVarArgs,
9918 Type, ReferenceFormatString, FExpr->getFormatString(),
9919 inFunctionCall ?
nullptr : Args[format_idx]);
9922 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9923 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9924 CallType, CheckedVarArgs, UncoveredArg);
9944 FormatStringLiteral RefLit = AuthoritativeFormatString;
9945 FormatStringLiteral TestLit = TestedFormatString;
9947 bool DiagAtStringLiteral;
9948 if (FunctionCallArg) {
9949 Arg = FunctionCallArg;
9950 DiagAtStringLiteral =
false;
9952 Arg = TestedFormatString;
9953 DiagAtStringLiteral =
true;
9955 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9956 AuthoritativeFormatString,
Type,
9957 IsObjC,
true, RefArgs) &&
9958 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9959 DiagAtStringLiteral, FmtArgs)) {
9961 TestedFormatString, FmtArgs, Arg,
9962 DiagAtStringLiteral);
9975 FormatStringLiteral RefLit = Str;
9979 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9988 bool HadError =
false;
9989 auto Iter = Args.begin();
9990 auto End = Args.end();
9991 while (Iter != End) {
9992 const auto &FirstInGroup = *Iter;
9994 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9996 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
10005 const char *Str = StrRef.data();
10008 assert(T &&
"String literal not of constant array type!");
10009 size_t TypeSize = T->getZExtSize();
10010 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
10021 switch (AbsFunction) {
10025 case Builtin::BI__builtin_abs:
10026 return Builtin::BI__builtin_labs;
10027 case Builtin::BI__builtin_labs:
10028 return Builtin::BI__builtin_llabs;
10029 case Builtin::BI__builtin_llabs:
10032 case Builtin::BI__builtin_fabsf:
10033 return Builtin::BI__builtin_fabs;
10034 case Builtin::BI__builtin_fabs:
10035 return Builtin::BI__builtin_fabsl;
10036 case Builtin::BI__builtin_fabsl:
10039 case Builtin::BI__builtin_cabsf:
10040 return Builtin::BI__builtin_cabs;
10041 case Builtin::BI__builtin_cabs:
10042 return Builtin::BI__builtin_cabsl;
10043 case Builtin::BI__builtin_cabsl:
10046 case Builtin::BIabs:
10047 return Builtin::BIlabs;
10048 case Builtin::BIlabs:
10049 return Builtin::BIllabs;
10050 case Builtin::BIllabs:
10053 case Builtin::BIfabsf:
10054 return Builtin::BIfabs;
10055 case Builtin::BIfabs:
10056 return Builtin::BIfabsl;
10057 case Builtin::BIfabsl:
10060 case Builtin::BIcabsf:
10061 return Builtin::BIcabs;
10062 case Builtin::BIcabs:
10063 return Builtin::BIcabsl;
10064 case Builtin::BIcabsl:
10071 unsigned AbsType) {
10093 unsigned AbsFunctionKind) {
10094 unsigned BestKind = 0;
10095 uint64_t ArgSize = Context.getTypeSize(ArgType);
10096 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
10099 if (Context.getTypeSize(ParamType) >= ArgSize) {
10102 else if (Context.hasSameType(ParamType, ArgType)) {
10118 if (T->isIntegralOrEnumerationType())
10120 if (T->isRealFloatingType())
10122 if (T->isAnyComplexType())
10125 llvm_unreachable(
"Type not integer, floating, or complex");
10132 switch (ValueKind) {
10137 case Builtin::BI__builtin_fabsf:
10138 case Builtin::BI__builtin_fabs:
10139 case Builtin::BI__builtin_fabsl:
10140 case Builtin::BI__builtin_cabsf:
10141 case Builtin::BI__builtin_cabs:
10142 case Builtin::BI__builtin_cabsl:
10143 return Builtin::BI__builtin_abs;
10144 case Builtin::BIfabsf:
10145 case Builtin::BIfabs:
10146 case Builtin::BIfabsl:
10147 case Builtin::BIcabsf:
10148 case Builtin::BIcabs:
10149 case Builtin::BIcabsl:
10150 return Builtin::BIabs;
10156 case Builtin::BI__builtin_abs:
10157 case Builtin::BI__builtin_labs:
10158 case Builtin::BI__builtin_llabs:
10159 case Builtin::BI__builtin_cabsf:
10160 case Builtin::BI__builtin_cabs:
10161 case Builtin::BI__builtin_cabsl:
10162 return Builtin::BI__builtin_fabsf;
10163 case Builtin::BIabs:
10164 case Builtin::BIlabs:
10165 case Builtin::BIllabs:
10166 case Builtin::BIcabsf:
10167 case Builtin::BIcabs:
10168 case Builtin::BIcabsl:
10169 return Builtin::BIfabsf;
10175 case Builtin::BI__builtin_abs:
10176 case Builtin::BI__builtin_labs:
10177 case Builtin::BI__builtin_llabs:
10178 case Builtin::BI__builtin_fabsf:
10179 case Builtin::BI__builtin_fabs:
10180 case Builtin::BI__builtin_fabsl:
10181 return Builtin::BI__builtin_cabsf;
10182 case Builtin::BIabs:
10183 case Builtin::BIlabs:
10184 case Builtin::BIllabs:
10185 case Builtin::BIfabsf:
10186 case Builtin::BIfabs:
10187 case Builtin::BIfabsl:
10188 return Builtin::BIcabsf;
10191 llvm_unreachable(
"Unable to convert function");
10202 case Builtin::BI__builtin_abs:
10203 case Builtin::BI__builtin_fabs:
10204 case Builtin::BI__builtin_fabsf:
10205 case Builtin::BI__builtin_fabsl:
10206 case Builtin::BI__builtin_labs:
10207 case Builtin::BI__builtin_llabs:
10208 case Builtin::BI__builtin_cabs:
10209 case Builtin::BI__builtin_cabsf:
10210 case Builtin::BI__builtin_cabsl:
10211 case Builtin::BIabs:
10212 case Builtin::BIlabs:
10213 case Builtin::BIllabs:
10214 case Builtin::BIfabs:
10215 case Builtin::BIfabsf:
10216 case Builtin::BIfabsl:
10217 case Builtin::BIcabs:
10218 case Builtin::BIcabsf:
10219 case Builtin::BIcabsl:
10222 llvm_unreachable(
"Unknown Builtin type");
10228 unsigned AbsKind,
QualType ArgType) {
10229 bool EmitHeaderHint =
true;
10230 const char *HeaderName =
nullptr;
10231 std::string FunctionName;
10232 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10233 FunctionName =
"std::abs";
10234 if (ArgType->isIntegralOrEnumerationType()) {
10235 HeaderName =
"cstdlib";
10236 }
else if (ArgType->isRealFloatingType()) {
10237 HeaderName =
"cmath";
10239 llvm_unreachable(
"Invalid Type");
10245 R.suppressDiagnostics();
10248 for (
const auto *I : R) {
10251 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10253 FDecl = dyn_cast<FunctionDecl>(I);
10268 EmitHeaderHint =
false;
10280 R.suppressDiagnostics();
10283 if (R.isSingleResult()) {
10284 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10286 EmitHeaderHint =
false;
10290 }
else if (!R.empty()) {
10296 S.
Diag(Loc, diag::note_replace_abs_function)
10302 if (!EmitHeaderHint)
10305 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10309template <std::
size_t StrLen>
10311 const char (&Str)[StrLen]) {
10324 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10325 return llvm::is_contained(names, calleeName);
10330 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10331 "__builtin_nanf16",
"__builtin_nanf128"});
10333 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10334 "__builtin_inff16",
"__builtin_inff128"});
10336 llvm_unreachable(
"unknown MathCheck");
10340 if (FDecl->
getName() !=
"infinity")
10343 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10345 if (RDecl->
getName() !=
"numeric_limits")
10362 if (FPO.getNoHonorNaNs() &&
10365 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10366 << 1 << 0 <<
Call->getSourceRange();
10370 if (FPO.getNoHonorInfs() &&
10374 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10375 << 0 << 0 <<
Call->getSourceRange();
10379void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10381 if (
Call->getNumArgs() != 1)
10386 if (AbsKind == 0 && !IsStdAbs)
10389 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10390 QualType ParamType =
Call->getArg(0)->getType();
10395 std::string FunctionName =
10396 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10397 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10398 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10427 if (ArgValueKind == ParamValueKind) {
10428 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10432 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10433 << FDecl << ArgType << ParamType;
10435 if (NewAbsKind == 0)
10439 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10448 if (NewAbsKind == 0)
10451 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10452 << FDecl << ParamValueKind << ArgValueKind;
10455 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10461 if (!
Call || !FDecl)
return;
10465 if (
Call->getExprLoc().isMacroID())
return;
10468 if (
Call->getNumArgs() != 2)
return;
10471 if (!ArgList)
return;
10472 if (ArgList->size() != 1)
return;
10475 const auto& TA = ArgList->
get(0);
10477 QualType ArgType = TA.getAsType();
10481 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10482 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10483 if (!MTE)
return false;
10484 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10485 if (!
Num)
return false;
10486 if (
Num->getValue() != 0)
return false;
10490 const Expr *FirstArg =
Call->getArg(0);
10491 const Expr *SecondArg =
Call->getArg(1);
10492 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10493 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10496 if (IsFirstArgZero == IsSecondArgZero)
return;
10501 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10503 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10504 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10507 SourceRange RemovalRange;
10508 if (IsFirstArgZero) {
10509 RemovalRange = SourceRange(FirstRange.
getBegin(),
10516 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10531 const auto *Size = dyn_cast<BinaryOperator>(E);
10536 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10540 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10541 << SizeRange << FnName;
10542 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10547 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10558 bool &IsContained) {
10561 IsContained =
false;
10574 for (
auto *FD : RD->
fields()) {
10578 IsContained =
true;
10579 return ContainedRD;
10587 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10588 if (Unary->getKind() == UETT_SizeOf)
10597 if (!
SizeOf->isArgumentType())
10598 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10605 return SizeOf->getTypeOfArgument();
10611struct SearchNonTrivialToInitializeField
10614 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10616 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10619 SourceLocation SL) {
10620 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10621 asDerived().visitArray(PDIK, AT, SL);
10625 Super::visitWithKind(PDIK, FT, SL);
10628 void visitARCStrong(QualType FT, SourceLocation SL) {
10631 void visitARCWeak(QualType FT, SourceLocation SL) {
10634 void visitStruct(QualType FT, SourceLocation SL) {
10639 const ArrayType *AT, SourceLocation SL) {
10640 visit(getContext().getBaseElementType(AT), SL);
10642 void visitTrivial(QualType FT, SourceLocation SL) {}
10644 static void diag(QualType RT,
const Expr *E, Sema &S) {
10645 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10654struct SearchNonTrivialToCopyField
10656 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10658 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10661 SourceLocation SL) {
10662 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10663 asDerived().visitArray(PCK, AT, SL);
10667 Super::visitWithKind(PCK, FT, SL);
10670 void visitARCStrong(QualType FT, SourceLocation SL) {
10673 void visitARCWeak(QualType FT, SourceLocation SL) {
10676 void visitPtrAuth(QualType FT, SourceLocation SL) {
10679 void visitStruct(QualType FT, SourceLocation SL) {
10684 SourceLocation SL) {
10685 visit(getContext().getBaseElementType(AT), SL);
10688 SourceLocation SL) {}
10689 void visitTrivial(QualType FT, SourceLocation SL) {}
10690 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10692 static void diag(QualType RT,
const Expr *E, Sema &S) {
10693 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10708 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10709 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10733 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10735 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10736 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10742 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10745 const Expr *SizeArg =
10746 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10748 auto isLiteralZero = [](
const Expr *E) {
10758 if (isLiteralZero(SizeArg) &&
10765 if (BId == Builtin::BIbzero ||
10768 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10769 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10770 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10771 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10772 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10780 if (BId == Builtin::BImemset &&
10784 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10785 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10790void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10797 unsigned ExpectedNumArgs =
10798 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10799 if (
Call->getNumArgs() < ExpectedNumArgs)
10802 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10803 BId == Builtin::BIstrndup ? 1 : 2);
10805 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10809 Call->getBeginLoc(),
Call->getRParenLoc()))
10821 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10822 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10825 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10829 QualType DestTy = Dest->
getType();
10830 QualType PointeeTy;
10831 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10843 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
10849 if (SizeOfArgTy != QualType()) {
10851 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10853 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10854 << FnName << SizeOfArgTy << ArgIdx
10861 PointeeTy = DestTy;
10864 if (PointeeTy == QualType())
10869 if (
const CXXRecordDecl *ContainedRD =
10872 unsigned OperationType = 0;
10873 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10876 if (ArgIdx != 0 || IsCmp) {
10877 if (BId == Builtin::BImemcpy)
10879 else if(BId == Builtin::BImemmove)
10886 PDiag(diag::warn_dyn_class_memaccess)
10887 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10888 << IsContained << ContainedRD << OperationType
10889 <<
Call->getCallee()->getSourceRange());
10891 BId != Builtin::BImemset)
10894 PDiag(diag::warn_arc_object_memaccess)
10895 << ArgIdx << FnName << PointeeTy
10896 <<
Call->getCallee()->getSourceRange());
10903 bool NonTriviallyCopyableCXXRecord =
10907 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10910 PDiag(diag::warn_cstruct_memaccess)
10911 << ArgIdx << FnName << PointeeTy << 0);
10912 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10913 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10914 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10918 PDiag(diag::warn_cxxstruct_memaccess)
10919 << FnName << PointeeTy);
10920 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10923 PDiag(diag::warn_cstruct_memaccess)
10924 << ArgIdx << FnName << PointeeTy << 1);
10925 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10926 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10927 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10931 PDiag(diag::warn_cxxstruct_memaccess)
10932 << FnName << PointeeTy);
10941 PDiag(diag::note_bad_memaccess_silence)
10947bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
10949 llvm::FoldingSetNodeID SizeOfArgID;
10955 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10958 QualType DestTy = Dest->
getType();
10959 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
10965 if (SizeOfArgID == llvm::FoldingSetNodeID())
10968 llvm::FoldingSetNodeID DestID;
10970 if (DestID == SizeOfArgID) {
10973 unsigned ActionIdx = 0;
10974 StringRef ReadableName = FnName->
getName();
10976 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
10977 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
10986 SourceLocation SL = SizeOfArg->
getExprLoc();
10991 if (
SM.isMacroArgExpansion(SL)) {
10993 SL =
SM.getSpellingLoc(SL);
10994 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10996 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
11001 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
11002 << ReadableName << PointeeTy << DestTy << DSR
11005 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
11006 << ActionIdx << SSR);
11042 if (CAT->getZExtSize() <= 1)
11050void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
11054 unsigned NumArgs =
Call->getNumArgs();
11055 if ((NumArgs != 3) && (NumArgs != 4))
11060 const Expr *CompareWithSrc =
nullptr;
11063 Call->getBeginLoc(),
Call->getRParenLoc()))
11068 CompareWithSrc = Ex;
11071 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
11072 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
11073 SizeCall->getNumArgs() == 1)
11078 if (!CompareWithSrc)
11085 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
11089 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
11090 if (!CompareWithSrcDRE ||
11094 const Expr *OriginalSizeArg =
Call->getArg(2);
11095 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
11102 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
11106 SmallString<128> sizeString;
11107 llvm::raw_svector_ostream
OS(sizeString);
11112 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
11119 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
11120 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
11121 return D1->getDecl() == D2->getDecl();
11126 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
11135void Sema::CheckStrncatArguments(
const CallExpr *CE,
11150 unsigned PatternType = 0;
11158 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
11159 if (BE->getOpcode() == BO_Sub) {
11160 const Expr *L = BE->getLHS()->IgnoreParenCasts();
11161 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
11172 if (PatternType == 0)
11181 if (
SM.isMacroArgExpansion(SL)) {
11182 SL =
SM.getSpellingLoc(SL);
11183 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
11188 QualType DstTy = DstArg->
getType();
11191 if (!isKnownSizeArray) {
11192 if (PatternType == 1)
11193 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11195 Diag(SL, diag::warn_strncat_src_size) << SR;
11199 if (PatternType == 1)
11200 Diag(SL, diag::warn_strncat_large_size) << SR;
11202 Diag(SL, diag::warn_strncat_src_size) << SR;
11204 SmallString<128> sizeString;
11205 llvm::raw_svector_ostream
OS(sizeString);
11213 Diag(SL, diag::note_strncat_wrong_size)
11218void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11227void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11229 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11230 const Decl *D = Lvalue->getDecl();
11231 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11232 if (!DD->getType()->isReferenceType())
11233 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11237 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11238 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11239 Lvalue->getMemberDecl());
11242void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11244 const auto *Lambda = dyn_cast<LambdaExpr>(
11249 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11250 << CalleeName << 2 ;
11253void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11255 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11256 if (Var ==
nullptr)
11260 << CalleeName << 0 << Var;
11263void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11266 llvm::raw_svector_ostream
OS(SizeString);
11269 if (Kind == clang::CK_BitCast &&
11270 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11272 if (Kind == clang::CK_IntegralToPointer &&
11274 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11277 switch (
Cast->getCastKind()) {
11278 case clang::CK_BitCast:
11279 case clang::CK_IntegralToPointer:
11280 case clang::CK_FunctionToPointerDecay:
11289 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11290 << CalleeName << 0 <<
OS.str();
11294void Sema::CheckFreeArguments(
const CallExpr *E) {
11295 const std::string CalleeName =
11300 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11302 case UnaryOperator::Opcode::UO_AddrOf:
11303 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11304 case UnaryOperator::Opcode::UO_Plus:
11305 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11310 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11312 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11314 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11315 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11316 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11322 << CalleeName << 1 ;
11327 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11328 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11332Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11341 Diag(ReturnLoc, diag::warn_null_ret)
11351 if (Op == OO_New || Op == OO_Array_New) {
11352 const FunctionProtoType *Proto
11356 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11362 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11367 if (
Context.getTargetInfo().getTriple().isPPC64())
11379 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11380 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11381 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11382 return FPLiteral && FPCast;
11385 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11391 llvm::APFloat TargetC = FPLiteral->
getValue();
11392 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11393 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11397 Diag(Loc, diag::warn_float_compare_literal)
11398 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11411 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11412 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11413 if (DRL->getDecl() == DRR->getDecl())
11421 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11422 if (FLL->isExact())
11424 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11425 if (FLR->isExact())
11429 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11430 CL &&
CL->getBuiltinCallee())
11433 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11434 CR && CR->getBuiltinCallee())
11438 Diag(Loc, diag::warn_floatingpoint_eq)
11459 IntRange(
unsigned Width,
bool NonNegative)
11460 : Width(Width), NonNegative(NonNegative) {}
11463 unsigned valueBits()
const {
11464 return NonNegative ? Width : Width - 1;
11468 static IntRange forBoolType() {
11469 return IntRange(1,
true);
11473 static IntRange forValueOfType(ASTContext &
C, QualType T) {
11474 return forValueOfCanonicalType(
C,
11479 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *T) {
11482 if (
const auto *VT = dyn_cast<VectorType>(T))
11483 T = VT->getElementType().getTypePtr();
11484 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11485 T = MT->getElementType().getTypePtr();
11486 if (
const auto *CT = dyn_cast<ComplexType>(T))
11487 T = CT->getElementType().getTypePtr();
11488 if (
const auto *AT = dyn_cast<AtomicType>(T))
11489 T = AT->getValueType().getTypePtr();
11490 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11491 T = OBT->getUnderlyingType().getTypePtr();
11493 if (!
C.getLangOpts().CPlusPlus) {
11496 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11501 if (
Enum->isFixed()) {
11502 return IntRange(
C.getIntWidth(QualType(T, 0)),
11503 !
Enum->getIntegerType()->isSignedIntegerType());
11506 unsigned NumPositive =
Enum->getNumPositiveBits();
11507 unsigned NumNegative =
Enum->getNumNegativeBits();
11509 if (NumNegative == 0)
11510 return IntRange(NumPositive,
true);
11512 return IntRange(std::max(NumPositive + 1, NumNegative),
11516 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11517 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11530 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *T) {
11533 if (
const VectorType *VT = dyn_cast<VectorType>(T))
11534 T = VT->getElementType().getTypePtr();
11535 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11536 T = MT->getElementType().getTypePtr();
11537 if (
const ComplexType *CT = dyn_cast<ComplexType>(T))
11538 T = CT->getElementType().getTypePtr();
11539 if (
const AtomicType *AT = dyn_cast<AtomicType>(T))
11540 T = AT->getValueType().getTypePtr();
11542 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11543 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11544 T = OBT->getUnderlyingType().getTypePtr();
11546 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11547 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11556 static IntRange join(IntRange L, IntRange R) {
11557 bool Unsigned = L.NonNegative &&
R.NonNegative;
11558 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11559 L.NonNegative &&
R.NonNegative);
11563 static IntRange bit_and(IntRange L, IntRange R) {
11564 unsigned Bits = std::max(L.Width,
R.Width);
11565 bool NonNegative =
false;
11566 if (L.NonNegative) {
11567 Bits = std::min(Bits, L.Width);
11568 NonNegative =
true;
11570 if (
R.NonNegative) {
11571 Bits = std::min(Bits,
R.Width);
11572 NonNegative =
true;
11574 return IntRange(Bits, NonNegative);
11578 static IntRange sum(IntRange L, IntRange R) {
11579 bool Unsigned = L.NonNegative &&
R.NonNegative;
11580 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11585 static IntRange difference(IntRange L, IntRange R) {
11589 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11590 bool Unsigned = L.NonNegative &&
R.Width == 0;
11591 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11597 static IntRange product(IntRange L, IntRange R) {
11601 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11602 bool Unsigned = L.NonNegative &&
R.NonNegative;
11603 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11608 static IntRange rem(IntRange L, IntRange R) {
11612 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11620 if (value.isSigned() && value.isNegative())
11621 return IntRange(value.getSignificantBits(),
false);
11623 if (value.getBitWidth() > MaxWidth)
11624 value = value.trunc(MaxWidth);
11628 return IntRange(value.getActiveBits(),
true);
11632 if (result.
isInt())
11639 R = IntRange::join(R, El);
11647 return IntRange::join(R, I);
11662 Ty = AtomicRHS->getValueType();
11681 bool InConstantContext,
11682 bool Approximate) {
11693 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11694 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11698 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11700 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11701 CE->getCastKind() == CK_BooleanToSignedIntegral;
11704 if (!isIntegerCast)
11705 return OutputTypeRange;
11708 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11709 InConstantContext, Approximate);
11711 return std::nullopt;
11714 if (SubRange->Width >= OutputTypeRange.Width)
11715 return OutputTypeRange;
11719 return IntRange(SubRange->Width,
11720 SubRange->NonNegative || OutputTypeRange.NonNegative);
11723 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11726 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11728 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11729 InConstantContext, Approximate);
11734 Expr *TrueExpr = CO->getTrueExpr();
11736 return std::nullopt;
11738 std::optional<IntRange> L =
11741 return std::nullopt;
11743 Expr *FalseExpr = CO->getFalseExpr();
11745 return std::nullopt;
11747 std::optional<IntRange> R =
11750 return std::nullopt;
11752 return IntRange::join(*L, *R);
11755 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11756 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11758 switch (BO->getOpcode()) {
11760 llvm_unreachable(
"builtin <=> should have class type");
11771 return IntRange::forBoolType();
11800 Combine = IntRange::bit_and;
11808 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11809 if (I->getValue() == 1) {
11810 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11811 return IntRange(R.Width,
true);
11821 case BO_ShrAssign: {
11823 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11825 return std::nullopt;
11829 if (std::optional<llvm::APSInt> shift =
11830 BO->getRHS()->getIntegerConstantExpr(
C)) {
11831 if (shift->isNonNegative()) {
11832 if (shift->uge(L->Width))
11833 L->Width = (L->NonNegative ? 0 : 1);
11835 L->Width -= shift->getZExtValue();
11849 Combine = IntRange::sum;
11853 if (BO->getLHS()->getType()->isPointerType())
11856 Combine = IntRange::difference;
11861 Combine = IntRange::product;
11870 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11872 return std::nullopt;
11875 if (std::optional<llvm::APSInt> divisor =
11876 BO->getRHS()->getIntegerConstantExpr(
C)) {
11877 unsigned log2 = divisor->logBase2();
11878 if (
log2 >= L->Width)
11879 L->Width = (L->NonNegative ? 0 : 1);
11881 L->Width = std::min(L->Width -
log2, MaxWidth);
11889 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11891 return std::nullopt;
11893 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11897 Combine = IntRange::rem;
11909 unsigned opWidth =
C.getIntWidth(T);
11911 InConstantContext, Approximate);
11913 return std::nullopt;
11916 InConstantContext, Approximate);
11918 return std::nullopt;
11920 IntRange
C = Combine(*L, *R);
11921 C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();
11922 C.Width = std::min(
C.Width, MaxWidth);
11926 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11927 switch (UO->getOpcode()) {
11930 return IntRange::forBoolType();
11944 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11947 return std::nullopt;
11952 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11962 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11965 return std::nullopt;
11970 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11980 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11981 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11985 return IntRange(BitField->getBitWidthValue(),
11986 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11989 return std::nullopt;
11995 bool InConstantContext,
11996 bool Approximate) {
12005 const llvm::fltSemantics &Src,
12006 const llvm::fltSemantics &Tgt) {
12007 llvm::APFloat truncated = value;
12010 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
12011 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
12013 return truncated.bitwiseIsEqual(value);
12022 const llvm::fltSemantics &Src,
12023 const llvm::fltSemantics &Tgt) {
12047 bool IsListInit =
false);
12062 return MacroName !=
"YES" && MacroName !=
"NO" &&
12063 MacroName !=
"true" && MacroName !=
"false";
12071 (!E->
getType()->isSignedIntegerType() ||
12086struct PromotedRange {
12088 llvm::APSInt PromotedMin;
12090 llvm::APSInt PromotedMax;
12092 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
12094 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
12095 else if (
R.Width >= BitWidth && !
Unsigned) {
12099 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
12100 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
12102 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
12103 .extOrTrunc(BitWidth);
12104 PromotedMin.setIsUnsigned(
Unsigned);
12106 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
12107 .extOrTrunc(BitWidth);
12108 PromotedMax.setIsUnsigned(
Unsigned);
12113 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
12123 InRangeFlag = 0x40,
12126 Min =
LE | InRangeFlag,
12127 InRange = InRangeFlag,
12128 Max =
GE | InRangeFlag,
12131 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
12136 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
12137 Value.isUnsigned() == PromotedMin.isUnsigned());
12138 if (!isContiguous()) {
12139 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
12140 if (
Value.isMinValue())
return Min;
12141 if (
Value.isMaxValue())
return Max;
12142 if (
Value >= PromotedMin)
return InRange;
12143 if (
Value <= PromotedMax)
return InRange;
12147 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
12148 case -1:
return Less;
12149 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
12151 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
12152 case -1:
return InRange;
12153 case 0:
return Max;
12158 llvm_unreachable(
"impossible compare result");
12161 static std::optional<StringRef>
12163 if (Op == BO_Cmp) {
12165 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
12167 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
12168 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
12169 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
12170 return std::nullopt;
12177 }
else if (Op == BO_NE) {
12181 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12188 if (Op == BO_GE || Op == BO_LE)
12189 std::swap(TrueFlag, FalseFlag);
12192 return StringRef(
"true");
12194 return StringRef(
"false");
12195 return std::nullopt;
12202 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12203 if (ICE->getCastKind() != CK_IntegralCast &&
12204 ICE->getCastKind() != CK_NoOp)
12206 E = ICE->getSubExpr();
12215 enum ConstantValueKind {
12220 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
12221 return BL->getValue() ? ConstantValueKind::LiteralTrue
12222 : ConstantValueKind::LiteralFalse;
12223 return ConstantValueKind::Miscellaneous;
12228 const llvm::APSInt &
Value,
12229 bool RhsConstant) {
12251 if (!OtherValueRange)
12256 OtherT = AT->getValueType();
12257 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12261 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12267 bool OtherIsBooleanDespiteType =
12269 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12270 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12274 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12275 Value.isUnsigned());
12276 auto Cmp = OtherPromotedValueRange.compare(
Value);
12277 auto Result = PromotedRange::constantValue(E->
getOpcode(),
Cmp, RhsConstant);
12283 bool TautologicalTypeCompare =
false;
12285 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12286 Value.isUnsigned());
12287 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12290 TautologicalTypeCompare =
true;
12298 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12307 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12313 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12314 Other->getType()->isUnsignedIntegerOrEnumerationType())
12315 TautologicalTypeCompare =
true;
12320 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
12321 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12325 llvm::raw_svector_ostream OS(PrettySourceValue);
12327 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12328 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12330 OS << (BL->getValue() ?
"YES" :
"NO");
12335 if (!TautologicalTypeCompare) {
12337 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12343 if (IsObjCSignedCharBool) {
12345 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12346 << OS.str() << *Result);
12353 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12357 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12358 : diag::warn_tautological_bool_compare)
12360 << OtherIsBooleanDespiteType << *Result
12367 ? diag::warn_unsigned_enum_always_true_comparison
12368 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12369 : diag::warn_unsigned_always_true_comparison)
12370 : diag::warn_tautological_constant_compare;
12373 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
12406 if (T->isIntegralType(S.
Context)) {
12407 std::optional<llvm::APSInt> RHSValue =
12409 std::optional<llvm::APSInt> LHSValue =
12413 if (RHSValue && LHSValue)
12417 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12419 const bool RhsConstant = (
bool)RHSValue;
12420 Expr *Const = RhsConstant ? RHS : LHS;
12422 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12431 if (!T->hasUnsignedIntegerRepresentation()) {
12445 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12447 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12453 Expr *signedOperand, *unsignedOperand;
12456 "unsigned comparison between two signed integer expressions?");
12457 signedOperand = LHS;
12458 unsignedOperand = RHS;
12460 signedOperand = RHS;
12461 unsignedOperand = LHS;
12467 std::optional<IntRange> signedRange =
12479 if (signedRange->NonNegative)
12491 if (!unsignedRange)
12496 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12498 if (unsignedRange->Width < comparisonWidth)
12503 S.
PDiag(diag::warn_mixed_sign_comparison)
12522 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12527 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12528 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12529 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12530 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12531 << BitfieldEnumDecl;
12538 Init->isValueDependent() ||
12539 Init->isTypeDependent())
12542 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12552 const PreferredTypeAttr *PTAttr =
nullptr;
12554 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12556 ED = PTAttr->getType()->getAsEnumDecl();
12564 bool SignedEnum = ED->getNumNegativeBits() > 0;
12571 unsigned DiagID = 0;
12572 if (SignedEnum && !SignedBitfield) {
12575 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12577 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12578 }
else if (SignedBitfield && !SignedEnum &&
12579 ED->getNumPositiveBits() == FieldWidth) {
12582 ? diag::warn_signed_bitfield_enum_conversion
12583 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12586 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12591 << SignedEnum << TypeRange;
12593 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12600 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12601 ED->getNumNegativeBits())
12602 : ED->getNumPositiveBits();
12605 if (BitsNeeded > FieldWidth) {
12609 ? diag::warn_bitfield_too_small_for_enum
12610 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12611 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12615 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12623 llvm::APSInt
Value = Result.Val.getInt();
12625 unsigned OriginalWidth =
Value.getBitWidth();
12631 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12632 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12639 if (!
Value.isSigned() ||
Value.isNegative())
12640 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12641 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12642 OriginalWidth =
Value.getSignificantBits();
12644 if (OriginalWidth <= FieldWidth)
12648 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12652 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12653 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12657 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12659 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12660 ? diag::warn_impcast_single_bit_bitield_precision_constant
12661 : diag::warn_impcast_bitfield_precision_constant)
12662 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12663 <<
Init->getSourceRange();
12700 bool PruneControlFlow =
false) {
12707 if (T.hasAddressSpace())
12709 if (PruneControlFlow) {
12723 bool PruneControlFlow =
false) {
12730 bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);
12735 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12736 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12741 llvm::APFloat
Value(0.0);
12747 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12752 diag::warn_impcast_float_integer, PruneWarnings);
12755 bool isExact =
false;
12758 T->hasUnsignedIntegerRepresentation());
12759 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12760 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12768 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12769 precision = (precision * 59 + 195) / 196;
12770 Value.toString(PrettySourceValue, precision);
12774 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12775 << PrettySourceValue);
12778 if (Result == llvm::APFloat::opOK && isExact) {
12779 if (IsLiteral)
return;
12780 return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
12786 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12789 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12790 : diag::warn_impcast_float_to_integer_out_of_range,
12793 unsigned DiagID = 0;
12796 DiagID = diag::warn_impcast_literal_float_to_integer;
12797 }
else if (IntegerValue == 0) {
12798 if (
Value.isZero()) {
12800 diag::warn_impcast_float_integer, PruneWarnings);
12803 DiagID = diag::warn_impcast_float_to_integer_zero;
12805 if (IntegerValue.isUnsigned()) {
12806 if (!IntegerValue.isMaxValue()) {
12808 diag::warn_impcast_float_integer, PruneWarnings);
12811 if (!IntegerValue.isMaxSignedValue() &&
12812 !IntegerValue.isMinSignedValue()) {
12814 diag::warn_impcast_float_integer, PruneWarnings);
12818 DiagID = diag::warn_impcast_float_to_integer;
12823 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12825 IntegerValue.toString(PrettyTargetValue);
12827 if (PruneWarnings) {
12831 << PrettySourceValue << PrettyTargetValue
12844 "Must be compound assignment operation");
12855 ->getComputationResultType()
12862 if (ResultBT->isInteger())
12864 E->
getExprLoc(), diag::warn_impcast_float_integer);
12866 if (!ResultBT->isFloatingPoint())
12875 diag::warn_impcast_float_result_precision);
12880 if (!Range.Width)
return "0";
12882 llvm::APSInt ValueInRange =
Value;
12883 ValueInRange.setIsSigned(!Range.NonNegative);
12884 ValueInRange = ValueInRange.trunc(Range.Width);
12885 return toString(ValueInRange, 10);
12895 const Type *Source =
12897 if (
Target->isDependentType())
12900 const auto *FloatCandidateBT =
12901 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12902 const Type *BoolCandidateType = ToBool ?
Target : Source;
12905 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12910 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12916 S, TheCall->
getArg(I - 1),
false));
12918 S, TheCall->
getArg(I + 1),
false));
12923 diag::warn_impcast_floating_point_to_bool);
12938 if (!IsGNUNullExpr && !HasNullPtrType)
12942 if (T->isAnyPointerType() || T->isBlockPointerType() ||
12943 T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())
12946 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12959 if (IsGNUNullExpr && Loc.
isMacroID()) {
12962 if (MacroName ==
"NULL")
12970 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12984 const char FirstLiteralCharacter =
12986 if (FirstLiteralCharacter ==
'0')
12992 if (CC.
isValid() && T->isCharType()) {
12993 const char FirstContextCharacter =
12995 if (FirstContextCharacter ==
'{')
13003 const auto *IL = dyn_cast<IntegerLiteral>(E);
13005 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
13006 if (UO->getOpcode() == UO_Minus)
13007 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
13018 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
13022 if (Opc == BO_Shl) {
13025 if (LHS && LHS->getValue() == 0)
13026 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
13028 RHS->getValue().isNonNegative() &&
13030 S.
Diag(ExprLoc, diag::warn_left_shift_always)
13031 << (Result.Val.getInt() != 0);
13033 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
13040 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
13045 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
13046 (RHS->getValue() == 0 || RHS->getValue() == 1))
13049 if (LHS->getValue() != 0 && RHS->getValue() != 0)
13050 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
13058 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
13064 if (Source->isChar16Type() &&
Target->isChar32Type())
13070 llvm::APSInt
Value(32);
13071 Value = Result.Val.getInt();
13072 bool IsASCII =
Value <= 0x7F;
13073 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
13074 bool ConversionPreservesSemantics =
13075 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
13077 if (!ConversionPreservesSemantics) {
13078 auto IsSingleCodeUnitCP = [](
const QualType &T,
13079 const llvm::APSInt &
Value) {
13080 if (T->isChar8Type())
13081 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
13082 if (T->isChar16Type())
13083 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
13084 assert(T->isChar32Type());
13085 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
13088 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
13097 LosesPrecision ? diag::warn_impcast_unicode_precision
13098 : diag::warn_impcast_unicode_char_type);
13103 From =
Context.getCanonicalType(From);
13104 To =
Context.getCanonicalType(To);
13107 From = MaybePointee;
13114 if (FromFn->getCFIUncheckedCalleeAttr() &&
13115 !ToFn->getCFIUncheckedCalleeAttr())
13123 bool *ICContext,
bool IsListInit) {
13128 if (Source ==
Target)
return;
13129 if (
Target->isDependentType())
return;
13139 if (Source->isAtomicType())
13143 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
13149 diag::warn_impcast_string_literal_to_bool);
13155 diag::warn_impcast_objective_c_literal_to_bool);
13157 if (Source->isPointerType() || Source->canDecayToPointerType()) {
13169 if (
ObjC().isSignedCharBool(T) && Source->isIntegralType(
Context)) {
13172 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
13174 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13183 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13185 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13196 diag::err_impcast_incompatible_type);
13201 ? diag::err_impcast_complex_scalar
13202 : diag::warn_impcast_complex_scalar);
13211 if (
Target->isSveVLSBuiltinType() &&
13218 if (
Target->isRVVVLSBuiltinType() &&
13228 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_vector_scalar);
13236 diag::warn_hlsl_impcast_vector_truncation);
13248 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13249 Target = VecTy->getElementType().getTypePtr();
13253 if (
Target->isScalarType())
13254 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_matrix_scalar);
13262 diag::warn_hlsl_impcast_matrix_truncation);
13268 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13269 Target = MatTy->getElementType().getTypePtr();
13271 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13277 const Type *OriginalTarget =
Context.getCanonicalType(T).getTypePtr();
13280 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13282 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13321 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_float_precision);
13324 else if (Order < 0) {
13328 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_double_promotion);
13334 if (TargetBT && TargetBT->
isInteger()) {
13361 diag::warn_impcast_floating_point_to_bool);
13369 if (Source->isFixedPointType()) {
13370 if (
Target->isUnsaturatedFixedPointType()) {
13374 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13375 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(T);
13376 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(T);
13379 PDiag(diag::warn_impcast_fixed_point_range)
13380 <<
Value.toString() << T
13386 }
else if (
Target->isIntegerType()) {
13390 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13393 llvm::APSInt IntResult = FXResult.convertToInt(
13394 Context.getIntWidth(T),
Target->isSignedIntegerOrEnumerationType(),
13399 PDiag(diag::warn_impcast_fixed_point_range)
13400 << FXResult.toString() << T
13407 }
else if (
Target->isUnsaturatedFixedPointType()) {
13408 if (Source->isIntegerType()) {
13415 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13416 Value,
Context.getFixedPointSemantics(T), &Overflowed);
13420 PDiag(diag::warn_impcast_fixed_point_range)
13441 unsigned int SourcePrecision =
SourceRange->Width;
13445 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13448 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13449 SourcePrecision > TargetPrecision) {
13451 if (std::optional<llvm::APSInt> SourceInt =
13456 llvm::APFloat TargetFloatValue(
13458 llvm::APFloat::opStatus ConversionStatus =
13459 TargetFloatValue.convertFromAPInt(
13461 llvm::APFloat::rmNearestTiesToEven);
13463 if (ConversionStatus != llvm::APFloat::opOK) {
13465 SourceInt->toString(PrettySourceValue, 10);
13467 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13471 PDiag(diag::warn_impcast_integer_float_precision_constant)
13472 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13478 diag::warn_impcast_integer_float_precision);
13487 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13492 if (
Target->isBooleanType())
13496 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13500 if (!Source->isIntegerType() || !
Target->isIntegerType())
13505 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13508 if (
ObjC().isSignedCharBool(T) && !Source->isCharType() &&
13511 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13516 if (!LikelySourceRange)
13519 IntRange SourceTypeRange =
13520 IntRange::forTargetOfCanonicalType(
Context, Source);
13521 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13523 if (LikelySourceRange->Width > TargetRange.Width) {
13527 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13528 if (TargetOBT->isWrapKind()) {
13535 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13536 if (SourceOBT->isWrapKind()) {
13546 llvm::APSInt
Value(32);
13556 PDiag(diag::warn_impcast_integer_precision_constant)
13557 << PrettySourceValue << PrettyTargetValue
13567 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13568 if (UO->getOpcode() == UO_Minus)
13570 *
this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
13573 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13574 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_integer_64_32,
13577 diag::warn_impcast_integer_precision);
13580 if (TargetRange.Width > SourceTypeRange.Width) {
13581 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13582 if (UO->getOpcode() == UO_Minus)
13583 if (Source->isUnsignedIntegerType()) {
13584 if (
Target->isUnsignedIntegerType())
13586 diag::warn_impcast_high_order_zero_bits);
13587 if (
Target->isSignedIntegerType())
13589 diag::warn_impcast_nonnegative_result);
13593 if (TargetRange.Width == LikelySourceRange->Width &&
13594 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13595 Source->isSignedIntegerType()) {
13609 PDiag(diag::warn_impcast_integer_precision_constant)
13610 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13620 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13621 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13622 LikelySourceRange->Width == TargetRange.Width))) {
13626 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13628 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13632 unsigned DiagID = diag::warn_impcast_integer_sign;
13640 DiagID = diag::warn_impcast_integer_sign_conditional;
13652 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_int_to_enum);
13657 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13659 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13660 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13661 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13662 TargetEnum->getDecl()->hasNameForLinkage() &&
13663 SourceEnum != TargetEnum) {
13668 diag::warn_impcast_different_enum_types);
13682 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13695 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13696 TrueExpr = BCO->getCommon();
13698 bool Suspicious =
false;
13702 if (T->isBooleanType())
13707 if (!Suspicious)
return;
13710 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13715 if (E->
getType() == T)
return;
13717 Suspicious =
false;
13722 E->
getType(), CC, &Suspicious);
13739struct AnalyzeImplicitConversionsWorkItem {
13748 bool ExtraCheckForImplicitConversion,
13751 WorkList.push_back({E, CC,
false});
13753 if (ExtraCheckForImplicitConversion && E->
getType() != T)
13760 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13762 Expr *OrigE = Item.E;
13781 Expr *SourceExpr = E;
13786 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13787 if (
auto *Src = OVE->getSourceExpr())
13790 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13791 if (UO->getOpcode() == UO_Not &&
13792 UO->getSubExpr()->isKnownToHaveBooleanValue())
13793 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13797 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13798 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13799 BO->getLHS()->isKnownToHaveBooleanValue() &&
13800 BO->getRHS()->isKnownToHaveBooleanValue() &&
13801 BO->getLHS()->HasSideEffects(S.
Context) &&
13802 BO->getRHS()->HasSideEffects(S.
Context)) {
13813 if (SR.str() ==
"&" || SR.str() ==
"|") {
13815 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13816 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13819 BO->getOperatorLoc(),
13820 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13821 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13823 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13841 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13847 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13853 if (SourceExpr->
getType() != T)
13862 for (
auto *SE : POE->semantics())
13863 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13864 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13868 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13869 E = CE->getSubExpr();
13875 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13876 if (InitListE->getNumInits() == 1) {
13877 E = InitListE->getInit(0);
13884 WorkList.push_back({E, CC, IsListInit});
13888 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13889 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13893 if (OutArgE->isInOut())
13894 WorkList.push_back(
13895 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13896 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13902 if (BO->isComparisonOp())
13906 if (BO->getOpcode() == BO_Assign)
13909 if (BO->isAssignmentOp())
13925 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13927 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13931 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13932 if (ChildExpr == CSE->getOperand())
13938 if (IsLogicalAndOperator &&
13943 WorkList.push_back({ChildExpr, CC, IsListInit});
13957 if (
U->getOpcode() == UO_LNot) {
13959 }
else if (
U->getOpcode() != UO_AddrOf) {
13960 if (
U->getSubExpr()->getType()->isAtomicType())
13961 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13962 diag::warn_atomic_implicit_seq_cst);
13973 WorkList.push_back({OrigE, CC, IsListInit});
13974 while (!WorkList.empty())
13986 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13989 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13990 if (!M->getMemberDecl()->getType()->isReferenceType())
13992 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13993 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13995 FD =
Call->getDirectCallee();
14004 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
14018 if (
SM.isMacroBodyExpansion(Loc))
14020 Loc =
SM.getImmediateMacroCallerLoc(Loc);
14044 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
14045 : diag::warn_this_bool_conversion;
14050 bool IsAddressOf =
false;
14052 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
14053 if (UO->getOpcode() != UO_AddrOf)
14055 IsAddressOf =
true;
14056 E = UO->getSubExpr();
14060 unsigned DiagID = IsCompare
14061 ? diag::warn_address_of_reference_null_compare
14062 : diag::warn_address_of_reference_bool_conversion;
14070 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
14073 llvm::raw_string_ostream S(Str);
14075 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
14076 : diag::warn_cast_nonnull_to_bool;
14079 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
14084 if (
auto *Callee =
Call->getDirectCallee()) {
14085 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
14086 ComplainAboutNonnullParamOrCall(A);
14095 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
14096 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
14097 MRecordDecl && MRecordDecl->isLambda()) {
14100 << MRecordDecl->getSourceRange() << Range << IsEqual;
14110 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
14111 D = M->getMemberDecl();
14119 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
14122 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
14123 ComplainAboutNonnullParamOrCall(A);
14127 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
14131 auto ParamIter = llvm::find(FD->
parameters(), PV);
14133 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
14137 ComplainAboutNonnullParamOrCall(
NonNull);
14142 if (ArgNo.getASTIndex() == ParamNo) {
14143 ComplainAboutNonnullParamOrCall(
NonNull);
14154 const bool IsFunction = T->isFunctionType();
14157 if (IsAddressOf && IsFunction) {
14162 if (!IsAddressOf && !IsFunction && !IsArray)
14167 llvm::raw_string_ostream S(Str);
14170 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
14171 : diag::warn_impcast_pointer_to_bool;
14178 DiagType = AddressOf;
14179 else if (IsFunction)
14180 DiagType = FunctionPointer;
14182 DiagType = ArrayPointer;
14184 llvm_unreachable(
"Could not determine diagnostic.");
14186 << Range << IsEqual;
14199 if (ReturnType.
isNull())
14230 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14231 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14233 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14234 Target->isUnsignedIntegerType()) {
14238 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14239 : diag::warn_impcast_overflow_behavior_pedantic;
14243 ? diag::warn_impcast_overflow_behavior_assignment
14244 : diag::warn_impcast_overflow_behavior;
14250 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14251 if (TargetOBT->isWrapKind()) {
14271 CheckArrayAccess(E);
14281void Sema::CheckForIntOverflow (
const Expr *E) {
14283 SmallVector<const Expr *, 2> Exprs(1, E);
14286 const Expr *OriginalE = Exprs.pop_back_val();
14294 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14295 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14298 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14299 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14300 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14302 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14303 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14304 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14305 Exprs.push_back(Temporary->getSubExpr());
14306 else if (
const auto *
Array = dyn_cast<ArraySubscriptExpr>(E))
14307 Exprs.push_back(
Array->getIdx());
14308 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14309 Exprs.push_back(Compound->getInitializer());
14310 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14311 New &&
New->isArray()) {
14312 if (
auto ArraySize =
New->getArraySize())
14313 Exprs.push_back(*ArraySize);
14314 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14315 Exprs.push_back(MTE->getSubExpr());
14316 }
while (!Exprs.empty());
14324 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14331 class SequenceTree {
14333 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14334 unsigned Parent : 31;
14335 LLVM_PREFERRED_TYPE(
bool)
14336 unsigned Merged : 1;
14338 SmallVector<Value, 8> Values;
14344 friend class SequenceTree;
14348 explicit Seq(
unsigned N) : Index(N) {}
14351 Seq() : Index(0) {}
14354 SequenceTree() { Values.push_back(
Value(0)); }
14355 Seq root()
const {
return Seq(0); }
14360 Seq allocate(
Seq Parent) {
14361 Values.push_back(
Value(Parent.Index));
14362 return Seq(Values.size() - 1);
14367 Values[S.Index].Merged =
true;
14373 bool isUnsequenced(
Seq Cur,
Seq Old) {
14374 unsigned C = representative(Cur.Index);
14375 unsigned Target = representative(Old.Index);
14379 C = Values[
C].Parent;
14386 unsigned representative(
unsigned K) {
14387 if (Values[K].Merged)
14389 return Values[K].Parent = representative(Values[K].Parent);
14395 using Object =
const NamedDecl *;
14409 UK_ModAsSideEffect,
14411 UK_Count = UK_ModAsSideEffect + 1
14417 const Expr *UsageExpr =
nullptr;
14418 SequenceTree::Seq
Seq;
14424 Usage Uses[UK_Count];
14427 bool Diagnosed =
false;
14431 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14439 UsageInfoMap UsageMap;
14442 SequenceTree::Seq Region;
14446 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14450 SmallVectorImpl<const Expr *> &WorkList;
14457 struct SequencedSubexpression {
14458 SequencedSubexpression(SequenceChecker &
Self)
14459 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14460 Self.ModAsSideEffect = &ModAsSideEffect;
14463 ~SequencedSubexpression() {
14464 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14468 UsageInfo &UI =
Self.UsageMap[M.first];
14469 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14470 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14471 SideEffectUsage = M.second;
14473 Self.ModAsSideEffect = OldModAsSideEffect;
14476 SequenceChecker &
Self;
14477 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14478 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14485 class EvaluationTracker {
14487 EvaluationTracker(SequenceChecker &
Self)
14489 Self.EvalTracker =
this;
14492 ~EvaluationTracker() {
14493 Self.EvalTracker = Prev;
14495 Prev->EvalOK &= EvalOK;
14498 bool evaluate(
const Expr *E,
bool &
Result) {
14503 Self.SemaRef.isConstantEvaluatedContext());
14508 SequenceChecker &
Self;
14509 EvaluationTracker *Prev;
14510 bool EvalOK =
true;
14511 } *EvalTracker =
nullptr;
14515 Object getObject(
const Expr *E,
bool Mod)
const {
14517 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14518 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14519 return getObject(UO->getSubExpr(), Mod);
14520 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14521 if (BO->getOpcode() == BO_Comma)
14522 return getObject(BO->getRHS(), Mod);
14523 if (Mod && BO->isAssignmentOp())
14524 return getObject(BO->getLHS(), Mod);
14525 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14528 return ME->getMemberDecl();
14529 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14538 void addUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14540 Usage &U = UI.Uses[UK];
14541 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14545 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14546 ModAsSideEffect->push_back(std::make_pair(O, U));
14548 U.UsageExpr = UsageExpr;
14558 void checkUsage(
Object O, UsageInfo &UI,
const Expr *UsageExpr,
14559 UsageKind OtherKind,
bool IsModMod) {
14563 const Usage &U = UI.Uses[OtherKind];
14564 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14567 const Expr *Mod = U.UsageExpr;
14568 const Expr *ModOrUse = UsageExpr;
14569 if (OtherKind == UK_Use)
14570 std::swap(Mod, ModOrUse);
14574 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14575 : diag::warn_unsequenced_mod_use)
14576 << O << SourceRange(ModOrUse->
getExprLoc()));
14577 UI.Diagnosed =
true;
14606 void notePreUse(
Object O,
const Expr *UseExpr) {
14607 UsageInfo &UI = UsageMap[O];
14609 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14612 void notePostUse(
Object O,
const Expr *UseExpr) {
14613 UsageInfo &UI = UsageMap[O];
14614 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14616 addUsage(O, UI, UseExpr, UK_Use);
14619 void notePreMod(
Object O,
const Expr *ModExpr) {
14620 UsageInfo &UI = UsageMap[O];
14622 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14623 checkUsage(O, UI, ModExpr, UK_Use,
false);
14626 void notePostMod(
Object O,
const Expr *ModExpr, UsageKind UK) {
14627 UsageInfo &UI = UsageMap[O];
14628 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14630 addUsage(O, UI, ModExpr, UK);
14634 SequenceChecker(Sema &S,
const Expr *E,
14635 SmallVectorImpl<const Expr *> &WorkList)
14636 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14640 (void)this->WorkList;
14643 void VisitStmt(
const Stmt *S) {
14647 void VisitExpr(
const Expr *E) {
14649 Base::VisitStmt(E);
14652 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14653 for (
auto *Sub : CSE->
children()) {
14654 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14669 void VisitCastExpr(
const CastExpr *E) {
14681 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14682 const Expr *SequencedAfter) {
14683 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14684 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14685 SequenceTree::Seq OldRegion = Region;
14688 SequencedSubexpression SeqBefore(*
this);
14689 Region = BeforeRegion;
14690 Visit(SequencedBefore);
14693 Region = AfterRegion;
14694 Visit(SequencedAfter);
14696 Region = OldRegion;
14698 Tree.merge(BeforeRegion);
14699 Tree.merge(AfterRegion);
14702 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14707 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14714 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14715 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14716 void VisitBinPtrMem(
const BinaryOperator *BO) {
14721 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14728 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14729 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14730 void VisitBinShlShr(
const BinaryOperator *BO) {
14734 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14741 void VisitBinComma(
const BinaryOperator *BO) {
14746 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14749 void VisitBinAssign(
const BinaryOperator *BO) {
14750 SequenceTree::Seq RHSRegion;
14751 SequenceTree::Seq LHSRegion;
14753 RHSRegion = Tree.allocate(Region);
14754 LHSRegion = Tree.allocate(Region);
14756 RHSRegion = Region;
14757 LHSRegion = Region;
14759 SequenceTree::Seq OldRegion = Region;
14775 SequencedSubexpression SeqBefore(*
this);
14776 Region = RHSRegion;
14780 Region = LHSRegion;
14784 notePostUse(O, BO);
14788 Region = LHSRegion;
14792 notePostUse(O, BO);
14794 Region = RHSRegion;
14802 Region = OldRegion;
14806 : UK_ModAsSideEffect);
14808 Tree.merge(RHSRegion);
14809 Tree.merge(LHSRegion);
14813 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14814 VisitBinAssign(CAO);
14817 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14818 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14819 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14822 return VisitExpr(UO);
14830 : UK_ModAsSideEffect);
14833 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14834 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14835 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14838 return VisitExpr(UO);
14842 notePostMod(O, UO, UK_ModAsSideEffect);
14845 void VisitBinLOr(
const BinaryOperator *BO) {
14851 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14852 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14853 SequenceTree::Seq OldRegion = Region;
14855 EvaluationTracker Eval(*
this);
14857 SequencedSubexpression Sequenced(*
this);
14858 Region = LHSRegion;
14865 bool EvalResult =
false;
14866 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14867 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14868 if (ShouldVisitRHS) {
14869 Region = RHSRegion;
14873 Region = OldRegion;
14874 Tree.merge(LHSRegion);
14875 Tree.merge(RHSRegion);
14878 void VisitBinLAnd(
const BinaryOperator *BO) {
14884 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14885 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14886 SequenceTree::Seq OldRegion = Region;
14888 EvaluationTracker Eval(*
this);
14890 SequencedSubexpression Sequenced(*
this);
14891 Region = LHSRegion;
14897 bool EvalResult =
false;
14898 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14899 bool ShouldVisitRHS = !EvalOK || EvalResult;
14900 if (ShouldVisitRHS) {
14901 Region = RHSRegion;
14905 Region = OldRegion;
14906 Tree.merge(LHSRegion);
14907 Tree.merge(RHSRegion);
14910 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14915 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14931 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14932 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14933 SequenceTree::Seq OldRegion = Region;
14935 EvaluationTracker Eval(*
this);
14937 SequencedSubexpression Sequenced(*
this);
14938 Region = ConditionRegion;
14948 bool EvalResult =
false;
14949 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14950 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14951 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14952 if (ShouldVisitTrueExpr) {
14953 Region = TrueRegion;
14956 if (ShouldVisitFalseExpr) {
14957 Region = FalseRegion;
14961 Region = OldRegion;
14962 Tree.merge(ConditionRegion);
14963 Tree.merge(TrueRegion);
14964 Tree.merge(FalseRegion);
14967 void VisitCallExpr(
const CallExpr *CE) {
14979 SequencedSubexpression Sequenced(*
this);
14984 SequenceTree::Seq CalleeRegion;
14985 SequenceTree::Seq OtherRegion;
14986 if (SemaRef.getLangOpts().CPlusPlus17) {
14987 CalleeRegion = Tree.allocate(Region);
14988 OtherRegion = Tree.allocate(Region);
14990 CalleeRegion = Region;
14991 OtherRegion = Region;
14993 SequenceTree::Seq OldRegion = Region;
14996 Region = CalleeRegion;
14998 SequencedSubexpression Sequenced(*this);
14999 Visit(CE->getCallee());
15001 Visit(CE->getCallee());
15005 Region = OtherRegion;
15009 Region = OldRegion;
15011 Tree.merge(CalleeRegion);
15012 Tree.merge(OtherRegion);
15030 return VisitCallExpr(CXXOCE);
15041 case OO_MinusEqual:
15043 case OO_SlashEqual:
15044 case OO_PercentEqual:
15045 case OO_CaretEqual:
15048 case OO_LessLessEqual:
15049 case OO_GreaterGreaterEqual:
15050 SequencingKind = RHSBeforeLHS;
15054 case OO_GreaterGreater:
15060 SequencingKind = LHSBeforeRHS;
15064 SequencingKind = LHSBeforeRest;
15068 SequencingKind = NoSequencing;
15072 if (SequencingKind == NoSequencing)
15073 return VisitCallExpr(CXXOCE);
15076 SequencedSubexpression Sequenced(*
this);
15079 assert(SemaRef.getLangOpts().CPlusPlus17 &&
15080 "Should only get there with C++17 and above!");
15081 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
15082 "Should only get there with an overloaded binary operator"
15083 " or an overloaded call operator!");
15085 if (SequencingKind == LHSBeforeRest) {
15086 assert(CXXOCE->getOperator() == OO_Call &&
15087 "We should only have an overloaded call operator here!");
15096 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
15097 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
15098 SequenceTree::Seq OldRegion = Region;
15100 assert(CXXOCE->getNumArgs() >= 1 &&
15101 "An overloaded call operator must have at least one argument"
15102 " for the postfix-expression!");
15103 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
15104 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
15105 CXXOCE->getNumArgs() - 1);
15109 Region = PostfixExprRegion;
15110 SequencedSubexpression Sequenced(*this);
15111 Visit(PostfixExpr);
15115 Region = ArgsRegion;
15116 for (const Expr *Arg : Args)
15119 Region = OldRegion;
15120 Tree.merge(PostfixExprRegion);
15121 Tree.merge(ArgsRegion);
15123 assert(CXXOCE->getNumArgs() == 2 &&
15124 "Should only have two arguments here!");
15125 assert((SequencingKind == LHSBeforeRHS ||
15126 SequencingKind == RHSBeforeLHS) &&
15127 "Unexpected sequencing kind!");
15131 const Expr *E1 = CXXOCE->getArg(0);
15132 const Expr *E2 = CXXOCE->getArg(1);
15133 if (SequencingKind == RHSBeforeLHS)
15136 return VisitSequencedExpressions(E1, E2);
15143 SequencedSubexpression Sequenced(*
this);
15146 return VisitExpr(CCE);
15149 SequenceExpressionsInOrder(
15155 return VisitExpr(ILE);
15158 SequenceExpressionsInOrder(ILE->
inits());
15170 SequenceTree::Seq Parent = Region;
15171 for (
const Expr *E : ExpressionList) {
15174 Region = Tree.allocate(Parent);
15175 Elts.push_back(Region);
15181 for (
unsigned I = 0; I < Elts.size(); ++I)
15182 Tree.merge(Elts[I]);
15186SequenceChecker::UsageInfo::UsageInfo() =
default;
15190void Sema::CheckUnsequencedOperations(
const Expr *E) {
15191 SmallVector<const Expr *, 8> WorkList;
15192 WorkList.push_back(E);
15193 while (!WorkList.empty()) {
15194 const Expr *Item = WorkList.pop_back_val();
15195 SequenceChecker(*
this, Item, WorkList);
15200 bool IsConstexpr) {
15203 CheckImplicitConversions(E, CheckLoc);
15205 CheckUnsequencedOperations(E);
15207 CheckForIntOverflow(E);
15220 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15224 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15228 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15242 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15246 bool CheckParameterNames) {
15247 bool HasInvalidParm =
false;
15249 assert(Param &&
"null in a parameter list");
15258 if (!Param->isInvalidDecl() &&
15260 diag::err_typecheck_decl_incomplete_type) ||
15262 diag::err_abstract_type_in_decl,
15264 Param->setInvalidDecl();
15265 HasInvalidParm =
true;
15270 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15274 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15282 QualType PType = Param->getOriginalType();
15290 if (!Param->isInvalidDecl()) {
15291 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15292 if (!ClassDecl->isInvalidDecl() &&
15293 !ClassDecl->hasIrrelevantDestructor() &&
15294 !ClassDecl->isDependentContext() &&
15295 ClassDecl->isParamDestroyedInCallee()) {
15307 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15308 if (!Param->getType().isConstQualified())
15309 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15313 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15318 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15319 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15324 if (!Param->isInvalidDecl() &&
15325 Param->getOriginalType()->isWebAssemblyTableType()) {
15326 Param->setInvalidDecl();
15327 HasInvalidParm =
true;
15328 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15332 return HasInvalidParm;
15335std::optional<std::pair<
15344static std::pair<CharUnits, CharUnits>
15352 if (
Base->isVirtual()) {
15359 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15366 DerivedType =
Base->getType();
15369 return std::make_pair(BaseAlignment, Offset);
15373static std::optional<std::pair<CharUnits, CharUnits>>
15379 return std::nullopt;
15384 return std::nullopt;
15388 CharUnits Offset = EltSize * IdxRes->getExtValue();
15391 return std::make_pair(P->first, P->second + Offset);
15397 return std::make_pair(
15398 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15404std::optional<std::pair<
15412 case Stmt::CStyleCastExprClass:
15413 case Stmt::CXXStaticCastExprClass:
15414 case Stmt::ImplicitCastExprClass: {
15416 const Expr *From = CE->getSubExpr();
15417 switch (CE->getCastKind()) {
15422 case CK_UncheckedDerivedToBase:
15423 case CK_DerivedToBase: {
15433 case Stmt::ArraySubscriptExprClass: {
15438 case Stmt::DeclRefExprClass: {
15442 if (!VD->getType()->isReferenceType()) {
15444 if (VD->hasDependentAlignment())
15453 case Stmt::MemberExprClass: {
15455 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15459 std::optional<std::pair<CharUnits, CharUnits>> P;
15468 return std::make_pair(P->first,
15471 case Stmt::UnaryOperatorClass: {
15481 case Stmt::BinaryOperatorClass: {
15493 return std::nullopt;
15498std::optional<std::pair<
15507 case Stmt::CStyleCastExprClass:
15508 case Stmt::CXXStaticCastExprClass:
15509 case Stmt::ImplicitCastExprClass: {
15511 const Expr *From = CE->getSubExpr();
15512 switch (CE->getCastKind()) {
15517 case CK_ArrayToPointerDecay:
15519 case CK_UncheckedDerivedToBase:
15520 case CK_DerivedToBase: {
15530 case Stmt::CXXThisExprClass: {
15535 case Stmt::UnaryOperatorClass: {
15541 case Stmt::BinaryOperatorClass: {
15550 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15551 std::swap(LHS, RHS);
15561 return std::nullopt;
15566 std::optional<std::pair<CharUnits, CharUnits>> P =
15570 return P->first.alignmentAtOffset(P->second);
15588 if (!DestPtr)
return;
15594 if (DestAlign.
isOne())
return;
15598 if (!SrcPtr)
return;
15609 if (SrcAlign >= DestAlign)
return;
15614 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15618void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15620 bool AllowOnePastEnd,
bool IndexNegated) {
15629 const Type *EffectiveType =
15633 Context.getAsConstantArrayType(BaseExpr->
getType());
15636 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15638 const Type *BaseType =
15640 bool IsUnboundedArray =
15642 Context, StrictFlexArraysLevel,
15645 (!IsUnboundedArray && BaseType->isDependentType()))
15653 if (IndexNegated) {
15654 index.setIsUnsigned(
false);
15658 if (IsUnboundedArray) {
15661 if (
index.isUnsigned() || !
index.isNegative()) {
15663 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15665 if (
index.getBitWidth() < AddrBits)
15667 std::optional<CharUnits> ElemCharUnits =
15668 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15671 if (!ElemCharUnits || ElemCharUnits->isZero())
15673 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15678 if (
index.getActiveBits() <= AddrBits) {
15680 llvm::APInt Product(
index);
15682 Product = Product.umul_ov(ElemBytes, Overflow);
15683 if (!Overflow && Product.getActiveBits() <= AddrBits)
15689 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15690 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15692 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15693 MaxElems = MaxElems.udiv(ElemBytes);
15696 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15697 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15702 PDiag(DiagID) << index << AddrBits
15703 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15704 << ElemBytes << MaxElems
15705 << MaxElems.getZExtValue()
15708 const NamedDecl *ND =
nullptr;
15710 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15712 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15714 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15715 ND = ME->getMemberDecl();
15719 PDiag(diag::note_array_declared_here) << ND);
15724 if (index.isUnsigned() || !index.isNegative()) {
15734 llvm::APInt size = ArrayTy->
getSize();
15736 if (BaseType != EffectiveType) {
15744 if (!ptrarith_typesize)
15745 ptrarith_typesize =
Context.getCharWidth();
15747 if (ptrarith_typesize != array_typesize) {
15749 uint64_t ratio = array_typesize / ptrarith_typesize;
15753 if (ptrarith_typesize * ratio == array_typesize)
15754 size *= llvm::APInt(size.getBitWidth(), ratio);
15758 if (size.getBitWidth() > index.getBitWidth())
15759 index = index.zext(size.getBitWidth());
15760 else if (size.getBitWidth() < index.getBitWidth())
15761 size = size.zext(index.getBitWidth());
15767 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15774 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15776 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15777 SourceLocation IndexLoc =
15779 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15784 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15785 : diag::warn_ptr_arith_exceeds_bounds;
15786 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15787 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15791 << index << ArrayTy->
desugar() << CastMsg
15794 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15796 DiagID = diag::warn_ptr_arith_precedes_bounds;
15797 if (index.isNegative()) index = -index;
15804 const NamedDecl *ND =
nullptr;
15806 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15808 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15810 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15811 ND = ME->getMemberDecl();
15815 PDiag(diag::note_array_declared_here) << ND);
15818void Sema::CheckArrayAccess(
const Expr *
expr) {
15819 int AllowOnePastEnd = 0;
15821 expr =
expr->IgnoreParenImpCasts();
15822 switch (
expr->getStmtClass()) {
15823 case Stmt::ArraySubscriptExprClass: {
15826 AllowOnePastEnd > 0);
15830 case Stmt::MemberExprClass: {
15834 case Stmt::CXXMemberCallExprClass: {
15838 case Stmt::ArraySectionExprClass: {
15844 nullptr, AllowOnePastEnd > 0);
15847 case Stmt::UnaryOperatorClass: {
15863 case Stmt::ConditionalOperatorClass: {
15865 if (
const Expr *lhs = cond->
getLHS())
15866 CheckArrayAccess(lhs);
15867 if (
const Expr *rhs = cond->
getRHS())
15868 CheckArrayAccess(rhs);
15871 case Stmt::CXXOperatorCallExprClass: {
15873 for (
const auto *Arg : OCE->arguments())
15874 CheckArrayAccess(Arg);
15884 Expr *RHS,
bool isProperty) {
15896 S.
Diag(Loc, diag::warn_arc_literal_assign)
15898 << (isProperty ? 0 : 1)
15906 Expr *RHS,
bool isProperty) {
15909 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15910 S.
Diag(Loc, diag::warn_arc_retained_assign)
15912 << (isProperty ? 0 : 1)
15916 RHS =
cast->getSubExpr();
15958 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15987 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15988 Diag(Loc, diag::warn_arc_retained_property_assign)
15992 RHS =
cast->getSubExpr();
16015 bool StmtLineInvalid;
16016 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
16018 if (StmtLineInvalid)
16021 bool BodyLineInvalid;
16022 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
16024 if (BodyLineInvalid)
16028 if (StmtLine != BodyLine)
16043 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16052 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16056 const Stmt *PossibleBody) {
16062 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
16063 StmtLoc = FS->getRParenLoc();
16064 Body = FS->getBody();
16065 DiagID = diag::warn_empty_for_body;
16066 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
16067 StmtLoc = WS->getRParenLoc();
16068 Body = WS->getBody();
16069 DiagID = diag::warn_empty_while_body;
16074 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
16098 if (!ProbableTypo) {
16099 bool BodyColInvalid;
16100 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
16102 if (BodyColInvalid)
16105 bool StmtColInvalid;
16108 if (StmtColInvalid)
16111 if (BodyCol > StmtCol)
16112 ProbableTypo =
true;
16115 if (ProbableTypo) {
16117 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
16125 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
16137 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
16139 RHSExpr = CE->
getArg(0);
16140 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
16141 CXXSCE && CXXSCE->isXValue())
16142 RHSExpr = CXXSCE->getSubExpr();
16146 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
16147 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
16150 if (LHSDeclRef && RHSDeclRef) {
16157 auto D =
Diag(OpLoc, diag::warn_self_move)
16173 const Expr *LHSBase = LHSExpr;
16174 const Expr *RHSBase = RHSExpr;
16175 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
16176 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
16177 if (!LHSME || !RHSME)
16180 while (LHSME && RHSME) {
16187 LHSME = dyn_cast<MemberExpr>(LHSBase);
16188 RHSME = dyn_cast<MemberExpr>(RHSBase);
16191 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16192 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16193 if (LHSDeclRef && RHSDeclRef) {
16200 Diag(OpLoc, diag::warn_self_move)
16207 Diag(OpLoc, diag::warn_self_move)
16231 bool AreUnionMembers =
false) {
16235 assert(((Field1Parent->isStructureOrClassType() &&
16236 Field2Parent->isStructureOrClassType()) ||
16237 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16238 "Can't evaluate layout compatibility between a struct field and a "
16240 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16241 (AreUnionMembers && Field1Parent->isUnionType())) &&
16242 "AreUnionMembers should be 'true' for union fields (only).");
16256 if (Bits1 != Bits2)
16260 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16261 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16264 if (!AreUnionMembers &&
16276 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16277 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16279 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16280 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16285 return isLayoutCompatible(C, F1, F2);
16296 for (
auto *Field1 : RD1->
fields()) {
16297 auto I = UnmatchedFields.begin();
16298 auto E = UnmatchedFields.end();
16300 for ( ; I != E; ++I) {
16302 bool Result = UnmatchedFields.erase(*I);
16312 return UnmatchedFields.empty();
16338 if (
C.hasSameType(T1, T2))
16347 if (TC1 == Type::Enum)
16349 if (TC1 == Type::Record) {
16368 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16399 const ValueDecl **VD, uint64_t *MagicValue,
16400 bool isConstantEvaluated) {
16408 case Stmt::UnaryOperatorClass: {
16417 case Stmt::DeclRefExprClass: {
16423 case Stmt::IntegerLiteralClass: {
16425 llvm::APInt MagicValueAPInt = IL->
getValue();
16426 if (MagicValueAPInt.getActiveBits() <= 64) {
16427 *MagicValue = MagicValueAPInt.getZExtValue();
16433 case Stmt::BinaryConditionalOperatorClass:
16434 case Stmt::ConditionalOperatorClass: {
16439 isConstantEvaluated)) {
16449 case Stmt::BinaryOperatorClass: {
16452 TypeExpr = BO->
getRHS();
16482 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16485 bool isConstantEvaluated) {
16486 FoundWrongKind =
false;
16491 uint64_t MagicValue;
16493 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16497 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16498 if (I->getArgumentKind() != ArgumentKind) {
16499 FoundWrongKind =
true;
16502 TypeInfo.Type = I->getMatchingCType();
16503 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16504 TypeInfo.MustBeNull = I->getMustBeNull();
16515 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16516 if (I == MagicValues->end())
16525 bool LayoutCompatible,
16527 if (!TypeTagForDatatypeMagicValues)
16528 TypeTagForDatatypeMagicValues.reset(
16529 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16532 (*TypeTagForDatatypeMagicValues)[Magic] =
16548 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16549 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16550 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16551 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16554void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16557 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16558 bool IsPointerAttr = Attr->getIsPointer();
16561 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16562 if (TypeTagIdxAST >= ExprArgs.size()) {
16563 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16564 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16567 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16568 bool FoundWrongKind;
16571 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16573 if (FoundWrongKind)
16575 diag::warn_type_tag_for_datatype_wrong_kind)
16581 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16582 if (ArgumentIdxAST >= ExprArgs.size()) {
16583 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16584 << 1 << Attr->getArgumentIdx().getSourceIndex();
16587 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16588 if (IsPointerAttr) {
16590 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16591 if (ICE->getType()->isVoidPointerType() &&
16592 ICE->getCastKind() == CK_BitCast)
16593 ArgumentExpr = ICE->getSubExpr();
16595 QualType ArgumentType = ArgumentExpr->
getType();
16601 if (TypeInfo.MustBeNull) {
16606 diag::warn_type_safety_null_pointer_required)
16614 QualType RequiredType = TypeInfo.Type;
16616 RequiredType =
Context.getPointerType(RequiredType);
16618 bool mismatch =
false;
16619 if (!TypeInfo.LayoutCompatible) {
16620 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16641 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16642 << ArgumentType << ArgumentKind
16643 << TypeInfo.LayoutCompatible << RequiredType
16661 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16669 if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())
16675 auto &MisalignedMembersForExpr =
16677 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16678 if (MA != MisalignedMembersForExpr.end() &&
16679 (T->isDependentType() || T->isIntegerType() ||
16680 (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
16682 T->getPointeeType()) <= MA->Alignment))))
16683 MisalignedMembersForExpr.erase(MA);
16692 const auto *ME = dyn_cast<MemberExpr>(E);
16704 bool AnyIsPacked =
false;
16706 QualType BaseType = ME->getBase()->getType();
16707 if (BaseType->isDependentType())
16711 auto *RD = BaseType->castAsRecordDecl();
16716 auto *FD = dyn_cast<FieldDecl>(MD);
16722 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16723 ReverseMemberChain.push_back(FD);
16726 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16728 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16735 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16746 if (ExpectedAlignment.
isOne())
16751 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16752 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16756 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16760 if (DRE && !TopME->
isArrow()) {
16763 CompleteObjectAlignment =
16764 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16768 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16771 CompleteObjectAlignment < ExpectedAlignment) {
16782 for (
FieldDecl *FDI : ReverseMemberChain) {
16783 if (FDI->hasAttr<PackedAttr>() ||
16784 FDI->getParent()->hasAttr<PackedAttr>()) {
16786 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16792 assert(FD &&
"We did not find a packed FieldDecl!");
16793 Action(E, FD->
getParent(), FD, Alignment);
16797void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16798 using namespace std::placeholders;
16801 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16825bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16826 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16853 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16870 assert(!Args.empty() &&
"Should have at least one argument.");
16872 Expr *Arg0 = Args.front();
16875 auto EmitError = [&](
Expr *ArgI) {
16877 diag::err_typecheck_call_different_arg_types)
16878 << Arg0->
getType() << ArgI->getType();
16883 for (
Expr *ArgI : Args.drop_front())
16894 for (
Expr *ArgI : Args.drop_front()) {
16895 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16898 VecI->getElementType()) ||
16899 Vec0->getNumElements() != VecI->getNumElements()) {
16908std::optional<QualType>
16912 return std::nullopt;
16916 return std::nullopt;
16919 for (
int I = 0; I < 2; ++I) {
16923 return std::nullopt;
16924 Args[I] = Converted.
get();
16931 return std::nullopt;
16934 return std::nullopt;
16936 TheCall->
setArg(0, Args[0]);
16937 TheCall->
setArg(1, Args[1]);
16948 TheCall->
getArg(1), Loc) ||
16950 TheCall->
getArg(2), Loc))
16954 for (
int I = 0; I < 3; ++I) {
16959 Args[I] = Converted.
get();
16962 int ArgOrdinal = 1;
16963 for (
Expr *Arg : Args) {
16965 ArgTyRestr, ArgOrdinal++))
16972 for (
int I = 0; I < 3; ++I)
16973 TheCall->
setArg(I, Args[I]);
16979bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16991bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
17000 diag::err_builtin_invalid_arg_type)
17001 << 1 << 2 << 1 << 1 << TyArg;
17015 Expr *Matrix = MatrixArg.
get();
17017 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
17020 << 1 << 3 << 0 << 0
17027 QualType ResultType =
Context.getConstantMatrixType(
17028 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
17031 TheCall->
setType(ResultType);
17034 TheCall->
setArg(0, Matrix);
17039static std::optional<unsigned>
17047 uint64_t
Dim =
Value->getZExtValue();
17063 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17065 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17073 unsigned PtrArgIdx = 0;
17074 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17075 Expr *RowsExpr = TheCall->
getArg(1);
17076 Expr *ColumnsExpr = TheCall->
getArg(2);
17077 Expr *StrideExpr = TheCall->
getArg(3);
17079 bool ArgError =
false;
17086 PtrExpr = PtrConv.
get();
17087 TheCall->
setArg(0, PtrExpr);
17094 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17095 QualType ElementTy;
17098 << PtrArgIdx + 1 << 0 << 5 << 0
17102 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
17106 << PtrArgIdx + 1 << 0 << 5
17113 auto ApplyArgumentConversions = [
this](Expr *E) {
17122 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
17124 RowsExpr = RowsConv.
get();
17125 TheCall->
setArg(1, RowsExpr);
17127 RowsExpr =
nullptr;
17129 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
17131 ColumnsExpr = ColumnsConv.
get();
17132 TheCall->
setArg(2, ColumnsExpr);
17134 ColumnsExpr =
nullptr;
17145 std::optional<unsigned> MaybeRows;
17149 std::optional<unsigned> MaybeColumns;
17154 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
17157 StrideExpr = StrideConv.
get();
17158 TheCall->
setArg(3, StrideExpr);
17161 if (std::optional<llvm::APSInt>
Value =
17164 if (Stride < *MaybeRows) {
17166 diag::err_builtin_matrix_stride_too_small);
17172 if (ArgError || !MaybeRows || !MaybeColumns)
17176 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17187 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17189 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17197 unsigned PtrArgIdx = 1;
17198 Expr *MatrixExpr = TheCall->
getArg(0);
17199 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17200 Expr *StrideExpr = TheCall->
getArg(2);
17202 bool ArgError =
false;
17208 MatrixExpr = MatrixConv.
get();
17209 TheCall->
setArg(0, MatrixExpr);
17216 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17219 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17227 PtrExpr = PtrConv.
get();
17228 TheCall->
setArg(1, PtrExpr);
17236 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17239 << PtrArgIdx + 1 << 0 << 5 << 0
17243 QualType ElementTy = PtrTy->getPointeeType();
17245 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17250 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17252 diag::err_builtin_matrix_pointer_arg_mismatch)
17253 << ElementTy << MatrixTy->getElementType();
17268 StrideExpr = StrideConv.
get();
17269 TheCall->
setArg(2, StrideExpr);
17274 if (std::optional<llvm::APSInt>
Value =
17277 if (Stride < MatrixTy->getNumRows()) {
17279 diag::err_builtin_matrix_stride_too_small);
17299 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17304 llvm::StringSet<> CalleeTCBs;
17305 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17306 CalleeTCBs.insert(A->getTCBName());
17307 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17308 CalleeTCBs.insert(A->getTCBName());
17312 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17313 StringRef CallerTCB = A->getTCBName();
17314 if (CalleeTCBs.count(CallerTCB) == 0) {
17315 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17316 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
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.
llvm::json::Object Object
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 checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall)
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType, QualType T)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool BuiltinRotateGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_stdc_rotate_{left,right} was called with two arguments, that the first argument...
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bswapg was called with a single argument, which is an unsigned integer,...
static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool isValidMathElementType(QualType T)
static void DiagnoseDeprecatedHIPAtomic(Sema &S, SourceRange ExprRange, MultiExprArg Args, AtomicExpr::AtomicOp Op)
Deprecate __hip_atomic_* builtins in favour of __scoped_atomic_* equivalents.
static bool IsSameCharType(QualType T1, QualType T2)
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth)
static const IntegerLiteral * getIntegerLiteral(Expr *E)
#define HIP_ATOMIC_FIXABLE(hip, scoped)
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 QualType getVectorElementType(ASTContext &Context, QualType VecTy)
static bool IsEnumConstOrFromMacro(Sema &S, const Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall)
static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall, SourceLocation CC)
static bool BuiltinBitreverseg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bitreverseg was called with a single argument, which is an integer.
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 bool CheckMissingFormatAttribute(Sema *S, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, StringLiteral *ReferenceFormatString, unsigned FormatIdx, unsigned FirstDataArg, FormatStringType FormatType, unsigned CallerParamIdx, SourceLocation Loc)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static void CheckCommaOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool ExtraCheckForImplicitConversion, llvm::SmallVectorImpl< AnalyzeImplicitConversionsWorkItem > &WorkList)
static void DiagnoseFloatingImpCast(Sema &S, const Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static int classifyConstantValue(Expr *Constant)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool PruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)
static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)
static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)
static bool referToTheSameDecl(const Expr *E1, const Expr *E2)
Check if two expressions refer to the same declaration.
static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall)
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static ExprResult GetVTablePointer(Sema &S, CallExpr *Call)
static bool requiresParensToAddCast(const Expr *E)
static bool HasEnumType(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const StringLiteral *ReferenceFormatString, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, std::optional< unsigned > *CallerFormatParamIdx=nullptr, bool IgnoreStringsWithoutSpecifiers=false)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, const Type *Target, Expr *E, QualType T, SourceLocation CC)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos, bool AllowConst, bool AllowAS)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr, int ArgOrdinal)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall)
static bool ConvertMaskedBuiltinArgs(Sema &S, CallExpr *TheCall)
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 ExprResult PointerAuthAuthLoadRelativeAndSign(Sema &S, CallExpr *Call)
static bool BuiltinStdCBuiltin(Sema &S, CallExpr *TheCall, QualType ReturnType)
Checks the __builtin_stdc_* builtins that take a single unsigned integer argument and return either i...
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, SourceLocation Loc)
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)
Compute the alignment and offset of a binary additive operator.
static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for DirectX constructs.
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SPIRV constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
C Language Family Type Representation.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
MatchKind
How well a given conversion specifier matches its argument.
@ NoMatch
The conversion specifier and the argument types are incompatible.
@ NoMatchPedantic
The conversion specifier and the argument type are disallowed by the C standard, but are in practice ...
@ Match
The conversion specifier and the argument type are compatible.
@ MatchPromotion
The conversion specifier and the argument type are compatible because of default argument promotions.
@ NoMatchSignedness
The conversion specifier and the argument type have different sign.
@ NoMatchTypeConfusion
The conversion specifier and the argument type are compatible, but still seems likely to be an error.
@ NoMatchPromotionTypeConfusion
The conversion specifier and the argument type are compatible but still seems likely to be an error.
unsigned getLength() const
const char * toString() const
const char * getStart() const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantAmount() const
unsigned getConstantLength() const
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, bool IsObjCLiteral)
Changes the specifier and length according to a QualType, retaining any flags or options.
void toString(raw_ostream &os) const
Sema::SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when the only matching conversion function is explicit.
Sema::SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when the expression has incomplete class type.
Sema::SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for one of the candidate conversions.
Sema::SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when there are multiple possible conversion functions.
Sema::SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic complaining that the expression does not have integral or enumeration type.
RotateIntegerConverter(unsigned ArgIndex, bool OnlyUnsigned)
Sema::SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when we picked a conversion function (for cases when we are not allowed to pick a ...
Sema::SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for the explicit conversion function.
bool match(QualType T) override
Determine whether the specified type is a valid destination type for this conversion.
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
void toString(raw_ostream &os) const
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APValue & getMatrixElt(unsigned Idx)
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
unsigned getMatrixNumElements() const
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
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
const LangOptions & getLangOpts() const
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.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
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
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
CanQualType UnsignedShortTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
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...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
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 ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
SourceLocation getQuestionLoc() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
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,...
static std::unique_ptr< AtomicScopeModel > getScopeModel(AtomicOp Op)
Get atomic scope model for the atomic op code.
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.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
static bool isAdditiveOp(Opcode Opc)
static bool isEqualityOp(Opcode Opc)
BinaryOperatorKind Opcode
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ conversion function within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
bool isDynamicClass() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getEndLoc() const
SourceLocation getRParenLoc() const
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
void shrinkNumArgs(unsigned NewNumArgs)
Reduce the number of arguments in this call expression.
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 byte-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.
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.
ConditionalOperator - The ?
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumElementsFlattened() const
Returns the number of elements required to embed the matrix into a vector.
static ConvertVectorExpr * Create(const ASTContext &C, Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc, FPOptionsOverride FPFeatures)
Expr * getOperand() 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 isStdNamespace() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getBeginLoc() const
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
std::string getAsString() const
Retrieve the human-readable string for this name.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
bool isComplete() const
Returns true if this can be considered a complete type.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
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,...
bool isIntegerConstantExpr(const ASTContext &Ctx) const
@ 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.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isFlexibleArrayMemberLike(const ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
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 * IgnoreCasts() LLVM_READONLY
Skip past any casts which might surround this expression until reaching a fixed point.
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
std::optional< uint64_t > tryEvaluateStrLen(const ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
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.
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 ...
std::optional< uint64_t > tryEvaluateObjectSize(const ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
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.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
UnresolvedSetImpl::iterator iterator
Represents a matrix type, as defined in the Matrix Types clang extensions.
static bool isValidElementType(QualType T, const LangOptions &LangOpts)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
Pointer-authentication qualifiers.
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
bool isAddressDiscriminated() const
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 isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
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.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isSEHExceptScope() const
Determine whether this scope is a SEH '__except' block.
unsigned getFlags() const
getFlags - Return the flags for this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
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.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Abstract base class used to perform a contextual implicit conversion from an expression to any type p...
ContextualImplicitConverter(bool Suppress=false, bool SuppressConversion=false)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
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...
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
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.
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
bool CheckOverflowBehaviorTypeConversion(Expr *E, QualType T, SourceLocation CC)
Check for overflow behavior type related implicit conversion diagnostics.
FPOptionsOverride CurFPFeatureOverrides()
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
DiagnosticsEngine & getDiagnostics() const
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
bool InOverflowBehaviorAssignmentContext
Track if we're currently analyzing overflow behavior types in assignment context.
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)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
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 BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
EltwiseBuiltinArgTyRestriction
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FormatStringI...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
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,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
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.
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.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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 TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool 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 isMatrixType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
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
bool isSizelessVectorType() const
Returns true for all scalable vector types.
NullabilityKindOrNone getNullability() const
Determine the nullability of the given type.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
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 ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
std::string getRepresentativeTypeName(ASTContext &C) const
MatchKind matchesType(ASTContext &C, QualType argTy) const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantLength() const
const char * toString() const
const char * getPosition() const
const OptionalFlag & isPrivate() const
bool hasValidLeftJustified() const
bool hasValidFieldWidth() const
bool hasValidSpacePrefix() const
const OptionalAmount & getPrecision() const
const OptionalFlag & hasSpacePrefix() const
bool usesPositionalArg() const
const OptionalFlag & isSensitive() const
const OptionalFlag & isLeftJustified() const
bool hasValidPrecision() const
const OptionalFlag & hasLeadingZeros() const
const OptionalFlag & hasAlternativeForm() const
bool hasValidLeadingZeros() const
void toString(raw_ostream &os) const
const PrintfConversionSpecifier & getConversionSpecifier() const
const OptionalFlag & hasPlusPrefix() const
const OptionalFlag & hasThousandsGrouping() const
bool hasValidThousandsGroupingPrefix() const
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const
Returns the builtin type that a data argument paired with this format specifier should have.
const OptionalFlag & isPublic() const
bool consumesDataArgument() const
bool hasValidPlusPrefix() const
bool hasValidAlternativeForm() const
bool consumesDataArgument() const
const ScanfConversionSpecifier & getConversionSpecifier() const
ArgType getArgType(ASTContext &Ctx) const
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
Pieces specific to fprintf format strings.
Pieces specific to fscanf format strings.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
uint32_t Literal
Literals are represented as positive integers.
ComparisonResult
Indicates the result of a tentative comparison.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ 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 LT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool hasSpecificAttr(const Container &container)
@ Arithmetic
An arithmetic operation.
@ Comparison
A comparison.
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ Success
Annotation was successful.
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
MutableArrayRef< Expr * > MultiExprArg
@ 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.
ActionResult< ParsedType > TypeResult
bool isFunctionOrMethodVariadic(const Decl *D)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
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())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
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
unsigned Indentation
The number of spaces to use to indent each line.
unsigned AnonymousTagNameStyle
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
unsigned NumCallArgs
The number of expressions in CallArgs.
const Expr *const * CallArgs
The list of argument expressions in a synthesized call.
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.
SmallVector< MisalignedMember, 4 > MisalignedMembers
Small set of gathered accesses to potentially misaligned members due to the packed attribute.