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)) ||
341 S.
Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
347 if (!IsValidIntegerType(AlignOp->
getType())) {
358 llvm::APSInt AlignValue = AlignResult.
Val.
getInt();
359 llvm::APSInt MaxValue(
360 llvm::APInt::getOneBitSet(MaxAlignmentBits + 1, MaxAlignmentBits));
361 if (AlignValue < 1) {
362 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_too_small) << 1;
365 if (llvm::APSInt::compareValues(AlignValue, MaxValue) > 0) {
370 if (!AlignValue.isPowerOf2()) {
371 S.
Diag(AlignOp->
getExprLoc(), diag::err_alignment_not_power_of_two);
374 if (AlignValue == 1) {
375 S.
Diag(AlignOp->
getExprLoc(), diag::warn_alignment_builtin_useless)
376 << IsBooleanAlignBuiltin;
404 std::pair<unsigned, const char *> Builtins[] = {
405 { Builtin::BI__builtin_add_overflow,
"ckd_add" },
406 { Builtin::BI__builtin_sub_overflow,
"ckd_sub" },
407 { Builtin::BI__builtin_mul_overflow,
"ckd_mul" },
410 bool CkdOperation = llvm::any_of(Builtins, [&](
const std::pair<
unsigned,
417 auto ValidCkdIntType = [](
QualType QT) {
420 if (
const auto *BT = QT.getCanonicalType()->getAs<
BuiltinType>())
421 return (BT->getKind() >= BuiltinType::Short &&
422 BT->getKind() <= BuiltinType::Int128) || (
423 BT->getKind() >= BuiltinType::UShort &&
424 BT->getKind() <= BuiltinType::UInt128) ||
425 BT->getKind() == BuiltinType::UChar ||
426 BT->getKind() == BuiltinType::SChar;
431 for (
unsigned I = 0; I < 2; ++I) {
437 bool IsValid = CkdOperation ? ValidCkdIntType(Ty) : Ty->
isIntegerType();
456 !PtrTy->getPointeeType()->isIntegerType() ||
457 (!ValidCkdIntType(PtrTy->getPointeeType()) && CkdOperation) ||
458 PtrTy->getPointeeType().isConstQualified()) {
460 diag::err_overflow_builtin_must_be_ptr_int)
468 if (BuiltinID == Builtin::BI__builtin_mul_overflow) {
469 for (
unsigned I = 0; I < 3; ++I) {
470 const auto Arg = TheCall->
getArg(I);
473 if (Ty->isBitIntType() && Ty->isSignedIntegerType() &&
475 return S.
Diag(Arg->getBeginLoc(),
476 diag::err_overflow_builtin_bit_int_max_size)
485struct BuiltinDumpStructGenerator {
489 SmallVector<Expr *, 32> Actions;
490 DiagnosticErrorTrap ErrorTracker;
491 PrintingPolicy Policy;
493 BuiltinDumpStructGenerator(Sema &S, CallExpr *TheCall)
494 : S(S), TheCall(TheCall), ErrorTracker(S.getDiagnostics()),
495 Policy(S.Context.getPrintingPolicy()) {
497 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
500 Expr *makeOpaqueValueExpr(Expr *Inner) {
504 Actions.push_back(OVE);
508 Expr *getStringLiteral(llvm::StringRef Str) {
511 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
514 bool callPrintFunction(llvm::StringRef Format,
515 llvm::ArrayRef<Expr *> Exprs = {}) {
516 SmallVector<Expr *, 8> Args;
518 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
520 Args.push_back(getStringLiteral(Format));
521 llvm::append_range(Args, Exprs);
524 Sema::CodeSynthesisContext Ctx;
537 Actions.push_back(RealCall.
get());
543 Expr *getIndentString(
unsigned Depth) {
547 llvm::SmallString<32>
Indent;
549 return getStringLiteral(
Indent);
556 bool appendFormatSpecifier(QualType T, llvm::SmallVectorImpl<char> &Str) {
557 llvm::raw_svector_ostream
OS(Str);
561 if (
auto *BT = T->
getAs<BuiltinType>()) {
562 switch (BT->getKind()) {
563 case BuiltinType::Bool:
566 case BuiltinType::Char_U:
567 case BuiltinType::UChar:
570 case BuiltinType::Char_S:
571 case BuiltinType::SChar:
579 analyze_printf::PrintfSpecifier
Specifier;
582 if (
Specifier.getConversionSpecifier().getKind() ==
583 analyze_printf::PrintfConversionSpecifier::sArg) {
589 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
609 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
610 Expr *IndentLit = getIndentString(Depth);
612 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
613 : callPrintFunction(
"%s", {TypeLit}))
616 return dumpRecordValue(RD, E, IndentLit, Depth);
620 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
629 Expr *RecordArg = makeOpaqueValueExpr(E);
632 if (callPrintFunction(
" {\n"))
636 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
637 for (
const auto &Base : CXXRD->bases()) {
645 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
651 Expr *FieldIndentArg = getIndentString(Depth + 1);
654 for (
auto *D : RD->
decls()) {
655 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
656 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
657 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
660 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
661 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
663 getStringLiteral(FD->getName())};
665 if (FD->isBitField()) {
669 FD->getBitWidthValue());
677 CXXScopeSpec(), Loc, IFD,
680 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
682 DeclarationNameInfo(FD->getDeclName(), Loc));
683 if (
Field.isInvalid())
686 auto *InnerRD = FD->getType()->getAsRecordDecl();
687 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
688 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
690 if (callPrintFunction(Format, Args) ||
691 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
695 if (appendFormatSpecifier(FD->getType(), Format)) {
697 Args.push_back(
Field.get());
707 Args.push_back(FieldAddr.
get());
710 if (callPrintFunction(Format, Args))
715 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
716 : callPrintFunction(
"}\n");
719 Expr *buildWrapper() {
722 TheCall->
setType(Wrapper->getType());
743 diag::err_expected_struct_pointer_argument)
752 diag::err_incomplete_type))
761 switch (BT ? BT->getKind() : BuiltinType::Void) {
762 case BuiltinType::Dependent:
763 case BuiltinType::Overload:
764 case BuiltinType::BoundMember:
765 case BuiltinType::PseudoObject:
766 case BuiltinType::UnknownAny:
767 case BuiltinType::BuiltinFn:
773 diag::err_expected_callable_argument)
779 BuiltinDumpStructGenerator Generator(S, TheCall);
785 Expr *PtrArg = PtrArgResult.
get();
789 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
792 return Generator.buildWrapper();
804 if (
Call->getStmtClass() != Stmt::CallExprClass) {
805 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
806 <<
Call->getSourceRange();
811 if (CE->getCallee()->getType()->isBlockPointerType()) {
812 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
813 <<
Call->getSourceRange();
817 const Decl *TargetDecl = CE->getCalleeDecl();
818 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
819 if (FD->getBuiltinID()) {
820 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
821 <<
Call->getSourceRange();
826 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
827 <<
Call->getSourceRange();
835 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
849 BuiltinCall->
setType(CE->getType());
853 BuiltinCall->
setArg(1, ChainResult.
get());
860class ScanfDiagnosticFormatHandler
864 using ComputeSizeFunction =
865 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
869 using DiagnoseFunction =
870 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
872 ComputeSizeFunction ComputeSizeArgument;
873 DiagnoseFunction Diagnose;
876 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
877 DiagnoseFunction Diagnose)
878 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
880 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
881 const char *StartSpecifier,
882 unsigned specifierLen)
override {
886 unsigned NulByte = 0;
898 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
900 analyze_format_string::OptionalAmount::HowSpecified::Constant)
905 std::optional<llvm::APSInt> DestSizeAPS =
910 unsigned DestSize = DestSizeAPS->getZExtValue();
912 if (DestSize < SourceSize)
919class EstimateSizeFormatHandler
924 bool IsKernelCompatible =
true;
927 EstimateSizeFormatHandler(StringRef Format)
928 :
Size(std::
min(Format.find(0), Format.size()) +
931 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
932 const char *,
unsigned SpecifierLen,
933 const TargetInfo &)
override {
935 const size_t FieldWidth = computeFieldWidth(FS);
936 const size_t Precision = computePrecision(FS);
943 Size += std::max(FieldWidth, (
size_t)1);
955 Size += std::max(FieldWidth, Precision);
971 Size += std::max(FieldWidth, 1 +
972 (Precision ? 1 + Precision
982 (Precision ? 1 + Precision : 0) +
992 (Precision ? 1 + Precision : 0) +
1007 IsKernelCompatible =
false;
1008 Size += std::max(FieldWidth, 2 + Precision);
1055 Size += (Precision ? 0 : 1);
1062 assert(SpecifierLen <= Size &&
"no underflow");
1063 Size -= SpecifierLen;
1067 size_t getSizeLowerBound()
const {
return Size; }
1068 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1071 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1072 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1073 size_t FieldWidth = 0;
1079 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1080 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1081 size_t Precision = 0;
1128 StringRef &FormatStrRef,
size_t &StrLen,
1130 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1131 Format && (Format->isOrdinary() || Format->isUTF8())) {
1132 FormatStrRef = Format->getString();
1134 Context.getAsConstantArrayType(Format->getType());
1135 assert(T &&
"String literal not of constant array type!");
1136 size_t TypeSize = T->getZExtSize();
1138 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1144void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1150 bool UseDABAttr =
false;
1151 const FunctionDecl *UseDecl = FD;
1153 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1155 UseDecl = DABAttr->getFunction();
1156 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1168 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1175 unsigned DABIndices = DABAttr->argIndices_size();
1176 unsigned NewIndex = Index < DABIndices
1177 ? DABAttr->argIndices_begin()[Index]
1180 return std::nullopt;
1184 auto ComputeExplicitObjectSizeArgument =
1185 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1186 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1188 return std::nullopt;
1189 unsigned NewIndex = *IndexOptional;
1191 Expr *SizeArg = TheCall->
getArg(NewIndex);
1193 return std::nullopt;
1199 auto ComputeSizeArgument =
1200 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1206 if (Index < FD->getNumParams()) {
1207 if (
const auto *POS =
1209 BOSType = POS->getType();
1212 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1214 return std::nullopt;
1215 unsigned NewIndex = *IndexOptional;
1218 return std::nullopt;
1220 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1221 if (std::optional<uint64_t> ObjSize =
1224 return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth);
1226 return std::nullopt;
1229 auto ComputeStrLenArgument =
1230 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1231 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1233 return std::nullopt;
1234 unsigned NewIndex = *IndexOptional;
1236 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1238 if (std::optional<uint64_t>
Result =
1241 return llvm::APSInt::getUnsigned(*
Result + 1).extOrTrunc(SizeTypeWidth);
1243 return std::nullopt;
1246 std::optional<llvm::APSInt> SourceSize;
1247 std::optional<llvm::APSInt> DestinationSize;
1248 unsigned DiagID = 0;
1249 bool IsChkVariant =
false;
1251 auto GetFunctionName = [&]() {
1252 std::string FunctionNameStr =
1254 llvm::StringRef FunctionName = FunctionNameStr;
1259 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1260 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1262 FunctionName.consume_front(
"__builtin_");
1264 return FunctionName.str();
1267 switch (BuiltinID) {
1270 case Builtin::BI__builtin_strcat:
1271 case Builtin::BIstrcat:
1272 case Builtin::BI__builtin_stpcpy:
1273 case Builtin::BIstpcpy:
1274 case Builtin::BI__builtin_strcpy:
1275 case Builtin::BIstrcpy: {
1276 DiagID = diag::warn_fortify_strlen_overflow;
1277 SourceSize = ComputeStrLenArgument(1);
1278 DestinationSize = ComputeSizeArgument(0);
1282 case Builtin::BI__builtin___strcat_chk:
1283 case Builtin::BI__builtin___stpcpy_chk:
1284 case Builtin::BI__builtin___strcpy_chk: {
1285 DiagID = diag::warn_fortify_strlen_overflow;
1286 SourceSize = ComputeStrLenArgument(1);
1287 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1288 IsChkVariant =
true;
1292 case Builtin::BIscanf:
1293 case Builtin::BIfscanf:
1294 case Builtin::BIsscanf: {
1295 unsigned FormatIndex = 1;
1296 unsigned DataIndex = 2;
1297 if (BuiltinID == Builtin::BIscanf) {
1302 const auto *FormatExpr =
1305 StringRef FormatStrRef;
1310 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1311 unsigned SourceSize) {
1312 DiagID = diag::warn_fortify_scanf_overflow;
1313 unsigned Index = ArgIndex + DataIndex;
1314 std::string FunctionName = GetFunctionName();
1316 PDiag(DiagID) << FunctionName << (Index + 1)
1317 << DestSize << SourceSize);
1320 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1321 return ComputeSizeArgument(Index + DataIndex);
1323 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1324 const char *FormatBytes = FormatStrRef.data();
1335 case Builtin::BIsprintf:
1336 case Builtin::BI__builtin___sprintf_chk: {
1337 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1340 StringRef FormatStrRef;
1343 EstimateSizeFormatHandler H(FormatStrRef);
1344 const char *FormatBytes = FormatStrRef.data();
1346 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1347 Context.getTargetInfo(),
false)) {
1348 DiagID = H.isKernelCompatible()
1349 ? diag::warn_format_overflow
1350 : diag::warn_format_overflow_non_kprintf;
1351 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1352 .extOrTrunc(SizeTypeWidth);
1353 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1354 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1355 IsChkVariant =
true;
1357 DestinationSize = ComputeSizeArgument(0);
1364 case Builtin::BI__builtin___memcpy_chk:
1365 case Builtin::BI__builtin___memmove_chk:
1366 case Builtin::BI__builtin___memset_chk:
1367 case Builtin::BI__builtin___strlcat_chk:
1368 case Builtin::BI__builtin___strlcpy_chk:
1369 case Builtin::BI__builtin___strncat_chk:
1370 case Builtin::BI__builtin___strncpy_chk:
1371 case Builtin::BI__builtin___stpncpy_chk:
1372 case Builtin::BI__builtin___memccpy_chk:
1373 case Builtin::BI__builtin___mempcpy_chk: {
1374 DiagID = diag::warn_builtin_chk_overflow;
1375 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1377 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1378 IsChkVariant =
true;
1382 case Builtin::BI__builtin___snprintf_chk:
1383 case Builtin::BI__builtin___vsnprintf_chk: {
1384 DiagID = diag::warn_builtin_chk_overflow;
1385 SourceSize = ComputeExplicitObjectSizeArgument(1);
1386 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1387 IsChkVariant =
true;
1391 case Builtin::BIstrncat:
1392 case Builtin::BI__builtin_strncat:
1393 case Builtin::BIstrncpy:
1394 case Builtin::BI__builtin_strncpy:
1395 case Builtin::BIstpncpy:
1396 case Builtin::BI__builtin_stpncpy: {
1402 DiagID = diag::warn_fortify_source_size_mismatch;
1403 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1404 DestinationSize = ComputeSizeArgument(0);
1408 case Builtin::BImemcpy:
1409 case Builtin::BI__builtin_memcpy:
1410 case Builtin::BImemmove:
1411 case Builtin::BI__builtin_memmove:
1412 case Builtin::BImemset:
1413 case Builtin::BI__builtin_memset:
1414 case Builtin::BImempcpy:
1415 case Builtin::BI__builtin_mempcpy: {
1416 DiagID = diag::warn_fortify_source_overflow;
1417 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1418 DestinationSize = ComputeSizeArgument(0);
1421 case Builtin::BIsnprintf:
1422 case Builtin::BI__builtin_snprintf:
1423 case Builtin::BIvsnprintf:
1424 case Builtin::BI__builtin_vsnprintf: {
1425 DiagID = diag::warn_fortify_source_size_mismatch;
1426 SourceSize = ComputeExplicitObjectSizeArgument(1);
1428 StringRef FormatStrRef;
1432 EstimateSizeFormatHandler H(FormatStrRef);
1433 const char *FormatBytes = FormatStrRef.data();
1435 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1436 Context.getTargetInfo(),
false)) {
1437 llvm::APSInt FormatSize =
1438 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1439 .extOrTrunc(SizeTypeWidth);
1440 if (FormatSize > *SourceSize && *SourceSize != 0) {
1441 unsigned TruncationDiagID =
1442 H.isKernelCompatible() ? diag::warn_format_truncation
1443 : diag::warn_format_truncation_non_kprintf;
1444 SmallString<16> SpecifiedSizeStr;
1445 SmallString<16> FormatSizeStr;
1446 SourceSize->toString(SpecifiedSizeStr, 10);
1447 FormatSize.toString(FormatSizeStr, 10);
1449 PDiag(TruncationDiagID)
1450 << GetFunctionName() << SpecifiedSizeStr
1455 DestinationSize = ComputeSizeArgument(0);
1459 CheckSizeofMemaccessArgument(LenArg, Dest, FnInfo);
1463 if (!SourceSize || !DestinationSize ||
1464 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1467 std::string FunctionName = GetFunctionName();
1469 SmallString<16> DestinationStr;
1470 SmallString<16> SourceStr;
1471 DestinationSize->toString(DestinationStr, 10);
1472 SourceSize->toString(SourceStr, 10);
1475 << FunctionName << DestinationStr << SourceStr);
1490 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1493 << DRE->getDecl()->getIdentifier();
1505 "__builtin_alloca has invalid address space");
1518 if (Arg->isTypeDependent() || Arg->isValueDependent())
1521 QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
1523 return S.
Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
1531enum PointerAuthOpKind {
1546 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1577 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1580 llvm::raw_svector_ostream Str(
Value);
1589 Result = KeyValue->getZExtValue();
1608 bool IsAddrDiscArg =
false;
1613 IsAddrDiscArg =
true;
1622 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1623 <<
Result->getExtValue();
1625 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1631 IntVal =
Result->getZExtValue();
1635static std::pair<const ValueDecl *, CharUnits>
1642 const auto *BaseDecl =
1647 return {BaseDecl, Result.Val.getLValueOffset()};
1651 bool RequireConstant =
false) {
1659 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1660 return OpKind != PAO_BlendInteger;
1662 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1663 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1664 OpKind == PAO_SignGeneric;
1673 }
else if (AllowsInteger(OpKind) &&
1680 <<
unsigned(OpKind == PAO_Discriminator ? 1
1681 : OpKind == PAO_BlendPointer ? 2
1682 : OpKind == PAO_BlendInteger ? 3
1684 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1694 if (!RequireConstant) {
1696 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1699 ? diag::warn_ptrauth_sign_null_pointer
1700 : diag::warn_ptrauth_auth_null_pointer)
1710 if (OpKind == PAO_Sign) {
1728 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1733 assert(OpKind == PAO_Discriminator);
1739 if (
Call->getBuiltinCallee() ==
1740 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1755 assert(
Pointer->getType()->isPointerType());
1767 assert(
Integer->getType()->isIntegerType());
1773 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1786 Call->setType(
Call->getArgs()[0]->getType());
1817 PointerAuthOpKind OpKind,
1818 bool RequireConstant) {
1829 Call->setType(
Call->getArgs()[0]->getType());
1845 Call->setType(
Call->getArgs()[0]->getType());
1854 const Expr *AddendExpr =
Call->getArg(5);
1856 if (!AddendIsConstInt) {
1857 const Expr *Arg =
Call->getArg(5)->IgnoreParenImpCasts();
1871 Call->setType(
Call->getArgs()[0]->getType());
1880 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1883 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1884 if (!Literal || Literal->getCharByteWidth() != 1) {
1900 Call->setArg(0, FirstValue.
get());
1906 if (!FirstArgRecord) {
1907 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1908 << 0 << FirstArgType;
1913 diag::err_get_vtable_pointer_requires_complete_type)) {
1918 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1919 << 1 << FirstArgRecord;
1923 Call->setType(ReturnType);
1948 auto DiagSelect = [&]() -> std::optional<unsigned> {
1955 return std::optional<unsigned>{};
1970 diag::err_incomplete_type))
1974 "Unhandled non-object pointer case");
2002 if (PT->getPointeeType()->isFunctionType()) {
2004 diag::err_builtin_is_within_lifetime_invalid_arg)
2010 if (PT->getPointeeType()->isVariableArrayType()) {
2012 << 1 <<
"__builtin_is_within_lifetime";
2017 diag::err_builtin_is_within_lifetime_invalid_arg)
2031 diag::err_builtin_trivially_relocate_invalid_arg_type)
2038 diag::err_incomplete_type))
2042 T->isIncompleteArrayType()) {
2044 diag::err_builtin_trivially_relocate_invalid_arg_type)
2045 << (T.isConstQualified() ? 1 : 2);
2054 diag::err_builtin_trivially_relocate_invalid_arg_type)
2061 if (Size.isInvalid())
2065 if (Size.isInvalid())
2067 SizeExpr = Size.get();
2068 TheCall->
setArg(2, SizeExpr);
2078 llvm::Triple::ObjectFormatType CurObjFormat =
2080 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2093 llvm::Triple::ArchType CurArch =
2095 if (llvm::is_contained(SupportedArchs, CurArch))
2105bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2112 case llvm::Triple::arm:
2113 case llvm::Triple::armeb:
2114 case llvm::Triple::thumb:
2115 case llvm::Triple::thumbeb:
2117 case llvm::Triple::aarch64:
2118 case llvm::Triple::aarch64_32:
2119 case llvm::Triple::aarch64_be:
2121 case llvm::Triple::bpfeb:
2122 case llvm::Triple::bpfel:
2124 case llvm::Triple::dxil:
2126 case llvm::Triple::hexagon:
2128 case llvm::Triple::mips:
2129 case llvm::Triple::mipsel:
2130 case llvm::Triple::mips64:
2131 case llvm::Triple::mips64el:
2133 case llvm::Triple::spirv:
2134 case llvm::Triple::spirv32:
2135 case llvm::Triple::spirv64:
2136 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2139 case llvm::Triple::systemz:
2141 case llvm::Triple::x86:
2142 case llvm::Triple::x86_64:
2144 case llvm::Triple::ppc:
2145 case llvm::Triple::ppcle:
2146 case llvm::Triple::ppc64:
2147 case llvm::Triple::ppc64le:
2149 case llvm::Triple::amdgcn:
2151 case llvm::Triple::riscv32:
2152 case llvm::Triple::riscv64:
2153 case llvm::Triple::riscv32be:
2154 case llvm::Triple::riscv64be:
2156 case llvm::Triple::loongarch32:
2157 case llvm::Triple::loongarch64:
2160 case llvm::Triple::wasm32:
2161 case llvm::Triple::wasm64:
2163 case llvm::Triple::nvptx:
2164 case llvm::Triple::nvptx64:
2170 return T->isDependentType() ||
2171 (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType());
2183 EltTy = VecTy->getElementType();
2185 switch (ArgTyRestr) {
2188 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2189 << ArgOrdinal << 2 << 1 << 1
2195 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2196 << ArgOrdinal << 5 << 0
2202 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2203 << ArgOrdinal << 5 << 1
2209 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2223 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2224 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2225 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2226 "Expecting __builtin_cpu_...");
2228 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2230 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2231 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2232 (!IsCPUSupports && TInfo->supportsCpuIs()));
2234 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2241 ? diag::err_builtin_aix_os_unsupported
2242 : diag::err_builtin_target_unsupported)
2248 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2286 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2287 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2288 BT->getNumBits() != 1) {
2290 << ArgTy << BT->getNumBits();
2360 TheCall->
setArg(0, Arg0);
2377 TheCall->
setArg(1, Arg1);
2383 << 2 << 1 << 4 << 0 << Arg1Ty;
2397 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2399 << (OnlyUnsigned ? 3 : 1)
2407 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2410 return OnlyUnsigned ? T->isUnsignedIntegerType() : T->isIntegerType();
2415 return emitError(S, Loc, T);
2420 return emitError(S, Loc, T);
2426 return emitError(S, Loc, T);
2431 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2436 return emitError(S, Loc, T);
2441 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2447 llvm_unreachable(
"conversion functions are permitted");
2466 TheCall->
setArg(0, Arg0);
2480 TheCall->
setArg(1, Arg1);
2491 unsigned Pos,
bool AllowConst,
2495 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2500 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2501 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2502 << Pos <<
"scalar pointer";
2511 diag::err_typecheck_convert_incompatible)
2520 bool TypeDependent =
false;
2521 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2549 Builtin::BI__builtin_masked_load))
2563 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2586 Builtin::BI__builtin_masked_store))
2594 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2604 diag::err_vec_builtin_incompatible_vector)
2633 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2646 << MaskTy << IdxTy);
2655 diag::err_vec_masked_load_store_ptr)
2684 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2700 << MaskTy << IdxTy);
2706 << MaskTy << ValTy);
2712 diag::err_vec_builtin_incompatible_vector)
2726 if (Args.size() == 0) {
2728 diag::err_typecheck_call_too_few_args_at_least)
2734 QualType FuncT = Args[0]->getType();
2737 if (Args.size() < 2) {
2739 diag::err_typecheck_call_too_few_args_at_least)
2745 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2746 QualType ObjectT = Args[1]->getType();
2748 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2797 tok::periodstar, ObjectArg.
get(), Args[0]);
2801 if (MPT->isMemberDataPointer())
2804 auto *MemCall =
new (S.
Context)
2828 return TyA->getElementType();
2835Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2840 unsigned ICEArguments = 0;
2842 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2847 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2849 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2854 if (ArgNo < TheCall->getNumArgs() &&
2857 ICEArguments &= ~(1 << ArgNo);
2861 switch (BuiltinID) {
2862 case Builtin::BI__builtin_cpu_supports:
2863 case Builtin::BI__builtin_cpu_is:
2865 Context.getAuxTargetInfo(), BuiltinID))
2868 case Builtin::BI__builtin_cpu_init:
2869 if (!
Context.getTargetInfo().supportsCpuInit()) {
2875 case Builtin::BI__builtin___CFStringMakeConstantString:
2879 *
this, BuiltinID, TheCall,
2880 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2883 "Wrong # arguments to builtin CFStringMakeConstantString");
2884 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2887 case Builtin::BI__builtin_ms_va_start:
2888 case Builtin::BI__builtin_stdarg_start:
2889 case Builtin::BI__builtin_va_start:
2890 case Builtin::BI__builtin_c23_va_start:
2891 if (BuiltinVAStart(BuiltinID, TheCall))
2894 case Builtin::BI__va_start: {
2895 switch (
Context.getTargetInfo().getTriple().getArch()) {
2896 case llvm::Triple::aarch64:
2897 case llvm::Triple::arm:
2898 case llvm::Triple::thumb:
2899 if (BuiltinVAStartARMMicrosoft(TheCall))
2903 if (BuiltinVAStart(BuiltinID, TheCall))
2911 case Builtin::BI_interlockedbittestandset_acq:
2912 case Builtin::BI_interlockedbittestandset_rel:
2913 case Builtin::BI_interlockedbittestandset_nf:
2914 case Builtin::BI_interlockedbittestandreset_acq:
2915 case Builtin::BI_interlockedbittestandreset_rel:
2916 case Builtin::BI_interlockedbittestandreset_nf:
2919 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2924 case Builtin::BI_bittest64:
2925 case Builtin::BI_bittestandcomplement64:
2926 case Builtin::BI_bittestandreset64:
2927 case Builtin::BI_bittestandset64:
2928 case Builtin::BI_interlockedbittestandreset64:
2929 case Builtin::BI_interlockedbittestandset64:
2932 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2933 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2938 case Builtin::BI_interlockedbittestandreset64_acq:
2939 case Builtin::BI_interlockedbittestandreset64_rel:
2940 case Builtin::BI_interlockedbittestandreset64_nf:
2941 case Builtin::BI_interlockedbittestandset64_acq:
2942 case Builtin::BI_interlockedbittestandset64_rel:
2943 case Builtin::BI_interlockedbittestandset64_nf:
2948 case Builtin::BI__builtin_set_flt_rounds:
2951 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2952 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2953 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2954 llvm::Triple::ppc64le}))
2958 case Builtin::BI__builtin_isgreater:
2959 case Builtin::BI__builtin_isgreaterequal:
2960 case Builtin::BI__builtin_isless:
2961 case Builtin::BI__builtin_islessequal:
2962 case Builtin::BI__builtin_islessgreater:
2963 case Builtin::BI__builtin_isunordered:
2964 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2967 case Builtin::BI__builtin_fpclassify:
2968 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2971 case Builtin::BI__builtin_isfpclass:
2972 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2975 case Builtin::BI__builtin_isfinite:
2976 case Builtin::BI__builtin_isinf:
2977 case Builtin::BI__builtin_isinf_sign:
2978 case Builtin::BI__builtin_isnan:
2979 case Builtin::BI__builtin_issignaling:
2980 case Builtin::BI__builtin_isnormal:
2981 case Builtin::BI__builtin_issubnormal:
2982 case Builtin::BI__builtin_iszero:
2983 case Builtin::BI__builtin_signbit:
2984 case Builtin::BI__builtin_signbitf:
2985 case Builtin::BI__builtin_signbitl:
2986 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2989 case Builtin::BI__builtin_shufflevector:
2993 case Builtin::BI__builtin_masked_load:
2994 case Builtin::BI__builtin_masked_expand_load:
2996 case Builtin::BI__builtin_masked_store:
2997 case Builtin::BI__builtin_masked_compress_store:
2999 case Builtin::BI__builtin_masked_gather:
3001 case Builtin::BI__builtin_masked_scatter:
3003 case Builtin::BI__builtin_invoke:
3005 case Builtin::BI__builtin_prefetch:
3006 if (BuiltinPrefetch(TheCall))
3009 case Builtin::BI__builtin_alloca_with_align:
3010 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3011 if (BuiltinAllocaWithAlign(TheCall))
3014 case Builtin::BI__builtin_alloca:
3015 case Builtin::BI__builtin_alloca_uninitialized:
3022 case Builtin::BI__builtin_infer_alloc_token:
3026 case Builtin::BI__arithmetic_fence:
3027 if (BuiltinArithmeticFence(TheCall))
3030 case Builtin::BI__assume:
3031 case Builtin::BI__builtin_assume:
3032 if (BuiltinAssume(TheCall))
3035 case Builtin::BI__builtin_assume_aligned:
3036 if (BuiltinAssumeAligned(TheCall))
3039 case Builtin::BI__builtin_dynamic_object_size:
3040 case Builtin::BI__builtin_object_size:
3044 case Builtin::BI__builtin_longjmp:
3045 if (BuiltinLongjmp(TheCall))
3048 case Builtin::BI__builtin_setjmp:
3049 if (BuiltinSetjmp(TheCall))
3052 case Builtin::BI__builtin_classify_type:
3057 case Builtin::BI__builtin_complex:
3058 if (BuiltinComplex(TheCall))
3061 case Builtin::BI__builtin_constant_p: {
3070 case Builtin::BI__builtin_launder:
3072 case Builtin::BI__builtin_is_within_lifetime:
3074 case Builtin::BI__builtin_trivially_relocate:
3077 case Builtin::BI__sync_fetch_and_add:
3078 case Builtin::BI__sync_fetch_and_add_1:
3079 case Builtin::BI__sync_fetch_and_add_2:
3080 case Builtin::BI__sync_fetch_and_add_4:
3081 case Builtin::BI__sync_fetch_and_add_8:
3082 case Builtin::BI__sync_fetch_and_add_16:
3083 case Builtin::BI__sync_fetch_and_sub:
3084 case Builtin::BI__sync_fetch_and_sub_1:
3085 case Builtin::BI__sync_fetch_and_sub_2:
3086 case Builtin::BI__sync_fetch_and_sub_4:
3087 case Builtin::BI__sync_fetch_and_sub_8:
3088 case Builtin::BI__sync_fetch_and_sub_16:
3089 case Builtin::BI__sync_fetch_and_or:
3090 case Builtin::BI__sync_fetch_and_or_1:
3091 case Builtin::BI__sync_fetch_and_or_2:
3092 case Builtin::BI__sync_fetch_and_or_4:
3093 case Builtin::BI__sync_fetch_and_or_8:
3094 case Builtin::BI__sync_fetch_and_or_16:
3095 case Builtin::BI__sync_fetch_and_and:
3096 case Builtin::BI__sync_fetch_and_and_1:
3097 case Builtin::BI__sync_fetch_and_and_2:
3098 case Builtin::BI__sync_fetch_and_and_4:
3099 case Builtin::BI__sync_fetch_and_and_8:
3100 case Builtin::BI__sync_fetch_and_and_16:
3101 case Builtin::BI__sync_fetch_and_xor:
3102 case Builtin::BI__sync_fetch_and_xor_1:
3103 case Builtin::BI__sync_fetch_and_xor_2:
3104 case Builtin::BI__sync_fetch_and_xor_4:
3105 case Builtin::BI__sync_fetch_and_xor_8:
3106 case Builtin::BI__sync_fetch_and_xor_16:
3107 case Builtin::BI__sync_fetch_and_nand:
3108 case Builtin::BI__sync_fetch_and_nand_1:
3109 case Builtin::BI__sync_fetch_and_nand_2:
3110 case Builtin::BI__sync_fetch_and_nand_4:
3111 case Builtin::BI__sync_fetch_and_nand_8:
3112 case Builtin::BI__sync_fetch_and_nand_16:
3113 case Builtin::BI__sync_add_and_fetch:
3114 case Builtin::BI__sync_add_and_fetch_1:
3115 case Builtin::BI__sync_add_and_fetch_2:
3116 case Builtin::BI__sync_add_and_fetch_4:
3117 case Builtin::BI__sync_add_and_fetch_8:
3118 case Builtin::BI__sync_add_and_fetch_16:
3119 case Builtin::BI__sync_sub_and_fetch:
3120 case Builtin::BI__sync_sub_and_fetch_1:
3121 case Builtin::BI__sync_sub_and_fetch_2:
3122 case Builtin::BI__sync_sub_and_fetch_4:
3123 case Builtin::BI__sync_sub_and_fetch_8:
3124 case Builtin::BI__sync_sub_and_fetch_16:
3125 case Builtin::BI__sync_and_and_fetch:
3126 case Builtin::BI__sync_and_and_fetch_1:
3127 case Builtin::BI__sync_and_and_fetch_2:
3128 case Builtin::BI__sync_and_and_fetch_4:
3129 case Builtin::BI__sync_and_and_fetch_8:
3130 case Builtin::BI__sync_and_and_fetch_16:
3131 case Builtin::BI__sync_or_and_fetch:
3132 case Builtin::BI__sync_or_and_fetch_1:
3133 case Builtin::BI__sync_or_and_fetch_2:
3134 case Builtin::BI__sync_or_and_fetch_4:
3135 case Builtin::BI__sync_or_and_fetch_8:
3136 case Builtin::BI__sync_or_and_fetch_16:
3137 case Builtin::BI__sync_xor_and_fetch:
3138 case Builtin::BI__sync_xor_and_fetch_1:
3139 case Builtin::BI__sync_xor_and_fetch_2:
3140 case Builtin::BI__sync_xor_and_fetch_4:
3141 case Builtin::BI__sync_xor_and_fetch_8:
3142 case Builtin::BI__sync_xor_and_fetch_16:
3143 case Builtin::BI__sync_nand_and_fetch:
3144 case Builtin::BI__sync_nand_and_fetch_1:
3145 case Builtin::BI__sync_nand_and_fetch_2:
3146 case Builtin::BI__sync_nand_and_fetch_4:
3147 case Builtin::BI__sync_nand_and_fetch_8:
3148 case Builtin::BI__sync_nand_and_fetch_16:
3149 case Builtin::BI__sync_val_compare_and_swap:
3150 case Builtin::BI__sync_val_compare_and_swap_1:
3151 case Builtin::BI__sync_val_compare_and_swap_2:
3152 case Builtin::BI__sync_val_compare_and_swap_4:
3153 case Builtin::BI__sync_val_compare_and_swap_8:
3154 case Builtin::BI__sync_val_compare_and_swap_16:
3155 case Builtin::BI__sync_bool_compare_and_swap:
3156 case Builtin::BI__sync_bool_compare_and_swap_1:
3157 case Builtin::BI__sync_bool_compare_and_swap_2:
3158 case Builtin::BI__sync_bool_compare_and_swap_4:
3159 case Builtin::BI__sync_bool_compare_and_swap_8:
3160 case Builtin::BI__sync_bool_compare_and_swap_16:
3161 case Builtin::BI__sync_lock_test_and_set:
3162 case Builtin::BI__sync_lock_test_and_set_1:
3163 case Builtin::BI__sync_lock_test_and_set_2:
3164 case Builtin::BI__sync_lock_test_and_set_4:
3165 case Builtin::BI__sync_lock_test_and_set_8:
3166 case Builtin::BI__sync_lock_test_and_set_16:
3167 case Builtin::BI__sync_lock_release:
3168 case Builtin::BI__sync_lock_release_1:
3169 case Builtin::BI__sync_lock_release_2:
3170 case Builtin::BI__sync_lock_release_4:
3171 case Builtin::BI__sync_lock_release_8:
3172 case Builtin::BI__sync_lock_release_16:
3173 case Builtin::BI__sync_swap:
3174 case Builtin::BI__sync_swap_1:
3175 case Builtin::BI__sync_swap_2:
3176 case Builtin::BI__sync_swap_4:
3177 case Builtin::BI__sync_swap_8:
3178 case Builtin::BI__sync_swap_16:
3179 return BuiltinAtomicOverloaded(TheCallResult);
3180 case Builtin::BI__sync_synchronize:
3184 case Builtin::BI__builtin_nontemporal_load:
3185 case Builtin::BI__builtin_nontemporal_store:
3186 return BuiltinNontemporalOverloaded(TheCallResult);
3187 case Builtin::BI__builtin_memcpy_inline: {
3188 clang::Expr *SizeOp = TheCall->
getArg(2);
3200 case Builtin::BI__builtin_memset_inline: {
3201 clang::Expr *SizeOp = TheCall->
getArg(2);
3211#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3212 case Builtin::BI##ID: \
3213 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3214#include "clang/Basic/Builtins.inc"
3215 case Builtin::BI__annotation:
3219 case Builtin::BI__builtin_annotation:
3223 case Builtin::BI__builtin_addressof:
3227 case Builtin::BI__builtin_function_start:
3231 case Builtin::BI__builtin_is_aligned:
3232 case Builtin::BI__builtin_align_up:
3233 case Builtin::BI__builtin_align_down:
3237 case Builtin::BI__builtin_add_overflow:
3238 case Builtin::BI__builtin_sub_overflow:
3239 case Builtin::BI__builtin_mul_overflow:
3243 case Builtin::BI__builtin_operator_new:
3244 case Builtin::BI__builtin_operator_delete: {
3245 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3247 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3250 case Builtin::BI__builtin_dump_struct:
3252 case Builtin::BI__builtin_expect_with_probability: {
3257 const Expr *ProbArg = TheCall->
getArg(2);
3258 SmallVector<PartialDiagnosticAt, 8> Notes;
3259 Expr::EvalResult Eval;
3263 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3270 bool LoseInfo =
false;
3271 Probability.convert(llvm::APFloat::IEEEdouble(),
3272 llvm::RoundingMode::Dynamic, &LoseInfo);
3273 if (!(Probability >= llvm::APFloat(0.0) &&
3274 Probability <= llvm::APFloat(1.0))) {
3281 case Builtin::BI__builtin_preserve_access_index:
3285 case Builtin::BI__builtin_call_with_static_chain:
3289 case Builtin::BI__exception_code:
3290 case Builtin::BI_exception_code:
3292 diag::err_seh___except_block))
3295 case Builtin::BI__exception_info:
3296 case Builtin::BI_exception_info:
3298 diag::err_seh___except_filter))
3301 case Builtin::BI__GetExceptionInfo:
3313 case Builtin::BIaddressof:
3314 case Builtin::BI__addressof:
3315 case Builtin::BIforward:
3316 case Builtin::BIforward_like:
3317 case Builtin::BImove:
3318 case Builtin::BImove_if_noexcept:
3319 case Builtin::BIas_const: {
3327 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3328 BuiltinID == Builtin::BI__addressof;
3330 (ReturnsPointer ?
Result->isAnyPointerType()
3331 :
Result->isReferenceType()) &&
3334 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3340 case Builtin::BI__builtin_ptrauth_strip:
3342 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3344 case Builtin::BI__builtin_ptrauth_sign_constant:
3347 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3350 case Builtin::BI__builtin_ptrauth_auth:
3353 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3355 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3357 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3359 case Builtin::BI__builtin_ptrauth_string_discriminator:
3362 case Builtin::BI__builtin_get_vtable_pointer:
3366 case Builtin::BIread_pipe:
3367 case Builtin::BIwrite_pipe:
3370 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3373 case Builtin::BIreserve_read_pipe:
3374 case Builtin::BIreserve_write_pipe:
3375 case Builtin::BIwork_group_reserve_read_pipe:
3376 case Builtin::BIwork_group_reserve_write_pipe:
3377 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3380 case Builtin::BIsub_group_reserve_read_pipe:
3381 case Builtin::BIsub_group_reserve_write_pipe:
3382 if (
OpenCL().checkSubgroupExt(TheCall) ||
3383 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3386 case Builtin::BIcommit_read_pipe:
3387 case Builtin::BIcommit_write_pipe:
3388 case Builtin::BIwork_group_commit_read_pipe:
3389 case Builtin::BIwork_group_commit_write_pipe:
3390 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3393 case Builtin::BIsub_group_commit_read_pipe:
3394 case Builtin::BIsub_group_commit_write_pipe:
3395 if (
OpenCL().checkSubgroupExt(TheCall) ||
3396 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3399 case Builtin::BIget_pipe_num_packets:
3400 case Builtin::BIget_pipe_max_packets:
3401 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3404 case Builtin::BIto_global:
3405 case Builtin::BIto_local:
3406 case Builtin::BIto_private:
3407 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3411 case Builtin::BIenqueue_kernel:
3412 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3415 case Builtin::BIget_kernel_work_group_size:
3416 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3417 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3420 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3421 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3422 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3425 case Builtin::BI__builtin_os_log_format:
3426 Cleanup.setExprNeedsCleanups(
true);
3428 case Builtin::BI__builtin_os_log_format_buffer_size:
3429 if (BuiltinOSLogFormat(TheCall))
3432 case Builtin::BI__builtin_frame_address:
3433 case Builtin::BI__builtin_return_address: {
3442 Result.Val.getInt() != 0)
3444 << ((BuiltinID == Builtin::BI__builtin_return_address)
3445 ?
"__builtin_return_address"
3446 :
"__builtin_frame_address")
3451 case Builtin::BI__builtin_nondeterministic_value: {
3452 if (BuiltinNonDeterministicValue(TheCall))
3459 case Builtin::BI__builtin_elementwise_abs:
3467 case Builtin::BI__builtin_elementwise_acos:
3468 case Builtin::BI__builtin_elementwise_asin:
3469 case Builtin::BI__builtin_elementwise_atan:
3470 case Builtin::BI__builtin_elementwise_ceil:
3471 case Builtin::BI__builtin_elementwise_cos:
3472 case Builtin::BI__builtin_elementwise_cosh:
3473 case Builtin::BI__builtin_elementwise_exp:
3474 case Builtin::BI__builtin_elementwise_exp2:
3475 case Builtin::BI__builtin_elementwise_exp10:
3476 case Builtin::BI__builtin_elementwise_floor:
3477 case Builtin::BI__builtin_elementwise_log:
3478 case Builtin::BI__builtin_elementwise_log2:
3479 case Builtin::BI__builtin_elementwise_log10:
3480 case Builtin::BI__builtin_elementwise_roundeven:
3481 case Builtin::BI__builtin_elementwise_round:
3482 case Builtin::BI__builtin_elementwise_rint:
3483 case Builtin::BI__builtin_elementwise_nearbyint:
3484 case Builtin::BI__builtin_elementwise_sin:
3485 case Builtin::BI__builtin_elementwise_sinh:
3486 case Builtin::BI__builtin_elementwise_sqrt:
3487 case Builtin::BI__builtin_elementwise_tan:
3488 case Builtin::BI__builtin_elementwise_tanh:
3489 case Builtin::BI__builtin_elementwise_trunc:
3490 case Builtin::BI__builtin_elementwise_canonicalize:
3495 case Builtin::BI__builtin_elementwise_fma:
3500 case Builtin::BI__builtin_elementwise_ldexp: {
3522 const auto *Vec0 = TyA->
getAs<VectorType>();
3523 const auto *Vec1 = TyExp->
getAs<VectorType>();
3524 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3526 if (Arg0Length != Arg1Length) {
3528 diag::err_typecheck_vector_lengths_not_equal)
3542 case Builtin::BI__builtin_elementwise_minnum:
3543 case Builtin::BI__builtin_elementwise_maxnum:
3544 case Builtin::BI__builtin_elementwise_minimum:
3545 case Builtin::BI__builtin_elementwise_maximum:
3546 case Builtin::BI__builtin_elementwise_minimumnum:
3547 case Builtin::BI__builtin_elementwise_maximumnum:
3548 case Builtin::BI__builtin_elementwise_atan2:
3549 case Builtin::BI__builtin_elementwise_fmod:
3550 case Builtin::BI__builtin_elementwise_pow:
3551 if (BuiltinElementwiseMath(TheCall,
3557 case Builtin::BI__builtin_elementwise_add_sat:
3558 case Builtin::BI__builtin_elementwise_sub_sat:
3559 if (BuiltinElementwiseMath(TheCall,
3563 case Builtin::BI__builtin_elementwise_fshl:
3564 case Builtin::BI__builtin_elementwise_fshr:
3569 case Builtin::BI__builtin_elementwise_min:
3570 case Builtin::BI__builtin_elementwise_max: {
3571 if (BuiltinElementwiseMath(TheCall))
3573 Expr *Arg0 = TheCall->
getArg(0);
3574 Expr *Arg1 = TheCall->
getArg(1);
3575 QualType Ty0 = Arg0->
getType();
3576 QualType Ty1 = Arg1->
getType();
3577 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3578 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3581 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3582 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3583 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3586 case Builtin::BI__builtin_elementwise_popcount:
3587 case Builtin::BI__builtin_elementwise_bitreverse:
3592 case Builtin::BI__builtin_elementwise_copysign: {
3601 QualType MagnitudeTy = Magnitude.
get()->
getType();
3614 diag::err_typecheck_call_different_arg_types)
3615 << MagnitudeTy << SignTy;
3623 case Builtin::BI__builtin_elementwise_clzg:
3624 case Builtin::BI__builtin_elementwise_ctzg:
3632 }
else if (BuiltinElementwiseMath(
3636 case Builtin::BI__builtin_reduce_max:
3637 case Builtin::BI__builtin_reduce_min: {
3638 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3641 const Expr *Arg = TheCall->
getArg(0);
3646 ElTy = TyA->getElementType();
3650 if (ElTy.isNull()) {
3660 case Builtin::BI__builtin_reduce_maximum:
3661 case Builtin::BI__builtin_reduce_minimum: {
3662 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3665 const Expr *Arg = TheCall->
getArg(0);
3670 ElTy = TyA->getElementType();
3674 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3687 case Builtin::BI__builtin_reduce_add:
3688 case Builtin::BI__builtin_reduce_mul:
3689 case Builtin::BI__builtin_reduce_xor:
3690 case Builtin::BI__builtin_reduce_or:
3691 case Builtin::BI__builtin_reduce_and: {
3692 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3695 const Expr *Arg = TheCall->
getArg(0);
3709 case Builtin::BI__builtin_reduce_assoc_fadd:
3710 case Builtin::BI__builtin_reduce_in_order_fadd: {
3712 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
3737 diag::err_builtin_invalid_arg_type)
3749 case Builtin::BI__builtin_matrix_transpose:
3750 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3752 case Builtin::BI__builtin_matrix_column_major_load:
3753 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3755 case Builtin::BI__builtin_matrix_column_major_store:
3756 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3758 case Builtin::BI__builtin_verbose_trap:
3763 case Builtin::BI__builtin_get_device_side_mangled_name: {
3764 auto Check = [](CallExpr *TheCall) {
3770 auto *D = DRE->getDecl();
3773 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3774 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3776 if (!Check(TheCall)) {
3778 diag::err_hip_invalid_args_builtin_mangled_name);
3783 case Builtin::BI__builtin_bswapg:
3787 case Builtin::BI__builtin_bitreverseg:
3791 case Builtin::BI__builtin_popcountg:
3795 case Builtin::BI__builtin_clzg:
3796 case Builtin::BI__builtin_ctzg:
3801 case Builtin::BI__builtin_stdc_rotate_left:
3802 case Builtin::BI__builtin_stdc_rotate_right:
3807 case Builtin::BI__builtin_allow_runtime_check: {
3808 Expr *Arg = TheCall->
getArg(0);
3818 case Builtin::BI__builtin_allow_sanitize_check: {
3822 Expr *Arg = TheCall->
getArg(0);
3824 const StringLiteral *SanitizerName =
3826 if (!SanitizerName) {
3832 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
3833 .Cases({
"address",
"thread",
"memory",
"hwaddress",
3834 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
3838 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
3844 case Builtin::BI__builtin_counted_by_ref:
3845 if (BuiltinCountedByRef(TheCall))
3855 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3856 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3857 assert(
Context.getAuxTargetInfo() &&
3858 "Aux Target Builtin, but not an aux target?");
3860 if (CheckTSBuiltinFunctionCall(
3862 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3865 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3871 return TheCallResult;
3886 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3890 diag::err_argument_not_contiguous_bit_field)
3897 bool IsVariadic =
false;
3900 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3901 IsVariadic = BD->isVariadic();
3902 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3903 IsVariadic = OMD->isVariadic();
3910 bool HasImplicitThisParam,
bool IsVariadic,
3914 else if (IsVariadic)
3924 if (HasImplicitThisParam) {
3956 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
3957 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3958 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3959 Expr = ILE->getInit(0);
3969 const Expr *ArgExpr,
3973 S.
PDiag(diag::warn_null_arg)
3979 if (
auto nullability =
type->getNullability())
3990 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3996 llvm::SmallBitVector NonNullArgs;
4002 for (
const auto *Arg : Args)
4009 unsigned IdxAST = Idx.getASTIndex();
4010 if (IdxAST >= Args.size())
4012 if (NonNullArgs.empty())
4013 NonNullArgs.resize(Args.size());
4014 NonNullArgs.set(IdxAST);
4023 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4028 unsigned ParamIndex = 0;
4030 I != E; ++I, ++ParamIndex) {
4033 if (NonNullArgs.empty())
4034 NonNullArgs.resize(Args.size());
4036 NonNullArgs.set(ParamIndex);
4043 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4048 type = blockType->getPointeeType();
4062 if (NonNullArgs.empty())
4063 NonNullArgs.resize(Args.size());
4065 NonNullArgs.set(Index);
4074 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4075 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4076 if (NonNullArgs[ArgIndex])
4082 StringRef ParamName,
QualType ArgTy,
4105 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4106 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4110 if (ArgAlign < ParamAlign)
4111 Diag(Loc, diag::warn_param_mismatched_alignment)
4113 << ParamName << (FDecl !=
nullptr) << FDecl;
4117 const Expr *ThisArg,
4119 if (!FD || Args.empty())
4121 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4122 if (Idx == LifetimeCaptureByAttr::Global ||
4123 Idx == LifetimeCaptureByAttr::Unknown)
4125 if (IsMemberFunction && Idx == 0)
4127 return Args[Idx - IsMemberFunction];
4129 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4134 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4135 for (
int CapturingParamIdx :
Attr->params()) {
4138 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4141 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4149 I + IsMemberFunction);
4151 if (IsMemberFunction) {
4159 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4172 llvm::SmallBitVector CheckedVarArgs;
4174 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4176 CheckedVarArgs.resize(Args.size());
4177 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4182 CheckedVarArgs.resize(Args.size());
4183 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4190 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4194 : isa_and_nonnull<FunctionDecl>(FDecl)
4196 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4200 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4202 if (
const Expr *Arg = Args[ArgIdx]) {
4203 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4210 if (FDecl || Proto) {
4215 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4216 CheckArgumentWithTypeTag(I, Args, Loc);
4222 if (!Proto && FDecl) {
4224 if (isa_and_nonnull<FunctionProtoType>(FT))
4230 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4232 bool IsScalableArg =
false;
4233 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4235 if (
const Expr *Arg = Args[ArgIdx]) {
4239 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4247 IsScalableArg =
true;
4249 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4258 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4259 llvm::StringMap<bool> CallerFeatureMap;
4260 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4261 if (!CallerFeatureMap.contains(
"sme"))
4262 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4263 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4264 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4273 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4275 (IsScalableArg || IsScalableRet)) {
4276 bool IsCalleeStreaming =
4278 bool IsCalleeStreamingCompatible =
4282 if (!IsCalleeStreamingCompatible &&
4286 unsigned VL = LO.VScaleMin * 128;
4287 unsigned SVL = LO.VScaleStreamingMin * 128;
4288 bool IsVLMismatch = VL && SVL && VL != SVL;
4290 auto EmitDiag = [&](
bool IsArg) {
4294 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4295 << IsArg << IsCalleeStreaming << SVL << VL;
4298 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4299 << IsArg << SVL << VL;
4301 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4318 bool CallerHasZAState =
false;
4319 bool CallerHasZT0State =
false;
4321 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4323 CallerHasZAState =
true;
4325 CallerHasZT0State =
true;
4329 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4331 CallerHasZT0State |=
4333 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4339 Diag(Loc, diag::err_sme_za_call_no_za_state);
4342 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4346 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4347 Diag(Loc, diag::note_sme_use_preserves_za);
4352 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4353 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4354 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4355 if (!Arg->isValueDependent()) {
4357 if (Arg->EvaluateAsInt(Align,
Context)) {
4358 const llvm::APSInt &I = Align.
Val.
getInt();
4359 if (!I.isPowerOf2())
4360 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4361 << Arg->getSourceRange();
4364 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4390 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4391 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4393 checkCall(FDecl, Proto,
nullptr, Args,
true,
4402 IsMemberOperatorCall;
4408 Expr *ImplicitThis =
nullptr;
4413 ImplicitThis = Args[0];
4416 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4427 ThisType =
Context.getPointerType(ThisType);
4433 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4451 CheckAbsoluteValueFunction(TheCall, FDecl);
4452 CheckMaxUnsignedZero(TheCall, FDecl);
4453 CheckInfNaNFunction(TheCall, FDecl);
4464 case Builtin::BIstrlcpy:
4465 case Builtin::BIstrlcat:
4466 CheckStrlcpycatArguments(TheCall, FnInfo);
4468 case Builtin::BIstrncat:
4469 CheckStrncatArguments(TheCall, FnInfo);
4471 case Builtin::BIfree:
4472 CheckFreeArguments(TheCall);
4475 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4484 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4485 Ty =
V->getType().getNonReferenceType();
4486 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4487 Ty = F->getType().getNonReferenceType();
4524 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4527 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4529 case AtomicExpr::AO__c11_atomic_init:
4530 case AtomicExpr::AO__opencl_atomic_init:
4531 llvm_unreachable(
"There is no ordering argument for an init");
4533 case AtomicExpr::AO__c11_atomic_load:
4534 case AtomicExpr::AO__opencl_atomic_load:
4535 case AtomicExpr::AO__hip_atomic_load:
4536 case AtomicExpr::AO__atomic_load_n:
4537 case AtomicExpr::AO__atomic_load:
4538 case AtomicExpr::AO__scoped_atomic_load_n:
4539 case AtomicExpr::AO__scoped_atomic_load:
4540 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4541 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4543 case AtomicExpr::AO__c11_atomic_store:
4544 case AtomicExpr::AO__opencl_atomic_store:
4545 case AtomicExpr::AO__hip_atomic_store:
4546 case AtomicExpr::AO__atomic_store:
4547 case AtomicExpr::AO__atomic_store_n:
4548 case AtomicExpr::AO__scoped_atomic_store:
4549 case AtomicExpr::AO__scoped_atomic_store_n:
4550 case AtomicExpr::AO__atomic_clear:
4551 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4552 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4553 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4612 const unsigned NumForm = ClearByte + 1;
4613 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4614 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4622 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4623 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4624 "need to update code for modified forms");
4625 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4626 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4627 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4628 "need to update code for modified C11 atomics");
4629 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4630 Op <= AtomicExpr::AO__opencl_atomic_store;
4631 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4632 Op <= AtomicExpr::AO__hip_atomic_store;
4633 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4634 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4635 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4636 Op <= AtomicExpr::AO__c11_atomic_store) ||
4638 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4639 Op == AtomicExpr::AO__atomic_store_n ||
4640 Op == AtomicExpr::AO__atomic_exchange_n ||
4641 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4642 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4643 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4644 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4645 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4649 enum ArithOpExtraValueType {
4654 unsigned ArithAllows = AOEVT_None;
4657 case AtomicExpr::AO__c11_atomic_init:
4658 case AtomicExpr::AO__opencl_atomic_init:
4662 case AtomicExpr::AO__c11_atomic_load:
4663 case AtomicExpr::AO__opencl_atomic_load:
4664 case AtomicExpr::AO__hip_atomic_load:
4665 case AtomicExpr::AO__atomic_load_n:
4666 case AtomicExpr::AO__scoped_atomic_load_n:
4667 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4671 case AtomicExpr::AO__atomic_load:
4672 case AtomicExpr::AO__scoped_atomic_load:
4673 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4677 case AtomicExpr::AO__c11_atomic_store:
4678 case AtomicExpr::AO__opencl_atomic_store:
4679 case AtomicExpr::AO__hip_atomic_store:
4680 case AtomicExpr::AO__atomic_store:
4681 case AtomicExpr::AO__atomic_store_n:
4682 case AtomicExpr::AO__scoped_atomic_store:
4683 case AtomicExpr::AO__scoped_atomic_store_n:
4684 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4687 case AtomicExpr::AO__atomic_fetch_add:
4688 case AtomicExpr::AO__atomic_fetch_sub:
4689 case AtomicExpr::AO__atomic_add_fetch:
4690 case AtomicExpr::AO__atomic_sub_fetch:
4691 case AtomicExpr::AO__scoped_atomic_fetch_add:
4692 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4693 case AtomicExpr::AO__scoped_atomic_add_fetch:
4694 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4695 case AtomicExpr::AO__c11_atomic_fetch_add:
4696 case AtomicExpr::AO__c11_atomic_fetch_sub:
4697 case AtomicExpr::AO__opencl_atomic_fetch_add:
4698 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4699 case AtomicExpr::AO__hip_atomic_fetch_add:
4700 case AtomicExpr::AO__hip_atomic_fetch_sub:
4701 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4704 case AtomicExpr::AO__atomic_fetch_max:
4705 case AtomicExpr::AO__atomic_fetch_min:
4706 case AtomicExpr::AO__atomic_max_fetch:
4707 case AtomicExpr::AO__atomic_min_fetch:
4708 case AtomicExpr::AO__scoped_atomic_fetch_max:
4709 case AtomicExpr::AO__scoped_atomic_fetch_min:
4710 case AtomicExpr::AO__scoped_atomic_max_fetch:
4711 case AtomicExpr::AO__scoped_atomic_min_fetch:
4712 case AtomicExpr::AO__c11_atomic_fetch_max:
4713 case AtomicExpr::AO__c11_atomic_fetch_min:
4714 case AtomicExpr::AO__opencl_atomic_fetch_max:
4715 case AtomicExpr::AO__opencl_atomic_fetch_min:
4716 case AtomicExpr::AO__hip_atomic_fetch_max:
4717 case AtomicExpr::AO__hip_atomic_fetch_min:
4718 ArithAllows = AOEVT_FP;
4721 case AtomicExpr::AO__c11_atomic_fetch_and:
4722 case AtomicExpr::AO__c11_atomic_fetch_or:
4723 case AtomicExpr::AO__c11_atomic_fetch_xor:
4724 case AtomicExpr::AO__hip_atomic_fetch_and:
4725 case AtomicExpr::AO__hip_atomic_fetch_or:
4726 case AtomicExpr::AO__hip_atomic_fetch_xor:
4727 case AtomicExpr::AO__c11_atomic_fetch_nand:
4728 case AtomicExpr::AO__opencl_atomic_fetch_and:
4729 case AtomicExpr::AO__opencl_atomic_fetch_or:
4730 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4731 case AtomicExpr::AO__atomic_fetch_and:
4732 case AtomicExpr::AO__atomic_fetch_or:
4733 case AtomicExpr::AO__atomic_fetch_xor:
4734 case AtomicExpr::AO__atomic_fetch_nand:
4735 case AtomicExpr::AO__atomic_and_fetch:
4736 case AtomicExpr::AO__atomic_or_fetch:
4737 case AtomicExpr::AO__atomic_xor_fetch:
4738 case AtomicExpr::AO__atomic_nand_fetch:
4739 case AtomicExpr::AO__atomic_fetch_uinc:
4740 case AtomicExpr::AO__atomic_fetch_udec:
4741 case AtomicExpr::AO__scoped_atomic_fetch_and:
4742 case AtomicExpr::AO__scoped_atomic_fetch_or:
4743 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4744 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4745 case AtomicExpr::AO__scoped_atomic_and_fetch:
4746 case AtomicExpr::AO__scoped_atomic_or_fetch:
4747 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4748 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4749 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
4750 case AtomicExpr::AO__scoped_atomic_fetch_udec:
4754 case AtomicExpr::AO__c11_atomic_exchange:
4755 case AtomicExpr::AO__hip_atomic_exchange:
4756 case AtomicExpr::AO__opencl_atomic_exchange:
4757 case AtomicExpr::AO__atomic_exchange_n:
4758 case AtomicExpr::AO__scoped_atomic_exchange_n:
4759 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4763 case AtomicExpr::AO__atomic_exchange:
4764 case AtomicExpr::AO__scoped_atomic_exchange:
4765 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4769 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4770 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4771 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4772 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4773 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4774 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4778 case AtomicExpr::AO__atomic_compare_exchange:
4779 case AtomicExpr::AO__atomic_compare_exchange_n:
4780 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4781 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4782 ArithAllows = AOEVT_Pointer;
4786 case AtomicExpr::AO__atomic_test_and_set:
4787 Form = TestAndSetByte;
4790 case AtomicExpr::AO__atomic_clear:
4795 unsigned AdjustedNumArgs = NumArgs[Form];
4796 if ((IsOpenCL || IsHIP || IsScoped) &&
4797 Op != AtomicExpr::AO__opencl_atomic_init)
4800 if (Args.size() < AdjustedNumArgs) {
4801 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4802 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4805 }
else if (Args.size() > AdjustedNumArgs) {
4806 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4807 diag::err_typecheck_call_too_many_args)
4808 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4814 Expr *Ptr = Args[0];
4819 Ptr = ConvertedPtr.
get();
4822 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4832 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4838 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4844 }
else if (Form != Load && Form != LoadCopy) {
4846 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4852 if (Form != TestAndSetByte && Form != ClearByte) {
4855 diag::err_incomplete_type))
4858 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4859 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4869 pointerType->getPointeeType().getCVRQualifiers());
4879 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4889 auto IsAllowedValueType = [&](
QualType ValType,
4890 unsigned AllowedType) ->
bool {
4891 bool IsX87LongDouble =
4893 &
Context.getTargetInfo().getLongDoubleFormat() ==
4894 &llvm::APFloat::x87DoubleExtended();
4898 return AllowedType & AOEVT_Pointer;
4902 if (IsX87LongDouble)
4906 if (!IsAllowedValueType(ValType, ArithAllows)) {
4907 auto DID = ArithAllows & AOEVT_FP
4908 ? (ArithAllows & AOEVT_Pointer
4909 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4910 : diag::err_atomic_op_needs_atomic_int_or_fp)
4911 : (ArithAllows & AOEVT_Pointer
4912 ? diag::err_atomic_op_needs_atomic_int_or_ptr
4913 : diag::err_atomic_op_needs_atomic_int);
4920 diag::err_incomplete_type)) {
4931 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4947 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4959 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4962 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4968 bool IsPassedByAddress =
false;
4969 if (!IsC11 && !IsHIP && !IsN) {
4971 IsPassedByAddress =
true;
4976 APIOrderedArgs.push_back(Args[0]);
4980 APIOrderedArgs.push_back(Args[1]);
4986 APIOrderedArgs.push_back(Args[2]);
4987 APIOrderedArgs.push_back(Args[1]);
4990 APIOrderedArgs.push_back(Args[2]);
4991 APIOrderedArgs.push_back(Args[3]);
4992 APIOrderedArgs.push_back(Args[1]);
4995 APIOrderedArgs.push_back(Args[2]);
4996 APIOrderedArgs.push_back(Args[4]);
4997 APIOrderedArgs.push_back(Args[1]);
4998 APIOrderedArgs.push_back(Args[3]);
5001 APIOrderedArgs.push_back(Args[2]);
5002 APIOrderedArgs.push_back(Args[4]);
5003 APIOrderedArgs.push_back(Args[5]);
5004 APIOrderedArgs.push_back(Args[1]);
5005 APIOrderedArgs.push_back(Args[3]);
5007 case TestAndSetByte:
5009 APIOrderedArgs.push_back(Args[1]);
5013 APIOrderedArgs.append(Args.begin(), Args.end());
5020 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5022 if (i < NumVals[Form] + 1) {
5035 assert(Form != Load);
5037 Ty =
Context.getPointerDiffType();
5040 else if (Form ==
Copy || Form == Xchg) {
5041 if (IsPassedByAddress) {
5048 Expr *ValArg = APIOrderedArgs[i];
5055 AS = PtrTy->getPointeeType().getAddressSpace();
5064 if (IsPassedByAddress)
5084 APIOrderedArgs[i] = Arg.
get();
5089 SubExprs.push_back(Ptr);
5093 SubExprs.push_back(APIOrderedArgs[1]);
5096 case TestAndSetByte:
5098 SubExprs.push_back(APIOrderedArgs[1]);
5104 SubExprs.push_back(APIOrderedArgs[2]);
5105 SubExprs.push_back(APIOrderedArgs[1]);
5109 SubExprs.push_back(APIOrderedArgs[3]);
5110 SubExprs.push_back(APIOrderedArgs[1]);
5111 SubExprs.push_back(APIOrderedArgs[2]);
5114 SubExprs.push_back(APIOrderedArgs[3]);
5115 SubExprs.push_back(APIOrderedArgs[1]);
5116 SubExprs.push_back(APIOrderedArgs[4]);
5117 SubExprs.push_back(APIOrderedArgs[2]);
5120 SubExprs.push_back(APIOrderedArgs[4]);
5121 SubExprs.push_back(APIOrderedArgs[1]);
5122 SubExprs.push_back(APIOrderedArgs[5]);
5123 SubExprs.push_back(APIOrderedArgs[2]);
5124 SubExprs.push_back(APIOrderedArgs[3]);
5129 if (SubExprs.size() >= 2 && Form !=
Init) {
5130 std::optional<llvm::APSInt>
Success =
5131 SubExprs[1]->getIntegerConstantExpr(
Context);
5133 Diag(SubExprs[1]->getBeginLoc(),
5134 diag::warn_atomic_op_has_invalid_memory_order)
5135 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5136 << SubExprs[1]->getSourceRange();
5138 if (SubExprs.size() >= 5) {
5139 if (std::optional<llvm::APSInt> Failure =
5140 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5141 if (!llvm::is_contained(
5142 {llvm::AtomicOrderingCABI::relaxed,
5143 llvm::AtomicOrderingCABI::consume,
5144 llvm::AtomicOrderingCABI::acquire,
5145 llvm::AtomicOrderingCABI::seq_cst},
5146 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
5147 Diag(SubExprs[3]->getBeginLoc(),
5148 diag::warn_atomic_op_has_invalid_memory_order)
5149 << 2 << SubExprs[3]->getSourceRange();
5156 auto *
Scope = Args[Args.size() - 1];
5157 if (std::optional<llvm::APSInt>
Result =
5159 if (!ScopeModel->isValid(
Result->getZExtValue()))
5160 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5161 <<
Scope->getSourceRange();
5163 SubExprs.push_back(
Scope);
5169 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5170 Op == AtomicExpr::AO__c11_atomic_store ||
5171 Op == AtomicExpr::AO__opencl_atomic_load ||
5172 Op == AtomicExpr::AO__hip_atomic_load ||
5173 Op == AtomicExpr::AO__opencl_atomic_store ||
5174 Op == AtomicExpr::AO__hip_atomic_store) &&
5175 Context.AtomicUsesUnsupportedLibcall(AE))
5177 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5178 Op == AtomicExpr::AO__opencl_atomic_load ||
5179 Op == AtomicExpr::AO__hip_atomic_load)
5184 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5200 assert(Fn &&
"builtin call without direct callee!");
5216 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5223 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5225 <<
Callee->getSourceRange();
5234 Expr *FirstArg = TheCall->
getArg(0);
5238 FirstArg = FirstArgResult.
get();
5239 TheCall->
setArg(0, FirstArg);
5251 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5258 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5288 QualType ResultType = ValType;
5293#define BUILTIN_ROW(x) \
5294 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5295 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5297 static const unsigned BuiltinIndices[][5] = {
5322 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5323 case 1: SizeIndex = 0;
break;
5324 case 2: SizeIndex = 1;
break;
5325 case 4: SizeIndex = 2;
break;
5326 case 8: SizeIndex = 3;
break;
5327 case 16: SizeIndex = 4;
break;
5339 unsigned BuiltinIndex, NumFixed = 1;
5340 bool WarnAboutSemanticsChange =
false;
5341 switch (BuiltinID) {
5342 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5343 case Builtin::BI__sync_fetch_and_add:
5344 case Builtin::BI__sync_fetch_and_add_1:
5345 case Builtin::BI__sync_fetch_and_add_2:
5346 case Builtin::BI__sync_fetch_and_add_4:
5347 case Builtin::BI__sync_fetch_and_add_8:
5348 case Builtin::BI__sync_fetch_and_add_16:
5352 case Builtin::BI__sync_fetch_and_sub:
5353 case Builtin::BI__sync_fetch_and_sub_1:
5354 case Builtin::BI__sync_fetch_and_sub_2:
5355 case Builtin::BI__sync_fetch_and_sub_4:
5356 case Builtin::BI__sync_fetch_and_sub_8:
5357 case Builtin::BI__sync_fetch_and_sub_16:
5361 case Builtin::BI__sync_fetch_and_or:
5362 case Builtin::BI__sync_fetch_and_or_1:
5363 case Builtin::BI__sync_fetch_and_or_2:
5364 case Builtin::BI__sync_fetch_and_or_4:
5365 case Builtin::BI__sync_fetch_and_or_8:
5366 case Builtin::BI__sync_fetch_and_or_16:
5370 case Builtin::BI__sync_fetch_and_and:
5371 case Builtin::BI__sync_fetch_and_and_1:
5372 case Builtin::BI__sync_fetch_and_and_2:
5373 case Builtin::BI__sync_fetch_and_and_4:
5374 case Builtin::BI__sync_fetch_and_and_8:
5375 case Builtin::BI__sync_fetch_and_and_16:
5379 case Builtin::BI__sync_fetch_and_xor:
5380 case Builtin::BI__sync_fetch_and_xor_1:
5381 case Builtin::BI__sync_fetch_and_xor_2:
5382 case Builtin::BI__sync_fetch_and_xor_4:
5383 case Builtin::BI__sync_fetch_and_xor_8:
5384 case Builtin::BI__sync_fetch_and_xor_16:
5388 case Builtin::BI__sync_fetch_and_nand:
5389 case Builtin::BI__sync_fetch_and_nand_1:
5390 case Builtin::BI__sync_fetch_and_nand_2:
5391 case Builtin::BI__sync_fetch_and_nand_4:
5392 case Builtin::BI__sync_fetch_and_nand_8:
5393 case Builtin::BI__sync_fetch_and_nand_16:
5395 WarnAboutSemanticsChange =
true;
5398 case Builtin::BI__sync_add_and_fetch:
5399 case Builtin::BI__sync_add_and_fetch_1:
5400 case Builtin::BI__sync_add_and_fetch_2:
5401 case Builtin::BI__sync_add_and_fetch_4:
5402 case Builtin::BI__sync_add_and_fetch_8:
5403 case Builtin::BI__sync_add_and_fetch_16:
5407 case Builtin::BI__sync_sub_and_fetch:
5408 case Builtin::BI__sync_sub_and_fetch_1:
5409 case Builtin::BI__sync_sub_and_fetch_2:
5410 case Builtin::BI__sync_sub_and_fetch_4:
5411 case Builtin::BI__sync_sub_and_fetch_8:
5412 case Builtin::BI__sync_sub_and_fetch_16:
5416 case Builtin::BI__sync_and_and_fetch:
5417 case Builtin::BI__sync_and_and_fetch_1:
5418 case Builtin::BI__sync_and_and_fetch_2:
5419 case Builtin::BI__sync_and_and_fetch_4:
5420 case Builtin::BI__sync_and_and_fetch_8:
5421 case Builtin::BI__sync_and_and_fetch_16:
5425 case Builtin::BI__sync_or_and_fetch:
5426 case Builtin::BI__sync_or_and_fetch_1:
5427 case Builtin::BI__sync_or_and_fetch_2:
5428 case Builtin::BI__sync_or_and_fetch_4:
5429 case Builtin::BI__sync_or_and_fetch_8:
5430 case Builtin::BI__sync_or_and_fetch_16:
5434 case Builtin::BI__sync_xor_and_fetch:
5435 case Builtin::BI__sync_xor_and_fetch_1:
5436 case Builtin::BI__sync_xor_and_fetch_2:
5437 case Builtin::BI__sync_xor_and_fetch_4:
5438 case Builtin::BI__sync_xor_and_fetch_8:
5439 case Builtin::BI__sync_xor_and_fetch_16:
5443 case Builtin::BI__sync_nand_and_fetch:
5444 case Builtin::BI__sync_nand_and_fetch_1:
5445 case Builtin::BI__sync_nand_and_fetch_2:
5446 case Builtin::BI__sync_nand_and_fetch_4:
5447 case Builtin::BI__sync_nand_and_fetch_8:
5448 case Builtin::BI__sync_nand_and_fetch_16:
5450 WarnAboutSemanticsChange =
true;
5453 case Builtin::BI__sync_val_compare_and_swap:
5454 case Builtin::BI__sync_val_compare_and_swap_1:
5455 case Builtin::BI__sync_val_compare_and_swap_2:
5456 case Builtin::BI__sync_val_compare_and_swap_4:
5457 case Builtin::BI__sync_val_compare_and_swap_8:
5458 case Builtin::BI__sync_val_compare_and_swap_16:
5463 case Builtin::BI__sync_bool_compare_and_swap:
5464 case Builtin::BI__sync_bool_compare_and_swap_1:
5465 case Builtin::BI__sync_bool_compare_and_swap_2:
5466 case Builtin::BI__sync_bool_compare_and_swap_4:
5467 case Builtin::BI__sync_bool_compare_and_swap_8:
5468 case Builtin::BI__sync_bool_compare_and_swap_16:
5474 case Builtin::BI__sync_lock_test_and_set:
5475 case Builtin::BI__sync_lock_test_and_set_1:
5476 case Builtin::BI__sync_lock_test_and_set_2:
5477 case Builtin::BI__sync_lock_test_and_set_4:
5478 case Builtin::BI__sync_lock_test_and_set_8:
5479 case Builtin::BI__sync_lock_test_and_set_16:
5483 case Builtin::BI__sync_lock_release:
5484 case Builtin::BI__sync_lock_release_1:
5485 case Builtin::BI__sync_lock_release_2:
5486 case Builtin::BI__sync_lock_release_4:
5487 case Builtin::BI__sync_lock_release_8:
5488 case Builtin::BI__sync_lock_release_16:
5494 case Builtin::BI__sync_swap:
5495 case Builtin::BI__sync_swap_1:
5496 case Builtin::BI__sync_swap_2:
5497 case Builtin::BI__sync_swap_4:
5498 case Builtin::BI__sync_swap_8:
5499 case Builtin::BI__sync_swap_16:
5507 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5508 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5509 <<
Callee->getSourceRange();
5513 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5514 <<
Callee->getSourceRange();
5516 if (WarnAboutSemanticsChange) {
5517 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5518 <<
Callee->getSourceRange();
5523 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5524 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5525 FunctionDecl *NewBuiltinDecl;
5526 if (NewBuiltinID == BuiltinID)
5527 NewBuiltinDecl = FDecl;
5530 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5533 assert(Res.getFoundDecl());
5534 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5535 if (!NewBuiltinDecl)
5542 for (
unsigned i = 0; i != NumFixed; ++i) {
5571 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5573 CK_BuiltinFnToFnPtr);
5584 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5585 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5586 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5590 return TheCallResult;
5594 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5599 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5600 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5601 "Unexpected nontemporal load/store builtin!");
5602 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5603 unsigned numArgs = isStore ? 2 : 1;
5613 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5619 PointerArg = PointerArgResult.
get();
5620 TheCall->
setArg(numArgs - 1, PointerArg);
5624 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5637 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5644 return TheCallResult;
5656 return TheCallResult;
5663 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5665 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5666 Literal = ObjcLiteral->getString();
5670 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5677 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5678 InitializedEntity Entity =
5688 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5689 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5690 TT.getArch() == llvm::Triple::aarch64_32);
5691 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5692 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5693 if (IsX64 || IsAArch64) {
5700 return S.
Diag(Fn->getBeginLoc(),
5701 diag::err_ms_va_start_used_in_sysv_function);
5708 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5709 return S.
Diag(Fn->getBeginLoc(),
5710 diag::err_va_start_used_in_wrong_abi_function)
5711 << !IsWindowsOrUEFI;
5717 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5725 bool IsVariadic =
false;
5728 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5729 IsVariadic =
Block->isVariadic();
5730 Params =
Block->parameters();
5731 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5734 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5735 IsVariadic = MD->isVariadic();
5737 Params = MD->parameters();
5740 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5744 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5749 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5754 *LastParam = Params.empty() ?
nullptr : Params.back();
5759bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5764 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5788 ParmVarDecl *LastParam;
5799 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5801 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5806 if (std::optional<llvm::APSInt> Val =
5808 Val &&
LangOpts.C23 && *Val == 0 &&
5809 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5810 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5817 SourceLocation ParamLoc;
5818 bool IsCRegister =
false;
5819 bool SecondArgIsLastNonVariadicArgument =
false;
5820 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5821 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5822 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5825 ParamLoc = PV->getLocation();
5831 if (!SecondArgIsLastNonVariadicArgument)
5833 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5834 else if (IsCRegister ||
Type->isReferenceType() ||
5835 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5838 if (!Context.isPromotableIntegerType(Type))
5840 const auto *ED = Type->getAsEnumDecl();
5843 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5845 unsigned Reason = 0;
5846 if (
Type->isReferenceType()) Reason = 1;
5847 else if (IsCRegister) Reason = 2;
5848 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5849 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5856 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5876 if (
Call->getNumArgs() < 3)
5878 diag::err_typecheck_call_too_few_args_at_least)
5879 << 0 << 3 <<
Call->getNumArgs()
5895 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5898 const QualType &ConstCharPtrTy =
5900 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5902 << Arg1->
getType() << ConstCharPtrTy << 1
5905 << 2 << Arg1->
getType() << ConstCharPtrTy;
5907 const QualType SizeTy =
Context.getSizeType();
5912 << Arg2->
getType() << SizeTy << 1
5915 << 3 << Arg2->
getType() << SizeTy;
5920bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5924 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5952 diag::err_typecheck_call_invalid_ordered_compare)
5960bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5961 unsigned BuiltinID) {
5966 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5967 BuiltinID == Builtin::BI__builtin_isinf ||
5968 BuiltinID == Builtin::BI__builtin_isinf_sign))
5972 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5973 BuiltinID == Builtin::BI__builtin_isunordered))
5977 bool IsFPClass = NumArgs == 2;
5980 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5984 for (
unsigned i = 0; i < FPArgNo; ++i) {
5985 Expr *Arg = TheCall->
getArg(i);
5998 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6006 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
6011 OrigArg = Res.
get();
6017 OrigArg = Res.
get();
6019 TheCall->
setArg(FPArgNo, OrigArg);
6021 QualType VectorResultTy;
6022 QualType ElementTy = OrigArg->
getType();
6027 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6033 diag::err_typecheck_call_invalid_unary_fp)
6045 if (!VectorResultTy.
isNull())
6046 ResultTy = VectorResultTy;
6055bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6060 for (
unsigned I = 0; I != 2; ++I) {
6061 Expr *Arg = TheCall->
getArg(I);
6071 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6086 Expr *Real = TheCall->
getArg(0);
6087 Expr *Imag = TheCall->
getArg(1);
6090 diag::err_typecheck_call_different_arg_types)
6105 diag::err_typecheck_call_too_few_args_at_least)
6106 << 0 << 2 << NumArgs
6113 unsigned NumElements = 0;
6128 unsigned NumResElements = NumArgs - 2;
6137 diag::err_vec_builtin_incompatible_vector)
6142 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6144 diag::err_vec_builtin_incompatible_vector)
6149 }
else if (NumElements != NumResElements) {
6152 ?
Context.getExtVectorType(EltType, NumResElements)
6153 :
Context.getVectorType(EltType, NumResElements,
6158 for (
unsigned I = 2; I != NumArgs; ++I) {
6166 diag::err_shufflevector_nonconstant_argument)
6172 else if (
Result->getActiveBits() > 64 ||
6173 Result->getZExtValue() >= NumElements * 2)
6175 diag::err_shufflevector_argument_too_large)
6200 diag::err_convertvector_non_vector)
6203 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6205 <<
"__builtin_convertvector");
6210 if (SrcElts != DstElts)
6212 diag::err_convertvector_incompatible_vector)
6220bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6225 diag::err_typecheck_call_too_many_args_at_most)
6226 << 0 << 3 << NumArgs << 0
6231 for (
unsigned i = 1; i != NumArgs; ++i)
6238bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6239 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6240 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6250 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6260bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6261 Expr *Arg = TheCall->
getArg(0);
6272bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6274 Expr *Arg = TheCall->
getArg(1);
6278 if (
const auto *UE =
6280 if (UE->getKind() == UETT_AlignOf ||
6281 UE->getKind() == UETT_PreferredAlignOf)
6287 if (!
Result.isPowerOf2())
6288 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6295 if (
Result > std::numeric_limits<int32_t>::max())
6303bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6308 Expr *FirstArg = TheCall->
getArg(0);
6314 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6318 TheCall->
setArg(0, FirstArgResult.
get());
6322 Expr *SecondArg = TheCall->
getArg(1);
6330 if (!
Result.isPowerOf2())
6331 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6343 Expr *ThirdArg = TheCall->
getArg(2);
6346 TheCall->
setArg(2, ThirdArg);
6352bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6353 unsigned BuiltinID =
6355 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6358 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6359 if (NumArgs < NumRequiredArgs) {
6360 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6361 << 0 << NumRequiredArgs << NumArgs
6364 if (NumArgs >= NumRequiredArgs + 0x100) {
6366 diag::err_typecheck_call_too_many_args_at_most)
6367 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6378 if (Arg.isInvalid())
6380 TheCall->
setArg(i, Arg.get());
6385 unsigned FormatIdx = i;
6395 unsigned FirstDataArg = i;
6396 while (i < NumArgs) {
6414 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6416 bool Success = CheckFormatArguments(
6419 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6443 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6452 int High,
bool RangeIsError) {
6466 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6474 PDiag(diag::warn_argument_invalid_range)
6517 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6522 if (
Value.isNegative())
6533 if ((
Value & 0xFF) != 0)
6558 Result.setIsUnsigned(
true);
6563 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6583 Result.setIsUnsigned(
true);
6591 diag::err_argument_not_shifted_byte_or_xxff)
6595bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6596 if (!Context.getTargetInfo().hasSjLjLowering())
6597 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6608 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6614bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6615 if (!Context.getTargetInfo().hasSjLjLowering())
6616 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6621bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6636 diag::err_builtin_counted_by_ref_invalid_arg)
6641 diag::err_builtin_counted_by_ref_has_side_effects)
6644 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6646 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6651 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6658 QualType MemberTy = ME->getMemberDecl()->getType();
6661 diag::err_builtin_counted_by_ref_invalid_arg)
6665 diag::err_builtin_counted_by_ref_invalid_arg)
6675bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6677 const CallExpr *CE =
6686 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6691 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6696 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6700 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6704 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6714class UncoveredArgHandler {
6715 enum {
Unknown = -1, AllCovered = -2 };
6717 signed FirstUncoveredArg =
Unknown;
6718 SmallVector<const Expr *, 4> DiagnosticExprs;
6721 UncoveredArgHandler() =
default;
6723 bool hasUncoveredArg()
const {
6724 return (FirstUncoveredArg >= 0);
6727 unsigned getUncoveredArg()
const {
6728 assert(hasUncoveredArg() &&
"no uncovered argument");
6729 return FirstUncoveredArg;
6732 void setAllCovered() {
6735 DiagnosticExprs.clear();
6736 FirstUncoveredArg = AllCovered;
6739 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6740 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6743 if (FirstUncoveredArg == AllCovered)
6748 if (NewFirstUncoveredArg == FirstUncoveredArg)
6749 DiagnosticExprs.push_back(StrExpr);
6750 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6751 DiagnosticExprs.clear();
6752 DiagnosticExprs.push_back(StrExpr);
6753 FirstUncoveredArg = NewFirstUncoveredArg;
6757 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6760enum StringLiteralCheckType {
6762 SLCT_UncheckedLiteral,
6770 bool AddendIsRight) {
6771 unsigned BitWidth = Offset.getBitWidth();
6772 unsigned AddendBitWidth = Addend.getBitWidth();
6774 if (Addend.isUnsigned()) {
6775 Addend = Addend.zext(++AddendBitWidth);
6776 Addend.setIsSigned(
true);
6779 if (AddendBitWidth > BitWidth) {
6780 Offset = Offset.sext(AddendBitWidth);
6781 BitWidth = AddendBitWidth;
6782 }
else if (BitWidth > AddendBitWidth) {
6783 Addend = Addend.sext(BitWidth);
6787 llvm::APSInt ResOffset = Offset;
6788 if (BinOpKind == BO_Add)
6789 ResOffset = Offset.sadd_ov(Addend, Ov);
6791 assert(AddendIsRight && BinOpKind == BO_Sub &&
6792 "operator must be add or sub with addend on the right");
6793 ResOffset = Offset.ssub_ov(Addend, Ov);
6799 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6800 "index (intermediate) result too big");
6801 Offset = Offset.sext(2 * BitWidth);
6802 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6806 Offset = std::move(ResOffset);
6814class FormatStringLiteral {
6815 const StringLiteral *FExpr;
6819 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6820 : FExpr(fexpr), Offset(Offset) {}
6822 const StringLiteral *getFormatString()
const {
return FExpr; }
6824 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6826 unsigned getByteLength()
const {
6827 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6830 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6837 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6838 bool isWide()
const {
return FExpr->
isWide(); }
6839 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6840 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6841 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6842 bool isPascal()
const {
return FExpr->
isPascal(); }
6844 SourceLocation getLocationOfByte(
6845 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6846 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6847 unsigned *StartTokenByteOffset =
nullptr)
const {
6849 StartToken, StartTokenByteOffset);
6852 SourceLocation getBeginLoc() const LLVM_READONLY {
6856 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6862 Sema &S,
const FormatStringLiteral *FExpr,
6867 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6868 bool IgnoreStringsWithoutSpecifiers);
6877static StringLiteralCheckType
6883 llvm::SmallBitVector &CheckedVarArgs,
6884 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
6885 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
6886 bool IgnoreStringsWithoutSpecifiers =
false) {
6888 return SLCT_NotALiteral;
6890 assert(Offset.isSigned() &&
"invalid offset");
6893 return SLCT_NotALiteral;
6902 return SLCT_UncheckedLiteral;
6905 case Stmt::InitListExprClass:
6909 format_idx, firstDataArg,
Type, CallType,
6910 false, CheckedVarArgs,
6911 UncoveredArg, Offset, CallerFormatParamIdx,
6912 IgnoreStringsWithoutSpecifiers);
6914 return SLCT_NotALiteral;
6915 case Stmt::BinaryConditionalOperatorClass:
6916 case Stmt::ConditionalOperatorClass: {
6925 bool CheckLeft =
true, CheckRight =
true;
6928 if (
C->getCond()->EvaluateAsBooleanCondition(
6940 StringLiteralCheckType Left;
6942 Left = SLCT_UncheckedLiteral;
6945 Args, APK, format_idx, firstDataArg,
Type,
6946 CallType, InFunctionCall, CheckedVarArgs,
6947 UncoveredArg, Offset, CallerFormatParamIdx,
6948 IgnoreStringsWithoutSpecifiers);
6949 if (Left == SLCT_NotALiteral || !CheckRight) {
6955 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6956 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6957 UncoveredArg, Offset, CallerFormatParamIdx,
6958 IgnoreStringsWithoutSpecifiers);
6960 return (CheckLeft && Left < Right) ? Left : Right;
6963 case Stmt::ImplicitCastExprClass:
6967 case Stmt::OpaqueValueExprClass:
6972 return SLCT_NotALiteral;
6974 case Stmt::PredefinedExprClass:
6978 return SLCT_UncheckedLiteral;
6980 case Stmt::DeclRefExprClass: {
6986 bool isConstant =
false;
6990 isConstant = AT->getElementType().isConstant(S.
Context);
6992 isConstant = T.isConstant(S.
Context) &&
6993 PT->getPointeeType().isConstant(S.
Context);
6994 }
else if (T->isObjCObjectPointerType()) {
6997 isConstant = T.isConstant(S.
Context);
7001 if (
const Expr *
Init = VD->getAnyInitializer()) {
7004 if (InitList->isStringLiteralInit())
7005 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7008 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7009 firstDataArg,
Type, CallType,
false,
7010 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7061 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7062 if (CallerFormatParamIdx)
7063 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7064 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7065 for (
const auto *PVFormatMatches :
7066 D->specific_attrs<FormatMatchesAttr>()) {
7071 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7075 S.
Diag(Args[format_idx]->getBeginLoc(),
7076 diag::warn_format_string_type_incompatible)
7077 << PVFormatMatches->getType()->getName()
7079 if (!InFunctionCall) {
7080 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7081 diag::note_format_string_defined);
7083 return SLCT_UncheckedLiteral;
7086 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7087 Args, APK, format_idx, firstDataArg,
Type, CallType,
7088 false, CheckedVarArgs, UncoveredArg,
7089 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7093 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7096 PVFormat->getFirstArg(), &CallerFSI))
7098 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7102 S.
Diag(Args[format_idx]->getBeginLoc(),
7103 diag::warn_format_string_type_incompatible)
7104 << PVFormat->getType()->getName()
7106 if (!InFunctionCall) {
7109 return SLCT_UncheckedLiteral;
7122 return SLCT_UncheckedLiteral;
7130 return SLCT_NotALiteral;
7133 case Stmt::CallExprClass:
7134 case Stmt::CXXMemberCallExprClass: {
7138 StringLiteralCheckType CommonResult;
7139 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7140 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7142 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7143 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7144 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7146 CommonResult = Result;
7151 return CommonResult;
7153 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7155 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7156 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7159 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7160 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7161 UncoveredArg, Offset, CallerFormatParamIdx,
7162 IgnoreStringsWithoutSpecifiers);
7168 format_idx, firstDataArg,
Type, CallType,
7169 false, CheckedVarArgs,
7170 UncoveredArg, Offset, CallerFormatParamIdx,
7171 IgnoreStringsWithoutSpecifiers);
7172 return SLCT_NotALiteral;
7174 case Stmt::ObjCMessageExprClass: {
7176 if (
const auto *MD = ME->getMethodDecl()) {
7177 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7186 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7188 MD->getSelector().isKeywordSelector(
7189 {
"localizedStringForKey",
"value",
"table"})) {
7190 IgnoreStringsWithoutSpecifiers =
true;
7193 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7195 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7196 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7197 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7201 return SLCT_NotALiteral;
7203 case Stmt::ObjCStringLiteralClass:
7204 case Stmt::StringLiteralClass: {
7213 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7216 return SLCT_NotALiteral;
7218 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7220 format_idx, firstDataArg,
Type, InFunctionCall,
7221 CallType, CheckedVarArgs, UncoveredArg,
7222 IgnoreStringsWithoutSpecifiers);
7223 return SLCT_CheckedLiteral;
7226 return SLCT_NotALiteral;
7228 case Stmt::BinaryOperatorClass: {
7242 if (LIsInt != RIsInt) {
7246 if (BinOpKind == BO_Add) {
7259 return SLCT_NotALiteral;
7261 case Stmt::UnaryOperatorClass: {
7263 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7264 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7266 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7276 return SLCT_NotALiteral;
7280 return SLCT_NotALiteral;
7291 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7292 if (isa_and_nonnull<StringLiteral>(LVE))
7313 return "freebsd_kprintf";
7322 return llvm::StringSwitch<FormatStringType>(Flavor)
7324 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7329 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7345bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7349 llvm::SmallBitVector &CheckedVarArgs) {
7350 FormatStringInfo FSI;
7354 return CheckFormatArguments(
7355 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7360bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7364 llvm::SmallBitVector &CheckedVarArgs) {
7365 FormatStringInfo FSI;
7369 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7370 Format->getFormatString(), FSI.FormatIdx,
7372 CallType, Loc, Range, CheckedVarArgs);
7380 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7393 unsigned CallerArgumentIndexOffset =
7396 unsigned FirstArgumentIndex = -1;
7406 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7407 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7411 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7412 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7414 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7417 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7418 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7421 FirstArgumentIndex =
7422 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7428 ? (NumCallerParams + CallerArgumentIndexOffset)
7433 if (!ReferenceFormatString)
7439 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7441 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7443 std::string
Attr, Fixit;
7444 llvm::raw_string_ostream AttrOS(
Attr);
7446 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7447 << FirstArgumentIndex <<
")";
7449 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7451 AttrOS.write_escaped(ReferenceFormatString->
getString());
7455 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7466 llvm::raw_string_ostream IS(Fixit);
7474 if (LO.C23 || LO.CPlusPlus11)
7475 IS <<
"[[gnu::" <<
Attr <<
"]]";
7476 else if (LO.ObjC || LO.GNUMode)
7477 IS <<
"__attribute__((" <<
Attr <<
"))";
7491 Caller->
addAttr(FormatAttr::CreateImplicit(
7493 FormatStringIndex, FirstArgumentIndex));
7495 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7497 FormatStringIndex, ReferenceFormatString));
7501 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7513 unsigned format_idx,
unsigned firstDataArg,
7517 llvm::SmallBitVector &CheckedVarArgs) {
7519 if (format_idx >= Args.size()) {
7520 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7524 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7538 UncoveredArgHandler UncoveredArg;
7539 std::optional<unsigned> CallerParamIdx;
7541 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7542 firstDataArg,
Type, CallType,
7543 true, CheckedVarArgs, UncoveredArg,
7544 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7547 if (UncoveredArg.hasUncoveredArg()) {
7548 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7549 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7550 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7553 if (CT != SLCT_NotALiteral)
7555 return CT == SLCT_CheckedLiteral;
7561 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7567 this, Args, APK, ReferenceFormatString, format_idx,
7568 firstDataArg,
Type, *CallerParamIdx, Loc))
7578 if (Args.size() == firstDataArg) {
7579 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7587 Diag(FormatLoc, diag::note_format_security_fixit)
7591 Diag(FormatLoc, diag::note_format_security_fixit)
7596 Diag(FormatLoc, diag::warn_format_nonliteral)
7607 const FormatStringLiteral *FExpr;
7608 const Expr *OrigFormatExpr;
7610 const unsigned FirstDataArg;
7611 const unsigned NumDataArgs;
7614 ArrayRef<const Expr *> Args;
7616 llvm::SmallBitVector CoveredArgs;
7617 bool usesPositionalArgs =
false;
7618 bool atFirstArg =
true;
7619 bool inFunctionCall;
7621 llvm::SmallBitVector &CheckedVarArgs;
7622 UncoveredArgHandler &UncoveredArg;
7625 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7627 unsigned firstDataArg,
unsigned numDataArgs,
7629 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7631 llvm::SmallBitVector &CheckedVarArgs,
7632 UncoveredArgHandler &UncoveredArg)
7633 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7634 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7635 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7636 inFunctionCall(inFunctionCall), CallType(callType),
7637 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7638 CoveredArgs.resize(numDataArgs);
7639 CoveredArgs.reset();
7642 bool HasFormatArguments()
const {
7647 void DoneProcessing();
7649 void HandleIncompleteSpecifier(
const char *startSpecifier,
7650 unsigned specifierLen)
override;
7652 void HandleInvalidLengthModifier(
7653 const analyze_format_string::FormatSpecifier &FS,
7654 const analyze_format_string::ConversionSpecifier &CS,
7655 const char *startSpecifier,
unsigned specifierLen,
7658 void HandleNonStandardLengthModifier(
7659 const analyze_format_string::FormatSpecifier &FS,
7660 const char *startSpecifier,
unsigned specifierLen);
7662 void HandleNonStandardConversionSpecifier(
7663 const analyze_format_string::ConversionSpecifier &CS,
7664 const char *startSpecifier,
unsigned specifierLen);
7666 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7668 void HandleInvalidPosition(
const char *startSpecifier,
7669 unsigned specifierLen,
7672 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7674 void HandleNullChar(
const char *nullCharacter)
override;
7676 template <
typename Range>
7678 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7679 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7680 bool IsStringLocation, Range StringRange,
7681 ArrayRef<FixItHint> Fixit = {});
7684 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7685 const char *startSpec,
7686 unsigned specifierLen,
7687 const char *csStart,
unsigned csLen);
7689 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7690 const char *startSpec,
7691 unsigned specifierLen);
7693 SourceRange getFormatStringRange();
7694 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7695 unsigned specifierLen);
7696 SourceLocation getLocationOfByte(
const char *x);
7698 const Expr *getDataArg(
unsigned i)
const;
7700 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7701 const analyze_format_string::ConversionSpecifier &CS,
7702 const char *startSpecifier,
unsigned specifierLen,
7705 template <
typename Range>
7706 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7707 bool IsStringLocation, Range StringRange,
7708 ArrayRef<FixItHint> Fixit = {});
7713SourceRange CheckFormatHandler::getFormatStringRange() {
7718getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7720 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7728SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7733void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7734 unsigned specifierLen){
7735 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7736 getLocationOfByte(startSpecifier),
7738 getSpecifierRange(startSpecifier, specifierLen));
7741void CheckFormatHandler::HandleInvalidLengthModifier(
7744 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7756 getSpecifierRange(startSpecifier, specifierLen));
7758 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7759 << FixedLM->toString()
7764 if (DiagID == diag::warn_format_nonsensical_length)
7770 getSpecifierRange(startSpecifier, specifierLen),
7775void CheckFormatHandler::HandleNonStandardLengthModifier(
7777 const char *startSpecifier,
unsigned specifierLen) {
7786 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7790 getSpecifierRange(startSpecifier, specifierLen));
7792 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7793 << FixedLM->toString()
7797 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7801 getSpecifierRange(startSpecifier, specifierLen));
7805void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7807 const char *startSpecifier,
unsigned specifierLen) {
7813 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7817 getSpecifierRange(startSpecifier, specifierLen));
7820 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7821 << FixedCS->toString()
7824 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7828 getSpecifierRange(startSpecifier, specifierLen));
7832void CheckFormatHandler::HandlePosition(
const char *startPos,
7835 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7836 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7837 getLocationOfByte(startPos),
7839 getSpecifierRange(startPos, posLen));
7842void CheckFormatHandler::HandleInvalidPosition(
7843 const char *startSpecifier,
unsigned specifierLen,
7846 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7847 EmitFormatDiagnostic(
7848 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7849 getLocationOfByte(startSpecifier),
true,
7850 getSpecifierRange(startSpecifier, specifierLen));
7853void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7857 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7858 getLocationOfByte(startPos),
7860 getSpecifierRange(startPos, posLen));
7863void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7866 EmitFormatDiagnostic(
7867 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7868 getLocationOfByte(nullCharacter),
true,
7869 getFormatStringRange());
7875const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7876 return Args[FirstDataArg + i];
7879void CheckFormatHandler::DoneProcessing() {
7882 if (HasFormatArguments()) {
7885 signed notCoveredArg = CoveredArgs.find_first();
7886 if (notCoveredArg >= 0) {
7887 assert((
unsigned)notCoveredArg < NumDataArgs);
7888 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7890 UncoveredArg.setAllCovered();
7895void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7896 const Expr *ArgExpr) {
7897 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7909 for (
auto E : DiagnosticExprs)
7912 CheckFormatHandler::EmitFormatDiagnostic(
7913 S, IsFunctionCall, DiagnosticExprs[0],
7919CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7921 const char *startSpec,
7922 unsigned specifierLen,
7923 const char *csStart,
7925 bool keepGoing =
true;
7926 if (argIndex < NumDataArgs) {
7929 CoveredArgs.set(argIndex);
7945 std::string CodePointStr;
7946 if (!llvm::sys::locale::isPrint(*csStart)) {
7947 llvm::UTF32 CodePoint;
7948 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7949 const llvm::UTF8 *E =
7950 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7951 llvm::ConversionResult
Result =
7952 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7954 if (
Result != llvm::conversionOK) {
7955 unsigned char FirstChar = *csStart;
7956 CodePoint = (llvm::UTF32)FirstChar;
7959 llvm::raw_string_ostream
OS(CodePointStr);
7960 if (CodePoint < 256)
7961 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7962 else if (CodePoint <= 0xFFFF)
7963 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7965 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7969 EmitFormatDiagnostic(
7970 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7971 true, getSpecifierRange(startSpec, specifierLen));
7977CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7978 const char *startSpec,
7979 unsigned specifierLen) {
7980 EmitFormatDiagnostic(
7981 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7982 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7986CheckFormatHandler::CheckNumArgs(
7989 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7991 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7993 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7994 << (argIndex+1) << NumDataArgs)
7995 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7996 EmitFormatDiagnostic(
7997 PDiag, getLocationOfByte(CS.
getStart()),
true,
7998 getSpecifierRange(startSpecifier, specifierLen));
8002 UncoveredArg.setAllCovered();
8008template<
typename Range>
8011 bool IsStringLocation,
8014 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
8015 Loc, IsStringLocation, StringRange, FixIt);
8045template <
typename Range>
8046void CheckFormatHandler::EmitFormatDiagnostic(
8047 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8050 if (InFunctionCall) {
8055 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8059 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8060 diag::note_format_string_defined);
8062 Note << StringRange;
8071class CheckPrintfHandler :
public CheckFormatHandler {
8073 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8075 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8077 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8079 llvm::SmallBitVector &CheckedVarArgs,
8080 UncoveredArgHandler &UncoveredArg)
8081 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8082 numDataArgs, beg, APK, Args, formatIdx,
8083 inFunctionCall, CallType, CheckedVarArgs,
8086 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8089 bool allowsObjCArg()
const {
8090 return FSType == FormatStringType::NSString ||
8091 FSType == FormatStringType::OSLog ||
8092 FSType == FormatStringType::OSTrace;
8095 bool HandleInvalidPrintfConversionSpecifier(
8096 const analyze_printf::PrintfSpecifier &FS,
8097 const char *startSpecifier,
8098 unsigned specifierLen)
override;
8100 void handleInvalidMaskType(StringRef MaskType)
override;
8102 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8103 const char *startSpecifier,
unsigned specifierLen,
8104 const TargetInfo &
Target)
override;
8105 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8106 const char *StartSpecifier,
8107 unsigned SpecifierLen,
8110 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
8111 const char *startSpecifier,
unsigned specifierLen);
8112 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8113 const analyze_printf::OptionalAmount &Amt,
8115 const char *startSpecifier,
unsigned specifierLen);
8116 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8117 const analyze_printf::OptionalFlag &flag,
8118 const char *startSpecifier,
unsigned specifierLen);
8119 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8120 const analyze_printf::OptionalFlag &ignoredFlag,
8121 const analyze_printf::OptionalFlag &flag,
8122 const char *startSpecifier,
unsigned specifierLen);
8123 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
8126 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8127 unsigned flagLen)
override;
8129 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8130 unsigned flagLen)
override;
8133 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8134 const char *flagsEnd,
8135 const char *conversionPosition)
override;
8140class EquatableFormatArgument {
8142 enum SpecifierSensitivity :
unsigned {
8149 enum FormatArgumentRole :
unsigned {
8157 analyze_format_string::ArgType ArgType;
8159 StringRef SpecifierLetter;
8160 CharSourceRange
Range;
8161 SourceLocation ElementLoc;
8162 FormatArgumentRole
Role : 2;
8163 SpecifierSensitivity Sensitivity : 2;
8164 unsigned Position : 14;
8165 unsigned ModifierFor : 14;
8167 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8168 bool InFunctionCall)
const;
8171 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8173 StringRef SpecifierLetter,
8174 analyze_format_string::ArgType ArgType,
8175 FormatArgumentRole
Role,
8176 SpecifierSensitivity Sensitivity,
unsigned Position,
8177 unsigned ModifierFor)
8178 : ArgType(ArgType), LengthMod(LengthMod),
8179 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8180 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8181 ModifierFor(ModifierFor) {}
8183 unsigned getPosition()
const {
return Position; }
8184 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8186 analyze_format_string::LengthModifier getLengthModifier()
const {
8187 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
8189 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8191 std::string buildFormatSpecifier()
const {
8193 llvm::raw_string_ostream(result)
8194 << getLengthModifier().toString() << SpecifierLetter;
8198 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8199 const Expr *FmtExpr,
bool InFunctionCall)
const;
8203class DecomposePrintfHandler :
public CheckPrintfHandler {
8204 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8207 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8208 const Expr *origFormatExpr,
8210 unsigned numDataArgs,
bool isObjC,
const char *beg,
8212 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8214 llvm::SmallBitVector &CheckedVarArgs,
8215 UncoveredArgHandler &UncoveredArg,
8216 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8217 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8218 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8219 inFunctionCall, CallType, CheckedVarArgs,
8221 Specs(Specs), HadError(
false) {}
8225 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8227 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8229 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8230 const char *startSpecifier,
8231 unsigned specifierLen,
8232 const TargetInfo &
Target)
override;
8237bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8239 unsigned specifierLen) {
8243 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
8245 startSpecifier, specifierLen,
8249void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8250 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8258 return T->isRecordType() || T->isComplexType();
8261bool CheckPrintfHandler::HandleAmount(
8263 const char *startSpecifier,
unsigned specifierLen) {
8265 if (HasFormatArguments()) {
8267 if (argIndex >= NumDataArgs) {
8268 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8272 getSpecifierRange(startSpecifier, specifierLen));
8282 CoveredArgs.set(argIndex);
8283 const Expr *Arg = getDataArg(argIndex);
8294 ? diag::err_printf_asterisk_wrong_type
8295 : diag::warn_printf_asterisk_wrong_type;
8296 EmitFormatDiagnostic(S.
PDiag(DiagID)
8301 getSpecifierRange(startSpecifier, specifierLen));
8311void CheckPrintfHandler::HandleInvalidAmount(
8315 const char *startSpecifier,
8316 unsigned specifierLen) {
8326 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8330 getSpecifierRange(startSpecifier, specifierLen),
8336 const char *startSpecifier,
8337 unsigned specifierLen) {
8341 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
8345 getSpecifierRange(startSpecifier, specifierLen),
8350void CheckPrintfHandler::HandleIgnoredFlag(
8354 const char *startSpecifier,
8355 unsigned specifierLen) {
8357 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8361 getSpecifierRange(startSpecifier, specifierLen),
8363 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8366void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8369 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
8370 getLocationOfByte(startFlag),
8372 getSpecifierRange(startFlag, flagLen));
8375void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8378 auto Range = getSpecifierRange(startFlag, flagLen);
8379 StringRef flag(startFlag, flagLen);
8380 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8381 getLocationOfByte(startFlag),
8386void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8387 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
8389 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8390 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8391 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8392 getLocationOfByte(conversionPosition),
8398 const Expr *FmtExpr,
8399 bool InFunctionCall)
const {
8400 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8401 ElementLoc,
true, Range);
8404bool EquatableFormatArgument::VerifyCompatible(
8405 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8406 bool InFunctionCall)
const {
8411 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8412 FmtExpr, InFunctionCall);
8413 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8417 if (
Role != FAR_Data) {
8418 if (ModifierFor !=
Other.ModifierFor) {
8421 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8422 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8423 FmtExpr, InFunctionCall);
8424 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8430 bool HadError =
false;
8431 if (Sensitivity !=
Other.Sensitivity) {
8434 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8435 << Sensitivity <<
Other.Sensitivity,
8436 FmtExpr, InFunctionCall);
8437 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8438 << 0 <<
Other.Range;
8441 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8445 case MK::MatchPromotion:
8449 case MK::NoMatchTypeConfusion:
8450 case MK::NoMatchPromotionTypeConfusion:
8452 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8453 << buildFormatSpecifier()
8454 <<
Other.buildFormatSpecifier(),
8455 FmtExpr, InFunctionCall);
8456 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8457 << 0 <<
Other.Range;
8460 case MK::NoMatchPedantic:
8462 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8463 << buildFormatSpecifier()
8464 <<
Other.buildFormatSpecifier(),
8465 FmtExpr, InFunctionCall);
8466 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8467 << 0 <<
Other.Range;
8470 case MK::NoMatchSignedness:
8472 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8473 << buildFormatSpecifier()
8474 <<
Other.buildFormatSpecifier(),
8475 FmtExpr, InFunctionCall);
8476 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8477 << 0 <<
Other.Range;
8483bool DecomposePrintfHandler::GetSpecifiers(
8484 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8487 StringRef
Data = FSL->getString();
8488 const char *Str =
Data.data();
8489 llvm::SmallBitVector BV;
8490 UncoveredArgHandler UA;
8491 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8492 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8504 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8505 const EquatableFormatArgument &B) {
8506 return A.getPosition() < B.getPosition();
8511bool DecomposePrintfHandler::HandlePrintfSpecifier(
8514 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8529 const unsigned Unset = ~0;
8530 unsigned FieldWidthIndex = Unset;
8531 unsigned PrecisionIndex = Unset;
8535 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8536 FieldWidthIndex = Specs.size();
8537 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8538 getLocationOfByte(FieldWidth.getStart()),
8540 FieldWidth.getArgType(S.
Context),
8541 EquatableFormatArgument::FAR_FieldWidth,
8542 EquatableFormatArgument::SS_None,
8543 FieldWidth.usesPositionalArg()
8544 ? FieldWidth.getPositionalArgIndex() - 1
8550 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8551 PrecisionIndex = Specs.size();
8553 getSpecifierRange(startSpecifier, specifierLen),
8554 getLocationOfByte(Precision.getStart()),
8556 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8557 EquatableFormatArgument::SS_None,
8558 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8564 unsigned SpecIndex =
8566 if (FieldWidthIndex != Unset)
8567 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8568 if (PrecisionIndex != Unset)
8569 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8571 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8573 Sensitivity = EquatableFormatArgument::SS_Private;
8575 Sensitivity = EquatableFormatArgument::SS_Public;
8577 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8579 Sensitivity = EquatableFormatArgument::SS_None;
8582 getSpecifierRange(startSpecifier, specifierLen),
8585 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8590 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8595 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8596 SpecIndex + 1, SpecIndex);
8604template<
typename MemberKind>
8622 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8637 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8639 if ((*MI)->getMinRequiredArguments() == 0)
8647bool CheckPrintfHandler::checkForCStrMembers(
8654 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8657 if (
Method->getMinRequiredArguments() == 0 &&
8670bool CheckPrintfHandler::HandlePrintfSpecifier(
8684 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8685 startSpecifier, specifierLen);
8693 startSpecifier, specifierLen)) {
8698 startSpecifier, specifierLen)) {
8702 if (!CS.consumesDataArgument()) {
8710 if (argIndex < NumDataArgs) {
8714 CoveredArgs.set(argIndex);
8721 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8724 if (HasFormatArguments()) {
8726 CoveredArgs.set(argIndex + 1);
8729 const Expr *Ex = getDataArg(argIndex);
8733 : ArgType::CPointerTy;
8735 EmitFormatDiagnostic(
8736 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8740 getSpecifierRange(startSpecifier, specifierLen));
8743 Ex = getDataArg(argIndex + 1);
8746 EmitFormatDiagnostic(
8747 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8751 getSpecifierRange(startSpecifier, specifierLen));
8758 if (!allowsObjCArg() && CS.isObjCArg()) {
8759 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8766 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8773 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8774 getLocationOfByte(CS.getStart()),
8776 getSpecifierRange(startSpecifier, specifierLen));
8786 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8793 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8797 getSpecifierRange(startSpecifier, specifierLen));
8800 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8804 getSpecifierRange(startSpecifier, specifierLen));
8808 const llvm::Triple &Triple =
Target.getTriple();
8810 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8811 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8812 getLocationOfByte(CS.getStart()),
8814 getSpecifierRange(startSpecifier, specifierLen));
8820 startSpecifier, specifierLen);
8826 startSpecifier, specifierLen);
8832 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8833 getLocationOfByte(startSpecifier),
8835 getSpecifierRange(startSpecifier, specifierLen));
8844 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8846 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8855 startSpecifier, specifierLen);
8858 startSpecifier, specifierLen);
8863 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8864 diag::warn_format_nonsensical_length);
8866 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8868 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8869 diag::warn_format_non_standard_conversion_spec);
8872 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8875 if (!HasFormatArguments())
8878 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8881 const Expr *Arg = getDataArg(argIndex);
8885 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8897 case Stmt::ArraySubscriptExprClass:
8898 case Stmt::CallExprClass:
8899 case Stmt::CharacterLiteralClass:
8900 case Stmt::CXXBoolLiteralExprClass:
8901 case Stmt::DeclRefExprClass:
8902 case Stmt::FloatingLiteralClass:
8903 case Stmt::IntegerLiteralClass:
8904 case Stmt::MemberExprClass:
8905 case Stmt::ObjCArrayLiteralClass:
8906 case Stmt::ObjCBoolLiteralExprClass:
8907 case Stmt::ObjCBoxedExprClass:
8908 case Stmt::ObjCDictionaryLiteralClass:
8909 case Stmt::ObjCEncodeExprClass:
8910 case Stmt::ObjCIvarRefExprClass:
8911 case Stmt::ObjCMessageExprClass:
8912 case Stmt::ObjCPropertyRefExprClass:
8913 case Stmt::ObjCStringLiteralClass:
8914 case Stmt::ObjCSubscriptRefExprClass:
8915 case Stmt::ParenExprClass:
8916 case Stmt::StringLiteralClass:
8917 case Stmt::UnaryOperatorClass:
8924static std::pair<QualType, StringRef>
8931 StringRef Name = UserTy->getDecl()->getName();
8932 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8933 .Case(
"CFIndex", Context.getNSIntegerType())
8934 .Case(
"NSInteger", Context.getNSIntegerType())
8935 .Case(
"NSUInteger", Context.getNSUIntegerType())
8936 .Case(
"SInt32", Context.IntTy)
8937 .Case(
"UInt32", Context.UnsignedIntTy)
8941 return std::make_pair(CastTy, Name);
8943 TyTy = UserTy->desugar();
8947 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8949 PE->getSubExpr()->getType(),
8958 StringRef TrueName, FalseName;
8960 std::tie(TrueTy, TrueName) =
8962 CO->getTrueExpr()->getType(),
8964 std::tie(FalseTy, FalseName) =
8966 CO->getFalseExpr()->getType(),
8967 CO->getFalseExpr());
8969 if (TrueTy == FalseTy)
8970 return std::make_pair(TrueTy, TrueName);
8971 else if (TrueTy.
isNull())
8972 return std::make_pair(FalseTy, FalseName);
8973 else if (FalseTy.
isNull())
8974 return std::make_pair(TrueTy, TrueName);
8977 return std::make_pair(
QualType(), StringRef());
8996 From = VecTy->getElementType();
8998 To = VecTy->getElementType();
9009 diag::warn_format_conversion_argument_type_mismatch_signedness,
9013 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9022 const char *StartSpecifier,
9023 unsigned SpecifierLen,
9035 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9036 ExprTy = TET->getUnderlyingExpr()->getType();
9039 if (
const OverflowBehaviorType *OBT =
9041 ExprTy = OBT->getUnderlyingType();
9055 getSpecifierRange(StartSpecifier, SpecifierLen);
9057 llvm::raw_svector_ostream os(FSString);
9059 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9070 getSpecifierRange(StartSpecifier, SpecifierLen);
9071 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9081 if (
Match == ArgType::Match)
9085 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9094 E = ICE->getSubExpr();
9104 if (OrigMatch == ArgType::NoMatchSignedness &&
9105 ImplicitMatch != ArgType::NoMatchSignedness)
9112 if (ImplicitMatch == ArgType::Match)
9130 if (
Match == ArgType::MatchPromotion)
9134 if (
Match == ArgType::MatchPromotion) {
9138 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9139 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9143 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9144 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9145 Match = ImplicitMatch;
9146 assert(
Match != ArgType::MatchPromotion);
9149 bool IsEnum =
false;
9150 bool IsScopedEnum =
false;
9153 IntendedTy = ED->getIntegerType();
9154 if (!ED->isScoped()) {
9155 ExprTy = IntendedTy;
9160 IsScopedEnum =
true;
9167 if (isObjCContext() &&
9178 const llvm::APInt &
V = IL->getValue();
9188 if (TD->getUnderlyingType() == IntendedTy)
9198 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
9206 if (!IsScopedEnum &&
9207 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9211 IntendedTy = CastTy;
9212 ShouldNotPrintDirectly =
true;
9217 PrintfSpecifier fixedFS = FS;
9224 llvm::raw_svector_ostream os(buf);
9227 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9229 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9235 llvm_unreachable(
"expected non-matching");
9237 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9240 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9243 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9246 Diag = diag::warn_format_conversion_argument_type_mismatch;
9267 llvm::raw_svector_ostream CastFix(CastBuf);
9268 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9270 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9276 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9281 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9303 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9309 Name = TypedefTy->getDecl()->getName();
9313 ? diag::warn_format_argument_needs_cast_pedantic
9314 : diag::warn_format_argument_needs_cast;
9315 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9326 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9327 : diag::warn_format_conversion_argument_type_mismatch;
9329 EmitFormatDiagnostic(
9341 bool EmitTypeMismatch =
false;
9350 llvm_unreachable(
"expected non-matching");
9352 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9355 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9358 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9362 ? diag::err_format_conversion_argument_type_mismatch
9363 : diag::warn_format_conversion_argument_type_mismatch;
9367 EmitFormatDiagnostic(
9376 EmitTypeMismatch =
true;
9378 EmitFormatDiagnostic(
9379 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9380 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9384 checkForCStrMembers(AT, E);
9390 EmitTypeMismatch =
true;
9392 EmitFormatDiagnostic(
9393 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9394 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9407 if (EmitTypeMismatch) {
9413 EmitFormatDiagnostic(
9414 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9420 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9421 "format string specifier index out of range");
9422 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9432class CheckScanfHandler :
public CheckFormatHandler {
9434 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9436 unsigned firstDataArg,
unsigned numDataArgs,
9438 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9440 llvm::SmallBitVector &CheckedVarArgs,
9441 UncoveredArgHandler &UncoveredArg)
9442 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9443 numDataArgs, beg, APK, Args, formatIdx,
9444 inFunctionCall, CallType, CheckedVarArgs,
9447 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9448 const char *startSpecifier,
9449 unsigned specifierLen)
override;
9451 bool HandleInvalidScanfConversionSpecifier(
9452 const analyze_scanf::ScanfSpecifier &FS,
9453 const char *startSpecifier,
9454 unsigned specifierLen)
override;
9456 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9461void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9463 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9464 getLocationOfByte(end),
true,
9465 getSpecifierRange(start, end - start));
9468bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9470 const char *startSpecifier,
9471 unsigned specifierLen) {
9475 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9477 startSpecifier, specifierLen,
9481bool CheckScanfHandler::HandleScanfSpecifier(
9483 const char *startSpecifier,
9484 unsigned specifierLen) {
9498 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9499 startSpecifier, specifierLen);
9510 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9525 if (argIndex < NumDataArgs) {
9529 CoveredArgs.set(argIndex);
9535 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9536 diag::warn_format_nonsensical_length);
9538 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9540 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9541 diag::warn_format_non_standard_conversion_spec);
9544 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9547 if (!HasFormatArguments())
9550 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9554 const Expr *Ex = getDataArg(argIndex);
9572 ScanfSpecifier fixedFS = FS;
9577 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9579 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9580 : diag::warn_format_conversion_argument_type_mismatch;
9585 llvm::raw_svector_ostream os(buf);
9588 EmitFormatDiagnostic(
9593 getSpecifierRange(startSpecifier, specifierLen),
9595 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9602 getSpecifierRange(startSpecifier, specifierLen));
9612 const Expr *FmtExpr,
bool InFunctionCall) {
9613 bool HadError =
false;
9614 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9615 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9616 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9628 for (; FmtIter < FmtEnd; ++FmtIter) {
9632 if (FmtIter->getPosition() < RefIter->getPosition())
9636 if (FmtIter->getPosition() > RefIter->getPosition())
9640 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9644 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9645 return Arg.getPosition() != RefIter->getPosition();
9649 if (FmtIter < FmtEnd) {
9650 CheckFormatHandler::EmitFormatDiagnostic(
9651 S, InFunctionCall, FmtExpr,
9652 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9653 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9654 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9655 }
else if (RefIter < RefEnd) {
9656 CheckFormatHandler::EmitFormatDiagnostic(
9657 S, InFunctionCall, FmtExpr,
9658 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9661 << 1 << RefIter->getSourceRange();
9667 Sema &S,
const FormatStringLiteral *FExpr,
9672 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9673 bool IgnoreStringsWithoutSpecifiers) {
9675 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9676 CheckFormatHandler::EmitFormatDiagnostic(
9677 S, inFunctionCall, Args[format_idx],
9678 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9684 StringRef StrRef = FExpr->getString();
9685 const char *Str = StrRef.data();
9689 assert(T &&
"String literal not of constant array type!");
9690 size_t TypeSize = T->getZExtSize();
9691 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9692 const unsigned numDataArgs = Args.size() - firstDataArg;
9694 if (IgnoreStringsWithoutSpecifiers &&
9701 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9702 CheckFormatHandler::EmitFormatDiagnostic(
9703 S, inFunctionCall, Args[format_idx],
9704 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9705 FExpr->getBeginLoc(),
9711 if (StrLen == 0 && numDataArgs > 0) {
9712 CheckFormatHandler::EmitFormatDiagnostic(
9713 S, inFunctionCall, Args[format_idx],
9714 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9725 if (ReferenceFormatString ==
nullptr) {
9726 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9727 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9728 inFunctionCall, CallType, CheckedVarArgs,
9738 Type, ReferenceFormatString, FExpr->getFormatString(),
9739 inFunctionCall ?
nullptr : Args[format_idx]);
9742 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9743 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9744 CallType, CheckedVarArgs, UncoveredArg);
9764 FormatStringLiteral RefLit = AuthoritativeFormatString;
9765 FormatStringLiteral TestLit = TestedFormatString;
9767 bool DiagAtStringLiteral;
9768 if (FunctionCallArg) {
9769 Arg = FunctionCallArg;
9770 DiagAtStringLiteral =
false;
9772 Arg = TestedFormatString;
9773 DiagAtStringLiteral =
true;
9775 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9776 AuthoritativeFormatString,
Type,
9777 IsObjC,
true, RefArgs) &&
9778 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9779 DiagAtStringLiteral, FmtArgs)) {
9781 TestedFormatString, FmtArgs, Arg,
9782 DiagAtStringLiteral);
9795 FormatStringLiteral RefLit = Str;
9799 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9808 bool HadError =
false;
9809 auto Iter = Args.begin();
9810 auto End = Args.end();
9811 while (Iter != End) {
9812 const auto &FirstInGroup = *Iter;
9814 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9816 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9825 const char *Str = StrRef.data();
9828 assert(T &&
"String literal not of constant array type!");
9829 size_t TypeSize = T->getZExtSize();
9830 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9841 switch (AbsFunction) {
9845 case Builtin::BI__builtin_abs:
9846 return Builtin::BI__builtin_labs;
9847 case Builtin::BI__builtin_labs:
9848 return Builtin::BI__builtin_llabs;
9849 case Builtin::BI__builtin_llabs:
9852 case Builtin::BI__builtin_fabsf:
9853 return Builtin::BI__builtin_fabs;
9854 case Builtin::BI__builtin_fabs:
9855 return Builtin::BI__builtin_fabsl;
9856 case Builtin::BI__builtin_fabsl:
9859 case Builtin::BI__builtin_cabsf:
9860 return Builtin::BI__builtin_cabs;
9861 case Builtin::BI__builtin_cabs:
9862 return Builtin::BI__builtin_cabsl;
9863 case Builtin::BI__builtin_cabsl:
9866 case Builtin::BIabs:
9867 return Builtin::BIlabs;
9868 case Builtin::BIlabs:
9869 return Builtin::BIllabs;
9870 case Builtin::BIllabs:
9873 case Builtin::BIfabsf:
9874 return Builtin::BIfabs;
9875 case Builtin::BIfabs:
9876 return Builtin::BIfabsl;
9877 case Builtin::BIfabsl:
9880 case Builtin::BIcabsf:
9881 return Builtin::BIcabs;
9882 case Builtin::BIcabs:
9883 return Builtin::BIcabsl;
9884 case Builtin::BIcabsl:
9913 unsigned AbsFunctionKind) {
9914 unsigned BestKind = 0;
9915 uint64_t ArgSize = Context.getTypeSize(ArgType);
9916 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9919 if (Context.getTypeSize(ParamType) >= ArgSize) {
9922 else if (Context.hasSameType(ParamType, ArgType)) {
9938 if (T->isIntegralOrEnumerationType())
9940 if (T->isRealFloatingType())
9942 if (T->isAnyComplexType())
9945 llvm_unreachable(
"Type not integer, floating, or complex");
9952 switch (ValueKind) {
9957 case Builtin::BI__builtin_fabsf:
9958 case Builtin::BI__builtin_fabs:
9959 case Builtin::BI__builtin_fabsl:
9960 case Builtin::BI__builtin_cabsf:
9961 case Builtin::BI__builtin_cabs:
9962 case Builtin::BI__builtin_cabsl:
9963 return Builtin::BI__builtin_abs;
9964 case Builtin::BIfabsf:
9965 case Builtin::BIfabs:
9966 case Builtin::BIfabsl:
9967 case Builtin::BIcabsf:
9968 case Builtin::BIcabs:
9969 case Builtin::BIcabsl:
9970 return Builtin::BIabs;
9976 case Builtin::BI__builtin_abs:
9977 case Builtin::BI__builtin_labs:
9978 case Builtin::BI__builtin_llabs:
9979 case Builtin::BI__builtin_cabsf:
9980 case Builtin::BI__builtin_cabs:
9981 case Builtin::BI__builtin_cabsl:
9982 return Builtin::BI__builtin_fabsf;
9983 case Builtin::BIabs:
9984 case Builtin::BIlabs:
9985 case Builtin::BIllabs:
9986 case Builtin::BIcabsf:
9987 case Builtin::BIcabs:
9988 case Builtin::BIcabsl:
9989 return Builtin::BIfabsf;
9995 case Builtin::BI__builtin_abs:
9996 case Builtin::BI__builtin_labs:
9997 case Builtin::BI__builtin_llabs:
9998 case Builtin::BI__builtin_fabsf:
9999 case Builtin::BI__builtin_fabs:
10000 case Builtin::BI__builtin_fabsl:
10001 return Builtin::BI__builtin_cabsf;
10002 case Builtin::BIabs:
10003 case Builtin::BIlabs:
10004 case Builtin::BIllabs:
10005 case Builtin::BIfabsf:
10006 case Builtin::BIfabs:
10007 case Builtin::BIfabsl:
10008 return Builtin::BIcabsf;
10011 llvm_unreachable(
"Unable to convert function");
10022 case Builtin::BI__builtin_abs:
10023 case Builtin::BI__builtin_fabs:
10024 case Builtin::BI__builtin_fabsf:
10025 case Builtin::BI__builtin_fabsl:
10026 case Builtin::BI__builtin_labs:
10027 case Builtin::BI__builtin_llabs:
10028 case Builtin::BI__builtin_cabs:
10029 case Builtin::BI__builtin_cabsf:
10030 case Builtin::BI__builtin_cabsl:
10031 case Builtin::BIabs:
10032 case Builtin::BIlabs:
10033 case Builtin::BIllabs:
10034 case Builtin::BIfabs:
10035 case Builtin::BIfabsf:
10036 case Builtin::BIfabsl:
10037 case Builtin::BIcabs:
10038 case Builtin::BIcabsf:
10039 case Builtin::BIcabsl:
10042 llvm_unreachable(
"Unknown Builtin type");
10048 unsigned AbsKind,
QualType ArgType) {
10049 bool EmitHeaderHint =
true;
10050 const char *HeaderName =
nullptr;
10051 std::string FunctionName;
10052 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10053 FunctionName =
"std::abs";
10054 if (ArgType->isIntegralOrEnumerationType()) {
10055 HeaderName =
"cstdlib";
10056 }
else if (ArgType->isRealFloatingType()) {
10057 HeaderName =
"cmath";
10059 llvm_unreachable(
"Invalid Type");
10068 for (
const auto *I : R) {
10071 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10073 FDecl = dyn_cast<FunctionDecl>(I);
10088 EmitHeaderHint =
false;
10106 EmitHeaderHint =
false;
10110 }
else if (!R.
empty()) {
10116 S.
Diag(Loc, diag::note_replace_abs_function)
10122 if (!EmitHeaderHint)
10125 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10129template <std::
size_t StrLen>
10131 const char (&Str)[StrLen]) {
10144 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10145 return llvm::is_contained(names, calleeName);
10150 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10151 "__builtin_nanf16",
"__builtin_nanf128"});
10153 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10154 "__builtin_inff16",
"__builtin_inff128"});
10156 llvm_unreachable(
"unknown MathCheck");
10160 if (FDecl->
getName() !=
"infinity")
10163 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10165 if (RDecl->
getName() !=
"numeric_limits")
10182 if (FPO.getNoHonorNaNs() &&
10185 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10186 << 1 << 0 <<
Call->getSourceRange();
10190 if (FPO.getNoHonorInfs() &&
10194 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10195 << 0 << 0 <<
Call->getSourceRange();
10199void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10201 if (
Call->getNumArgs() != 1)
10206 if (AbsKind == 0 && !IsStdAbs)
10209 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10210 QualType ParamType =
Call->getArg(0)->getType();
10215 std::string FunctionName =
10216 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10217 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10218 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10247 if (ArgValueKind == ParamValueKind) {
10248 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10252 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10253 << FDecl << ArgType << ParamType;
10255 if (NewAbsKind == 0)
10259 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10268 if (NewAbsKind == 0)
10271 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10272 << FDecl << ParamValueKind << ArgValueKind;
10275 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10281 if (!
Call || !FDecl)
return;
10285 if (
Call->getExprLoc().isMacroID())
return;
10288 if (
Call->getNumArgs() != 2)
return;
10291 if (!ArgList)
return;
10292 if (ArgList->size() != 1)
return;
10295 const auto& TA = ArgList->
get(0);
10297 QualType ArgType = TA.getAsType();
10301 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10302 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10303 if (!MTE)
return false;
10304 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10305 if (!
Num)
return false;
10306 if (
Num->getValue() != 0)
return false;
10310 const Expr *FirstArg =
Call->getArg(0);
10311 const Expr *SecondArg =
Call->getArg(1);
10312 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10313 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10316 if (IsFirstArgZero == IsSecondArgZero)
return;
10321 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10323 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10324 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10327 SourceRange RemovalRange;
10328 if (IsFirstArgZero) {
10329 RemovalRange = SourceRange(FirstRange.
getBegin(),
10336 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10351 const auto *Size = dyn_cast<BinaryOperator>(E);
10356 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10360 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10361 << SizeRange << FnName;
10362 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10367 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10378 bool &IsContained) {
10381 IsContained =
false;
10394 for (
auto *FD : RD->
fields()) {
10398 IsContained =
true;
10399 return ContainedRD;
10407 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10408 if (Unary->getKind() == UETT_SizeOf)
10417 if (!
SizeOf->isArgumentType())
10418 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10425 return SizeOf->getTypeOfArgument();
10431struct SearchNonTrivialToInitializeField
10434 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10436 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10439 SourceLocation SL) {
10440 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10441 asDerived().visitArray(PDIK, AT, SL);
10445 Super::visitWithKind(PDIK, FT, SL);
10448 void visitARCStrong(QualType FT, SourceLocation SL) {
10451 void visitARCWeak(QualType FT, SourceLocation SL) {
10454 void visitStruct(QualType FT, SourceLocation SL) {
10459 const ArrayType *AT, SourceLocation SL) {
10460 visit(getContext().getBaseElementType(AT), SL);
10462 void visitTrivial(QualType FT, SourceLocation SL) {}
10464 static void diag(QualType RT,
const Expr *E, Sema &S) {
10465 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10474struct SearchNonTrivialToCopyField
10476 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10478 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10481 SourceLocation SL) {
10482 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10483 asDerived().visitArray(PCK, AT, SL);
10487 Super::visitWithKind(PCK, FT, SL);
10490 void visitARCStrong(QualType FT, SourceLocation SL) {
10493 void visitARCWeak(QualType FT, SourceLocation SL) {
10496 void visitPtrAuth(QualType FT, SourceLocation SL) {
10499 void visitStruct(QualType FT, SourceLocation SL) {
10504 SourceLocation SL) {
10505 visit(getContext().getBaseElementType(AT), SL);
10508 SourceLocation SL) {}
10509 void visitTrivial(QualType FT, SourceLocation SL) {}
10510 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10512 static void diag(QualType RT,
const Expr *E, Sema &S) {
10513 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10528 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10529 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10553 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10555 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10556 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10562 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10565 const Expr *SizeArg =
10566 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10568 auto isLiteralZero = [](
const Expr *E) {
10578 if (isLiteralZero(SizeArg) &&
10585 if (BId == Builtin::BIbzero ||
10588 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10589 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10590 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10591 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10592 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10600 if (BId == Builtin::BImemset &&
10604 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10605 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10610void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10617 unsigned ExpectedNumArgs =
10618 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10619 if (
Call->getNumArgs() < ExpectedNumArgs)
10622 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10623 BId == Builtin::BIstrndup ? 1 : 2);
10625 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10629 Call->getBeginLoc(),
Call->getRParenLoc()))
10641 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10642 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10645 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10649 QualType DestTy = Dest->
getType();
10650 QualType PointeeTy;
10651 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10663 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
10669 if (SizeOfArgTy != QualType()) {
10671 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10673 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10674 << FnName << SizeOfArgTy << ArgIdx
10681 PointeeTy = DestTy;
10684 if (PointeeTy == QualType())
10689 if (
const CXXRecordDecl *ContainedRD =
10692 unsigned OperationType = 0;
10693 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10696 if (ArgIdx != 0 || IsCmp) {
10697 if (BId == Builtin::BImemcpy)
10699 else if(BId == Builtin::BImemmove)
10706 PDiag(diag::warn_dyn_class_memaccess)
10707 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10708 << IsContained << ContainedRD << OperationType
10709 <<
Call->getCallee()->getSourceRange());
10711 BId != Builtin::BImemset)
10714 PDiag(diag::warn_arc_object_memaccess)
10715 << ArgIdx << FnName << PointeeTy
10716 <<
Call->getCallee()->getSourceRange());
10723 bool NonTriviallyCopyableCXXRecord =
10727 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10730 PDiag(diag::warn_cstruct_memaccess)
10731 << ArgIdx << FnName << PointeeTy << 0);
10732 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10733 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10734 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10738 PDiag(diag::warn_cxxstruct_memaccess)
10739 << FnName << PointeeTy);
10740 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10743 PDiag(diag::warn_cstruct_memaccess)
10744 << ArgIdx << FnName << PointeeTy << 1);
10745 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10746 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10747 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10751 PDiag(diag::warn_cxxstruct_memaccess)
10752 << FnName << PointeeTy);
10761 PDiag(diag::note_bad_memaccess_silence)
10767bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
10769 llvm::FoldingSetNodeID SizeOfArgID;
10775 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10778 QualType DestTy = Dest->
getType();
10779 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
10785 if (SizeOfArgID == llvm::FoldingSetNodeID())
10788 llvm::FoldingSetNodeID DestID;
10790 if (DestID == SizeOfArgID) {
10793 unsigned ActionIdx = 0;
10794 StringRef ReadableName = FnName->
getName();
10796 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
10797 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
10806 SourceLocation SL = SizeOfArg->
getExprLoc();
10811 if (
SM.isMacroArgExpansion(SL)) {
10813 SL =
SM.getSpellingLoc(SL);
10814 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10816 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10821 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10822 << ReadableName << PointeeTy << DestTy << DSR
10825 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10826 << ActionIdx << SSR);
10862 if (CAT->getZExtSize() <= 1)
10870void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10874 unsigned NumArgs =
Call->getNumArgs();
10875 if ((NumArgs != 3) && (NumArgs != 4))
10880 const Expr *CompareWithSrc =
nullptr;
10883 Call->getBeginLoc(),
Call->getRParenLoc()))
10888 CompareWithSrc = Ex;
10891 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10892 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10893 SizeCall->getNumArgs() == 1)
10898 if (!CompareWithSrc)
10905 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10909 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10910 if (!CompareWithSrcDRE ||
10914 const Expr *OriginalSizeArg =
Call->getArg(2);
10915 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10922 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10926 SmallString<128> sizeString;
10927 llvm::raw_svector_ostream
OS(sizeString);
10932 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10939 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10940 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10941 return D1->getDecl() == D2->getDecl();
10946 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10955void Sema::CheckStrncatArguments(
const CallExpr *CE,
10970 unsigned PatternType = 0;
10978 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10979 if (BE->getOpcode() == BO_Sub) {
10980 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10981 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10992 if (PatternType == 0)
11001 if (
SM.isMacroArgExpansion(SL)) {
11002 SL =
SM.getSpellingLoc(SL);
11003 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
11008 QualType DstTy = DstArg->
getType();
11011 if (!isKnownSizeArray) {
11012 if (PatternType == 1)
11013 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11015 Diag(SL, diag::warn_strncat_src_size) << SR;
11019 if (PatternType == 1)
11020 Diag(SL, diag::warn_strncat_large_size) << SR;
11022 Diag(SL, diag::warn_strncat_src_size) << SR;
11024 SmallString<128> sizeString;
11025 llvm::raw_svector_ostream
OS(sizeString);
11033 Diag(SL, diag::note_strncat_wrong_size)
11038void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11047void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11049 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11050 const Decl *D = Lvalue->getDecl();
11051 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11052 if (!DD->getType()->isReferenceType())
11053 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11057 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11058 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11059 Lvalue->getMemberDecl());
11062void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11064 const auto *Lambda = dyn_cast<LambdaExpr>(
11069 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11070 << CalleeName << 2 ;
11073void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11075 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11076 if (Var ==
nullptr)
11080 << CalleeName << 0 << Var;
11083void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11086 llvm::raw_svector_ostream
OS(SizeString);
11089 if (Kind == clang::CK_BitCast &&
11090 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11092 if (Kind == clang::CK_IntegralToPointer &&
11094 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11097 switch (
Cast->getCastKind()) {
11098 case clang::CK_BitCast:
11099 case clang::CK_IntegralToPointer:
11100 case clang::CK_FunctionToPointerDecay:
11109 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11110 << CalleeName << 0 <<
OS.str();
11114void Sema::CheckFreeArguments(
const CallExpr *E) {
11115 const std::string CalleeName =
11120 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11122 case UnaryOperator::Opcode::UO_AddrOf:
11123 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11124 case UnaryOperator::Opcode::UO_Plus:
11125 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11130 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11132 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11134 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11135 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11136 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11142 << CalleeName << 1 ;
11147 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11148 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11152Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11161 Diag(ReturnLoc, diag::warn_null_ret)
11171 if (Op == OO_New || Op == OO_Array_New) {
11172 const FunctionProtoType *Proto
11176 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11182 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11187 if (
Context.getTargetInfo().getTriple().isPPC64())
11199 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11200 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11202 return FPLiteral && FPCast;
11205 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11211 llvm::APFloat TargetC = FPLiteral->
getValue();
11212 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11213 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11217 Diag(Loc, diag::warn_float_compare_literal)
11218 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11231 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11232 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11233 if (DRL->getDecl() == DRR->getDecl())
11241 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11242 if (FLL->isExact())
11244 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11245 if (FLR->isExact())
11249 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11250 CL &&
CL->getBuiltinCallee())
11253 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11254 CR && CR->getBuiltinCallee())
11258 Diag(Loc, diag::warn_floatingpoint_eq)
11279 IntRange(
unsigned Width,
bool NonNegative)
11280 : Width(Width), NonNegative(NonNegative) {}
11283 unsigned valueBits()
const {
11284 return NonNegative ? Width : Width - 1;
11288 static IntRange forBoolType() {
11289 return IntRange(1,
true);
11293 static IntRange forValueOfType(ASTContext &
C, QualType T) {
11294 return forValueOfCanonicalType(
C,
11299 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *T) {
11302 if (
const auto *VT = dyn_cast<VectorType>(T))
11303 T = VT->getElementType().getTypePtr();
11304 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11305 T = MT->getElementType().getTypePtr();
11306 if (
const auto *CT = dyn_cast<ComplexType>(T))
11307 T = CT->getElementType().getTypePtr();
11308 if (
const auto *AT = dyn_cast<AtomicType>(T))
11309 T = AT->getValueType().getTypePtr();
11310 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11311 T = OBT->getUnderlyingType().getTypePtr();
11313 if (!
C.getLangOpts().CPlusPlus) {
11316 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11321 if (
Enum->isFixed()) {
11322 return IntRange(
C.getIntWidth(QualType(T, 0)),
11323 !
Enum->getIntegerType()->isSignedIntegerType());
11326 unsigned NumPositive =
Enum->getNumPositiveBits();
11327 unsigned NumNegative =
Enum->getNumNegativeBits();
11329 if (NumNegative == 0)
11330 return IntRange(NumPositive,
true);
11332 return IntRange(std::max(NumPositive + 1, NumNegative),
11336 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11337 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11350 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *T) {
11353 if (
const VectorType *VT = dyn_cast<VectorType>(T))
11354 T = VT->getElementType().getTypePtr();
11355 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11356 T = MT->getElementType().getTypePtr();
11357 if (
const ComplexType *CT = dyn_cast<ComplexType>(T))
11358 T = CT->getElementType().getTypePtr();
11359 if (
const AtomicType *AT = dyn_cast<AtomicType>(T))
11360 T = AT->getValueType().getTypePtr();
11362 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11363 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11364 T = OBT->getUnderlyingType().getTypePtr();
11366 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11367 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11376 static IntRange join(IntRange L, IntRange R) {
11377 bool Unsigned = L.NonNegative && R.NonNegative;
11378 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
11379 L.NonNegative && R.NonNegative);
11383 static IntRange bit_and(IntRange L, IntRange R) {
11384 unsigned Bits = std::max(L.Width, R.Width);
11385 bool NonNegative =
false;
11386 if (L.NonNegative) {
11387 Bits = std::min(Bits, L.Width);
11388 NonNegative =
true;
11390 if (R.NonNegative) {
11391 Bits = std::min(Bits, R.Width);
11392 NonNegative =
true;
11394 return IntRange(Bits, NonNegative);
11398 static IntRange sum(IntRange L, IntRange R) {
11399 bool Unsigned = L.NonNegative && R.NonNegative;
11400 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
11405 static IntRange difference(IntRange L, IntRange R) {
11409 bool CanWiden = !L.NonNegative || !R.NonNegative;
11410 bool Unsigned = L.NonNegative && R.Width == 0;
11411 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
11417 static IntRange product(IntRange L, IntRange R) {
11421 bool CanWiden = !L.NonNegative && !R.NonNegative;
11422 bool Unsigned = L.NonNegative && R.NonNegative;
11423 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
11428 static IntRange rem(IntRange L, IntRange R) {
11432 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
11440 if (value.isSigned() && value.isNegative())
11441 return IntRange(value.getSignificantBits(),
false);
11443 if (value.getBitWidth() > MaxWidth)
11444 value = value.trunc(MaxWidth);
11448 return IntRange(value.getActiveBits(),
true);
11452 if (result.
isInt())
11459 R = IntRange::join(R, El);
11467 return IntRange::join(R, I);
11482 Ty = AtomicRHS->getValueType();
11501 bool InConstantContext,
11502 bool Approximate) {
11513 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11514 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11518 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11520 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11521 CE->getCastKind() == CK_BooleanToSignedIntegral;
11524 if (!isIntegerCast)
11525 return OutputTypeRange;
11528 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11529 InConstantContext, Approximate);
11531 return std::nullopt;
11534 if (SubRange->Width >= OutputTypeRange.Width)
11535 return OutputTypeRange;
11539 return IntRange(SubRange->Width,
11540 SubRange->NonNegative || OutputTypeRange.NonNegative);
11543 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11546 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11548 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11549 InConstantContext, Approximate);
11554 Expr *TrueExpr = CO->getTrueExpr();
11556 return std::nullopt;
11558 std::optional<IntRange> L =
11561 return std::nullopt;
11563 Expr *FalseExpr = CO->getFalseExpr();
11565 return std::nullopt;
11567 std::optional<IntRange> R =
11570 return std::nullopt;
11572 return IntRange::join(*L, *R);
11575 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11576 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11578 switch (BO->getOpcode()) {
11580 llvm_unreachable(
"builtin <=> should have class type");
11591 return IntRange::forBoolType();
11620 Combine = IntRange::bit_and;
11628 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11629 if (I->getValue() == 1) {
11630 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11631 return IntRange(R.Width,
true);
11641 case BO_ShrAssign: {
11643 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11645 return std::nullopt;
11649 if (std::optional<llvm::APSInt> shift =
11650 BO->getRHS()->getIntegerConstantExpr(
C)) {
11651 if (shift->isNonNegative()) {
11652 if (shift->uge(L->Width))
11653 L->Width = (L->NonNegative ? 0 : 1);
11655 L->Width -= shift->getZExtValue();
11669 Combine = IntRange::sum;
11673 if (BO->getLHS()->getType()->isPointerType())
11676 Combine = IntRange::difference;
11681 Combine = IntRange::product;
11690 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11692 return std::nullopt;
11695 if (std::optional<llvm::APSInt> divisor =
11696 BO->getRHS()->getIntegerConstantExpr(
C)) {
11697 unsigned log2 = divisor->logBase2();
11698 if (
log2 >= L->Width)
11699 L->Width = (L->NonNegative ? 0 : 1);
11701 L->Width = std::min(L->Width -
log2, MaxWidth);
11709 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11711 return std::nullopt;
11713 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11717 Combine = IntRange::rem;
11729 unsigned opWidth =
C.getIntWidth(T);
11731 InConstantContext, Approximate);
11733 return std::nullopt;
11736 InConstantContext, Approximate);
11738 return std::nullopt;
11740 IntRange
C = Combine(*L, *R);
11741 C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();
11742 C.Width = std::min(
C.Width, MaxWidth);
11746 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11747 switch (UO->getOpcode()) {
11750 return IntRange::forBoolType();
11764 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11767 return std::nullopt;
11772 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11782 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11785 return std::nullopt;
11790 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11800 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11801 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11805 return IntRange(BitField->getBitWidthValue(),
11806 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11809 return std::nullopt;
11815 bool InConstantContext,
11816 bool Approximate) {
11825 const llvm::fltSemantics &Src,
11826 const llvm::fltSemantics &Tgt) {
11827 llvm::APFloat truncated = value;
11830 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11831 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11833 return truncated.bitwiseIsEqual(value);
11842 const llvm::fltSemantics &Src,
11843 const llvm::fltSemantics &Tgt) {
11867 bool IsListInit =
false);
11882 return MacroName !=
"YES" && MacroName !=
"NO" &&
11883 MacroName !=
"true" && MacroName !=
"false";
11891 (!E->
getType()->isSignedIntegerType() ||
11906struct PromotedRange {
11908 llvm::APSInt PromotedMin;
11910 llvm::APSInt PromotedMax;
11912 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11914 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11915 else if (R.Width >= BitWidth && !
Unsigned) {
11919 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11920 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11922 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11923 .extOrTrunc(BitWidth);
11924 PromotedMin.setIsUnsigned(
Unsigned);
11926 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11927 .extOrTrunc(BitWidth);
11928 PromotedMax.setIsUnsigned(
Unsigned);
11933 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11943 InRangeFlag = 0x40,
11946 Min =
LE | InRangeFlag,
11947 InRange = InRangeFlag,
11948 Max =
GE | InRangeFlag,
11951 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11956 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11957 Value.isUnsigned() == PromotedMin.isUnsigned());
11958 if (!isContiguous()) {
11959 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11960 if (
Value.isMinValue())
return Min;
11961 if (
Value.isMaxValue())
return Max;
11962 if (
Value >= PromotedMin)
return InRange;
11963 if (
Value <= PromotedMax)
return InRange;
11967 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11968 case -1:
return Less;
11969 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11971 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11972 case -1:
return InRange;
11973 case 0:
return Max;
11978 llvm_unreachable(
"impossible compare result");
11981 static std::optional<StringRef>
11983 if (Op == BO_Cmp) {
11985 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11987 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11988 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11989 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11990 return std::nullopt;
11997 }
else if (Op == BO_NE) {
12001 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12008 if (Op == BO_GE || Op == BO_LE)
12009 std::swap(TrueFlag, FalseFlag);
12012 return StringRef(
"true");
12014 return StringRef(
"false");
12015 return std::nullopt;
12022 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12023 if (ICE->getCastKind() != CK_IntegralCast &&
12024 ICE->getCastKind() != CK_NoOp)
12026 E = ICE->getSubExpr();
12035 enum ConstantValueKind {
12040 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
12041 return BL->getValue() ? ConstantValueKind::LiteralTrue
12042 : ConstantValueKind::LiteralFalse;
12043 return ConstantValueKind::Miscellaneous;
12048 const llvm::APSInt &
Value,
12049 bool RhsConstant) {
12071 if (!OtherValueRange)
12076 OtherT = AT->getValueType();
12077 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12081 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12087 bool OtherIsBooleanDespiteType =
12089 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12090 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12094 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12095 Value.isUnsigned());
12096 auto Cmp = OtherPromotedValueRange.compare(
Value);
12097 auto Result = PromotedRange::constantValue(E->
getOpcode(),
Cmp, RhsConstant);
12103 bool TautologicalTypeCompare =
false;
12105 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12106 Value.isUnsigned());
12107 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12110 TautologicalTypeCompare =
true;
12118 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12127 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12133 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12134 Other->getType()->isUnsignedIntegerOrEnumerationType())
12135 TautologicalTypeCompare =
true;
12140 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
12141 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12145 llvm::raw_svector_ostream OS(PrettySourceValue);
12147 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12148 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12150 OS << (BL->getValue() ?
"YES" :
"NO");
12155 if (!TautologicalTypeCompare) {
12157 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12163 if (IsObjCSignedCharBool) {
12165 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12166 << OS.str() << *Result);
12173 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12177 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12178 : diag::warn_tautological_bool_compare)
12180 << OtherIsBooleanDespiteType << *Result
12187 ? diag::warn_unsigned_enum_always_true_comparison
12188 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12189 : diag::warn_unsigned_always_true_comparison)
12190 : diag::warn_tautological_constant_compare;
12193 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
12226 if (T->isIntegralType(S.
Context)) {
12227 std::optional<llvm::APSInt> RHSValue =
12229 std::optional<llvm::APSInt> LHSValue =
12233 if (RHSValue && LHSValue)
12237 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12239 const bool RhsConstant = (
bool)RHSValue;
12240 Expr *Const = RhsConstant ? RHS : LHS;
12242 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12251 if (!T->hasUnsignedIntegerRepresentation()) {
12265 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12267 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12273 Expr *signedOperand, *unsignedOperand;
12276 "unsigned comparison between two signed integer expressions?");
12277 signedOperand = LHS;
12278 unsignedOperand = RHS;
12280 signedOperand = RHS;
12281 unsignedOperand = LHS;
12287 std::optional<IntRange> signedRange =
12299 if (signedRange->NonNegative)
12311 if (!unsignedRange)
12316 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12318 if (unsignedRange->Width < comparisonWidth)
12323 S.
PDiag(diag::warn_mixed_sign_comparison)
12342 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12347 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12348 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12349 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12350 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12351 << BitfieldEnumDecl;
12358 Init->isValueDependent() ||
12359 Init->isTypeDependent())
12362 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12372 const PreferredTypeAttr *PTAttr =
nullptr;
12374 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12376 ED = PTAttr->getType()->getAsEnumDecl();
12384 bool SignedEnum = ED->getNumNegativeBits() > 0;
12391 unsigned DiagID = 0;
12392 if (SignedEnum && !SignedBitfield) {
12395 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12397 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12398 }
else if (SignedBitfield && !SignedEnum &&
12399 ED->getNumPositiveBits() == FieldWidth) {
12402 ? diag::warn_signed_bitfield_enum_conversion
12403 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12406 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12411 << SignedEnum << TypeRange;
12413 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12420 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12421 ED->getNumNegativeBits())
12422 : ED->getNumPositiveBits();
12425 if (BitsNeeded > FieldWidth) {
12429 ? diag::warn_bitfield_too_small_for_enum
12430 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12431 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12435 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12443 llvm::APSInt
Value = Result.Val.getInt();
12445 unsigned OriginalWidth =
Value.getBitWidth();
12451 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12452 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12459 if (!
Value.isSigned() ||
Value.isNegative())
12460 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12461 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12462 OriginalWidth =
Value.getSignificantBits();
12464 if (OriginalWidth <= FieldWidth)
12468 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12472 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12473 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12477 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12479 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12480 ? diag::warn_impcast_single_bit_bitield_precision_constant
12481 : diag::warn_impcast_bitfield_precision_constant)
12482 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12483 <<
Init->getSourceRange();
12520 bool PruneControlFlow =
false) {
12527 if (T.hasAddressSpace())
12529 if (PruneControlFlow) {
12543 bool PruneControlFlow =
false) {
12550 bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);
12555 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12556 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12561 llvm::APFloat
Value(0.0);
12567 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12572 diag::warn_impcast_float_integer, PruneWarnings);
12575 bool isExact =
false;
12578 T->hasUnsignedIntegerRepresentation());
12579 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12580 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12588 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12589 precision = (precision * 59 + 195) / 196;
12590 Value.toString(PrettySourceValue, precision);
12594 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12595 << PrettySourceValue);
12598 if (Result == llvm::APFloat::opOK && isExact) {
12599 if (IsLiteral)
return;
12600 return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
12606 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12609 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12610 : diag::warn_impcast_float_to_integer_out_of_range,
12613 unsigned DiagID = 0;
12616 DiagID = diag::warn_impcast_literal_float_to_integer;
12617 }
else if (IntegerValue == 0) {
12618 if (
Value.isZero()) {
12620 diag::warn_impcast_float_integer, PruneWarnings);
12623 DiagID = diag::warn_impcast_float_to_integer_zero;
12625 if (IntegerValue.isUnsigned()) {
12626 if (!IntegerValue.isMaxValue()) {
12628 diag::warn_impcast_float_integer, PruneWarnings);
12631 if (!IntegerValue.isMaxSignedValue() &&
12632 !IntegerValue.isMinSignedValue()) {
12634 diag::warn_impcast_float_integer, PruneWarnings);
12638 DiagID = diag::warn_impcast_float_to_integer;
12643 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12645 IntegerValue.toString(PrettyTargetValue);
12647 if (PruneWarnings) {
12651 << PrettySourceValue << PrettyTargetValue
12664 "Must be compound assignment operation");
12675 ->getComputationResultType()
12682 if (ResultBT->isInteger())
12684 E->
getExprLoc(), diag::warn_impcast_float_integer);
12686 if (!ResultBT->isFloatingPoint())
12695 diag::warn_impcast_float_result_precision);
12700 if (!Range.Width)
return "0";
12702 llvm::APSInt ValueInRange =
Value;
12703 ValueInRange.setIsSigned(!Range.NonNegative);
12704 ValueInRange = ValueInRange.trunc(Range.Width);
12705 return toString(ValueInRange, 10);
12715 const Type *Source =
12717 if (
Target->isDependentType())
12720 const auto *FloatCandidateBT =
12721 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12722 const Type *BoolCandidateType = ToBool ?
Target : Source;
12725 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12730 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12736 S, TheCall->
getArg(I - 1),
false));
12738 S, TheCall->
getArg(I + 1),
false));
12743 diag::warn_impcast_floating_point_to_bool);
12758 if (!IsGNUNullExpr && !HasNullPtrType)
12762 if (T->isAnyPointerType() || T->isBlockPointerType() ||
12763 T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())
12766 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12779 if (IsGNUNullExpr && Loc.
isMacroID()) {
12782 if (MacroName ==
"NULL")
12790 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12804 const char FirstLiteralCharacter =
12806 if (FirstLiteralCharacter ==
'0')
12812 if (CC.
isValid() && T->isCharType()) {
12813 const char FirstContextCharacter =
12815 if (FirstContextCharacter ==
'{')
12823 const auto *IL = dyn_cast<IntegerLiteral>(E);
12825 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12826 if (UO->getOpcode() == UO_Minus)
12827 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12838 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12842 if (Opc == BO_Shl) {
12845 if (LHS && LHS->getValue() == 0)
12846 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12848 RHS->getValue().isNonNegative() &&
12850 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12851 << (Result.Val.getInt() != 0);
12853 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12860 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12865 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12866 (RHS->getValue() == 0 || RHS->getValue() == 1))
12869 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12870 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12878 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12884 if (Source->isChar16Type() &&
Target->isChar32Type())
12890 llvm::APSInt
Value(32);
12891 Value = Result.Val.getInt();
12892 bool IsASCII =
Value <= 0x7F;
12893 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12894 bool ConversionPreservesSemantics =
12895 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12897 if (!ConversionPreservesSemantics) {
12898 auto IsSingleCodeUnitCP = [](
const QualType &T,
12899 const llvm::APSInt &
Value) {
12900 if (T->isChar8Type())
12901 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12902 if (T->isChar16Type())
12903 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12904 assert(T->isChar32Type());
12905 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12908 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12917 LosesPrecision ? diag::warn_impcast_unicode_precision
12918 : diag::warn_impcast_unicode_char_type);
12923 From =
Context.getCanonicalType(From);
12924 To =
Context.getCanonicalType(To);
12927 From = MaybePointee;
12934 if (FromFn->getCFIUncheckedCalleeAttr() &&
12935 !ToFn->getCFIUncheckedCalleeAttr())
12943 bool *ICContext,
bool IsListInit) {
12948 if (Source ==
Target)
return;
12949 if (
Target->isDependentType())
return;
12959 if (Source->isAtomicType())
12963 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12969 diag::warn_impcast_string_literal_to_bool);
12975 diag::warn_impcast_objective_c_literal_to_bool);
12977 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12989 if (
ObjC().isSignedCharBool(T) && Source->isIntegralType(
Context)) {
12992 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12994 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13003 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13005 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13010 if (
Target->isSveVLSBuiltinType() &&
13017 if (
Target->isRVVVLSBuiltinType() &&
13027 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_vector_scalar);
13035 diag::warn_hlsl_impcast_vector_truncation);
13047 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13048 Target = VecTy->getElementType().getTypePtr();
13052 if (
Target->isScalarType())
13053 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_matrix_scalar);
13061 diag::warn_hlsl_impcast_matrix_truncation);
13067 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13068 Target = MatTy->getElementType().getTypePtr();
13078 ? diag::err_impcast_complex_scalar
13079 : diag::warn_impcast_complex_scalar);
13086 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13092 const Type *OriginalTarget =
Context.getCanonicalType(T).getTypePtr();
13095 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13097 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13136 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_float_precision);
13139 else if (Order < 0) {
13143 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_double_promotion);
13149 if (TargetBT && TargetBT->
isInteger()) {
13176 diag::warn_impcast_floating_point_to_bool);
13184 if (Source->isFixedPointType()) {
13185 if (
Target->isUnsaturatedFixedPointType()) {
13189 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13190 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(T);
13191 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(T);
13194 PDiag(diag::warn_impcast_fixed_point_range)
13195 <<
Value.toString() << T
13201 }
else if (
Target->isIntegerType()) {
13205 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13208 llvm::APSInt IntResult = FXResult.convertToInt(
13209 Context.getIntWidth(T),
Target->isSignedIntegerOrEnumerationType(),
13214 PDiag(diag::warn_impcast_fixed_point_range)
13215 << FXResult.toString() << T
13222 }
else if (
Target->isUnsaturatedFixedPointType()) {
13223 if (Source->isIntegerType()) {
13230 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13231 Value,
Context.getFixedPointSemantics(T), &Overflowed);
13235 PDiag(diag::warn_impcast_fixed_point_range)
13256 unsigned int SourcePrecision =
SourceRange->Width;
13260 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13263 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13264 SourcePrecision > TargetPrecision) {
13266 if (std::optional<llvm::APSInt> SourceInt =
13271 llvm::APFloat TargetFloatValue(
13273 llvm::APFloat::opStatus ConversionStatus =
13274 TargetFloatValue.convertFromAPInt(
13276 llvm::APFloat::rmNearestTiesToEven);
13278 if (ConversionStatus != llvm::APFloat::opOK) {
13280 SourceInt->toString(PrettySourceValue, 10);
13282 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13286 PDiag(diag::warn_impcast_integer_float_precision_constant)
13287 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13293 diag::warn_impcast_integer_float_precision);
13302 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13307 if (
Target->isBooleanType())
13311 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13315 if (!Source->isIntegerType() || !
Target->isIntegerType())
13320 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13323 if (
ObjC().isSignedCharBool(T) && !Source->isCharType() &&
13326 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13331 if (!LikelySourceRange)
13334 IntRange SourceTypeRange =
13335 IntRange::forTargetOfCanonicalType(
Context, Source);
13336 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13338 if (LikelySourceRange->Width > TargetRange.Width) {
13342 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13343 if (TargetOBT->isWrapKind()) {
13350 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13351 if (SourceOBT->isWrapKind()) {
13361 llvm::APSInt
Value(32);
13371 PDiag(diag::warn_impcast_integer_precision_constant)
13372 << PrettySourceValue << PrettyTargetValue
13382 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13383 if (UO->getOpcode() == UO_Minus)
13385 *
this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
13388 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13389 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_integer_64_32,
13392 diag::warn_impcast_integer_precision);
13395 if (TargetRange.Width > SourceTypeRange.Width) {
13396 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13397 if (UO->getOpcode() == UO_Minus)
13398 if (Source->isUnsignedIntegerType()) {
13399 if (
Target->isUnsignedIntegerType())
13401 diag::warn_impcast_high_order_zero_bits);
13402 if (
Target->isSignedIntegerType())
13404 diag::warn_impcast_nonnegative_result);
13408 if (TargetRange.Width == LikelySourceRange->Width &&
13409 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13410 Source->isSignedIntegerType()) {
13424 PDiag(diag::warn_impcast_integer_precision_constant)
13425 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13435 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13436 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13437 LikelySourceRange->Width == TargetRange.Width))) {
13441 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13443 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13447 unsigned DiagID = diag::warn_impcast_integer_sign;
13455 DiagID = diag::warn_impcast_integer_sign_conditional;
13467 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_int_to_enum);
13472 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13474 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13475 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13476 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13477 TargetEnum->getDecl()->hasNameForLinkage() &&
13478 SourceEnum != TargetEnum) {
13483 diag::warn_impcast_different_enum_types);
13497 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13510 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13511 TrueExpr = BCO->getCommon();
13513 bool Suspicious =
false;
13517 if (T->isBooleanType())
13522 if (!Suspicious)
return;
13525 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13530 if (E->
getType() == T)
return;
13532 Suspicious =
false;
13537 E->
getType(), CC, &Suspicious);
13554struct AnalyzeImplicitConversionsWorkItem {
13563 bool ExtraCheckForImplicitConversion,
13566 WorkList.push_back({E, CC,
false});
13568 if (ExtraCheckForImplicitConversion && E->
getType() != T)
13575 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13577 Expr *OrigE = Item.E;
13596 Expr *SourceExpr = E;
13601 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13602 if (
auto *Src = OVE->getSourceExpr())
13605 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13606 if (UO->getOpcode() == UO_Not &&
13607 UO->getSubExpr()->isKnownToHaveBooleanValue())
13608 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13612 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13613 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13614 BO->getLHS()->isKnownToHaveBooleanValue() &&
13615 BO->getRHS()->isKnownToHaveBooleanValue() &&
13616 BO->getLHS()->HasSideEffects(S.
Context) &&
13617 BO->getRHS()->HasSideEffects(S.
Context)) {
13628 if (SR.str() ==
"&" || SR.str() ==
"|") {
13630 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13631 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13634 BO->getOperatorLoc(),
13635 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13636 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13638 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13656 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13662 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13668 if (SourceExpr->
getType() != T)
13677 for (
auto *SE : POE->semantics())
13678 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13679 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13683 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13684 E = CE->getSubExpr();
13690 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13691 if (InitListE->getNumInits() == 1) {
13692 E = InitListE->getInit(0);
13699 WorkList.push_back({E, CC, IsListInit});
13703 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13704 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13708 if (OutArgE->isInOut())
13709 WorkList.push_back(
13710 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13711 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13717 if (BO->isComparisonOp())
13721 if (BO->getOpcode() == BO_Assign)
13724 if (BO->isAssignmentOp())
13740 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13742 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13746 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13747 if (ChildExpr == CSE->getOperand())
13753 if (IsLogicalAndOperator &&
13758 WorkList.push_back({ChildExpr, CC, IsListInit});
13772 if (
U->getOpcode() == UO_LNot) {
13774 }
else if (
U->getOpcode() != UO_AddrOf) {
13775 if (
U->getSubExpr()->getType()->isAtomicType())
13776 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13777 diag::warn_atomic_implicit_seq_cst);
13788 WorkList.push_back({OrigE, CC, IsListInit});
13789 while (!WorkList.empty())
13801 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13804 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13805 if (!M->getMemberDecl()->getType()->isReferenceType())
13807 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13808 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13810 FD =
Call->getDirectCallee();
13819 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13833 if (
SM.isMacroBodyExpansion(Loc))
13835 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13859 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13860 : diag::warn_this_bool_conversion;
13865 bool IsAddressOf =
false;
13867 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13868 if (UO->getOpcode() != UO_AddrOf)
13870 IsAddressOf =
true;
13871 E = UO->getSubExpr();
13875 unsigned DiagID = IsCompare
13876 ? diag::warn_address_of_reference_null_compare
13877 : diag::warn_address_of_reference_bool_conversion;
13885 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13888 llvm::raw_string_ostream S(Str);
13890 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13891 : diag::warn_cast_nonnull_to_bool;
13894 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13899 if (
auto *Callee =
Call->getDirectCallee()) {
13900 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13901 ComplainAboutNonnullParamOrCall(A);
13910 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13911 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13912 MRecordDecl && MRecordDecl->isLambda()) {
13915 << MRecordDecl->getSourceRange() << Range << IsEqual;
13925 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13926 D = M->getMemberDecl();
13934 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13937 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13938 ComplainAboutNonnullParamOrCall(A);
13942 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13946 auto ParamIter = llvm::find(FD->
parameters(), PV);
13948 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13952 ComplainAboutNonnullParamOrCall(
NonNull);
13957 if (ArgNo.getASTIndex() == ParamNo) {
13958 ComplainAboutNonnullParamOrCall(
NonNull);
13969 const bool IsFunction = T->isFunctionType();
13972 if (IsAddressOf && IsFunction) {
13977 if (!IsAddressOf && !IsFunction && !IsArray)
13982 llvm::raw_string_ostream S(Str);
13985 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13986 : diag::warn_impcast_pointer_to_bool;
13993 DiagType = AddressOf;
13994 else if (IsFunction)
13995 DiagType = FunctionPointer;
13997 DiagType = ArrayPointer;
13999 llvm_unreachable(
"Could not determine diagnostic.");
14001 << Range << IsEqual;
14014 if (ReturnType.
isNull())
14045 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14046 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14048 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14049 Target->isUnsignedIntegerType()) {
14053 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14054 : diag::warn_impcast_overflow_behavior_pedantic;
14058 ? diag::warn_impcast_overflow_behavior_assignment
14059 : diag::warn_impcast_overflow_behavior;
14065 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14066 if (TargetOBT->isWrapKind()) {
14086 CheckArrayAccess(E);
14096void Sema::CheckForIntOverflow (
const Expr *E) {
14098 SmallVector<const Expr *, 2> Exprs(1, E);
14101 const Expr *OriginalE = Exprs.pop_back_val();
14109 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14110 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14113 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14114 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14115 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14117 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14118 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14119 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14120 Exprs.push_back(Temporary->getSubExpr());
14121 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
14122 Exprs.push_back(
Array->getIdx());
14123 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14124 Exprs.push_back(Compound->getInitializer());
14125 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14126 New &&
New->isArray()) {
14127 if (
auto ArraySize =
New->getArraySize())
14128 Exprs.push_back(*ArraySize);
14129 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14130 Exprs.push_back(MTE->getSubExpr());
14131 }
while (!Exprs.empty());
14139 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14146 class SequenceTree {
14148 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14149 unsigned Parent : 31;
14150 LLVM_PREFERRED_TYPE(
bool)
14151 unsigned Merged : 1;
14153 SmallVector<Value, 8> Values;
14159 friend class SequenceTree;
14163 explicit Seq(
unsigned N) : Index(N) {}
14166 Seq() : Index(0) {}
14169 SequenceTree() { Values.push_back(
Value(0)); }
14170 Seq root()
const {
return Seq(0); }
14175 Seq allocate(
Seq Parent) {
14176 Values.push_back(
Value(Parent.Index));
14177 return Seq(Values.size() - 1);
14182 Values[S.Index].Merged =
true;
14188 bool isUnsequenced(
Seq Cur,
Seq Old) {
14189 unsigned C = representative(Cur.Index);
14190 unsigned Target = representative(Old.Index);
14194 C = Values[
C].Parent;
14201 unsigned representative(
unsigned K) {
14202 if (Values[K].Merged)
14204 return Values[K].Parent = representative(Values[K].Parent);
14210 using Object =
const NamedDecl *;
14224 UK_ModAsSideEffect,
14226 UK_Count = UK_ModAsSideEffect + 1
14232 const Expr *UsageExpr =
nullptr;
14233 SequenceTree::Seq
Seq;
14239 Usage Uses[UK_Count];
14242 bool Diagnosed =
false;
14246 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14254 UsageInfoMap UsageMap;
14257 SequenceTree::Seq Region;
14261 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14265 SmallVectorImpl<const Expr *> &WorkList;
14272 struct SequencedSubexpression {
14273 SequencedSubexpression(SequenceChecker &
Self)
14274 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14275 Self.ModAsSideEffect = &ModAsSideEffect;
14278 ~SequencedSubexpression() {
14279 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14283 UsageInfo &UI =
Self.UsageMap[M.first];
14284 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14285 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14286 SideEffectUsage = M.second;
14288 Self.ModAsSideEffect = OldModAsSideEffect;
14291 SequenceChecker &
Self;
14292 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14293 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14300 class EvaluationTracker {
14302 EvaluationTracker(SequenceChecker &
Self)
14304 Self.EvalTracker =
this;
14307 ~EvaluationTracker() {
14308 Self.EvalTracker = Prev;
14310 Prev->EvalOK &= EvalOK;
14313 bool evaluate(
const Expr *E,
bool &
Result) {
14318 Self.SemaRef.isConstantEvaluatedContext());
14323 SequenceChecker &
Self;
14324 EvaluationTracker *Prev;
14325 bool EvalOK =
true;
14326 } *EvalTracker =
nullptr;
14330 Object getObject(
const Expr *E,
bool Mod)
const {
14332 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14333 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14334 return getObject(UO->getSubExpr(), Mod);
14335 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14336 if (BO->getOpcode() == BO_Comma)
14337 return getObject(BO->getRHS(), Mod);
14338 if (Mod && BO->isAssignmentOp())
14339 return getObject(BO->getLHS(), Mod);
14340 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14343 return ME->getMemberDecl();
14344 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14353 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14355 Usage &U = UI.Uses[UK];
14356 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14360 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14361 ModAsSideEffect->push_back(std::make_pair(O, U));
14363 U.UsageExpr = UsageExpr;
14373 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
14374 UsageKind OtherKind,
bool IsModMod) {
14378 const Usage &U = UI.Uses[OtherKind];
14379 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14382 const Expr *Mod = U.UsageExpr;
14383 const Expr *ModOrUse = UsageExpr;
14384 if (OtherKind == UK_Use)
14385 std::swap(Mod, ModOrUse);
14389 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14390 : diag::warn_unsequenced_mod_use)
14391 << O << SourceRange(ModOrUse->
getExprLoc()));
14392 UI.Diagnosed =
true;
14421 void notePreUse(Object O,
const Expr *UseExpr) {
14422 UsageInfo &UI = UsageMap[O];
14424 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14427 void notePostUse(Object O,
const Expr *UseExpr) {
14428 UsageInfo &UI = UsageMap[O];
14429 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14431 addUsage(O, UI, UseExpr, UK_Use);
14434 void notePreMod(Object O,
const Expr *ModExpr) {
14435 UsageInfo &UI = UsageMap[O];
14437 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14438 checkUsage(O, UI, ModExpr, UK_Use,
false);
14441 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
14442 UsageInfo &UI = UsageMap[O];
14443 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14445 addUsage(O, UI, ModExpr, UK);
14449 SequenceChecker(Sema &S,
const Expr *E,
14450 SmallVectorImpl<const Expr *> &WorkList)
14451 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14455 (void)this->WorkList;
14458 void VisitStmt(
const Stmt *S) {
14462 void VisitExpr(
const Expr *E) {
14464 Base::VisitStmt(E);
14467 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14468 for (
auto *Sub : CSE->
children()) {
14469 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14484 void VisitCastExpr(
const CastExpr *E) {
14496 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14497 const Expr *SequencedAfter) {
14498 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14499 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14500 SequenceTree::Seq OldRegion = Region;
14503 SequencedSubexpression SeqBefore(*
this);
14504 Region = BeforeRegion;
14505 Visit(SequencedBefore);
14508 Region = AfterRegion;
14509 Visit(SequencedAfter);
14511 Region = OldRegion;
14513 Tree.merge(BeforeRegion);
14514 Tree.merge(AfterRegion);
14517 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14522 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14529 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14530 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14531 void VisitBinPtrMem(
const BinaryOperator *BO) {
14536 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14543 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14544 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14545 void VisitBinShlShr(
const BinaryOperator *BO) {
14549 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14556 void VisitBinComma(
const BinaryOperator *BO) {
14561 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14564 void VisitBinAssign(
const BinaryOperator *BO) {
14565 SequenceTree::Seq RHSRegion;
14566 SequenceTree::Seq LHSRegion;
14568 RHSRegion = Tree.allocate(Region);
14569 LHSRegion = Tree.allocate(Region);
14571 RHSRegion = Region;
14572 LHSRegion = Region;
14574 SequenceTree::Seq OldRegion = Region;
14590 SequencedSubexpression SeqBefore(*
this);
14591 Region = RHSRegion;
14595 Region = LHSRegion;
14599 notePostUse(O, BO);
14603 Region = LHSRegion;
14607 notePostUse(O, BO);
14609 Region = RHSRegion;
14617 Region = OldRegion;
14621 : UK_ModAsSideEffect);
14623 Tree.merge(RHSRegion);
14624 Tree.merge(LHSRegion);
14628 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14629 VisitBinAssign(CAO);
14632 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14633 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14634 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14637 return VisitExpr(UO);
14645 : UK_ModAsSideEffect);
14648 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14649 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14650 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14653 return VisitExpr(UO);
14657 notePostMod(O, UO, UK_ModAsSideEffect);
14660 void VisitBinLOr(
const BinaryOperator *BO) {
14666 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14667 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14668 SequenceTree::Seq OldRegion = Region;
14670 EvaluationTracker Eval(*
this);
14672 SequencedSubexpression Sequenced(*
this);
14673 Region = LHSRegion;
14680 bool EvalResult =
false;
14681 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14682 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14683 if (ShouldVisitRHS) {
14684 Region = RHSRegion;
14688 Region = OldRegion;
14689 Tree.merge(LHSRegion);
14690 Tree.merge(RHSRegion);
14693 void VisitBinLAnd(
const BinaryOperator *BO) {
14699 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14700 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14701 SequenceTree::Seq OldRegion = Region;
14703 EvaluationTracker Eval(*
this);
14705 SequencedSubexpression Sequenced(*
this);
14706 Region = LHSRegion;
14712 bool EvalResult =
false;
14713 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14714 bool ShouldVisitRHS = !EvalOK || EvalResult;
14715 if (ShouldVisitRHS) {
14716 Region = RHSRegion;
14720 Region = OldRegion;
14721 Tree.merge(LHSRegion);
14722 Tree.merge(RHSRegion);
14725 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14730 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14746 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14747 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14748 SequenceTree::Seq OldRegion = Region;
14750 EvaluationTracker Eval(*
this);
14752 SequencedSubexpression Sequenced(*
this);
14753 Region = ConditionRegion;
14763 bool EvalResult =
false;
14764 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14765 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14766 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14767 if (ShouldVisitTrueExpr) {
14768 Region = TrueRegion;
14771 if (ShouldVisitFalseExpr) {
14772 Region = FalseRegion;
14776 Region = OldRegion;
14777 Tree.merge(ConditionRegion);
14778 Tree.merge(TrueRegion);
14779 Tree.merge(FalseRegion);
14782 void VisitCallExpr(
const CallExpr *CE) {
14794 SequencedSubexpression Sequenced(*
this);
14799 SequenceTree::Seq CalleeRegion;
14800 SequenceTree::Seq OtherRegion;
14801 if (SemaRef.getLangOpts().CPlusPlus17) {
14802 CalleeRegion = Tree.allocate(Region);
14803 OtherRegion = Tree.allocate(Region);
14805 CalleeRegion = Region;
14806 OtherRegion = Region;
14808 SequenceTree::Seq OldRegion = Region;
14811 Region = CalleeRegion;
14813 SequencedSubexpression Sequenced(*this);
14814 Visit(CE->getCallee());
14816 Visit(CE->getCallee());
14820 Region = OtherRegion;
14824 Region = OldRegion;
14826 Tree.merge(CalleeRegion);
14827 Tree.merge(OtherRegion);
14845 return VisitCallExpr(CXXOCE);
14856 case OO_MinusEqual:
14858 case OO_SlashEqual:
14859 case OO_PercentEqual:
14860 case OO_CaretEqual:
14863 case OO_LessLessEqual:
14864 case OO_GreaterGreaterEqual:
14865 SequencingKind = RHSBeforeLHS;
14869 case OO_GreaterGreater:
14875 SequencingKind = LHSBeforeRHS;
14879 SequencingKind = LHSBeforeRest;
14883 SequencingKind = NoSequencing;
14887 if (SequencingKind == NoSequencing)
14888 return VisitCallExpr(CXXOCE);
14891 SequencedSubexpression Sequenced(*
this);
14894 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14895 "Should only get there with C++17 and above!");
14896 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14897 "Should only get there with an overloaded binary operator"
14898 " or an overloaded call operator!");
14900 if (SequencingKind == LHSBeforeRest) {
14901 assert(CXXOCE->getOperator() == OO_Call &&
14902 "We should only have an overloaded call operator here!");
14911 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14912 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14913 SequenceTree::Seq OldRegion = Region;
14915 assert(CXXOCE->getNumArgs() >= 1 &&
14916 "An overloaded call operator must have at least one argument"
14917 " for the postfix-expression!");
14918 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14919 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14920 CXXOCE->getNumArgs() - 1);
14924 Region = PostfixExprRegion;
14925 SequencedSubexpression Sequenced(*this);
14926 Visit(PostfixExpr);
14930 Region = ArgsRegion;
14931 for (const Expr *Arg : Args)
14934 Region = OldRegion;
14935 Tree.merge(PostfixExprRegion);
14936 Tree.merge(ArgsRegion);
14938 assert(CXXOCE->getNumArgs() == 2 &&
14939 "Should only have two arguments here!");
14940 assert((SequencingKind == LHSBeforeRHS ||
14941 SequencingKind == RHSBeforeLHS) &&
14942 "Unexpected sequencing kind!");
14946 const Expr *E1 = CXXOCE->getArg(0);
14947 const Expr *E2 = CXXOCE->getArg(1);
14948 if (SequencingKind == RHSBeforeLHS)
14951 return VisitSequencedExpressions(E1, E2);
14958 SequencedSubexpression Sequenced(*
this);
14961 return VisitExpr(CCE);
14964 SequenceExpressionsInOrder(
14970 return VisitExpr(ILE);
14973 SequenceExpressionsInOrder(ILE->
inits());
14985 SequenceTree::Seq Parent = Region;
14986 for (
const Expr *E : ExpressionList) {
14989 Region = Tree.allocate(Parent);
14990 Elts.push_back(Region);
14996 for (
unsigned I = 0; I < Elts.size(); ++I)
14997 Tree.merge(Elts[I]);
15001SequenceChecker::UsageInfo::UsageInfo() =
default;
15005void Sema::CheckUnsequencedOperations(
const Expr *E) {
15006 SmallVector<const Expr *, 8> WorkList;
15007 WorkList.push_back(E);
15008 while (!WorkList.empty()) {
15009 const Expr *Item = WorkList.pop_back_val();
15010 SequenceChecker(*
this, Item, WorkList);
15015 bool IsConstexpr) {
15018 CheckImplicitConversions(E, CheckLoc);
15020 CheckUnsequencedOperations(E);
15022 CheckForIntOverflow(E);
15035 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15039 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15043 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15057 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15061 bool CheckParameterNames) {
15062 bool HasInvalidParm =
false;
15064 assert(Param &&
"null in a parameter list");
15073 if (!Param->isInvalidDecl() &&
15075 diag::err_typecheck_decl_incomplete_type) ||
15077 diag::err_abstract_type_in_decl,
15079 Param->setInvalidDecl();
15080 HasInvalidParm =
true;
15085 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15089 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15097 QualType PType = Param->getOriginalType();
15105 if (!Param->isInvalidDecl()) {
15106 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15107 if (!ClassDecl->isInvalidDecl() &&
15108 !ClassDecl->hasIrrelevantDestructor() &&
15109 !ClassDecl->isDependentContext() &&
15110 ClassDecl->isParamDestroyedInCallee()) {
15122 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15123 if (!Param->getType().isConstQualified())
15124 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15128 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15133 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15134 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15139 if (!Param->isInvalidDecl() &&
15140 Param->getOriginalType()->isWebAssemblyTableType()) {
15141 Param->setInvalidDecl();
15142 HasInvalidParm =
true;
15143 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15147 return HasInvalidParm;
15150std::optional<std::pair<
15159static std::pair<CharUnits, CharUnits>
15167 if (
Base->isVirtual()) {
15174 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15181 DerivedType =
Base->getType();
15184 return std::make_pair(BaseAlignment, Offset);
15188static std::optional<std::pair<CharUnits, CharUnits>>
15194 return std::nullopt;
15199 return std::nullopt;
15203 CharUnits Offset = EltSize * IdxRes->getExtValue();
15206 return std::make_pair(P->first, P->second + Offset);
15212 return std::make_pair(
15213 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15219std::optional<std::pair<
15227 case Stmt::CStyleCastExprClass:
15228 case Stmt::CXXStaticCastExprClass:
15229 case Stmt::ImplicitCastExprClass: {
15231 const Expr *From = CE->getSubExpr();
15232 switch (CE->getCastKind()) {
15237 case CK_UncheckedDerivedToBase:
15238 case CK_DerivedToBase: {
15248 case Stmt::ArraySubscriptExprClass: {
15253 case Stmt::DeclRefExprClass: {
15257 if (!VD->getType()->isReferenceType()) {
15259 if (VD->hasDependentAlignment())
15268 case Stmt::MemberExprClass: {
15270 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15274 std::optional<std::pair<CharUnits, CharUnits>> P;
15283 return std::make_pair(P->first,
15286 case Stmt::UnaryOperatorClass: {
15296 case Stmt::BinaryOperatorClass: {
15308 return std::nullopt;
15313std::optional<std::pair<
15322 case Stmt::CStyleCastExprClass:
15323 case Stmt::CXXStaticCastExprClass:
15324 case Stmt::ImplicitCastExprClass: {
15326 const Expr *From = CE->getSubExpr();
15327 switch (CE->getCastKind()) {
15332 case CK_ArrayToPointerDecay:
15334 case CK_UncheckedDerivedToBase:
15335 case CK_DerivedToBase: {
15345 case Stmt::CXXThisExprClass: {
15350 case Stmt::UnaryOperatorClass: {
15356 case Stmt::BinaryOperatorClass: {
15365 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15366 std::swap(LHS, RHS);
15376 return std::nullopt;
15381 std::optional<std::pair<CharUnits, CharUnits>> P =
15385 return P->first.alignmentAtOffset(P->second);
15403 if (!DestPtr)
return;
15409 if (DestAlign.
isOne())
return;
15413 if (!SrcPtr)
return;
15424 if (SrcAlign >= DestAlign)
return;
15429 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15433void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15435 bool AllowOnePastEnd,
bool IndexNegated) {
15444 const Type *EffectiveType =
15448 Context.getAsConstantArrayType(BaseExpr->
getType());
15451 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15453 const Type *BaseType =
15455 bool IsUnboundedArray =
15457 Context, StrictFlexArraysLevel,
15460 (!IsUnboundedArray && BaseType->isDependentType()))
15468 if (IndexNegated) {
15469 index.setIsUnsigned(
false);
15473 if (IsUnboundedArray) {
15476 if (
index.isUnsigned() || !
index.isNegative()) {
15478 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15480 if (
index.getBitWidth() < AddrBits)
15482 std::optional<CharUnits> ElemCharUnits =
15483 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15486 if (!ElemCharUnits || ElemCharUnits->isZero())
15488 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15493 if (
index.getActiveBits() <= AddrBits) {
15495 llvm::APInt Product(
index);
15497 Product = Product.umul_ov(ElemBytes, Overflow);
15498 if (!Overflow && Product.getActiveBits() <= AddrBits)
15504 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15505 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15507 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15508 MaxElems = MaxElems.udiv(ElemBytes);
15511 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15512 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15517 PDiag(DiagID) << index << AddrBits
15518 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15519 << ElemBytes << MaxElems
15520 << MaxElems.getZExtValue()
15523 const NamedDecl *ND =
nullptr;
15525 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15527 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15529 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15530 ND = ME->getMemberDecl();
15534 PDiag(diag::note_array_declared_here) << ND);
15539 if (index.isUnsigned() || !index.isNegative()) {
15549 llvm::APInt size = ArrayTy->
getSize();
15551 if (BaseType != EffectiveType) {
15559 if (!ptrarith_typesize)
15560 ptrarith_typesize =
Context.getCharWidth();
15562 if (ptrarith_typesize != array_typesize) {
15564 uint64_t ratio = array_typesize / ptrarith_typesize;
15568 if (ptrarith_typesize * ratio == array_typesize)
15569 size *= llvm::APInt(size.getBitWidth(), ratio);
15573 if (size.getBitWidth() > index.getBitWidth())
15574 index = index.zext(size.getBitWidth());
15575 else if (size.getBitWidth() < index.getBitWidth())
15576 size = size.zext(index.getBitWidth());
15582 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15589 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15591 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15592 SourceLocation IndexLoc =
15594 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15599 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15600 : diag::warn_ptr_arith_exceeds_bounds;
15601 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15602 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15606 << index << ArrayTy->
desugar() << CastMsg
15609 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15611 DiagID = diag::warn_ptr_arith_precedes_bounds;
15612 if (index.isNegative()) index = -index;
15619 const NamedDecl *ND =
nullptr;
15621 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15623 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15625 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15626 ND = ME->getMemberDecl();
15630 PDiag(diag::note_array_declared_here) << ND);
15633void Sema::CheckArrayAccess(
const Expr *
expr) {
15634 int AllowOnePastEnd = 0;
15636 expr =
expr->IgnoreParenImpCasts();
15637 switch (
expr->getStmtClass()) {
15638 case Stmt::ArraySubscriptExprClass: {
15641 AllowOnePastEnd > 0);
15645 case Stmt::MemberExprClass: {
15649 case Stmt::CXXMemberCallExprClass: {
15653 case Stmt::ArraySectionExprClass: {
15659 nullptr, AllowOnePastEnd > 0);
15662 case Stmt::UnaryOperatorClass: {
15678 case Stmt::ConditionalOperatorClass: {
15680 if (
const Expr *lhs = cond->
getLHS())
15681 CheckArrayAccess(lhs);
15682 if (
const Expr *rhs = cond->
getRHS())
15683 CheckArrayAccess(rhs);
15686 case Stmt::CXXOperatorCallExprClass: {
15688 for (
const auto *Arg : OCE->arguments())
15689 CheckArrayAccess(Arg);
15699 Expr *RHS,
bool isProperty) {
15711 S.
Diag(Loc, diag::warn_arc_literal_assign)
15713 << (isProperty ? 0 : 1)
15721 Expr *RHS,
bool isProperty) {
15724 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15725 S.
Diag(Loc, diag::warn_arc_retained_assign)
15727 << (isProperty ? 0 : 1)
15731 RHS =
cast->getSubExpr();
15773 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15802 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15803 Diag(Loc, diag::warn_arc_retained_property_assign)
15807 RHS =
cast->getSubExpr();
15830 bool StmtLineInvalid;
15831 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15833 if (StmtLineInvalid)
15836 bool BodyLineInvalid;
15837 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15839 if (BodyLineInvalid)
15843 if (StmtLine != BodyLine)
15858 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15867 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15871 const Stmt *PossibleBody) {
15877 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15878 StmtLoc = FS->getRParenLoc();
15879 Body = FS->getBody();
15880 DiagID = diag::warn_empty_for_body;
15881 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15882 StmtLoc = WS->getRParenLoc();
15883 Body = WS->getBody();
15884 DiagID = diag::warn_empty_while_body;
15889 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15913 if (!ProbableTypo) {
15914 bool BodyColInvalid;
15915 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15917 if (BodyColInvalid)
15920 bool StmtColInvalid;
15923 if (StmtColInvalid)
15926 if (BodyCol > StmtCol)
15927 ProbableTypo =
true;
15930 if (ProbableTypo) {
15932 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15940 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15952 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15954 RHSExpr = CE->
getArg(0);
15955 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15956 CXXSCE && CXXSCE->isXValue())
15957 RHSExpr = CXXSCE->getSubExpr();
15961 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15962 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15965 if (LHSDeclRef && RHSDeclRef) {
15972 auto D =
Diag(OpLoc, diag::warn_self_move)
15988 const Expr *LHSBase = LHSExpr;
15989 const Expr *RHSBase = RHSExpr;
15990 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15991 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15992 if (!LHSME || !RHSME)
15995 while (LHSME && RHSME) {
16002 LHSME = dyn_cast<MemberExpr>(LHSBase);
16003 RHSME = dyn_cast<MemberExpr>(RHSBase);
16006 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16007 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16008 if (LHSDeclRef && RHSDeclRef) {
16015 Diag(OpLoc, diag::warn_self_move)
16022 Diag(OpLoc, diag::warn_self_move)
16046 bool AreUnionMembers =
false) {
16050 assert(((Field1Parent->isStructureOrClassType() &&
16051 Field2Parent->isStructureOrClassType()) ||
16052 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16053 "Can't evaluate layout compatibility between a struct field and a "
16055 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16056 (AreUnionMembers && Field1Parent->isUnionType())) &&
16057 "AreUnionMembers should be 'true' for union fields (only).");
16071 if (Bits1 != Bits2)
16075 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16076 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16079 if (!AreUnionMembers &&
16091 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16092 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16094 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16095 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16100 return isLayoutCompatible(C, F1, F2);
16111 for (
auto *Field1 : RD1->
fields()) {
16112 auto I = UnmatchedFields.begin();
16113 auto E = UnmatchedFields.end();
16115 for ( ; I != E; ++I) {
16117 bool Result = UnmatchedFields.erase(*I);
16127 return UnmatchedFields.empty();
16153 if (
C.hasSameType(T1, T2))
16162 if (TC1 == Type::Enum)
16164 if (TC1 == Type::Record) {
16183 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16214 const ValueDecl **VD, uint64_t *MagicValue,
16215 bool isConstantEvaluated) {
16223 case Stmt::UnaryOperatorClass: {
16232 case Stmt::DeclRefExprClass: {
16238 case Stmt::IntegerLiteralClass: {
16240 llvm::APInt MagicValueAPInt = IL->
getValue();
16241 if (MagicValueAPInt.getActiveBits() <= 64) {
16242 *MagicValue = MagicValueAPInt.getZExtValue();
16248 case Stmt::BinaryConditionalOperatorClass:
16249 case Stmt::ConditionalOperatorClass: {
16254 isConstantEvaluated)) {
16264 case Stmt::BinaryOperatorClass: {
16267 TypeExpr = BO->
getRHS();
16297 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16300 bool isConstantEvaluated) {
16301 FoundWrongKind =
false;
16306 uint64_t MagicValue;
16308 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16312 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16313 if (I->getArgumentKind() != ArgumentKind) {
16314 FoundWrongKind =
true;
16317 TypeInfo.Type = I->getMatchingCType();
16318 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16319 TypeInfo.MustBeNull = I->getMustBeNull();
16330 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16331 if (I == MagicValues->end())
16340 bool LayoutCompatible,
16342 if (!TypeTagForDatatypeMagicValues)
16343 TypeTagForDatatypeMagicValues.reset(
16344 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16347 (*TypeTagForDatatypeMagicValues)[Magic] =
16363 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16364 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16365 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16366 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16369void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16372 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16373 bool IsPointerAttr = Attr->getIsPointer();
16376 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16377 if (TypeTagIdxAST >= ExprArgs.size()) {
16378 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16379 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16382 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16383 bool FoundWrongKind;
16386 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16388 if (FoundWrongKind)
16390 diag::warn_type_tag_for_datatype_wrong_kind)
16396 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16397 if (ArgumentIdxAST >= ExprArgs.size()) {
16398 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16399 << 1 << Attr->getArgumentIdx().getSourceIndex();
16402 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16403 if (IsPointerAttr) {
16405 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16406 if (ICE->getType()->isVoidPointerType() &&
16407 ICE->getCastKind() == CK_BitCast)
16408 ArgumentExpr = ICE->getSubExpr();
16410 QualType ArgumentType = ArgumentExpr->
getType();
16416 if (TypeInfo.MustBeNull) {
16421 diag::warn_type_safety_null_pointer_required)
16429 QualType RequiredType = TypeInfo.Type;
16431 RequiredType =
Context.getPointerType(RequiredType);
16433 bool mismatch =
false;
16434 if (!TypeInfo.LayoutCompatible) {
16435 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16456 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16457 << ArgumentType << ArgumentKind
16458 << TypeInfo.LayoutCompatible << RequiredType
16476 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16484 if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())
16490 auto &MisalignedMembersForExpr =
16492 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16493 if (MA != MisalignedMembersForExpr.end() &&
16494 (T->isDependentType() || T->isIntegerType() ||
16495 (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
16497 T->getPointeeType()) <= MA->Alignment))))
16498 MisalignedMembersForExpr.erase(MA);
16507 const auto *ME = dyn_cast<MemberExpr>(E);
16519 bool AnyIsPacked =
false;
16521 QualType BaseType = ME->getBase()->getType();
16522 if (BaseType->isDependentType())
16526 auto *RD = BaseType->castAsRecordDecl();
16531 auto *FD = dyn_cast<FieldDecl>(MD);
16537 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16538 ReverseMemberChain.push_back(FD);
16541 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16543 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16550 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16561 if (ExpectedAlignment.
isOne())
16566 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16567 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16571 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16575 if (DRE && !TopME->
isArrow()) {
16578 CompleteObjectAlignment =
16579 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16583 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16586 CompleteObjectAlignment < ExpectedAlignment) {
16597 for (
FieldDecl *FDI : ReverseMemberChain) {
16598 if (FDI->hasAttr<PackedAttr>() ||
16599 FDI->getParent()->hasAttr<PackedAttr>()) {
16601 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16607 assert(FD &&
"We did not find a packed FieldDecl!");
16608 Action(E, FD->
getParent(), FD, Alignment);
16612void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16613 using namespace std::placeholders;
16616 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16640bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16641 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16668 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16685 assert(!Args.empty() &&
"Should have at least one argument.");
16687 Expr *Arg0 = Args.front();
16690 auto EmitError = [&](
Expr *ArgI) {
16692 diag::err_typecheck_call_different_arg_types)
16693 << Arg0->
getType() << ArgI->getType();
16698 for (
Expr *ArgI : Args.drop_front())
16709 for (
Expr *ArgI : Args.drop_front()) {
16710 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16713 VecI->getElementType()) ||
16714 Vec0->getNumElements() != VecI->getNumElements()) {
16723std::optional<QualType>
16727 return std::nullopt;
16731 return std::nullopt;
16734 for (
int I = 0; I < 2; ++I) {
16738 return std::nullopt;
16739 Args[I] = Converted.
get();
16746 return std::nullopt;
16749 return std::nullopt;
16751 TheCall->
setArg(0, Args[0]);
16752 TheCall->
setArg(1, Args[1]);
16763 TheCall->
getArg(1), Loc) ||
16765 TheCall->
getArg(2), Loc))
16769 for (
int I = 0; I < 3; ++I) {
16774 Args[I] = Converted.
get();
16777 int ArgOrdinal = 1;
16778 for (
Expr *Arg : Args) {
16780 ArgTyRestr, ArgOrdinal++))
16787 for (
int I = 0; I < 3; ++I)
16788 TheCall->
setArg(I, Args[I]);
16794bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16806bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16815 diag::err_builtin_invalid_arg_type)
16816 << 1 << 2 << 1 << 1 << TyArg;
16830 Expr *Matrix = MatrixArg.
get();
16832 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16835 << 1 << 3 << 0 << 0
16842 QualType ResultType =
Context.getConstantMatrixType(
16843 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16846 TheCall->
setType(ResultType);
16849 TheCall->
setArg(0, Matrix);
16854static std::optional<unsigned>
16862 uint64_t
Dim =
Value->getZExtValue();
16878 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16880 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16888 unsigned PtrArgIdx = 0;
16889 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16890 Expr *RowsExpr = TheCall->
getArg(1);
16891 Expr *ColumnsExpr = TheCall->
getArg(2);
16892 Expr *StrideExpr = TheCall->
getArg(3);
16894 bool ArgError =
false;
16901 PtrExpr = PtrConv.
get();
16902 TheCall->
setArg(0, PtrExpr);
16909 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16910 QualType ElementTy;
16913 << PtrArgIdx + 1 << 0 << 5 << 0
16917 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16921 << PtrArgIdx + 1 << 0 << 5
16928 auto ApplyArgumentConversions = [
this](Expr *E) {
16937 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16939 RowsExpr = RowsConv.
get();
16940 TheCall->
setArg(1, RowsExpr);
16942 RowsExpr =
nullptr;
16944 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16946 ColumnsExpr = ColumnsConv.
get();
16947 TheCall->
setArg(2, ColumnsExpr);
16949 ColumnsExpr =
nullptr;
16960 std::optional<unsigned> MaybeRows;
16964 std::optional<unsigned> MaybeColumns;
16969 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16972 StrideExpr = StrideConv.
get();
16973 TheCall->
setArg(3, StrideExpr);
16976 if (std::optional<llvm::APSInt>
Value =
16979 if (Stride < *MaybeRows) {
16981 diag::err_builtin_matrix_stride_too_small);
16987 if (ArgError || !MaybeRows || !MaybeColumns)
16991 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17002 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17004 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17012 unsigned PtrArgIdx = 1;
17013 Expr *MatrixExpr = TheCall->
getArg(0);
17014 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17015 Expr *StrideExpr = TheCall->
getArg(2);
17017 bool ArgError =
false;
17023 MatrixExpr = MatrixConv.
get();
17024 TheCall->
setArg(0, MatrixExpr);
17031 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17034 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17042 PtrExpr = PtrConv.
get();
17043 TheCall->
setArg(1, PtrExpr);
17051 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17054 << PtrArgIdx + 1 << 0 << 5 << 0
17058 QualType ElementTy = PtrTy->getPointeeType();
17060 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17065 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17067 diag::err_builtin_matrix_pointer_arg_mismatch)
17068 << ElementTy << MatrixTy->getElementType();
17083 StrideExpr = StrideConv.
get();
17084 TheCall->
setArg(2, StrideExpr);
17089 if (std::optional<llvm::APSInt>
Value =
17092 if (Stride < MatrixTy->getNumRows()) {
17094 diag::err_builtin_matrix_stride_too_small);
17114 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17119 llvm::StringSet<> CalleeTCBs;
17120 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17121 CalleeTCBs.insert(A->getTCBName());
17122 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17123 CalleeTCBs.insert(A->getTCBName());
17127 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17128 StringRef CallerTCB = A->getTCBName();
17129 if (CalleeTCBs.count(CallerTCB) == 0) {
17130 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17131 << 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.
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 bool IsSameCharType(QualType T1, QualType T2)
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth)
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static 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 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.
bool empty() const
Return true if no decls were found.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
UnresolvedSetImpl::iterator iterator
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
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 isAtomicType() const
bool isFunctionProtoType() 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
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
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)
llvm::json::Object Object
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.