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());
2186 switch (ArgTyRestr) {
2189 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2190 << ArgOrdinal << 2 << 1 << 1
2197 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2198 << ArgOrdinal << 5 << 0
2204 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2205 << ArgOrdinal << 5 << 1
2211 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2225 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2226 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2227 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2228 "Expecting __builtin_cpu_...");
2230 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2232 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2233 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2234 (!IsCPUSupports && TInfo->supportsCpuIs()));
2236 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2243 ? diag::err_builtin_aix_os_unsupported
2244 : diag::err_builtin_target_unsupported)
2250 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2288 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2289 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8 &&
2290 BT->getNumBits() != 1) {
2292 << ArgTy << BT->getNumBits();
2362 TheCall->
setArg(0, Arg0);
2379 TheCall->
setArg(1, Arg1);
2385 << 2 << 1 << 4 << 0 << Arg1Ty;
2399 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2401 << (OnlyUnsigned ? 3 : 1)
2409 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2412 return OnlyUnsigned ? T->isUnsignedIntegerType() : T->isIntegerType();
2417 return emitError(S, Loc, T);
2422 return emitError(S, Loc, T);
2428 return emitError(S, Loc, T);
2433 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2438 return emitError(S, Loc, T);
2443 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2449 llvm_unreachable(
"conversion functions are permitted");
2468 TheCall->
setArg(0, Arg0);
2482 TheCall->
setArg(1, Arg1);
2493 unsigned Pos,
bool AllowConst,
2497 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2502 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2503 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2504 << Pos <<
"scalar pointer";
2513 diag::err_typecheck_convert_incompatible)
2522 bool TypeDependent =
false;
2523 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2551 Builtin::BI__builtin_masked_load))
2565 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2588 Builtin::BI__builtin_masked_store))
2596 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2606 diag::err_vec_builtin_incompatible_vector)
2635 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2648 << MaskTy << IdxTy);
2657 diag::err_vec_masked_load_store_ptr)
2686 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2702 << MaskTy << IdxTy);
2708 << MaskTy << ValTy);
2714 diag::err_vec_builtin_incompatible_vector)
2728 if (Args.size() == 0) {
2730 diag::err_typecheck_call_too_few_args_at_least)
2736 QualType FuncT = Args[0]->getType();
2739 if (Args.size() < 2) {
2741 diag::err_typecheck_call_too_few_args_at_least)
2747 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2748 QualType ObjectT = Args[1]->getType();
2750 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2799 tok::periodstar, ObjectArg.
get(), Args[0]);
2803 if (MPT->isMemberDataPointer())
2806 auto *MemCall =
new (S.
Context)
2830 return TyA->getElementType();
2837Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2842 unsigned ICEArguments = 0;
2844 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2849 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2851 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2856 if (ArgNo < TheCall->getNumArgs() &&
2859 ICEArguments &= ~(1 << ArgNo);
2863 switch (BuiltinID) {
2864 case Builtin::BI__builtin_cpu_supports:
2865 case Builtin::BI__builtin_cpu_is:
2867 Context.getAuxTargetInfo(), BuiltinID))
2870 case Builtin::BI__builtin_cpu_init:
2871 if (!
Context.getTargetInfo().supportsCpuInit()) {
2877 case Builtin::BI__builtin___CFStringMakeConstantString:
2881 *
this, BuiltinID, TheCall,
2882 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2885 "Wrong # arguments to builtin CFStringMakeConstantString");
2886 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2889 case Builtin::BI__builtin_ms_va_start:
2890 case Builtin::BI__builtin_stdarg_start:
2891 case Builtin::BI__builtin_va_start:
2892 case Builtin::BI__builtin_c23_va_start:
2893 if (BuiltinVAStart(BuiltinID, TheCall))
2896 case Builtin::BI__va_start: {
2897 switch (
Context.getTargetInfo().getTriple().getArch()) {
2898 case llvm::Triple::aarch64:
2899 case llvm::Triple::arm:
2900 case llvm::Triple::thumb:
2901 if (BuiltinVAStartARMMicrosoft(TheCall))
2905 if (BuiltinVAStart(BuiltinID, TheCall))
2913 case Builtin::BI_interlockedbittestandset_acq:
2914 case Builtin::BI_interlockedbittestandset_rel:
2915 case Builtin::BI_interlockedbittestandset_nf:
2916 case Builtin::BI_interlockedbittestandreset_acq:
2917 case Builtin::BI_interlockedbittestandreset_rel:
2918 case Builtin::BI_interlockedbittestandreset_nf:
2921 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2926 case Builtin::BI_bittest64:
2927 case Builtin::BI_bittestandcomplement64:
2928 case Builtin::BI_bittestandreset64:
2929 case Builtin::BI_bittestandset64:
2930 case Builtin::BI_interlockedbittestandreset64:
2931 case Builtin::BI_interlockedbittestandset64:
2934 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2935 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2940 case Builtin::BI_interlockedbittestandreset64_acq:
2941 case Builtin::BI_interlockedbittestandreset64_rel:
2942 case Builtin::BI_interlockedbittestandreset64_nf:
2943 case Builtin::BI_interlockedbittestandset64_acq:
2944 case Builtin::BI_interlockedbittestandset64_rel:
2945 case Builtin::BI_interlockedbittestandset64_nf:
2950 case Builtin::BI__builtin_set_flt_rounds:
2953 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2954 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2955 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2956 llvm::Triple::ppc64le}))
2960 case Builtin::BI__builtin_isgreater:
2961 case Builtin::BI__builtin_isgreaterequal:
2962 case Builtin::BI__builtin_isless:
2963 case Builtin::BI__builtin_islessequal:
2964 case Builtin::BI__builtin_islessgreater:
2965 case Builtin::BI__builtin_isunordered:
2966 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2969 case Builtin::BI__builtin_fpclassify:
2970 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2973 case Builtin::BI__builtin_isfpclass:
2974 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2977 case Builtin::BI__builtin_isfinite:
2978 case Builtin::BI__builtin_isinf:
2979 case Builtin::BI__builtin_isinf_sign:
2980 case Builtin::BI__builtin_isnan:
2981 case Builtin::BI__builtin_issignaling:
2982 case Builtin::BI__builtin_isnormal:
2983 case Builtin::BI__builtin_issubnormal:
2984 case Builtin::BI__builtin_iszero:
2985 case Builtin::BI__builtin_signbit:
2986 case Builtin::BI__builtin_signbitf:
2987 case Builtin::BI__builtin_signbitl:
2988 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2991 case Builtin::BI__builtin_shufflevector:
2995 case Builtin::BI__builtin_masked_load:
2996 case Builtin::BI__builtin_masked_expand_load:
2998 case Builtin::BI__builtin_masked_store:
2999 case Builtin::BI__builtin_masked_compress_store:
3001 case Builtin::BI__builtin_masked_gather:
3003 case Builtin::BI__builtin_masked_scatter:
3005 case Builtin::BI__builtin_invoke:
3007 case Builtin::BI__builtin_prefetch:
3008 if (BuiltinPrefetch(TheCall))
3011 case Builtin::BI__builtin_alloca_with_align:
3012 case Builtin::BI__builtin_alloca_with_align_uninitialized:
3013 if (BuiltinAllocaWithAlign(TheCall))
3016 case Builtin::BI__builtin_alloca:
3017 case Builtin::BI__builtin_alloca_uninitialized:
3024 case Builtin::BI__builtin_infer_alloc_token:
3028 case Builtin::BI__arithmetic_fence:
3029 if (BuiltinArithmeticFence(TheCall))
3032 case Builtin::BI__assume:
3033 case Builtin::BI__builtin_assume:
3034 if (BuiltinAssume(TheCall))
3037 case Builtin::BI__builtin_assume_aligned:
3038 if (BuiltinAssumeAligned(TheCall))
3041 case Builtin::BI__builtin_dynamic_object_size:
3042 case Builtin::BI__builtin_object_size:
3046 case Builtin::BI__builtin_longjmp:
3047 if (BuiltinLongjmp(TheCall))
3050 case Builtin::BI__builtin_setjmp:
3051 if (BuiltinSetjmp(TheCall))
3054 case Builtin::BI__builtin_complex:
3055 if (BuiltinComplex(TheCall))
3058 case Builtin::BI__builtin_classify_type:
3059 case Builtin::BI__builtin_constant_p: {
3068 case Builtin::BI__builtin_launder:
3070 case Builtin::BI__builtin_is_within_lifetime:
3072 case Builtin::BI__builtin_trivially_relocate:
3075 case Builtin::BI__sync_fetch_and_add:
3076 case Builtin::BI__sync_fetch_and_add_1:
3077 case Builtin::BI__sync_fetch_and_add_2:
3078 case Builtin::BI__sync_fetch_and_add_4:
3079 case Builtin::BI__sync_fetch_and_add_8:
3080 case Builtin::BI__sync_fetch_and_add_16:
3081 case Builtin::BI__sync_fetch_and_sub:
3082 case Builtin::BI__sync_fetch_and_sub_1:
3083 case Builtin::BI__sync_fetch_and_sub_2:
3084 case Builtin::BI__sync_fetch_and_sub_4:
3085 case Builtin::BI__sync_fetch_and_sub_8:
3086 case Builtin::BI__sync_fetch_and_sub_16:
3087 case Builtin::BI__sync_fetch_and_or:
3088 case Builtin::BI__sync_fetch_and_or_1:
3089 case Builtin::BI__sync_fetch_and_or_2:
3090 case Builtin::BI__sync_fetch_and_or_4:
3091 case Builtin::BI__sync_fetch_and_or_8:
3092 case Builtin::BI__sync_fetch_and_or_16:
3093 case Builtin::BI__sync_fetch_and_and:
3094 case Builtin::BI__sync_fetch_and_and_1:
3095 case Builtin::BI__sync_fetch_and_and_2:
3096 case Builtin::BI__sync_fetch_and_and_4:
3097 case Builtin::BI__sync_fetch_and_and_8:
3098 case Builtin::BI__sync_fetch_and_and_16:
3099 case Builtin::BI__sync_fetch_and_xor:
3100 case Builtin::BI__sync_fetch_and_xor_1:
3101 case Builtin::BI__sync_fetch_and_xor_2:
3102 case Builtin::BI__sync_fetch_and_xor_4:
3103 case Builtin::BI__sync_fetch_and_xor_8:
3104 case Builtin::BI__sync_fetch_and_xor_16:
3105 case Builtin::BI__sync_fetch_and_nand:
3106 case Builtin::BI__sync_fetch_and_nand_1:
3107 case Builtin::BI__sync_fetch_and_nand_2:
3108 case Builtin::BI__sync_fetch_and_nand_4:
3109 case Builtin::BI__sync_fetch_and_nand_8:
3110 case Builtin::BI__sync_fetch_and_nand_16:
3111 case Builtin::BI__sync_add_and_fetch:
3112 case Builtin::BI__sync_add_and_fetch_1:
3113 case Builtin::BI__sync_add_and_fetch_2:
3114 case Builtin::BI__sync_add_and_fetch_4:
3115 case Builtin::BI__sync_add_and_fetch_8:
3116 case Builtin::BI__sync_add_and_fetch_16:
3117 case Builtin::BI__sync_sub_and_fetch:
3118 case Builtin::BI__sync_sub_and_fetch_1:
3119 case Builtin::BI__sync_sub_and_fetch_2:
3120 case Builtin::BI__sync_sub_and_fetch_4:
3121 case Builtin::BI__sync_sub_and_fetch_8:
3122 case Builtin::BI__sync_sub_and_fetch_16:
3123 case Builtin::BI__sync_and_and_fetch:
3124 case Builtin::BI__sync_and_and_fetch_1:
3125 case Builtin::BI__sync_and_and_fetch_2:
3126 case Builtin::BI__sync_and_and_fetch_4:
3127 case Builtin::BI__sync_and_and_fetch_8:
3128 case Builtin::BI__sync_and_and_fetch_16:
3129 case Builtin::BI__sync_or_and_fetch:
3130 case Builtin::BI__sync_or_and_fetch_1:
3131 case Builtin::BI__sync_or_and_fetch_2:
3132 case Builtin::BI__sync_or_and_fetch_4:
3133 case Builtin::BI__sync_or_and_fetch_8:
3134 case Builtin::BI__sync_or_and_fetch_16:
3135 case Builtin::BI__sync_xor_and_fetch:
3136 case Builtin::BI__sync_xor_and_fetch_1:
3137 case Builtin::BI__sync_xor_and_fetch_2:
3138 case Builtin::BI__sync_xor_and_fetch_4:
3139 case Builtin::BI__sync_xor_and_fetch_8:
3140 case Builtin::BI__sync_xor_and_fetch_16:
3141 case Builtin::BI__sync_nand_and_fetch:
3142 case Builtin::BI__sync_nand_and_fetch_1:
3143 case Builtin::BI__sync_nand_and_fetch_2:
3144 case Builtin::BI__sync_nand_and_fetch_4:
3145 case Builtin::BI__sync_nand_and_fetch_8:
3146 case Builtin::BI__sync_nand_and_fetch_16:
3147 case Builtin::BI__sync_val_compare_and_swap:
3148 case Builtin::BI__sync_val_compare_and_swap_1:
3149 case Builtin::BI__sync_val_compare_and_swap_2:
3150 case Builtin::BI__sync_val_compare_and_swap_4:
3151 case Builtin::BI__sync_val_compare_and_swap_8:
3152 case Builtin::BI__sync_val_compare_and_swap_16:
3153 case Builtin::BI__sync_bool_compare_and_swap:
3154 case Builtin::BI__sync_bool_compare_and_swap_1:
3155 case Builtin::BI__sync_bool_compare_and_swap_2:
3156 case Builtin::BI__sync_bool_compare_and_swap_4:
3157 case Builtin::BI__sync_bool_compare_and_swap_8:
3158 case Builtin::BI__sync_bool_compare_and_swap_16:
3159 case Builtin::BI__sync_lock_test_and_set:
3160 case Builtin::BI__sync_lock_test_and_set_1:
3161 case Builtin::BI__sync_lock_test_and_set_2:
3162 case Builtin::BI__sync_lock_test_and_set_4:
3163 case Builtin::BI__sync_lock_test_and_set_8:
3164 case Builtin::BI__sync_lock_test_and_set_16:
3165 case Builtin::BI__sync_lock_release:
3166 case Builtin::BI__sync_lock_release_1:
3167 case Builtin::BI__sync_lock_release_2:
3168 case Builtin::BI__sync_lock_release_4:
3169 case Builtin::BI__sync_lock_release_8:
3170 case Builtin::BI__sync_lock_release_16:
3171 case Builtin::BI__sync_swap:
3172 case Builtin::BI__sync_swap_1:
3173 case Builtin::BI__sync_swap_2:
3174 case Builtin::BI__sync_swap_4:
3175 case Builtin::BI__sync_swap_8:
3176 case Builtin::BI__sync_swap_16:
3177 return BuiltinAtomicOverloaded(TheCallResult);
3178 case Builtin::BI__sync_synchronize:
3182 case Builtin::BI__builtin_nontemporal_load:
3183 case Builtin::BI__builtin_nontemporal_store:
3184 return BuiltinNontemporalOverloaded(TheCallResult);
3185 case Builtin::BI__builtin_memcpy_inline: {
3186 clang::Expr *SizeOp = TheCall->
getArg(2);
3198 case Builtin::BI__builtin_memset_inline: {
3199 clang::Expr *SizeOp = TheCall->
getArg(2);
3209#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3210 case Builtin::BI##ID: \
3211 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3212#include "clang/Basic/Builtins.inc"
3213 case Builtin::BI__annotation:
3217 case Builtin::BI__builtin_annotation:
3221 case Builtin::BI__builtin_addressof:
3225 case Builtin::BI__builtin_function_start:
3229 case Builtin::BI__builtin_is_aligned:
3230 case Builtin::BI__builtin_align_up:
3231 case Builtin::BI__builtin_align_down:
3235 case Builtin::BI__builtin_add_overflow:
3236 case Builtin::BI__builtin_sub_overflow:
3237 case Builtin::BI__builtin_mul_overflow:
3241 case Builtin::BI__builtin_operator_new:
3242 case Builtin::BI__builtin_operator_delete: {
3243 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3245 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3248 case Builtin::BI__builtin_dump_struct:
3250 case Builtin::BI__builtin_expect_with_probability: {
3255 const Expr *ProbArg = TheCall->
getArg(2);
3256 SmallVector<PartialDiagnosticAt, 8> Notes;
3257 Expr::EvalResult Eval;
3261 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3268 bool LoseInfo =
false;
3269 Probability.convert(llvm::APFloat::IEEEdouble(),
3270 llvm::RoundingMode::Dynamic, &LoseInfo);
3271 if (!(Probability >= llvm::APFloat(0.0) &&
3272 Probability <= llvm::APFloat(1.0))) {
3279 case Builtin::BI__builtin_preserve_access_index:
3283 case Builtin::BI__builtin_call_with_static_chain:
3287 case Builtin::BI__exception_code:
3288 case Builtin::BI_exception_code:
3290 diag::err_seh___except_block))
3293 case Builtin::BI__exception_info:
3294 case Builtin::BI_exception_info:
3296 diag::err_seh___except_filter))
3299 case Builtin::BI__GetExceptionInfo:
3311 case Builtin::BIaddressof:
3312 case Builtin::BI__addressof:
3313 case Builtin::BIforward:
3314 case Builtin::BIforward_like:
3315 case Builtin::BImove:
3316 case Builtin::BImove_if_noexcept:
3317 case Builtin::BIas_const: {
3325 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3326 BuiltinID == Builtin::BI__addressof;
3328 (ReturnsPointer ?
Result->isAnyPointerType()
3329 :
Result->isReferenceType()) &&
3332 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3338 case Builtin::BI__builtin_ptrauth_strip:
3340 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3342 case Builtin::BI__builtin_ptrauth_sign_constant:
3345 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3348 case Builtin::BI__builtin_ptrauth_auth:
3351 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3353 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3355 case Builtin::BI__builtin_ptrauth_auth_load_relative_and_sign:
3357 case Builtin::BI__builtin_ptrauth_string_discriminator:
3360 case Builtin::BI__builtin_get_vtable_pointer:
3364 case Builtin::BIread_pipe:
3365 case Builtin::BIwrite_pipe:
3368 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3371 case Builtin::BIreserve_read_pipe:
3372 case Builtin::BIreserve_write_pipe:
3373 case Builtin::BIwork_group_reserve_read_pipe:
3374 case Builtin::BIwork_group_reserve_write_pipe:
3375 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3378 case Builtin::BIsub_group_reserve_read_pipe:
3379 case Builtin::BIsub_group_reserve_write_pipe:
3380 if (
OpenCL().checkSubgroupExt(TheCall) ||
3381 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3384 case Builtin::BIcommit_read_pipe:
3385 case Builtin::BIcommit_write_pipe:
3386 case Builtin::BIwork_group_commit_read_pipe:
3387 case Builtin::BIwork_group_commit_write_pipe:
3388 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3391 case Builtin::BIsub_group_commit_read_pipe:
3392 case Builtin::BIsub_group_commit_write_pipe:
3393 if (
OpenCL().checkSubgroupExt(TheCall) ||
3394 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3397 case Builtin::BIget_pipe_num_packets:
3398 case Builtin::BIget_pipe_max_packets:
3399 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3402 case Builtin::BIto_global:
3403 case Builtin::BIto_local:
3404 case Builtin::BIto_private:
3405 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3409 case Builtin::BIenqueue_kernel:
3410 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3413 case Builtin::BIget_kernel_work_group_size:
3414 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3415 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3418 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3419 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3420 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3423 case Builtin::BI__builtin_os_log_format:
3424 Cleanup.setExprNeedsCleanups(
true);
3426 case Builtin::BI__builtin_os_log_format_buffer_size:
3427 if (BuiltinOSLogFormat(TheCall))
3430 case Builtin::BI__builtin_frame_address:
3431 case Builtin::BI__builtin_return_address: {
3440 Result.Val.getInt() != 0)
3442 << ((BuiltinID == Builtin::BI__builtin_return_address)
3443 ?
"__builtin_return_address"
3444 :
"__builtin_frame_address")
3449 case Builtin::BI__builtin_nondeterministic_value: {
3450 if (BuiltinNonDeterministicValue(TheCall))
3457 case Builtin::BI__builtin_elementwise_abs:
3465 case Builtin::BI__builtin_elementwise_acos:
3466 case Builtin::BI__builtin_elementwise_asin:
3467 case Builtin::BI__builtin_elementwise_atan:
3468 case Builtin::BI__builtin_elementwise_ceil:
3469 case Builtin::BI__builtin_elementwise_cos:
3470 case Builtin::BI__builtin_elementwise_cosh:
3471 case Builtin::BI__builtin_elementwise_exp:
3472 case Builtin::BI__builtin_elementwise_exp2:
3473 case Builtin::BI__builtin_elementwise_exp10:
3474 case Builtin::BI__builtin_elementwise_floor:
3475 case Builtin::BI__builtin_elementwise_log:
3476 case Builtin::BI__builtin_elementwise_log2:
3477 case Builtin::BI__builtin_elementwise_log10:
3478 case Builtin::BI__builtin_elementwise_roundeven:
3479 case Builtin::BI__builtin_elementwise_round:
3480 case Builtin::BI__builtin_elementwise_rint:
3481 case Builtin::BI__builtin_elementwise_nearbyint:
3482 case Builtin::BI__builtin_elementwise_sin:
3483 case Builtin::BI__builtin_elementwise_sinh:
3484 case Builtin::BI__builtin_elementwise_sqrt:
3485 case Builtin::BI__builtin_elementwise_tan:
3486 case Builtin::BI__builtin_elementwise_tanh:
3487 case Builtin::BI__builtin_elementwise_trunc:
3488 case Builtin::BI__builtin_elementwise_canonicalize:
3493 case Builtin::BI__builtin_elementwise_fma:
3498 case Builtin::BI__builtin_elementwise_ldexp: {
3520 const auto *Vec0 = TyA->
getAs<VectorType>();
3521 const auto *Vec1 = TyExp->
getAs<VectorType>();
3522 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3524 if (Arg0Length != Arg1Length) {
3526 diag::err_typecheck_vector_lengths_not_equal)
3540 case Builtin::BI__builtin_elementwise_minnum:
3541 case Builtin::BI__builtin_elementwise_maxnum:
3542 case Builtin::BI__builtin_elementwise_minimum:
3543 case Builtin::BI__builtin_elementwise_maximum:
3544 case Builtin::BI__builtin_elementwise_minimumnum:
3545 case Builtin::BI__builtin_elementwise_maximumnum:
3546 case Builtin::BI__builtin_elementwise_atan2:
3547 case Builtin::BI__builtin_elementwise_fmod:
3548 case Builtin::BI__builtin_elementwise_pow:
3549 if (BuiltinElementwiseMath(TheCall,
3555 case Builtin::BI__builtin_elementwise_add_sat:
3556 case Builtin::BI__builtin_elementwise_sub_sat:
3557 if (BuiltinElementwiseMath(TheCall,
3561 case Builtin::BI__builtin_elementwise_fshl:
3562 case Builtin::BI__builtin_elementwise_fshr:
3567 case Builtin::BI__builtin_elementwise_min:
3568 case Builtin::BI__builtin_elementwise_max: {
3569 if (BuiltinElementwiseMath(TheCall))
3571 Expr *Arg0 = TheCall->
getArg(0);
3572 Expr *Arg1 = TheCall->
getArg(1);
3573 QualType Ty0 = Arg0->
getType();
3574 QualType Ty1 = Arg1->
getType();
3575 const VectorType *VecTy0 = Ty0->
getAs<VectorType>();
3576 const VectorType *VecTy1 = Ty1->
getAs<VectorType>();
3579 (VecTy1 && VecTy1->getElementType()->isFloatingType()))
3580 Diag(TheCall->
getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion)
3581 <<
Context.BuiltinInfo.getQuotedName(BuiltinID);
3584 case Builtin::BI__builtin_elementwise_popcount:
3585 case Builtin::BI__builtin_elementwise_bitreverse:
3590 case Builtin::BI__builtin_elementwise_copysign: {
3599 QualType MagnitudeTy = Magnitude.
get()->
getType();
3612 diag::err_typecheck_call_different_arg_types)
3613 << MagnitudeTy << SignTy;
3621 case Builtin::BI__builtin_elementwise_clzg:
3622 case Builtin::BI__builtin_elementwise_ctzg:
3630 }
else if (BuiltinElementwiseMath(
3634 case Builtin::BI__builtin_reduce_max:
3635 case Builtin::BI__builtin_reduce_min: {
3636 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3639 const Expr *Arg = TheCall->
getArg(0);
3644 ElTy = TyA->getElementType();
3648 if (ElTy.isNull()) {
3658 case Builtin::BI__builtin_reduce_maximum:
3659 case Builtin::BI__builtin_reduce_minimum: {
3660 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3663 const Expr *Arg = TheCall->
getArg(0);
3668 ElTy = TyA->getElementType();
3672 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3685 case Builtin::BI__builtin_reduce_add:
3686 case Builtin::BI__builtin_reduce_mul:
3687 case Builtin::BI__builtin_reduce_xor:
3688 case Builtin::BI__builtin_reduce_or:
3689 case Builtin::BI__builtin_reduce_and: {
3690 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3693 const Expr *Arg = TheCall->
getArg(0);
3707 case Builtin::BI__builtin_reduce_assoc_fadd:
3708 case Builtin::BI__builtin_reduce_in_order_fadd: {
3710 bool InOrder = BuiltinID == Builtin::BI__builtin_reduce_in_order_fadd;
3735 diag::err_builtin_invalid_arg_type)
3747 case Builtin::BI__builtin_matrix_transpose:
3748 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3750 case Builtin::BI__builtin_matrix_column_major_load:
3751 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3753 case Builtin::BI__builtin_matrix_column_major_store:
3754 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3756 case Builtin::BI__builtin_verbose_trap:
3761 case Builtin::BI__builtin_get_device_side_mangled_name: {
3762 auto Check = [](CallExpr *TheCall) {
3768 auto *D = DRE->getDecl();
3771 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3772 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3774 if (!Check(TheCall)) {
3776 diag::err_hip_invalid_args_builtin_mangled_name);
3781 case Builtin::BI__builtin_bswapg:
3785 case Builtin::BI__builtin_bitreverseg:
3789 case Builtin::BI__builtin_popcountg:
3793 case Builtin::BI__builtin_clzg:
3794 case Builtin::BI__builtin_ctzg:
3799 case Builtin::BI__builtin_stdc_rotate_left:
3800 case Builtin::BI__builtin_stdc_rotate_right:
3805 case Builtin::BI__builtin_allow_runtime_check: {
3806 Expr *Arg = TheCall->
getArg(0);
3816 case Builtin::BI__builtin_allow_sanitize_check: {
3820 Expr *Arg = TheCall->
getArg(0);
3822 const StringLiteral *SanitizerName =
3824 if (!SanitizerName) {
3830 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
3831 .Cases({
"address",
"thread",
"memory",
"hwaddress",
3832 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
3836 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
3842 case Builtin::BI__builtin_counted_by_ref:
3843 if (BuiltinCountedByRef(TheCall))
3853 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3854 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3855 assert(
Context.getAuxTargetInfo() &&
3856 "Aux Target Builtin, but not an aux target?");
3858 if (CheckTSBuiltinFunctionCall(
3860 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3863 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3869 return TheCallResult;
3884 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3888 diag::err_argument_not_contiguous_bit_field)
3895 bool IsVariadic =
false;
3898 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3899 IsVariadic = BD->isVariadic();
3900 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3901 IsVariadic = OMD->isVariadic();
3908 bool HasImplicitThisParam,
bool IsVariadic,
3912 else if (IsVariadic)
3922 if (HasImplicitThisParam) {
3954 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
3955 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3956 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3957 Expr = ILE->getInit(0);
3967 const Expr *ArgExpr,
3971 S.
PDiag(diag::warn_null_arg)
3977 if (
auto nullability =
type->getNullability())
3988 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3994 llvm::SmallBitVector NonNullArgs;
4000 for (
const auto *Arg : Args)
4007 unsigned IdxAST = Idx.getASTIndex();
4008 if (IdxAST >= Args.size())
4010 if (NonNullArgs.empty())
4011 NonNullArgs.resize(Args.size());
4012 NonNullArgs.set(IdxAST);
4021 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
4026 unsigned ParamIndex = 0;
4028 I != E; ++I, ++ParamIndex) {
4031 if (NonNullArgs.empty())
4032 NonNullArgs.resize(Args.size());
4034 NonNullArgs.set(ParamIndex);
4041 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
4046 type = blockType->getPointeeType();
4060 if (NonNullArgs.empty())
4061 NonNullArgs.resize(Args.size());
4063 NonNullArgs.set(Index);
4072 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
4073 ArgIndex != ArgIndexEnd; ++ArgIndex) {
4074 if (NonNullArgs[ArgIndex])
4080 StringRef ParamName,
QualType ArgTy,
4103 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
4104 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
4108 if (ArgAlign < ParamAlign)
4109 Diag(Loc, diag::warn_param_mismatched_alignment)
4111 << ParamName << (FDecl !=
nullptr) << FDecl;
4115 const Expr *ThisArg,
4117 if (!FD || Args.empty())
4119 auto GetArgAt = [&](
int Idx) ->
const Expr * {
4120 if (Idx == LifetimeCaptureByAttr::Global ||
4121 Idx == LifetimeCaptureByAttr::Unknown)
4123 if (IsMemberFunction && Idx == 0)
4125 return Args[Idx - IsMemberFunction];
4127 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4132 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4133 for (
int CapturingParamIdx :
Attr->params()) {
4136 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4139 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4147 I + IsMemberFunction);
4149 if (IsMemberFunction) {
4157 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4170 llvm::SmallBitVector CheckedVarArgs;
4172 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4174 CheckedVarArgs.resize(Args.size());
4175 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4180 CheckedVarArgs.resize(Args.size());
4181 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4188 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4192 : isa_and_nonnull<FunctionDecl>(FDecl)
4194 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4198 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4200 if (
const Expr *Arg = Args[ArgIdx]) {
4201 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4208 if (FDecl || Proto) {
4213 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4214 CheckArgumentWithTypeTag(I, Args, Loc);
4220 if (!Proto && FDecl) {
4222 if (isa_and_nonnull<FunctionProtoType>(FT))
4228 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4230 bool IsScalableArg =
false;
4231 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4233 if (
const Expr *Arg = Args[ArgIdx]) {
4237 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4245 IsScalableArg =
true;
4247 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4256 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4257 llvm::StringMap<bool> CallerFeatureMap;
4258 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4259 if (!CallerFeatureMap.contains(
"sme"))
4260 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4261 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4262 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4271 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4273 (IsScalableArg || IsScalableRet)) {
4274 bool IsCalleeStreaming =
4276 bool IsCalleeStreamingCompatible =
4280 if (!IsCalleeStreamingCompatible &&
4284 unsigned VL = LO.VScaleMin * 128;
4285 unsigned SVL = LO.VScaleStreamingMin * 128;
4286 bool IsVLMismatch = VL && SVL && VL != SVL;
4288 auto EmitDiag = [&](
bool IsArg) {
4292 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4293 << IsArg << IsCalleeStreaming << SVL << VL;
4296 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4297 << IsArg << SVL << VL;
4299 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4316 bool CallerHasZAState =
false;
4317 bool CallerHasZT0State =
false;
4319 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4321 CallerHasZAState =
true;
4323 CallerHasZT0State =
true;
4327 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4329 CallerHasZT0State |=
4331 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4337 Diag(Loc, diag::err_sme_za_call_no_za_state);
4340 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4344 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4345 Diag(Loc, diag::note_sme_use_preserves_za);
4350 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4351 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4352 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4353 if (!Arg->isValueDependent()) {
4355 if (Arg->EvaluateAsInt(Align,
Context)) {
4356 const llvm::APSInt &I = Align.
Val.
getInt();
4357 if (!I.isPowerOf2())
4358 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4359 << Arg->getSourceRange();
4362 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4388 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4389 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4391 checkCall(FDecl, Proto,
nullptr, Args,
true,
4400 IsMemberOperatorCall;
4406 Expr *ImplicitThis =
nullptr;
4411 ImplicitThis = Args[0];
4414 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4425 ThisType =
Context.getPointerType(ThisType);
4431 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4449 CheckAbsoluteValueFunction(TheCall, FDecl);
4450 CheckMaxUnsignedZero(TheCall, FDecl);
4451 CheckInfNaNFunction(TheCall, FDecl);
4462 case Builtin::BIstrlcpy:
4463 case Builtin::BIstrlcat:
4464 CheckStrlcpycatArguments(TheCall, FnInfo);
4466 case Builtin::BIstrncat:
4467 CheckStrncatArguments(TheCall, FnInfo);
4469 case Builtin::BIfree:
4470 CheckFreeArguments(TheCall);
4473 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4482 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4483 Ty =
V->getType().getNonReferenceType();
4484 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4485 Ty = F->getType().getNonReferenceType();
4522 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4525 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4527 case AtomicExpr::AO__c11_atomic_init:
4528 case AtomicExpr::AO__opencl_atomic_init:
4529 llvm_unreachable(
"There is no ordering argument for an init");
4531 case AtomicExpr::AO__c11_atomic_load:
4532 case AtomicExpr::AO__opencl_atomic_load:
4533 case AtomicExpr::AO__hip_atomic_load:
4534 case AtomicExpr::AO__atomic_load_n:
4535 case AtomicExpr::AO__atomic_load:
4536 case AtomicExpr::AO__scoped_atomic_load_n:
4537 case AtomicExpr::AO__scoped_atomic_load:
4538 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4539 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4541 case AtomicExpr::AO__c11_atomic_store:
4542 case AtomicExpr::AO__opencl_atomic_store:
4543 case AtomicExpr::AO__hip_atomic_store:
4544 case AtomicExpr::AO__atomic_store:
4545 case AtomicExpr::AO__atomic_store_n:
4546 case AtomicExpr::AO__scoped_atomic_store:
4547 case AtomicExpr::AO__scoped_atomic_store_n:
4548 case AtomicExpr::AO__atomic_clear:
4549 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4550 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4551 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4610 const unsigned NumForm = ClearByte + 1;
4611 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4612 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4620 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4621 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4622 "need to update code for modified forms");
4623 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4624 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4625 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4626 "need to update code for modified C11 atomics");
4627 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4628 Op <= AtomicExpr::AO__opencl_atomic_store;
4629 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4630 Op <= AtomicExpr::AO__hip_atomic_store;
4631 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4632 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4633 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4634 Op <= AtomicExpr::AO__c11_atomic_store) ||
4636 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4637 Op == AtomicExpr::AO__atomic_store_n ||
4638 Op == AtomicExpr::AO__atomic_exchange_n ||
4639 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4640 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4641 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4642 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4643 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4647 enum ArithOpExtraValueType {
4652 unsigned ArithAllows = AOEVT_None;
4655 case AtomicExpr::AO__c11_atomic_init:
4656 case AtomicExpr::AO__opencl_atomic_init:
4660 case AtomicExpr::AO__c11_atomic_load:
4661 case AtomicExpr::AO__opencl_atomic_load:
4662 case AtomicExpr::AO__hip_atomic_load:
4663 case AtomicExpr::AO__atomic_load_n:
4664 case AtomicExpr::AO__scoped_atomic_load_n:
4665 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4669 case AtomicExpr::AO__atomic_load:
4670 case AtomicExpr::AO__scoped_atomic_load:
4671 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4675 case AtomicExpr::AO__c11_atomic_store:
4676 case AtomicExpr::AO__opencl_atomic_store:
4677 case AtomicExpr::AO__hip_atomic_store:
4678 case AtomicExpr::AO__atomic_store:
4679 case AtomicExpr::AO__atomic_store_n:
4680 case AtomicExpr::AO__scoped_atomic_store:
4681 case AtomicExpr::AO__scoped_atomic_store_n:
4682 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4685 case AtomicExpr::AO__atomic_fetch_add:
4686 case AtomicExpr::AO__atomic_fetch_sub:
4687 case AtomicExpr::AO__atomic_add_fetch:
4688 case AtomicExpr::AO__atomic_sub_fetch:
4689 case AtomicExpr::AO__scoped_atomic_fetch_add:
4690 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4691 case AtomicExpr::AO__scoped_atomic_add_fetch:
4692 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4693 case AtomicExpr::AO__c11_atomic_fetch_add:
4694 case AtomicExpr::AO__c11_atomic_fetch_sub:
4695 case AtomicExpr::AO__opencl_atomic_fetch_add:
4696 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4697 case AtomicExpr::AO__hip_atomic_fetch_add:
4698 case AtomicExpr::AO__hip_atomic_fetch_sub:
4699 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4702 case AtomicExpr::AO__atomic_fetch_max:
4703 case AtomicExpr::AO__atomic_fetch_min:
4704 case AtomicExpr::AO__atomic_max_fetch:
4705 case AtomicExpr::AO__atomic_min_fetch:
4706 case AtomicExpr::AO__scoped_atomic_fetch_max:
4707 case AtomicExpr::AO__scoped_atomic_fetch_min:
4708 case AtomicExpr::AO__scoped_atomic_max_fetch:
4709 case AtomicExpr::AO__scoped_atomic_min_fetch:
4710 case AtomicExpr::AO__c11_atomic_fetch_max:
4711 case AtomicExpr::AO__c11_atomic_fetch_min:
4712 case AtomicExpr::AO__opencl_atomic_fetch_max:
4713 case AtomicExpr::AO__opencl_atomic_fetch_min:
4714 case AtomicExpr::AO__hip_atomic_fetch_max:
4715 case AtomicExpr::AO__hip_atomic_fetch_min:
4716 ArithAllows = AOEVT_FP;
4719 case AtomicExpr::AO__c11_atomic_fetch_and:
4720 case AtomicExpr::AO__c11_atomic_fetch_or:
4721 case AtomicExpr::AO__c11_atomic_fetch_xor:
4722 case AtomicExpr::AO__hip_atomic_fetch_and:
4723 case AtomicExpr::AO__hip_atomic_fetch_or:
4724 case AtomicExpr::AO__hip_atomic_fetch_xor:
4725 case AtomicExpr::AO__c11_atomic_fetch_nand:
4726 case AtomicExpr::AO__opencl_atomic_fetch_and:
4727 case AtomicExpr::AO__opencl_atomic_fetch_or:
4728 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4729 case AtomicExpr::AO__atomic_fetch_and:
4730 case AtomicExpr::AO__atomic_fetch_or:
4731 case AtomicExpr::AO__atomic_fetch_xor:
4732 case AtomicExpr::AO__atomic_fetch_nand:
4733 case AtomicExpr::AO__atomic_and_fetch:
4734 case AtomicExpr::AO__atomic_or_fetch:
4735 case AtomicExpr::AO__atomic_xor_fetch:
4736 case AtomicExpr::AO__atomic_nand_fetch:
4737 case AtomicExpr::AO__atomic_fetch_uinc:
4738 case AtomicExpr::AO__atomic_fetch_udec:
4739 case AtomicExpr::AO__scoped_atomic_fetch_and:
4740 case AtomicExpr::AO__scoped_atomic_fetch_or:
4741 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4742 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4743 case AtomicExpr::AO__scoped_atomic_and_fetch:
4744 case AtomicExpr::AO__scoped_atomic_or_fetch:
4745 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4746 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4747 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
4748 case AtomicExpr::AO__scoped_atomic_fetch_udec:
4752 case AtomicExpr::AO__c11_atomic_exchange:
4753 case AtomicExpr::AO__hip_atomic_exchange:
4754 case AtomicExpr::AO__opencl_atomic_exchange:
4755 case AtomicExpr::AO__atomic_exchange_n:
4756 case AtomicExpr::AO__scoped_atomic_exchange_n:
4757 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4761 case AtomicExpr::AO__atomic_exchange:
4762 case AtomicExpr::AO__scoped_atomic_exchange:
4763 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4767 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4768 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4769 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4770 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4771 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4772 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4776 case AtomicExpr::AO__atomic_compare_exchange:
4777 case AtomicExpr::AO__atomic_compare_exchange_n:
4778 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4779 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4780 ArithAllows = AOEVT_Pointer;
4784 case AtomicExpr::AO__atomic_test_and_set:
4785 Form = TestAndSetByte;
4788 case AtomicExpr::AO__atomic_clear:
4793 unsigned AdjustedNumArgs = NumArgs[Form];
4794 if ((IsOpenCL || IsHIP || IsScoped) &&
4795 Op != AtomicExpr::AO__opencl_atomic_init)
4798 if (Args.size() < AdjustedNumArgs) {
4799 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4800 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4803 }
else if (Args.size() > AdjustedNumArgs) {
4804 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4805 diag::err_typecheck_call_too_many_args)
4806 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4812 Expr *Ptr = Args[0];
4817 Ptr = ConvertedPtr.
get();
4820 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4830 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4836 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4842 }
else if (Form != Load && Form != LoadCopy) {
4844 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4850 if (Form != TestAndSetByte && Form != ClearByte) {
4853 diag::err_incomplete_type))
4856 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4857 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4867 pointerType->getPointeeType().getCVRQualifiers());
4877 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4887 auto IsAllowedValueType = [&](
QualType ValType,
4888 unsigned AllowedType) ->
bool {
4889 bool IsX87LongDouble =
4891 &
Context.getTargetInfo().getLongDoubleFormat() ==
4892 &llvm::APFloat::x87DoubleExtended();
4896 return AllowedType & AOEVT_Pointer;
4900 if (IsX87LongDouble)
4904 if (!IsAllowedValueType(ValType, ArithAllows)) {
4905 auto DID = ArithAllows & AOEVT_FP
4906 ? (ArithAllows & AOEVT_Pointer
4907 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4908 : diag::err_atomic_op_needs_atomic_int_or_fp)
4909 : (ArithAllows & AOEVT_Pointer
4910 ? diag::err_atomic_op_needs_atomic_int_or_ptr
4911 : diag::err_atomic_op_needs_atomic_int);
4918 diag::err_incomplete_type)) {
4929 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4945 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4957 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4960 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4966 bool IsPassedByAddress =
false;
4967 if (!IsC11 && !IsHIP && !IsN) {
4969 IsPassedByAddress =
true;
4974 APIOrderedArgs.push_back(Args[0]);
4978 APIOrderedArgs.push_back(Args[1]);
4984 APIOrderedArgs.push_back(Args[2]);
4985 APIOrderedArgs.push_back(Args[1]);
4988 APIOrderedArgs.push_back(Args[2]);
4989 APIOrderedArgs.push_back(Args[3]);
4990 APIOrderedArgs.push_back(Args[1]);
4993 APIOrderedArgs.push_back(Args[2]);
4994 APIOrderedArgs.push_back(Args[4]);
4995 APIOrderedArgs.push_back(Args[1]);
4996 APIOrderedArgs.push_back(Args[3]);
4999 APIOrderedArgs.push_back(Args[2]);
5000 APIOrderedArgs.push_back(Args[4]);
5001 APIOrderedArgs.push_back(Args[5]);
5002 APIOrderedArgs.push_back(Args[1]);
5003 APIOrderedArgs.push_back(Args[3]);
5005 case TestAndSetByte:
5007 APIOrderedArgs.push_back(Args[1]);
5011 APIOrderedArgs.append(Args.begin(), Args.end());
5018 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
5020 if (i < NumVals[Form] + 1) {
5033 assert(Form != Load);
5035 Ty =
Context.getPointerDiffType();
5038 else if (Form ==
Copy || Form == Xchg) {
5039 if (IsPassedByAddress) {
5046 Expr *ValArg = APIOrderedArgs[i];
5053 AS = PtrTy->getPointeeType().getAddressSpace();
5062 if (IsPassedByAddress)
5082 APIOrderedArgs[i] = Arg.
get();
5087 SubExprs.push_back(Ptr);
5091 SubExprs.push_back(APIOrderedArgs[1]);
5094 case TestAndSetByte:
5096 SubExprs.push_back(APIOrderedArgs[1]);
5102 SubExprs.push_back(APIOrderedArgs[2]);
5103 SubExprs.push_back(APIOrderedArgs[1]);
5107 SubExprs.push_back(APIOrderedArgs[3]);
5108 SubExprs.push_back(APIOrderedArgs[1]);
5109 SubExprs.push_back(APIOrderedArgs[2]);
5112 SubExprs.push_back(APIOrderedArgs[3]);
5113 SubExprs.push_back(APIOrderedArgs[1]);
5114 SubExprs.push_back(APIOrderedArgs[4]);
5115 SubExprs.push_back(APIOrderedArgs[2]);
5118 SubExprs.push_back(APIOrderedArgs[4]);
5119 SubExprs.push_back(APIOrderedArgs[1]);
5120 SubExprs.push_back(APIOrderedArgs[5]);
5121 SubExprs.push_back(APIOrderedArgs[2]);
5122 SubExprs.push_back(APIOrderedArgs[3]);
5127 if (SubExprs.size() >= 2 && Form !=
Init) {
5128 std::optional<llvm::APSInt>
Success =
5129 SubExprs[1]->getIntegerConstantExpr(
Context);
5131 Diag(SubExprs[1]->getBeginLoc(),
5132 diag::warn_atomic_op_has_invalid_memory_order)
5133 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5134 << SubExprs[1]->getSourceRange();
5136 if (SubExprs.size() >= 5) {
5137 if (std::optional<llvm::APSInt> Failure =
5138 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5139 if (!llvm::is_contained(
5140 {llvm::AtomicOrderingCABI::relaxed,
5141 llvm::AtomicOrderingCABI::consume,
5142 llvm::AtomicOrderingCABI::acquire,
5143 llvm::AtomicOrderingCABI::seq_cst},
5144 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
5145 Diag(SubExprs[3]->getBeginLoc(),
5146 diag::warn_atomic_op_has_invalid_memory_order)
5147 << 2 << SubExprs[3]->getSourceRange();
5154 auto *
Scope = Args[Args.size() - 1];
5155 if (std::optional<llvm::APSInt>
Result =
5157 if (!ScopeModel->isValid(
Result->getZExtValue()))
5158 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5159 <<
Scope->getSourceRange();
5161 SubExprs.push_back(
Scope);
5167 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5168 Op == AtomicExpr::AO__c11_atomic_store ||
5169 Op == AtomicExpr::AO__opencl_atomic_load ||
5170 Op == AtomicExpr::AO__hip_atomic_load ||
5171 Op == AtomicExpr::AO__opencl_atomic_store ||
5172 Op == AtomicExpr::AO__hip_atomic_store) &&
5173 Context.AtomicUsesUnsupportedLibcall(AE))
5175 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5176 Op == AtomicExpr::AO__opencl_atomic_load ||
5177 Op == AtomicExpr::AO__hip_atomic_load)
5182 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5198 assert(Fn &&
"builtin call without direct callee!");
5214 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5221 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5223 <<
Callee->getSourceRange();
5232 Expr *FirstArg = TheCall->
getArg(0);
5236 FirstArg = FirstArgResult.
get();
5237 TheCall->
setArg(0, FirstArg);
5249 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5256 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5286 QualType ResultType = ValType;
5291#define BUILTIN_ROW(x) \
5292 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5293 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5295 static const unsigned BuiltinIndices[][5] = {
5320 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5321 case 1: SizeIndex = 0;
break;
5322 case 2: SizeIndex = 1;
break;
5323 case 4: SizeIndex = 2;
break;
5324 case 8: SizeIndex = 3;
break;
5325 case 16: SizeIndex = 4;
break;
5337 unsigned BuiltinIndex, NumFixed = 1;
5338 bool WarnAboutSemanticsChange =
false;
5339 switch (BuiltinID) {
5340 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5341 case Builtin::BI__sync_fetch_and_add:
5342 case Builtin::BI__sync_fetch_and_add_1:
5343 case Builtin::BI__sync_fetch_and_add_2:
5344 case Builtin::BI__sync_fetch_and_add_4:
5345 case Builtin::BI__sync_fetch_and_add_8:
5346 case Builtin::BI__sync_fetch_and_add_16:
5350 case Builtin::BI__sync_fetch_and_sub:
5351 case Builtin::BI__sync_fetch_and_sub_1:
5352 case Builtin::BI__sync_fetch_and_sub_2:
5353 case Builtin::BI__sync_fetch_and_sub_4:
5354 case Builtin::BI__sync_fetch_and_sub_8:
5355 case Builtin::BI__sync_fetch_and_sub_16:
5359 case Builtin::BI__sync_fetch_and_or:
5360 case Builtin::BI__sync_fetch_and_or_1:
5361 case Builtin::BI__sync_fetch_and_or_2:
5362 case Builtin::BI__sync_fetch_and_or_4:
5363 case Builtin::BI__sync_fetch_and_or_8:
5364 case Builtin::BI__sync_fetch_and_or_16:
5368 case Builtin::BI__sync_fetch_and_and:
5369 case Builtin::BI__sync_fetch_and_and_1:
5370 case Builtin::BI__sync_fetch_and_and_2:
5371 case Builtin::BI__sync_fetch_and_and_4:
5372 case Builtin::BI__sync_fetch_and_and_8:
5373 case Builtin::BI__sync_fetch_and_and_16:
5377 case Builtin::BI__sync_fetch_and_xor:
5378 case Builtin::BI__sync_fetch_and_xor_1:
5379 case Builtin::BI__sync_fetch_and_xor_2:
5380 case Builtin::BI__sync_fetch_and_xor_4:
5381 case Builtin::BI__sync_fetch_and_xor_8:
5382 case Builtin::BI__sync_fetch_and_xor_16:
5386 case Builtin::BI__sync_fetch_and_nand:
5387 case Builtin::BI__sync_fetch_and_nand_1:
5388 case Builtin::BI__sync_fetch_and_nand_2:
5389 case Builtin::BI__sync_fetch_and_nand_4:
5390 case Builtin::BI__sync_fetch_and_nand_8:
5391 case Builtin::BI__sync_fetch_and_nand_16:
5393 WarnAboutSemanticsChange =
true;
5396 case Builtin::BI__sync_add_and_fetch:
5397 case Builtin::BI__sync_add_and_fetch_1:
5398 case Builtin::BI__sync_add_and_fetch_2:
5399 case Builtin::BI__sync_add_and_fetch_4:
5400 case Builtin::BI__sync_add_and_fetch_8:
5401 case Builtin::BI__sync_add_and_fetch_16:
5405 case Builtin::BI__sync_sub_and_fetch:
5406 case Builtin::BI__sync_sub_and_fetch_1:
5407 case Builtin::BI__sync_sub_and_fetch_2:
5408 case Builtin::BI__sync_sub_and_fetch_4:
5409 case Builtin::BI__sync_sub_and_fetch_8:
5410 case Builtin::BI__sync_sub_and_fetch_16:
5414 case Builtin::BI__sync_and_and_fetch:
5415 case Builtin::BI__sync_and_and_fetch_1:
5416 case Builtin::BI__sync_and_and_fetch_2:
5417 case Builtin::BI__sync_and_and_fetch_4:
5418 case Builtin::BI__sync_and_and_fetch_8:
5419 case Builtin::BI__sync_and_and_fetch_16:
5423 case Builtin::BI__sync_or_and_fetch:
5424 case Builtin::BI__sync_or_and_fetch_1:
5425 case Builtin::BI__sync_or_and_fetch_2:
5426 case Builtin::BI__sync_or_and_fetch_4:
5427 case Builtin::BI__sync_or_and_fetch_8:
5428 case Builtin::BI__sync_or_and_fetch_16:
5432 case Builtin::BI__sync_xor_and_fetch:
5433 case Builtin::BI__sync_xor_and_fetch_1:
5434 case Builtin::BI__sync_xor_and_fetch_2:
5435 case Builtin::BI__sync_xor_and_fetch_4:
5436 case Builtin::BI__sync_xor_and_fetch_8:
5437 case Builtin::BI__sync_xor_and_fetch_16:
5441 case Builtin::BI__sync_nand_and_fetch:
5442 case Builtin::BI__sync_nand_and_fetch_1:
5443 case Builtin::BI__sync_nand_and_fetch_2:
5444 case Builtin::BI__sync_nand_and_fetch_4:
5445 case Builtin::BI__sync_nand_and_fetch_8:
5446 case Builtin::BI__sync_nand_and_fetch_16:
5448 WarnAboutSemanticsChange =
true;
5451 case Builtin::BI__sync_val_compare_and_swap:
5452 case Builtin::BI__sync_val_compare_and_swap_1:
5453 case Builtin::BI__sync_val_compare_and_swap_2:
5454 case Builtin::BI__sync_val_compare_and_swap_4:
5455 case Builtin::BI__sync_val_compare_and_swap_8:
5456 case Builtin::BI__sync_val_compare_and_swap_16:
5461 case Builtin::BI__sync_bool_compare_and_swap:
5462 case Builtin::BI__sync_bool_compare_and_swap_1:
5463 case Builtin::BI__sync_bool_compare_and_swap_2:
5464 case Builtin::BI__sync_bool_compare_and_swap_4:
5465 case Builtin::BI__sync_bool_compare_and_swap_8:
5466 case Builtin::BI__sync_bool_compare_and_swap_16:
5472 case Builtin::BI__sync_lock_test_and_set:
5473 case Builtin::BI__sync_lock_test_and_set_1:
5474 case Builtin::BI__sync_lock_test_and_set_2:
5475 case Builtin::BI__sync_lock_test_and_set_4:
5476 case Builtin::BI__sync_lock_test_and_set_8:
5477 case Builtin::BI__sync_lock_test_and_set_16:
5481 case Builtin::BI__sync_lock_release:
5482 case Builtin::BI__sync_lock_release_1:
5483 case Builtin::BI__sync_lock_release_2:
5484 case Builtin::BI__sync_lock_release_4:
5485 case Builtin::BI__sync_lock_release_8:
5486 case Builtin::BI__sync_lock_release_16:
5492 case Builtin::BI__sync_swap:
5493 case Builtin::BI__sync_swap_1:
5494 case Builtin::BI__sync_swap_2:
5495 case Builtin::BI__sync_swap_4:
5496 case Builtin::BI__sync_swap_8:
5497 case Builtin::BI__sync_swap_16:
5505 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5506 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5507 <<
Callee->getSourceRange();
5511 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5512 <<
Callee->getSourceRange();
5514 if (WarnAboutSemanticsChange) {
5515 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5516 <<
Callee->getSourceRange();
5521 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5522 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5523 FunctionDecl *NewBuiltinDecl;
5524 if (NewBuiltinID == BuiltinID)
5525 NewBuiltinDecl = FDecl;
5528 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5531 assert(Res.getFoundDecl());
5532 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5533 if (!NewBuiltinDecl)
5540 for (
unsigned i = 0; i != NumFixed; ++i) {
5569 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5571 CK_BuiltinFnToFnPtr);
5582 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5583 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5584 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5588 return TheCallResult;
5592 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5597 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5598 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5599 "Unexpected nontemporal load/store builtin!");
5600 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5601 unsigned numArgs = isStore ? 2 : 1;
5611 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5617 PointerArg = PointerArgResult.
get();
5618 TheCall->
setArg(numArgs - 1, PointerArg);
5622 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5635 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5642 return TheCallResult;
5654 return TheCallResult;
5661 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5663 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5664 Literal = ObjcLiteral->getString();
5668 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5675 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5676 InitializedEntity Entity =
5686 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5687 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5688 TT.getArch() == llvm::Triple::aarch64_32);
5689 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5690 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5691 if (IsX64 || IsAArch64) {
5698 return S.
Diag(Fn->getBeginLoc(),
5699 diag::err_ms_va_start_used_in_sysv_function);
5706 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5707 return S.
Diag(Fn->getBeginLoc(),
5708 diag::err_va_start_used_in_wrong_abi_function)
5709 << !IsWindowsOrUEFI;
5715 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5723 bool IsVariadic =
false;
5726 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5727 IsVariadic =
Block->isVariadic();
5728 Params =
Block->parameters();
5729 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5732 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5733 IsVariadic = MD->isVariadic();
5735 Params = MD->parameters();
5738 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5742 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5747 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5752 *LastParam = Params.empty() ?
nullptr : Params.back();
5757bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5762 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5786 ParmVarDecl *LastParam;
5797 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5799 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5804 if (std::optional<llvm::APSInt> Val =
5806 Val &&
LangOpts.C23 && *Val == 0 &&
5807 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5808 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5815 SourceLocation ParamLoc;
5816 bool IsCRegister =
false;
5817 bool SecondArgIsLastNonVariadicArgument =
false;
5818 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5819 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5820 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5823 ParamLoc = PV->getLocation();
5829 if (!SecondArgIsLastNonVariadicArgument)
5831 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5832 else if (IsCRegister ||
Type->isReferenceType() ||
5833 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5836 if (!Context.isPromotableIntegerType(Type))
5838 const auto *ED = Type->getAsEnumDecl();
5841 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5843 unsigned Reason = 0;
5844 if (
Type->isReferenceType()) Reason = 1;
5845 else if (IsCRegister) Reason = 2;
5846 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5847 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5854 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5874 if (
Call->getNumArgs() < 3)
5876 diag::err_typecheck_call_too_few_args_at_least)
5877 << 0 << 3 <<
Call->getNumArgs()
5893 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5896 const QualType &ConstCharPtrTy =
5898 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5900 << Arg1->
getType() << ConstCharPtrTy << 1
5903 << 2 << Arg1->
getType() << ConstCharPtrTy;
5905 const QualType SizeTy =
Context.getSizeType();
5910 << Arg2->
getType() << SizeTy << 1
5913 << 3 << Arg2->
getType() << SizeTy;
5918bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5922 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5950 diag::err_typecheck_call_invalid_ordered_compare)
5958bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5959 unsigned BuiltinID) {
5964 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5965 BuiltinID == Builtin::BI__builtin_isinf ||
5966 BuiltinID == Builtin::BI__builtin_isinf_sign))
5970 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5971 BuiltinID == Builtin::BI__builtin_isunordered))
5975 bool IsFPClass = NumArgs == 2;
5978 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5982 for (
unsigned i = 0; i < FPArgNo; ++i) {
5983 Expr *Arg = TheCall->
getArg(i);
5996 Expr *OrigArg = TheCall->
getArg(FPArgNo);
6004 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
6009 OrigArg = Res.
get();
6015 OrigArg = Res.
get();
6017 TheCall->
setArg(FPArgNo, OrigArg);
6019 QualType VectorResultTy;
6020 QualType ElementTy = OrigArg->
getType();
6025 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
6031 diag::err_typecheck_call_invalid_unary_fp)
6043 if (!VectorResultTy.
isNull())
6044 ResultTy = VectorResultTy;
6053bool Sema::BuiltinComplex(
CallExpr *TheCall) {
6058 for (
unsigned I = 0; I != 2; ++I) {
6059 Expr *Arg = TheCall->
getArg(I);
6069 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
6084 Expr *Real = TheCall->
getArg(0);
6085 Expr *Imag = TheCall->
getArg(1);
6088 diag::err_typecheck_call_different_arg_types)
6103 diag::err_typecheck_call_too_few_args_at_least)
6104 << 0 << 2 << NumArgs
6111 unsigned NumElements = 0;
6126 unsigned NumResElements = NumArgs - 2;
6135 diag::err_vec_builtin_incompatible_vector)
6140 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6142 diag::err_vec_builtin_incompatible_vector)
6147 }
else if (NumElements != NumResElements) {
6150 ?
Context.getExtVectorType(EltType, NumResElements)
6151 :
Context.getVectorType(EltType, NumResElements,
6156 for (
unsigned I = 2; I != NumArgs; ++I) {
6164 diag::err_shufflevector_nonconstant_argument)
6170 else if (
Result->getActiveBits() > 64 ||
6171 Result->getZExtValue() >= NumElements * 2)
6173 diag::err_shufflevector_argument_too_large)
6198 diag::err_convertvector_non_vector)
6201 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6203 <<
"__builtin_convertvector");
6208 if (SrcElts != DstElts)
6210 diag::err_convertvector_incompatible_vector)
6218bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6223 diag::err_typecheck_call_too_many_args_at_most)
6224 << 0 << 3 << NumArgs << 0
6229 for (
unsigned i = 1; i != NumArgs; ++i)
6236bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6237 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6238 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6248 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6258bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6259 Expr *Arg = TheCall->
getArg(0);
6270bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6272 Expr *Arg = TheCall->
getArg(1);
6276 if (
const auto *UE =
6278 if (UE->getKind() == UETT_AlignOf ||
6279 UE->getKind() == UETT_PreferredAlignOf)
6285 if (!
Result.isPowerOf2())
6286 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6293 if (
Result > std::numeric_limits<int32_t>::max())
6301bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6306 Expr *FirstArg = TheCall->
getArg(0);
6312 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6316 TheCall->
setArg(0, FirstArgResult.
get());
6320 Expr *SecondArg = TheCall->
getArg(1);
6328 if (!
Result.isPowerOf2())
6329 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6341 Expr *ThirdArg = TheCall->
getArg(2);
6344 TheCall->
setArg(2, ThirdArg);
6350bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6351 unsigned BuiltinID =
6353 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6356 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6357 if (NumArgs < NumRequiredArgs) {
6358 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6359 << 0 << NumRequiredArgs << NumArgs
6362 if (NumArgs >= NumRequiredArgs + 0x100) {
6364 diag::err_typecheck_call_too_many_args_at_most)
6365 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6376 if (Arg.isInvalid())
6378 TheCall->
setArg(i, Arg.get());
6383 unsigned FormatIdx = i;
6393 unsigned FirstDataArg = i;
6394 while (i < NumArgs) {
6412 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6414 bool Success = CheckFormatArguments(
6417 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6441 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6450 int High,
bool RangeIsError) {
6464 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6472 PDiag(diag::warn_argument_invalid_range)
6515 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6520 if (
Value.isNegative())
6531 if ((
Value & 0xFF) != 0)
6556 Result.setIsUnsigned(
true);
6561 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6581 Result.setIsUnsigned(
true);
6589 diag::err_argument_not_shifted_byte_or_xxff)
6593bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6594 if (!Context.getTargetInfo().hasSjLjLowering())
6595 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6606 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6612bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6613 if (!Context.getTargetInfo().hasSjLjLowering())
6614 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6619bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6634 diag::err_builtin_counted_by_ref_invalid_arg)
6639 diag::err_builtin_counted_by_ref_has_side_effects)
6642 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6644 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6649 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6656 QualType MemberTy = ME->getMemberDecl()->getType();
6659 diag::err_builtin_counted_by_ref_invalid_arg)
6663 diag::err_builtin_counted_by_ref_invalid_arg)
6673bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6675 const CallExpr *CE =
6684 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6689 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6694 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6698 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6702 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6712class UncoveredArgHandler {
6713 enum {
Unknown = -1, AllCovered = -2 };
6715 signed FirstUncoveredArg =
Unknown;
6716 SmallVector<const Expr *, 4> DiagnosticExprs;
6719 UncoveredArgHandler() =
default;
6721 bool hasUncoveredArg()
const {
6722 return (FirstUncoveredArg >= 0);
6725 unsigned getUncoveredArg()
const {
6726 assert(hasUncoveredArg() &&
"no uncovered argument");
6727 return FirstUncoveredArg;
6730 void setAllCovered() {
6733 DiagnosticExprs.clear();
6734 FirstUncoveredArg = AllCovered;
6737 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6738 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6741 if (FirstUncoveredArg == AllCovered)
6746 if (NewFirstUncoveredArg == FirstUncoveredArg)
6747 DiagnosticExprs.push_back(StrExpr);
6748 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6749 DiagnosticExprs.clear();
6750 DiagnosticExprs.push_back(StrExpr);
6751 FirstUncoveredArg = NewFirstUncoveredArg;
6755 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6758enum StringLiteralCheckType {
6760 SLCT_UncheckedLiteral,
6768 bool AddendIsRight) {
6769 unsigned BitWidth = Offset.getBitWidth();
6770 unsigned AddendBitWidth = Addend.getBitWidth();
6772 if (Addend.isUnsigned()) {
6773 Addend = Addend.zext(++AddendBitWidth);
6774 Addend.setIsSigned(
true);
6777 if (AddendBitWidth > BitWidth) {
6778 Offset = Offset.sext(AddendBitWidth);
6779 BitWidth = AddendBitWidth;
6780 }
else if (BitWidth > AddendBitWidth) {
6781 Addend = Addend.sext(BitWidth);
6785 llvm::APSInt ResOffset = Offset;
6786 if (BinOpKind == BO_Add)
6787 ResOffset = Offset.sadd_ov(Addend, Ov);
6789 assert(AddendIsRight && BinOpKind == BO_Sub &&
6790 "operator must be add or sub with addend on the right");
6791 ResOffset = Offset.ssub_ov(Addend, Ov);
6797 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6798 "index (intermediate) result too big");
6799 Offset = Offset.sext(2 * BitWidth);
6800 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6804 Offset = std::move(ResOffset);
6812class FormatStringLiteral {
6813 const StringLiteral *FExpr;
6817 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6818 : FExpr(fexpr), Offset(Offset) {}
6820 const StringLiteral *getFormatString()
const {
return FExpr; }
6822 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6824 unsigned getByteLength()
const {
6825 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6828 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6835 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6836 bool isWide()
const {
return FExpr->
isWide(); }
6837 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6838 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6839 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6840 bool isPascal()
const {
return FExpr->
isPascal(); }
6842 SourceLocation getLocationOfByte(
6843 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6844 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6845 unsigned *StartTokenByteOffset =
nullptr)
const {
6847 StartToken, StartTokenByteOffset);
6850 SourceLocation getBeginLoc() const LLVM_READONLY {
6854 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6860 Sema &S,
const FormatStringLiteral *FExpr,
6865 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6866 bool IgnoreStringsWithoutSpecifiers);
6875static StringLiteralCheckType
6881 llvm::SmallBitVector &CheckedVarArgs,
6882 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
6883 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
6884 bool IgnoreStringsWithoutSpecifiers =
false) {
6886 return SLCT_NotALiteral;
6888 assert(Offset.isSigned() &&
"invalid offset");
6891 return SLCT_NotALiteral;
6900 return SLCT_UncheckedLiteral;
6903 case Stmt::InitListExprClass:
6907 format_idx, firstDataArg,
Type, CallType,
6908 false, CheckedVarArgs,
6909 UncoveredArg, Offset, CallerFormatParamIdx,
6910 IgnoreStringsWithoutSpecifiers);
6912 return SLCT_NotALiteral;
6913 case Stmt::BinaryConditionalOperatorClass:
6914 case Stmt::ConditionalOperatorClass: {
6923 bool CheckLeft =
true, CheckRight =
true;
6926 if (
C->getCond()->EvaluateAsBooleanCondition(
6938 StringLiteralCheckType Left;
6940 Left = SLCT_UncheckedLiteral;
6943 Args, APK, format_idx, firstDataArg,
Type,
6944 CallType, InFunctionCall, CheckedVarArgs,
6945 UncoveredArg, Offset, CallerFormatParamIdx,
6946 IgnoreStringsWithoutSpecifiers);
6947 if (Left == SLCT_NotALiteral || !CheckRight) {
6953 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6954 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6955 UncoveredArg, Offset, CallerFormatParamIdx,
6956 IgnoreStringsWithoutSpecifiers);
6958 return (CheckLeft && Left < Right) ? Left : Right;
6961 case Stmt::ImplicitCastExprClass:
6965 case Stmt::OpaqueValueExprClass:
6970 return SLCT_NotALiteral;
6972 case Stmt::PredefinedExprClass:
6976 return SLCT_UncheckedLiteral;
6978 case Stmt::DeclRefExprClass: {
6984 bool isConstant =
false;
6988 isConstant = AT->getElementType().isConstant(S.
Context);
6990 isConstant = T.isConstant(S.
Context) &&
6991 PT->getPointeeType().isConstant(S.
Context);
6992 }
else if (T->isObjCObjectPointerType()) {
6995 isConstant = T.isConstant(S.
Context);
6999 if (
const Expr *
Init = VD->getAnyInitializer()) {
7002 if (InitList->isStringLiteralInit())
7003 Init = InitList->getInit(0)->IgnoreParenImpCasts();
7006 S, ReferenceFormatString,
Init, Args, APK, format_idx,
7007 firstDataArg,
Type, CallType,
false,
7008 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
7059 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
7060 if (CallerFormatParamIdx)
7061 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
7062 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
7063 for (
const auto *PVFormatMatches :
7064 D->specific_attrs<FormatMatchesAttr>()) {
7069 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
7073 S.
Diag(Args[format_idx]->getBeginLoc(),
7074 diag::warn_format_string_type_incompatible)
7075 << PVFormatMatches->getType()->getName()
7077 if (!InFunctionCall) {
7078 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
7079 diag::note_format_string_defined);
7081 return SLCT_UncheckedLiteral;
7084 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
7085 Args, APK, format_idx, firstDataArg,
Type, CallType,
7086 false, CheckedVarArgs, UncoveredArg,
7087 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7091 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
7094 PVFormat->getFirstArg(), &CallerFSI))
7096 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
7100 S.
Diag(Args[format_idx]->getBeginLoc(),
7101 diag::warn_format_string_type_incompatible)
7102 << PVFormat->getType()->getName()
7104 if (!InFunctionCall) {
7107 return SLCT_UncheckedLiteral;
7120 return SLCT_UncheckedLiteral;
7128 return SLCT_NotALiteral;
7131 case Stmt::CallExprClass:
7132 case Stmt::CXXMemberCallExprClass: {
7136 StringLiteralCheckType CommonResult;
7137 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7138 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7140 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7141 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7142 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7144 CommonResult = Result;
7149 return CommonResult;
7151 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7153 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7154 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7157 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7158 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7159 UncoveredArg, Offset, CallerFormatParamIdx,
7160 IgnoreStringsWithoutSpecifiers);
7166 format_idx, firstDataArg,
Type, CallType,
7167 false, CheckedVarArgs,
7168 UncoveredArg, Offset, CallerFormatParamIdx,
7169 IgnoreStringsWithoutSpecifiers);
7170 return SLCT_NotALiteral;
7172 case Stmt::ObjCMessageExprClass: {
7174 if (
const auto *MD = ME->getMethodDecl()) {
7175 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7184 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7186 MD->getSelector().isKeywordSelector(
7187 {
"localizedStringForKey",
"value",
"table"})) {
7188 IgnoreStringsWithoutSpecifiers =
true;
7191 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7193 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7194 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7195 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7199 return SLCT_NotALiteral;
7201 case Stmt::ObjCStringLiteralClass:
7202 case Stmt::StringLiteralClass: {
7211 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7214 return SLCT_NotALiteral;
7216 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7218 format_idx, firstDataArg,
Type, InFunctionCall,
7219 CallType, CheckedVarArgs, UncoveredArg,
7220 IgnoreStringsWithoutSpecifiers);
7221 return SLCT_CheckedLiteral;
7224 return SLCT_NotALiteral;
7226 case Stmt::BinaryOperatorClass: {
7240 if (LIsInt != RIsInt) {
7244 if (BinOpKind == BO_Add) {
7257 return SLCT_NotALiteral;
7259 case Stmt::UnaryOperatorClass: {
7261 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7262 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7264 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7274 return SLCT_NotALiteral;
7278 return SLCT_NotALiteral;
7289 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7290 if (isa_and_nonnull<StringLiteral>(LVE))
7311 return "freebsd_kprintf";
7320 return llvm::StringSwitch<FormatStringType>(Flavor)
7322 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7327 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7343bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7347 llvm::SmallBitVector &CheckedVarArgs) {
7348 FormatStringInfo FSI;
7352 return CheckFormatArguments(
7353 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7358bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7362 llvm::SmallBitVector &CheckedVarArgs) {
7363 FormatStringInfo FSI;
7367 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7368 Format->getFormatString(), FSI.FormatIdx,
7370 CallType, Loc, Range, CheckedVarArgs);
7378 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7391 unsigned CallerArgumentIndexOffset =
7394 unsigned FirstArgumentIndex = -1;
7404 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7405 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7409 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7410 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7412 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7415 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7416 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7419 FirstArgumentIndex =
7420 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7426 ? (NumCallerParams + CallerArgumentIndexOffset)
7431 if (!ReferenceFormatString)
7437 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7439 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7441 std::string
Attr, Fixit;
7442 llvm::raw_string_ostream AttrOS(
Attr);
7444 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7445 << FirstArgumentIndex <<
")";
7447 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7449 AttrOS.write_escaped(ReferenceFormatString->
getString());
7453 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7464 llvm::raw_string_ostream IS(Fixit);
7472 if (LO.C23 || LO.CPlusPlus11)
7473 IS <<
"[[gnu::" <<
Attr <<
"]]";
7474 else if (LO.ObjC || LO.GNUMode)
7475 IS <<
"__attribute__((" <<
Attr <<
"))";
7489 Caller->
addAttr(FormatAttr::CreateImplicit(
7491 FormatStringIndex, FirstArgumentIndex));
7493 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7495 FormatStringIndex, ReferenceFormatString));
7499 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7511 unsigned format_idx,
unsigned firstDataArg,
7515 llvm::SmallBitVector &CheckedVarArgs) {
7517 if (format_idx >= Args.size()) {
7518 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7522 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7536 UncoveredArgHandler UncoveredArg;
7537 std::optional<unsigned> CallerParamIdx;
7539 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7540 firstDataArg,
Type, CallType,
7541 true, CheckedVarArgs, UncoveredArg,
7542 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7545 if (UncoveredArg.hasUncoveredArg()) {
7546 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7547 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7548 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7551 if (CT != SLCT_NotALiteral)
7553 return CT == SLCT_CheckedLiteral;
7559 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7565 this, Args, APK, ReferenceFormatString, format_idx,
7566 firstDataArg,
Type, *CallerParamIdx, Loc))
7576 if (Args.size() == firstDataArg) {
7577 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7585 Diag(FormatLoc, diag::note_format_security_fixit)
7589 Diag(FormatLoc, diag::note_format_security_fixit)
7594 Diag(FormatLoc, diag::warn_format_nonliteral)
7605 const FormatStringLiteral *FExpr;
7606 const Expr *OrigFormatExpr;
7608 const unsigned FirstDataArg;
7609 const unsigned NumDataArgs;
7612 ArrayRef<const Expr *> Args;
7614 llvm::SmallBitVector CoveredArgs;
7615 bool usesPositionalArgs =
false;
7616 bool atFirstArg =
true;
7617 bool inFunctionCall;
7619 llvm::SmallBitVector &CheckedVarArgs;
7620 UncoveredArgHandler &UncoveredArg;
7623 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7625 unsigned firstDataArg,
unsigned numDataArgs,
7627 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7629 llvm::SmallBitVector &CheckedVarArgs,
7630 UncoveredArgHandler &UncoveredArg)
7631 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7632 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7633 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7634 inFunctionCall(inFunctionCall), CallType(callType),
7635 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7636 CoveredArgs.resize(numDataArgs);
7637 CoveredArgs.reset();
7640 bool HasFormatArguments()
const {
7645 void DoneProcessing();
7647 void HandleIncompleteSpecifier(
const char *startSpecifier,
7648 unsigned specifierLen)
override;
7650 void HandleInvalidLengthModifier(
7651 const analyze_format_string::FormatSpecifier &FS,
7652 const analyze_format_string::ConversionSpecifier &CS,
7653 const char *startSpecifier,
unsigned specifierLen,
7656 void HandleNonStandardLengthModifier(
7657 const analyze_format_string::FormatSpecifier &FS,
7658 const char *startSpecifier,
unsigned specifierLen);
7660 void HandleNonStandardConversionSpecifier(
7661 const analyze_format_string::ConversionSpecifier &CS,
7662 const char *startSpecifier,
unsigned specifierLen);
7664 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7666 void HandleInvalidPosition(
const char *startSpecifier,
7667 unsigned specifierLen,
7670 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7672 void HandleNullChar(
const char *nullCharacter)
override;
7674 template <
typename Range>
7676 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7677 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7678 bool IsStringLocation, Range StringRange,
7679 ArrayRef<FixItHint> Fixit = {});
7682 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7683 const char *startSpec,
7684 unsigned specifierLen,
7685 const char *csStart,
unsigned csLen);
7687 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7688 const char *startSpec,
7689 unsigned specifierLen);
7691 SourceRange getFormatStringRange();
7692 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7693 unsigned specifierLen);
7694 SourceLocation getLocationOfByte(
const char *x);
7696 const Expr *getDataArg(
unsigned i)
const;
7698 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7699 const analyze_format_string::ConversionSpecifier &CS,
7700 const char *startSpecifier,
unsigned specifierLen,
7703 template <
typename Range>
7704 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7705 bool IsStringLocation, Range StringRange,
7706 ArrayRef<FixItHint> Fixit = {});
7711SourceRange CheckFormatHandler::getFormatStringRange() {
7716getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7718 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7726SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7731void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7732 unsigned specifierLen){
7733 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7734 getLocationOfByte(startSpecifier),
7736 getSpecifierRange(startSpecifier, specifierLen));
7739void CheckFormatHandler::HandleInvalidLengthModifier(
7742 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7754 getSpecifierRange(startSpecifier, specifierLen));
7756 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7757 << FixedLM->toString()
7762 if (DiagID == diag::warn_format_nonsensical_length)
7768 getSpecifierRange(startSpecifier, specifierLen),
7773void CheckFormatHandler::HandleNonStandardLengthModifier(
7775 const char *startSpecifier,
unsigned specifierLen) {
7784 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7788 getSpecifierRange(startSpecifier, specifierLen));
7790 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7791 << FixedLM->toString()
7795 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7799 getSpecifierRange(startSpecifier, specifierLen));
7803void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7805 const char *startSpecifier,
unsigned specifierLen) {
7811 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7815 getSpecifierRange(startSpecifier, specifierLen));
7818 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7819 << FixedCS->toString()
7822 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7826 getSpecifierRange(startSpecifier, specifierLen));
7830void CheckFormatHandler::HandlePosition(
const char *startPos,
7833 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7834 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7835 getLocationOfByte(startPos),
7837 getSpecifierRange(startPos, posLen));
7840void CheckFormatHandler::HandleInvalidPosition(
7841 const char *startSpecifier,
unsigned specifierLen,
7844 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7845 EmitFormatDiagnostic(
7846 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7847 getLocationOfByte(startSpecifier),
true,
7848 getSpecifierRange(startSpecifier, specifierLen));
7851void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7855 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7856 getLocationOfByte(startPos),
7858 getSpecifierRange(startPos, posLen));
7861void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7864 EmitFormatDiagnostic(
7865 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7866 getLocationOfByte(nullCharacter),
true,
7867 getFormatStringRange());
7873const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7874 return Args[FirstDataArg + i];
7877void CheckFormatHandler::DoneProcessing() {
7880 if (HasFormatArguments()) {
7883 signed notCoveredArg = CoveredArgs.find_first();
7884 if (notCoveredArg >= 0) {
7885 assert((
unsigned)notCoveredArg < NumDataArgs);
7886 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7888 UncoveredArg.setAllCovered();
7893void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7894 const Expr *ArgExpr) {
7895 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7907 for (
auto E : DiagnosticExprs)
7910 CheckFormatHandler::EmitFormatDiagnostic(
7911 S, IsFunctionCall, DiagnosticExprs[0],
7917CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7919 const char *startSpec,
7920 unsigned specifierLen,
7921 const char *csStart,
7923 bool keepGoing =
true;
7924 if (argIndex < NumDataArgs) {
7927 CoveredArgs.set(argIndex);
7943 std::string CodePointStr;
7944 if (!llvm::sys::locale::isPrint(*csStart)) {
7945 llvm::UTF32 CodePoint;
7946 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7947 const llvm::UTF8 *E =
7948 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7949 llvm::ConversionResult
Result =
7950 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7952 if (
Result != llvm::conversionOK) {
7953 unsigned char FirstChar = *csStart;
7954 CodePoint = (llvm::UTF32)FirstChar;
7957 llvm::raw_string_ostream
OS(CodePointStr);
7958 if (CodePoint < 256)
7959 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7960 else if (CodePoint <= 0xFFFF)
7961 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7963 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7967 EmitFormatDiagnostic(
7968 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7969 true, getSpecifierRange(startSpec, specifierLen));
7975CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7976 const char *startSpec,
7977 unsigned specifierLen) {
7978 EmitFormatDiagnostic(
7979 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7980 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7984CheckFormatHandler::CheckNumArgs(
7987 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7989 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7991 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7992 << (argIndex+1) << NumDataArgs)
7993 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7994 EmitFormatDiagnostic(
7995 PDiag, getLocationOfByte(CS.
getStart()),
true,
7996 getSpecifierRange(startSpecifier, specifierLen));
8000 UncoveredArg.setAllCovered();
8006template<
typename Range>
8009 bool IsStringLocation,
8012 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
8013 Loc, IsStringLocation, StringRange, FixIt);
8043template <
typename Range>
8044void CheckFormatHandler::EmitFormatDiagnostic(
8045 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
8048 if (InFunctionCall) {
8053 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
8057 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
8058 diag::note_format_string_defined);
8060 Note << StringRange;
8069class CheckPrintfHandler :
public CheckFormatHandler {
8071 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8073 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
8075 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8077 llvm::SmallBitVector &CheckedVarArgs,
8078 UncoveredArgHandler &UncoveredArg)
8079 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8080 numDataArgs, beg, APK, Args, formatIdx,
8081 inFunctionCall, CallType, CheckedVarArgs,
8084 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
8087 bool allowsObjCArg()
const {
8088 return FSType == FormatStringType::NSString ||
8089 FSType == FormatStringType::OSLog ||
8090 FSType == FormatStringType::OSTrace;
8093 bool HandleInvalidPrintfConversionSpecifier(
8094 const analyze_printf::PrintfSpecifier &FS,
8095 const char *startSpecifier,
8096 unsigned specifierLen)
override;
8098 void handleInvalidMaskType(StringRef MaskType)
override;
8100 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8101 const char *startSpecifier,
unsigned specifierLen,
8102 const TargetInfo &
Target)
override;
8103 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
8104 const char *StartSpecifier,
8105 unsigned SpecifierLen,
8108 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
8109 const char *startSpecifier,
unsigned specifierLen);
8110 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
8111 const analyze_printf::OptionalAmount &Amt,
8113 const char *startSpecifier,
unsigned specifierLen);
8114 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
8115 const analyze_printf::OptionalFlag &flag,
8116 const char *startSpecifier,
unsigned specifierLen);
8117 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
8118 const analyze_printf::OptionalFlag &ignoredFlag,
8119 const analyze_printf::OptionalFlag &flag,
8120 const char *startSpecifier,
unsigned specifierLen);
8121 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
8124 void HandleEmptyObjCModifierFlag(
const char *startFlag,
8125 unsigned flagLen)
override;
8127 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8128 unsigned flagLen)
override;
8131 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8132 const char *flagsEnd,
8133 const char *conversionPosition)
override;
8138class EquatableFormatArgument {
8140 enum SpecifierSensitivity :
unsigned {
8147 enum FormatArgumentRole :
unsigned {
8155 analyze_format_string::ArgType ArgType;
8157 StringRef SpecifierLetter;
8158 CharSourceRange
Range;
8159 SourceLocation ElementLoc;
8160 FormatArgumentRole
Role : 2;
8161 SpecifierSensitivity Sensitivity : 2;
8162 unsigned Position : 14;
8163 unsigned ModifierFor : 14;
8165 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8166 bool InFunctionCall)
const;
8169 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8171 StringRef SpecifierLetter,
8172 analyze_format_string::ArgType ArgType,
8173 FormatArgumentRole
Role,
8174 SpecifierSensitivity Sensitivity,
unsigned Position,
8175 unsigned ModifierFor)
8176 : ArgType(ArgType), LengthMod(LengthMod),
8177 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8178 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8179 ModifierFor(ModifierFor) {}
8181 unsigned getPosition()
const {
return Position; }
8182 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8184 analyze_format_string::LengthModifier getLengthModifier()
const {
8185 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
8187 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8189 std::string buildFormatSpecifier()
const {
8191 llvm::raw_string_ostream(result)
8192 << getLengthModifier().toString() << SpecifierLetter;
8196 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8197 const Expr *FmtExpr,
bool InFunctionCall)
const;
8201class DecomposePrintfHandler :
public CheckPrintfHandler {
8202 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8205 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8206 const Expr *origFormatExpr,
8208 unsigned numDataArgs,
bool isObjC,
const char *beg,
8210 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8212 llvm::SmallBitVector &CheckedVarArgs,
8213 UncoveredArgHandler &UncoveredArg,
8214 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8215 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8216 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8217 inFunctionCall, CallType, CheckedVarArgs,
8219 Specs(Specs), HadError(
false) {}
8223 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8225 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8227 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8228 const char *startSpecifier,
8229 unsigned specifierLen,
8230 const TargetInfo &
Target)
override;
8235bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8237 unsigned specifierLen) {
8241 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
8243 startSpecifier, specifierLen,
8247void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8248 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8256 return T->isRecordType() || T->isComplexType();
8259bool CheckPrintfHandler::HandleAmount(
8261 const char *startSpecifier,
unsigned specifierLen) {
8263 if (HasFormatArguments()) {
8265 if (argIndex >= NumDataArgs) {
8266 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8270 getSpecifierRange(startSpecifier, specifierLen));
8280 CoveredArgs.set(argIndex);
8281 const Expr *Arg = getDataArg(argIndex);
8292 ? diag::err_printf_asterisk_wrong_type
8293 : diag::warn_printf_asterisk_wrong_type;
8294 EmitFormatDiagnostic(S.
PDiag(DiagID)
8299 getSpecifierRange(startSpecifier, specifierLen));
8309void CheckPrintfHandler::HandleInvalidAmount(
8313 const char *startSpecifier,
8314 unsigned specifierLen) {
8324 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8328 getSpecifierRange(startSpecifier, specifierLen),
8334 const char *startSpecifier,
8335 unsigned specifierLen) {
8339 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
8343 getSpecifierRange(startSpecifier, specifierLen),
8348void CheckPrintfHandler::HandleIgnoredFlag(
8352 const char *startSpecifier,
8353 unsigned specifierLen) {
8355 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8359 getSpecifierRange(startSpecifier, specifierLen),
8361 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8364void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8367 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
8368 getLocationOfByte(startFlag),
8370 getSpecifierRange(startFlag, flagLen));
8373void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8376 auto Range = getSpecifierRange(startFlag, flagLen);
8377 StringRef flag(startFlag, flagLen);
8378 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8379 getLocationOfByte(startFlag),
8384void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8385 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
8387 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8388 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8389 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8390 getLocationOfByte(conversionPosition),
8396 const Expr *FmtExpr,
8397 bool InFunctionCall)
const {
8398 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8399 ElementLoc,
true, Range);
8402bool EquatableFormatArgument::VerifyCompatible(
8403 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8404 bool InFunctionCall)
const {
8409 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8410 FmtExpr, InFunctionCall);
8411 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8415 if (
Role != FAR_Data) {
8416 if (ModifierFor !=
Other.ModifierFor) {
8419 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8420 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8421 FmtExpr, InFunctionCall);
8422 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8428 bool HadError =
false;
8429 if (Sensitivity !=
Other.Sensitivity) {
8432 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8433 << Sensitivity <<
Other.Sensitivity,
8434 FmtExpr, InFunctionCall);
8435 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8436 << 0 <<
Other.Range;
8439 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8443 case MK::MatchPromotion:
8447 case MK::NoMatchTypeConfusion:
8448 case MK::NoMatchPromotionTypeConfusion:
8450 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8451 << buildFormatSpecifier()
8452 <<
Other.buildFormatSpecifier(),
8453 FmtExpr, InFunctionCall);
8454 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8455 << 0 <<
Other.Range;
8458 case MK::NoMatchPedantic:
8460 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8461 << buildFormatSpecifier()
8462 <<
Other.buildFormatSpecifier(),
8463 FmtExpr, InFunctionCall);
8464 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8465 << 0 <<
Other.Range;
8468 case MK::NoMatchSignedness:
8470 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8471 << buildFormatSpecifier()
8472 <<
Other.buildFormatSpecifier(),
8473 FmtExpr, InFunctionCall);
8474 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8475 << 0 <<
Other.Range;
8481bool DecomposePrintfHandler::GetSpecifiers(
8482 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8485 StringRef
Data = FSL->getString();
8486 const char *Str =
Data.data();
8487 llvm::SmallBitVector BV;
8488 UncoveredArgHandler UA;
8489 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8490 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8502 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8503 const EquatableFormatArgument &B) {
8504 return A.getPosition() < B.getPosition();
8509bool DecomposePrintfHandler::HandlePrintfSpecifier(
8512 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8527 const unsigned Unset = ~0;
8528 unsigned FieldWidthIndex = Unset;
8529 unsigned PrecisionIndex = Unset;
8533 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8534 FieldWidthIndex = Specs.size();
8535 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8536 getLocationOfByte(FieldWidth.getStart()),
8538 FieldWidth.getArgType(S.
Context),
8539 EquatableFormatArgument::FAR_FieldWidth,
8540 EquatableFormatArgument::SS_None,
8541 FieldWidth.usesPositionalArg()
8542 ? FieldWidth.getPositionalArgIndex() - 1
8548 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8549 PrecisionIndex = Specs.size();
8551 getSpecifierRange(startSpecifier, specifierLen),
8552 getLocationOfByte(Precision.getStart()),
8554 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8555 EquatableFormatArgument::SS_None,
8556 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8562 unsigned SpecIndex =
8564 if (FieldWidthIndex != Unset)
8565 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8566 if (PrecisionIndex != Unset)
8567 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8569 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8571 Sensitivity = EquatableFormatArgument::SS_Private;
8573 Sensitivity = EquatableFormatArgument::SS_Public;
8575 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8577 Sensitivity = EquatableFormatArgument::SS_None;
8580 getSpecifierRange(startSpecifier, specifierLen),
8583 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8588 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8593 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8594 SpecIndex + 1, SpecIndex);
8602template<
typename MemberKind>
8613 R.suppressDiagnostics();
8620 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8635 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8637 if ((*MI)->getMinRequiredArguments() == 0)
8645bool CheckPrintfHandler::checkForCStrMembers(
8652 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8655 if (
Method->getMinRequiredArguments() == 0 &&
8668bool CheckPrintfHandler::HandlePrintfSpecifier(
8682 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8683 startSpecifier, specifierLen);
8691 startSpecifier, specifierLen)) {
8696 startSpecifier, specifierLen)) {
8700 if (!CS.consumesDataArgument()) {
8708 if (argIndex < NumDataArgs) {
8712 CoveredArgs.set(argIndex);
8719 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8722 if (HasFormatArguments()) {
8724 CoveredArgs.set(argIndex + 1);
8727 const Expr *Ex = getDataArg(argIndex);
8731 : ArgType::CPointerTy;
8733 EmitFormatDiagnostic(
8734 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8738 getSpecifierRange(startSpecifier, specifierLen));
8741 Ex = getDataArg(argIndex + 1);
8744 EmitFormatDiagnostic(
8745 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8749 getSpecifierRange(startSpecifier, specifierLen));
8756 if (!allowsObjCArg() && CS.isObjCArg()) {
8757 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8764 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8771 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8772 getLocationOfByte(CS.getStart()),
8774 getSpecifierRange(startSpecifier, specifierLen));
8784 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8791 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8795 getSpecifierRange(startSpecifier, specifierLen));
8798 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8802 getSpecifierRange(startSpecifier, specifierLen));
8806 const llvm::Triple &Triple =
Target.getTriple();
8808 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8809 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8810 getLocationOfByte(CS.getStart()),
8812 getSpecifierRange(startSpecifier, specifierLen));
8818 startSpecifier, specifierLen);
8824 startSpecifier, specifierLen);
8830 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8831 getLocationOfByte(startSpecifier),
8833 getSpecifierRange(startSpecifier, specifierLen));
8842 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8844 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8853 startSpecifier, specifierLen);
8856 startSpecifier, specifierLen);
8861 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8862 diag::warn_format_nonsensical_length);
8864 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8866 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8867 diag::warn_format_non_standard_conversion_spec);
8870 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8873 if (!HasFormatArguments())
8876 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8879 const Expr *Arg = getDataArg(argIndex);
8883 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8895 case Stmt::ArraySubscriptExprClass:
8896 case Stmt::CallExprClass:
8897 case Stmt::CharacterLiteralClass:
8898 case Stmt::CXXBoolLiteralExprClass:
8899 case Stmt::DeclRefExprClass:
8900 case Stmt::FloatingLiteralClass:
8901 case Stmt::IntegerLiteralClass:
8902 case Stmt::MemberExprClass:
8903 case Stmt::ObjCArrayLiteralClass:
8904 case Stmt::ObjCBoolLiteralExprClass:
8905 case Stmt::ObjCBoxedExprClass:
8906 case Stmt::ObjCDictionaryLiteralClass:
8907 case Stmt::ObjCEncodeExprClass:
8908 case Stmt::ObjCIvarRefExprClass:
8909 case Stmt::ObjCMessageExprClass:
8910 case Stmt::ObjCPropertyRefExprClass:
8911 case Stmt::ObjCStringLiteralClass:
8912 case Stmt::ObjCSubscriptRefExprClass:
8913 case Stmt::ParenExprClass:
8914 case Stmt::StringLiteralClass:
8915 case Stmt::UnaryOperatorClass:
8922static std::pair<QualType, StringRef>
8929 StringRef Name = UserTy->getDecl()->getName();
8930 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8931 .Case(
"CFIndex", Context.getNSIntegerType())
8932 .Case(
"NSInteger", Context.getNSIntegerType())
8933 .Case(
"NSUInteger", Context.getNSUIntegerType())
8934 .Case(
"SInt32", Context.IntTy)
8935 .Case(
"UInt32", Context.UnsignedIntTy)
8939 return std::make_pair(CastTy, Name);
8941 TyTy = UserTy->desugar();
8945 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8947 PE->getSubExpr()->getType(),
8956 StringRef TrueName, FalseName;
8958 std::tie(TrueTy, TrueName) =
8960 CO->getTrueExpr()->getType(),
8962 std::tie(FalseTy, FalseName) =
8964 CO->getFalseExpr()->getType(),
8965 CO->getFalseExpr());
8967 if (TrueTy == FalseTy)
8968 return std::make_pair(TrueTy, TrueName);
8969 else if (TrueTy.
isNull())
8970 return std::make_pair(FalseTy, FalseName);
8971 else if (FalseTy.
isNull())
8972 return std::make_pair(TrueTy, TrueName);
8975 return std::make_pair(
QualType(), StringRef());
8994 From = VecTy->getElementType();
8996 To = VecTy->getElementType();
9007 diag::warn_format_conversion_argument_type_mismatch_signedness,
9011 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
9020 const char *StartSpecifier,
9021 unsigned SpecifierLen,
9033 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
9034 ExprTy = TET->getUnderlyingExpr()->getType();
9037 if (
const OverflowBehaviorType *OBT =
9039 ExprTy = OBT->getUnderlyingType();
9053 getSpecifierRange(StartSpecifier, SpecifierLen);
9055 llvm::raw_svector_ostream os(FSString);
9057 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
9068 getSpecifierRange(StartSpecifier, SpecifierLen);
9069 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
9079 if (
Match == ArgType::Match)
9083 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
9092 E = ICE->getSubExpr();
9102 if (OrigMatch == ArgType::NoMatchSignedness &&
9103 ImplicitMatch != ArgType::NoMatchSignedness)
9110 if (ImplicitMatch == ArgType::Match)
9128 if (
Match == ArgType::MatchPromotion)
9132 if (
Match == ArgType::MatchPromotion) {
9136 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9137 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9141 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9142 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9143 Match = ImplicitMatch;
9144 assert(
Match != ArgType::MatchPromotion);
9147 bool IsEnum =
false;
9148 bool IsScopedEnum =
false;
9151 IntendedTy = ED->getIntegerType();
9152 if (!ED->isScoped()) {
9153 ExprTy = IntendedTy;
9158 IsScopedEnum =
true;
9165 if (isObjCContext() &&
9176 const llvm::APInt &
V = IL->getValue();
9186 if (TD->getUnderlyingType() == IntendedTy)
9196 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
9204 if (!IsScopedEnum &&
9205 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9209 IntendedTy = CastTy;
9210 ShouldNotPrintDirectly =
true;
9215 PrintfSpecifier fixedFS = FS;
9222 llvm::raw_svector_ostream os(buf);
9225 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9227 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9233 llvm_unreachable(
"expected non-matching");
9235 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9238 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9241 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9244 Diag = diag::warn_format_conversion_argument_type_mismatch;
9265 llvm::raw_svector_ostream CastFix(CastBuf);
9266 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9268 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9274 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9279 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9301 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9307 Name = TypedefTy->getDecl()->getName();
9311 ? diag::warn_format_argument_needs_cast_pedantic
9312 : diag::warn_format_argument_needs_cast;
9313 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9324 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9325 : diag::warn_format_conversion_argument_type_mismatch;
9327 EmitFormatDiagnostic(
9339 bool EmitTypeMismatch =
false;
9348 llvm_unreachable(
"expected non-matching");
9350 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9353 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9356 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9360 ? diag::err_format_conversion_argument_type_mismatch
9361 : diag::warn_format_conversion_argument_type_mismatch;
9365 EmitFormatDiagnostic(
9374 EmitTypeMismatch =
true;
9376 EmitFormatDiagnostic(
9377 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9378 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9382 checkForCStrMembers(AT, E);
9388 EmitTypeMismatch =
true;
9390 EmitFormatDiagnostic(
9391 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9392 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9405 if (EmitTypeMismatch) {
9411 EmitFormatDiagnostic(
9412 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9418 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9419 "format string specifier index out of range");
9420 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9430class CheckScanfHandler :
public CheckFormatHandler {
9432 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9434 unsigned firstDataArg,
unsigned numDataArgs,
9436 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9438 llvm::SmallBitVector &CheckedVarArgs,
9439 UncoveredArgHandler &UncoveredArg)
9440 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9441 numDataArgs, beg, APK, Args, formatIdx,
9442 inFunctionCall, CallType, CheckedVarArgs,
9445 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9446 const char *startSpecifier,
9447 unsigned specifierLen)
override;
9449 bool HandleInvalidScanfConversionSpecifier(
9450 const analyze_scanf::ScanfSpecifier &FS,
9451 const char *startSpecifier,
9452 unsigned specifierLen)
override;
9454 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9459void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9461 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9462 getLocationOfByte(end),
true,
9463 getSpecifierRange(start, end - start));
9466bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9468 const char *startSpecifier,
9469 unsigned specifierLen) {
9473 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9475 startSpecifier, specifierLen,
9479bool CheckScanfHandler::HandleScanfSpecifier(
9481 const char *startSpecifier,
9482 unsigned specifierLen) {
9496 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9497 startSpecifier, specifierLen);
9508 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9523 if (argIndex < NumDataArgs) {
9527 CoveredArgs.set(argIndex);
9533 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9534 diag::warn_format_nonsensical_length);
9536 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9538 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9539 diag::warn_format_non_standard_conversion_spec);
9542 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9545 if (!HasFormatArguments())
9548 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9552 const Expr *Ex = getDataArg(argIndex);
9570 ScanfSpecifier fixedFS = FS;
9575 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9577 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9578 : diag::warn_format_conversion_argument_type_mismatch;
9583 llvm::raw_svector_ostream os(buf);
9586 EmitFormatDiagnostic(
9591 getSpecifierRange(startSpecifier, specifierLen),
9593 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9600 getSpecifierRange(startSpecifier, specifierLen));
9610 const Expr *FmtExpr,
bool InFunctionCall) {
9611 bool HadError =
false;
9612 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9613 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9614 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9626 for (; FmtIter < FmtEnd; ++FmtIter) {
9630 if (FmtIter->getPosition() < RefIter->getPosition())
9634 if (FmtIter->getPosition() > RefIter->getPosition())
9638 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9642 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9643 return Arg.getPosition() != RefIter->getPosition();
9647 if (FmtIter < FmtEnd) {
9648 CheckFormatHandler::EmitFormatDiagnostic(
9649 S, InFunctionCall, FmtExpr,
9650 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9651 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9652 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9653 }
else if (RefIter < RefEnd) {
9654 CheckFormatHandler::EmitFormatDiagnostic(
9655 S, InFunctionCall, FmtExpr,
9656 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9659 << 1 << RefIter->getSourceRange();
9665 Sema &S,
const FormatStringLiteral *FExpr,
9670 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9671 bool IgnoreStringsWithoutSpecifiers) {
9673 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9674 CheckFormatHandler::EmitFormatDiagnostic(
9675 S, inFunctionCall, Args[format_idx],
9676 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9682 StringRef StrRef = FExpr->getString();
9683 const char *Str = StrRef.data();
9687 assert(T &&
"String literal not of constant array type!");
9688 size_t TypeSize = T->getZExtSize();
9689 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9690 const unsigned numDataArgs = Args.size() - firstDataArg;
9692 if (IgnoreStringsWithoutSpecifiers &&
9699 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9700 CheckFormatHandler::EmitFormatDiagnostic(
9701 S, inFunctionCall, Args[format_idx],
9702 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9703 FExpr->getBeginLoc(),
9709 if (StrLen == 0 && numDataArgs > 0) {
9710 CheckFormatHandler::EmitFormatDiagnostic(
9711 S, inFunctionCall, Args[format_idx],
9712 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9723 if (ReferenceFormatString ==
nullptr) {
9724 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9725 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9726 inFunctionCall, CallType, CheckedVarArgs,
9736 Type, ReferenceFormatString, FExpr->getFormatString(),
9737 inFunctionCall ?
nullptr : Args[format_idx]);
9740 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9741 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9742 CallType, CheckedVarArgs, UncoveredArg);
9762 FormatStringLiteral RefLit = AuthoritativeFormatString;
9763 FormatStringLiteral TestLit = TestedFormatString;
9765 bool DiagAtStringLiteral;
9766 if (FunctionCallArg) {
9767 Arg = FunctionCallArg;
9768 DiagAtStringLiteral =
false;
9770 Arg = TestedFormatString;
9771 DiagAtStringLiteral =
true;
9773 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9774 AuthoritativeFormatString,
Type,
9775 IsObjC,
true, RefArgs) &&
9776 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9777 DiagAtStringLiteral, FmtArgs)) {
9779 TestedFormatString, FmtArgs, Arg,
9780 DiagAtStringLiteral);
9793 FormatStringLiteral RefLit = Str;
9797 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9806 bool HadError =
false;
9807 auto Iter = Args.begin();
9808 auto End = Args.end();
9809 while (Iter != End) {
9810 const auto &FirstInGroup = *Iter;
9812 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9814 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9823 const char *Str = StrRef.data();
9826 assert(T &&
"String literal not of constant array type!");
9827 size_t TypeSize = T->getZExtSize();
9828 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9839 switch (AbsFunction) {
9843 case Builtin::BI__builtin_abs:
9844 return Builtin::BI__builtin_labs;
9845 case Builtin::BI__builtin_labs:
9846 return Builtin::BI__builtin_llabs;
9847 case Builtin::BI__builtin_llabs:
9850 case Builtin::BI__builtin_fabsf:
9851 return Builtin::BI__builtin_fabs;
9852 case Builtin::BI__builtin_fabs:
9853 return Builtin::BI__builtin_fabsl;
9854 case Builtin::BI__builtin_fabsl:
9857 case Builtin::BI__builtin_cabsf:
9858 return Builtin::BI__builtin_cabs;
9859 case Builtin::BI__builtin_cabs:
9860 return Builtin::BI__builtin_cabsl;
9861 case Builtin::BI__builtin_cabsl:
9864 case Builtin::BIabs:
9865 return Builtin::BIlabs;
9866 case Builtin::BIlabs:
9867 return Builtin::BIllabs;
9868 case Builtin::BIllabs:
9871 case Builtin::BIfabsf:
9872 return Builtin::BIfabs;
9873 case Builtin::BIfabs:
9874 return Builtin::BIfabsl;
9875 case Builtin::BIfabsl:
9878 case Builtin::BIcabsf:
9879 return Builtin::BIcabs;
9880 case Builtin::BIcabs:
9881 return Builtin::BIcabsl;
9882 case Builtin::BIcabsl:
9911 unsigned AbsFunctionKind) {
9912 unsigned BestKind = 0;
9913 uint64_t ArgSize = Context.getTypeSize(ArgType);
9914 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9917 if (Context.getTypeSize(ParamType) >= ArgSize) {
9920 else if (Context.hasSameType(ParamType, ArgType)) {
9936 if (T->isIntegralOrEnumerationType())
9938 if (T->isRealFloatingType())
9940 if (T->isAnyComplexType())
9943 llvm_unreachable(
"Type not integer, floating, or complex");
9950 switch (ValueKind) {
9955 case Builtin::BI__builtin_fabsf:
9956 case Builtin::BI__builtin_fabs:
9957 case Builtin::BI__builtin_fabsl:
9958 case Builtin::BI__builtin_cabsf:
9959 case Builtin::BI__builtin_cabs:
9960 case Builtin::BI__builtin_cabsl:
9961 return Builtin::BI__builtin_abs;
9962 case Builtin::BIfabsf:
9963 case Builtin::BIfabs:
9964 case Builtin::BIfabsl:
9965 case Builtin::BIcabsf:
9966 case Builtin::BIcabs:
9967 case Builtin::BIcabsl:
9968 return Builtin::BIabs;
9974 case Builtin::BI__builtin_abs:
9975 case Builtin::BI__builtin_labs:
9976 case Builtin::BI__builtin_llabs:
9977 case Builtin::BI__builtin_cabsf:
9978 case Builtin::BI__builtin_cabs:
9979 case Builtin::BI__builtin_cabsl:
9980 return Builtin::BI__builtin_fabsf;
9981 case Builtin::BIabs:
9982 case Builtin::BIlabs:
9983 case Builtin::BIllabs:
9984 case Builtin::BIcabsf:
9985 case Builtin::BIcabs:
9986 case Builtin::BIcabsl:
9987 return Builtin::BIfabsf;
9993 case Builtin::BI__builtin_abs:
9994 case Builtin::BI__builtin_labs:
9995 case Builtin::BI__builtin_llabs:
9996 case Builtin::BI__builtin_fabsf:
9997 case Builtin::BI__builtin_fabs:
9998 case Builtin::BI__builtin_fabsl:
9999 return Builtin::BI__builtin_cabsf;
10000 case Builtin::BIabs:
10001 case Builtin::BIlabs:
10002 case Builtin::BIllabs:
10003 case Builtin::BIfabsf:
10004 case Builtin::BIfabs:
10005 case Builtin::BIfabsl:
10006 return Builtin::BIcabsf;
10009 llvm_unreachable(
"Unable to convert function");
10020 case Builtin::BI__builtin_abs:
10021 case Builtin::BI__builtin_fabs:
10022 case Builtin::BI__builtin_fabsf:
10023 case Builtin::BI__builtin_fabsl:
10024 case Builtin::BI__builtin_labs:
10025 case Builtin::BI__builtin_llabs:
10026 case Builtin::BI__builtin_cabs:
10027 case Builtin::BI__builtin_cabsf:
10028 case Builtin::BI__builtin_cabsl:
10029 case Builtin::BIabs:
10030 case Builtin::BIlabs:
10031 case Builtin::BIllabs:
10032 case Builtin::BIfabs:
10033 case Builtin::BIfabsf:
10034 case Builtin::BIfabsl:
10035 case Builtin::BIcabs:
10036 case Builtin::BIcabsf:
10037 case Builtin::BIcabsl:
10040 llvm_unreachable(
"Unknown Builtin type");
10046 unsigned AbsKind,
QualType ArgType) {
10047 bool EmitHeaderHint =
true;
10048 const char *HeaderName =
nullptr;
10049 std::string FunctionName;
10050 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
10051 FunctionName =
"std::abs";
10052 if (ArgType->isIntegralOrEnumerationType()) {
10053 HeaderName =
"cstdlib";
10054 }
else if (ArgType->isRealFloatingType()) {
10055 HeaderName =
"cmath";
10057 llvm_unreachable(
"Invalid Type");
10063 R.suppressDiagnostics();
10066 for (
const auto *I : R) {
10069 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
10071 FDecl = dyn_cast<FunctionDecl>(I);
10086 EmitHeaderHint =
false;
10098 R.suppressDiagnostics();
10101 if (R.isSingleResult()) {
10102 FunctionDecl *FD = dyn_cast<FunctionDecl>(R.getFoundDecl());
10104 EmitHeaderHint =
false;
10108 }
else if (!R.empty()) {
10114 S.
Diag(Loc, diag::note_replace_abs_function)
10120 if (!EmitHeaderHint)
10123 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
10127template <std::
size_t StrLen>
10129 const char (&Str)[StrLen]) {
10142 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10143 return llvm::is_contained(names, calleeName);
10148 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10149 "__builtin_nanf16",
"__builtin_nanf128"});
10151 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10152 "__builtin_inff16",
"__builtin_inff128"});
10154 llvm_unreachable(
"unknown MathCheck");
10158 if (FDecl->
getName() !=
"infinity")
10161 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10163 if (RDecl->
getName() !=
"numeric_limits")
10180 if (FPO.getNoHonorNaNs() &&
10183 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10184 << 1 << 0 <<
Call->getSourceRange();
10188 if (FPO.getNoHonorInfs() &&
10192 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10193 << 0 << 0 <<
Call->getSourceRange();
10197void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10199 if (
Call->getNumArgs() != 1)
10204 if (AbsKind == 0 && !IsStdAbs)
10207 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10208 QualType ParamType =
Call->getArg(0)->getType();
10213 std::string FunctionName =
10214 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10215 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10216 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10245 if (ArgValueKind == ParamValueKind) {
10246 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10250 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10251 << FDecl << ArgType << ParamType;
10253 if (NewAbsKind == 0)
10257 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10266 if (NewAbsKind == 0)
10269 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10270 << FDecl << ParamValueKind << ArgValueKind;
10273 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10279 if (!
Call || !FDecl)
return;
10283 if (
Call->getExprLoc().isMacroID())
return;
10286 if (
Call->getNumArgs() != 2)
return;
10289 if (!ArgList)
return;
10290 if (ArgList->size() != 1)
return;
10293 const auto& TA = ArgList->
get(0);
10295 QualType ArgType = TA.getAsType();
10299 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10300 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10301 if (!MTE)
return false;
10302 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10303 if (!
Num)
return false;
10304 if (
Num->getValue() != 0)
return false;
10308 const Expr *FirstArg =
Call->getArg(0);
10309 const Expr *SecondArg =
Call->getArg(1);
10310 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10311 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10314 if (IsFirstArgZero == IsSecondArgZero)
return;
10319 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10321 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10322 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10325 SourceRange RemovalRange;
10326 if (IsFirstArgZero) {
10327 RemovalRange = SourceRange(FirstRange.
getBegin(),
10334 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10349 const auto *Size = dyn_cast<BinaryOperator>(E);
10354 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10358 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10359 << SizeRange << FnName;
10360 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10365 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10376 bool &IsContained) {
10379 IsContained =
false;
10392 for (
auto *FD : RD->
fields()) {
10396 IsContained =
true;
10397 return ContainedRD;
10405 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10406 if (Unary->getKind() == UETT_SizeOf)
10415 if (!
SizeOf->isArgumentType())
10416 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10423 return SizeOf->getTypeOfArgument();
10429struct SearchNonTrivialToInitializeField
10432 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10434 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10437 SourceLocation SL) {
10438 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10439 asDerived().visitArray(PDIK, AT, SL);
10443 Super::visitWithKind(PDIK, FT, SL);
10446 void visitARCStrong(QualType FT, SourceLocation SL) {
10449 void visitARCWeak(QualType FT, SourceLocation SL) {
10452 void visitStruct(QualType FT, SourceLocation SL) {
10457 const ArrayType *AT, SourceLocation SL) {
10458 visit(getContext().getBaseElementType(AT), SL);
10460 void visitTrivial(QualType FT, SourceLocation SL) {}
10462 static void diag(QualType RT,
const Expr *E, Sema &S) {
10463 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10472struct SearchNonTrivialToCopyField
10474 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10476 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10479 SourceLocation SL) {
10480 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10481 asDerived().visitArray(PCK, AT, SL);
10485 Super::visitWithKind(PCK, FT, SL);
10488 void visitARCStrong(QualType FT, SourceLocation SL) {
10491 void visitARCWeak(QualType FT, SourceLocation SL) {
10494 void visitPtrAuth(QualType FT, SourceLocation SL) {
10497 void visitStruct(QualType FT, SourceLocation SL) {
10502 SourceLocation SL) {
10503 visit(getContext().getBaseElementType(AT), SL);
10506 SourceLocation SL) {}
10507 void visitTrivial(QualType FT, SourceLocation SL) {}
10508 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10510 static void diag(QualType RT,
const Expr *E, Sema &S) {
10511 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10526 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10527 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10551 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10553 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10554 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10560 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10563 const Expr *SizeArg =
10564 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10566 auto isLiteralZero = [](
const Expr *E) {
10576 if (isLiteralZero(SizeArg) &&
10583 if (BId == Builtin::BIbzero ||
10586 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10587 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10588 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10589 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10590 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10598 if (BId == Builtin::BImemset &&
10602 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10603 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10608void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10615 unsigned ExpectedNumArgs =
10616 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10617 if (
Call->getNumArgs() < ExpectedNumArgs)
10620 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10621 BId == Builtin::BIstrndup ? 1 : 2);
10623 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10627 Call->getBeginLoc(),
Call->getRParenLoc()))
10639 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10640 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10643 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10647 QualType DestTy = Dest->
getType();
10648 QualType PointeeTy;
10649 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10661 if (CheckSizeofMemaccessArgument(LenExpr, Dest, FnName))
10667 if (SizeOfArgTy != QualType()) {
10669 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10671 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10672 << FnName << SizeOfArgTy << ArgIdx
10679 PointeeTy = DestTy;
10682 if (PointeeTy == QualType())
10687 if (
const CXXRecordDecl *ContainedRD =
10690 unsigned OperationType = 0;
10691 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10694 if (ArgIdx != 0 || IsCmp) {
10695 if (BId == Builtin::BImemcpy)
10697 else if(BId == Builtin::BImemmove)
10704 PDiag(diag::warn_dyn_class_memaccess)
10705 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10706 << IsContained << ContainedRD << OperationType
10707 <<
Call->getCallee()->getSourceRange());
10709 BId != Builtin::BImemset)
10712 PDiag(diag::warn_arc_object_memaccess)
10713 << ArgIdx << FnName << PointeeTy
10714 <<
Call->getCallee()->getSourceRange());
10721 bool NonTriviallyCopyableCXXRecord =
10725 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10728 PDiag(diag::warn_cstruct_memaccess)
10729 << ArgIdx << FnName << PointeeTy << 0);
10730 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10731 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10732 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10736 PDiag(diag::warn_cxxstruct_memaccess)
10737 << FnName << PointeeTy);
10738 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10741 PDiag(diag::warn_cstruct_memaccess)
10742 << ArgIdx << FnName << PointeeTy << 1);
10743 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10744 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10745 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10749 PDiag(diag::warn_cxxstruct_memaccess)
10750 << FnName << PointeeTy);
10759 PDiag(diag::note_bad_memaccess_silence)
10765bool Sema::CheckSizeofMemaccessArgument(
const Expr *LenExpr,
const Expr *Dest,
10767 llvm::FoldingSetNodeID SizeOfArgID;
10773 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10776 QualType DestTy = Dest->
getType();
10777 const PointerType *DestPtrTy = DestTy->
getAs<PointerType>();
10783 if (SizeOfArgID == llvm::FoldingSetNodeID())
10786 llvm::FoldingSetNodeID DestID;
10788 if (DestID == SizeOfArgID) {
10791 unsigned ActionIdx = 0;
10792 StringRef ReadableName = FnName->
getName();
10794 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest);
10795 UnaryOp && UnaryOp->getOpcode() == UO_AddrOf)
10804 SourceLocation SL = SizeOfArg->
getExprLoc();
10809 if (
SM.isMacroArgExpansion(SL)) {
10811 SL =
SM.getSpellingLoc(SL);
10812 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10814 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10819 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10820 << ReadableName << PointeeTy << DestTy << DSR
10823 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10824 << ActionIdx << SSR);
10860 if (CAT->getZExtSize() <= 1)
10868void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10872 unsigned NumArgs =
Call->getNumArgs();
10873 if ((NumArgs != 3) && (NumArgs != 4))
10878 const Expr *CompareWithSrc =
nullptr;
10881 Call->getBeginLoc(),
Call->getRParenLoc()))
10886 CompareWithSrc = Ex;
10889 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10890 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10891 SizeCall->getNumArgs() == 1)
10896 if (!CompareWithSrc)
10903 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10907 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10908 if (!CompareWithSrcDRE ||
10912 const Expr *OriginalSizeArg =
Call->getArg(2);
10913 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10920 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10924 SmallString<128> sizeString;
10925 llvm::raw_svector_ostream
OS(sizeString);
10930 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10937 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10938 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10939 return D1->getDecl() == D2->getDecl();
10944 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10953void Sema::CheckStrncatArguments(
const CallExpr *CE,
10968 unsigned PatternType = 0;
10976 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10977 if (BE->getOpcode() == BO_Sub) {
10978 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10979 const Expr *
R = BE->getRHS()->IgnoreParenCasts();
10990 if (PatternType == 0)
10999 if (
SM.isMacroArgExpansion(SL)) {
11000 SL =
SM.getSpellingLoc(SL);
11001 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
11006 QualType DstTy = DstArg->
getType();
11009 if (!isKnownSizeArray) {
11010 if (PatternType == 1)
11011 Diag(SL, diag::warn_strncat_wrong_size) << SR;
11013 Diag(SL, diag::warn_strncat_src_size) << SR;
11017 if (PatternType == 1)
11018 Diag(SL, diag::warn_strncat_large_size) << SR;
11020 Diag(SL, diag::warn_strncat_src_size) << SR;
11022 SmallString<128> sizeString;
11023 llvm::raw_svector_ostream
OS(sizeString);
11031 Diag(SL, diag::note_strncat_wrong_size)
11036void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
11045void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
11047 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
11048 const Decl *D = Lvalue->getDecl();
11049 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
11050 if (!DD->getType()->isReferenceType())
11051 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
11055 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
11056 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
11057 Lvalue->getMemberDecl());
11060void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
11062 const auto *Lambda = dyn_cast<LambdaExpr>(
11067 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
11068 << CalleeName << 2 ;
11071void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
11073 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
11074 if (Var ==
nullptr)
11078 << CalleeName << 0 << Var;
11081void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
11084 llvm::raw_svector_ostream
OS(SizeString);
11087 if (Kind == clang::CK_BitCast &&
11088 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
11090 if (Kind == clang::CK_IntegralToPointer &&
11092 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
11095 switch (
Cast->getCastKind()) {
11096 case clang::CK_BitCast:
11097 case clang::CK_IntegralToPointer:
11098 case clang::CK_FunctionToPointerDecay:
11107 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
11108 << CalleeName << 0 <<
OS.str();
11112void Sema::CheckFreeArguments(
const CallExpr *E) {
11113 const std::string CalleeName =
11118 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
11120 case UnaryOperator::Opcode::UO_AddrOf:
11121 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
11122 case UnaryOperator::Opcode::UO_Plus:
11123 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
11128 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
11130 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
11132 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
11133 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
11134 << CalleeName << 0 << Label->getLabel()->getIdentifier();
11140 << CalleeName << 1 ;
11145 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11146 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11150Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11159 Diag(ReturnLoc, diag::warn_null_ret)
11169 if (Op == OO_New || Op == OO_Array_New) {
11170 const FunctionProtoType *Proto
11174 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11180 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11185 if (
Context.getTargetInfo().getTriple().isPPC64())
11197 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11198 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11199 FPCast = dyn_cast<CastExpr>(R->IgnoreParens());
11200 return FPLiteral && FPCast;
11203 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11209 llvm::APFloat TargetC = FPLiteral->
getValue();
11210 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11211 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11215 Diag(Loc, diag::warn_float_compare_literal)
11216 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11229 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11230 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11231 if (DRL->getDecl() == DRR->getDecl())
11239 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11240 if (FLL->isExact())
11242 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11243 if (FLR->isExact())
11247 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11248 CL &&
CL->getBuiltinCallee())
11251 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11252 CR && CR->getBuiltinCallee())
11256 Diag(Loc, diag::warn_floatingpoint_eq)
11277 IntRange(
unsigned Width,
bool NonNegative)
11278 : Width(Width), NonNegative(NonNegative) {}
11281 unsigned valueBits()
const {
11282 return NonNegative ? Width : Width - 1;
11286 static IntRange forBoolType() {
11287 return IntRange(1,
true);
11291 static IntRange forValueOfType(ASTContext &
C, QualType T) {
11292 return forValueOfCanonicalType(
C,
11297 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *T) {
11300 if (
const auto *VT = dyn_cast<VectorType>(T))
11301 T = VT->getElementType().getTypePtr();
11302 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11303 T = MT->getElementType().getTypePtr();
11304 if (
const auto *CT = dyn_cast<ComplexType>(T))
11305 T = CT->getElementType().getTypePtr();
11306 if (
const auto *AT = dyn_cast<AtomicType>(T))
11307 T = AT->getValueType().getTypePtr();
11308 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11309 T = OBT->getUnderlyingType().getTypePtr();
11311 if (!
C.getLangOpts().CPlusPlus) {
11314 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11319 if (
Enum->isFixed()) {
11320 return IntRange(
C.getIntWidth(QualType(T, 0)),
11321 !
Enum->getIntegerType()->isSignedIntegerType());
11324 unsigned NumPositive =
Enum->getNumPositiveBits();
11325 unsigned NumNegative =
Enum->getNumNegativeBits();
11327 if (NumNegative == 0)
11328 return IntRange(NumPositive,
true);
11330 return IntRange(std::max(NumPositive + 1, NumNegative),
11334 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11335 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11348 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *T) {
11351 if (
const VectorType *VT = dyn_cast<VectorType>(T))
11352 T = VT->getElementType().getTypePtr();
11353 if (
const auto *MT = dyn_cast<ConstantMatrixType>(T))
11354 T = MT->getElementType().getTypePtr();
11355 if (
const ComplexType *CT = dyn_cast<ComplexType>(T))
11356 T = CT->getElementType().getTypePtr();
11357 if (
const AtomicType *AT = dyn_cast<AtomicType>(T))
11358 T = AT->getValueType().getTypePtr();
11360 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11361 if (
const OverflowBehaviorType *OBT = dyn_cast<OverflowBehaviorType>(T))
11362 T = OBT->getUnderlyingType().getTypePtr();
11364 if (
const auto *EIT = dyn_cast<BitIntType>(T))
11365 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11374 static IntRange join(IntRange L, IntRange R) {
11375 bool Unsigned = L.NonNegative &&
R.NonNegative;
11376 return IntRange(std::max(L.valueBits(),
R.valueBits()) + !
Unsigned,
11377 L.NonNegative &&
R.NonNegative);
11381 static IntRange bit_and(IntRange L, IntRange R) {
11382 unsigned Bits = std::max(L.Width,
R.Width);
11383 bool NonNegative =
false;
11384 if (L.NonNegative) {
11385 Bits = std::min(Bits, L.Width);
11386 NonNegative =
true;
11388 if (
R.NonNegative) {
11389 Bits = std::min(Bits,
R.Width);
11390 NonNegative =
true;
11392 return IntRange(Bits, NonNegative);
11396 static IntRange sum(IntRange L, IntRange R) {
11397 bool Unsigned = L.NonNegative &&
R.NonNegative;
11398 return IntRange(std::max(L.valueBits(),
R.valueBits()) + 1 + !
Unsigned,
11403 static IntRange difference(IntRange L, IntRange R) {
11407 bool CanWiden = !L.NonNegative || !
R.NonNegative;
11408 bool Unsigned = L.NonNegative &&
R.Width == 0;
11409 return IntRange(std::max(L.valueBits(),
R.valueBits()) + CanWiden +
11415 static IntRange product(IntRange L, IntRange R) {
11419 bool CanWiden = !L.NonNegative && !
R.NonNegative;
11420 bool Unsigned = L.NonNegative &&
R.NonNegative;
11421 return IntRange(L.valueBits() +
R.valueBits() + CanWiden + !
Unsigned,
11426 static IntRange rem(IntRange L, IntRange R) {
11430 return IntRange(std::min(L.valueBits(),
R.valueBits()) + !
Unsigned,
11438 if (value.isSigned() && value.isNegative())
11439 return IntRange(value.getSignificantBits(),
false);
11441 if (value.getBitWidth() > MaxWidth)
11442 value = value.trunc(MaxWidth);
11446 return IntRange(value.getActiveBits(),
true);
11450 if (result.
isInt())
11457 R = IntRange::join(R, El);
11465 return IntRange::join(R, I);
11480 Ty = AtomicRHS->getValueType();
11499 bool InConstantContext,
11500 bool Approximate) {
11511 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11512 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11516 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11518 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11519 CE->getCastKind() == CK_BooleanToSignedIntegral;
11522 if (!isIntegerCast)
11523 return OutputTypeRange;
11526 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11527 InConstantContext, Approximate);
11529 return std::nullopt;
11532 if (SubRange->Width >= OutputTypeRange.Width)
11533 return OutputTypeRange;
11537 return IntRange(SubRange->Width,
11538 SubRange->NonNegative || OutputTypeRange.NonNegative);
11541 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11544 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11546 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11547 InConstantContext, Approximate);
11552 Expr *TrueExpr = CO->getTrueExpr();
11554 return std::nullopt;
11556 std::optional<IntRange> L =
11559 return std::nullopt;
11561 Expr *FalseExpr = CO->getFalseExpr();
11563 return std::nullopt;
11565 std::optional<IntRange> R =
11568 return std::nullopt;
11570 return IntRange::join(*L, *R);
11573 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11574 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11576 switch (BO->getOpcode()) {
11578 llvm_unreachable(
"builtin <=> should have class type");
11589 return IntRange::forBoolType();
11618 Combine = IntRange::bit_and;
11626 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11627 if (I->getValue() == 1) {
11628 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11629 return IntRange(R.Width,
true);
11639 case BO_ShrAssign: {
11641 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11643 return std::nullopt;
11647 if (std::optional<llvm::APSInt> shift =
11648 BO->getRHS()->getIntegerConstantExpr(
C)) {
11649 if (shift->isNonNegative()) {
11650 if (shift->uge(L->Width))
11651 L->Width = (L->NonNegative ? 0 : 1);
11653 L->Width -= shift->getZExtValue();
11667 Combine = IntRange::sum;
11671 if (BO->getLHS()->getType()->isPointerType())
11674 Combine = IntRange::difference;
11679 Combine = IntRange::product;
11688 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11690 return std::nullopt;
11693 if (std::optional<llvm::APSInt> divisor =
11694 BO->getRHS()->getIntegerConstantExpr(
C)) {
11695 unsigned log2 = divisor->logBase2();
11696 if (
log2 >= L->Width)
11697 L->Width = (L->NonNegative ? 0 : 1);
11699 L->Width = std::min(L->Width -
log2, MaxWidth);
11707 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11709 return std::nullopt;
11711 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11715 Combine = IntRange::rem;
11727 unsigned opWidth =
C.getIntWidth(T);
11729 InConstantContext, Approximate);
11731 return std::nullopt;
11734 InConstantContext, Approximate);
11736 return std::nullopt;
11738 IntRange
C = Combine(*L, *R);
11739 C.NonNegative |= T->isUnsignedIntegerOrEnumerationType();
11740 C.Width = std::min(
C.Width, MaxWidth);
11744 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11745 switch (UO->getOpcode()) {
11748 return IntRange::forBoolType();
11762 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11765 return std::nullopt;
11770 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11780 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11783 return std::nullopt;
11788 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11798 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11799 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11803 return IntRange(BitField->getBitWidthValue(),
11804 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11807 return std::nullopt;
11813 bool InConstantContext,
11814 bool Approximate) {
11823 const llvm::fltSemantics &Src,
11824 const llvm::fltSemantics &Tgt) {
11825 llvm::APFloat truncated = value;
11828 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11829 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11831 return truncated.bitwiseIsEqual(value);
11840 const llvm::fltSemantics &Src,
11841 const llvm::fltSemantics &Tgt) {
11865 bool IsListInit =
false);
11880 return MacroName !=
"YES" && MacroName !=
"NO" &&
11881 MacroName !=
"true" && MacroName !=
"false";
11889 (!E->
getType()->isSignedIntegerType() ||
11904struct PromotedRange {
11906 llvm::APSInt PromotedMin;
11908 llvm::APSInt PromotedMax;
11910 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11912 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11913 else if (
R.Width >= BitWidth && !
Unsigned) {
11917 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11918 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11920 PromotedMin = llvm::APSInt::getMinValue(
R.Width,
R.NonNegative)
11921 .extOrTrunc(BitWidth);
11922 PromotedMin.setIsUnsigned(
Unsigned);
11924 PromotedMax = llvm::APSInt::getMaxValue(
R.Width,
R.NonNegative)
11925 .extOrTrunc(BitWidth);
11926 PromotedMax.setIsUnsigned(
Unsigned);
11931 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11941 InRangeFlag = 0x40,
11944 Min =
LE | InRangeFlag,
11945 InRange = InRangeFlag,
11946 Max =
GE | InRangeFlag,
11949 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11954 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11955 Value.isUnsigned() == PromotedMin.isUnsigned());
11956 if (!isContiguous()) {
11957 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11958 if (
Value.isMinValue())
return Min;
11959 if (
Value.isMaxValue())
return Max;
11960 if (
Value >= PromotedMin)
return InRange;
11961 if (
Value <= PromotedMax)
return InRange;
11965 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11966 case -1:
return Less;
11967 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11969 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11970 case -1:
return InRange;
11971 case 0:
return Max;
11976 llvm_unreachable(
"impossible compare result");
11979 static std::optional<StringRef>
11981 if (Op == BO_Cmp) {
11983 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11985 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11986 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11987 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11988 return std::nullopt;
11995 }
else if (Op == BO_NE) {
11999 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
12006 if (Op == BO_GE || Op == BO_LE)
12007 std::swap(TrueFlag, FalseFlag);
12010 return StringRef(
"true");
12012 return StringRef(
"false");
12013 return std::nullopt;
12020 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
12021 if (ICE->getCastKind() != CK_IntegralCast &&
12022 ICE->getCastKind() != CK_NoOp)
12024 E = ICE->getSubExpr();
12033 enum ConstantValueKind {
12038 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
12039 return BL->getValue() ? ConstantValueKind::LiteralTrue
12040 : ConstantValueKind::LiteralFalse;
12041 return ConstantValueKind::Miscellaneous;
12046 const llvm::APSInt &
Value,
12047 bool RhsConstant) {
12069 if (!OtherValueRange)
12074 OtherT = AT->getValueType();
12075 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
12079 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
12085 bool OtherIsBooleanDespiteType =
12087 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
12088 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
12092 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
12093 Value.isUnsigned());
12094 auto Cmp = OtherPromotedValueRange.compare(
Value);
12095 auto Result = PromotedRange::constantValue(E->
getOpcode(),
Cmp, RhsConstant);
12101 bool TautologicalTypeCompare =
false;
12103 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
12104 Value.isUnsigned());
12105 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
12108 TautologicalTypeCompare =
true;
12116 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
12125 bool InRange =
Cmp & PromotedRange::InRangeFlag;
12131 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
12132 Other->getType()->isUnsignedIntegerOrEnumerationType())
12133 TautologicalTypeCompare =
true;
12138 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
12139 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
12143 llvm::raw_svector_ostream OS(PrettySourceValue);
12145 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
12146 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
12148 OS << (BL->getValue() ?
"YES" :
"NO");
12153 if (!TautologicalTypeCompare) {
12155 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12161 if (IsObjCSignedCharBool) {
12163 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12164 << OS.str() << *Result);
12171 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12175 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12176 : diag::warn_tautological_bool_compare)
12178 << OtherIsBooleanDespiteType << *Result
12185 ? diag::warn_unsigned_enum_always_true_comparison
12186 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12187 : diag::warn_unsigned_always_true_comparison)
12188 : diag::warn_tautological_constant_compare;
12191 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
12224 if (T->isIntegralType(S.
Context)) {
12225 std::optional<llvm::APSInt> RHSValue =
12227 std::optional<llvm::APSInt> LHSValue =
12231 if (RHSValue && LHSValue)
12235 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12237 const bool RhsConstant = (
bool)RHSValue;
12238 Expr *Const = RhsConstant ? RHS : LHS;
12240 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12249 if (!T->hasUnsignedIntegerRepresentation()) {
12263 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12265 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12271 Expr *signedOperand, *unsignedOperand;
12274 "unsigned comparison between two signed integer expressions?");
12275 signedOperand = LHS;
12276 unsignedOperand = RHS;
12278 signedOperand = RHS;
12279 unsignedOperand = LHS;
12285 std::optional<IntRange> signedRange =
12297 if (signedRange->NonNegative)
12309 if (!unsignedRange)
12314 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12316 if (unsignedRange->Width < comparisonWidth)
12321 S.
PDiag(diag::warn_mixed_sign_comparison)
12340 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12345 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12346 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12347 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12348 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12349 << BitfieldEnumDecl;
12356 Init->isValueDependent() ||
12357 Init->isTypeDependent())
12360 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12370 const PreferredTypeAttr *PTAttr =
nullptr;
12372 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12374 ED = PTAttr->getType()->getAsEnumDecl();
12382 bool SignedEnum = ED->getNumNegativeBits() > 0;
12389 unsigned DiagID = 0;
12390 if (SignedEnum && !SignedBitfield) {
12393 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12395 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12396 }
else if (SignedBitfield && !SignedEnum &&
12397 ED->getNumPositiveBits() == FieldWidth) {
12400 ? diag::warn_signed_bitfield_enum_conversion
12401 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12404 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12409 << SignedEnum << TypeRange;
12411 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12418 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12419 ED->getNumNegativeBits())
12420 : ED->getNumPositiveBits();
12423 if (BitsNeeded > FieldWidth) {
12427 ? diag::warn_bitfield_too_small_for_enum
12428 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12429 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12433 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12441 llvm::APSInt
Value = Result.Val.getInt();
12443 unsigned OriginalWidth =
Value.getBitWidth();
12449 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12450 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12457 if (!
Value.isSigned() ||
Value.isNegative())
12458 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12459 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12460 OriginalWidth =
Value.getSignificantBits();
12462 if (OriginalWidth <= FieldWidth)
12466 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12470 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12471 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12475 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12477 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12478 ? diag::warn_impcast_single_bit_bitield_precision_constant
12479 : diag::warn_impcast_bitfield_precision_constant)
12480 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12481 <<
Init->getSourceRange();
12518 bool PruneControlFlow =
false) {
12525 if (T.hasAddressSpace())
12527 if (PruneControlFlow) {
12541 bool PruneControlFlow =
false) {
12548 bool IsBool = T->isSpecificBuiltinType(BuiltinType::Bool);
12553 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12554 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12559 llvm::APFloat
Value(0.0);
12565 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12570 diag::warn_impcast_float_integer, PruneWarnings);
12573 bool isExact =
false;
12576 T->hasUnsignedIntegerRepresentation());
12577 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12578 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12586 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12587 precision = (precision * 59 + 195) / 196;
12588 Value.toString(PrettySourceValue, precision);
12592 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12593 << PrettySourceValue);
12596 if (Result == llvm::APFloat::opOK && isExact) {
12597 if (IsLiteral)
return;
12598 return DiagnoseImpCast(S, E, T, CContext, diag::warn_impcast_float_integer,
12604 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12607 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12608 : diag::warn_impcast_float_to_integer_out_of_range,
12611 unsigned DiagID = 0;
12614 DiagID = diag::warn_impcast_literal_float_to_integer;
12615 }
else if (IntegerValue == 0) {
12616 if (
Value.isZero()) {
12618 diag::warn_impcast_float_integer, PruneWarnings);
12621 DiagID = diag::warn_impcast_float_to_integer_zero;
12623 if (IntegerValue.isUnsigned()) {
12624 if (!IntegerValue.isMaxValue()) {
12626 diag::warn_impcast_float_integer, PruneWarnings);
12629 if (!IntegerValue.isMaxSignedValue() &&
12630 !IntegerValue.isMinSignedValue()) {
12632 diag::warn_impcast_float_integer, PruneWarnings);
12636 DiagID = diag::warn_impcast_float_to_integer;
12641 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12643 IntegerValue.toString(PrettyTargetValue);
12645 if (PruneWarnings) {
12649 << PrettySourceValue << PrettyTargetValue
12662 "Must be compound assignment operation");
12673 ->getComputationResultType()
12680 if (ResultBT->isInteger())
12682 E->
getExprLoc(), diag::warn_impcast_float_integer);
12684 if (!ResultBT->isFloatingPoint())
12693 diag::warn_impcast_float_result_precision);
12698 if (!Range.Width)
return "0";
12700 llvm::APSInt ValueInRange =
Value;
12701 ValueInRange.setIsSigned(!Range.NonNegative);
12702 ValueInRange = ValueInRange.trunc(Range.Width);
12703 return toString(ValueInRange, 10);
12713 const Type *Source =
12715 if (
Target->isDependentType())
12718 const auto *FloatCandidateBT =
12719 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12720 const Type *BoolCandidateType = ToBool ?
Target : Source;
12723 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12728 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12734 S, TheCall->
getArg(I - 1),
false));
12736 S, TheCall->
getArg(I + 1),
false));
12741 diag::warn_impcast_floating_point_to_bool);
12756 if (!IsGNUNullExpr && !HasNullPtrType)
12760 if (T->isAnyPointerType() || T->isBlockPointerType() ||
12761 T->isMemberPointerType() || !T->isScalarType() || T->isNullPtrType())
12764 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12777 if (IsGNUNullExpr && Loc.
isMacroID()) {
12780 if (MacroName ==
"NULL")
12788 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12802 const char FirstLiteralCharacter =
12804 if (FirstLiteralCharacter ==
'0')
12810 if (CC.
isValid() && T->isCharType()) {
12811 const char FirstContextCharacter =
12813 if (FirstContextCharacter ==
'{')
12821 const auto *IL = dyn_cast<IntegerLiteral>(E);
12823 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12824 if (UO->getOpcode() == UO_Minus)
12825 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12836 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12840 if (Opc == BO_Shl) {
12843 if (LHS && LHS->getValue() == 0)
12844 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12846 RHS->getValue().isNonNegative() &&
12848 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12849 << (Result.Val.getInt() != 0);
12851 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12858 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12863 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12864 (RHS->getValue() == 0 || RHS->getValue() == 1))
12867 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12868 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12876 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12882 if (Source->isChar16Type() &&
Target->isChar32Type())
12888 llvm::APSInt
Value(32);
12889 Value = Result.Val.getInt();
12890 bool IsASCII =
Value <= 0x7F;
12891 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12892 bool ConversionPreservesSemantics =
12893 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12895 if (!ConversionPreservesSemantics) {
12896 auto IsSingleCodeUnitCP = [](
const QualType &T,
12897 const llvm::APSInt &
Value) {
12898 if (T->isChar8Type())
12899 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12900 if (T->isChar16Type())
12901 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12902 assert(T->isChar32Type());
12903 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12906 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12915 LosesPrecision ? diag::warn_impcast_unicode_precision
12916 : diag::warn_impcast_unicode_char_type);
12921 From =
Context.getCanonicalType(From);
12922 To =
Context.getCanonicalType(To);
12925 From = MaybePointee;
12932 if (FromFn->getCFIUncheckedCalleeAttr() &&
12933 !ToFn->getCFIUncheckedCalleeAttr())
12941 bool *ICContext,
bool IsListInit) {
12946 if (Source ==
Target)
return;
12947 if (
Target->isDependentType())
return;
12957 if (Source->isAtomicType())
12961 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12967 diag::warn_impcast_string_literal_to_bool);
12973 diag::warn_impcast_objective_c_literal_to_bool);
12975 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12987 if (
ObjC().isSignedCharBool(T) && Source->isIntegralType(
Context)) {
12990 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12992 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
13001 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
13003 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
13008 if (
Target->isSveVLSBuiltinType() &&
13015 if (
Target->isRVVVLSBuiltinType() &&
13025 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_vector_scalar);
13033 diag::warn_hlsl_impcast_vector_truncation);
13045 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
13046 Target = VecTy->getElementType().getTypePtr();
13050 if (
Target->isScalarType())
13051 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_matrix_scalar);
13059 diag::warn_hlsl_impcast_matrix_truncation);
13065 if (
const auto *MatTy = dyn_cast<ConstantMatrixType>(
Target))
13066 Target = MatTy->getElementType().getTypePtr();
13076 ? diag::err_impcast_complex_scalar
13077 : diag::warn_impcast_complex_scalar);
13084 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
13090 const Type *OriginalTarget =
Context.getCanonicalType(T).getTypePtr();
13093 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
13095 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
13134 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_float_precision);
13137 else if (Order < 0) {
13141 DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_double_promotion);
13147 if (TargetBT && TargetBT->
isInteger()) {
13174 diag::warn_impcast_floating_point_to_bool);
13182 if (Source->isFixedPointType()) {
13183 if (
Target->isUnsaturatedFixedPointType()) {
13187 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13188 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(T);
13189 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(T);
13192 PDiag(diag::warn_impcast_fixed_point_range)
13193 <<
Value.toString() << T
13199 }
else if (
Target->isIntegerType()) {
13203 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13206 llvm::APSInt IntResult = FXResult.convertToInt(
13207 Context.getIntWidth(T),
Target->isSignedIntegerOrEnumerationType(),
13212 PDiag(diag::warn_impcast_fixed_point_range)
13213 << FXResult.toString() << T
13220 }
else if (
Target->isUnsaturatedFixedPointType()) {
13221 if (Source->isIntegerType()) {
13228 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13229 Value,
Context.getFixedPointSemantics(T), &Overflowed);
13233 PDiag(diag::warn_impcast_fixed_point_range)
13254 unsigned int SourcePrecision =
SourceRange->Width;
13258 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13261 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13262 SourcePrecision > TargetPrecision) {
13264 if (std::optional<llvm::APSInt> SourceInt =
13269 llvm::APFloat TargetFloatValue(
13271 llvm::APFloat::opStatus ConversionStatus =
13272 TargetFloatValue.convertFromAPInt(
13274 llvm::APFloat::rmNearestTiesToEven);
13276 if (ConversionStatus != llvm::APFloat::opOK) {
13278 SourceInt->toString(PrettySourceValue, 10);
13280 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13284 PDiag(diag::warn_impcast_integer_float_precision_constant)
13285 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13291 diag::warn_impcast_integer_float_precision);
13300 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13305 if (
Target->isBooleanType())
13309 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13313 if (!Source->isIntegerType() || !
Target->isIntegerType())
13318 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13321 if (
ObjC().isSignedCharBool(T) && !Source->isCharType() &&
13324 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13329 if (!LikelySourceRange)
13332 IntRange SourceTypeRange =
13333 IntRange::forTargetOfCanonicalType(
Context, Source);
13334 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13336 if (LikelySourceRange->Width > TargetRange.Width) {
13340 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
13341 if (TargetOBT->isWrapKind()) {
13348 if (
const auto *SourceOBT = E->
getType()->
getAs<OverflowBehaviorType>()) {
13349 if (SourceOBT->isWrapKind()) {
13359 llvm::APSInt
Value(32);
13369 PDiag(diag::warn_impcast_integer_precision_constant)
13370 << PrettySourceValue << PrettyTargetValue
13380 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13381 if (UO->getOpcode() == UO_Minus)
13383 *
this, E, T, CC, diag::warn_impcast_integer_precision_on_negation);
13386 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13387 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_integer_64_32,
13390 diag::warn_impcast_integer_precision);
13393 if (TargetRange.Width > SourceTypeRange.Width) {
13394 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13395 if (UO->getOpcode() == UO_Minus)
13396 if (Source->isUnsignedIntegerType()) {
13397 if (
Target->isUnsignedIntegerType())
13399 diag::warn_impcast_high_order_zero_bits);
13400 if (
Target->isSignedIntegerType())
13402 diag::warn_impcast_nonnegative_result);
13406 if (TargetRange.Width == LikelySourceRange->Width &&
13407 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13408 Source->isSignedIntegerType()) {
13422 PDiag(diag::warn_impcast_integer_precision_constant)
13423 << PrettySourceValue << PrettyTargetValue << E->
getType() << T
13433 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13434 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13435 LikelySourceRange->Width == TargetRange.Width))) {
13439 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13441 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13445 unsigned DiagID = diag::warn_impcast_integer_sign;
13453 DiagID = diag::warn_impcast_integer_sign_conditional;
13465 return DiagnoseImpCast(*
this, E, T, CC, diag::warn_impcast_int_to_enum);
13470 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13472 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13473 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13474 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13475 TargetEnum->getDecl()->hasNameForLinkage() &&
13476 SourceEnum != TargetEnum) {
13481 diag::warn_impcast_different_enum_types);
13495 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13508 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13509 TrueExpr = BCO->getCommon();
13511 bool Suspicious =
false;
13515 if (T->isBooleanType())
13520 if (!Suspicious)
return;
13523 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13528 if (E->
getType() == T)
return;
13530 Suspicious =
false;
13535 E->
getType(), CC, &Suspicious);
13552struct AnalyzeImplicitConversionsWorkItem {
13561 bool ExtraCheckForImplicitConversion,
13564 WorkList.push_back({E, CC,
false});
13566 if (ExtraCheckForImplicitConversion && E->
getType() != T)
13573 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13575 Expr *OrigE = Item.E;
13594 Expr *SourceExpr = E;
13599 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13600 if (
auto *Src = OVE->getSourceExpr())
13603 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13604 if (UO->getOpcode() == UO_Not &&
13605 UO->getSubExpr()->isKnownToHaveBooleanValue())
13606 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13610 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13611 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13612 BO->getLHS()->isKnownToHaveBooleanValue() &&
13613 BO->getRHS()->isKnownToHaveBooleanValue() &&
13614 BO->getLHS()->HasSideEffects(S.
Context) &&
13615 BO->getRHS()->HasSideEffects(S.
Context)) {
13626 if (SR.str() ==
"&" || SR.str() ==
"|") {
13628 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13629 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13632 BO->getOperatorLoc(),
13633 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13634 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13636 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13654 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13660 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13666 if (SourceExpr->
getType() != T)
13675 for (
auto *SE : POE->semantics())
13676 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13677 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13681 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13682 E = CE->getSubExpr();
13688 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13689 if (InitListE->getNumInits() == 1) {
13690 E = InitListE->getInit(0);
13697 WorkList.push_back({E, CC, IsListInit});
13701 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13702 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13706 if (OutArgE->isInOut())
13707 WorkList.push_back(
13708 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13709 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13715 if (BO->isComparisonOp())
13719 if (BO->getOpcode() == BO_Assign)
13722 if (BO->isAssignmentOp())
13738 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13740 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13744 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13745 if (ChildExpr == CSE->getOperand())
13751 if (IsLogicalAndOperator &&
13756 WorkList.push_back({ChildExpr, CC, IsListInit});
13770 if (
U->getOpcode() == UO_LNot) {
13772 }
else if (
U->getOpcode() != UO_AddrOf) {
13773 if (
U->getSubExpr()->getType()->isAtomicType())
13774 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13775 diag::warn_atomic_implicit_seq_cst);
13786 WorkList.push_back({OrigE, CC, IsListInit});
13787 while (!WorkList.empty())
13799 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13802 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13803 if (!M->getMemberDecl()->getType()->isReferenceType())
13805 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13806 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13808 FD =
Call->getDirectCallee();
13817 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13831 if (
SM.isMacroBodyExpansion(Loc))
13833 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13857 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13858 : diag::warn_this_bool_conversion;
13863 bool IsAddressOf =
false;
13865 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13866 if (UO->getOpcode() != UO_AddrOf)
13868 IsAddressOf =
true;
13869 E = UO->getSubExpr();
13873 unsigned DiagID = IsCompare
13874 ? diag::warn_address_of_reference_null_compare
13875 : diag::warn_address_of_reference_bool_conversion;
13883 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13886 llvm::raw_string_ostream S(Str);
13888 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13889 : diag::warn_cast_nonnull_to_bool;
13892 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13897 if (
auto *Callee =
Call->getDirectCallee()) {
13898 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13899 ComplainAboutNonnullParamOrCall(A);
13908 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13909 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13910 MRecordDecl && MRecordDecl->isLambda()) {
13913 << MRecordDecl->getSourceRange() << Range << IsEqual;
13923 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13924 D = M->getMemberDecl();
13932 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13935 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13936 ComplainAboutNonnullParamOrCall(A);
13940 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13944 auto ParamIter = llvm::find(FD->
parameters(), PV);
13946 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13950 ComplainAboutNonnullParamOrCall(
NonNull);
13955 if (ArgNo.getASTIndex() == ParamNo) {
13956 ComplainAboutNonnullParamOrCall(
NonNull);
13967 const bool IsFunction = T->isFunctionType();
13970 if (IsAddressOf && IsFunction) {
13975 if (!IsAddressOf && !IsFunction && !IsArray)
13980 llvm::raw_string_ostream S(Str);
13983 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13984 : diag::warn_impcast_pointer_to_bool;
13991 DiagType = AddressOf;
13992 else if (IsFunction)
13993 DiagType = FunctionPointer;
13995 DiagType = ArrayPointer;
13997 llvm_unreachable(
"Could not determine diagnostic.");
13999 << Range << IsEqual;
14012 if (ReturnType.
isNull())
14043 if (
const auto *OBT = Source->getAs<OverflowBehaviorType>()) {
14044 if (
Target->isIntegerType() && !
Target->isOverflowBehaviorType()) {
14046 if (OBT->isUnsignedIntegerType() && OBT->isWrapKind() &&
14047 Target->isUnsignedIntegerType()) {
14051 ? diag::warn_impcast_overflow_behavior_assignment_pedantic
14052 : diag::warn_impcast_overflow_behavior_pedantic;
14056 ? diag::warn_impcast_overflow_behavior_assignment
14057 : diag::warn_impcast_overflow_behavior;
14063 if (
const auto *TargetOBT =
Target->getAs<OverflowBehaviorType>()) {
14064 if (TargetOBT->isWrapKind()) {
14084 CheckArrayAccess(E);
14094void Sema::CheckForIntOverflow (
const Expr *E) {
14096 SmallVector<const Expr *, 2> Exprs(1, E);
14099 const Expr *OriginalE = Exprs.pop_back_val();
14107 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
14108 Exprs.append(InitList->inits().begin(), InitList->inits().end());
14111 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
14112 Exprs.append(
Call->arg_begin(),
Call->arg_end());
14113 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
14115 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
14116 Exprs.append(Construct->arg_begin(), Construct->arg_end());
14117 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
14118 Exprs.push_back(Temporary->getSubExpr());
14119 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
14120 Exprs.push_back(
Array->getIdx());
14121 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
14122 Exprs.push_back(Compound->getInitializer());
14123 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
14124 New &&
New->isArray()) {
14125 if (
auto ArraySize =
New->getArraySize())
14126 Exprs.push_back(*ArraySize);
14127 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
14128 Exprs.push_back(MTE->getSubExpr());
14129 }
while (!Exprs.empty());
14137 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
14144 class SequenceTree {
14146 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
14147 unsigned Parent : 31;
14148 LLVM_PREFERRED_TYPE(
bool)
14149 unsigned Merged : 1;
14151 SmallVector<Value, 8> Values;
14157 friend class SequenceTree;
14161 explicit Seq(
unsigned N) : Index(N) {}
14164 Seq() : Index(0) {}
14167 SequenceTree() { Values.push_back(
Value(0)); }
14168 Seq root()
const {
return Seq(0); }
14173 Seq allocate(
Seq Parent) {
14174 Values.push_back(
Value(Parent.Index));
14175 return Seq(Values.size() - 1);
14180 Values[S.Index].Merged =
true;
14186 bool isUnsequenced(
Seq Cur,
Seq Old) {
14187 unsigned C = representative(Cur.Index);
14188 unsigned Target = representative(Old.Index);
14192 C = Values[
C].Parent;
14199 unsigned representative(
unsigned K) {
14200 if (Values[K].Merged)
14202 return Values[K].Parent = representative(Values[K].Parent);
14208 using Object =
const NamedDecl *;
14222 UK_ModAsSideEffect,
14224 UK_Count = UK_ModAsSideEffect + 1
14230 const Expr *UsageExpr =
nullptr;
14231 SequenceTree::Seq
Seq;
14237 Usage Uses[UK_Count];
14240 bool Diagnosed =
false;
14244 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14252 UsageInfoMap UsageMap;
14255 SequenceTree::Seq Region;
14259 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14263 SmallVectorImpl<const Expr *> &WorkList;
14270 struct SequencedSubexpression {
14271 SequencedSubexpression(SequenceChecker &
Self)
14272 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14273 Self.ModAsSideEffect = &ModAsSideEffect;
14276 ~SequencedSubexpression() {
14277 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14281 UsageInfo &UI =
Self.UsageMap[M.first];
14282 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14283 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14284 SideEffectUsage = M.second;
14286 Self.ModAsSideEffect = OldModAsSideEffect;
14289 SequenceChecker &
Self;
14290 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14291 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14298 class EvaluationTracker {
14300 EvaluationTracker(SequenceChecker &
Self)
14302 Self.EvalTracker =
this;
14305 ~EvaluationTracker() {
14306 Self.EvalTracker = Prev;
14308 Prev->EvalOK &= EvalOK;
14311 bool evaluate(
const Expr *E,
bool &
Result) {
14316 Self.SemaRef.isConstantEvaluatedContext());
14321 SequenceChecker &
Self;
14322 EvaluationTracker *Prev;
14323 bool EvalOK =
true;
14324 } *EvalTracker =
nullptr;
14328 Object getObject(
const Expr *E,
bool Mod)
const {
14330 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14331 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14332 return getObject(UO->getSubExpr(), Mod);
14333 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14334 if (BO->getOpcode() == BO_Comma)
14335 return getObject(BO->getRHS(), Mod);
14336 if (Mod && BO->isAssignmentOp())
14337 return getObject(BO->getLHS(), Mod);
14338 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14341 return ME->getMemberDecl();
14342 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14351 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14353 Usage &U = UI.Uses[UK];
14354 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14358 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14359 ModAsSideEffect->push_back(std::make_pair(O, U));
14361 U.UsageExpr = UsageExpr;
14371 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
14372 UsageKind OtherKind,
bool IsModMod) {
14376 const Usage &U = UI.Uses[OtherKind];
14377 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14380 const Expr *Mod = U.UsageExpr;
14381 const Expr *ModOrUse = UsageExpr;
14382 if (OtherKind == UK_Use)
14383 std::swap(Mod, ModOrUse);
14387 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14388 : diag::warn_unsequenced_mod_use)
14389 << O << SourceRange(ModOrUse->
getExprLoc()));
14390 UI.Diagnosed =
true;
14419 void notePreUse(Object O,
const Expr *UseExpr) {
14420 UsageInfo &UI = UsageMap[O];
14422 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14425 void notePostUse(Object O,
const Expr *UseExpr) {
14426 UsageInfo &UI = UsageMap[O];
14427 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14429 addUsage(O, UI, UseExpr, UK_Use);
14432 void notePreMod(Object O,
const Expr *ModExpr) {
14433 UsageInfo &UI = UsageMap[O];
14435 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14436 checkUsage(O, UI, ModExpr, UK_Use,
false);
14439 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
14440 UsageInfo &UI = UsageMap[O];
14441 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14443 addUsage(O, UI, ModExpr, UK);
14447 SequenceChecker(Sema &S,
const Expr *E,
14448 SmallVectorImpl<const Expr *> &WorkList)
14449 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14453 (void)this->WorkList;
14456 void VisitStmt(
const Stmt *S) {
14460 void VisitExpr(
const Expr *E) {
14462 Base::VisitStmt(E);
14465 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14466 for (
auto *Sub : CSE->
children()) {
14467 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14482 void VisitCastExpr(
const CastExpr *E) {
14494 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14495 const Expr *SequencedAfter) {
14496 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14497 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14498 SequenceTree::Seq OldRegion = Region;
14501 SequencedSubexpression SeqBefore(*
this);
14502 Region = BeforeRegion;
14503 Visit(SequencedBefore);
14506 Region = AfterRegion;
14507 Visit(SequencedAfter);
14509 Region = OldRegion;
14511 Tree.merge(BeforeRegion);
14512 Tree.merge(AfterRegion);
14515 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14520 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14527 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14528 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14529 void VisitBinPtrMem(
const BinaryOperator *BO) {
14534 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14541 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14542 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14543 void VisitBinShlShr(
const BinaryOperator *BO) {
14547 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14554 void VisitBinComma(
const BinaryOperator *BO) {
14559 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14562 void VisitBinAssign(
const BinaryOperator *BO) {
14563 SequenceTree::Seq RHSRegion;
14564 SequenceTree::Seq LHSRegion;
14566 RHSRegion = Tree.allocate(Region);
14567 LHSRegion = Tree.allocate(Region);
14569 RHSRegion = Region;
14570 LHSRegion = Region;
14572 SequenceTree::Seq OldRegion = Region;
14588 SequencedSubexpression SeqBefore(*
this);
14589 Region = RHSRegion;
14593 Region = LHSRegion;
14597 notePostUse(O, BO);
14601 Region = LHSRegion;
14605 notePostUse(O, BO);
14607 Region = RHSRegion;
14615 Region = OldRegion;
14619 : UK_ModAsSideEffect);
14621 Tree.merge(RHSRegion);
14622 Tree.merge(LHSRegion);
14626 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14627 VisitBinAssign(CAO);
14630 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14631 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14632 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14635 return VisitExpr(UO);
14643 : UK_ModAsSideEffect);
14646 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14647 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14648 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14651 return VisitExpr(UO);
14655 notePostMod(O, UO, UK_ModAsSideEffect);
14658 void VisitBinLOr(
const BinaryOperator *BO) {
14664 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14665 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14666 SequenceTree::Seq OldRegion = Region;
14668 EvaluationTracker Eval(*
this);
14670 SequencedSubexpression Sequenced(*
this);
14671 Region = LHSRegion;
14678 bool EvalResult =
false;
14679 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14680 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14681 if (ShouldVisitRHS) {
14682 Region = RHSRegion;
14686 Region = OldRegion;
14687 Tree.merge(LHSRegion);
14688 Tree.merge(RHSRegion);
14691 void VisitBinLAnd(
const BinaryOperator *BO) {
14697 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14698 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14699 SequenceTree::Seq OldRegion = Region;
14701 EvaluationTracker Eval(*
this);
14703 SequencedSubexpression Sequenced(*
this);
14704 Region = LHSRegion;
14710 bool EvalResult =
false;
14711 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14712 bool ShouldVisitRHS = !EvalOK || EvalResult;
14713 if (ShouldVisitRHS) {
14714 Region = RHSRegion;
14718 Region = OldRegion;
14719 Tree.merge(LHSRegion);
14720 Tree.merge(RHSRegion);
14723 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14728 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14744 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14745 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14746 SequenceTree::Seq OldRegion = Region;
14748 EvaluationTracker Eval(*
this);
14750 SequencedSubexpression Sequenced(*
this);
14751 Region = ConditionRegion;
14761 bool EvalResult =
false;
14762 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14763 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14764 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14765 if (ShouldVisitTrueExpr) {
14766 Region = TrueRegion;
14769 if (ShouldVisitFalseExpr) {
14770 Region = FalseRegion;
14774 Region = OldRegion;
14775 Tree.merge(ConditionRegion);
14776 Tree.merge(TrueRegion);
14777 Tree.merge(FalseRegion);
14780 void VisitCallExpr(
const CallExpr *CE) {
14792 SequencedSubexpression Sequenced(*
this);
14797 SequenceTree::Seq CalleeRegion;
14798 SequenceTree::Seq OtherRegion;
14799 if (SemaRef.getLangOpts().CPlusPlus17) {
14800 CalleeRegion = Tree.allocate(Region);
14801 OtherRegion = Tree.allocate(Region);
14803 CalleeRegion = Region;
14804 OtherRegion = Region;
14806 SequenceTree::Seq OldRegion = Region;
14809 Region = CalleeRegion;
14811 SequencedSubexpression Sequenced(*this);
14812 Visit(CE->getCallee());
14814 Visit(CE->getCallee());
14818 Region = OtherRegion;
14822 Region = OldRegion;
14824 Tree.merge(CalleeRegion);
14825 Tree.merge(OtherRegion);
14843 return VisitCallExpr(CXXOCE);
14854 case OO_MinusEqual:
14856 case OO_SlashEqual:
14857 case OO_PercentEqual:
14858 case OO_CaretEqual:
14861 case OO_LessLessEqual:
14862 case OO_GreaterGreaterEqual:
14863 SequencingKind = RHSBeforeLHS;
14867 case OO_GreaterGreater:
14873 SequencingKind = LHSBeforeRHS;
14877 SequencingKind = LHSBeforeRest;
14881 SequencingKind = NoSequencing;
14885 if (SequencingKind == NoSequencing)
14886 return VisitCallExpr(CXXOCE);
14889 SequencedSubexpression Sequenced(*
this);
14892 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14893 "Should only get there with C++17 and above!");
14894 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14895 "Should only get there with an overloaded binary operator"
14896 " or an overloaded call operator!");
14898 if (SequencingKind == LHSBeforeRest) {
14899 assert(CXXOCE->getOperator() == OO_Call &&
14900 "We should only have an overloaded call operator here!");
14909 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14910 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14911 SequenceTree::Seq OldRegion = Region;
14913 assert(CXXOCE->getNumArgs() >= 1 &&
14914 "An overloaded call operator must have at least one argument"
14915 " for the postfix-expression!");
14916 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14917 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14918 CXXOCE->getNumArgs() - 1);
14922 Region = PostfixExprRegion;
14923 SequencedSubexpression Sequenced(*this);
14924 Visit(PostfixExpr);
14928 Region = ArgsRegion;
14929 for (const Expr *Arg : Args)
14932 Region = OldRegion;
14933 Tree.merge(PostfixExprRegion);
14934 Tree.merge(ArgsRegion);
14936 assert(CXXOCE->getNumArgs() == 2 &&
14937 "Should only have two arguments here!");
14938 assert((SequencingKind == LHSBeforeRHS ||
14939 SequencingKind == RHSBeforeLHS) &&
14940 "Unexpected sequencing kind!");
14944 const Expr *E1 = CXXOCE->getArg(0);
14945 const Expr *E2 = CXXOCE->getArg(1);
14946 if (SequencingKind == RHSBeforeLHS)
14949 return VisitSequencedExpressions(E1, E2);
14956 SequencedSubexpression Sequenced(*
this);
14959 return VisitExpr(CCE);
14962 SequenceExpressionsInOrder(
14968 return VisitExpr(ILE);
14971 SequenceExpressionsInOrder(ILE->
inits());
14983 SequenceTree::Seq Parent = Region;
14984 for (
const Expr *E : ExpressionList) {
14987 Region = Tree.allocate(Parent);
14988 Elts.push_back(Region);
14994 for (
unsigned I = 0; I < Elts.size(); ++I)
14995 Tree.merge(Elts[I]);
14999SequenceChecker::UsageInfo::UsageInfo() =
default;
15003void Sema::CheckUnsequencedOperations(
const Expr *E) {
15004 SmallVector<const Expr *, 8> WorkList;
15005 WorkList.push_back(E);
15006 while (!WorkList.empty()) {
15007 const Expr *Item = WorkList.pop_back_val();
15008 SequenceChecker(*
this, Item, WorkList);
15013 bool IsConstexpr) {
15016 CheckImplicitConversions(E, CheckLoc);
15018 CheckUnsequencedOperations(E);
15020 CheckForIntOverflow(E);
15033 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
15037 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
15041 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
15055 S.
Diag(Loc, diag::err_array_star_in_function_definition);
15059 bool CheckParameterNames) {
15060 bool HasInvalidParm =
false;
15062 assert(Param &&
"null in a parameter list");
15071 if (!Param->isInvalidDecl() &&
15073 diag::err_typecheck_decl_incomplete_type) ||
15075 diag::err_abstract_type_in_decl,
15077 Param->setInvalidDecl();
15078 HasInvalidParm =
true;
15083 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
15087 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
15095 QualType PType = Param->getOriginalType();
15103 if (!Param->isInvalidDecl()) {
15104 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
15105 if (!ClassDecl->isInvalidDecl() &&
15106 !ClassDecl->hasIrrelevantDestructor() &&
15107 !ClassDecl->isDependentContext() &&
15108 ClassDecl->isParamDestroyedInCallee()) {
15120 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
15121 if (!Param->getType().isConstQualified())
15122 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
15126 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
15131 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
15132 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
15137 if (!Param->isInvalidDecl() &&
15138 Param->getOriginalType()->isWebAssemblyTableType()) {
15139 Param->setInvalidDecl();
15140 HasInvalidParm =
true;
15141 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
15145 return HasInvalidParm;
15148std::optional<std::pair<
15157static std::pair<CharUnits, CharUnits>
15165 if (
Base->isVirtual()) {
15172 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
15179 DerivedType =
Base->getType();
15182 return std::make_pair(BaseAlignment, Offset);
15186static std::optional<std::pair<CharUnits, CharUnits>>
15192 return std::nullopt;
15197 return std::nullopt;
15201 CharUnits Offset = EltSize * IdxRes->getExtValue();
15204 return std::make_pair(P->first, P->second + Offset);
15210 return std::make_pair(
15211 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
15217std::optional<std::pair<
15225 case Stmt::CStyleCastExprClass:
15226 case Stmt::CXXStaticCastExprClass:
15227 case Stmt::ImplicitCastExprClass: {
15229 const Expr *From = CE->getSubExpr();
15230 switch (CE->getCastKind()) {
15235 case CK_UncheckedDerivedToBase:
15236 case CK_DerivedToBase: {
15246 case Stmt::ArraySubscriptExprClass: {
15251 case Stmt::DeclRefExprClass: {
15255 if (!VD->getType()->isReferenceType()) {
15257 if (VD->hasDependentAlignment())
15266 case Stmt::MemberExprClass: {
15268 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15272 std::optional<std::pair<CharUnits, CharUnits>> P;
15281 return std::make_pair(P->first,
15284 case Stmt::UnaryOperatorClass: {
15294 case Stmt::BinaryOperatorClass: {
15306 return std::nullopt;
15311std::optional<std::pair<
15320 case Stmt::CStyleCastExprClass:
15321 case Stmt::CXXStaticCastExprClass:
15322 case Stmt::ImplicitCastExprClass: {
15324 const Expr *From = CE->getSubExpr();
15325 switch (CE->getCastKind()) {
15330 case CK_ArrayToPointerDecay:
15332 case CK_UncheckedDerivedToBase:
15333 case CK_DerivedToBase: {
15343 case Stmt::CXXThisExprClass: {
15348 case Stmt::UnaryOperatorClass: {
15354 case Stmt::BinaryOperatorClass: {
15363 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15364 std::swap(LHS, RHS);
15374 return std::nullopt;
15379 std::optional<std::pair<CharUnits, CharUnits>> P =
15383 return P->first.alignmentAtOffset(P->second);
15401 if (!DestPtr)
return;
15407 if (DestAlign.
isOne())
return;
15411 if (!SrcPtr)
return;
15422 if (SrcAlign >= DestAlign)
return;
15427 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15431void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15433 bool AllowOnePastEnd,
bool IndexNegated) {
15442 const Type *EffectiveType =
15446 Context.getAsConstantArrayType(BaseExpr->
getType());
15449 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15451 const Type *BaseType =
15453 bool IsUnboundedArray =
15455 Context, StrictFlexArraysLevel,
15458 (!IsUnboundedArray && BaseType->isDependentType()))
15466 if (IndexNegated) {
15467 index.setIsUnsigned(
false);
15471 if (IsUnboundedArray) {
15474 if (
index.isUnsigned() || !
index.isNegative()) {
15476 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15478 if (
index.getBitWidth() < AddrBits)
15480 std::optional<CharUnits> ElemCharUnits =
15481 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15484 if (!ElemCharUnits || ElemCharUnits->isZero())
15486 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15491 if (
index.getActiveBits() <= AddrBits) {
15493 llvm::APInt Product(
index);
15495 Product = Product.umul_ov(ElemBytes, Overflow);
15496 if (!Overflow && Product.getActiveBits() <= AddrBits)
15502 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15503 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15505 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15506 MaxElems = MaxElems.udiv(ElemBytes);
15509 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15510 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15515 PDiag(DiagID) << index << AddrBits
15516 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15517 << ElemBytes << MaxElems
15518 << MaxElems.getZExtValue()
15521 const NamedDecl *ND =
nullptr;
15523 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15525 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15527 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15528 ND = ME->getMemberDecl();
15532 PDiag(diag::note_array_declared_here) << ND);
15537 if (index.isUnsigned() || !index.isNegative()) {
15547 llvm::APInt size = ArrayTy->
getSize();
15549 if (BaseType != EffectiveType) {
15557 if (!ptrarith_typesize)
15558 ptrarith_typesize =
Context.getCharWidth();
15560 if (ptrarith_typesize != array_typesize) {
15562 uint64_t ratio = array_typesize / ptrarith_typesize;
15566 if (ptrarith_typesize * ratio == array_typesize)
15567 size *= llvm::APInt(size.getBitWidth(), ratio);
15571 if (size.getBitWidth() > index.getBitWidth())
15572 index = index.zext(size.getBitWidth());
15573 else if (size.getBitWidth() < index.getBitWidth())
15574 size = size.zext(index.getBitWidth());
15580 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15587 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15589 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15590 SourceLocation IndexLoc =
15592 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15597 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15598 : diag::warn_ptr_arith_exceeds_bounds;
15599 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15600 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15604 << index << ArrayTy->
desugar() << CastMsg
15607 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15609 DiagID = diag::warn_ptr_arith_precedes_bounds;
15610 if (index.isNegative()) index = -index;
15617 const NamedDecl *ND =
nullptr;
15619 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15621 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15623 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15624 ND = ME->getMemberDecl();
15628 PDiag(diag::note_array_declared_here) << ND);
15631void Sema::CheckArrayAccess(
const Expr *
expr) {
15632 int AllowOnePastEnd = 0;
15634 expr =
expr->IgnoreParenImpCasts();
15635 switch (
expr->getStmtClass()) {
15636 case Stmt::ArraySubscriptExprClass: {
15639 AllowOnePastEnd > 0);
15643 case Stmt::MemberExprClass: {
15647 case Stmt::CXXMemberCallExprClass: {
15651 case Stmt::ArraySectionExprClass: {
15657 nullptr, AllowOnePastEnd > 0);
15660 case Stmt::UnaryOperatorClass: {
15676 case Stmt::ConditionalOperatorClass: {
15678 if (
const Expr *lhs = cond->
getLHS())
15679 CheckArrayAccess(lhs);
15680 if (
const Expr *rhs = cond->
getRHS())
15681 CheckArrayAccess(rhs);
15684 case Stmt::CXXOperatorCallExprClass: {
15686 for (
const auto *Arg : OCE->arguments())
15687 CheckArrayAccess(Arg);
15697 Expr *RHS,
bool isProperty) {
15709 S.
Diag(Loc, diag::warn_arc_literal_assign)
15711 << (isProperty ? 0 : 1)
15719 Expr *RHS,
bool isProperty) {
15722 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15723 S.
Diag(Loc, diag::warn_arc_retained_assign)
15725 << (isProperty ? 0 : 1)
15729 RHS =
cast->getSubExpr();
15771 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15800 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15801 Diag(Loc, diag::warn_arc_retained_property_assign)
15805 RHS =
cast->getSubExpr();
15828 bool StmtLineInvalid;
15829 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15831 if (StmtLineInvalid)
15834 bool BodyLineInvalid;
15835 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15837 if (BodyLineInvalid)
15841 if (StmtLine != BodyLine)
15856 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15865 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15869 const Stmt *PossibleBody) {
15875 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15876 StmtLoc = FS->getRParenLoc();
15877 Body = FS->getBody();
15878 DiagID = diag::warn_empty_for_body;
15879 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15880 StmtLoc = WS->getRParenLoc();
15881 Body = WS->getBody();
15882 DiagID = diag::warn_empty_while_body;
15887 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15911 if (!ProbableTypo) {
15912 bool BodyColInvalid;
15913 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15915 if (BodyColInvalid)
15918 bool StmtColInvalid;
15921 if (StmtColInvalid)
15924 if (BodyCol > StmtCol)
15925 ProbableTypo =
true;
15928 if (ProbableTypo) {
15930 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15938 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15950 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15952 RHSExpr = CE->
getArg(0);
15953 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15954 CXXSCE && CXXSCE->isXValue())
15955 RHSExpr = CXXSCE->getSubExpr();
15959 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15960 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15963 if (LHSDeclRef && RHSDeclRef) {
15970 auto D =
Diag(OpLoc, diag::warn_self_move)
15986 const Expr *LHSBase = LHSExpr;
15987 const Expr *RHSBase = RHSExpr;
15988 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15989 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15990 if (!LHSME || !RHSME)
15993 while (LHSME && RHSME) {
16000 LHSME = dyn_cast<MemberExpr>(LHSBase);
16001 RHSME = dyn_cast<MemberExpr>(RHSBase);
16004 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
16005 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
16006 if (LHSDeclRef && RHSDeclRef) {
16013 Diag(OpLoc, diag::warn_self_move)
16020 Diag(OpLoc, diag::warn_self_move)
16044 bool AreUnionMembers =
false) {
16048 assert(((Field1Parent->isStructureOrClassType() &&
16049 Field2Parent->isStructureOrClassType()) ||
16050 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
16051 "Can't evaluate layout compatibility between a struct field and a "
16053 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
16054 (AreUnionMembers && Field1Parent->isUnionType())) &&
16055 "AreUnionMembers should be 'true' for union fields (only).");
16069 if (Bits1 != Bits2)
16073 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
16074 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
16077 if (!AreUnionMembers &&
16089 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
16090 RD1 = D1CXX->getStandardLayoutBaseWithFields();
16092 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
16093 RD2 = D2CXX->getStandardLayoutBaseWithFields();
16098 return isLayoutCompatible(C, F1, F2);
16109 for (
auto *Field1 : RD1->
fields()) {
16110 auto I = UnmatchedFields.begin();
16111 auto E = UnmatchedFields.end();
16113 for ( ; I != E; ++I) {
16115 bool Result = UnmatchedFields.erase(*I);
16125 return UnmatchedFields.empty();
16151 if (
C.hasSameType(T1, T2))
16160 if (TC1 == Type::Enum)
16162 if (TC1 == Type::Record) {
16181 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
16212 const ValueDecl **VD, uint64_t *MagicValue,
16213 bool isConstantEvaluated) {
16221 case Stmt::UnaryOperatorClass: {
16230 case Stmt::DeclRefExprClass: {
16236 case Stmt::IntegerLiteralClass: {
16238 llvm::APInt MagicValueAPInt = IL->
getValue();
16239 if (MagicValueAPInt.getActiveBits() <= 64) {
16240 *MagicValue = MagicValueAPInt.getZExtValue();
16246 case Stmt::BinaryConditionalOperatorClass:
16247 case Stmt::ConditionalOperatorClass: {
16252 isConstantEvaluated)) {
16262 case Stmt::BinaryOperatorClass: {
16265 TypeExpr = BO->
getRHS();
16295 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16298 bool isConstantEvaluated) {
16299 FoundWrongKind =
false;
16304 uint64_t MagicValue;
16306 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16310 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16311 if (I->getArgumentKind() != ArgumentKind) {
16312 FoundWrongKind =
true;
16315 TypeInfo.Type = I->getMatchingCType();
16316 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16317 TypeInfo.MustBeNull = I->getMustBeNull();
16328 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16329 if (I == MagicValues->end())
16338 bool LayoutCompatible,
16340 if (!TypeTagForDatatypeMagicValues)
16341 TypeTagForDatatypeMagicValues.reset(
16342 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16345 (*TypeTagForDatatypeMagicValues)[Magic] =
16361 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16362 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16363 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16364 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16367void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16370 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16371 bool IsPointerAttr = Attr->getIsPointer();
16374 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16375 if (TypeTagIdxAST >= ExprArgs.size()) {
16376 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16377 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16380 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16381 bool FoundWrongKind;
16384 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16386 if (FoundWrongKind)
16388 diag::warn_type_tag_for_datatype_wrong_kind)
16394 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16395 if (ArgumentIdxAST >= ExprArgs.size()) {
16396 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16397 << 1 << Attr->getArgumentIdx().getSourceIndex();
16400 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16401 if (IsPointerAttr) {
16403 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16404 if (ICE->getType()->isVoidPointerType() &&
16405 ICE->getCastKind() == CK_BitCast)
16406 ArgumentExpr = ICE->getSubExpr();
16408 QualType ArgumentType = ArgumentExpr->
getType();
16414 if (TypeInfo.MustBeNull) {
16419 diag::warn_type_safety_null_pointer_required)
16427 QualType RequiredType = TypeInfo.Type;
16429 RequiredType =
Context.getPointerType(RequiredType);
16431 bool mismatch =
false;
16432 if (!TypeInfo.LayoutCompatible) {
16433 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16454 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16455 << ArgumentType << ArgumentKind
16456 << TypeInfo.LayoutCompatible << RequiredType
16474 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16482 if (!T->isPointerType() && !T->isIntegerType() && !T->isDependentType())
16488 auto &MisalignedMembersForExpr =
16490 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16491 if (MA != MisalignedMembersForExpr.end() &&
16492 (T->isDependentType() || T->isIntegerType() ||
16493 (T->isPointerType() && (T->getPointeeType()->isIncompleteType() ||
16495 T->getPointeeType()) <= MA->Alignment))))
16496 MisalignedMembersForExpr.erase(MA);
16505 const auto *ME = dyn_cast<MemberExpr>(E);
16517 bool AnyIsPacked =
false;
16519 QualType BaseType = ME->getBase()->getType();
16520 if (BaseType->isDependentType())
16524 auto *RD = BaseType->castAsRecordDecl();
16529 auto *FD = dyn_cast<FieldDecl>(MD);
16535 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16536 ReverseMemberChain.push_back(FD);
16539 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16541 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16548 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16559 if (ExpectedAlignment.
isOne())
16564 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16565 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16569 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16573 if (DRE && !TopME->
isArrow()) {
16576 CompleteObjectAlignment =
16577 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16581 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16584 CompleteObjectAlignment < ExpectedAlignment) {
16595 for (
FieldDecl *FDI : ReverseMemberChain) {
16596 if (FDI->hasAttr<PackedAttr>() ||
16597 FDI->getParent()->hasAttr<PackedAttr>()) {
16599 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16605 assert(FD &&
"We did not find a packed FieldDecl!");
16606 Action(E, FD->
getParent(), FD, Alignment);
16610void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16611 using namespace std::placeholders;
16614 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16638bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16639 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16666 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16683 assert(!Args.empty() &&
"Should have at least one argument.");
16685 Expr *Arg0 = Args.front();
16688 auto EmitError = [&](
Expr *ArgI) {
16690 diag::err_typecheck_call_different_arg_types)
16691 << Arg0->
getType() << ArgI->getType();
16696 for (
Expr *ArgI : Args.drop_front())
16707 for (
Expr *ArgI : Args.drop_front()) {
16708 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16711 VecI->getElementType()) ||
16712 Vec0->getNumElements() != VecI->getNumElements()) {
16721std::optional<QualType>
16725 return std::nullopt;
16729 return std::nullopt;
16732 for (
int I = 0; I < 2; ++I) {
16736 return std::nullopt;
16737 Args[I] = Converted.
get();
16744 return std::nullopt;
16747 return std::nullopt;
16749 TheCall->
setArg(0, Args[0]);
16750 TheCall->
setArg(1, Args[1]);
16761 TheCall->
getArg(1), Loc) ||
16763 TheCall->
getArg(2), Loc))
16767 for (
int I = 0; I < 3; ++I) {
16772 Args[I] = Converted.
get();
16775 int ArgOrdinal = 1;
16776 for (
Expr *Arg : Args) {
16778 ArgTyRestr, ArgOrdinal++))
16785 for (
int I = 0; I < 3; ++I)
16786 TheCall->
setArg(I, Args[I]);
16792bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16804bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16813 diag::err_builtin_invalid_arg_type)
16814 << 1 << 2 << 1 << 1 << TyArg;
16828 Expr *Matrix = MatrixArg.
get();
16830 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16833 << 1 << 3 << 0 << 0
16840 QualType ResultType =
Context.getConstantMatrixType(
16841 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16844 TheCall->
setType(ResultType);
16847 TheCall->
setArg(0, Matrix);
16852static std::optional<unsigned>
16860 uint64_t
Dim =
Value->getZExtValue();
16876 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16878 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16886 unsigned PtrArgIdx = 0;
16887 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16888 Expr *RowsExpr = TheCall->
getArg(1);
16889 Expr *ColumnsExpr = TheCall->
getArg(2);
16890 Expr *StrideExpr = TheCall->
getArg(3);
16892 bool ArgError =
false;
16899 PtrExpr = PtrConv.
get();
16900 TheCall->
setArg(0, PtrExpr);
16907 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16908 QualType ElementTy;
16911 << PtrArgIdx + 1 << 0 << 5 << 0
16915 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16919 << PtrArgIdx + 1 << 0 << 5
16926 auto ApplyArgumentConversions = [
this](Expr *E) {
16935 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16937 RowsExpr = RowsConv.
get();
16938 TheCall->
setArg(1, RowsExpr);
16940 RowsExpr =
nullptr;
16942 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16944 ColumnsExpr = ColumnsConv.
get();
16945 TheCall->
setArg(2, ColumnsExpr);
16947 ColumnsExpr =
nullptr;
16958 std::optional<unsigned> MaybeRows;
16962 std::optional<unsigned> MaybeColumns;
16967 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16970 StrideExpr = StrideConv.
get();
16971 TheCall->
setArg(3, StrideExpr);
16974 if (std::optional<llvm::APSInt>
Value =
16977 if (Stride < *MaybeRows) {
16979 diag::err_builtin_matrix_stride_too_small);
16985 if (ArgError || !MaybeRows || !MaybeColumns)
16989 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
17000 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
17002 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
17010 unsigned PtrArgIdx = 1;
17011 Expr *MatrixExpr = TheCall->
getArg(0);
17012 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
17013 Expr *StrideExpr = TheCall->
getArg(2);
17015 bool ArgError =
false;
17021 MatrixExpr = MatrixConv.
get();
17022 TheCall->
setArg(0, MatrixExpr);
17029 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
17032 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
17040 PtrExpr = PtrConv.
get();
17041 TheCall->
setArg(1, PtrExpr);
17049 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
17052 << PtrArgIdx + 1 << 0 << 5 << 0
17056 QualType ElementTy = PtrTy->getPointeeType();
17058 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
17063 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
17065 diag::err_builtin_matrix_pointer_arg_mismatch)
17066 << ElementTy << MatrixTy->getElementType();
17081 StrideExpr = StrideConv.
get();
17082 TheCall->
setArg(2, StrideExpr);
17087 if (std::optional<llvm::APSInt>
Value =
17090 if (Stride < MatrixTy->getNumRows()) {
17092 diag::err_builtin_matrix_stride_too_small);
17112 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
17117 llvm::StringSet<> CalleeTCBs;
17118 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
17119 CalleeTCBs.insert(A->getTCBName());
17120 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
17121 CalleeTCBs.insert(A->getTCBName());
17125 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
17126 StringRef CallerTCB = A->getTCBName();
17127 if (CalleeTCBs.count(CallerTCB) == 0) {
17128 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17129 << 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.
UnresolvedSetImpl::iterator iterator
Represents a matrix type, as defined in the Matrix Types clang extensions.
static bool isValidElementType(QualType T, const LangOptions &LangOpts)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
Pointer-authentication qualifiers.
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
bool isAddressDiscriminated() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isSEHExceptScope() const
Determine whether this scope is a SEH '__except' block.
unsigned getFlags() const
getFlags - Return the flags for this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Abstract base class used to perform a contextual implicit conversion from an expression to any type p...
ContextualImplicitConverter(bool Suppress=false, bool SuppressConversion=false)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
bool CheckOverflowBehaviorTypeConversion(Expr *E, QualType T, SourceLocation CC)
Check for overflow behavior type related implicit conversion diagnostics.
FPOptionsOverride CurFPFeatureOverrides()
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
DiagnosticsEngine & getDiagnostics() const
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
bool InOverflowBehaviorAssignmentContext
Track if we're currently analyzing overflow behavior types in assignment context.
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
EltwiseBuiltinArgTyRestriction
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FormatStringI...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isAtomicType() const
bool isFunctionProtoType() const
bool isMatrixType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
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.