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()) {
499 Expr *makeOpaqueValueExpr(Expr *Inner) {
503 Actions.push_back(OVE);
507 Expr *getStringLiteral(llvm::StringRef Str) {
510 return new (S.
Context) ParenExpr(Loc, Loc, Lit);
513 bool callPrintFunction(llvm::StringRef Format,
514 llvm::ArrayRef<Expr *> Exprs = {}) {
515 SmallVector<Expr *, 8> Args;
517 Args.reserve((TheCall->
getNumArgs() - 2) + 1 + Exprs.size());
519 Args.push_back(getStringLiteral(Format));
520 llvm::append_range(Args, Exprs);
523 Sema::CodeSynthesisContext Ctx;
536 Actions.push_back(RealCall.
get());
542 Expr *getIndentString(
unsigned Depth) {
546 llvm::SmallString<32>
Indent;
548 return getStringLiteral(
Indent);
552 return getStringLiteral(
T.getAsString(Policy));
555 bool appendFormatSpecifier(QualType
T, llvm::SmallVectorImpl<char> &Str) {
556 llvm::raw_svector_ostream
OS(Str);
560 if (
auto *BT =
T->
getAs<BuiltinType>()) {
561 switch (BT->getKind()) {
562 case BuiltinType::Bool:
565 case BuiltinType::Char_U:
566 case BuiltinType::UChar:
569 case BuiltinType::Char_S:
570 case BuiltinType::SChar:
578 analyze_printf::PrintfSpecifier
Specifier;
581 if (
Specifier.getConversionSpecifier().getKind() ==
582 analyze_printf::PrintfConversionSpecifier::sArg) {
588 Specifier.setPrecision(analyze_printf::OptionalAmount(32u));
608 bool dumpUnnamedRecord(
const RecordDecl *RD, Expr *E,
unsigned Depth) {
609 Expr *IndentLit = getIndentString(Depth);
611 if (IndentLit ? callPrintFunction(
"%s%s", {IndentLit, TypeLit})
612 : callPrintFunction(
"%s", {TypeLit}))
615 return dumpRecordValue(RD, E, IndentLit, Depth);
619 bool dumpRecordValue(
const RecordDecl *RD, Expr *E, Expr *RecordIndent,
628 Expr *RecordArg = makeOpaqueValueExpr(E);
631 if (callPrintFunction(
" {\n"))
635 if (
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
636 for (
const auto &Base : CXXRD->bases()) {
644 dumpUnnamedRecord(
Base.getType()->getAsRecordDecl(), BasePtr.
get(),
650 Expr *FieldIndentArg = getIndentString(Depth + 1);
653 for (
auto *D : RD->
decls()) {
654 auto *IFD = dyn_cast<IndirectFieldDecl>(D);
655 auto *FD = IFD ? IFD->getAnonField() : dyn_cast<FieldDecl>(D);
656 if (!FD || FD->isUnnamedBitField() || FD->isAnonymousStructOrUnion())
659 llvm::SmallString<20> Format = llvm::StringRef(
"%s%s %s ");
660 llvm::SmallVector<Expr *, 5> Args = {FieldIndentArg,
662 getStringLiteral(FD->getName())};
664 if (FD->isBitField()) {
668 FD->getBitWidthValue());
676 CXXScopeSpec(), Loc, IFD,
679 RecordArg, RecordArgIsPtr, Loc, CXXScopeSpec(), FD,
681 DeclarationNameInfo(FD->getDeclName(), Loc));
682 if (
Field.isInvalid())
685 auto *InnerRD = FD->getType()->getAsRecordDecl();
686 auto *InnerCXXRD = dyn_cast_or_null<CXXRecordDecl>(InnerRD);
687 if (InnerRD && (!InnerCXXRD || InnerCXXRD->isAggregate())) {
689 if (callPrintFunction(Format, Args) ||
690 dumpRecordValue(InnerRD,
Field.get(), FieldIndentArg, Depth + 1))
694 if (appendFormatSpecifier(FD->getType(), Format)) {
696 Args.push_back(
Field.get());
706 Args.push_back(FieldAddr.
get());
709 if (callPrintFunction(Format, Args))
714 return RecordIndent ? callPrintFunction(
"%s}\n", RecordIndent)
715 : callPrintFunction(
"}\n");
718 Expr *buildWrapper() {
721 TheCall->
setType(Wrapper->getType());
742 diag::err_expected_struct_pointer_argument)
751 diag::err_incomplete_type))
760 switch (BT ? BT->getKind() : BuiltinType::Void) {
761 case BuiltinType::Dependent:
762 case BuiltinType::Overload:
763 case BuiltinType::BoundMember:
764 case BuiltinType::PseudoObject:
765 case BuiltinType::UnknownAny:
766 case BuiltinType::BuiltinFn:
772 diag::err_expected_callable_argument)
778 BuiltinDumpStructGenerator Generator(S, TheCall);
784 Expr *PtrArg = PtrArgResult.
get();
788 if (Generator.dumpUnnamedRecord(RD, PtrArg, 0))
791 return Generator.buildWrapper();
803 if (
Call->getStmtClass() != Stmt::CallExprClass) {
804 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_not_call)
805 <<
Call->getSourceRange();
810 if (CE->getCallee()->getType()->isBlockPointerType()) {
811 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_block_call)
812 <<
Call->getSourceRange();
816 const Decl *TargetDecl = CE->getCalleeDecl();
817 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl))
818 if (FD->getBuiltinID()) {
819 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_builtin_call)
820 <<
Call->getSourceRange();
825 S.
Diag(BuiltinLoc, diag::err_first_argument_to_cwsc_pdtor_call)
826 <<
Call->getSourceRange();
834 S.
Diag(BuiltinLoc, diag::err_second_argument_to_cwsc_not_pointer)
848 BuiltinCall->
setType(CE->getType());
852 BuiltinCall->
setArg(1, ChainResult.
get());
859class ScanfDiagnosticFormatHandler
863 using ComputeSizeFunction =
864 llvm::function_ref<std::optional<llvm::APSInt>(
unsigned)>;
868 using DiagnoseFunction =
869 llvm::function_ref<void(
unsigned,
unsigned,
unsigned)>;
871 ComputeSizeFunction ComputeSizeArgument;
872 DiagnoseFunction Diagnose;
875 ScanfDiagnosticFormatHandler(ComputeSizeFunction ComputeSizeArgument,
876 DiagnoseFunction Diagnose)
877 : ComputeSizeArgument(ComputeSizeArgument), Diagnose(Diagnose) {}
879 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
880 const char *StartSpecifier,
881 unsigned specifierLen)
override {
885 unsigned NulByte = 0;
897 analyze_format_string::OptionalAmount FW = FS.
getFieldWidth();
899 analyze_format_string::OptionalAmount::HowSpecified::Constant)
904 std::optional<llvm::APSInt> DestSizeAPS =
909 unsigned DestSize = DestSizeAPS->getZExtValue();
911 if (DestSize < SourceSize)
918class EstimateSizeFormatHandler
923 bool IsKernelCompatible =
true;
926 EstimateSizeFormatHandler(StringRef Format)
927 :
Size(std::
min(Format.find(0), Format.size()) +
930 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
931 const char *,
unsigned SpecifierLen,
932 const TargetInfo &)
override {
934 const size_t FieldWidth = computeFieldWidth(FS);
935 const size_t Precision = computePrecision(FS);
942 Size += std::max(FieldWidth, (
size_t)1);
954 Size += std::max(FieldWidth, Precision);
970 Size += std::max(FieldWidth, 1 +
971 (Precision ? 1 + Precision
981 (Precision ? 1 + Precision : 0) +
991 (Precision ? 1 + Precision : 0) +
1006 IsKernelCompatible =
false;
1007 Size += std::max(FieldWidth, 2 + Precision);
1054 Size += (Precision ? 0 : 1);
1061 assert(SpecifierLen <= Size &&
"no underflow");
1062 Size -= SpecifierLen;
1066 size_t getSizeLowerBound()
const {
return Size; }
1067 bool isKernelCompatible()
const {
return IsKernelCompatible; }
1070 static size_t computeFieldWidth(
const analyze_printf::PrintfSpecifier &FS) {
1071 const analyze_format_string::OptionalAmount &FW = FS.
getFieldWidth();
1072 size_t FieldWidth = 0;
1078 static size_t computePrecision(
const analyze_printf::PrintfSpecifier &FS) {
1079 const analyze_format_string::OptionalAmount &FW = FS.
getPrecision();
1080 size_t Precision = 0;
1127 StringRef &FormatStrRef,
size_t &StrLen,
1129 if (
const auto *Format = dyn_cast<StringLiteral>(FormatExpr);
1130 Format && (Format->isOrdinary() || Format->isUTF8())) {
1131 FormatStrRef = Format->getString();
1133 Context.getAsConstantArrayType(Format->getType());
1134 assert(
T &&
"String literal not of constant array type!");
1135 size_t TypeSize =
T->getZExtSize();
1137 StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, FormatStrRef.find(0));
1143void Sema::checkFortifiedBuiltinMemoryFunction(
FunctionDecl *FD,
1149 bool UseDABAttr =
false;
1150 const FunctionDecl *UseDecl = FD;
1152 const auto *DABAttr = FD->
getAttr<DiagnoseAsBuiltinAttr>();
1154 UseDecl = DABAttr->getFunction();
1155 assert(UseDecl &&
"Missing FunctionDecl in DiagnoseAsBuiltin attribute!");
1167 auto TranslateIndex = [&](
unsigned Index) -> std::optional<unsigned> {
1174 unsigned DABIndices = DABAttr->argIndices_size();
1175 unsigned NewIndex = Index < DABIndices
1176 ? DABAttr->argIndices_begin()[Index]
1179 return std::nullopt;
1183 auto ComputeExplicitObjectSizeArgument =
1184 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1185 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1187 return std::nullopt;
1188 unsigned NewIndex = *IndexOptional;
1190 Expr *SizeArg = TheCall->
getArg(NewIndex);
1192 return std::nullopt;
1198 auto ComputeSizeArgument =
1199 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1205 if (Index < FD->getNumParams()) {
1206 if (
const auto *POS =
1208 BOSType = POS->getType();
1211 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1213 return std::nullopt;
1214 unsigned NewIndex = *IndexOptional;
1217 return std::nullopt;
1219 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1222 return std::nullopt;
1225 return llvm::APSInt::getUnsigned(
Result).extOrTrunc(SizeTypeWidth);
1228 auto ComputeStrLenArgument =
1229 [&](
unsigned Index) -> std::optional<llvm::APSInt> {
1230 std::optional<unsigned> IndexOptional = TranslateIndex(Index);
1232 return std::nullopt;
1233 unsigned NewIndex = *IndexOptional;
1235 const Expr *ObjArg = TheCall->
getArg(NewIndex);
1238 return std::nullopt;
1240 return llvm::APSInt::getUnsigned(
Result + 1).extOrTrunc(SizeTypeWidth);
1243 std::optional<llvm::APSInt> SourceSize;
1244 std::optional<llvm::APSInt> DestinationSize;
1245 unsigned DiagID = 0;
1246 bool IsChkVariant =
false;
1248 auto GetFunctionName = [&]() {
1249 std::string FunctionNameStr =
1251 llvm::StringRef FunctionName = FunctionNameStr;
1256 FunctionName = FunctionName.drop_front(std::strlen(
"__builtin___"));
1257 FunctionName = FunctionName.drop_back(std::strlen(
"_chk"));
1259 FunctionName.consume_front(
"__builtin_");
1261 return FunctionName.str();
1264 switch (BuiltinID) {
1267 case Builtin::BI__builtin_strcat:
1268 case Builtin::BIstrcat:
1269 case Builtin::BI__builtin_stpcpy:
1270 case Builtin::BIstpcpy:
1271 case Builtin::BI__builtin_strcpy:
1272 case Builtin::BIstrcpy: {
1273 DiagID = diag::warn_fortify_strlen_overflow;
1274 SourceSize = ComputeStrLenArgument(1);
1275 DestinationSize = ComputeSizeArgument(0);
1279 case Builtin::BI__builtin___strcat_chk:
1280 case Builtin::BI__builtin___stpcpy_chk:
1281 case Builtin::BI__builtin___strcpy_chk: {
1282 DiagID = diag::warn_fortify_strlen_overflow;
1283 SourceSize = ComputeStrLenArgument(1);
1284 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1285 IsChkVariant =
true;
1289 case Builtin::BIscanf:
1290 case Builtin::BIfscanf:
1291 case Builtin::BIsscanf: {
1292 unsigned FormatIndex = 1;
1293 unsigned DataIndex = 2;
1294 if (BuiltinID == Builtin::BIscanf) {
1299 const auto *FormatExpr =
1302 StringRef FormatStrRef;
1307 auto Diagnose = [&](
unsigned ArgIndex,
unsigned DestSize,
1308 unsigned SourceSize) {
1309 DiagID = diag::warn_fortify_scanf_overflow;
1310 unsigned Index = ArgIndex + DataIndex;
1311 std::string FunctionName = GetFunctionName();
1313 PDiag(DiagID) << FunctionName << (Index + 1)
1314 << DestSize << SourceSize);
1317 auto ShiftedComputeSizeArgument = [&](
unsigned Index) {
1318 return ComputeSizeArgument(Index + DataIndex);
1320 ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument,
Diagnose);
1321 const char *FormatBytes = FormatStrRef.data();
1332 case Builtin::BIsprintf:
1333 case Builtin::BI__builtin___sprintf_chk: {
1334 size_t FormatIndex = BuiltinID == Builtin::BIsprintf ? 1 : 3;
1337 StringRef FormatStrRef;
1340 EstimateSizeFormatHandler H(FormatStrRef);
1341 const char *FormatBytes = FormatStrRef.data();
1343 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1344 Context.getTargetInfo(),
false)) {
1345 DiagID = H.isKernelCompatible()
1346 ? diag::warn_format_overflow
1347 : diag::warn_format_overflow_non_kprintf;
1348 SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1349 .extOrTrunc(SizeTypeWidth);
1350 if (BuiltinID == Builtin::BI__builtin___sprintf_chk) {
1351 DestinationSize = ComputeExplicitObjectSizeArgument(2);
1352 IsChkVariant =
true;
1354 DestinationSize = ComputeSizeArgument(0);
1361 case Builtin::BI__builtin___memcpy_chk:
1362 case Builtin::BI__builtin___memmove_chk:
1363 case Builtin::BI__builtin___memset_chk:
1364 case Builtin::BI__builtin___strlcat_chk:
1365 case Builtin::BI__builtin___strlcpy_chk:
1366 case Builtin::BI__builtin___strncat_chk:
1367 case Builtin::BI__builtin___strncpy_chk:
1368 case Builtin::BI__builtin___stpncpy_chk:
1369 case Builtin::BI__builtin___memccpy_chk:
1370 case Builtin::BI__builtin___mempcpy_chk: {
1371 DiagID = diag::warn_builtin_chk_overflow;
1372 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 2);
1374 ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1375 IsChkVariant =
true;
1379 case Builtin::BI__builtin___snprintf_chk:
1380 case Builtin::BI__builtin___vsnprintf_chk: {
1381 DiagID = diag::warn_builtin_chk_overflow;
1382 SourceSize = ComputeExplicitObjectSizeArgument(1);
1383 DestinationSize = ComputeExplicitObjectSizeArgument(3);
1384 IsChkVariant =
true;
1388 case Builtin::BIstrncat:
1389 case Builtin::BI__builtin_strncat:
1390 case Builtin::BIstrncpy:
1391 case Builtin::BI__builtin_strncpy:
1392 case Builtin::BIstpncpy:
1393 case Builtin::BI__builtin_stpncpy: {
1399 DiagID = diag::warn_fortify_source_size_mismatch;
1400 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1401 DestinationSize = ComputeSizeArgument(0);
1405 case Builtin::BImemcpy:
1406 case Builtin::BI__builtin_memcpy:
1407 case Builtin::BImemmove:
1408 case Builtin::BI__builtin_memmove:
1409 case Builtin::BImemset:
1410 case Builtin::BI__builtin_memset:
1411 case Builtin::BImempcpy:
1412 case Builtin::BI__builtin_mempcpy: {
1413 DiagID = diag::warn_fortify_source_overflow;
1414 SourceSize = ComputeExplicitObjectSizeArgument(TheCall->
getNumArgs() - 1);
1415 DestinationSize = ComputeSizeArgument(0);
1418 case Builtin::BIsnprintf:
1419 case Builtin::BI__builtin_snprintf:
1420 case Builtin::BIvsnprintf:
1421 case Builtin::BI__builtin_vsnprintf: {
1422 DiagID = diag::warn_fortify_source_size_mismatch;
1423 SourceSize = ComputeExplicitObjectSizeArgument(1);
1425 StringRef FormatStrRef;
1429 EstimateSizeFormatHandler H(FormatStrRef);
1430 const char *FormatBytes = FormatStrRef.data();
1432 H, FormatBytes, FormatBytes + StrLen,
getLangOpts(),
1433 Context.getTargetInfo(),
false)) {
1434 llvm::APSInt FormatSize =
1435 llvm::APSInt::getUnsigned(H.getSizeLowerBound())
1436 .extOrTrunc(SizeTypeWidth);
1437 if (FormatSize > *SourceSize && *SourceSize != 0) {
1438 unsigned TruncationDiagID =
1439 H.isKernelCompatible() ? diag::warn_format_truncation
1440 : diag::warn_format_truncation_non_kprintf;
1441 SmallString<16> SpecifiedSizeStr;
1442 SmallString<16> FormatSizeStr;
1443 SourceSize->toString(SpecifiedSizeStr, 10);
1444 FormatSize.toString(FormatSizeStr, 10);
1446 PDiag(TruncationDiagID)
1447 << GetFunctionName() << SpecifiedSizeStr
1452 DestinationSize = ComputeSizeArgument(0);
1456 if (!SourceSize || !DestinationSize ||
1457 llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0)
1460 std::string FunctionName = GetFunctionName();
1462 SmallString<16> DestinationStr;
1463 SmallString<16> SourceStr;
1464 DestinationSize->toString(DestinationStr, 10);
1465 SourceSize->toString(SourceStr, 10);
1468 << FunctionName << DestinationStr << SourceStr);
1483 if (!S || !(S->
getFlags() & NeededScopeFlags)) {
1486 << DRE->getDecl()->getIdentifier();
1498 "__builtin_alloca has invalid address space");
1511 if (Arg->isTypeDependent() || Arg->isValueDependent())
1514 QualType ArgTy = Arg->IgnoreParenImpCasts()->getType();
1516 return S.
Diag(Arg->getBeginLoc(), diag::err_param_with_void_type);
1524enum PointerAuthOpKind {
1539 Diag(Loc, diag::err_ptrauth_disabled) << Range;
1570 if (!
Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) {
1573 llvm::raw_svector_ostream Str(
Value);
1582 Result = KeyValue->getZExtValue();
1601 bool IsAddrDiscArg =
false;
1606 IsAddrDiscArg =
true;
1615 Diag(Arg->
getExprLoc(), diag::err_ptrauth_address_discrimination_invalid)
1616 <<
Result->getExtValue();
1618 Diag(Arg->
getExprLoc(), diag::err_ptrauth_extra_discriminator_invalid)
1624 IntVal =
Result->getZExtValue();
1628static std::pair<const ValueDecl *, CharUnits>
1635 const auto *BaseDecl =
1640 return {BaseDecl, Result.Val.getLValueOffset()};
1644 bool RequireConstant =
false) {
1652 auto AllowsPointer = [](PointerAuthOpKind OpKind) {
1653 return OpKind != PAO_BlendInteger;
1655 auto AllowsInteger = [](PointerAuthOpKind OpKind) {
1656 return OpKind == PAO_Discriminator || OpKind == PAO_BlendInteger ||
1657 OpKind == PAO_SignGeneric;
1666 }
else if (AllowsInteger(OpKind) &&
1673 <<
unsigned(OpKind == PAO_Discriminator ? 1
1674 : OpKind == PAO_BlendPointer ? 2
1675 : OpKind == PAO_BlendInteger ? 3
1677 <<
unsigned(AllowsInteger(OpKind) ? (AllowsPointer(OpKind) ? 2 : 1) : 0)
1687 if (!RequireConstant) {
1689 if ((OpKind == PAO_Sign || OpKind == PAO_Auth) &&
1692 ? diag::warn_ptrauth_sign_null_pointer
1693 : diag::warn_ptrauth_auth_null_pointer)
1703 if (OpKind == PAO_Sign) {
1721 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_pointer);
1726 assert(OpKind == PAO_Discriminator);
1732 if (
Call->getBuiltinCallee() ==
1733 Builtin::BI__builtin_ptrauth_blend_discriminator) {
1748 assert(
Pointer->getType()->isPointerType());
1760 assert(
Integer->getType()->isIntegerType());
1766 S.
Diag(Arg->
getExprLoc(), diag::err_ptrauth_bad_constant_discriminator);
1779 Call->setType(
Call->getArgs()[0]->getType());
1810 PointerAuthOpKind OpKind,
1811 bool RequireConstant) {
1822 Call->setType(
Call->getArgs()[0]->getType());
1838 Call->setType(
Call->getArgs()[0]->getType());
1847 const Expr *Arg =
Call->getArg(0)->IgnoreParenImpCasts();
1850 const auto *Literal = dyn_cast<StringLiteral>(Arg);
1851 if (!Literal || Literal->getCharByteWidth() != 1) {
1867 Call->setArg(0, FirstValue.
get());
1873 if (!FirstArgRecord) {
1874 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1875 << 0 << FirstArgType;
1880 diag::err_get_vtable_pointer_requires_complete_type)) {
1885 S.
Diag(FirstArg->
getBeginLoc(), diag::err_get_vtable_pointer_incorrect_type)
1886 << 1 << FirstArgRecord;
1890 Call->setType(ReturnType);
1915 auto DiagSelect = [&]() -> std::optional<unsigned> {
1922 return std::optional<unsigned>{};
1937 diag::err_incomplete_type))
1941 "Unhandled non-object pointer case");
1969 if (PT->getPointeeType()->isFunctionType()) {
1971 diag::err_builtin_is_within_lifetime_invalid_arg)
1977 if (PT->getPointeeType()->isVariableArrayType()) {
1979 << 1 <<
"__builtin_is_within_lifetime";
1984 diag::err_builtin_is_within_lifetime_invalid_arg)
1998 diag::err_builtin_trivially_relocate_invalid_arg_type)
2005 diag::err_incomplete_type))
2009 T->isIncompleteArrayType()) {
2011 diag::err_builtin_trivially_relocate_invalid_arg_type)
2012 << (
T.isConstQualified() ? 1 : 2);
2021 diag::err_builtin_trivially_relocate_invalid_arg_type)
2028 if (Size.isInvalid())
2032 if (Size.isInvalid())
2034 SizeExpr = Size.get();
2035 TheCall->
setArg(2, SizeExpr);
2045 llvm::Triple::ObjectFormatType CurObjFormat =
2047 if (llvm::is_contained(UnsupportedObjectFormatTypes, CurObjFormat)) {
2060 llvm::Triple::ArchType CurArch =
2062 if (llvm::is_contained(SupportedArchs, CurArch))
2072bool Sema::CheckTSBuiltinFunctionCall(
const TargetInfo &TI,
unsigned BuiltinID,
2079 case llvm::Triple::arm:
2080 case llvm::Triple::armeb:
2081 case llvm::Triple::thumb:
2082 case llvm::Triple::thumbeb:
2084 case llvm::Triple::aarch64:
2085 case llvm::Triple::aarch64_32:
2086 case llvm::Triple::aarch64_be:
2088 case llvm::Triple::bpfeb:
2089 case llvm::Triple::bpfel:
2091 case llvm::Triple::dxil:
2093 case llvm::Triple::hexagon:
2095 case llvm::Triple::mips:
2096 case llvm::Triple::mipsel:
2097 case llvm::Triple::mips64:
2098 case llvm::Triple::mips64el:
2100 case llvm::Triple::spirv:
2101 case llvm::Triple::spirv32:
2102 case llvm::Triple::spirv64:
2103 if (TI.
getTriple().getOS() != llvm::Triple::OSType::AMDHSA)
2106 case llvm::Triple::systemz:
2108 case llvm::Triple::x86:
2109 case llvm::Triple::x86_64:
2111 case llvm::Triple::ppc:
2112 case llvm::Triple::ppcle:
2113 case llvm::Triple::ppc64:
2114 case llvm::Triple::ppc64le:
2116 case llvm::Triple::amdgcn:
2118 case llvm::Triple::riscv32:
2119 case llvm::Triple::riscv64:
2121 case llvm::Triple::loongarch32:
2122 case llvm::Triple::loongarch64:
2125 case llvm::Triple::wasm32:
2126 case llvm::Triple::wasm64:
2128 case llvm::Triple::nvptx:
2129 case llvm::Triple::nvptx64:
2135 return T->isDependentType() ||
2136 (
T->isRealType() && !
T->isBooleanType() && !
T->isEnumeralType());
2148 EltTy = VecTy->getElementType();
2150 switch (ArgTyRestr) {
2153 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2154 << ArgOrdinal << 2 << 1 << 1
2160 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2161 << ArgOrdinal << 5 << 0
2167 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2168 << ArgOrdinal << 5 << 1
2174 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2188 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2189 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2190 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2191 "Expecting __builtin_cpu_...");
2193 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2195 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2196 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2197 (!IsCPUSupports && TInfo->supportsCpuIs()));
2199 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2206 ? diag::err_builtin_aix_os_unsupported
2207 : diag::err_builtin_target_unsupported)
2213 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2251 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2252 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8) {
2254 << ArgTy << BT->getNumBits();
2298 TheCall->
setArg(0, Arg0);
2315 TheCall->
setArg(1, Arg1);
2321 << 2 << 1 << 4 << 0 << Arg1Ty;
2330 unsigned Pos,
bool AllowConst,
2334 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2339 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2340 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2341 << Pos <<
"scalar pointer";
2350 diag::err_typecheck_convert_incompatible)
2359 bool TypeDependent =
false;
2360 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2388 Builtin::BI__builtin_masked_load))
2402 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2425 Builtin::BI__builtin_masked_store))
2433 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2443 diag::err_vec_builtin_incompatible_vector)
2472 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2485 << MaskTy << IdxTy);
2494 diag::err_vec_masked_load_store_ptr)
2523 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2539 << MaskTy << IdxTy);
2545 << MaskTy << ValTy);
2551 diag::err_vec_builtin_incompatible_vector)
2565 if (Args.size() == 0) {
2567 diag::err_typecheck_call_too_few_args_at_least)
2573 QualType FuncT = Args[0]->getType();
2576 if (Args.size() < 2) {
2578 diag::err_typecheck_call_too_few_args_at_least)
2584 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2585 QualType ObjectT = Args[1]->getType();
2587 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2636 tok::periodstar, ObjectArg.
get(), Args[0]);
2640 if (MPT->isMemberDataPointer())
2643 auto *MemCall =
new (S.
Context)
2666Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2671 unsigned ICEArguments = 0;
2673 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2678 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2680 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2685 if (ArgNo < TheCall->getNumArgs() &&
2688 ICEArguments &= ~(1 << ArgNo);
2692 switch (BuiltinID) {
2693 case Builtin::BI__builtin_cpu_supports:
2694 case Builtin::BI__builtin_cpu_is:
2696 Context.getAuxTargetInfo(), BuiltinID))
2699 case Builtin::BI__builtin_cpu_init:
2700 if (!
Context.getTargetInfo().supportsCpuInit()) {
2706 case Builtin::BI__builtin___CFStringMakeConstantString:
2710 *
this, BuiltinID, TheCall,
2711 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2714 "Wrong # arguments to builtin CFStringMakeConstantString");
2715 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2718 case Builtin::BI__builtin_ms_va_start:
2719 case Builtin::BI__builtin_stdarg_start:
2720 case Builtin::BI__builtin_va_start:
2721 case Builtin::BI__builtin_c23_va_start:
2722 if (BuiltinVAStart(BuiltinID, TheCall))
2725 case Builtin::BI__va_start: {
2726 switch (
Context.getTargetInfo().getTriple().getArch()) {
2727 case llvm::Triple::aarch64:
2728 case llvm::Triple::arm:
2729 case llvm::Triple::thumb:
2730 if (BuiltinVAStartARMMicrosoft(TheCall))
2734 if (BuiltinVAStart(BuiltinID, TheCall))
2742 case Builtin::BI_interlockedbittestandset_acq:
2743 case Builtin::BI_interlockedbittestandset_rel:
2744 case Builtin::BI_interlockedbittestandset_nf:
2745 case Builtin::BI_interlockedbittestandreset_acq:
2746 case Builtin::BI_interlockedbittestandreset_rel:
2747 case Builtin::BI_interlockedbittestandreset_nf:
2750 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2755 case Builtin::BI_bittest64:
2756 case Builtin::BI_bittestandcomplement64:
2757 case Builtin::BI_bittestandreset64:
2758 case Builtin::BI_bittestandset64:
2759 case Builtin::BI_interlockedbittestandreset64:
2760 case Builtin::BI_interlockedbittestandset64:
2763 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2764 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2769 case Builtin::BI_interlockedbittestandreset64_acq:
2770 case Builtin::BI_interlockedbittestandreset64_rel:
2771 case Builtin::BI_interlockedbittestandreset64_nf:
2772 case Builtin::BI_interlockedbittestandset64_acq:
2773 case Builtin::BI_interlockedbittestandset64_rel:
2774 case Builtin::BI_interlockedbittestandset64_nf:
2779 case Builtin::BI__builtin_set_flt_rounds:
2782 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2783 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2784 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2785 llvm::Triple::ppc64le}))
2789 case Builtin::BI__builtin_isgreater:
2790 case Builtin::BI__builtin_isgreaterequal:
2791 case Builtin::BI__builtin_isless:
2792 case Builtin::BI__builtin_islessequal:
2793 case Builtin::BI__builtin_islessgreater:
2794 case Builtin::BI__builtin_isunordered:
2795 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2798 case Builtin::BI__builtin_fpclassify:
2799 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2802 case Builtin::BI__builtin_isfpclass:
2803 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2806 case Builtin::BI__builtin_isfinite:
2807 case Builtin::BI__builtin_isinf:
2808 case Builtin::BI__builtin_isinf_sign:
2809 case Builtin::BI__builtin_isnan:
2810 case Builtin::BI__builtin_issignaling:
2811 case Builtin::BI__builtin_isnormal:
2812 case Builtin::BI__builtin_issubnormal:
2813 case Builtin::BI__builtin_iszero:
2814 case Builtin::BI__builtin_signbit:
2815 case Builtin::BI__builtin_signbitf:
2816 case Builtin::BI__builtin_signbitl:
2817 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2820 case Builtin::BI__builtin_shufflevector:
2824 case Builtin::BI__builtin_masked_load:
2825 case Builtin::BI__builtin_masked_expand_load:
2827 case Builtin::BI__builtin_masked_store:
2828 case Builtin::BI__builtin_masked_compress_store:
2830 case Builtin::BI__builtin_masked_gather:
2832 case Builtin::BI__builtin_masked_scatter:
2834 case Builtin::BI__builtin_invoke:
2836 case Builtin::BI__builtin_prefetch:
2837 if (BuiltinPrefetch(TheCall))
2840 case Builtin::BI__builtin_alloca_with_align:
2841 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2842 if (BuiltinAllocaWithAlign(TheCall))
2845 case Builtin::BI__builtin_alloca:
2846 case Builtin::BI__builtin_alloca_uninitialized:
2853 case Builtin::BI__builtin_infer_alloc_token:
2857 case Builtin::BI__arithmetic_fence:
2858 if (BuiltinArithmeticFence(TheCall))
2861 case Builtin::BI__assume:
2862 case Builtin::BI__builtin_assume:
2863 if (BuiltinAssume(TheCall))
2866 case Builtin::BI__builtin_assume_aligned:
2867 if (BuiltinAssumeAligned(TheCall))
2870 case Builtin::BI__builtin_dynamic_object_size:
2871 case Builtin::BI__builtin_object_size:
2875 case Builtin::BI__builtin_longjmp:
2876 if (BuiltinLongjmp(TheCall))
2879 case Builtin::BI__builtin_setjmp:
2880 if (BuiltinSetjmp(TheCall))
2883 case Builtin::BI__builtin_classify_type:
2888 case Builtin::BI__builtin_complex:
2889 if (BuiltinComplex(TheCall))
2892 case Builtin::BI__builtin_constant_p: {
2901 case Builtin::BI__builtin_launder:
2903 case Builtin::BI__builtin_is_within_lifetime:
2905 case Builtin::BI__builtin_trivially_relocate:
2908 case Builtin::BI__sync_fetch_and_add:
2909 case Builtin::BI__sync_fetch_and_add_1:
2910 case Builtin::BI__sync_fetch_and_add_2:
2911 case Builtin::BI__sync_fetch_and_add_4:
2912 case Builtin::BI__sync_fetch_and_add_8:
2913 case Builtin::BI__sync_fetch_and_add_16:
2914 case Builtin::BI__sync_fetch_and_sub:
2915 case Builtin::BI__sync_fetch_and_sub_1:
2916 case Builtin::BI__sync_fetch_and_sub_2:
2917 case Builtin::BI__sync_fetch_and_sub_4:
2918 case Builtin::BI__sync_fetch_and_sub_8:
2919 case Builtin::BI__sync_fetch_and_sub_16:
2920 case Builtin::BI__sync_fetch_and_or:
2921 case Builtin::BI__sync_fetch_and_or_1:
2922 case Builtin::BI__sync_fetch_and_or_2:
2923 case Builtin::BI__sync_fetch_and_or_4:
2924 case Builtin::BI__sync_fetch_and_or_8:
2925 case Builtin::BI__sync_fetch_and_or_16:
2926 case Builtin::BI__sync_fetch_and_and:
2927 case Builtin::BI__sync_fetch_and_and_1:
2928 case Builtin::BI__sync_fetch_and_and_2:
2929 case Builtin::BI__sync_fetch_and_and_4:
2930 case Builtin::BI__sync_fetch_and_and_8:
2931 case Builtin::BI__sync_fetch_and_and_16:
2932 case Builtin::BI__sync_fetch_and_xor:
2933 case Builtin::BI__sync_fetch_and_xor_1:
2934 case Builtin::BI__sync_fetch_and_xor_2:
2935 case Builtin::BI__sync_fetch_and_xor_4:
2936 case Builtin::BI__sync_fetch_and_xor_8:
2937 case Builtin::BI__sync_fetch_and_xor_16:
2938 case Builtin::BI__sync_fetch_and_nand:
2939 case Builtin::BI__sync_fetch_and_nand_1:
2940 case Builtin::BI__sync_fetch_and_nand_2:
2941 case Builtin::BI__sync_fetch_and_nand_4:
2942 case Builtin::BI__sync_fetch_and_nand_8:
2943 case Builtin::BI__sync_fetch_and_nand_16:
2944 case Builtin::BI__sync_add_and_fetch:
2945 case Builtin::BI__sync_add_and_fetch_1:
2946 case Builtin::BI__sync_add_and_fetch_2:
2947 case Builtin::BI__sync_add_and_fetch_4:
2948 case Builtin::BI__sync_add_and_fetch_8:
2949 case Builtin::BI__sync_add_and_fetch_16:
2950 case Builtin::BI__sync_sub_and_fetch:
2951 case Builtin::BI__sync_sub_and_fetch_1:
2952 case Builtin::BI__sync_sub_and_fetch_2:
2953 case Builtin::BI__sync_sub_and_fetch_4:
2954 case Builtin::BI__sync_sub_and_fetch_8:
2955 case Builtin::BI__sync_sub_and_fetch_16:
2956 case Builtin::BI__sync_and_and_fetch:
2957 case Builtin::BI__sync_and_and_fetch_1:
2958 case Builtin::BI__sync_and_and_fetch_2:
2959 case Builtin::BI__sync_and_and_fetch_4:
2960 case Builtin::BI__sync_and_and_fetch_8:
2961 case Builtin::BI__sync_and_and_fetch_16:
2962 case Builtin::BI__sync_or_and_fetch:
2963 case Builtin::BI__sync_or_and_fetch_1:
2964 case Builtin::BI__sync_or_and_fetch_2:
2965 case Builtin::BI__sync_or_and_fetch_4:
2966 case Builtin::BI__sync_or_and_fetch_8:
2967 case Builtin::BI__sync_or_and_fetch_16:
2968 case Builtin::BI__sync_xor_and_fetch:
2969 case Builtin::BI__sync_xor_and_fetch_1:
2970 case Builtin::BI__sync_xor_and_fetch_2:
2971 case Builtin::BI__sync_xor_and_fetch_4:
2972 case Builtin::BI__sync_xor_and_fetch_8:
2973 case Builtin::BI__sync_xor_and_fetch_16:
2974 case Builtin::BI__sync_nand_and_fetch:
2975 case Builtin::BI__sync_nand_and_fetch_1:
2976 case Builtin::BI__sync_nand_and_fetch_2:
2977 case Builtin::BI__sync_nand_and_fetch_4:
2978 case Builtin::BI__sync_nand_and_fetch_8:
2979 case Builtin::BI__sync_nand_and_fetch_16:
2980 case Builtin::BI__sync_val_compare_and_swap:
2981 case Builtin::BI__sync_val_compare_and_swap_1:
2982 case Builtin::BI__sync_val_compare_and_swap_2:
2983 case Builtin::BI__sync_val_compare_and_swap_4:
2984 case Builtin::BI__sync_val_compare_and_swap_8:
2985 case Builtin::BI__sync_val_compare_and_swap_16:
2986 case Builtin::BI__sync_bool_compare_and_swap:
2987 case Builtin::BI__sync_bool_compare_and_swap_1:
2988 case Builtin::BI__sync_bool_compare_and_swap_2:
2989 case Builtin::BI__sync_bool_compare_and_swap_4:
2990 case Builtin::BI__sync_bool_compare_and_swap_8:
2991 case Builtin::BI__sync_bool_compare_and_swap_16:
2992 case Builtin::BI__sync_lock_test_and_set:
2993 case Builtin::BI__sync_lock_test_and_set_1:
2994 case Builtin::BI__sync_lock_test_and_set_2:
2995 case Builtin::BI__sync_lock_test_and_set_4:
2996 case Builtin::BI__sync_lock_test_and_set_8:
2997 case Builtin::BI__sync_lock_test_and_set_16:
2998 case Builtin::BI__sync_lock_release:
2999 case Builtin::BI__sync_lock_release_1:
3000 case Builtin::BI__sync_lock_release_2:
3001 case Builtin::BI__sync_lock_release_4:
3002 case Builtin::BI__sync_lock_release_8:
3003 case Builtin::BI__sync_lock_release_16:
3004 case Builtin::BI__sync_swap:
3005 case Builtin::BI__sync_swap_1:
3006 case Builtin::BI__sync_swap_2:
3007 case Builtin::BI__sync_swap_4:
3008 case Builtin::BI__sync_swap_8:
3009 case Builtin::BI__sync_swap_16:
3010 return BuiltinAtomicOverloaded(TheCallResult);
3011 case Builtin::BI__sync_synchronize:
3015 case Builtin::BI__builtin_nontemporal_load:
3016 case Builtin::BI__builtin_nontemporal_store:
3017 return BuiltinNontemporalOverloaded(TheCallResult);
3018 case Builtin::BI__builtin_memcpy_inline: {
3019 clang::Expr *SizeOp = TheCall->
getArg(2);
3031 case Builtin::BI__builtin_memset_inline: {
3032 clang::Expr *SizeOp = TheCall->
getArg(2);
3042#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3043 case Builtin::BI##ID: \
3044 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3045#include "clang/Basic/Builtins.inc"
3046 case Builtin::BI__annotation:
3050 case Builtin::BI__builtin_annotation:
3054 case Builtin::BI__builtin_addressof:
3058 case Builtin::BI__builtin_function_start:
3062 case Builtin::BI__builtin_is_aligned:
3063 case Builtin::BI__builtin_align_up:
3064 case Builtin::BI__builtin_align_down:
3068 case Builtin::BI__builtin_add_overflow:
3069 case Builtin::BI__builtin_sub_overflow:
3070 case Builtin::BI__builtin_mul_overflow:
3074 case Builtin::BI__builtin_operator_new:
3075 case Builtin::BI__builtin_operator_delete: {
3076 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3078 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3081 case Builtin::BI__builtin_dump_struct:
3083 case Builtin::BI__builtin_expect_with_probability: {
3088 const Expr *ProbArg = TheCall->
getArg(2);
3089 SmallVector<PartialDiagnosticAt, 8> Notes;
3090 Expr::EvalResult Eval;
3094 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3101 bool LoseInfo =
false;
3102 Probability.convert(llvm::APFloat::IEEEdouble(),
3103 llvm::RoundingMode::Dynamic, &LoseInfo);
3104 if (!(Probability >= llvm::APFloat(0.0) &&
3105 Probability <= llvm::APFloat(1.0))) {
3112 case Builtin::BI__builtin_preserve_access_index:
3116 case Builtin::BI__builtin_call_with_static_chain:
3120 case Builtin::BI__exception_code:
3121 case Builtin::BI_exception_code:
3123 diag::err_seh___except_block))
3126 case Builtin::BI__exception_info:
3127 case Builtin::BI_exception_info:
3129 diag::err_seh___except_filter))
3132 case Builtin::BI__GetExceptionInfo:
3144 case Builtin::BIaddressof:
3145 case Builtin::BI__addressof:
3146 case Builtin::BIforward:
3147 case Builtin::BIforward_like:
3148 case Builtin::BImove:
3149 case Builtin::BImove_if_noexcept:
3150 case Builtin::BIas_const: {
3158 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3159 BuiltinID == Builtin::BI__addressof;
3161 (ReturnsPointer ?
Result->isAnyPointerType()
3162 :
Result->isReferenceType()) &&
3165 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3171 case Builtin::BI__builtin_ptrauth_strip:
3173 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3175 case Builtin::BI__builtin_ptrauth_sign_constant:
3178 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3181 case Builtin::BI__builtin_ptrauth_auth:
3184 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3186 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3188 case Builtin::BI__builtin_ptrauth_string_discriminator:
3191 case Builtin::BI__builtin_get_vtable_pointer:
3195 case Builtin::BIread_pipe:
3196 case Builtin::BIwrite_pipe:
3199 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3202 case Builtin::BIreserve_read_pipe:
3203 case Builtin::BIreserve_write_pipe:
3204 case Builtin::BIwork_group_reserve_read_pipe:
3205 case Builtin::BIwork_group_reserve_write_pipe:
3206 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3209 case Builtin::BIsub_group_reserve_read_pipe:
3210 case Builtin::BIsub_group_reserve_write_pipe:
3211 if (
OpenCL().checkSubgroupExt(TheCall) ||
3212 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3215 case Builtin::BIcommit_read_pipe:
3216 case Builtin::BIcommit_write_pipe:
3217 case Builtin::BIwork_group_commit_read_pipe:
3218 case Builtin::BIwork_group_commit_write_pipe:
3219 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3222 case Builtin::BIsub_group_commit_read_pipe:
3223 case Builtin::BIsub_group_commit_write_pipe:
3224 if (
OpenCL().checkSubgroupExt(TheCall) ||
3225 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3228 case Builtin::BIget_pipe_num_packets:
3229 case Builtin::BIget_pipe_max_packets:
3230 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3233 case Builtin::BIto_global:
3234 case Builtin::BIto_local:
3235 case Builtin::BIto_private:
3236 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3240 case Builtin::BIenqueue_kernel:
3241 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3244 case Builtin::BIget_kernel_work_group_size:
3245 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3246 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3249 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3250 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3251 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3254 case Builtin::BI__builtin_os_log_format:
3255 Cleanup.setExprNeedsCleanups(
true);
3257 case Builtin::BI__builtin_os_log_format_buffer_size:
3258 if (BuiltinOSLogFormat(TheCall))
3261 case Builtin::BI__builtin_frame_address:
3262 case Builtin::BI__builtin_return_address: {
3271 Result.Val.getInt() != 0)
3273 << ((BuiltinID == Builtin::BI__builtin_return_address)
3274 ?
"__builtin_return_address"
3275 :
"__builtin_frame_address")
3280 case Builtin::BI__builtin_nondeterministic_value: {
3281 if (BuiltinNonDeterministicValue(TheCall))
3288 case Builtin::BI__builtin_elementwise_abs:
3296 case Builtin::BI__builtin_elementwise_acos:
3297 case Builtin::BI__builtin_elementwise_asin:
3298 case Builtin::BI__builtin_elementwise_atan:
3299 case Builtin::BI__builtin_elementwise_ceil:
3300 case Builtin::BI__builtin_elementwise_cos:
3301 case Builtin::BI__builtin_elementwise_cosh:
3302 case Builtin::BI__builtin_elementwise_exp:
3303 case Builtin::BI__builtin_elementwise_exp2:
3304 case Builtin::BI__builtin_elementwise_exp10:
3305 case Builtin::BI__builtin_elementwise_floor:
3306 case Builtin::BI__builtin_elementwise_log:
3307 case Builtin::BI__builtin_elementwise_log2:
3308 case Builtin::BI__builtin_elementwise_log10:
3309 case Builtin::BI__builtin_elementwise_roundeven:
3310 case Builtin::BI__builtin_elementwise_round:
3311 case Builtin::BI__builtin_elementwise_rint:
3312 case Builtin::BI__builtin_elementwise_nearbyint:
3313 case Builtin::BI__builtin_elementwise_sin:
3314 case Builtin::BI__builtin_elementwise_sinh:
3315 case Builtin::BI__builtin_elementwise_sqrt:
3316 case Builtin::BI__builtin_elementwise_tan:
3317 case Builtin::BI__builtin_elementwise_tanh:
3318 case Builtin::BI__builtin_elementwise_trunc:
3319 case Builtin::BI__builtin_elementwise_canonicalize:
3324 case Builtin::BI__builtin_elementwise_fma:
3329 case Builtin::BI__builtin_elementwise_ldexp: {
3351 const auto *Vec0 = TyA->
getAs<VectorType>();
3352 const auto *Vec1 = TyExp->
getAs<VectorType>();
3353 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3355 if (Arg0Length != Arg1Length) {
3357 diag::err_typecheck_vector_lengths_not_equal)
3371 case Builtin::BI__builtin_elementwise_minnum:
3372 case Builtin::BI__builtin_elementwise_maxnum:
3373 case Builtin::BI__builtin_elementwise_minimum:
3374 case Builtin::BI__builtin_elementwise_maximum:
3375 case Builtin::BI__builtin_elementwise_minimumnum:
3376 case Builtin::BI__builtin_elementwise_maximumnum:
3377 case Builtin::BI__builtin_elementwise_atan2:
3378 case Builtin::BI__builtin_elementwise_fmod:
3379 case Builtin::BI__builtin_elementwise_pow:
3380 if (BuiltinElementwiseMath(TheCall,
3386 case Builtin::BI__builtin_elementwise_add_sat:
3387 case Builtin::BI__builtin_elementwise_sub_sat:
3388 if (BuiltinElementwiseMath(TheCall,
3392 case Builtin::BI__builtin_elementwise_fshl:
3393 case Builtin::BI__builtin_elementwise_fshr:
3398 case Builtin::BI__builtin_elementwise_min:
3399 case Builtin::BI__builtin_elementwise_max:
3400 if (BuiltinElementwiseMath(TheCall))
3403 case Builtin::BI__builtin_elementwise_popcount:
3404 case Builtin::BI__builtin_elementwise_bitreverse:
3409 case Builtin::BI__builtin_elementwise_copysign: {
3418 QualType MagnitudeTy = Magnitude.
get()->
getType();
3431 diag::err_typecheck_call_different_arg_types)
3432 << MagnitudeTy << SignTy;
3440 case Builtin::BI__builtin_elementwise_clzg:
3441 case Builtin::BI__builtin_elementwise_ctzg:
3449 }
else if (BuiltinElementwiseMath(
3453 case Builtin::BI__builtin_reduce_max:
3454 case Builtin::BI__builtin_reduce_min: {
3455 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3458 const Expr *Arg = TheCall->
getArg(0);
3463 ElTy = TyA->getElementType();
3467 if (ElTy.isNull()) {
3477 case Builtin::BI__builtin_reduce_maximum:
3478 case Builtin::BI__builtin_reduce_minimum: {
3479 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3482 const Expr *Arg = TheCall->
getArg(0);
3487 ElTy = TyA->getElementType();
3491 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3504 case Builtin::BI__builtin_reduce_add:
3505 case Builtin::BI__builtin_reduce_mul:
3506 case Builtin::BI__builtin_reduce_xor:
3507 case Builtin::BI__builtin_reduce_or:
3508 case Builtin::BI__builtin_reduce_and: {
3509 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3512 const Expr *Arg = TheCall->
getArg(0);
3517 ElTy = TyA->getElementType();
3521 if (ElTy.isNull() || !ElTy->isIntegerType()) {
3532 case Builtin::BI__builtin_matrix_transpose:
3533 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3535 case Builtin::BI__builtin_matrix_column_major_load:
3536 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3538 case Builtin::BI__builtin_matrix_column_major_store:
3539 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3541 case Builtin::BI__builtin_verbose_trap:
3546 case Builtin::BI__builtin_get_device_side_mangled_name: {
3547 auto Check = [](CallExpr *TheCall) {
3553 auto *D = DRE->getDecl();
3556 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3557 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3559 if (!Check(TheCall)) {
3561 diag::err_hip_invalid_args_builtin_mangled_name);
3566 case Builtin::BI__builtin_bswapg:
3570 case Builtin::BI__builtin_popcountg:
3574 case Builtin::BI__builtin_clzg:
3575 case Builtin::BI__builtin_ctzg:
3580 case Builtin::BI__builtin_allow_runtime_check: {
3581 Expr *Arg = TheCall->
getArg(0);
3590 case Builtin::BI__builtin_counted_by_ref:
3591 if (BuiltinCountedByRef(TheCall))
3601 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3602 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3603 assert(
Context.getAuxTargetInfo() &&
3604 "Aux Target Builtin, but not an aux target?");
3606 if (CheckTSBuiltinFunctionCall(
3608 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3611 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3617 return TheCallResult;
3632 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3636 diag::err_argument_not_contiguous_bit_field)
3643 bool IsVariadic =
false;
3646 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3647 IsVariadic = BD->isVariadic();
3648 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3649 IsVariadic = OMD->isVariadic();
3656 bool HasImplicitThisParam,
bool IsVariadic,
3660 else if (IsVariadic)
3670 if (HasImplicitThisParam) {
3702 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
3703 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3704 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3705 Expr = ILE->getInit(0);
3715 const Expr *ArgExpr,
3719 S.
PDiag(diag::warn_null_arg)
3725 if (
auto nullability =
type->getNullability())
3736 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3742 llvm::SmallBitVector NonNullArgs;
3748 for (
const auto *Arg : Args)
3755 unsigned IdxAST = Idx.getASTIndex();
3756 if (IdxAST >= Args.size())
3758 if (NonNullArgs.empty())
3759 NonNullArgs.resize(Args.size());
3760 NonNullArgs.set(IdxAST);
3769 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3774 unsigned ParamIndex = 0;
3776 I != E; ++I, ++ParamIndex) {
3779 if (NonNullArgs.empty())
3780 NonNullArgs.resize(Args.size());
3782 NonNullArgs.set(ParamIndex);
3789 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3794 type = blockType->getPointeeType();
3808 if (NonNullArgs.empty())
3809 NonNullArgs.resize(Args.size());
3811 NonNullArgs.set(Index);
3820 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3821 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3822 if (NonNullArgs[ArgIndex])
3828 StringRef ParamName,
QualType ArgTy,
3851 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
3852 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
3856 if (ArgAlign < ParamAlign)
3857 Diag(Loc, diag::warn_param_mismatched_alignment)
3859 << ParamName << (FDecl !=
nullptr) << FDecl;
3863 const Expr *ThisArg,
3865 if (!FD || Args.empty())
3867 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3868 if (Idx == LifetimeCaptureByAttr::Global ||
3869 Idx == LifetimeCaptureByAttr::Unknown)
3871 if (IsMemberFunction && Idx == 0)
3873 return Args[Idx - IsMemberFunction];
3875 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3880 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3881 for (
int CapturingParamIdx :
Attr->params()) {
3884 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
3887 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3895 I + IsMemberFunction);
3897 if (IsMemberFunction) {
3905 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3918 llvm::SmallBitVector CheckedVarArgs;
3920 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
3922 CheckedVarArgs.resize(Args.size());
3923 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
3928 CheckedVarArgs.resize(Args.size());
3929 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
3936 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3940 : isa_and_nonnull<FunctionDecl>(FDecl)
3942 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3946 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3948 if (
const Expr *Arg = Args[ArgIdx]) {
3949 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3956 if (FDecl || Proto) {
3961 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3962 CheckArgumentWithTypeTag(I, Args, Loc);
3968 if (!Proto && FDecl) {
3970 if (isa_and_nonnull<FunctionProtoType>(FT))
3976 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3978 bool IsScalableArg =
false;
3979 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3981 if (
const Expr *Arg = Args[ArgIdx]) {
3985 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
3993 IsScalableArg =
true;
3995 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4004 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4005 llvm::StringMap<bool> CallerFeatureMap;
4006 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4007 if (!CallerFeatureMap.contains(
"sme"))
4008 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4009 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4010 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4019 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4021 (IsScalableArg || IsScalableRet)) {
4022 bool IsCalleeStreaming =
4024 bool IsCalleeStreamingCompatible =
4028 if (!IsCalleeStreamingCompatible &&
4032 unsigned VL = LO.VScaleMin * 128;
4033 unsigned SVL = LO.VScaleStreamingMin * 128;
4034 bool IsVLMismatch = VL && SVL && VL != SVL;
4036 auto EmitDiag = [&](
bool IsArg) {
4040 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4041 << IsArg << IsCalleeStreaming << SVL << VL;
4044 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4045 << IsArg << SVL << VL;
4047 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4064 bool CallerHasZAState =
false;
4065 bool CallerHasZT0State =
false;
4067 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4069 CallerHasZAState =
true;
4071 CallerHasZT0State =
true;
4075 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4077 CallerHasZT0State |=
4079 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4085 Diag(Loc, diag::err_sme_za_call_no_za_state);
4088 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4092 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4093 Diag(Loc, diag::note_sme_use_preserves_za);
4098 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4099 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4100 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4101 if (!Arg->isValueDependent()) {
4103 if (Arg->EvaluateAsInt(Align,
Context)) {
4104 const llvm::APSInt &I = Align.
Val.
getInt();
4105 if (!I.isPowerOf2())
4106 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4107 << Arg->getSourceRange();
4110 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4136 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4137 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4139 checkCall(FDecl, Proto,
nullptr, Args,
true,
4148 IsMemberOperatorCall;
4154 Expr *ImplicitThis =
nullptr;
4159 ImplicitThis = Args[0];
4162 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4173 ThisType =
Context.getPointerType(ThisType);
4179 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4197 CheckAbsoluteValueFunction(TheCall, FDecl);
4198 CheckMaxUnsignedZero(TheCall, FDecl);
4199 CheckInfNaNFunction(TheCall, FDecl);
4210 case Builtin::BIstrlcpy:
4211 case Builtin::BIstrlcat:
4212 CheckStrlcpycatArguments(TheCall, FnInfo);
4214 case Builtin::BIstrncat:
4215 CheckStrncatArguments(TheCall, FnInfo);
4217 case Builtin::BIfree:
4218 CheckFreeArguments(TheCall);
4221 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4230 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4231 Ty =
V->getType().getNonReferenceType();
4232 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4233 Ty = F->getType().getNonReferenceType();
4270 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4273 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4275 case AtomicExpr::AO__c11_atomic_init:
4276 case AtomicExpr::AO__opencl_atomic_init:
4277 llvm_unreachable(
"There is no ordering argument for an init");
4279 case AtomicExpr::AO__c11_atomic_load:
4280 case AtomicExpr::AO__opencl_atomic_load:
4281 case AtomicExpr::AO__hip_atomic_load:
4282 case AtomicExpr::AO__atomic_load_n:
4283 case AtomicExpr::AO__atomic_load:
4284 case AtomicExpr::AO__scoped_atomic_load_n:
4285 case AtomicExpr::AO__scoped_atomic_load:
4286 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4287 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4289 case AtomicExpr::AO__c11_atomic_store:
4290 case AtomicExpr::AO__opencl_atomic_store:
4291 case AtomicExpr::AO__hip_atomic_store:
4292 case AtomicExpr::AO__atomic_store:
4293 case AtomicExpr::AO__atomic_store_n:
4294 case AtomicExpr::AO__scoped_atomic_store:
4295 case AtomicExpr::AO__scoped_atomic_store_n:
4296 case AtomicExpr::AO__atomic_clear:
4297 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4298 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4299 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4358 const unsigned NumForm = ClearByte + 1;
4359 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4360 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4368 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4369 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4370 "need to update code for modified forms");
4371 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4372 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4373 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4374 "need to update code for modified C11 atomics");
4375 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4376 Op <= AtomicExpr::AO__opencl_atomic_store;
4377 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4378 Op <= AtomicExpr::AO__hip_atomic_store;
4379 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4380 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4381 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4382 Op <= AtomicExpr::AO__c11_atomic_store) ||
4384 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4385 Op == AtomicExpr::AO__atomic_store_n ||
4386 Op == AtomicExpr::AO__atomic_exchange_n ||
4387 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4388 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4389 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4390 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4391 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4395 enum ArithOpExtraValueType {
4400 unsigned ArithAllows = AOEVT_None;
4403 case AtomicExpr::AO__c11_atomic_init:
4404 case AtomicExpr::AO__opencl_atomic_init:
4408 case AtomicExpr::AO__c11_atomic_load:
4409 case AtomicExpr::AO__opencl_atomic_load:
4410 case AtomicExpr::AO__hip_atomic_load:
4411 case AtomicExpr::AO__atomic_load_n:
4412 case AtomicExpr::AO__scoped_atomic_load_n:
4416 case AtomicExpr::AO__atomic_load:
4417 case AtomicExpr::AO__scoped_atomic_load:
4421 case AtomicExpr::AO__c11_atomic_store:
4422 case AtomicExpr::AO__opencl_atomic_store:
4423 case AtomicExpr::AO__hip_atomic_store:
4424 case AtomicExpr::AO__atomic_store:
4425 case AtomicExpr::AO__atomic_store_n:
4426 case AtomicExpr::AO__scoped_atomic_store:
4427 case AtomicExpr::AO__scoped_atomic_store_n:
4430 case AtomicExpr::AO__atomic_fetch_add:
4431 case AtomicExpr::AO__atomic_fetch_sub:
4432 case AtomicExpr::AO__atomic_add_fetch:
4433 case AtomicExpr::AO__atomic_sub_fetch:
4434 case AtomicExpr::AO__scoped_atomic_fetch_add:
4435 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4436 case AtomicExpr::AO__scoped_atomic_add_fetch:
4437 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4438 case AtomicExpr::AO__c11_atomic_fetch_add:
4439 case AtomicExpr::AO__c11_atomic_fetch_sub:
4440 case AtomicExpr::AO__opencl_atomic_fetch_add:
4441 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4442 case AtomicExpr::AO__hip_atomic_fetch_add:
4443 case AtomicExpr::AO__hip_atomic_fetch_sub:
4444 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4447 case AtomicExpr::AO__atomic_fetch_max:
4448 case AtomicExpr::AO__atomic_fetch_min:
4449 case AtomicExpr::AO__atomic_max_fetch:
4450 case AtomicExpr::AO__atomic_min_fetch:
4451 case AtomicExpr::AO__scoped_atomic_fetch_max:
4452 case AtomicExpr::AO__scoped_atomic_fetch_min:
4453 case AtomicExpr::AO__scoped_atomic_max_fetch:
4454 case AtomicExpr::AO__scoped_atomic_min_fetch:
4455 case AtomicExpr::AO__c11_atomic_fetch_max:
4456 case AtomicExpr::AO__c11_atomic_fetch_min:
4457 case AtomicExpr::AO__opencl_atomic_fetch_max:
4458 case AtomicExpr::AO__opencl_atomic_fetch_min:
4459 case AtomicExpr::AO__hip_atomic_fetch_max:
4460 case AtomicExpr::AO__hip_atomic_fetch_min:
4461 ArithAllows = AOEVT_FP;
4464 case AtomicExpr::AO__c11_atomic_fetch_and:
4465 case AtomicExpr::AO__c11_atomic_fetch_or:
4466 case AtomicExpr::AO__c11_atomic_fetch_xor:
4467 case AtomicExpr::AO__hip_atomic_fetch_and:
4468 case AtomicExpr::AO__hip_atomic_fetch_or:
4469 case AtomicExpr::AO__hip_atomic_fetch_xor:
4470 case AtomicExpr::AO__c11_atomic_fetch_nand:
4471 case AtomicExpr::AO__opencl_atomic_fetch_and:
4472 case AtomicExpr::AO__opencl_atomic_fetch_or:
4473 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4474 case AtomicExpr::AO__atomic_fetch_and:
4475 case AtomicExpr::AO__atomic_fetch_or:
4476 case AtomicExpr::AO__atomic_fetch_xor:
4477 case AtomicExpr::AO__atomic_fetch_nand:
4478 case AtomicExpr::AO__atomic_and_fetch:
4479 case AtomicExpr::AO__atomic_or_fetch:
4480 case AtomicExpr::AO__atomic_xor_fetch:
4481 case AtomicExpr::AO__atomic_nand_fetch:
4482 case AtomicExpr::AO__scoped_atomic_fetch_and:
4483 case AtomicExpr::AO__scoped_atomic_fetch_or:
4484 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4485 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4486 case AtomicExpr::AO__scoped_atomic_and_fetch:
4487 case AtomicExpr::AO__scoped_atomic_or_fetch:
4488 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4489 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4490 case AtomicExpr::AO__scoped_atomic_uinc_wrap:
4491 case AtomicExpr::AO__scoped_atomic_udec_wrap:
4495 case AtomicExpr::AO__c11_atomic_exchange:
4496 case AtomicExpr::AO__hip_atomic_exchange:
4497 case AtomicExpr::AO__opencl_atomic_exchange:
4498 case AtomicExpr::AO__atomic_exchange_n:
4499 case AtomicExpr::AO__scoped_atomic_exchange_n:
4503 case AtomicExpr::AO__atomic_exchange:
4504 case AtomicExpr::AO__scoped_atomic_exchange:
4508 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4509 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4510 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4511 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4512 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4513 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4517 case AtomicExpr::AO__atomic_compare_exchange:
4518 case AtomicExpr::AO__atomic_compare_exchange_n:
4519 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4520 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4524 case AtomicExpr::AO__atomic_test_and_set:
4525 Form = TestAndSetByte;
4528 case AtomicExpr::AO__atomic_clear:
4533 unsigned AdjustedNumArgs = NumArgs[Form];
4534 if ((IsOpenCL || IsHIP || IsScoped) &&
4535 Op != AtomicExpr::AO__opencl_atomic_init)
4538 if (Args.size() < AdjustedNumArgs) {
4539 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4540 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4543 }
else if (Args.size() > AdjustedNumArgs) {
4544 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4545 diag::err_typecheck_call_too_many_args)
4546 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4552 Expr *Ptr = Args[0];
4557 Ptr = ConvertedPtr.
get();
4560 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4570 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4576 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4582 }
else if (Form != Load && Form != LoadCopy) {
4584 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4590 if (Form != TestAndSetByte && Form != ClearByte) {
4593 diag::err_incomplete_type))
4596 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4597 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4607 pointerType->getPointeeType().getCVRQualifiers());
4617 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4626 auto IsAllowedValueType = [&](
QualType ValType,
4627 unsigned AllowedType) ->
bool {
4631 return AllowedType & AOEVT_Pointer;
4636 &
Context.getTargetInfo().getLongDoubleFormat() ==
4637 &llvm::APFloat::x87DoubleExtended())
4641 if (!IsAllowedValueType(ValType, ArithAllows)) {
4642 auto DID = ArithAllows & AOEVT_FP
4643 ? (ArithAllows & AOEVT_Pointer
4644 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4645 : diag::err_atomic_op_needs_atomic_int_or_fp)
4646 : diag::err_atomic_op_needs_atomic_int;
4653 diag::err_incomplete_type)) {
4659 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4670 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4686 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4698 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4701 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4707 bool IsPassedByAddress =
false;
4708 if (!IsC11 && !IsHIP && !IsN) {
4710 IsPassedByAddress =
true;
4715 APIOrderedArgs.push_back(Args[0]);
4719 APIOrderedArgs.push_back(Args[1]);
4725 APIOrderedArgs.push_back(Args[2]);
4726 APIOrderedArgs.push_back(Args[1]);
4729 APIOrderedArgs.push_back(Args[2]);
4730 APIOrderedArgs.push_back(Args[3]);
4731 APIOrderedArgs.push_back(Args[1]);
4734 APIOrderedArgs.push_back(Args[2]);
4735 APIOrderedArgs.push_back(Args[4]);
4736 APIOrderedArgs.push_back(Args[1]);
4737 APIOrderedArgs.push_back(Args[3]);
4740 APIOrderedArgs.push_back(Args[2]);
4741 APIOrderedArgs.push_back(Args[4]);
4742 APIOrderedArgs.push_back(Args[5]);
4743 APIOrderedArgs.push_back(Args[1]);
4744 APIOrderedArgs.push_back(Args[3]);
4746 case TestAndSetByte:
4748 APIOrderedArgs.push_back(Args[1]);
4752 APIOrderedArgs.append(Args.begin(), Args.end());
4759 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4761 if (i < NumVals[Form] + 1) {
4774 assert(Form != Load);
4776 Ty =
Context.getPointerDiffType();
4779 else if (Form ==
Copy || Form == Xchg) {
4780 if (IsPassedByAddress) {
4787 Expr *ValArg = APIOrderedArgs[i];
4794 AS = PtrTy->getPointeeType().getAddressSpace();
4803 if (IsPassedByAddress)
4823 APIOrderedArgs[i] = Arg.
get();
4828 SubExprs.push_back(Ptr);
4832 SubExprs.push_back(APIOrderedArgs[1]);
4835 case TestAndSetByte:
4837 SubExprs.push_back(APIOrderedArgs[1]);
4843 SubExprs.push_back(APIOrderedArgs[2]);
4844 SubExprs.push_back(APIOrderedArgs[1]);
4848 SubExprs.push_back(APIOrderedArgs[3]);
4849 SubExprs.push_back(APIOrderedArgs[1]);
4850 SubExprs.push_back(APIOrderedArgs[2]);
4853 SubExprs.push_back(APIOrderedArgs[3]);
4854 SubExprs.push_back(APIOrderedArgs[1]);
4855 SubExprs.push_back(APIOrderedArgs[4]);
4856 SubExprs.push_back(APIOrderedArgs[2]);
4859 SubExprs.push_back(APIOrderedArgs[4]);
4860 SubExprs.push_back(APIOrderedArgs[1]);
4861 SubExprs.push_back(APIOrderedArgs[5]);
4862 SubExprs.push_back(APIOrderedArgs[2]);
4863 SubExprs.push_back(APIOrderedArgs[3]);
4868 if (SubExprs.size() >= 2 && Form !=
Init) {
4869 std::optional<llvm::APSInt>
Success =
4870 SubExprs[1]->getIntegerConstantExpr(
Context);
4872 Diag(SubExprs[1]->getBeginLoc(),
4873 diag::warn_atomic_op_has_invalid_memory_order)
4874 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4875 << SubExprs[1]->getSourceRange();
4877 if (SubExprs.size() >= 5) {
4878 if (std::optional<llvm::APSInt> Failure =
4879 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4880 if (!llvm::is_contained(
4881 {llvm::AtomicOrderingCABI::relaxed,
4882 llvm::AtomicOrderingCABI::consume,
4883 llvm::AtomicOrderingCABI::acquire,
4884 llvm::AtomicOrderingCABI::seq_cst},
4885 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4886 Diag(SubExprs[3]->getBeginLoc(),
4887 diag::warn_atomic_op_has_invalid_memory_order)
4888 << 2 << SubExprs[3]->getSourceRange();
4895 auto *
Scope = Args[Args.size() - 1];
4896 if (std::optional<llvm::APSInt>
Result =
4898 if (!ScopeModel->isValid(
Result->getZExtValue()))
4899 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
4900 <<
Scope->getSourceRange();
4902 SubExprs.push_back(
Scope);
4908 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4909 Op == AtomicExpr::AO__c11_atomic_store ||
4910 Op == AtomicExpr::AO__opencl_atomic_load ||
4911 Op == AtomicExpr::AO__hip_atomic_load ||
4912 Op == AtomicExpr::AO__opencl_atomic_store ||
4913 Op == AtomicExpr::AO__hip_atomic_store) &&
4914 Context.AtomicUsesUnsupportedLibcall(AE))
4916 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4917 Op == AtomicExpr::AO__opencl_atomic_load ||
4918 Op == AtomicExpr::AO__hip_atomic_load)
4923 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4939 assert(Fn &&
"builtin call without direct callee!");
4955 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
4962 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4964 <<
Callee->getSourceRange();
4973 Expr *FirstArg = TheCall->
getArg(0);
4977 FirstArg = FirstArgResult.
get();
4978 TheCall->
setArg(0, FirstArg);
4990 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4997 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5027 QualType ResultType = ValType;
5032#define BUILTIN_ROW(x) \
5033 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5034 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5036 static const unsigned BuiltinIndices[][5] = {
5061 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5062 case 1: SizeIndex = 0;
break;
5063 case 2: SizeIndex = 1;
break;
5064 case 4: SizeIndex = 2;
break;
5065 case 8: SizeIndex = 3;
break;
5066 case 16: SizeIndex = 4;
break;
5078 unsigned BuiltinIndex, NumFixed = 1;
5079 bool WarnAboutSemanticsChange =
false;
5080 switch (BuiltinID) {
5081 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5082 case Builtin::BI__sync_fetch_and_add:
5083 case Builtin::BI__sync_fetch_and_add_1:
5084 case Builtin::BI__sync_fetch_and_add_2:
5085 case Builtin::BI__sync_fetch_and_add_4:
5086 case Builtin::BI__sync_fetch_and_add_8:
5087 case Builtin::BI__sync_fetch_and_add_16:
5091 case Builtin::BI__sync_fetch_and_sub:
5092 case Builtin::BI__sync_fetch_and_sub_1:
5093 case Builtin::BI__sync_fetch_and_sub_2:
5094 case Builtin::BI__sync_fetch_and_sub_4:
5095 case Builtin::BI__sync_fetch_and_sub_8:
5096 case Builtin::BI__sync_fetch_and_sub_16:
5100 case Builtin::BI__sync_fetch_and_or:
5101 case Builtin::BI__sync_fetch_and_or_1:
5102 case Builtin::BI__sync_fetch_and_or_2:
5103 case Builtin::BI__sync_fetch_and_or_4:
5104 case Builtin::BI__sync_fetch_and_or_8:
5105 case Builtin::BI__sync_fetch_and_or_16:
5109 case Builtin::BI__sync_fetch_and_and:
5110 case Builtin::BI__sync_fetch_and_and_1:
5111 case Builtin::BI__sync_fetch_and_and_2:
5112 case Builtin::BI__sync_fetch_and_and_4:
5113 case Builtin::BI__sync_fetch_and_and_8:
5114 case Builtin::BI__sync_fetch_and_and_16:
5118 case Builtin::BI__sync_fetch_and_xor:
5119 case Builtin::BI__sync_fetch_and_xor_1:
5120 case Builtin::BI__sync_fetch_and_xor_2:
5121 case Builtin::BI__sync_fetch_and_xor_4:
5122 case Builtin::BI__sync_fetch_and_xor_8:
5123 case Builtin::BI__sync_fetch_and_xor_16:
5127 case Builtin::BI__sync_fetch_and_nand:
5128 case Builtin::BI__sync_fetch_and_nand_1:
5129 case Builtin::BI__sync_fetch_and_nand_2:
5130 case Builtin::BI__sync_fetch_and_nand_4:
5131 case Builtin::BI__sync_fetch_and_nand_8:
5132 case Builtin::BI__sync_fetch_and_nand_16:
5134 WarnAboutSemanticsChange =
true;
5137 case Builtin::BI__sync_add_and_fetch:
5138 case Builtin::BI__sync_add_and_fetch_1:
5139 case Builtin::BI__sync_add_and_fetch_2:
5140 case Builtin::BI__sync_add_and_fetch_4:
5141 case Builtin::BI__sync_add_and_fetch_8:
5142 case Builtin::BI__sync_add_and_fetch_16:
5146 case Builtin::BI__sync_sub_and_fetch:
5147 case Builtin::BI__sync_sub_and_fetch_1:
5148 case Builtin::BI__sync_sub_and_fetch_2:
5149 case Builtin::BI__sync_sub_and_fetch_4:
5150 case Builtin::BI__sync_sub_and_fetch_8:
5151 case Builtin::BI__sync_sub_and_fetch_16:
5155 case Builtin::BI__sync_and_and_fetch:
5156 case Builtin::BI__sync_and_and_fetch_1:
5157 case Builtin::BI__sync_and_and_fetch_2:
5158 case Builtin::BI__sync_and_and_fetch_4:
5159 case Builtin::BI__sync_and_and_fetch_8:
5160 case Builtin::BI__sync_and_and_fetch_16:
5164 case Builtin::BI__sync_or_and_fetch:
5165 case Builtin::BI__sync_or_and_fetch_1:
5166 case Builtin::BI__sync_or_and_fetch_2:
5167 case Builtin::BI__sync_or_and_fetch_4:
5168 case Builtin::BI__sync_or_and_fetch_8:
5169 case Builtin::BI__sync_or_and_fetch_16:
5173 case Builtin::BI__sync_xor_and_fetch:
5174 case Builtin::BI__sync_xor_and_fetch_1:
5175 case Builtin::BI__sync_xor_and_fetch_2:
5176 case Builtin::BI__sync_xor_and_fetch_4:
5177 case Builtin::BI__sync_xor_and_fetch_8:
5178 case Builtin::BI__sync_xor_and_fetch_16:
5182 case Builtin::BI__sync_nand_and_fetch:
5183 case Builtin::BI__sync_nand_and_fetch_1:
5184 case Builtin::BI__sync_nand_and_fetch_2:
5185 case Builtin::BI__sync_nand_and_fetch_4:
5186 case Builtin::BI__sync_nand_and_fetch_8:
5187 case Builtin::BI__sync_nand_and_fetch_16:
5189 WarnAboutSemanticsChange =
true;
5192 case Builtin::BI__sync_val_compare_and_swap:
5193 case Builtin::BI__sync_val_compare_and_swap_1:
5194 case Builtin::BI__sync_val_compare_and_swap_2:
5195 case Builtin::BI__sync_val_compare_and_swap_4:
5196 case Builtin::BI__sync_val_compare_and_swap_8:
5197 case Builtin::BI__sync_val_compare_and_swap_16:
5202 case Builtin::BI__sync_bool_compare_and_swap:
5203 case Builtin::BI__sync_bool_compare_and_swap_1:
5204 case Builtin::BI__sync_bool_compare_and_swap_2:
5205 case Builtin::BI__sync_bool_compare_and_swap_4:
5206 case Builtin::BI__sync_bool_compare_and_swap_8:
5207 case Builtin::BI__sync_bool_compare_and_swap_16:
5213 case Builtin::BI__sync_lock_test_and_set:
5214 case Builtin::BI__sync_lock_test_and_set_1:
5215 case Builtin::BI__sync_lock_test_and_set_2:
5216 case Builtin::BI__sync_lock_test_and_set_4:
5217 case Builtin::BI__sync_lock_test_and_set_8:
5218 case Builtin::BI__sync_lock_test_and_set_16:
5222 case Builtin::BI__sync_lock_release:
5223 case Builtin::BI__sync_lock_release_1:
5224 case Builtin::BI__sync_lock_release_2:
5225 case Builtin::BI__sync_lock_release_4:
5226 case Builtin::BI__sync_lock_release_8:
5227 case Builtin::BI__sync_lock_release_16:
5233 case Builtin::BI__sync_swap:
5234 case Builtin::BI__sync_swap_1:
5235 case Builtin::BI__sync_swap_2:
5236 case Builtin::BI__sync_swap_4:
5237 case Builtin::BI__sync_swap_8:
5238 case Builtin::BI__sync_swap_16:
5246 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5247 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5248 <<
Callee->getSourceRange();
5252 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5253 <<
Callee->getSourceRange();
5255 if (WarnAboutSemanticsChange) {
5256 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5257 <<
Callee->getSourceRange();
5262 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5263 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5264 FunctionDecl *NewBuiltinDecl;
5265 if (NewBuiltinID == BuiltinID)
5266 NewBuiltinDecl = FDecl;
5269 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5272 assert(Res.getFoundDecl());
5273 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5274 if (!NewBuiltinDecl)
5281 for (
unsigned i = 0; i != NumFixed; ++i) {
5310 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5312 CK_BuiltinFnToFnPtr);
5323 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5324 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5325 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5329 return TheCallResult;
5333 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5338 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5339 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5340 "Unexpected nontemporal load/store builtin!");
5341 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5342 unsigned numArgs = isStore ? 2 : 1;
5352 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5358 PointerArg = PointerArgResult.
get();
5359 TheCall->
setArg(numArgs - 1, PointerArg);
5363 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5376 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5383 return TheCallResult;
5395 return TheCallResult;
5402 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5404 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5405 Literal = ObjcLiteral->getString();
5409 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5416 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5417 InitializedEntity Entity =
5427 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5428 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5429 TT.getArch() == llvm::Triple::aarch64_32);
5430 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5431 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5432 if (IsX64 || IsAArch64) {
5439 return S.
Diag(Fn->getBeginLoc(),
5440 diag::err_ms_va_start_used_in_sysv_function);
5447 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5448 return S.
Diag(Fn->getBeginLoc(),
5449 diag::err_va_start_used_in_wrong_abi_function)
5450 << !IsWindowsOrUEFI;
5456 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5464 bool IsVariadic =
false;
5467 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5468 IsVariadic =
Block->isVariadic();
5469 Params =
Block->parameters();
5470 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5473 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5474 IsVariadic = MD->isVariadic();
5476 Params = MD->parameters();
5479 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5483 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5488 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5493 *LastParam = Params.empty() ?
nullptr : Params.back();
5498bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5503 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5527 ParmVarDecl *LastParam;
5538 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5540 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5545 if (std::optional<llvm::APSInt> Val =
5547 Val &&
LangOpts.C23 && *Val == 0 &&
5548 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5549 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5556 SourceLocation ParamLoc;
5557 bool IsCRegister =
false;
5558 bool SecondArgIsLastNonVariadicArgument =
false;
5559 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5560 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5561 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5564 ParamLoc = PV->getLocation();
5570 if (!SecondArgIsLastNonVariadicArgument)
5572 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5573 else if (IsCRegister ||
Type->isReferenceType() ||
5574 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5577 if (!Context.isPromotableIntegerType(Type))
5579 const auto *ED = Type->getAsEnumDecl();
5582 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5584 unsigned Reason = 0;
5585 if (
Type->isReferenceType()) Reason = 1;
5586 else if (IsCRegister) Reason = 2;
5587 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5588 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5595 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5615 if (
Call->getNumArgs() < 3)
5617 diag::err_typecheck_call_too_few_args_at_least)
5618 << 0 << 3 <<
Call->getNumArgs()
5631 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5634 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5637 const QualType &ConstCharPtrTy =
5639 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5641 << Arg1->
getType() << ConstCharPtrTy << 1
5644 << 2 << Arg1->
getType() << ConstCharPtrTy;
5646 const QualType SizeTy =
Context.getSizeType();
5651 << Arg2->
getType() << SizeTy << 1
5654 << 3 << Arg2->
getType() << SizeTy;
5659bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5663 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5691 diag::err_typecheck_call_invalid_ordered_compare)
5699bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5700 unsigned BuiltinID) {
5705 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5706 BuiltinID == Builtin::BI__builtin_isinf ||
5707 BuiltinID == Builtin::BI__builtin_isinf_sign))
5711 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5712 BuiltinID == Builtin::BI__builtin_isunordered))
5716 bool IsFPClass = NumArgs == 2;
5719 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5723 for (
unsigned i = 0; i < FPArgNo; ++i) {
5724 Expr *Arg = TheCall->
getArg(i);
5737 Expr *OrigArg = TheCall->
getArg(FPArgNo);
5745 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
5750 OrigArg = Res.
get();
5756 OrigArg = Res.
get();
5758 TheCall->
setArg(FPArgNo, OrigArg);
5760 QualType VectorResultTy;
5761 QualType ElementTy = OrigArg->
getType();
5766 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
5772 diag::err_typecheck_call_invalid_unary_fp)
5784 if (!VectorResultTy.
isNull())
5785 ResultTy = VectorResultTy;
5794bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5799 for (
unsigned I = 0; I != 2; ++I) {
5800 Expr *Arg = TheCall->
getArg(I);
5810 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5825 Expr *Real = TheCall->
getArg(0);
5826 Expr *Imag = TheCall->
getArg(1);
5829 diag::err_typecheck_call_different_arg_types)
5844 diag::err_typecheck_call_too_few_args_at_least)
5845 << 0 << 2 << NumArgs
5852 unsigned NumElements = 0;
5867 unsigned NumResElements = NumArgs - 2;
5876 diag::err_vec_builtin_incompatible_vector)
5881 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
5883 diag::err_vec_builtin_incompatible_vector)
5888 }
else if (NumElements != NumResElements) {
5891 ?
Context.getExtVectorType(EltType, NumResElements)
5892 :
Context.getVectorType(EltType, NumResElements,
5897 for (
unsigned I = 2; I != NumArgs; ++I) {
5905 diag::err_shufflevector_nonconstant_argument)
5911 else if (
Result->getActiveBits() > 64 ||
5912 Result->getZExtValue() >= NumElements * 2)
5914 diag::err_shufflevector_argument_too_large)
5939 diag::err_convertvector_non_vector)
5942 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5944 <<
"__builtin_convertvector");
5949 if (SrcElts != DstElts)
5951 diag::err_convertvector_incompatible_vector)
5959bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5964 diag::err_typecheck_call_too_many_args_at_most)
5965 << 0 << 3 << NumArgs << 0
5970 for (
unsigned i = 1; i != NumArgs; ++i)
5977bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5978 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
5979 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5989 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5999bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6000 Expr *Arg = TheCall->
getArg(0);
6011bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6013 Expr *Arg = TheCall->
getArg(1);
6017 if (
const auto *UE =
6019 if (UE->getKind() == UETT_AlignOf ||
6020 UE->getKind() == UETT_PreferredAlignOf)
6026 if (!
Result.isPowerOf2())
6027 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6034 if (
Result > std::numeric_limits<int32_t>::max())
6042bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6047 Expr *FirstArg = TheCall->
getArg(0);
6053 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6057 TheCall->
setArg(0, FirstArgResult.
get());
6061 Expr *SecondArg = TheCall->
getArg(1);
6069 if (!
Result.isPowerOf2())
6070 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6082 Expr *ThirdArg = TheCall->
getArg(2);
6085 TheCall->
setArg(2, ThirdArg);
6091bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6092 unsigned BuiltinID =
6094 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6097 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6098 if (NumArgs < NumRequiredArgs) {
6099 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6100 << 0 << NumRequiredArgs << NumArgs
6103 if (NumArgs >= NumRequiredArgs + 0x100) {
6105 diag::err_typecheck_call_too_many_args_at_most)
6106 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6117 if (Arg.isInvalid())
6119 TheCall->
setArg(i, Arg.get());
6124 unsigned FormatIdx = i;
6134 unsigned FirstDataArg = i;
6135 while (i < NumArgs) {
6153 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6155 bool Success = CheckFormatArguments(
6158 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6182 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6191 int High,
bool RangeIsError) {
6205 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6213 PDiag(diag::warn_argument_invalid_range)
6256 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6261 if (
Value.isNegative())
6272 if ((
Value & 0xFF) != 0)
6297 Result.setIsUnsigned(
true);
6302 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6322 Result.setIsUnsigned(
true);
6330 diag::err_argument_not_shifted_byte_or_xxff)
6334bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6335 if (!Context.getTargetInfo().hasSjLjLowering())
6336 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6347 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6353bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6354 if (!Context.getTargetInfo().hasSjLjLowering())
6355 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6360bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6375 diag::err_builtin_counted_by_ref_invalid_arg)
6380 diag::err_builtin_counted_by_ref_has_side_effects)
6383 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6385 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6390 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6397 QualType MemberTy = ME->getMemberDecl()->getType();
6400 diag::err_builtin_counted_by_ref_invalid_arg)
6404 diag::err_builtin_counted_by_ref_invalid_arg)
6414bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6416 const CallExpr *CE =
6425 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6430 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6435 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6439 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6443 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6453class UncoveredArgHandler {
6454 enum {
Unknown = -1, AllCovered = -2 };
6456 signed FirstUncoveredArg =
Unknown;
6457 SmallVector<const Expr *, 4> DiagnosticExprs;
6460 UncoveredArgHandler() =
default;
6462 bool hasUncoveredArg()
const {
6463 return (FirstUncoveredArg >= 0);
6466 unsigned getUncoveredArg()
const {
6467 assert(hasUncoveredArg() &&
"no uncovered argument");
6468 return FirstUncoveredArg;
6471 void setAllCovered() {
6474 DiagnosticExprs.clear();
6475 FirstUncoveredArg = AllCovered;
6478 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6479 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6482 if (FirstUncoveredArg == AllCovered)
6487 if (NewFirstUncoveredArg == FirstUncoveredArg)
6488 DiagnosticExprs.push_back(StrExpr);
6489 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6490 DiagnosticExprs.clear();
6491 DiagnosticExprs.push_back(StrExpr);
6492 FirstUncoveredArg = NewFirstUncoveredArg;
6496 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6499enum StringLiteralCheckType {
6501 SLCT_UncheckedLiteral,
6509 bool AddendIsRight) {
6510 unsigned BitWidth = Offset.getBitWidth();
6511 unsigned AddendBitWidth = Addend.getBitWidth();
6513 if (Addend.isUnsigned()) {
6514 Addend = Addend.zext(++AddendBitWidth);
6515 Addend.setIsSigned(
true);
6518 if (AddendBitWidth > BitWidth) {
6519 Offset = Offset.sext(AddendBitWidth);
6520 BitWidth = AddendBitWidth;
6521 }
else if (BitWidth > AddendBitWidth) {
6522 Addend = Addend.sext(BitWidth);
6526 llvm::APSInt ResOffset = Offset;
6527 if (BinOpKind == BO_Add)
6528 ResOffset = Offset.sadd_ov(Addend, Ov);
6530 assert(AddendIsRight && BinOpKind == BO_Sub &&
6531 "operator must be add or sub with addend on the right");
6532 ResOffset = Offset.ssub_ov(Addend, Ov);
6538 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6539 "index (intermediate) result too big");
6540 Offset = Offset.sext(2 * BitWidth);
6541 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6553class FormatStringLiteral {
6554 const StringLiteral *FExpr;
6558 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6559 : FExpr(fexpr), Offset(Offset) {}
6561 const StringLiteral *getFormatString()
const {
return FExpr; }
6563 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6565 unsigned getByteLength()
const {
6566 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6569 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6576 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6577 bool isWide()
const {
return FExpr->
isWide(); }
6578 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6579 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6580 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6581 bool isPascal()
const {
return FExpr->
isPascal(); }
6583 SourceLocation getLocationOfByte(
6584 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6585 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6586 unsigned *StartTokenByteOffset =
nullptr)
const {
6588 StartToken, StartTokenByteOffset);
6591 SourceLocation getBeginLoc() const LLVM_READONLY {
6595 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6601 Sema &S,
const FormatStringLiteral *FExpr,
6606 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6607 bool IgnoreStringsWithoutSpecifiers);
6616static StringLiteralCheckType
6622 llvm::SmallBitVector &CheckedVarArgs,
6623 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
6624 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
6625 bool IgnoreStringsWithoutSpecifiers =
false) {
6627 return SLCT_NotALiteral;
6629 assert(Offset.isSigned() &&
"invalid offset");
6632 return SLCT_NotALiteral;
6641 return SLCT_UncheckedLiteral;
6644 case Stmt::InitListExprClass:
6648 format_idx, firstDataArg,
Type, CallType,
6649 false, CheckedVarArgs,
6650 UncoveredArg, Offset, CallerFormatParamIdx,
6651 IgnoreStringsWithoutSpecifiers);
6653 return SLCT_NotALiteral;
6654 case Stmt::BinaryConditionalOperatorClass:
6655 case Stmt::ConditionalOperatorClass: {
6664 bool CheckLeft =
true, CheckRight =
true;
6667 if (
C->getCond()->EvaluateAsBooleanCondition(
6679 StringLiteralCheckType Left;
6681 Left = SLCT_UncheckedLiteral;
6684 Args, APK, format_idx, firstDataArg,
Type,
6685 CallType, InFunctionCall, CheckedVarArgs,
6686 UncoveredArg, Offset, CallerFormatParamIdx,
6687 IgnoreStringsWithoutSpecifiers);
6688 if (Left == SLCT_NotALiteral || !CheckRight) {
6694 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6695 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6696 UncoveredArg, Offset, CallerFormatParamIdx,
6697 IgnoreStringsWithoutSpecifiers);
6699 return (CheckLeft && Left < Right) ? Left : Right;
6702 case Stmt::ImplicitCastExprClass:
6706 case Stmt::OpaqueValueExprClass:
6711 return SLCT_NotALiteral;
6713 case Stmt::PredefinedExprClass:
6717 return SLCT_UncheckedLiteral;
6719 case Stmt::DeclRefExprClass: {
6725 bool isConstant =
false;
6729 isConstant = AT->getElementType().isConstant(S.
Context);
6731 isConstant =
T.isConstant(S.
Context) &&
6732 PT->getPointeeType().isConstant(S.
Context);
6733 }
else if (
T->isObjCObjectPointerType()) {
6736 isConstant =
T.isConstant(S.
Context);
6740 if (
const Expr *
Init = VD->getAnyInitializer()) {
6743 if (InitList->isStringLiteralInit())
6744 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6747 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6748 firstDataArg,
Type, CallType,
false,
6749 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
6800 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6801 if (CallerFormatParamIdx)
6802 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
6803 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
6804 for (
const auto *PVFormatMatches :
6805 D->specific_attrs<FormatMatchesAttr>()) {
6810 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6814 S.
Diag(Args[format_idx]->getBeginLoc(),
6815 diag::warn_format_string_type_incompatible)
6816 << PVFormatMatches->getType()->getName()
6818 if (!InFunctionCall) {
6819 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6820 diag::note_format_string_defined);
6822 return SLCT_UncheckedLiteral;
6825 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6826 Args, APK, format_idx, firstDataArg,
Type, CallType,
6827 false, CheckedVarArgs, UncoveredArg,
6828 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6832 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
6835 PVFormat->getFirstArg(), &CallerFSI))
6837 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6841 S.
Diag(Args[format_idx]->getBeginLoc(),
6842 diag::warn_format_string_type_incompatible)
6843 << PVFormat->getType()->getName()
6845 if (!InFunctionCall) {
6848 return SLCT_UncheckedLiteral;
6861 return SLCT_UncheckedLiteral;
6869 return SLCT_NotALiteral;
6872 case Stmt::CallExprClass:
6873 case Stmt::CXXMemberCallExprClass: {
6877 StringLiteralCheckType CommonResult;
6878 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6879 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6881 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6882 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6883 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6885 CommonResult = Result;
6890 return CommonResult;
6892 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6894 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6895 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6898 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6899 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6900 UncoveredArg, Offset, CallerFormatParamIdx,
6901 IgnoreStringsWithoutSpecifiers);
6907 format_idx, firstDataArg,
Type, CallType,
6908 false, CheckedVarArgs,
6909 UncoveredArg, Offset, CallerFormatParamIdx,
6910 IgnoreStringsWithoutSpecifiers);
6911 return SLCT_NotALiteral;
6913 case Stmt::ObjCMessageExprClass: {
6915 if (
const auto *MD = ME->getMethodDecl()) {
6916 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6925 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6927 MD->getSelector().isKeywordSelector(
6928 {
"localizedStringForKey",
"value",
"table"})) {
6929 IgnoreStringsWithoutSpecifiers =
true;
6932 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6934 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6935 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6936 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6940 return SLCT_NotALiteral;
6942 case Stmt::ObjCStringLiteralClass:
6943 case Stmt::StringLiteralClass: {
6952 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6955 return SLCT_NotALiteral;
6957 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6959 format_idx, firstDataArg,
Type, InFunctionCall,
6960 CallType, CheckedVarArgs, UncoveredArg,
6961 IgnoreStringsWithoutSpecifiers);
6962 return SLCT_CheckedLiteral;
6965 return SLCT_NotALiteral;
6967 case Stmt::BinaryOperatorClass: {
6981 if (LIsInt != RIsInt) {
6985 if (BinOpKind == BO_Add) {
6998 return SLCT_NotALiteral;
7000 case Stmt::UnaryOperatorClass: {
7002 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7003 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7005 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7015 return SLCT_NotALiteral;
7019 return SLCT_NotALiteral;
7030 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7031 if (isa_and_nonnull<StringLiteral>(LVE))
7052 return "freebsd_kprintf";
7061 return llvm::StringSwitch<FormatStringType>(Flavor)
7063 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7068 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7084bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7088 llvm::SmallBitVector &CheckedVarArgs) {
7089 FormatStringInfo FSI;
7093 return CheckFormatArguments(
7094 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7099bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7103 llvm::SmallBitVector &CheckedVarArgs) {
7104 FormatStringInfo FSI;
7108 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7109 Format->getFormatString(), FSI.FormatIdx,
7111 CallType, Loc, Range, CheckedVarArgs);
7119 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7132 unsigned CallerArgumentIndexOffset =
7135 unsigned FirstArgumentIndex = -1;
7145 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7146 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7150 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7151 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7153 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7156 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7157 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7160 FirstArgumentIndex =
7161 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7167 ? (NumCallerParams + CallerArgumentIndexOffset)
7172 if (!ReferenceFormatString)
7178 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7180 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7182 std::string
Attr, Fixit;
7183 llvm::raw_string_ostream AttrOS(
Attr);
7185 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7186 << FirstArgumentIndex <<
")";
7188 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7190 AttrOS.write_escaped(ReferenceFormatString->
getString());
7194 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7205 llvm::raw_string_ostream IS(Fixit);
7213 if (LO.C23 || LO.CPlusPlus11)
7214 IS <<
"[[gnu::" <<
Attr <<
"]]";
7215 else if (LO.ObjC || LO.GNUMode)
7216 IS <<
"__attribute__((" <<
Attr <<
"))";
7230 Caller->
addAttr(FormatAttr::CreateImplicit(
7232 FormatStringIndex, FirstArgumentIndex));
7234 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7236 FormatStringIndex, ReferenceFormatString));
7240 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7252 unsigned format_idx,
unsigned firstDataArg,
7256 llvm::SmallBitVector &CheckedVarArgs) {
7258 if (format_idx >= Args.size()) {
7259 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7263 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7277 UncoveredArgHandler UncoveredArg;
7278 std::optional<unsigned> CallerParamIdx;
7280 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7281 firstDataArg,
Type, CallType,
7282 true, CheckedVarArgs, UncoveredArg,
7283 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7286 if (UncoveredArg.hasUncoveredArg()) {
7287 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7288 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7289 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7292 if (CT != SLCT_NotALiteral)
7294 return CT == SLCT_CheckedLiteral;
7300 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7306 this, Args, APK, ReferenceFormatString, format_idx,
7307 firstDataArg,
Type, *CallerParamIdx, Loc))
7317 if (Args.size() == firstDataArg) {
7318 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7326 Diag(FormatLoc, diag::note_format_security_fixit)
7330 Diag(FormatLoc, diag::note_format_security_fixit)
7335 Diag(FormatLoc, diag::warn_format_nonliteral)
7346 const FormatStringLiteral *FExpr;
7347 const Expr *OrigFormatExpr;
7349 const unsigned FirstDataArg;
7350 const unsigned NumDataArgs;
7353 ArrayRef<const Expr *> Args;
7355 llvm::SmallBitVector CoveredArgs;
7356 bool usesPositionalArgs =
false;
7357 bool atFirstArg =
true;
7358 bool inFunctionCall;
7360 llvm::SmallBitVector &CheckedVarArgs;
7361 UncoveredArgHandler &UncoveredArg;
7364 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7366 unsigned firstDataArg,
unsigned numDataArgs,
7368 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7370 llvm::SmallBitVector &CheckedVarArgs,
7371 UncoveredArgHandler &UncoveredArg)
7372 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7373 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7374 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7375 inFunctionCall(inFunctionCall), CallType(callType),
7376 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7377 CoveredArgs.resize(numDataArgs);
7378 CoveredArgs.reset();
7381 bool HasFormatArguments()
const {
7386 void DoneProcessing();
7388 void HandleIncompleteSpecifier(
const char *startSpecifier,
7389 unsigned specifierLen)
override;
7391 void HandleInvalidLengthModifier(
7392 const analyze_format_string::FormatSpecifier &FS,
7393 const analyze_format_string::ConversionSpecifier &CS,
7394 const char *startSpecifier,
unsigned specifierLen,
7397 void HandleNonStandardLengthModifier(
7398 const analyze_format_string::FormatSpecifier &FS,
7399 const char *startSpecifier,
unsigned specifierLen);
7401 void HandleNonStandardConversionSpecifier(
7402 const analyze_format_string::ConversionSpecifier &CS,
7403 const char *startSpecifier,
unsigned specifierLen);
7405 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7407 void HandleInvalidPosition(
const char *startSpecifier,
7408 unsigned specifierLen,
7411 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7413 void HandleNullChar(
const char *nullCharacter)
override;
7415 template <
typename Range>
7417 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7418 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7419 bool IsStringLocation, Range StringRange,
7420 ArrayRef<FixItHint> Fixit = {});
7423 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7424 const char *startSpec,
7425 unsigned specifierLen,
7426 const char *csStart,
unsigned csLen);
7428 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7429 const char *startSpec,
7430 unsigned specifierLen);
7432 SourceRange getFormatStringRange();
7433 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7434 unsigned specifierLen);
7435 SourceLocation getLocationOfByte(
const char *x);
7437 const Expr *getDataArg(
unsigned i)
const;
7439 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7440 const analyze_format_string::ConversionSpecifier &CS,
7441 const char *startSpecifier,
unsigned specifierLen,
7444 template <
typename Range>
7445 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7446 bool IsStringLocation, Range StringRange,
7447 ArrayRef<FixItHint> Fixit = {});
7452SourceRange CheckFormatHandler::getFormatStringRange() {
7457getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7459 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7467SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7472void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7473 unsigned specifierLen){
7474 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7475 getLocationOfByte(startSpecifier),
7477 getSpecifierRange(startSpecifier, specifierLen));
7480void CheckFormatHandler::HandleInvalidLengthModifier(
7483 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7495 getSpecifierRange(startSpecifier, specifierLen));
7497 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7498 << FixedLM->toString()
7503 if (DiagID == diag::warn_format_nonsensical_length)
7509 getSpecifierRange(startSpecifier, specifierLen),
7514void CheckFormatHandler::HandleNonStandardLengthModifier(
7516 const char *startSpecifier,
unsigned specifierLen) {
7525 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7529 getSpecifierRange(startSpecifier, specifierLen));
7531 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7532 << FixedLM->toString()
7536 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7540 getSpecifierRange(startSpecifier, specifierLen));
7544void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7546 const char *startSpecifier,
unsigned specifierLen) {
7552 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7556 getSpecifierRange(startSpecifier, specifierLen));
7559 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7560 << FixedCS->toString()
7563 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7567 getSpecifierRange(startSpecifier, specifierLen));
7571void CheckFormatHandler::HandlePosition(
const char *startPos,
7574 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7575 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7576 getLocationOfByte(startPos),
7578 getSpecifierRange(startPos, posLen));
7581void CheckFormatHandler::HandleInvalidPosition(
7582 const char *startSpecifier,
unsigned specifierLen,
7585 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7586 EmitFormatDiagnostic(
7587 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7588 getLocationOfByte(startSpecifier),
true,
7589 getSpecifierRange(startSpecifier, specifierLen));
7592void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7596 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7597 getLocationOfByte(startPos),
7599 getSpecifierRange(startPos, posLen));
7602void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7605 EmitFormatDiagnostic(
7606 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7607 getLocationOfByte(nullCharacter),
true,
7608 getFormatStringRange());
7614const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7615 return Args[FirstDataArg + i];
7618void CheckFormatHandler::DoneProcessing() {
7621 if (HasFormatArguments()) {
7624 signed notCoveredArg = CoveredArgs.find_first();
7625 if (notCoveredArg >= 0) {
7626 assert((
unsigned)notCoveredArg < NumDataArgs);
7627 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7629 UncoveredArg.setAllCovered();
7634void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7635 const Expr *ArgExpr) {
7636 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7648 for (
auto E : DiagnosticExprs)
7651 CheckFormatHandler::EmitFormatDiagnostic(
7652 S, IsFunctionCall, DiagnosticExprs[0],
7658CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7660 const char *startSpec,
7661 unsigned specifierLen,
7662 const char *csStart,
7664 bool keepGoing =
true;
7665 if (argIndex < NumDataArgs) {
7668 CoveredArgs.set(argIndex);
7684 std::string CodePointStr;
7685 if (!llvm::sys::locale::isPrint(*csStart)) {
7686 llvm::UTF32 CodePoint;
7687 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7688 const llvm::UTF8 *E =
7689 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7690 llvm::ConversionResult
Result =
7691 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7693 if (
Result != llvm::conversionOK) {
7694 unsigned char FirstChar = *csStart;
7695 CodePoint = (llvm::UTF32)FirstChar;
7698 llvm::raw_string_ostream
OS(CodePointStr);
7699 if (CodePoint < 256)
7700 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7701 else if (CodePoint <= 0xFFFF)
7702 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7704 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7708 EmitFormatDiagnostic(
7709 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7710 true, getSpecifierRange(startSpec, specifierLen));
7716CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7717 const char *startSpec,
7718 unsigned specifierLen) {
7719 EmitFormatDiagnostic(
7720 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7721 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7725CheckFormatHandler::CheckNumArgs(
7728 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7730 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7732 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7733 << (argIndex+1) << NumDataArgs)
7734 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7735 EmitFormatDiagnostic(
7736 PDiag, getLocationOfByte(CS.
getStart()),
true,
7737 getSpecifierRange(startSpecifier, specifierLen));
7741 UncoveredArg.setAllCovered();
7747template<
typename Range>
7750 bool IsStringLocation,
7753 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7754 Loc, IsStringLocation, StringRange, FixIt);
7784template <
typename Range>
7785void CheckFormatHandler::EmitFormatDiagnostic(
7786 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7789 if (InFunctionCall) {
7794 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
7798 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
7799 diag::note_format_string_defined);
7801 Note << StringRange;
7810class CheckPrintfHandler :
public CheckFormatHandler {
7812 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7814 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7816 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7818 llvm::SmallBitVector &CheckedVarArgs,
7819 UncoveredArgHandler &UncoveredArg)
7820 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7821 numDataArgs, beg, APK, Args, formatIdx,
7822 inFunctionCall, CallType, CheckedVarArgs,
7825 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7828 bool allowsObjCArg()
const {
7829 return FSType == FormatStringType::NSString ||
7830 FSType == FormatStringType::OSLog ||
7831 FSType == FormatStringType::OSTrace;
7834 bool HandleInvalidPrintfConversionSpecifier(
7835 const analyze_printf::PrintfSpecifier &FS,
7836 const char *startSpecifier,
7837 unsigned specifierLen)
override;
7839 void handleInvalidMaskType(StringRef MaskType)
override;
7841 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7842 const char *startSpecifier,
unsigned specifierLen,
7843 const TargetInfo &
Target)
override;
7844 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
7845 const char *StartSpecifier,
7846 unsigned SpecifierLen,
7849 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
7850 const char *startSpecifier,
unsigned specifierLen);
7851 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
7852 const analyze_printf::OptionalAmount &Amt,
7854 const char *startSpecifier,
unsigned specifierLen);
7855 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
7856 const analyze_printf::OptionalFlag &flag,
7857 const char *startSpecifier,
unsigned specifierLen);
7858 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
7859 const analyze_printf::OptionalFlag &ignoredFlag,
7860 const analyze_printf::OptionalFlag &flag,
7861 const char *startSpecifier,
unsigned specifierLen);
7862 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7865 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7866 unsigned flagLen)
override;
7868 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7869 unsigned flagLen)
override;
7872 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7873 const char *flagsEnd,
7874 const char *conversionPosition)
override;
7879class EquatableFormatArgument {
7881 enum SpecifierSensitivity :
unsigned {
7888 enum FormatArgumentRole :
unsigned {
7896 analyze_format_string::ArgType ArgType;
7898 StringRef SpecifierLetter;
7899 CharSourceRange
Range;
7900 SourceLocation ElementLoc;
7901 FormatArgumentRole
Role : 2;
7902 SpecifierSensitivity Sensitivity : 2;
7903 unsigned Position : 14;
7904 unsigned ModifierFor : 14;
7906 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
7907 bool InFunctionCall)
const;
7910 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
7912 StringRef SpecifierLetter,
7913 analyze_format_string::ArgType ArgType,
7914 FormatArgumentRole
Role,
7915 SpecifierSensitivity Sensitivity,
unsigned Position,
7916 unsigned ModifierFor)
7917 : ArgType(ArgType), LengthMod(LengthMod),
7918 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7919 Role(
Role), Sensitivity(Sensitivity), Position(Position),
7920 ModifierFor(ModifierFor) {}
7922 unsigned getPosition()
const {
return Position; }
7923 SourceLocation getSourceLocation()
const {
return ElementLoc; }
7925 analyze_format_string::LengthModifier getLengthModifier()
const {
7926 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
7928 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7930 std::string buildFormatSpecifier()
const {
7932 llvm::raw_string_ostream(result)
7933 << getLengthModifier().toString() << SpecifierLetter;
7937 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
7938 const Expr *FmtExpr,
bool InFunctionCall)
const;
7942class DecomposePrintfHandler :
public CheckPrintfHandler {
7943 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
7946 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7947 const Expr *origFormatExpr,
7949 unsigned numDataArgs,
bool isObjC,
const char *beg,
7951 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7953 llvm::SmallBitVector &CheckedVarArgs,
7954 UncoveredArgHandler &UncoveredArg,
7955 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
7956 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7957 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7958 inFunctionCall, CallType, CheckedVarArgs,
7960 Specs(Specs), HadError(
false) {}
7964 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7966 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
7968 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7969 const char *startSpecifier,
7970 unsigned specifierLen,
7971 const TargetInfo &
Target)
override;
7976bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7978 unsigned specifierLen) {
7982 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
7984 startSpecifier, specifierLen,
7988void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7989 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7997 return T->isRecordType() ||
T->isComplexType();
8000bool CheckPrintfHandler::HandleAmount(
8002 const char *startSpecifier,
unsigned specifierLen) {
8004 if (HasFormatArguments()) {
8006 if (argIndex >= NumDataArgs) {
8007 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8011 getSpecifierRange(startSpecifier, specifierLen));
8021 CoveredArgs.set(argIndex);
8022 const Expr *Arg = getDataArg(argIndex);
8033 ? diag::err_printf_asterisk_wrong_type
8034 : diag::warn_printf_asterisk_wrong_type;
8035 EmitFormatDiagnostic(S.
PDiag(DiagID)
8040 getSpecifierRange(startSpecifier, specifierLen));
8050void CheckPrintfHandler::HandleInvalidAmount(
8054 const char *startSpecifier,
8055 unsigned specifierLen) {
8065 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8069 getSpecifierRange(startSpecifier, specifierLen),
8075 const char *startSpecifier,
8076 unsigned specifierLen) {
8080 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
8084 getSpecifierRange(startSpecifier, specifierLen),
8089void CheckPrintfHandler::HandleIgnoredFlag(
8093 const char *startSpecifier,
8094 unsigned specifierLen) {
8096 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8100 getSpecifierRange(startSpecifier, specifierLen),
8102 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8105void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8108 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
8109 getLocationOfByte(startFlag),
8111 getSpecifierRange(startFlag, flagLen));
8114void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8117 auto Range = getSpecifierRange(startFlag, flagLen);
8118 StringRef flag(startFlag, flagLen);
8119 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8120 getLocationOfByte(startFlag),
8125void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8126 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
8128 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8129 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8130 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8131 getLocationOfByte(conversionPosition),
8137 const Expr *FmtExpr,
8138 bool InFunctionCall)
const {
8139 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8140 ElementLoc,
true, Range);
8143bool EquatableFormatArgument::VerifyCompatible(
8144 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8145 bool InFunctionCall)
const {
8150 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8151 FmtExpr, InFunctionCall);
8152 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8156 if (
Role != FAR_Data) {
8157 if (ModifierFor !=
Other.ModifierFor) {
8160 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8161 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8162 FmtExpr, InFunctionCall);
8163 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8169 bool HadError =
false;
8170 if (Sensitivity !=
Other.Sensitivity) {
8173 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8174 << Sensitivity <<
Other.Sensitivity,
8175 FmtExpr, InFunctionCall);
8176 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8177 << 0 <<
Other.Range;
8180 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8184 case MK::MatchPromotion:
8188 case MK::NoMatchTypeConfusion:
8189 case MK::NoMatchPromotionTypeConfusion:
8191 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8192 << buildFormatSpecifier()
8193 <<
Other.buildFormatSpecifier(),
8194 FmtExpr, InFunctionCall);
8195 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8196 << 0 <<
Other.Range;
8199 case MK::NoMatchPedantic:
8201 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8202 << buildFormatSpecifier()
8203 <<
Other.buildFormatSpecifier(),
8204 FmtExpr, InFunctionCall);
8205 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8206 << 0 <<
Other.Range;
8209 case MK::NoMatchSignedness:
8211 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8212 << buildFormatSpecifier()
8213 <<
Other.buildFormatSpecifier(),
8214 FmtExpr, InFunctionCall);
8215 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8216 << 0 <<
Other.Range;
8222bool DecomposePrintfHandler::GetSpecifiers(
8223 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8226 StringRef
Data = FSL->getString();
8227 const char *Str =
Data.data();
8228 llvm::SmallBitVector BV;
8229 UncoveredArgHandler UA;
8230 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8231 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8243 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8244 const EquatableFormatArgument &B) {
8245 return A.getPosition() < B.getPosition();
8250bool DecomposePrintfHandler::HandlePrintfSpecifier(
8253 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8268 const unsigned Unset = ~0;
8269 unsigned FieldWidthIndex = Unset;
8270 unsigned PrecisionIndex = Unset;
8274 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8275 FieldWidthIndex = Specs.size();
8276 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8277 getLocationOfByte(FieldWidth.getStart()),
8279 FieldWidth.getArgType(S.
Context),
8280 EquatableFormatArgument::FAR_FieldWidth,
8281 EquatableFormatArgument::SS_None,
8282 FieldWidth.usesPositionalArg()
8283 ? FieldWidth.getPositionalArgIndex() - 1
8289 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8290 PrecisionIndex = Specs.size();
8292 getSpecifierRange(startSpecifier, specifierLen),
8293 getLocationOfByte(Precision.getStart()),
8295 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8296 EquatableFormatArgument::SS_None,
8297 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8303 unsigned SpecIndex =
8305 if (FieldWidthIndex != Unset)
8306 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8307 if (PrecisionIndex != Unset)
8308 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8310 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8312 Sensitivity = EquatableFormatArgument::SS_Private;
8314 Sensitivity = EquatableFormatArgument::SS_Public;
8316 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8318 Sensitivity = EquatableFormatArgument::SS_None;
8321 getSpecifierRange(startSpecifier, specifierLen),
8324 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8329 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8334 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8335 SpecIndex + 1, SpecIndex);
8343template<
typename MemberKind>
8361 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8376 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8378 if ((*MI)->getMinRequiredArguments() == 0)
8386bool CheckPrintfHandler::checkForCStrMembers(
8393 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8396 if (
Method->getMinRequiredArguments() == 0 &&
8409bool CheckPrintfHandler::HandlePrintfSpecifier(
8423 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8424 startSpecifier, specifierLen);
8432 startSpecifier, specifierLen)) {
8437 startSpecifier, specifierLen)) {
8441 if (!CS.consumesDataArgument()) {
8449 if (argIndex < NumDataArgs) {
8453 CoveredArgs.set(argIndex);
8460 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8463 if (HasFormatArguments()) {
8465 CoveredArgs.set(argIndex + 1);
8468 const Expr *Ex = getDataArg(argIndex);
8472 : ArgType::CPointerTy;
8474 EmitFormatDiagnostic(
8475 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8479 getSpecifierRange(startSpecifier, specifierLen));
8482 Ex = getDataArg(argIndex + 1);
8485 EmitFormatDiagnostic(
8486 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8490 getSpecifierRange(startSpecifier, specifierLen));
8497 if (!allowsObjCArg() && CS.isObjCArg()) {
8498 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8505 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8512 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8513 getLocationOfByte(CS.getStart()),
8515 getSpecifierRange(startSpecifier, specifierLen));
8525 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8532 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8536 getSpecifierRange(startSpecifier, specifierLen));
8539 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8543 getSpecifierRange(startSpecifier, specifierLen));
8547 const llvm::Triple &Triple =
Target.getTriple();
8549 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8550 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8551 getLocationOfByte(CS.getStart()),
8553 getSpecifierRange(startSpecifier, specifierLen));
8559 startSpecifier, specifierLen);
8565 startSpecifier, specifierLen);
8571 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8572 getLocationOfByte(startSpecifier),
8574 getSpecifierRange(startSpecifier, specifierLen));
8583 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8585 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8594 startSpecifier, specifierLen);
8597 startSpecifier, specifierLen);
8602 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8603 diag::warn_format_nonsensical_length);
8605 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8607 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8608 diag::warn_format_non_standard_conversion_spec);
8611 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8614 if (!HasFormatArguments())
8617 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8620 const Expr *Arg = getDataArg(argIndex);
8624 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8636 case Stmt::ArraySubscriptExprClass:
8637 case Stmt::CallExprClass:
8638 case Stmt::CharacterLiteralClass:
8639 case Stmt::CXXBoolLiteralExprClass:
8640 case Stmt::DeclRefExprClass:
8641 case Stmt::FloatingLiteralClass:
8642 case Stmt::IntegerLiteralClass:
8643 case Stmt::MemberExprClass:
8644 case Stmt::ObjCArrayLiteralClass:
8645 case Stmt::ObjCBoolLiteralExprClass:
8646 case Stmt::ObjCBoxedExprClass:
8647 case Stmt::ObjCDictionaryLiteralClass:
8648 case Stmt::ObjCEncodeExprClass:
8649 case Stmt::ObjCIvarRefExprClass:
8650 case Stmt::ObjCMessageExprClass:
8651 case Stmt::ObjCPropertyRefExprClass:
8652 case Stmt::ObjCStringLiteralClass:
8653 case Stmt::ObjCSubscriptRefExprClass:
8654 case Stmt::ParenExprClass:
8655 case Stmt::StringLiteralClass:
8656 case Stmt::UnaryOperatorClass:
8663static std::pair<QualType, StringRef>
8670 StringRef Name = UserTy->getDecl()->getName();
8671 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8672 .Case(
"CFIndex", Context.getNSIntegerType())
8673 .Case(
"NSInteger", Context.getNSIntegerType())
8674 .Case(
"NSUInteger", Context.getNSUIntegerType())
8675 .Case(
"SInt32", Context.IntTy)
8676 .Case(
"UInt32", Context.UnsignedIntTy)
8680 return std::make_pair(CastTy, Name);
8682 TyTy = UserTy->desugar();
8686 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8688 PE->getSubExpr()->getType(),
8697 StringRef TrueName, FalseName;
8699 std::tie(TrueTy, TrueName) =
8701 CO->getTrueExpr()->getType(),
8703 std::tie(FalseTy, FalseName) =
8705 CO->getFalseExpr()->getType(),
8706 CO->getFalseExpr());
8708 if (TrueTy == FalseTy)
8709 return std::make_pair(TrueTy, TrueName);
8710 else if (TrueTy.
isNull())
8711 return std::make_pair(FalseTy, FalseName);
8712 else if (FalseTy.
isNull())
8713 return std::make_pair(TrueTy, TrueName);
8716 return std::make_pair(
QualType(), StringRef());
8735 From = VecTy->getElementType();
8737 To = VecTy->getElementType();
8748 diag::warn_format_conversion_argument_type_mismatch_signedness,
8752 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
8761 const char *StartSpecifier,
8762 unsigned SpecifierLen,
8774 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8775 ExprTy = TET->getUnderlyingExpr()->getType();
8790 getSpecifierRange(StartSpecifier, SpecifierLen);
8792 llvm::raw_svector_ostream os(FSString);
8794 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8805 getSpecifierRange(StartSpecifier, SpecifierLen);
8806 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8816 if (
Match == ArgType::Match)
8820 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8829 E = ICE->getSubExpr();
8839 if (OrigMatch == ArgType::NoMatchSignedness &&
8840 ImplicitMatch != ArgType::NoMatchSignedness)
8847 if (ImplicitMatch == ArgType::Match)
8865 if (
Match == ArgType::MatchPromotion)
8869 if (
Match == ArgType::MatchPromotion) {
8873 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8874 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8878 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8879 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8880 Match = ImplicitMatch;
8881 assert(
Match != ArgType::MatchPromotion);
8884 bool IsEnum =
false;
8885 bool IsScopedEnum =
false;
8888 IntendedTy = ED->getIntegerType();
8889 if (!ED->isScoped()) {
8890 ExprTy = IntendedTy;
8895 IsScopedEnum =
true;
8902 if (isObjCContext() &&
8913 const llvm::APInt &
V = IL->getValue();
8923 if (TD->getUnderlyingType() == IntendedTy)
8933 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8941 if (!IsScopedEnum &&
8942 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8946 IntendedTy = CastTy;
8947 ShouldNotPrintDirectly =
true;
8952 PrintfSpecifier fixedFS = FS;
8959 llvm::raw_svector_ostream os(buf);
8962 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8964 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8970 llvm_unreachable(
"expected non-matching");
8972 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8975 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8978 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8981 Diag = diag::warn_format_conversion_argument_type_mismatch;
9002 llvm::raw_svector_ostream CastFix(CastBuf);
9003 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9005 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9011 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9016 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9038 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9044 Name = TypedefTy->getDecl()->getName();
9048 ? diag::warn_format_argument_needs_cast_pedantic
9049 : diag::warn_format_argument_needs_cast;
9050 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9061 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9062 : diag::warn_format_conversion_argument_type_mismatch;
9064 EmitFormatDiagnostic(
9076 bool EmitTypeMismatch =
false;
9085 llvm_unreachable(
"expected non-matching");
9087 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9090 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9093 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9097 ? diag::err_format_conversion_argument_type_mismatch
9098 : diag::warn_format_conversion_argument_type_mismatch;
9102 EmitFormatDiagnostic(
9111 EmitTypeMismatch =
true;
9113 EmitFormatDiagnostic(
9114 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9115 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9119 checkForCStrMembers(AT, E);
9125 EmitTypeMismatch =
true;
9127 EmitFormatDiagnostic(
9128 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9129 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9142 if (EmitTypeMismatch) {
9148 EmitFormatDiagnostic(
9149 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9155 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9156 "format string specifier index out of range");
9157 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9167class CheckScanfHandler :
public CheckFormatHandler {
9169 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9171 unsigned firstDataArg,
unsigned numDataArgs,
9173 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9175 llvm::SmallBitVector &CheckedVarArgs,
9176 UncoveredArgHandler &UncoveredArg)
9177 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9178 numDataArgs, beg, APK, Args, formatIdx,
9179 inFunctionCall, CallType, CheckedVarArgs,
9182 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9183 const char *startSpecifier,
9184 unsigned specifierLen)
override;
9186 bool HandleInvalidScanfConversionSpecifier(
9187 const analyze_scanf::ScanfSpecifier &FS,
9188 const char *startSpecifier,
9189 unsigned specifierLen)
override;
9191 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9196void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9198 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9199 getLocationOfByte(end),
true,
9200 getSpecifierRange(start, end - start));
9203bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9205 const char *startSpecifier,
9206 unsigned specifierLen) {
9210 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9212 startSpecifier, specifierLen,
9216bool CheckScanfHandler::HandleScanfSpecifier(
9218 const char *startSpecifier,
9219 unsigned specifierLen) {
9233 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9234 startSpecifier, specifierLen);
9245 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9260 if (argIndex < NumDataArgs) {
9264 CoveredArgs.set(argIndex);
9270 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9271 diag::warn_format_nonsensical_length);
9273 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9275 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9276 diag::warn_format_non_standard_conversion_spec);
9279 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9282 if (!HasFormatArguments())
9285 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9289 const Expr *Ex = getDataArg(argIndex);
9307 ScanfSpecifier fixedFS = FS;
9312 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9314 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9315 : diag::warn_format_conversion_argument_type_mismatch;
9320 llvm::raw_svector_ostream os(buf);
9323 EmitFormatDiagnostic(
9328 getSpecifierRange(startSpecifier, specifierLen),
9330 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9337 getSpecifierRange(startSpecifier, specifierLen));
9347 const Expr *FmtExpr,
bool InFunctionCall) {
9348 bool HadError =
false;
9349 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9350 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9351 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9363 for (; FmtIter < FmtEnd; ++FmtIter) {
9367 if (FmtIter->getPosition() < RefIter->getPosition())
9371 if (FmtIter->getPosition() > RefIter->getPosition())
9375 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9379 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9380 return Arg.getPosition() != RefIter->getPosition();
9384 if (FmtIter < FmtEnd) {
9385 CheckFormatHandler::EmitFormatDiagnostic(
9386 S, InFunctionCall, FmtExpr,
9387 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9388 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9389 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9390 }
else if (RefIter < RefEnd) {
9391 CheckFormatHandler::EmitFormatDiagnostic(
9392 S, InFunctionCall, FmtExpr,
9393 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9396 << 1 << RefIter->getSourceRange();
9402 Sema &S,
const FormatStringLiteral *FExpr,
9407 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9408 bool IgnoreStringsWithoutSpecifiers) {
9410 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9411 CheckFormatHandler::EmitFormatDiagnostic(
9412 S, inFunctionCall, Args[format_idx],
9413 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9419 StringRef StrRef = FExpr->getString();
9420 const char *Str = StrRef.data();
9424 assert(
T &&
"String literal not of constant array type!");
9425 size_t TypeSize =
T->getZExtSize();
9426 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9427 const unsigned numDataArgs = Args.size() - firstDataArg;
9429 if (IgnoreStringsWithoutSpecifiers &&
9436 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9437 CheckFormatHandler::EmitFormatDiagnostic(
9438 S, inFunctionCall, Args[format_idx],
9439 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9440 FExpr->getBeginLoc(),
9446 if (StrLen == 0 && numDataArgs > 0) {
9447 CheckFormatHandler::EmitFormatDiagnostic(
9448 S, inFunctionCall, Args[format_idx],
9449 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9460 if (ReferenceFormatString ==
nullptr) {
9461 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9462 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9463 inFunctionCall, CallType, CheckedVarArgs,
9473 Type, ReferenceFormatString, FExpr->getFormatString(),
9474 inFunctionCall ?
nullptr : Args[format_idx]);
9477 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9478 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9479 CallType, CheckedVarArgs, UncoveredArg);
9499 FormatStringLiteral RefLit = AuthoritativeFormatString;
9500 FormatStringLiteral TestLit = TestedFormatString;
9502 bool DiagAtStringLiteral;
9503 if (FunctionCallArg) {
9504 Arg = FunctionCallArg;
9505 DiagAtStringLiteral =
false;
9507 Arg = TestedFormatString;
9508 DiagAtStringLiteral =
true;
9510 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9511 AuthoritativeFormatString,
Type,
9512 IsObjC,
true, RefArgs) &&
9513 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9514 DiagAtStringLiteral, FmtArgs)) {
9516 TestedFormatString, FmtArgs, Arg,
9517 DiagAtStringLiteral);
9530 FormatStringLiteral RefLit = Str;
9534 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9543 bool HadError =
false;
9544 auto Iter = Args.begin();
9545 auto End = Args.end();
9546 while (Iter != End) {
9547 const auto &FirstInGroup = *Iter;
9549 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9551 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9560 const char *Str = StrRef.data();
9563 assert(
T &&
"String literal not of constant array type!");
9564 size_t TypeSize =
T->getZExtSize();
9565 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9576 switch (AbsFunction) {
9580 case Builtin::BI__builtin_abs:
9581 return Builtin::BI__builtin_labs;
9582 case Builtin::BI__builtin_labs:
9583 return Builtin::BI__builtin_llabs;
9584 case Builtin::BI__builtin_llabs:
9587 case Builtin::BI__builtin_fabsf:
9588 return Builtin::BI__builtin_fabs;
9589 case Builtin::BI__builtin_fabs:
9590 return Builtin::BI__builtin_fabsl;
9591 case Builtin::BI__builtin_fabsl:
9594 case Builtin::BI__builtin_cabsf:
9595 return Builtin::BI__builtin_cabs;
9596 case Builtin::BI__builtin_cabs:
9597 return Builtin::BI__builtin_cabsl;
9598 case Builtin::BI__builtin_cabsl:
9601 case Builtin::BIabs:
9602 return Builtin::BIlabs;
9603 case Builtin::BIlabs:
9604 return Builtin::BIllabs;
9605 case Builtin::BIllabs:
9608 case Builtin::BIfabsf:
9609 return Builtin::BIfabs;
9610 case Builtin::BIfabs:
9611 return Builtin::BIfabsl;
9612 case Builtin::BIfabsl:
9615 case Builtin::BIcabsf:
9616 return Builtin::BIcabs;
9617 case Builtin::BIcabs:
9618 return Builtin::BIcabsl;
9619 case Builtin::BIcabsl:
9648 unsigned AbsFunctionKind) {
9649 unsigned BestKind = 0;
9650 uint64_t ArgSize = Context.getTypeSize(ArgType);
9651 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9654 if (Context.getTypeSize(ParamType) >= ArgSize) {
9657 else if (Context.hasSameType(ParamType, ArgType)) {
9673 if (
T->isIntegralOrEnumerationType())
9675 if (
T->isRealFloatingType())
9677 if (
T->isAnyComplexType())
9680 llvm_unreachable(
"Type not integer, floating, or complex");
9687 switch (ValueKind) {
9692 case Builtin::BI__builtin_fabsf:
9693 case Builtin::BI__builtin_fabs:
9694 case Builtin::BI__builtin_fabsl:
9695 case Builtin::BI__builtin_cabsf:
9696 case Builtin::BI__builtin_cabs:
9697 case Builtin::BI__builtin_cabsl:
9698 return Builtin::BI__builtin_abs;
9699 case Builtin::BIfabsf:
9700 case Builtin::BIfabs:
9701 case Builtin::BIfabsl:
9702 case Builtin::BIcabsf:
9703 case Builtin::BIcabs:
9704 case Builtin::BIcabsl:
9705 return Builtin::BIabs;
9711 case Builtin::BI__builtin_abs:
9712 case Builtin::BI__builtin_labs:
9713 case Builtin::BI__builtin_llabs:
9714 case Builtin::BI__builtin_cabsf:
9715 case Builtin::BI__builtin_cabs:
9716 case Builtin::BI__builtin_cabsl:
9717 return Builtin::BI__builtin_fabsf;
9718 case Builtin::BIabs:
9719 case Builtin::BIlabs:
9720 case Builtin::BIllabs:
9721 case Builtin::BIcabsf:
9722 case Builtin::BIcabs:
9723 case Builtin::BIcabsl:
9724 return Builtin::BIfabsf;
9730 case Builtin::BI__builtin_abs:
9731 case Builtin::BI__builtin_labs:
9732 case Builtin::BI__builtin_llabs:
9733 case Builtin::BI__builtin_fabsf:
9734 case Builtin::BI__builtin_fabs:
9735 case Builtin::BI__builtin_fabsl:
9736 return Builtin::BI__builtin_cabsf;
9737 case Builtin::BIabs:
9738 case Builtin::BIlabs:
9739 case Builtin::BIllabs:
9740 case Builtin::BIfabsf:
9741 case Builtin::BIfabs:
9742 case Builtin::BIfabsl:
9743 return Builtin::BIcabsf;
9746 llvm_unreachable(
"Unable to convert function");
9757 case Builtin::BI__builtin_abs:
9758 case Builtin::BI__builtin_fabs:
9759 case Builtin::BI__builtin_fabsf:
9760 case Builtin::BI__builtin_fabsl:
9761 case Builtin::BI__builtin_labs:
9762 case Builtin::BI__builtin_llabs:
9763 case Builtin::BI__builtin_cabs:
9764 case Builtin::BI__builtin_cabsf:
9765 case Builtin::BI__builtin_cabsl:
9766 case Builtin::BIabs:
9767 case Builtin::BIlabs:
9768 case Builtin::BIllabs:
9769 case Builtin::BIfabs:
9770 case Builtin::BIfabsf:
9771 case Builtin::BIfabsl:
9772 case Builtin::BIcabs:
9773 case Builtin::BIcabsf:
9774 case Builtin::BIcabsl:
9777 llvm_unreachable(
"Unknown Builtin type");
9783 unsigned AbsKind,
QualType ArgType) {
9784 bool EmitHeaderHint =
true;
9785 const char *HeaderName =
nullptr;
9786 std::string FunctionName;
9787 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9788 FunctionName =
"std::abs";
9789 if (ArgType->isIntegralOrEnumerationType()) {
9790 HeaderName =
"cstdlib";
9791 }
else if (ArgType->isRealFloatingType()) {
9792 HeaderName =
"cmath";
9794 llvm_unreachable(
"Invalid Type");
9803 for (
const auto *I : R) {
9806 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9808 FDecl = dyn_cast<FunctionDecl>(I);
9823 EmitHeaderHint =
false;
9841 EmitHeaderHint =
false;
9845 }
else if (!R.
empty()) {
9851 S.
Diag(Loc, diag::note_replace_abs_function)
9857 if (!EmitHeaderHint)
9860 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9864template <std::
size_t StrLen>
9866 const char (&Str)[StrLen]) {
9879 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9880 return llvm::is_contained(names, calleeName);
9885 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9886 "__builtin_nanf16",
"__builtin_nanf128"});
9888 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9889 "__builtin_inff16",
"__builtin_inff128"});
9891 llvm_unreachable(
"unknown MathCheck");
9895 if (FDecl->
getName() !=
"infinity")
9898 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9900 if (RDecl->
getName() !=
"numeric_limits")
9917 if (FPO.getNoHonorNaNs() &&
9920 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9921 << 1 << 0 <<
Call->getSourceRange();
9925 if (FPO.getNoHonorInfs() &&
9929 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9930 << 0 << 0 <<
Call->getSourceRange();
9934void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9936 if (
Call->getNumArgs() != 1)
9941 if (AbsKind == 0 && !IsStdAbs)
9944 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9945 QualType ParamType =
Call->getArg(0)->getType();
9950 std::string FunctionName =
9951 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
9952 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9953 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9982 if (ArgValueKind == ParamValueKind) {
9983 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
9987 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9988 << FDecl << ArgType << ParamType;
9990 if (NewAbsKind == 0)
9994 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10003 if (NewAbsKind == 0)
10006 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10007 << FDecl << ParamValueKind << ArgValueKind;
10010 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10016 if (!
Call || !FDecl)
return;
10020 if (
Call->getExprLoc().isMacroID())
return;
10023 if (
Call->getNumArgs() != 2)
return;
10026 if (!ArgList)
return;
10027 if (ArgList->size() != 1)
return;
10030 const auto& TA = ArgList->
get(0);
10032 QualType ArgType = TA.getAsType();
10036 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10037 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10038 if (!MTE)
return false;
10039 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10040 if (!
Num)
return false;
10041 if (
Num->getValue() != 0)
return false;
10045 const Expr *FirstArg =
Call->getArg(0);
10046 const Expr *SecondArg =
Call->getArg(1);
10047 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10048 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10051 if (IsFirstArgZero == IsSecondArgZero)
return;
10056 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10058 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10059 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10062 SourceRange RemovalRange;
10063 if (IsFirstArgZero) {
10064 RemovalRange = SourceRange(FirstRange.
getBegin(),
10071 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10086 const auto *Size = dyn_cast<BinaryOperator>(E);
10091 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10095 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10096 << SizeRange << FnName;
10097 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10102 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10113 bool &IsContained) {
10115 const Type *Ty =
T->getBaseElementTypeUnsafe();
10116 IsContained =
false;
10129 for (
auto *FD : RD->
fields()) {
10133 IsContained =
true;
10134 return ContainedRD;
10142 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10143 if (Unary->getKind() == UETT_SizeOf)
10152 if (!
SizeOf->isArgumentType())
10153 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10160 return SizeOf->getTypeOfArgument();
10166struct SearchNonTrivialToInitializeField
10169 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10171 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10174 SourceLocation SL) {
10175 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10176 asDerived().visitArray(PDIK, AT, SL);
10180 Super::visitWithKind(PDIK, FT, SL);
10183 void visitARCStrong(QualType FT, SourceLocation SL) {
10186 void visitARCWeak(QualType FT, SourceLocation SL) {
10189 void visitStruct(QualType FT, SourceLocation SL) {
10194 const ArrayType *AT, SourceLocation SL) {
10195 visit(getContext().getBaseElementType(AT), SL);
10197 void visitTrivial(QualType FT, SourceLocation SL) {}
10199 static void diag(QualType RT,
const Expr *E, Sema &S) {
10200 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10209struct SearchNonTrivialToCopyField
10211 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10213 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10216 SourceLocation SL) {
10217 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10218 asDerived().visitArray(PCK, AT, SL);
10222 Super::visitWithKind(PCK, FT, SL);
10225 void visitARCStrong(QualType FT, SourceLocation SL) {
10228 void visitARCWeak(QualType FT, SourceLocation SL) {
10231 void visitPtrAuth(QualType FT, SourceLocation SL) {
10234 void visitStruct(QualType FT, SourceLocation SL) {
10239 SourceLocation SL) {
10240 visit(getContext().getBaseElementType(AT), SL);
10243 SourceLocation SL) {}
10244 void visitTrivial(QualType FT, SourceLocation SL) {}
10245 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10247 static void diag(QualType RT,
const Expr *E, Sema &S) {
10248 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10263 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10264 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10288 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10290 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10291 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10297 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10300 const Expr *SizeArg =
10301 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10303 auto isLiteralZero = [](
const Expr *E) {
10313 if (isLiteralZero(SizeArg) &&
10320 if (BId == Builtin::BIbzero ||
10323 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10324 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10325 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10326 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10327 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10335 if (BId == Builtin::BImemset &&
10339 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10340 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10345void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10352 unsigned ExpectedNumArgs =
10353 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10354 if (
Call->getNumArgs() < ExpectedNumArgs)
10357 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10358 BId == Builtin::BIstrndup ? 1 : 2);
10360 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10361 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10364 Call->getBeginLoc(),
Call->getRParenLoc()))
10373 llvm::FoldingSetNodeID SizeOfArgID;
10378 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10379 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10382 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10383 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10384 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10386 QualType DestTy = Dest->
getType();
10387 QualType PointeeTy;
10388 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10401 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10405 if (SizeOfArgID == llvm::FoldingSetNodeID())
10407 llvm::FoldingSetNodeID DestID;
10409 if (DestID == SizeOfArgID) {
10412 unsigned ActionIdx = 0;
10413 StringRef ReadableName = FnName->
getName();
10415 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10416 if (UnaryOp->getOpcode() == UO_AddrOf)
10425 SourceLocation SL = SizeOfArg->
getExprLoc();
10430 if (
SM.isMacroArgExpansion(SL)) {
10432 SL =
SM.getSpellingLoc(SL);
10433 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10435 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10440 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10447 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10458 if (SizeOfArgTy != QualType()) {
10460 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10462 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10463 << FnName << SizeOfArgTy << ArgIdx
10470 PointeeTy = DestTy;
10473 if (PointeeTy == QualType())
10478 if (
const CXXRecordDecl *ContainedRD =
10481 unsigned OperationType = 0;
10482 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10485 if (ArgIdx != 0 || IsCmp) {
10486 if (BId == Builtin::BImemcpy)
10488 else if(BId == Builtin::BImemmove)
10495 PDiag(diag::warn_dyn_class_memaccess)
10496 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10497 << IsContained << ContainedRD << OperationType
10498 <<
Call->getCallee()->getSourceRange());
10500 BId != Builtin::BImemset)
10503 PDiag(diag::warn_arc_object_memaccess)
10504 << ArgIdx << FnName << PointeeTy
10505 <<
Call->getCallee()->getSourceRange());
10512 bool NonTriviallyCopyableCXXRecord =
10516 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10519 PDiag(diag::warn_cstruct_memaccess)
10520 << ArgIdx << FnName << PointeeTy << 0);
10521 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10522 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10523 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10527 PDiag(diag::warn_cxxstruct_memaccess)
10528 << FnName << PointeeTy);
10529 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10532 PDiag(diag::warn_cstruct_memaccess)
10533 << ArgIdx << FnName << PointeeTy << 1);
10534 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10535 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10536 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10540 PDiag(diag::warn_cxxstruct_memaccess)
10541 << FnName << PointeeTy);
10550 PDiag(diag::note_bad_memaccess_silence)
10586 if (CAT->getZExtSize() <= 1)
10594void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10598 unsigned NumArgs =
Call->getNumArgs();
10599 if ((NumArgs != 3) && (NumArgs != 4))
10604 const Expr *CompareWithSrc =
nullptr;
10607 Call->getBeginLoc(),
Call->getRParenLoc()))
10612 CompareWithSrc = Ex;
10615 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10616 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10617 SizeCall->getNumArgs() == 1)
10622 if (!CompareWithSrc)
10629 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10633 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10634 if (!CompareWithSrcDRE ||
10638 const Expr *OriginalSizeArg =
Call->getArg(2);
10639 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10646 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10650 SmallString<128> sizeString;
10651 llvm::raw_svector_ostream
OS(sizeString);
10656 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10663 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10664 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10665 return D1->getDecl() == D2->getDecl();
10670 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10679void Sema::CheckStrncatArguments(
const CallExpr *CE,
10694 unsigned PatternType = 0;
10702 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10703 if (BE->getOpcode() == BO_Sub) {
10704 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10705 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10716 if (PatternType == 0)
10725 if (
SM.isMacroArgExpansion(SL)) {
10726 SL =
SM.getSpellingLoc(SL);
10727 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10732 QualType DstTy = DstArg->
getType();
10735 if (!isKnownSizeArray) {
10736 if (PatternType == 1)
10737 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10739 Diag(SL, diag::warn_strncat_src_size) << SR;
10743 if (PatternType == 1)
10744 Diag(SL, diag::warn_strncat_large_size) << SR;
10746 Diag(SL, diag::warn_strncat_src_size) << SR;
10748 SmallString<128> sizeString;
10749 llvm::raw_svector_ostream
OS(sizeString);
10757 Diag(SL, diag::note_strncat_wrong_size)
10762void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10771void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10773 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10774 const Decl *D = Lvalue->getDecl();
10775 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10776 if (!DD->getType()->isReferenceType())
10777 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10781 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10782 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10783 Lvalue->getMemberDecl());
10786void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10788 const auto *Lambda = dyn_cast<LambdaExpr>(
10793 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10794 << CalleeName << 2 ;
10797void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10799 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10800 if (Var ==
nullptr)
10804 << CalleeName << 0 << Var;
10807void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10810 llvm::raw_svector_ostream
OS(SizeString);
10813 if (Kind == clang::CK_BitCast &&
10814 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10816 if (Kind == clang::CK_IntegralToPointer &&
10818 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10821 switch (
Cast->getCastKind()) {
10822 case clang::CK_BitCast:
10823 case clang::CK_IntegralToPointer:
10824 case clang::CK_FunctionToPointerDecay:
10833 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10834 << CalleeName << 0 <<
OS.str();
10838void Sema::CheckFreeArguments(
const CallExpr *E) {
10839 const std::string CalleeName =
10844 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10846 case UnaryOperator::Opcode::UO_AddrOf:
10847 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10848 case UnaryOperator::Opcode::UO_Plus:
10849 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10854 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10856 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10858 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10859 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10860 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10866 << CalleeName << 1 ;
10871 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
10872 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10876Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10885 Diag(ReturnLoc, diag::warn_null_ret)
10895 if (Op == OO_New || Op == OO_Array_New) {
10896 const FunctionProtoType *Proto
10900 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10906 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10911 if (
Context.getTargetInfo().getTriple().isPPC64())
10923 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10924 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10926 return FPLiteral && FPCast;
10929 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10935 llvm::APFloat TargetC = FPLiteral->
getValue();
10936 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
10937 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10941 Diag(Loc, diag::warn_float_compare_literal)
10942 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10955 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10956 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10957 if (DRL->getDecl() == DRR->getDecl())
10965 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10966 if (FLL->isExact())
10968 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10969 if (FLR->isExact())
10973 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10974 CL &&
CL->getBuiltinCallee())
10977 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10978 CR && CR->getBuiltinCallee())
10982 Diag(Loc, diag::warn_floatingpoint_eq)
11003 IntRange(
unsigned Width,
bool NonNegative)
11004 : Width(Width), NonNegative(NonNegative) {}
11007 unsigned valueBits()
const {
11008 return NonNegative ? Width : Width - 1;
11012 static IntRange forBoolType() {
11013 return IntRange(1,
true);
11017 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11018 return forValueOfCanonicalType(
C,
11023 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11026 if (
const auto *VT = dyn_cast<VectorType>(
T))
11027 T = VT->getElementType().getTypePtr();
11028 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11029 T = CT->getElementType().getTypePtr();
11030 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11031 T = AT->getValueType().getTypePtr();
11033 if (!
C.getLangOpts().CPlusPlus) {
11036 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11041 if (
Enum->isFixed()) {
11042 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11043 !
Enum->getIntegerType()->isSignedIntegerType());
11046 unsigned NumPositive =
Enum->getNumPositiveBits();
11047 unsigned NumNegative =
Enum->getNumNegativeBits();
11049 if (NumNegative == 0)
11050 return IntRange(NumPositive,
true);
11052 return IntRange(std::max(NumPositive + 1, NumNegative),
11056 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11057 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11070 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11073 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11074 T = VT->getElementType().getTypePtr();
11075 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11076 T = CT->getElementType().getTypePtr();
11077 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11078 T = AT->getValueType().getTypePtr();
11080 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11082 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11083 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11092 static IntRange join(IntRange L, IntRange R) {
11093 bool Unsigned = L.NonNegative && R.NonNegative;
11094 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
11095 L.NonNegative && R.NonNegative);
11099 static IntRange bit_and(IntRange L, IntRange R) {
11100 unsigned Bits = std::max(L.Width, R.Width);
11101 bool NonNegative =
false;
11102 if (L.NonNegative) {
11103 Bits = std::min(Bits, L.Width);
11104 NonNegative =
true;
11106 if (R.NonNegative) {
11107 Bits = std::min(Bits, R.Width);
11108 NonNegative =
true;
11110 return IntRange(Bits, NonNegative);
11114 static IntRange sum(IntRange L, IntRange R) {
11115 bool Unsigned = L.NonNegative && R.NonNegative;
11116 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
11121 static IntRange difference(IntRange L, IntRange R) {
11125 bool CanWiden = !L.NonNegative || !R.NonNegative;
11126 bool Unsigned = L.NonNegative && R.Width == 0;
11127 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
11133 static IntRange product(IntRange L, IntRange R) {
11137 bool CanWiden = !L.NonNegative && !R.NonNegative;
11138 bool Unsigned = L.NonNegative && R.NonNegative;
11139 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
11144 static IntRange rem(IntRange L, IntRange R) {
11148 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
11156 if (value.isSigned() && value.isNegative())
11157 return IntRange(value.getSignificantBits(),
false);
11159 if (value.getBitWidth() > MaxWidth)
11160 value = value.trunc(MaxWidth);
11164 return IntRange(value.getActiveBits(),
true);
11168 if (result.
isInt())
11175 R = IntRange::join(R, El);
11183 return IntRange::join(R, I);
11198 Ty = AtomicRHS->getValueType();
11217 bool InConstantContext,
11218 bool Approximate) {
11229 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11230 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11234 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11236 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11237 CE->getCastKind() == CK_BooleanToSignedIntegral;
11240 if (!isIntegerCast)
11241 return OutputTypeRange;
11244 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11245 InConstantContext, Approximate);
11247 return std::nullopt;
11250 if (SubRange->Width >= OutputTypeRange.Width)
11251 return OutputTypeRange;
11255 return IntRange(SubRange->Width,
11256 SubRange->NonNegative || OutputTypeRange.NonNegative);
11259 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11262 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11264 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11265 InConstantContext, Approximate);
11270 Expr *TrueExpr = CO->getTrueExpr();
11272 return std::nullopt;
11274 std::optional<IntRange> L =
11277 return std::nullopt;
11279 Expr *FalseExpr = CO->getFalseExpr();
11281 return std::nullopt;
11283 std::optional<IntRange> R =
11286 return std::nullopt;
11288 return IntRange::join(*L, *R);
11291 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11292 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11294 switch (BO->getOpcode()) {
11296 llvm_unreachable(
"builtin <=> should have class type");
11307 return IntRange::forBoolType();
11336 Combine = IntRange::bit_and;
11344 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11345 if (I->getValue() == 1) {
11346 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11347 return IntRange(R.Width,
true);
11357 case BO_ShrAssign: {
11359 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11361 return std::nullopt;
11365 if (std::optional<llvm::APSInt> shift =
11366 BO->getRHS()->getIntegerConstantExpr(
C)) {
11367 if (shift->isNonNegative()) {
11368 if (shift->uge(L->Width))
11369 L->Width = (L->NonNegative ? 0 : 1);
11371 L->Width -= shift->getZExtValue();
11385 Combine = IntRange::sum;
11389 if (BO->getLHS()->getType()->isPointerType())
11392 Combine = IntRange::difference;
11397 Combine = IntRange::product;
11406 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11408 return std::nullopt;
11411 if (std::optional<llvm::APSInt> divisor =
11412 BO->getRHS()->getIntegerConstantExpr(
C)) {
11413 unsigned log2 = divisor->logBase2();
11414 if (
log2 >= L->Width)
11415 L->Width = (L->NonNegative ? 0 : 1);
11417 L->Width = std::min(L->Width -
log2, MaxWidth);
11425 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11427 return std::nullopt;
11429 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11433 Combine = IntRange::rem;
11445 unsigned opWidth =
C.getIntWidth(
T);
11447 InConstantContext, Approximate);
11449 return std::nullopt;
11452 InConstantContext, Approximate);
11454 return std::nullopt;
11456 IntRange
C = Combine(*L, *R);
11457 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11458 C.Width = std::min(
C.Width, MaxWidth);
11462 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11463 switch (UO->getOpcode()) {
11466 return IntRange::forBoolType();
11480 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11483 return std::nullopt;
11488 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11498 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11501 return std::nullopt;
11506 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11516 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11517 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11521 return IntRange(BitField->getBitWidthValue(),
11522 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11525 return std::nullopt;
11531 bool InConstantContext,
11532 bool Approximate) {
11541 const llvm::fltSemantics &Src,
11542 const llvm::fltSemantics &Tgt) {
11543 llvm::APFloat truncated = value;
11546 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11547 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11549 return truncated.bitwiseIsEqual(value);
11558 const llvm::fltSemantics &Src,
11559 const llvm::fltSemantics &Tgt) {
11576 bool IsListInit =
false);
11591 return MacroName !=
"YES" && MacroName !=
"NO" &&
11592 MacroName !=
"true" && MacroName !=
"false";
11600 (!E->
getType()->isSignedIntegerType() ||
11615struct PromotedRange {
11617 llvm::APSInt PromotedMin;
11619 llvm::APSInt PromotedMax;
11621 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11623 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11624 else if (R.Width >= BitWidth && !
Unsigned) {
11628 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11629 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11631 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11632 .extOrTrunc(BitWidth);
11633 PromotedMin.setIsUnsigned(
Unsigned);
11635 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11636 .extOrTrunc(BitWidth);
11637 PromotedMax.setIsUnsigned(
Unsigned);
11642 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11652 InRangeFlag = 0x40,
11655 Min =
LE | InRangeFlag,
11656 InRange = InRangeFlag,
11657 Max =
GE | InRangeFlag,
11660 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11665 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11666 Value.isUnsigned() == PromotedMin.isUnsigned());
11667 if (!isContiguous()) {
11668 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11669 if (
Value.isMinValue())
return Min;
11670 if (
Value.isMaxValue())
return Max;
11671 if (
Value >= PromotedMin)
return InRange;
11672 if (
Value <= PromotedMax)
return InRange;
11676 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11677 case -1:
return Less;
11678 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11680 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11681 case -1:
return InRange;
11682 case 0:
return Max;
11687 llvm_unreachable(
"impossible compare result");
11690 static std::optional<StringRef>
11692 if (Op == BO_Cmp) {
11694 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11696 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11697 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11698 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11699 return std::nullopt;
11706 }
else if (Op == BO_NE) {
11710 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11717 if (Op == BO_GE || Op == BO_LE)
11718 std::swap(TrueFlag, FalseFlag);
11721 return StringRef(
"true");
11723 return StringRef(
"false");
11724 return std::nullopt;
11731 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11732 if (ICE->getCastKind() != CK_IntegralCast &&
11733 ICE->getCastKind() != CK_NoOp)
11735 E = ICE->getSubExpr();
11744 enum ConstantValueKind {
11749 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11750 return BL->getValue() ? ConstantValueKind::LiteralTrue
11751 : ConstantValueKind::LiteralFalse;
11752 return ConstantValueKind::Miscellaneous;
11757 const llvm::APSInt &
Value,
11758 bool RhsConstant) {
11780 if (!OtherValueRange)
11785 OtherT = AT->getValueType();
11786 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11790 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11796 bool OtherIsBooleanDespiteType =
11798 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11799 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11803 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11804 Value.isUnsigned());
11805 auto Cmp = OtherPromotedValueRange.compare(
Value);
11806 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11812 bool TautologicalTypeCompare =
false;
11814 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11815 Value.isUnsigned());
11816 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11819 TautologicalTypeCompare =
true;
11827 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11836 bool InRange = Cmp & PromotedRange::InRangeFlag;
11842 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11843 Other->getType()->isUnsignedIntegerOrEnumerationType())
11844 TautologicalTypeCompare =
true;
11849 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11850 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11854 llvm::raw_svector_ostream OS(PrettySourceValue);
11856 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11857 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11859 OS << (BL->getValue() ?
"YES" :
"NO");
11864 if (!TautologicalTypeCompare) {
11866 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11872 if (IsObjCSignedCharBool) {
11874 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11875 << OS.str() << *Result);
11882 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11886 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11887 : diag::warn_tautological_bool_compare)
11889 << OtherIsBooleanDespiteType << *Result
11896 ? diag::warn_unsigned_enum_always_true_comparison
11897 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11898 : diag::warn_unsigned_always_true_comparison)
11899 : diag::warn_tautological_constant_compare;
11902 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
11935 if (
T->isIntegralType(S.
Context)) {
11936 std::optional<llvm::APSInt> RHSValue =
11938 std::optional<llvm::APSInt> LHSValue =
11942 if (RHSValue && LHSValue)
11946 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11948 const bool RhsConstant = (
bool)RHSValue;
11949 Expr *Const = RhsConstant ? RHS : LHS;
11951 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11960 if (!
T->hasUnsignedIntegerRepresentation()) {
11974 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11976 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11982 Expr *signedOperand, *unsignedOperand;
11985 "unsigned comparison between two signed integer expressions?");
11986 signedOperand = LHS;
11987 unsignedOperand = RHS;
11989 signedOperand = RHS;
11990 unsignedOperand = LHS;
11996 std::optional<IntRange> signedRange =
12008 if (signedRange->NonNegative)
12020 if (!unsignedRange)
12025 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12027 if (unsignedRange->Width < comparisonWidth)
12032 S.
PDiag(diag::warn_mixed_sign_comparison)
12051 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12056 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12057 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12058 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12059 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12060 << BitfieldEnumDecl;
12067 Init->isValueDependent() ||
12068 Init->isTypeDependent())
12071 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12081 const PreferredTypeAttr *PTAttr =
nullptr;
12083 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12085 ED = PTAttr->getType()->getAsEnumDecl();
12093 bool SignedEnum = ED->getNumNegativeBits() > 0;
12100 unsigned DiagID = 0;
12101 if (SignedEnum && !SignedBitfield) {
12104 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12106 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12107 }
else if (SignedBitfield && !SignedEnum &&
12108 ED->getNumPositiveBits() == FieldWidth) {
12111 ? diag::warn_signed_bitfield_enum_conversion
12112 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12115 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12120 << SignedEnum << TypeRange;
12122 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12129 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12130 ED->getNumNegativeBits())
12131 : ED->getNumPositiveBits();
12134 if (BitsNeeded > FieldWidth) {
12138 ? diag::warn_bitfield_too_small_for_enum
12139 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12140 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12144 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12152 llvm::APSInt
Value = Result.Val.getInt();
12154 unsigned OriginalWidth =
Value.getBitWidth();
12160 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12161 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12168 if (!
Value.isSigned() ||
Value.isNegative())
12169 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12170 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12171 OriginalWidth =
Value.getSignificantBits();
12173 if (OriginalWidth <= FieldWidth)
12177 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12181 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12182 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12186 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12188 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12189 ? diag::warn_impcast_single_bit_bitield_precision_constant
12190 : diag::warn_impcast_bitfield_precision_constant)
12191 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12192 <<
Init->getSourceRange();
12224 bool PruneControlFlow =
false) {
12231 if (
T.hasAddressSpace())
12233 if (PruneControlFlow) {
12247 bool PruneControlFlow =
false) {
12254 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
12259 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12260 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12265 llvm::APFloat
Value(0.0);
12271 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12276 diag::warn_impcast_float_integer, PruneWarnings);
12279 bool isExact =
false;
12282 T->hasUnsignedIntegerRepresentation());
12283 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12284 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12292 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12293 precision = (precision * 59 + 195) / 196;
12294 Value.toString(PrettySourceValue, precision);
12298 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12299 << PrettySourceValue);
12302 if (Result == llvm::APFloat::opOK && isExact) {
12303 if (IsLiteral)
return;
12304 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
12310 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12313 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12314 : diag::warn_impcast_float_to_integer_out_of_range,
12317 unsigned DiagID = 0;
12320 DiagID = diag::warn_impcast_literal_float_to_integer;
12321 }
else if (IntegerValue == 0) {
12322 if (
Value.isZero()) {
12324 diag::warn_impcast_float_integer, PruneWarnings);
12327 DiagID = diag::warn_impcast_float_to_integer_zero;
12329 if (IntegerValue.isUnsigned()) {
12330 if (!IntegerValue.isMaxValue()) {
12332 diag::warn_impcast_float_integer, PruneWarnings);
12335 if (!IntegerValue.isMaxSignedValue() &&
12336 !IntegerValue.isMinSignedValue()) {
12338 diag::warn_impcast_float_integer, PruneWarnings);
12342 DiagID = diag::warn_impcast_float_to_integer;
12347 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12349 IntegerValue.toString(PrettyTargetValue);
12351 if (PruneWarnings) {
12354 << E->
getType() <<
T.getUnqualifiedType()
12355 << PrettySourceValue << PrettyTargetValue
12359 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12368 "Must be compound assignment operation");
12379 ->getComputationResultType()
12386 if (ResultBT->isInteger())
12388 E->
getExprLoc(), diag::warn_impcast_float_integer);
12390 if (!ResultBT->isFloatingPoint())
12399 diag::warn_impcast_float_result_precision);
12404 if (!Range.Width)
return "0";
12406 llvm::APSInt ValueInRange =
Value;
12407 ValueInRange.setIsSigned(!Range.NonNegative);
12408 ValueInRange = ValueInRange.trunc(Range.Width);
12409 return toString(ValueInRange, 10);
12419 const Type *Source =
12421 if (
Target->isDependentType())
12424 const auto *FloatCandidateBT =
12425 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12426 const Type *BoolCandidateType = ToBool ?
Target : Source;
12429 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12434 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12440 S, TheCall->
getArg(I - 1),
false));
12442 S, TheCall->
getArg(I + 1),
false));
12447 diag::warn_impcast_floating_point_to_bool);
12462 if (!IsGNUNullExpr && !HasNullPtrType)
12466 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12467 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12470 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12483 if (IsGNUNullExpr && Loc.
isMacroID()) {
12486 if (MacroName ==
"NULL")
12494 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12508 const char FirstLiteralCharacter =
12510 if (FirstLiteralCharacter ==
'0')
12516 if (CC.
isValid() &&
T->isCharType()) {
12517 const char FirstContextCharacter =
12519 if (FirstContextCharacter ==
'{')
12527 const auto *IL = dyn_cast<IntegerLiteral>(E);
12529 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12530 if (UO->getOpcode() == UO_Minus)
12531 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12542 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12546 if (Opc == BO_Shl) {
12549 if (LHS && LHS->getValue() == 0)
12550 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12552 RHS->getValue().isNonNegative() &&
12554 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12555 << (Result.Val.getInt() != 0);
12557 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12564 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12569 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12570 (RHS->getValue() == 0 || RHS->getValue() == 1))
12573 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12574 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12582 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12588 if (Source->isChar16Type() &&
Target->isChar32Type())
12594 llvm::APSInt
Value(32);
12595 Value = Result.Val.getInt();
12596 bool IsASCII =
Value <= 0x7F;
12597 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12598 bool ConversionPreservesSemantics =
12599 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12601 if (!ConversionPreservesSemantics) {
12602 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12603 const llvm::APSInt &
Value) {
12604 if (
T->isChar8Type())
12605 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12606 if (
T->isChar16Type())
12607 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12608 assert(
T->isChar32Type());
12609 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12612 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12621 LosesPrecision ? diag::warn_impcast_unicode_precision
12622 : diag::warn_impcast_unicode_char_type);
12627 From =
Context.getCanonicalType(From);
12628 To =
Context.getCanonicalType(To);
12631 From = MaybePointee;
12638 if (FromFn->getCFIUncheckedCalleeAttr() &&
12639 !ToFn->getCFIUncheckedCalleeAttr())
12647 bool *ICContext,
bool IsListInit) {
12652 if (Source ==
Target)
return;
12653 if (
Target->isDependentType())
return;
12663 if (Source->isAtomicType())
12667 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12673 diag::warn_impcast_string_literal_to_bool);
12679 diag::warn_impcast_objective_c_literal_to_bool);
12681 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12691 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12694 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12696 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12705 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12707 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12712 if (
Target->isSveVLSBuiltinType() &&
12719 if (
Target->isRVVVLSBuiltinType() &&
12729 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12737 diag::warn_hlsl_impcast_vector_truncation);
12749 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
12750 Target = VecTy->getElementType().getTypePtr();
12753 if (
Target->isScalarType())
12754 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
12762 diag::warn_hlsl_impcast_matrix_truncation);
12773 ? diag::err_impcast_complex_scalar
12774 : diag::warn_impcast_complex_scalar);
12781 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12787 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12790 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12792 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12834 else if (Order < 0) {
12844 if (TargetBT && TargetBT->
isInteger()) {
12871 diag::warn_impcast_floating_point_to_bool);
12879 if (Source->isFixedPointType()) {
12880 if (
Target->isUnsaturatedFixedPointType()) {
12884 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12885 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
12886 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
12889 PDiag(diag::warn_impcast_fixed_point_range)
12890 <<
Value.toString() <<
T
12896 }
else if (
Target->isIntegerType()) {
12900 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12903 llvm::APSInt IntResult = FXResult.convertToInt(
12904 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
12909 PDiag(diag::warn_impcast_fixed_point_range)
12910 << FXResult.toString() <<
T
12917 }
else if (
Target->isUnsaturatedFixedPointType()) {
12918 if (Source->isIntegerType()) {
12925 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12930 PDiag(diag::warn_impcast_fixed_point_range)
12951 unsigned int SourcePrecision =
SourceRange->Width;
12955 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12958 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12959 SourcePrecision > TargetPrecision) {
12961 if (std::optional<llvm::APSInt> SourceInt =
12966 llvm::APFloat TargetFloatValue(
12968 llvm::APFloat::opStatus ConversionStatus =
12969 TargetFloatValue.convertFromAPInt(
12971 llvm::APFloat::rmNearestTiesToEven);
12973 if (ConversionStatus != llvm::APFloat::opOK) {
12975 SourceInt->toString(PrettySourceValue, 10);
12977 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12981 PDiag(diag::warn_impcast_integer_float_precision_constant)
12982 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12988 diag::warn_impcast_integer_float_precision);
12997 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13002 if (
Target->isBooleanType())
13006 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13010 if (!Source->isIntegerType() || !
Target->isIntegerType())
13015 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13018 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13021 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13026 if (!LikelySourceRange)
13029 IntRange SourceTypeRange =
13030 IntRange::forTargetOfCanonicalType(
Context, Source);
13031 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13033 if (LikelySourceRange->Width > TargetRange.Width) {
13039 llvm::APSInt
Value(32);
13049 PDiag(diag::warn_impcast_integer_precision_constant)
13050 << PrettySourceValue << PrettyTargetValue
13060 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13061 if (UO->getOpcode() == UO_Minus)
13063 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
13066 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13070 diag::warn_impcast_integer_precision);
13073 if (TargetRange.Width > SourceTypeRange.Width) {
13074 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13075 if (UO->getOpcode() == UO_Minus)
13076 if (Source->isUnsignedIntegerType()) {
13077 if (
Target->isUnsignedIntegerType())
13079 diag::warn_impcast_high_order_zero_bits);
13080 if (
Target->isSignedIntegerType())
13082 diag::warn_impcast_nonnegative_result);
13086 if (TargetRange.Width == LikelySourceRange->Width &&
13087 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13088 Source->isSignedIntegerType()) {
13102 PDiag(diag::warn_impcast_integer_precision_constant)
13103 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13113 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13114 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13115 LikelySourceRange->Width == TargetRange.Width))) {
13119 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13121 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13125 unsigned DiagID = diag::warn_impcast_integer_sign;
13133 DiagID = diag::warn_impcast_integer_sign_conditional;
13150 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13152 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13153 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13154 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13155 TargetEnum->getDecl()->hasNameForLinkage() &&
13156 SourceEnum != TargetEnum) {
13161 diag::warn_impcast_different_enum_types);
13175 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13188 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13189 TrueExpr = BCO->getCommon();
13191 bool Suspicious =
false;
13195 if (
T->isBooleanType())
13200 if (!Suspicious)
return;
13203 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13210 Suspicious =
false;
13215 E->
getType(), CC, &Suspicious);
13232struct AnalyzeImplicitConversionsWorkItem {
13241 bool ExtraCheckForImplicitConversion,
13244 WorkList.push_back({E, CC,
false});
13246 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
13253 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13255 Expr *OrigE = Item.E;
13274 Expr *SourceExpr = E;
13279 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13280 if (
auto *Src = OVE->getSourceExpr())
13283 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13284 if (UO->getOpcode() == UO_Not &&
13285 UO->getSubExpr()->isKnownToHaveBooleanValue())
13286 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13290 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13291 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13292 BO->getLHS()->isKnownToHaveBooleanValue() &&
13293 BO->getRHS()->isKnownToHaveBooleanValue() &&
13294 BO->getLHS()->HasSideEffects(S.
Context) &&
13295 BO->getRHS()->HasSideEffects(S.
Context)) {
13306 if (SR.str() ==
"&" || SR.str() ==
"|") {
13308 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13309 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13312 BO->getOperatorLoc(),
13313 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13314 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13316 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13334 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13340 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13355 for (
auto *SE : POE->semantics())
13356 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13357 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13361 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13362 E = CE->getSubExpr();
13368 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13369 if (InitListE->getNumInits() == 1) {
13370 E = InitListE->getInit(0);
13377 WorkList.push_back({E, CC, IsListInit});
13381 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13382 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13386 if (OutArgE->isInOut())
13387 WorkList.push_back(
13388 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13389 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13395 if (BO->isComparisonOp())
13399 if (BO->getOpcode() == BO_Assign)
13402 if (BO->isAssignmentOp())
13418 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13420 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13424 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13425 if (ChildExpr == CSE->getOperand())
13431 if (IsLogicalAndOperator &&
13436 WorkList.push_back({ChildExpr, CC, IsListInit});
13450 if (
U->getOpcode() == UO_LNot) {
13452 }
else if (
U->getOpcode() != UO_AddrOf) {
13453 if (
U->getSubExpr()->getType()->isAtomicType())
13454 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13455 diag::warn_atomic_implicit_seq_cst);
13466 WorkList.push_back({OrigE, CC, IsListInit});
13467 while (!WorkList.empty())
13479 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13482 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13483 if (!M->getMemberDecl()->getType()->isReferenceType())
13485 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13486 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13488 FD =
Call->getDirectCallee();
13497 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13511 if (
SM.isMacroBodyExpansion(Loc))
13513 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13537 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13538 : diag::warn_this_bool_conversion;
13543 bool IsAddressOf =
false;
13545 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13546 if (UO->getOpcode() != UO_AddrOf)
13548 IsAddressOf =
true;
13549 E = UO->getSubExpr();
13553 unsigned DiagID = IsCompare
13554 ? diag::warn_address_of_reference_null_compare
13555 : diag::warn_address_of_reference_bool_conversion;
13563 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13566 llvm::raw_string_ostream S(Str);
13568 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13569 : diag::warn_cast_nonnull_to_bool;
13572 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13577 if (
auto *Callee =
Call->getDirectCallee()) {
13578 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13579 ComplainAboutNonnullParamOrCall(A);
13588 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13589 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13590 MRecordDecl && MRecordDecl->isLambda()) {
13593 << MRecordDecl->getSourceRange() << Range << IsEqual;
13603 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13604 D = M->getMemberDecl();
13612 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13615 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13616 ComplainAboutNonnullParamOrCall(A);
13620 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13624 auto ParamIter = llvm::find(FD->
parameters(), PV);
13626 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13630 ComplainAboutNonnullParamOrCall(
NonNull);
13635 if (ArgNo.getASTIndex() == ParamNo) {
13636 ComplainAboutNonnullParamOrCall(
NonNull);
13646 const bool IsArray =
T->isArrayType();
13647 const bool IsFunction =
T->isFunctionType();
13650 if (IsAddressOf && IsFunction) {
13655 if (!IsAddressOf && !IsFunction && !IsArray)
13660 llvm::raw_string_ostream S(Str);
13663 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13664 : diag::warn_impcast_pointer_to_bool;
13671 DiagType = AddressOf;
13672 else if (IsFunction)
13673 DiagType = FunctionPointer;
13675 DiagType = ArrayPointer;
13677 llvm_unreachable(
"Could not determine diagnostic.");
13679 << Range << IsEqual;
13692 if (ReturnType.
isNull())
13730 CheckArrayAccess(E);
13740void Sema::CheckForIntOverflow (
const Expr *E) {
13742 SmallVector<const Expr *, 2> Exprs(1, E);
13745 const Expr *OriginalE = Exprs.pop_back_val();
13753 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13754 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13757 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13758 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13759 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13761 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13762 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13763 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13764 Exprs.push_back(Temporary->getSubExpr());
13765 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13766 Exprs.push_back(Array->getIdx());
13767 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13768 Exprs.push_back(Compound->getInitializer());
13769 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13770 New &&
New->isArray()) {
13771 if (
auto ArraySize =
New->getArraySize())
13772 Exprs.push_back(*ArraySize);
13773 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13774 Exprs.push_back(MTE->getSubExpr());
13775 }
while (!Exprs.empty());
13783 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13790 class SequenceTree {
13792 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13793 unsigned Parent : 31;
13794 LLVM_PREFERRED_TYPE(
bool)
13795 unsigned Merged : 1;
13797 SmallVector<Value, 8> Values;
13803 friend class SequenceTree;
13807 explicit Seq(
unsigned N) : Index(N) {}
13810 Seq() : Index(0) {}
13813 SequenceTree() { Values.push_back(
Value(0)); }
13814 Seq root()
const {
return Seq(0); }
13819 Seq allocate(
Seq Parent) {
13820 Values.push_back(
Value(Parent.Index));
13821 return Seq(Values.size() - 1);
13826 Values[S.Index].Merged =
true;
13832 bool isUnsequenced(
Seq Cur,
Seq Old) {
13833 unsigned C = representative(Cur.Index);
13834 unsigned Target = representative(Old.Index);
13838 C = Values[
C].Parent;
13845 unsigned representative(
unsigned K) {
13846 if (Values[K].Merged)
13848 return Values[K].Parent = representative(Values[K].Parent);
13854 using Object =
const NamedDecl *;
13868 UK_ModAsSideEffect,
13870 UK_Count = UK_ModAsSideEffect + 1
13876 const Expr *UsageExpr =
nullptr;
13877 SequenceTree::Seq
Seq;
13883 Usage Uses[UK_Count];
13886 bool Diagnosed =
false;
13890 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13898 UsageInfoMap UsageMap;
13901 SequenceTree::Seq Region;
13905 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
13909 SmallVectorImpl<const Expr *> &WorkList;
13916 struct SequencedSubexpression {
13917 SequencedSubexpression(SequenceChecker &
Self)
13918 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
13919 Self.ModAsSideEffect = &ModAsSideEffect;
13922 ~SequencedSubexpression() {
13923 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13927 UsageInfo &UI =
Self.UsageMap[M.first];
13928 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13929 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13930 SideEffectUsage = M.second;
13932 Self.ModAsSideEffect = OldModAsSideEffect;
13935 SequenceChecker &
Self;
13936 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
13937 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
13944 class EvaluationTracker {
13946 EvaluationTracker(SequenceChecker &
Self)
13948 Self.EvalTracker =
this;
13951 ~EvaluationTracker() {
13952 Self.EvalTracker = Prev;
13954 Prev->EvalOK &= EvalOK;
13957 bool evaluate(
const Expr *E,
bool &
Result) {
13962 Self.SemaRef.isConstantEvaluatedContext());
13967 SequenceChecker &
Self;
13968 EvaluationTracker *Prev;
13969 bool EvalOK =
true;
13970 } *EvalTracker =
nullptr;
13974 Object getObject(
const Expr *E,
bool Mod)
const {
13976 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
13977 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13978 return getObject(UO->getSubExpr(), Mod);
13979 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
13980 if (BO->getOpcode() == BO_Comma)
13981 return getObject(BO->getRHS(), Mod);
13982 if (Mod && BO->isAssignmentOp())
13983 return getObject(BO->getLHS(), Mod);
13984 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
13987 return ME->getMemberDecl();
13988 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
13997 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13999 Usage &U = UI.Uses[UK];
14000 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14004 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14005 ModAsSideEffect->push_back(std::make_pair(O, U));
14007 U.UsageExpr = UsageExpr;
14017 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
14018 UsageKind OtherKind,
bool IsModMod) {
14022 const Usage &U = UI.Uses[OtherKind];
14023 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14026 const Expr *Mod = U.UsageExpr;
14027 const Expr *ModOrUse = UsageExpr;
14028 if (OtherKind == UK_Use)
14029 std::swap(Mod, ModOrUse);
14033 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14034 : diag::warn_unsequenced_mod_use)
14035 << O << SourceRange(ModOrUse->
getExprLoc()));
14036 UI.Diagnosed =
true;
14065 void notePreUse(Object O,
const Expr *UseExpr) {
14066 UsageInfo &UI = UsageMap[O];
14068 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14071 void notePostUse(Object O,
const Expr *UseExpr) {
14072 UsageInfo &UI = UsageMap[O];
14073 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14075 addUsage(O, UI, UseExpr, UK_Use);
14078 void notePreMod(Object O,
const Expr *ModExpr) {
14079 UsageInfo &UI = UsageMap[O];
14081 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14082 checkUsage(O, UI, ModExpr, UK_Use,
false);
14085 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
14086 UsageInfo &UI = UsageMap[O];
14087 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14089 addUsage(O, UI, ModExpr, UK);
14093 SequenceChecker(Sema &S,
const Expr *E,
14094 SmallVectorImpl<const Expr *> &WorkList)
14095 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14099 (void)this->WorkList;
14102 void VisitStmt(
const Stmt *S) {
14106 void VisitExpr(
const Expr *E) {
14108 Base::VisitStmt(E);
14111 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14112 for (
auto *Sub : CSE->
children()) {
14113 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14128 void VisitCastExpr(
const CastExpr *E) {
14140 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14141 const Expr *SequencedAfter) {
14142 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14143 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14144 SequenceTree::Seq OldRegion = Region;
14147 SequencedSubexpression SeqBefore(*
this);
14148 Region = BeforeRegion;
14149 Visit(SequencedBefore);
14152 Region = AfterRegion;
14153 Visit(SequencedAfter);
14155 Region = OldRegion;
14157 Tree.merge(BeforeRegion);
14158 Tree.merge(AfterRegion);
14161 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14166 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14173 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14174 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14175 void VisitBinPtrMem(
const BinaryOperator *BO) {
14180 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14187 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14188 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14189 void VisitBinShlShr(
const BinaryOperator *BO) {
14193 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14200 void VisitBinComma(
const BinaryOperator *BO) {
14205 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14208 void VisitBinAssign(
const BinaryOperator *BO) {
14209 SequenceTree::Seq RHSRegion;
14210 SequenceTree::Seq LHSRegion;
14212 RHSRegion = Tree.allocate(Region);
14213 LHSRegion = Tree.allocate(Region);
14215 RHSRegion = Region;
14216 LHSRegion = Region;
14218 SequenceTree::Seq OldRegion = Region;
14234 SequencedSubexpression SeqBefore(*
this);
14235 Region = RHSRegion;
14239 Region = LHSRegion;
14243 notePostUse(O, BO);
14247 Region = LHSRegion;
14251 notePostUse(O, BO);
14253 Region = RHSRegion;
14261 Region = OldRegion;
14265 : UK_ModAsSideEffect);
14267 Tree.merge(RHSRegion);
14268 Tree.merge(LHSRegion);
14272 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14273 VisitBinAssign(CAO);
14276 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14277 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14278 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14281 return VisitExpr(UO);
14289 : UK_ModAsSideEffect);
14292 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14293 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14294 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14297 return VisitExpr(UO);
14301 notePostMod(O, UO, UK_ModAsSideEffect);
14304 void VisitBinLOr(
const BinaryOperator *BO) {
14310 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14311 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14312 SequenceTree::Seq OldRegion = Region;
14314 EvaluationTracker Eval(*
this);
14316 SequencedSubexpression Sequenced(*
this);
14317 Region = LHSRegion;
14324 bool EvalResult =
false;
14325 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14326 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14327 if (ShouldVisitRHS) {
14328 Region = RHSRegion;
14332 Region = OldRegion;
14333 Tree.merge(LHSRegion);
14334 Tree.merge(RHSRegion);
14337 void VisitBinLAnd(
const BinaryOperator *BO) {
14343 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14344 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14345 SequenceTree::Seq OldRegion = Region;
14347 EvaluationTracker Eval(*
this);
14349 SequencedSubexpression Sequenced(*
this);
14350 Region = LHSRegion;
14356 bool EvalResult =
false;
14357 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14358 bool ShouldVisitRHS = !EvalOK || EvalResult;
14359 if (ShouldVisitRHS) {
14360 Region = RHSRegion;
14364 Region = OldRegion;
14365 Tree.merge(LHSRegion);
14366 Tree.merge(RHSRegion);
14369 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14374 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14390 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14391 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14392 SequenceTree::Seq OldRegion = Region;
14394 EvaluationTracker Eval(*
this);
14396 SequencedSubexpression Sequenced(*
this);
14397 Region = ConditionRegion;
14407 bool EvalResult =
false;
14408 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14409 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14410 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14411 if (ShouldVisitTrueExpr) {
14412 Region = TrueRegion;
14415 if (ShouldVisitFalseExpr) {
14416 Region = FalseRegion;
14420 Region = OldRegion;
14421 Tree.merge(ConditionRegion);
14422 Tree.merge(TrueRegion);
14423 Tree.merge(FalseRegion);
14426 void VisitCallExpr(
const CallExpr *CE) {
14438 SequencedSubexpression Sequenced(*
this);
14443 SequenceTree::Seq CalleeRegion;
14444 SequenceTree::Seq OtherRegion;
14445 if (SemaRef.getLangOpts().CPlusPlus17) {
14446 CalleeRegion = Tree.allocate(Region);
14447 OtherRegion = Tree.allocate(Region);
14449 CalleeRegion = Region;
14450 OtherRegion = Region;
14452 SequenceTree::Seq OldRegion = Region;
14455 Region = CalleeRegion;
14457 SequencedSubexpression Sequenced(*this);
14458 Visit(CE->getCallee());
14460 Visit(CE->getCallee());
14464 Region = OtherRegion;
14468 Region = OldRegion;
14470 Tree.merge(CalleeRegion);
14471 Tree.merge(OtherRegion);
14489 return VisitCallExpr(CXXOCE);
14500 case OO_MinusEqual:
14502 case OO_SlashEqual:
14503 case OO_PercentEqual:
14504 case OO_CaretEqual:
14507 case OO_LessLessEqual:
14508 case OO_GreaterGreaterEqual:
14509 SequencingKind = RHSBeforeLHS;
14513 case OO_GreaterGreater:
14519 SequencingKind = LHSBeforeRHS;
14523 SequencingKind = LHSBeforeRest;
14527 SequencingKind = NoSequencing;
14531 if (SequencingKind == NoSequencing)
14532 return VisitCallExpr(CXXOCE);
14535 SequencedSubexpression Sequenced(*
this);
14538 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14539 "Should only get there with C++17 and above!");
14540 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14541 "Should only get there with an overloaded binary operator"
14542 " or an overloaded call operator!");
14544 if (SequencingKind == LHSBeforeRest) {
14545 assert(CXXOCE->getOperator() == OO_Call &&
14546 "We should only have an overloaded call operator here!");
14555 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14556 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14557 SequenceTree::Seq OldRegion = Region;
14559 assert(CXXOCE->getNumArgs() >= 1 &&
14560 "An overloaded call operator must have at least one argument"
14561 " for the postfix-expression!");
14562 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14563 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14564 CXXOCE->getNumArgs() - 1);
14568 Region = PostfixExprRegion;
14569 SequencedSubexpression Sequenced(*this);
14570 Visit(PostfixExpr);
14574 Region = ArgsRegion;
14575 for (const Expr *Arg : Args)
14578 Region = OldRegion;
14579 Tree.merge(PostfixExprRegion);
14580 Tree.merge(ArgsRegion);
14582 assert(CXXOCE->getNumArgs() == 2 &&
14583 "Should only have two arguments here!");
14584 assert((SequencingKind == LHSBeforeRHS ||
14585 SequencingKind == RHSBeforeLHS) &&
14586 "Unexpected sequencing kind!");
14590 const Expr *E1 = CXXOCE->getArg(0);
14591 const Expr *E2 = CXXOCE->getArg(1);
14592 if (SequencingKind == RHSBeforeLHS)
14595 return VisitSequencedExpressions(E1, E2);
14602 SequencedSubexpression Sequenced(*
this);
14605 return VisitExpr(CCE);
14608 SequenceExpressionsInOrder(
14614 return VisitExpr(ILE);
14617 SequenceExpressionsInOrder(ILE->
inits());
14629 SequenceTree::Seq Parent = Region;
14630 for (
const Expr *E : ExpressionList) {
14633 Region = Tree.allocate(Parent);
14634 Elts.push_back(Region);
14640 for (
unsigned I = 0; I < Elts.size(); ++I)
14641 Tree.merge(Elts[I]);
14645SequenceChecker::UsageInfo::UsageInfo() =
default;
14649void Sema::CheckUnsequencedOperations(
const Expr *E) {
14650 SmallVector<const Expr *, 8> WorkList;
14651 WorkList.push_back(E);
14652 while (!WorkList.empty()) {
14653 const Expr *Item = WorkList.pop_back_val();
14654 SequenceChecker(*
this, Item, WorkList);
14659 bool IsConstexpr) {
14662 CheckImplicitConversions(E, CheckLoc);
14664 CheckUnsequencedOperations(E);
14666 CheckForIntOverflow(E);
14679 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14683 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14687 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14701 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14705 bool CheckParameterNames) {
14706 bool HasInvalidParm =
false;
14708 assert(Param &&
"null in a parameter list");
14717 if (!Param->isInvalidDecl() &&
14719 diag::err_typecheck_decl_incomplete_type) ||
14721 diag::err_abstract_type_in_decl,
14723 Param->setInvalidDecl();
14724 HasInvalidParm =
true;
14729 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14733 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14741 QualType PType = Param->getOriginalType();
14749 if (!Param->isInvalidDecl()) {
14750 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14751 if (!ClassDecl->isInvalidDecl() &&
14752 !ClassDecl->hasIrrelevantDestructor() &&
14753 !ClassDecl->isDependentContext() &&
14754 ClassDecl->isParamDestroyedInCallee()) {
14766 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14767 if (!Param->getType().isConstQualified())
14768 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14772 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14777 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14778 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14783 if (!Param->isInvalidDecl() &&
14784 Param->getOriginalType()->isWebAssemblyTableType()) {
14785 Param->setInvalidDecl();
14786 HasInvalidParm =
true;
14787 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14791 return HasInvalidParm;
14794std::optional<std::pair<
14803static std::pair<CharUnits, CharUnits>
14811 if (
Base->isVirtual()) {
14818 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14825 DerivedType =
Base->getType();
14828 return std::make_pair(BaseAlignment, Offset);
14832static std::optional<std::pair<CharUnits, CharUnits>>
14838 return std::nullopt;
14843 return std::nullopt;
14847 CharUnits Offset = EltSize * IdxRes->getExtValue();
14850 return std::make_pair(P->first, P->second + Offset);
14856 return std::make_pair(
14857 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14863std::optional<std::pair<
14871 case Stmt::CStyleCastExprClass:
14872 case Stmt::CXXStaticCastExprClass:
14873 case Stmt::ImplicitCastExprClass: {
14875 const Expr *From = CE->getSubExpr();
14876 switch (CE->getCastKind()) {
14881 case CK_UncheckedDerivedToBase:
14882 case CK_DerivedToBase: {
14892 case Stmt::ArraySubscriptExprClass: {
14897 case Stmt::DeclRefExprClass: {
14901 if (!VD->getType()->isReferenceType()) {
14903 if (VD->hasDependentAlignment())
14912 case Stmt::MemberExprClass: {
14914 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14918 std::optional<std::pair<CharUnits, CharUnits>> P;
14927 return std::make_pair(P->first,
14930 case Stmt::UnaryOperatorClass: {
14940 case Stmt::BinaryOperatorClass: {
14952 return std::nullopt;
14957std::optional<std::pair<
14966 case Stmt::CStyleCastExprClass:
14967 case Stmt::CXXStaticCastExprClass:
14968 case Stmt::ImplicitCastExprClass: {
14970 const Expr *From = CE->getSubExpr();
14971 switch (CE->getCastKind()) {
14976 case CK_ArrayToPointerDecay:
14978 case CK_UncheckedDerivedToBase:
14979 case CK_DerivedToBase: {
14989 case Stmt::CXXThisExprClass: {
14994 case Stmt::UnaryOperatorClass: {
15000 case Stmt::BinaryOperatorClass: {
15009 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15010 std::swap(LHS, RHS);
15020 return std::nullopt;
15025 std::optional<std::pair<CharUnits, CharUnits>> P =
15029 return P->first.alignmentAtOffset(P->second);
15047 if (!DestPtr)
return;
15053 if (DestAlign.
isOne())
return;
15057 if (!SrcPtr)
return;
15068 if (SrcAlign >= DestAlign)
return;
15073 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15077void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15079 bool AllowOnePastEnd,
bool IndexNegated) {
15088 const Type *EffectiveType =
15092 Context.getAsConstantArrayType(BaseExpr->
getType());
15095 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15097 const Type *BaseType =
15099 bool IsUnboundedArray =
15101 Context, StrictFlexArraysLevel,
15104 (!IsUnboundedArray && BaseType->isDependentType()))
15112 if (IndexNegated) {
15113 index.setIsUnsigned(
false);
15117 if (IsUnboundedArray) {
15120 if (
index.isUnsigned() || !
index.isNegative()) {
15122 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15124 if (
index.getBitWidth() < AddrBits)
15126 std::optional<CharUnits> ElemCharUnits =
15127 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15130 if (!ElemCharUnits || ElemCharUnits->isZero())
15132 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15137 if (
index.getActiveBits() <= AddrBits) {
15139 llvm::APInt Product(
index);
15141 Product = Product.umul_ov(ElemBytes, Overflow);
15142 if (!Overflow && Product.getActiveBits() <= AddrBits)
15148 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15149 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15151 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15152 MaxElems = MaxElems.udiv(ElemBytes);
15155 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15156 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15161 PDiag(DiagID) << index << AddrBits
15162 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15163 << ElemBytes << MaxElems
15164 << MaxElems.getZExtValue()
15167 const NamedDecl *ND =
nullptr;
15169 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15171 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15173 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15174 ND = ME->getMemberDecl();
15178 PDiag(diag::note_array_declared_here) << ND);
15183 if (index.isUnsigned() || !index.isNegative()) {
15193 llvm::APInt size = ArrayTy->
getSize();
15195 if (BaseType != EffectiveType) {
15203 if (!ptrarith_typesize)
15204 ptrarith_typesize =
Context.getCharWidth();
15206 if (ptrarith_typesize != array_typesize) {
15208 uint64_t ratio = array_typesize / ptrarith_typesize;
15212 if (ptrarith_typesize * ratio == array_typesize)
15213 size *= llvm::APInt(size.getBitWidth(), ratio);
15217 if (size.getBitWidth() > index.getBitWidth())
15218 index = index.zext(size.getBitWidth());
15219 else if (size.getBitWidth() < index.getBitWidth())
15220 size = size.zext(index.getBitWidth());
15226 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15233 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15235 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15236 SourceLocation IndexLoc =
15238 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15243 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15244 : diag::warn_ptr_arith_exceeds_bounds;
15245 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15246 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15250 << index << ArrayTy->
desugar() << CastMsg
15253 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15255 DiagID = diag::warn_ptr_arith_precedes_bounds;
15256 if (index.isNegative()) index = -index;
15263 const NamedDecl *ND =
nullptr;
15265 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15267 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15269 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15270 ND = ME->getMemberDecl();
15274 PDiag(diag::note_array_declared_here) << ND);
15277void Sema::CheckArrayAccess(
const Expr *
expr) {
15278 int AllowOnePastEnd = 0;
15280 expr =
expr->IgnoreParenImpCasts();
15281 switch (
expr->getStmtClass()) {
15282 case Stmt::ArraySubscriptExprClass: {
15285 AllowOnePastEnd > 0);
15289 case Stmt::MemberExprClass: {
15293 case Stmt::ArraySectionExprClass: {
15299 nullptr, AllowOnePastEnd > 0);
15302 case Stmt::UnaryOperatorClass: {
15318 case Stmt::ConditionalOperatorClass: {
15320 if (
const Expr *lhs = cond->
getLHS())
15321 CheckArrayAccess(lhs);
15322 if (
const Expr *rhs = cond->
getRHS())
15323 CheckArrayAccess(rhs);
15326 case Stmt::CXXOperatorCallExprClass: {
15328 for (
const auto *Arg : OCE->arguments())
15329 CheckArrayAccess(Arg);
15339 Expr *RHS,
bool isProperty) {
15351 S.
Diag(Loc, diag::warn_arc_literal_assign)
15353 << (isProperty ? 0 : 1)
15361 Expr *RHS,
bool isProperty) {
15364 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15365 S.
Diag(Loc, diag::warn_arc_retained_assign)
15367 << (isProperty ? 0 : 1)
15371 RHS =
cast->getSubExpr();
15413 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15442 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15443 Diag(Loc, diag::warn_arc_retained_property_assign)
15447 RHS =
cast->getSubExpr();
15470 bool StmtLineInvalid;
15471 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15473 if (StmtLineInvalid)
15476 bool BodyLineInvalid;
15477 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15479 if (BodyLineInvalid)
15483 if (StmtLine != BodyLine)
15498 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15507 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15511 const Stmt *PossibleBody) {
15517 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15518 StmtLoc = FS->getRParenLoc();
15519 Body = FS->getBody();
15520 DiagID = diag::warn_empty_for_body;
15521 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15522 StmtLoc = WS->getRParenLoc();
15523 Body = WS->getBody();
15524 DiagID = diag::warn_empty_while_body;
15529 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15553 if (!ProbableTypo) {
15554 bool BodyColInvalid;
15555 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15557 if (BodyColInvalid)
15560 bool StmtColInvalid;
15563 if (StmtColInvalid)
15566 if (BodyCol > StmtCol)
15567 ProbableTypo =
true;
15570 if (ProbableTypo) {
15572 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15580 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15592 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15594 RHSExpr = CE->
getArg(0);
15595 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15596 CXXSCE && CXXSCE->isXValue())
15597 RHSExpr = CXXSCE->getSubExpr();
15601 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15602 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15605 if (LHSDeclRef && RHSDeclRef) {
15612 auto D =
Diag(OpLoc, diag::warn_self_move)
15628 const Expr *LHSBase = LHSExpr;
15629 const Expr *RHSBase = RHSExpr;
15630 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15631 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15632 if (!LHSME || !RHSME)
15635 while (LHSME && RHSME) {
15642 LHSME = dyn_cast<MemberExpr>(LHSBase);
15643 RHSME = dyn_cast<MemberExpr>(RHSBase);
15646 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15647 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15648 if (LHSDeclRef && RHSDeclRef) {
15655 Diag(OpLoc, diag::warn_self_move)
15662 Diag(OpLoc, diag::warn_self_move)
15686 bool AreUnionMembers =
false) {
15690 assert(((Field1Parent->isStructureOrClassType() &&
15691 Field2Parent->isStructureOrClassType()) ||
15692 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15693 "Can't evaluate layout compatibility between a struct field and a "
15695 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15696 (AreUnionMembers && Field1Parent->isUnionType())) &&
15697 "AreUnionMembers should be 'true' for union fields (only).");
15711 if (Bits1 != Bits2)
15715 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15716 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15719 if (!AreUnionMembers &&
15731 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15732 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15734 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15735 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15740 return isLayoutCompatible(C, F1, F2);
15751 for (
auto *Field1 : RD1->
fields()) {
15752 auto I = UnmatchedFields.begin();
15753 auto E = UnmatchedFields.end();
15755 for ( ; I != E; ++I) {
15757 bool Result = UnmatchedFields.erase(*I);
15767 return UnmatchedFields.empty();
15793 if (
C.hasSameType(T1, T2))
15802 if (TC1 == Type::Enum)
15804 if (TC1 == Type::Record) {
15823 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15854 const ValueDecl **VD, uint64_t *MagicValue,
15855 bool isConstantEvaluated) {
15863 case Stmt::UnaryOperatorClass: {
15872 case Stmt::DeclRefExprClass: {
15878 case Stmt::IntegerLiteralClass: {
15880 llvm::APInt MagicValueAPInt = IL->
getValue();
15881 if (MagicValueAPInt.getActiveBits() <= 64) {
15882 *MagicValue = MagicValueAPInt.getZExtValue();
15888 case Stmt::BinaryConditionalOperatorClass:
15889 case Stmt::ConditionalOperatorClass: {
15894 isConstantEvaluated)) {
15904 case Stmt::BinaryOperatorClass: {
15907 TypeExpr = BO->
getRHS();
15937 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15940 bool isConstantEvaluated) {
15941 FoundWrongKind =
false;
15946 uint64_t MagicValue;
15948 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15952 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15953 if (I->getArgumentKind() != ArgumentKind) {
15954 FoundWrongKind =
true;
15957 TypeInfo.Type = I->getMatchingCType();
15958 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15959 TypeInfo.MustBeNull = I->getMustBeNull();
15970 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15971 if (I == MagicValues->end())
15980 bool LayoutCompatible,
15982 if (!TypeTagForDatatypeMagicValues)
15983 TypeTagForDatatypeMagicValues.reset(
15984 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15987 (*TypeTagForDatatypeMagicValues)[Magic] =
16003 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16004 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16005 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16006 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16009void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16012 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16013 bool IsPointerAttr = Attr->getIsPointer();
16016 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16017 if (TypeTagIdxAST >= ExprArgs.size()) {
16018 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16019 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16022 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16023 bool FoundWrongKind;
16026 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16028 if (FoundWrongKind)
16030 diag::warn_type_tag_for_datatype_wrong_kind)
16036 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16037 if (ArgumentIdxAST >= ExprArgs.size()) {
16038 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16039 << 1 << Attr->getArgumentIdx().getSourceIndex();
16042 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16043 if (IsPointerAttr) {
16045 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16046 if (ICE->getType()->isVoidPointerType() &&
16047 ICE->getCastKind() == CK_BitCast)
16048 ArgumentExpr = ICE->getSubExpr();
16050 QualType ArgumentType = ArgumentExpr->
getType();
16056 if (TypeInfo.MustBeNull) {
16061 diag::warn_type_safety_null_pointer_required)
16069 QualType RequiredType = TypeInfo.Type;
16071 RequiredType =
Context.getPointerType(RequiredType);
16073 bool mismatch =
false;
16074 if (!TypeInfo.LayoutCompatible) {
16075 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16096 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16097 << ArgumentType << ArgumentKind
16098 << TypeInfo.LayoutCompatible << RequiredType
16116 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16124 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
16130 auto &MisalignedMembersForExpr =
16132 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16133 if (MA != MisalignedMembersForExpr.end() &&
16134 (
T->isDependentType() ||
T->isIntegerType() ||
16135 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
16137 T->getPointeeType()) <= MA->Alignment))))
16138 MisalignedMembersForExpr.erase(MA);
16147 const auto *ME = dyn_cast<MemberExpr>(E);
16159 bool AnyIsPacked =
false;
16161 QualType BaseType = ME->getBase()->getType();
16162 if (BaseType->isDependentType())
16166 auto *RD = BaseType->castAsRecordDecl();
16171 auto *FD = dyn_cast<FieldDecl>(MD);
16177 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16178 ReverseMemberChain.push_back(FD);
16181 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16183 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16190 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16201 if (ExpectedAlignment.
isOne())
16206 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16207 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16211 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16215 if (DRE && !TopME->
isArrow()) {
16218 CompleteObjectAlignment =
16219 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16223 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16226 CompleteObjectAlignment < ExpectedAlignment) {
16237 for (
FieldDecl *FDI : ReverseMemberChain) {
16238 if (FDI->hasAttr<PackedAttr>() ||
16239 FDI->getParent()->hasAttr<PackedAttr>()) {
16241 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16247 assert(FD &&
"We did not find a packed FieldDecl!");
16248 Action(E, FD->
getParent(), FD, Alignment);
16252void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16253 using namespace std::placeholders;
16256 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16280bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16281 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16294 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
16295 TheCall->
setType(VecTy0->getElementType());
16308 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16325 assert(!Args.empty() &&
"Should have at least one argument.");
16327 Expr *Arg0 = Args.front();
16330 auto EmitError = [&](
Expr *ArgI) {
16332 diag::err_typecheck_call_different_arg_types)
16333 << Arg0->
getType() << ArgI->getType();
16338 for (
Expr *ArgI : Args.drop_front())
16349 for (
Expr *ArgI : Args.drop_front()) {
16350 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16353 VecI->getElementType()) ||
16354 Vec0->getNumElements() != VecI->getNumElements()) {
16363std::optional<QualType>
16367 return std::nullopt;
16371 return std::nullopt;
16374 for (
int I = 0; I < 2; ++I) {
16378 return std::nullopt;
16379 Args[I] = Converted.
get();
16386 return std::nullopt;
16389 return std::nullopt;
16391 TheCall->
setArg(0, Args[0]);
16392 TheCall->
setArg(1, Args[1]);
16403 TheCall->
getArg(1), Loc) ||
16405 TheCall->
getArg(2), Loc))
16409 for (
int I = 0; I < 3; ++I) {
16414 Args[I] = Converted.
get();
16417 int ArgOrdinal = 1;
16418 for (
Expr *Arg : Args) {
16420 ArgTyRestr, ArgOrdinal++))
16427 for (
int I = 0; I < 3; ++I)
16428 TheCall->
setArg(I, Args[I]);
16434bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16446bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16455 diag::err_builtin_invalid_arg_type)
16456 << 1 << 2 << 1 << 1 << TyArg;
16470 Expr *Matrix = MatrixArg.
get();
16472 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16475 << 1 << 3 << 0 << 0
16482 QualType ResultType =
Context.getConstantMatrixType(
16483 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16486 TheCall->
setType(ResultType);
16489 TheCall->
setArg(0, Matrix);
16494static std::optional<unsigned>
16502 uint64_t
Dim =
Value->getZExtValue();
16518 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16520 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16528 unsigned PtrArgIdx = 0;
16529 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16530 Expr *RowsExpr = TheCall->
getArg(1);
16531 Expr *ColumnsExpr = TheCall->
getArg(2);
16532 Expr *StrideExpr = TheCall->
getArg(3);
16534 bool ArgError =
false;
16541 PtrExpr = PtrConv.
get();
16542 TheCall->
setArg(0, PtrExpr);
16549 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16550 QualType ElementTy;
16553 << PtrArgIdx + 1 << 0 << 5 << 0
16557 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16561 << PtrArgIdx + 1 << 0 << 5
16568 auto ApplyArgumentConversions = [
this](Expr *E) {
16577 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16579 RowsExpr = RowsConv.
get();
16580 TheCall->
setArg(1, RowsExpr);
16582 RowsExpr =
nullptr;
16584 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16586 ColumnsExpr = ColumnsConv.
get();
16587 TheCall->
setArg(2, ColumnsExpr);
16589 ColumnsExpr =
nullptr;
16600 std::optional<unsigned> MaybeRows;
16604 std::optional<unsigned> MaybeColumns;
16609 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16612 StrideExpr = StrideConv.
get();
16613 TheCall->
setArg(3, StrideExpr);
16616 if (std::optional<llvm::APSInt>
Value =
16619 if (Stride < *MaybeRows) {
16621 diag::err_builtin_matrix_stride_too_small);
16627 if (ArgError || !MaybeRows || !MaybeColumns)
16631 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16642 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16644 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16652 unsigned PtrArgIdx = 1;
16653 Expr *MatrixExpr = TheCall->
getArg(0);
16654 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16655 Expr *StrideExpr = TheCall->
getArg(2);
16657 bool ArgError =
false;
16663 MatrixExpr = MatrixConv.
get();
16664 TheCall->
setArg(0, MatrixExpr);
16671 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16674 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16682 PtrExpr = PtrConv.
get();
16683 TheCall->
setArg(1, PtrExpr);
16691 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16694 << PtrArgIdx + 1 << 0 << 5 << 0
16698 QualType ElementTy = PtrTy->getPointeeType();
16700 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16705 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16707 diag::err_builtin_matrix_pointer_arg_mismatch)
16708 << ElementTy << MatrixTy->getElementType();
16723 StrideExpr = StrideConv.
get();
16724 TheCall->
setArg(2, StrideExpr);
16729 if (std::optional<llvm::APSInt>
Value =
16732 if (Stride < MatrixTy->getNumRows()) {
16734 diag::err_builtin_matrix_stride_too_small);
16754 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16759 llvm::StringSet<> CalleeTCBs;
16760 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16761 CalleeTCBs.insert(A->getTCBName());
16762 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16763 CalleeTCBs.insert(A->getTCBName());
16767 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16768 StringRef CallerTCB = A->getTCBName();
16769 if (CalleeTCBs.count(CallerTCB) == 0) {
16770 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16771 << 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 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 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 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 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
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
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
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++ 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 character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
CharUnits - This is an opaque type for sizes expressed in character units.
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,...
@ 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.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
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 * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
UnresolvedSetImpl::iterator iterator
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isValidElementType(QualType T, const LangOptions &LangOpts)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
Pointer-authentication qualifiers.
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
bool isAddressDiscriminated() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
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)
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.
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 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...
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)
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 DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
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,...
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
A set of unresolved declarations.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
std::string getRepresentativeTypeName(ASTContext &C) const
MatchKind matchesType(ASTContext &C, QualType argTy) const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantLength() const
const char * toString() const
const char * getPosition() const
const OptionalFlag & isPrivate() const
bool hasValidLeftJustified() const
bool hasValidFieldWidth() const
bool hasValidSpacePrefix() const
const OptionalAmount & getPrecision() const
const OptionalFlag & hasSpacePrefix() const
bool usesPositionalArg() const
const OptionalFlag & isSensitive() const
const OptionalFlag & isLeftJustified() const
bool hasValidPrecision() const
const OptionalFlag & hasLeadingZeros() const
const OptionalFlag & hasAlternativeForm() const
bool hasValidLeadingZeros() const
void toString(raw_ostream &os) const
const PrintfConversionSpecifier & getConversionSpecifier() const
const OptionalFlag & hasPlusPrefix() const
const OptionalFlag & hasThousandsGrouping() const
bool hasValidThousandsGroupingPrefix() const
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const
Returns the builtin type that a data argument paired with this format specifier should have.
const OptionalFlag & isPublic() const
bool consumesDataArgument() const
bool hasValidPlusPrefix() const
bool hasValidAlternativeForm() const
bool consumesDataArgument() const
const ScanfConversionSpecifier & getConversionSpecifier() const
ArgType getArgType(ASTContext &Ctx) const
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
Defines the clang::TargetInfo interface.
__inline void unsigned int _2
Pieces specific to fprintf format strings.
Pieces specific to fscanf format strings.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
uint32_t Literal
Literals are represented as positive integers.
ComparisonResult
Indicates the result of a tentative comparison.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ After
Like System, but searched after the system directories.
@ FixIt
Parse and apply any fixits to the source.
bool GT(InterpState &S, CodePtr OpPC)
bool LT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
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
const FunctionProtoType * T
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 AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned Indentation
The number of spaces to use to indent each line.
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.