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);
3591 case Builtin::BI__builtin_allow_sanitize_check: {
3592 Expr *Arg = TheCall->
getArg(0);
3594 const StringLiteral *SanitizerName =
3596 if (!SanitizerName) {
3602 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
3603 .Cases({
"address",
"thread",
"memory",
"hwaddress",
3604 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
3608 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
3614 case Builtin::BI__builtin_counted_by_ref:
3615 if (BuiltinCountedByRef(TheCall))
3625 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3626 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3627 assert(
Context.getAuxTargetInfo() &&
3628 "Aux Target Builtin, but not an aux target?");
3630 if (CheckTSBuiltinFunctionCall(
3632 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3635 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3641 return TheCallResult;
3656 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3660 diag::err_argument_not_contiguous_bit_field)
3667 bool IsVariadic =
false;
3670 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3671 IsVariadic = BD->isVariadic();
3672 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3673 IsVariadic = OMD->isVariadic();
3680 bool HasImplicitThisParam,
bool IsVariadic,
3684 else if (IsVariadic)
3694 if (HasImplicitThisParam) {
3726 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
3727 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3728 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3729 Expr = ILE->getInit(0);
3739 const Expr *ArgExpr,
3743 S.
PDiag(diag::warn_null_arg)
3749 if (
auto nullability =
type->getNullability())
3760 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3766 llvm::SmallBitVector NonNullArgs;
3772 for (
const auto *Arg : Args)
3779 unsigned IdxAST = Idx.getASTIndex();
3780 if (IdxAST >= Args.size())
3782 if (NonNullArgs.empty())
3783 NonNullArgs.resize(Args.size());
3784 NonNullArgs.set(IdxAST);
3793 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3798 unsigned ParamIndex = 0;
3800 I != E; ++I, ++ParamIndex) {
3803 if (NonNullArgs.empty())
3804 NonNullArgs.resize(Args.size());
3806 NonNullArgs.set(ParamIndex);
3813 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3818 type = blockType->getPointeeType();
3832 if (NonNullArgs.empty())
3833 NonNullArgs.resize(Args.size());
3835 NonNullArgs.set(Index);
3844 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3845 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3846 if (NonNullArgs[ArgIndex])
3852 StringRef ParamName,
QualType ArgTy,
3875 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
3876 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
3880 if (ArgAlign < ParamAlign)
3881 Diag(Loc, diag::warn_param_mismatched_alignment)
3883 << ParamName << (FDecl !=
nullptr) << FDecl;
3887 const Expr *ThisArg,
3889 if (!FD || Args.empty())
3891 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3892 if (Idx == LifetimeCaptureByAttr::Global ||
3893 Idx == LifetimeCaptureByAttr::Unknown)
3895 if (IsMemberFunction && Idx == 0)
3897 return Args[Idx - IsMemberFunction];
3899 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3904 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3905 for (
int CapturingParamIdx :
Attr->params()) {
3908 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
3911 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3919 I + IsMemberFunction);
3921 if (IsMemberFunction) {
3929 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3942 llvm::SmallBitVector CheckedVarArgs;
3944 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
3946 CheckedVarArgs.resize(Args.size());
3947 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
3952 CheckedVarArgs.resize(Args.size());
3953 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
3960 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3964 : isa_and_nonnull<FunctionDecl>(FDecl)
3966 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3970 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3972 if (
const Expr *Arg = Args[ArgIdx]) {
3973 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3980 if (FDecl || Proto) {
3985 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3986 CheckArgumentWithTypeTag(I, Args, Loc);
3992 if (!Proto && FDecl) {
3994 if (isa_and_nonnull<FunctionProtoType>(FT))
4000 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4002 bool IsScalableArg =
false;
4003 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4005 if (
const Expr *Arg = Args[ArgIdx]) {
4009 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4017 IsScalableArg =
true;
4019 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4028 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4029 llvm::StringMap<bool> CallerFeatureMap;
4030 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4031 if (!CallerFeatureMap.contains(
"sme"))
4032 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4033 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4034 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4043 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4045 (IsScalableArg || IsScalableRet)) {
4046 bool IsCalleeStreaming =
4048 bool IsCalleeStreamingCompatible =
4052 if (!IsCalleeStreamingCompatible &&
4056 unsigned VL = LO.VScaleMin * 128;
4057 unsigned SVL = LO.VScaleStreamingMin * 128;
4058 bool IsVLMismatch = VL && SVL && VL != SVL;
4060 auto EmitDiag = [&](
bool IsArg) {
4064 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4065 << IsArg << IsCalleeStreaming << SVL << VL;
4068 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4069 << IsArg << SVL << VL;
4071 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4088 bool CallerHasZAState =
false;
4089 bool CallerHasZT0State =
false;
4091 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4093 CallerHasZAState =
true;
4095 CallerHasZT0State =
true;
4099 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4101 CallerHasZT0State |=
4103 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4109 Diag(Loc, diag::err_sme_za_call_no_za_state);
4112 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4116 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4117 Diag(Loc, diag::note_sme_use_preserves_za);
4122 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4123 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4124 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4125 if (!Arg->isValueDependent()) {
4127 if (Arg->EvaluateAsInt(Align,
Context)) {
4128 const llvm::APSInt &I = Align.
Val.
getInt();
4129 if (!I.isPowerOf2())
4130 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4131 << Arg->getSourceRange();
4134 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4160 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4161 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4163 checkCall(FDecl, Proto,
nullptr, Args,
true,
4172 IsMemberOperatorCall;
4178 Expr *ImplicitThis =
nullptr;
4183 ImplicitThis = Args[0];
4186 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4197 ThisType =
Context.getPointerType(ThisType);
4203 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4221 CheckAbsoluteValueFunction(TheCall, FDecl);
4222 CheckMaxUnsignedZero(TheCall, FDecl);
4223 CheckInfNaNFunction(TheCall, FDecl);
4234 case Builtin::BIstrlcpy:
4235 case Builtin::BIstrlcat:
4236 CheckStrlcpycatArguments(TheCall, FnInfo);
4238 case Builtin::BIstrncat:
4239 CheckStrncatArguments(TheCall, FnInfo);
4241 case Builtin::BIfree:
4242 CheckFreeArguments(TheCall);
4245 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4254 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4255 Ty =
V->getType().getNonReferenceType();
4256 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4257 Ty = F->getType().getNonReferenceType();
4294 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4297 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4299 case AtomicExpr::AO__c11_atomic_init:
4300 case AtomicExpr::AO__opencl_atomic_init:
4301 llvm_unreachable(
"There is no ordering argument for an init");
4303 case AtomicExpr::AO__c11_atomic_load:
4304 case AtomicExpr::AO__opencl_atomic_load:
4305 case AtomicExpr::AO__hip_atomic_load:
4306 case AtomicExpr::AO__atomic_load_n:
4307 case AtomicExpr::AO__atomic_load:
4308 case AtomicExpr::AO__scoped_atomic_load_n:
4309 case AtomicExpr::AO__scoped_atomic_load:
4310 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4311 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4313 case AtomicExpr::AO__c11_atomic_store:
4314 case AtomicExpr::AO__opencl_atomic_store:
4315 case AtomicExpr::AO__hip_atomic_store:
4316 case AtomicExpr::AO__atomic_store:
4317 case AtomicExpr::AO__atomic_store_n:
4318 case AtomicExpr::AO__scoped_atomic_store:
4319 case AtomicExpr::AO__scoped_atomic_store_n:
4320 case AtomicExpr::AO__atomic_clear:
4321 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4322 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4323 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4382 const unsigned NumForm = ClearByte + 1;
4383 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4384 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4392 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4393 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4394 "need to update code for modified forms");
4395 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4396 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4397 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4398 "need to update code for modified C11 atomics");
4399 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4400 Op <= AtomicExpr::AO__opencl_atomic_store;
4401 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4402 Op <= AtomicExpr::AO__hip_atomic_store;
4403 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4404 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4405 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4406 Op <= AtomicExpr::AO__c11_atomic_store) ||
4408 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4409 Op == AtomicExpr::AO__atomic_store_n ||
4410 Op == AtomicExpr::AO__atomic_exchange_n ||
4411 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4412 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4413 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4414 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4415 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4419 enum ArithOpExtraValueType {
4424 unsigned ArithAllows = AOEVT_None;
4427 case AtomicExpr::AO__c11_atomic_init:
4428 case AtomicExpr::AO__opencl_atomic_init:
4432 case AtomicExpr::AO__c11_atomic_load:
4433 case AtomicExpr::AO__opencl_atomic_load:
4434 case AtomicExpr::AO__hip_atomic_load:
4435 case AtomicExpr::AO__atomic_load_n:
4436 case AtomicExpr::AO__scoped_atomic_load_n:
4440 case AtomicExpr::AO__atomic_load:
4441 case AtomicExpr::AO__scoped_atomic_load:
4445 case AtomicExpr::AO__c11_atomic_store:
4446 case AtomicExpr::AO__opencl_atomic_store:
4447 case AtomicExpr::AO__hip_atomic_store:
4448 case AtomicExpr::AO__atomic_store:
4449 case AtomicExpr::AO__atomic_store_n:
4450 case AtomicExpr::AO__scoped_atomic_store:
4451 case AtomicExpr::AO__scoped_atomic_store_n:
4454 case AtomicExpr::AO__atomic_fetch_add:
4455 case AtomicExpr::AO__atomic_fetch_sub:
4456 case AtomicExpr::AO__atomic_add_fetch:
4457 case AtomicExpr::AO__atomic_sub_fetch:
4458 case AtomicExpr::AO__scoped_atomic_fetch_add:
4459 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4460 case AtomicExpr::AO__scoped_atomic_add_fetch:
4461 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4462 case AtomicExpr::AO__c11_atomic_fetch_add:
4463 case AtomicExpr::AO__c11_atomic_fetch_sub:
4464 case AtomicExpr::AO__opencl_atomic_fetch_add:
4465 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4466 case AtomicExpr::AO__hip_atomic_fetch_add:
4467 case AtomicExpr::AO__hip_atomic_fetch_sub:
4468 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4471 case AtomicExpr::AO__atomic_fetch_max:
4472 case AtomicExpr::AO__atomic_fetch_min:
4473 case AtomicExpr::AO__atomic_max_fetch:
4474 case AtomicExpr::AO__atomic_min_fetch:
4475 case AtomicExpr::AO__scoped_atomic_fetch_max:
4476 case AtomicExpr::AO__scoped_atomic_fetch_min:
4477 case AtomicExpr::AO__scoped_atomic_max_fetch:
4478 case AtomicExpr::AO__scoped_atomic_min_fetch:
4479 case AtomicExpr::AO__c11_atomic_fetch_max:
4480 case AtomicExpr::AO__c11_atomic_fetch_min:
4481 case AtomicExpr::AO__opencl_atomic_fetch_max:
4482 case AtomicExpr::AO__opencl_atomic_fetch_min:
4483 case AtomicExpr::AO__hip_atomic_fetch_max:
4484 case AtomicExpr::AO__hip_atomic_fetch_min:
4485 ArithAllows = AOEVT_FP;
4488 case AtomicExpr::AO__c11_atomic_fetch_and:
4489 case AtomicExpr::AO__c11_atomic_fetch_or:
4490 case AtomicExpr::AO__c11_atomic_fetch_xor:
4491 case AtomicExpr::AO__hip_atomic_fetch_and:
4492 case AtomicExpr::AO__hip_atomic_fetch_or:
4493 case AtomicExpr::AO__hip_atomic_fetch_xor:
4494 case AtomicExpr::AO__c11_atomic_fetch_nand:
4495 case AtomicExpr::AO__opencl_atomic_fetch_and:
4496 case AtomicExpr::AO__opencl_atomic_fetch_or:
4497 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4498 case AtomicExpr::AO__atomic_fetch_and:
4499 case AtomicExpr::AO__atomic_fetch_or:
4500 case AtomicExpr::AO__atomic_fetch_xor:
4501 case AtomicExpr::AO__atomic_fetch_nand:
4502 case AtomicExpr::AO__atomic_and_fetch:
4503 case AtomicExpr::AO__atomic_or_fetch:
4504 case AtomicExpr::AO__atomic_xor_fetch:
4505 case AtomicExpr::AO__atomic_nand_fetch:
4506 case AtomicExpr::AO__scoped_atomic_fetch_and:
4507 case AtomicExpr::AO__scoped_atomic_fetch_or:
4508 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4509 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4510 case AtomicExpr::AO__scoped_atomic_and_fetch:
4511 case AtomicExpr::AO__scoped_atomic_or_fetch:
4512 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4513 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4514 case AtomicExpr::AO__scoped_atomic_uinc_wrap:
4515 case AtomicExpr::AO__scoped_atomic_udec_wrap:
4519 case AtomicExpr::AO__c11_atomic_exchange:
4520 case AtomicExpr::AO__hip_atomic_exchange:
4521 case AtomicExpr::AO__opencl_atomic_exchange:
4522 case AtomicExpr::AO__atomic_exchange_n:
4523 case AtomicExpr::AO__scoped_atomic_exchange_n:
4527 case AtomicExpr::AO__atomic_exchange:
4528 case AtomicExpr::AO__scoped_atomic_exchange:
4532 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4533 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4534 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4535 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4536 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4537 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4541 case AtomicExpr::AO__atomic_compare_exchange:
4542 case AtomicExpr::AO__atomic_compare_exchange_n:
4543 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4544 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4548 case AtomicExpr::AO__atomic_test_and_set:
4549 Form = TestAndSetByte;
4552 case AtomicExpr::AO__atomic_clear:
4557 unsigned AdjustedNumArgs = NumArgs[Form];
4558 if ((IsOpenCL || IsHIP || IsScoped) &&
4559 Op != AtomicExpr::AO__opencl_atomic_init)
4562 if (Args.size() < AdjustedNumArgs) {
4563 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4564 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4567 }
else if (Args.size() > AdjustedNumArgs) {
4568 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4569 diag::err_typecheck_call_too_many_args)
4570 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4576 Expr *Ptr = Args[0];
4581 Ptr = ConvertedPtr.
get();
4584 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4594 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4600 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4606 }
else if (Form != Load && Form != LoadCopy) {
4608 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4614 if (Form != TestAndSetByte && Form != ClearByte) {
4617 diag::err_incomplete_type))
4620 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4621 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4631 pointerType->getPointeeType().getCVRQualifiers());
4641 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4650 auto IsAllowedValueType = [&](
QualType ValType,
4651 unsigned AllowedType) ->
bool {
4655 return AllowedType & AOEVT_Pointer;
4660 &
Context.getTargetInfo().getLongDoubleFormat() ==
4661 &llvm::APFloat::x87DoubleExtended())
4665 if (!IsAllowedValueType(ValType, ArithAllows)) {
4666 auto DID = ArithAllows & AOEVT_FP
4667 ? (ArithAllows & AOEVT_Pointer
4668 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4669 : diag::err_atomic_op_needs_atomic_int_or_fp)
4670 : diag::err_atomic_op_needs_atomic_int;
4677 diag::err_incomplete_type)) {
4683 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4694 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4710 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4722 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4725 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4731 bool IsPassedByAddress =
false;
4732 if (!IsC11 && !IsHIP && !IsN) {
4734 IsPassedByAddress =
true;
4739 APIOrderedArgs.push_back(Args[0]);
4743 APIOrderedArgs.push_back(Args[1]);
4749 APIOrderedArgs.push_back(Args[2]);
4750 APIOrderedArgs.push_back(Args[1]);
4753 APIOrderedArgs.push_back(Args[2]);
4754 APIOrderedArgs.push_back(Args[3]);
4755 APIOrderedArgs.push_back(Args[1]);
4758 APIOrderedArgs.push_back(Args[2]);
4759 APIOrderedArgs.push_back(Args[4]);
4760 APIOrderedArgs.push_back(Args[1]);
4761 APIOrderedArgs.push_back(Args[3]);
4764 APIOrderedArgs.push_back(Args[2]);
4765 APIOrderedArgs.push_back(Args[4]);
4766 APIOrderedArgs.push_back(Args[5]);
4767 APIOrderedArgs.push_back(Args[1]);
4768 APIOrderedArgs.push_back(Args[3]);
4770 case TestAndSetByte:
4772 APIOrderedArgs.push_back(Args[1]);
4776 APIOrderedArgs.append(Args.begin(), Args.end());
4783 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4785 if (i < NumVals[Form] + 1) {
4798 assert(Form != Load);
4800 Ty =
Context.getPointerDiffType();
4803 else if (Form ==
Copy || Form == Xchg) {
4804 if (IsPassedByAddress) {
4811 Expr *ValArg = APIOrderedArgs[i];
4818 AS = PtrTy->getPointeeType().getAddressSpace();
4827 if (IsPassedByAddress)
4847 APIOrderedArgs[i] = Arg.
get();
4852 SubExprs.push_back(Ptr);
4856 SubExprs.push_back(APIOrderedArgs[1]);
4859 case TestAndSetByte:
4861 SubExprs.push_back(APIOrderedArgs[1]);
4867 SubExprs.push_back(APIOrderedArgs[2]);
4868 SubExprs.push_back(APIOrderedArgs[1]);
4872 SubExprs.push_back(APIOrderedArgs[3]);
4873 SubExprs.push_back(APIOrderedArgs[1]);
4874 SubExprs.push_back(APIOrderedArgs[2]);
4877 SubExprs.push_back(APIOrderedArgs[3]);
4878 SubExprs.push_back(APIOrderedArgs[1]);
4879 SubExprs.push_back(APIOrderedArgs[4]);
4880 SubExprs.push_back(APIOrderedArgs[2]);
4883 SubExprs.push_back(APIOrderedArgs[4]);
4884 SubExprs.push_back(APIOrderedArgs[1]);
4885 SubExprs.push_back(APIOrderedArgs[5]);
4886 SubExprs.push_back(APIOrderedArgs[2]);
4887 SubExprs.push_back(APIOrderedArgs[3]);
4892 if (SubExprs.size() >= 2 && Form !=
Init) {
4893 std::optional<llvm::APSInt>
Success =
4894 SubExprs[1]->getIntegerConstantExpr(
Context);
4896 Diag(SubExprs[1]->getBeginLoc(),
4897 diag::warn_atomic_op_has_invalid_memory_order)
4898 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4899 << SubExprs[1]->getSourceRange();
4901 if (SubExprs.size() >= 5) {
4902 if (std::optional<llvm::APSInt> Failure =
4903 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4904 if (!llvm::is_contained(
4905 {llvm::AtomicOrderingCABI::relaxed,
4906 llvm::AtomicOrderingCABI::consume,
4907 llvm::AtomicOrderingCABI::acquire,
4908 llvm::AtomicOrderingCABI::seq_cst},
4909 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4910 Diag(SubExprs[3]->getBeginLoc(),
4911 diag::warn_atomic_op_has_invalid_memory_order)
4912 << 2 << SubExprs[3]->getSourceRange();
4919 auto *
Scope = Args[Args.size() - 1];
4920 if (std::optional<llvm::APSInt>
Result =
4922 if (!ScopeModel->isValid(
Result->getZExtValue()))
4923 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
4924 <<
Scope->getSourceRange();
4926 SubExprs.push_back(
Scope);
4932 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4933 Op == AtomicExpr::AO__c11_atomic_store ||
4934 Op == AtomicExpr::AO__opencl_atomic_load ||
4935 Op == AtomicExpr::AO__hip_atomic_load ||
4936 Op == AtomicExpr::AO__opencl_atomic_store ||
4937 Op == AtomicExpr::AO__hip_atomic_store) &&
4938 Context.AtomicUsesUnsupportedLibcall(AE))
4940 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4941 Op == AtomicExpr::AO__opencl_atomic_load ||
4942 Op == AtomicExpr::AO__hip_atomic_load)
4947 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4963 assert(Fn &&
"builtin call without direct callee!");
4979 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
4986 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4988 <<
Callee->getSourceRange();
4997 Expr *FirstArg = TheCall->
getArg(0);
5001 FirstArg = FirstArgResult.
get();
5002 TheCall->
setArg(0, FirstArg);
5014 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5021 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5051 QualType ResultType = ValType;
5056#define BUILTIN_ROW(x) \
5057 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5058 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5060 static const unsigned BuiltinIndices[][5] = {
5085 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5086 case 1: SizeIndex = 0;
break;
5087 case 2: SizeIndex = 1;
break;
5088 case 4: SizeIndex = 2;
break;
5089 case 8: SizeIndex = 3;
break;
5090 case 16: SizeIndex = 4;
break;
5102 unsigned BuiltinIndex, NumFixed = 1;
5103 bool WarnAboutSemanticsChange =
false;
5104 switch (BuiltinID) {
5105 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5106 case Builtin::BI__sync_fetch_and_add:
5107 case Builtin::BI__sync_fetch_and_add_1:
5108 case Builtin::BI__sync_fetch_and_add_2:
5109 case Builtin::BI__sync_fetch_and_add_4:
5110 case Builtin::BI__sync_fetch_and_add_8:
5111 case Builtin::BI__sync_fetch_and_add_16:
5115 case Builtin::BI__sync_fetch_and_sub:
5116 case Builtin::BI__sync_fetch_and_sub_1:
5117 case Builtin::BI__sync_fetch_and_sub_2:
5118 case Builtin::BI__sync_fetch_and_sub_4:
5119 case Builtin::BI__sync_fetch_and_sub_8:
5120 case Builtin::BI__sync_fetch_and_sub_16:
5124 case Builtin::BI__sync_fetch_and_or:
5125 case Builtin::BI__sync_fetch_and_or_1:
5126 case Builtin::BI__sync_fetch_and_or_2:
5127 case Builtin::BI__sync_fetch_and_or_4:
5128 case Builtin::BI__sync_fetch_and_or_8:
5129 case Builtin::BI__sync_fetch_and_or_16:
5133 case Builtin::BI__sync_fetch_and_and:
5134 case Builtin::BI__sync_fetch_and_and_1:
5135 case Builtin::BI__sync_fetch_and_and_2:
5136 case Builtin::BI__sync_fetch_and_and_4:
5137 case Builtin::BI__sync_fetch_and_and_8:
5138 case Builtin::BI__sync_fetch_and_and_16:
5142 case Builtin::BI__sync_fetch_and_xor:
5143 case Builtin::BI__sync_fetch_and_xor_1:
5144 case Builtin::BI__sync_fetch_and_xor_2:
5145 case Builtin::BI__sync_fetch_and_xor_4:
5146 case Builtin::BI__sync_fetch_and_xor_8:
5147 case Builtin::BI__sync_fetch_and_xor_16:
5151 case Builtin::BI__sync_fetch_and_nand:
5152 case Builtin::BI__sync_fetch_and_nand_1:
5153 case Builtin::BI__sync_fetch_and_nand_2:
5154 case Builtin::BI__sync_fetch_and_nand_4:
5155 case Builtin::BI__sync_fetch_and_nand_8:
5156 case Builtin::BI__sync_fetch_and_nand_16:
5158 WarnAboutSemanticsChange =
true;
5161 case Builtin::BI__sync_add_and_fetch:
5162 case Builtin::BI__sync_add_and_fetch_1:
5163 case Builtin::BI__sync_add_and_fetch_2:
5164 case Builtin::BI__sync_add_and_fetch_4:
5165 case Builtin::BI__sync_add_and_fetch_8:
5166 case Builtin::BI__sync_add_and_fetch_16:
5170 case Builtin::BI__sync_sub_and_fetch:
5171 case Builtin::BI__sync_sub_and_fetch_1:
5172 case Builtin::BI__sync_sub_and_fetch_2:
5173 case Builtin::BI__sync_sub_and_fetch_4:
5174 case Builtin::BI__sync_sub_and_fetch_8:
5175 case Builtin::BI__sync_sub_and_fetch_16:
5179 case Builtin::BI__sync_and_and_fetch:
5180 case Builtin::BI__sync_and_and_fetch_1:
5181 case Builtin::BI__sync_and_and_fetch_2:
5182 case Builtin::BI__sync_and_and_fetch_4:
5183 case Builtin::BI__sync_and_and_fetch_8:
5184 case Builtin::BI__sync_and_and_fetch_16:
5188 case Builtin::BI__sync_or_and_fetch:
5189 case Builtin::BI__sync_or_and_fetch_1:
5190 case Builtin::BI__sync_or_and_fetch_2:
5191 case Builtin::BI__sync_or_and_fetch_4:
5192 case Builtin::BI__sync_or_and_fetch_8:
5193 case Builtin::BI__sync_or_and_fetch_16:
5197 case Builtin::BI__sync_xor_and_fetch:
5198 case Builtin::BI__sync_xor_and_fetch_1:
5199 case Builtin::BI__sync_xor_and_fetch_2:
5200 case Builtin::BI__sync_xor_and_fetch_4:
5201 case Builtin::BI__sync_xor_and_fetch_8:
5202 case Builtin::BI__sync_xor_and_fetch_16:
5206 case Builtin::BI__sync_nand_and_fetch:
5207 case Builtin::BI__sync_nand_and_fetch_1:
5208 case Builtin::BI__sync_nand_and_fetch_2:
5209 case Builtin::BI__sync_nand_and_fetch_4:
5210 case Builtin::BI__sync_nand_and_fetch_8:
5211 case Builtin::BI__sync_nand_and_fetch_16:
5213 WarnAboutSemanticsChange =
true;
5216 case Builtin::BI__sync_val_compare_and_swap:
5217 case Builtin::BI__sync_val_compare_and_swap_1:
5218 case Builtin::BI__sync_val_compare_and_swap_2:
5219 case Builtin::BI__sync_val_compare_and_swap_4:
5220 case Builtin::BI__sync_val_compare_and_swap_8:
5221 case Builtin::BI__sync_val_compare_and_swap_16:
5226 case Builtin::BI__sync_bool_compare_and_swap:
5227 case Builtin::BI__sync_bool_compare_and_swap_1:
5228 case Builtin::BI__sync_bool_compare_and_swap_2:
5229 case Builtin::BI__sync_bool_compare_and_swap_4:
5230 case Builtin::BI__sync_bool_compare_and_swap_8:
5231 case Builtin::BI__sync_bool_compare_and_swap_16:
5237 case Builtin::BI__sync_lock_test_and_set:
5238 case Builtin::BI__sync_lock_test_and_set_1:
5239 case Builtin::BI__sync_lock_test_and_set_2:
5240 case Builtin::BI__sync_lock_test_and_set_4:
5241 case Builtin::BI__sync_lock_test_and_set_8:
5242 case Builtin::BI__sync_lock_test_and_set_16:
5246 case Builtin::BI__sync_lock_release:
5247 case Builtin::BI__sync_lock_release_1:
5248 case Builtin::BI__sync_lock_release_2:
5249 case Builtin::BI__sync_lock_release_4:
5250 case Builtin::BI__sync_lock_release_8:
5251 case Builtin::BI__sync_lock_release_16:
5257 case Builtin::BI__sync_swap:
5258 case Builtin::BI__sync_swap_1:
5259 case Builtin::BI__sync_swap_2:
5260 case Builtin::BI__sync_swap_4:
5261 case Builtin::BI__sync_swap_8:
5262 case Builtin::BI__sync_swap_16:
5270 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5271 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5272 <<
Callee->getSourceRange();
5276 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5277 <<
Callee->getSourceRange();
5279 if (WarnAboutSemanticsChange) {
5280 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5281 <<
Callee->getSourceRange();
5286 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5287 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5288 FunctionDecl *NewBuiltinDecl;
5289 if (NewBuiltinID == BuiltinID)
5290 NewBuiltinDecl = FDecl;
5293 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5296 assert(Res.getFoundDecl());
5297 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5298 if (!NewBuiltinDecl)
5305 for (
unsigned i = 0; i != NumFixed; ++i) {
5334 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5336 CK_BuiltinFnToFnPtr);
5347 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5348 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5349 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5353 return TheCallResult;
5357 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5362 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5363 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5364 "Unexpected nontemporal load/store builtin!");
5365 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5366 unsigned numArgs = isStore ? 2 : 1;
5376 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5382 PointerArg = PointerArgResult.
get();
5383 TheCall->
setArg(numArgs - 1, PointerArg);
5387 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5400 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5407 return TheCallResult;
5419 return TheCallResult;
5426 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5428 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5429 Literal = ObjcLiteral->getString();
5433 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5440 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5441 InitializedEntity Entity =
5451 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5452 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5453 TT.getArch() == llvm::Triple::aarch64_32);
5454 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5455 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5456 if (IsX64 || IsAArch64) {
5463 return S.
Diag(Fn->getBeginLoc(),
5464 diag::err_ms_va_start_used_in_sysv_function);
5471 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5472 return S.
Diag(Fn->getBeginLoc(),
5473 diag::err_va_start_used_in_wrong_abi_function)
5474 << !IsWindowsOrUEFI;
5480 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5488 bool IsVariadic =
false;
5491 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5492 IsVariadic =
Block->isVariadic();
5493 Params =
Block->parameters();
5494 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5497 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5498 IsVariadic = MD->isVariadic();
5500 Params = MD->parameters();
5503 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5507 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5512 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5517 *LastParam = Params.empty() ?
nullptr : Params.back();
5522bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5527 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5551 ParmVarDecl *LastParam;
5562 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5564 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5569 if (std::optional<llvm::APSInt> Val =
5571 Val &&
LangOpts.C23 && *Val == 0 &&
5572 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5573 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5580 SourceLocation ParamLoc;
5581 bool IsCRegister =
false;
5582 bool SecondArgIsLastNonVariadicArgument =
false;
5583 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5584 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5585 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5588 ParamLoc = PV->getLocation();
5594 if (!SecondArgIsLastNonVariadicArgument)
5596 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5597 else if (IsCRegister ||
Type->isReferenceType() ||
5598 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5601 if (!Context.isPromotableIntegerType(Type))
5603 const auto *ED = Type->getAsEnumDecl();
5606 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5608 unsigned Reason = 0;
5609 if (
Type->isReferenceType()) Reason = 1;
5610 else if (IsCRegister) Reason = 2;
5611 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5612 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5619 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5639 if (
Call->getNumArgs() < 3)
5641 diag::err_typecheck_call_too_few_args_at_least)
5642 << 0 << 3 <<
Call->getNumArgs()
5655 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5658 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5661 const QualType &ConstCharPtrTy =
5663 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5665 << Arg1->
getType() << ConstCharPtrTy << 1
5668 << 2 << Arg1->
getType() << ConstCharPtrTy;
5670 const QualType SizeTy =
Context.getSizeType();
5675 << Arg2->
getType() << SizeTy << 1
5678 << 3 << Arg2->
getType() << SizeTy;
5683bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5687 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5715 diag::err_typecheck_call_invalid_ordered_compare)
5723bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5724 unsigned BuiltinID) {
5729 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5730 BuiltinID == Builtin::BI__builtin_isinf ||
5731 BuiltinID == Builtin::BI__builtin_isinf_sign))
5735 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5736 BuiltinID == Builtin::BI__builtin_isunordered))
5740 bool IsFPClass = NumArgs == 2;
5743 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5747 for (
unsigned i = 0; i < FPArgNo; ++i) {
5748 Expr *Arg = TheCall->
getArg(i);
5761 Expr *OrigArg = TheCall->
getArg(FPArgNo);
5769 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
5774 OrigArg = Res.
get();
5780 OrigArg = Res.
get();
5782 TheCall->
setArg(FPArgNo, OrigArg);
5784 QualType VectorResultTy;
5785 QualType ElementTy = OrigArg->
getType();
5790 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
5796 diag::err_typecheck_call_invalid_unary_fp)
5808 if (!VectorResultTy.
isNull())
5809 ResultTy = VectorResultTy;
5818bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5823 for (
unsigned I = 0; I != 2; ++I) {
5824 Expr *Arg = TheCall->
getArg(I);
5834 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5849 Expr *Real = TheCall->
getArg(0);
5850 Expr *Imag = TheCall->
getArg(1);
5853 diag::err_typecheck_call_different_arg_types)
5868 diag::err_typecheck_call_too_few_args_at_least)
5869 << 0 << 2 << NumArgs
5876 unsigned NumElements = 0;
5891 unsigned NumResElements = NumArgs - 2;
5900 diag::err_vec_builtin_incompatible_vector)
5905 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
5907 diag::err_vec_builtin_incompatible_vector)
5912 }
else if (NumElements != NumResElements) {
5915 ?
Context.getExtVectorType(EltType, NumResElements)
5916 :
Context.getVectorType(EltType, NumResElements,
5921 for (
unsigned I = 2; I != NumArgs; ++I) {
5929 diag::err_shufflevector_nonconstant_argument)
5935 else if (
Result->getActiveBits() > 64 ||
5936 Result->getZExtValue() >= NumElements * 2)
5938 diag::err_shufflevector_argument_too_large)
5963 diag::err_convertvector_non_vector)
5966 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5968 <<
"__builtin_convertvector");
5973 if (SrcElts != DstElts)
5975 diag::err_convertvector_incompatible_vector)
5983bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5988 diag::err_typecheck_call_too_many_args_at_most)
5989 << 0 << 3 << NumArgs << 0
5994 for (
unsigned i = 1; i != NumArgs; ++i)
6001bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6002 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6003 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6013 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6023bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6024 Expr *Arg = TheCall->
getArg(0);
6035bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6037 Expr *Arg = TheCall->
getArg(1);
6041 if (
const auto *UE =
6043 if (UE->getKind() == UETT_AlignOf ||
6044 UE->getKind() == UETT_PreferredAlignOf)
6050 if (!
Result.isPowerOf2())
6051 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6058 if (
Result > std::numeric_limits<int32_t>::max())
6066bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6071 Expr *FirstArg = TheCall->
getArg(0);
6077 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6081 TheCall->
setArg(0, FirstArgResult.
get());
6085 Expr *SecondArg = TheCall->
getArg(1);
6093 if (!
Result.isPowerOf2())
6094 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6106 Expr *ThirdArg = TheCall->
getArg(2);
6109 TheCall->
setArg(2, ThirdArg);
6115bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6116 unsigned BuiltinID =
6118 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6121 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6122 if (NumArgs < NumRequiredArgs) {
6123 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6124 << 0 << NumRequiredArgs << NumArgs
6127 if (NumArgs >= NumRequiredArgs + 0x100) {
6129 diag::err_typecheck_call_too_many_args_at_most)
6130 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6141 if (Arg.isInvalid())
6143 TheCall->
setArg(i, Arg.get());
6148 unsigned FormatIdx = i;
6158 unsigned FirstDataArg = i;
6159 while (i < NumArgs) {
6177 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6179 bool Success = CheckFormatArguments(
6182 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6206 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6215 int High,
bool RangeIsError) {
6229 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6237 PDiag(diag::warn_argument_invalid_range)
6280 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6285 if (
Value.isNegative())
6296 if ((
Value & 0xFF) != 0)
6321 Result.setIsUnsigned(
true);
6326 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6346 Result.setIsUnsigned(
true);
6354 diag::err_argument_not_shifted_byte_or_xxff)
6358bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6359 if (!Context.getTargetInfo().hasSjLjLowering())
6360 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6371 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6377bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6378 if (!Context.getTargetInfo().hasSjLjLowering())
6379 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6384bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6399 diag::err_builtin_counted_by_ref_invalid_arg)
6404 diag::err_builtin_counted_by_ref_has_side_effects)
6407 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6409 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6414 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6421 QualType MemberTy = ME->getMemberDecl()->getType();
6424 diag::err_builtin_counted_by_ref_invalid_arg)
6428 diag::err_builtin_counted_by_ref_invalid_arg)
6438bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6440 const CallExpr *CE =
6449 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6454 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6459 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6463 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6467 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6477class UncoveredArgHandler {
6478 enum {
Unknown = -1, AllCovered = -2 };
6480 signed FirstUncoveredArg =
Unknown;
6481 SmallVector<const Expr *, 4> DiagnosticExprs;
6484 UncoveredArgHandler() =
default;
6486 bool hasUncoveredArg()
const {
6487 return (FirstUncoveredArg >= 0);
6490 unsigned getUncoveredArg()
const {
6491 assert(hasUncoveredArg() &&
"no uncovered argument");
6492 return FirstUncoveredArg;
6495 void setAllCovered() {
6498 DiagnosticExprs.clear();
6499 FirstUncoveredArg = AllCovered;
6502 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6503 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6506 if (FirstUncoveredArg == AllCovered)
6511 if (NewFirstUncoveredArg == FirstUncoveredArg)
6512 DiagnosticExprs.push_back(StrExpr);
6513 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6514 DiagnosticExprs.clear();
6515 DiagnosticExprs.push_back(StrExpr);
6516 FirstUncoveredArg = NewFirstUncoveredArg;
6520 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6523enum StringLiteralCheckType {
6525 SLCT_UncheckedLiteral,
6533 bool AddendIsRight) {
6534 unsigned BitWidth = Offset.getBitWidth();
6535 unsigned AddendBitWidth = Addend.getBitWidth();
6537 if (Addend.isUnsigned()) {
6538 Addend = Addend.zext(++AddendBitWidth);
6539 Addend.setIsSigned(
true);
6542 if (AddendBitWidth > BitWidth) {
6543 Offset = Offset.sext(AddendBitWidth);
6544 BitWidth = AddendBitWidth;
6545 }
else if (BitWidth > AddendBitWidth) {
6546 Addend = Addend.sext(BitWidth);
6550 llvm::APSInt ResOffset = Offset;
6551 if (BinOpKind == BO_Add)
6552 ResOffset = Offset.sadd_ov(Addend, Ov);
6554 assert(AddendIsRight && BinOpKind == BO_Sub &&
6555 "operator must be add or sub with addend on the right");
6556 ResOffset = Offset.ssub_ov(Addend, Ov);
6562 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6563 "index (intermediate) result too big");
6564 Offset = Offset.sext(2 * BitWidth);
6565 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6577class FormatStringLiteral {
6578 const StringLiteral *FExpr;
6582 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6583 : FExpr(fexpr), Offset(Offset) {}
6585 const StringLiteral *getFormatString()
const {
return FExpr; }
6587 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6589 unsigned getByteLength()
const {
6590 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6593 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6600 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6601 bool isWide()
const {
return FExpr->
isWide(); }
6602 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6603 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6604 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6605 bool isPascal()
const {
return FExpr->
isPascal(); }
6607 SourceLocation getLocationOfByte(
6608 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6609 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6610 unsigned *StartTokenByteOffset =
nullptr)
const {
6612 StartToken, StartTokenByteOffset);
6615 SourceLocation getBeginLoc() const LLVM_READONLY {
6619 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6625 Sema &S,
const FormatStringLiteral *FExpr,
6630 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6631 bool IgnoreStringsWithoutSpecifiers);
6640static StringLiteralCheckType
6646 llvm::SmallBitVector &CheckedVarArgs,
6647 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
6648 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
6649 bool IgnoreStringsWithoutSpecifiers =
false) {
6651 return SLCT_NotALiteral;
6653 assert(Offset.isSigned() &&
"invalid offset");
6656 return SLCT_NotALiteral;
6665 return SLCT_UncheckedLiteral;
6668 case Stmt::InitListExprClass:
6672 format_idx, firstDataArg,
Type, CallType,
6673 false, CheckedVarArgs,
6674 UncoveredArg, Offset, CallerFormatParamIdx,
6675 IgnoreStringsWithoutSpecifiers);
6677 return SLCT_NotALiteral;
6678 case Stmt::BinaryConditionalOperatorClass:
6679 case Stmt::ConditionalOperatorClass: {
6688 bool CheckLeft =
true, CheckRight =
true;
6691 if (
C->getCond()->EvaluateAsBooleanCondition(
6703 StringLiteralCheckType Left;
6705 Left = SLCT_UncheckedLiteral;
6708 Args, APK, format_idx, firstDataArg,
Type,
6709 CallType, InFunctionCall, CheckedVarArgs,
6710 UncoveredArg, Offset, CallerFormatParamIdx,
6711 IgnoreStringsWithoutSpecifiers);
6712 if (Left == SLCT_NotALiteral || !CheckRight) {
6718 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6719 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6720 UncoveredArg, Offset, CallerFormatParamIdx,
6721 IgnoreStringsWithoutSpecifiers);
6723 return (CheckLeft && Left < Right) ? Left : Right;
6726 case Stmt::ImplicitCastExprClass:
6730 case Stmt::OpaqueValueExprClass:
6735 return SLCT_NotALiteral;
6737 case Stmt::PredefinedExprClass:
6741 return SLCT_UncheckedLiteral;
6743 case Stmt::DeclRefExprClass: {
6749 bool isConstant =
false;
6753 isConstant = AT->getElementType().isConstant(S.
Context);
6755 isConstant =
T.isConstant(S.
Context) &&
6756 PT->getPointeeType().isConstant(S.
Context);
6757 }
else if (
T->isObjCObjectPointerType()) {
6760 isConstant =
T.isConstant(S.
Context);
6764 if (
const Expr *
Init = VD->getAnyInitializer()) {
6767 if (InitList->isStringLiteralInit())
6768 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6771 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6772 firstDataArg,
Type, CallType,
false,
6773 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
6824 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6825 if (CallerFormatParamIdx)
6826 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
6827 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
6828 for (
const auto *PVFormatMatches :
6829 D->specific_attrs<FormatMatchesAttr>()) {
6834 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6838 S.
Diag(Args[format_idx]->getBeginLoc(),
6839 diag::warn_format_string_type_incompatible)
6840 << PVFormatMatches->getType()->getName()
6842 if (!InFunctionCall) {
6843 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6844 diag::note_format_string_defined);
6846 return SLCT_UncheckedLiteral;
6849 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6850 Args, APK, format_idx, firstDataArg,
Type, CallType,
6851 false, CheckedVarArgs, UncoveredArg,
6852 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6856 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
6859 PVFormat->getFirstArg(), &CallerFSI))
6861 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6865 S.
Diag(Args[format_idx]->getBeginLoc(),
6866 diag::warn_format_string_type_incompatible)
6867 << PVFormat->getType()->getName()
6869 if (!InFunctionCall) {
6872 return SLCT_UncheckedLiteral;
6885 return SLCT_UncheckedLiteral;
6893 return SLCT_NotALiteral;
6896 case Stmt::CallExprClass:
6897 case Stmt::CXXMemberCallExprClass: {
6901 StringLiteralCheckType CommonResult;
6902 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6903 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6905 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6906 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6907 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6909 CommonResult = Result;
6914 return CommonResult;
6916 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6918 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6919 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6922 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6923 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6924 UncoveredArg, Offset, CallerFormatParamIdx,
6925 IgnoreStringsWithoutSpecifiers);
6931 format_idx, firstDataArg,
Type, CallType,
6932 false, CheckedVarArgs,
6933 UncoveredArg, Offset, CallerFormatParamIdx,
6934 IgnoreStringsWithoutSpecifiers);
6935 return SLCT_NotALiteral;
6937 case Stmt::ObjCMessageExprClass: {
6939 if (
const auto *MD = ME->getMethodDecl()) {
6940 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6949 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6951 MD->getSelector().isKeywordSelector(
6952 {
"localizedStringForKey",
"value",
"table"})) {
6953 IgnoreStringsWithoutSpecifiers =
true;
6956 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6958 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6959 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6960 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6964 return SLCT_NotALiteral;
6966 case Stmt::ObjCStringLiteralClass:
6967 case Stmt::StringLiteralClass: {
6976 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6979 return SLCT_NotALiteral;
6981 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6983 format_idx, firstDataArg,
Type, InFunctionCall,
6984 CallType, CheckedVarArgs, UncoveredArg,
6985 IgnoreStringsWithoutSpecifiers);
6986 return SLCT_CheckedLiteral;
6989 return SLCT_NotALiteral;
6991 case Stmt::BinaryOperatorClass: {
7005 if (LIsInt != RIsInt) {
7009 if (BinOpKind == BO_Add) {
7022 return SLCT_NotALiteral;
7024 case Stmt::UnaryOperatorClass: {
7026 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7027 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7029 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7039 return SLCT_NotALiteral;
7043 return SLCT_NotALiteral;
7054 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7055 if (isa_and_nonnull<StringLiteral>(LVE))
7076 return "freebsd_kprintf";
7085 return llvm::StringSwitch<FormatStringType>(Flavor)
7087 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7092 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7108bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7112 llvm::SmallBitVector &CheckedVarArgs) {
7113 FormatStringInfo FSI;
7117 return CheckFormatArguments(
7118 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7123bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7127 llvm::SmallBitVector &CheckedVarArgs) {
7128 FormatStringInfo FSI;
7132 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7133 Format->getFormatString(), FSI.FormatIdx,
7135 CallType, Loc, Range, CheckedVarArgs);
7143 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7156 unsigned CallerArgumentIndexOffset =
7159 unsigned FirstArgumentIndex = -1;
7169 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7170 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7174 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7175 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7177 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7180 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7181 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7184 FirstArgumentIndex =
7185 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7191 ? (NumCallerParams + CallerArgumentIndexOffset)
7196 if (!ReferenceFormatString)
7202 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7204 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7206 std::string
Attr, Fixit;
7207 llvm::raw_string_ostream AttrOS(
Attr);
7209 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7210 << FirstArgumentIndex <<
")";
7212 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7214 AttrOS.write_escaped(ReferenceFormatString->
getString());
7218 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7229 llvm::raw_string_ostream IS(Fixit);
7237 if (LO.C23 || LO.CPlusPlus11)
7238 IS <<
"[[gnu::" <<
Attr <<
"]]";
7239 else if (LO.ObjC || LO.GNUMode)
7240 IS <<
"__attribute__((" <<
Attr <<
"))";
7254 Caller->
addAttr(FormatAttr::CreateImplicit(
7256 FormatStringIndex, FirstArgumentIndex));
7258 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7260 FormatStringIndex, ReferenceFormatString));
7264 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7276 unsigned format_idx,
unsigned firstDataArg,
7280 llvm::SmallBitVector &CheckedVarArgs) {
7282 if (format_idx >= Args.size()) {
7283 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7287 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7301 UncoveredArgHandler UncoveredArg;
7302 std::optional<unsigned> CallerParamIdx;
7304 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7305 firstDataArg,
Type, CallType,
7306 true, CheckedVarArgs, UncoveredArg,
7307 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7310 if (UncoveredArg.hasUncoveredArg()) {
7311 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7312 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7313 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7316 if (CT != SLCT_NotALiteral)
7318 return CT == SLCT_CheckedLiteral;
7324 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7330 this, Args, APK, ReferenceFormatString, format_idx,
7331 firstDataArg,
Type, *CallerParamIdx, Loc))
7341 if (Args.size() == firstDataArg) {
7342 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7350 Diag(FormatLoc, diag::note_format_security_fixit)
7354 Diag(FormatLoc, diag::note_format_security_fixit)
7359 Diag(FormatLoc, diag::warn_format_nonliteral)
7370 const FormatStringLiteral *FExpr;
7371 const Expr *OrigFormatExpr;
7373 const unsigned FirstDataArg;
7374 const unsigned NumDataArgs;
7377 ArrayRef<const Expr *> Args;
7379 llvm::SmallBitVector CoveredArgs;
7380 bool usesPositionalArgs =
false;
7381 bool atFirstArg =
true;
7382 bool inFunctionCall;
7384 llvm::SmallBitVector &CheckedVarArgs;
7385 UncoveredArgHandler &UncoveredArg;
7388 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7390 unsigned firstDataArg,
unsigned numDataArgs,
7392 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7394 llvm::SmallBitVector &CheckedVarArgs,
7395 UncoveredArgHandler &UncoveredArg)
7396 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7397 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7398 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7399 inFunctionCall(inFunctionCall), CallType(callType),
7400 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7401 CoveredArgs.resize(numDataArgs);
7402 CoveredArgs.reset();
7405 bool HasFormatArguments()
const {
7410 void DoneProcessing();
7412 void HandleIncompleteSpecifier(
const char *startSpecifier,
7413 unsigned specifierLen)
override;
7415 void HandleInvalidLengthModifier(
7416 const analyze_format_string::FormatSpecifier &FS,
7417 const analyze_format_string::ConversionSpecifier &CS,
7418 const char *startSpecifier,
unsigned specifierLen,
7421 void HandleNonStandardLengthModifier(
7422 const analyze_format_string::FormatSpecifier &FS,
7423 const char *startSpecifier,
unsigned specifierLen);
7425 void HandleNonStandardConversionSpecifier(
7426 const analyze_format_string::ConversionSpecifier &CS,
7427 const char *startSpecifier,
unsigned specifierLen);
7429 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7431 void HandleInvalidPosition(
const char *startSpecifier,
7432 unsigned specifierLen,
7435 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7437 void HandleNullChar(
const char *nullCharacter)
override;
7439 template <
typename Range>
7441 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7442 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7443 bool IsStringLocation, Range StringRange,
7444 ArrayRef<FixItHint> Fixit = {});
7447 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7448 const char *startSpec,
7449 unsigned specifierLen,
7450 const char *csStart,
unsigned csLen);
7452 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7453 const char *startSpec,
7454 unsigned specifierLen);
7456 SourceRange getFormatStringRange();
7457 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7458 unsigned specifierLen);
7459 SourceLocation getLocationOfByte(
const char *x);
7461 const Expr *getDataArg(
unsigned i)
const;
7463 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7464 const analyze_format_string::ConversionSpecifier &CS,
7465 const char *startSpecifier,
unsigned specifierLen,
7468 template <
typename Range>
7469 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7470 bool IsStringLocation, Range StringRange,
7471 ArrayRef<FixItHint> Fixit = {});
7476SourceRange CheckFormatHandler::getFormatStringRange() {
7481getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7483 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7491SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7496void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7497 unsigned specifierLen){
7498 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7499 getLocationOfByte(startSpecifier),
7501 getSpecifierRange(startSpecifier, specifierLen));
7504void CheckFormatHandler::HandleInvalidLengthModifier(
7507 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7519 getSpecifierRange(startSpecifier, specifierLen));
7521 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7522 << FixedLM->toString()
7527 if (DiagID == diag::warn_format_nonsensical_length)
7533 getSpecifierRange(startSpecifier, specifierLen),
7538void CheckFormatHandler::HandleNonStandardLengthModifier(
7540 const char *startSpecifier,
unsigned specifierLen) {
7549 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7553 getSpecifierRange(startSpecifier, specifierLen));
7555 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7556 << FixedLM->toString()
7560 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7564 getSpecifierRange(startSpecifier, specifierLen));
7568void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7570 const char *startSpecifier,
unsigned specifierLen) {
7576 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7580 getSpecifierRange(startSpecifier, specifierLen));
7583 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7584 << FixedCS->toString()
7587 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7591 getSpecifierRange(startSpecifier, specifierLen));
7595void CheckFormatHandler::HandlePosition(
const char *startPos,
7598 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7599 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7600 getLocationOfByte(startPos),
7602 getSpecifierRange(startPos, posLen));
7605void CheckFormatHandler::HandleInvalidPosition(
7606 const char *startSpecifier,
unsigned specifierLen,
7609 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7610 EmitFormatDiagnostic(
7611 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7612 getLocationOfByte(startSpecifier),
true,
7613 getSpecifierRange(startSpecifier, specifierLen));
7616void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7620 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7621 getLocationOfByte(startPos),
7623 getSpecifierRange(startPos, posLen));
7626void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7629 EmitFormatDiagnostic(
7630 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7631 getLocationOfByte(nullCharacter),
true,
7632 getFormatStringRange());
7638const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7639 return Args[FirstDataArg + i];
7642void CheckFormatHandler::DoneProcessing() {
7645 if (HasFormatArguments()) {
7648 signed notCoveredArg = CoveredArgs.find_first();
7649 if (notCoveredArg >= 0) {
7650 assert((
unsigned)notCoveredArg < NumDataArgs);
7651 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7653 UncoveredArg.setAllCovered();
7658void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7659 const Expr *ArgExpr) {
7660 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7672 for (
auto E : DiagnosticExprs)
7675 CheckFormatHandler::EmitFormatDiagnostic(
7676 S, IsFunctionCall, DiagnosticExprs[0],
7682CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7684 const char *startSpec,
7685 unsigned specifierLen,
7686 const char *csStart,
7688 bool keepGoing =
true;
7689 if (argIndex < NumDataArgs) {
7692 CoveredArgs.set(argIndex);
7708 std::string CodePointStr;
7709 if (!llvm::sys::locale::isPrint(*csStart)) {
7710 llvm::UTF32 CodePoint;
7711 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7712 const llvm::UTF8 *E =
7713 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7714 llvm::ConversionResult
Result =
7715 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7717 if (
Result != llvm::conversionOK) {
7718 unsigned char FirstChar = *csStart;
7719 CodePoint = (llvm::UTF32)FirstChar;
7722 llvm::raw_string_ostream
OS(CodePointStr);
7723 if (CodePoint < 256)
7724 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7725 else if (CodePoint <= 0xFFFF)
7726 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7728 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7732 EmitFormatDiagnostic(
7733 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7734 true, getSpecifierRange(startSpec, specifierLen));
7740CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7741 const char *startSpec,
7742 unsigned specifierLen) {
7743 EmitFormatDiagnostic(
7744 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7745 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7749CheckFormatHandler::CheckNumArgs(
7752 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7754 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7756 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7757 << (argIndex+1) << NumDataArgs)
7758 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7759 EmitFormatDiagnostic(
7760 PDiag, getLocationOfByte(CS.
getStart()),
true,
7761 getSpecifierRange(startSpecifier, specifierLen));
7765 UncoveredArg.setAllCovered();
7771template<
typename Range>
7774 bool IsStringLocation,
7777 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7778 Loc, IsStringLocation, StringRange, FixIt);
7808template <
typename Range>
7809void CheckFormatHandler::EmitFormatDiagnostic(
7810 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7813 if (InFunctionCall) {
7818 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
7822 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
7823 diag::note_format_string_defined);
7825 Note << StringRange;
7834class CheckPrintfHandler :
public CheckFormatHandler {
7836 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7838 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7840 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7842 llvm::SmallBitVector &CheckedVarArgs,
7843 UncoveredArgHandler &UncoveredArg)
7844 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7845 numDataArgs, beg, APK, Args, formatIdx,
7846 inFunctionCall, CallType, CheckedVarArgs,
7849 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7852 bool allowsObjCArg()
const {
7853 return FSType == FormatStringType::NSString ||
7854 FSType == FormatStringType::OSLog ||
7855 FSType == FormatStringType::OSTrace;
7858 bool HandleInvalidPrintfConversionSpecifier(
7859 const analyze_printf::PrintfSpecifier &FS,
7860 const char *startSpecifier,
7861 unsigned specifierLen)
override;
7863 void handleInvalidMaskType(StringRef MaskType)
override;
7865 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7866 const char *startSpecifier,
unsigned specifierLen,
7867 const TargetInfo &
Target)
override;
7868 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
7869 const char *StartSpecifier,
7870 unsigned SpecifierLen,
7873 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
7874 const char *startSpecifier,
unsigned specifierLen);
7875 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
7876 const analyze_printf::OptionalAmount &Amt,
7878 const char *startSpecifier,
unsigned specifierLen);
7879 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
7880 const analyze_printf::OptionalFlag &flag,
7881 const char *startSpecifier,
unsigned specifierLen);
7882 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
7883 const analyze_printf::OptionalFlag &ignoredFlag,
7884 const analyze_printf::OptionalFlag &flag,
7885 const char *startSpecifier,
unsigned specifierLen);
7886 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7889 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7890 unsigned flagLen)
override;
7892 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7893 unsigned flagLen)
override;
7896 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7897 const char *flagsEnd,
7898 const char *conversionPosition)
override;
7903class EquatableFormatArgument {
7905 enum SpecifierSensitivity :
unsigned {
7912 enum FormatArgumentRole :
unsigned {
7920 analyze_format_string::ArgType ArgType;
7922 StringRef SpecifierLetter;
7923 CharSourceRange
Range;
7924 SourceLocation ElementLoc;
7925 FormatArgumentRole
Role : 2;
7926 SpecifierSensitivity Sensitivity : 2;
7927 unsigned Position : 14;
7928 unsigned ModifierFor : 14;
7930 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
7931 bool InFunctionCall)
const;
7934 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
7936 StringRef SpecifierLetter,
7937 analyze_format_string::ArgType ArgType,
7938 FormatArgumentRole
Role,
7939 SpecifierSensitivity Sensitivity,
unsigned Position,
7940 unsigned ModifierFor)
7941 : ArgType(ArgType), LengthMod(LengthMod),
7942 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7943 Role(
Role), Sensitivity(Sensitivity), Position(Position),
7944 ModifierFor(ModifierFor) {}
7946 unsigned getPosition()
const {
return Position; }
7947 SourceLocation getSourceLocation()
const {
return ElementLoc; }
7949 analyze_format_string::LengthModifier getLengthModifier()
const {
7950 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
7952 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7954 std::string buildFormatSpecifier()
const {
7956 llvm::raw_string_ostream(result)
7957 << getLengthModifier().toString() << SpecifierLetter;
7961 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
7962 const Expr *FmtExpr,
bool InFunctionCall)
const;
7966class DecomposePrintfHandler :
public CheckPrintfHandler {
7967 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
7970 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7971 const Expr *origFormatExpr,
7973 unsigned numDataArgs,
bool isObjC,
const char *beg,
7975 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7977 llvm::SmallBitVector &CheckedVarArgs,
7978 UncoveredArgHandler &UncoveredArg,
7979 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
7980 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7981 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7982 inFunctionCall, CallType, CheckedVarArgs,
7984 Specs(Specs), HadError(
false) {}
7988 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7990 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
7992 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7993 const char *startSpecifier,
7994 unsigned specifierLen,
7995 const TargetInfo &
Target)
override;
8000bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8002 unsigned specifierLen) {
8006 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
8008 startSpecifier, specifierLen,
8012void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8013 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8021 return T->isRecordType() ||
T->isComplexType();
8024bool CheckPrintfHandler::HandleAmount(
8026 const char *startSpecifier,
unsigned specifierLen) {
8028 if (HasFormatArguments()) {
8030 if (argIndex >= NumDataArgs) {
8031 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8035 getSpecifierRange(startSpecifier, specifierLen));
8045 CoveredArgs.set(argIndex);
8046 const Expr *Arg = getDataArg(argIndex);
8057 ? diag::err_printf_asterisk_wrong_type
8058 : diag::warn_printf_asterisk_wrong_type;
8059 EmitFormatDiagnostic(S.
PDiag(DiagID)
8064 getSpecifierRange(startSpecifier, specifierLen));
8074void CheckPrintfHandler::HandleInvalidAmount(
8078 const char *startSpecifier,
8079 unsigned specifierLen) {
8089 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8093 getSpecifierRange(startSpecifier, specifierLen),
8099 const char *startSpecifier,
8100 unsigned specifierLen) {
8104 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
8108 getSpecifierRange(startSpecifier, specifierLen),
8113void CheckPrintfHandler::HandleIgnoredFlag(
8117 const char *startSpecifier,
8118 unsigned specifierLen) {
8120 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8124 getSpecifierRange(startSpecifier, specifierLen),
8126 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8129void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8132 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
8133 getLocationOfByte(startFlag),
8135 getSpecifierRange(startFlag, flagLen));
8138void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8141 auto Range = getSpecifierRange(startFlag, flagLen);
8142 StringRef flag(startFlag, flagLen);
8143 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8144 getLocationOfByte(startFlag),
8149void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8150 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
8152 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8153 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8154 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8155 getLocationOfByte(conversionPosition),
8161 const Expr *FmtExpr,
8162 bool InFunctionCall)
const {
8163 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8164 ElementLoc,
true, Range);
8167bool EquatableFormatArgument::VerifyCompatible(
8168 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8169 bool InFunctionCall)
const {
8174 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8175 FmtExpr, InFunctionCall);
8176 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8180 if (
Role != FAR_Data) {
8181 if (ModifierFor !=
Other.ModifierFor) {
8184 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8185 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8186 FmtExpr, InFunctionCall);
8187 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8193 bool HadError =
false;
8194 if (Sensitivity !=
Other.Sensitivity) {
8197 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8198 << Sensitivity <<
Other.Sensitivity,
8199 FmtExpr, InFunctionCall);
8200 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8201 << 0 <<
Other.Range;
8204 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8208 case MK::MatchPromotion:
8212 case MK::NoMatchTypeConfusion:
8213 case MK::NoMatchPromotionTypeConfusion:
8215 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8216 << buildFormatSpecifier()
8217 <<
Other.buildFormatSpecifier(),
8218 FmtExpr, InFunctionCall);
8219 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8220 << 0 <<
Other.Range;
8223 case MK::NoMatchPedantic:
8225 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8226 << buildFormatSpecifier()
8227 <<
Other.buildFormatSpecifier(),
8228 FmtExpr, InFunctionCall);
8229 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8230 << 0 <<
Other.Range;
8233 case MK::NoMatchSignedness:
8235 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8236 << buildFormatSpecifier()
8237 <<
Other.buildFormatSpecifier(),
8238 FmtExpr, InFunctionCall);
8239 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8240 << 0 <<
Other.Range;
8246bool DecomposePrintfHandler::GetSpecifiers(
8247 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8250 StringRef
Data = FSL->getString();
8251 const char *Str =
Data.data();
8252 llvm::SmallBitVector BV;
8253 UncoveredArgHandler UA;
8254 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8255 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8267 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8268 const EquatableFormatArgument &B) {
8269 return A.getPosition() < B.getPosition();
8274bool DecomposePrintfHandler::HandlePrintfSpecifier(
8277 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8292 const unsigned Unset = ~0;
8293 unsigned FieldWidthIndex = Unset;
8294 unsigned PrecisionIndex = Unset;
8298 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8299 FieldWidthIndex = Specs.size();
8300 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8301 getLocationOfByte(FieldWidth.getStart()),
8303 FieldWidth.getArgType(S.
Context),
8304 EquatableFormatArgument::FAR_FieldWidth,
8305 EquatableFormatArgument::SS_None,
8306 FieldWidth.usesPositionalArg()
8307 ? FieldWidth.getPositionalArgIndex() - 1
8313 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8314 PrecisionIndex = Specs.size();
8316 getSpecifierRange(startSpecifier, specifierLen),
8317 getLocationOfByte(Precision.getStart()),
8319 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8320 EquatableFormatArgument::SS_None,
8321 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8327 unsigned SpecIndex =
8329 if (FieldWidthIndex != Unset)
8330 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8331 if (PrecisionIndex != Unset)
8332 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8334 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8336 Sensitivity = EquatableFormatArgument::SS_Private;
8338 Sensitivity = EquatableFormatArgument::SS_Public;
8340 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8342 Sensitivity = EquatableFormatArgument::SS_None;
8345 getSpecifierRange(startSpecifier, specifierLen),
8348 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8353 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8358 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8359 SpecIndex + 1, SpecIndex);
8367template<
typename MemberKind>
8385 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8400 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8402 if ((*MI)->getMinRequiredArguments() == 0)
8410bool CheckPrintfHandler::checkForCStrMembers(
8417 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8420 if (
Method->getMinRequiredArguments() == 0 &&
8433bool CheckPrintfHandler::HandlePrintfSpecifier(
8447 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8448 startSpecifier, specifierLen);
8456 startSpecifier, specifierLen)) {
8461 startSpecifier, specifierLen)) {
8465 if (!CS.consumesDataArgument()) {
8473 if (argIndex < NumDataArgs) {
8477 CoveredArgs.set(argIndex);
8484 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8487 if (HasFormatArguments()) {
8489 CoveredArgs.set(argIndex + 1);
8492 const Expr *Ex = getDataArg(argIndex);
8496 : ArgType::CPointerTy;
8498 EmitFormatDiagnostic(
8499 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8503 getSpecifierRange(startSpecifier, specifierLen));
8506 Ex = getDataArg(argIndex + 1);
8509 EmitFormatDiagnostic(
8510 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8514 getSpecifierRange(startSpecifier, specifierLen));
8521 if (!allowsObjCArg() && CS.isObjCArg()) {
8522 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8529 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8536 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8537 getLocationOfByte(CS.getStart()),
8539 getSpecifierRange(startSpecifier, specifierLen));
8549 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8556 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8560 getSpecifierRange(startSpecifier, specifierLen));
8563 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8567 getSpecifierRange(startSpecifier, specifierLen));
8571 const llvm::Triple &Triple =
Target.getTriple();
8573 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8574 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8575 getLocationOfByte(CS.getStart()),
8577 getSpecifierRange(startSpecifier, specifierLen));
8583 startSpecifier, specifierLen);
8589 startSpecifier, specifierLen);
8595 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8596 getLocationOfByte(startSpecifier),
8598 getSpecifierRange(startSpecifier, specifierLen));
8607 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8609 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8618 startSpecifier, specifierLen);
8621 startSpecifier, specifierLen);
8626 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8627 diag::warn_format_nonsensical_length);
8629 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8631 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8632 diag::warn_format_non_standard_conversion_spec);
8635 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8638 if (!HasFormatArguments())
8641 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8644 const Expr *Arg = getDataArg(argIndex);
8648 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8660 case Stmt::ArraySubscriptExprClass:
8661 case Stmt::CallExprClass:
8662 case Stmt::CharacterLiteralClass:
8663 case Stmt::CXXBoolLiteralExprClass:
8664 case Stmt::DeclRefExprClass:
8665 case Stmt::FloatingLiteralClass:
8666 case Stmt::IntegerLiteralClass:
8667 case Stmt::MemberExprClass:
8668 case Stmt::ObjCArrayLiteralClass:
8669 case Stmt::ObjCBoolLiteralExprClass:
8670 case Stmt::ObjCBoxedExprClass:
8671 case Stmt::ObjCDictionaryLiteralClass:
8672 case Stmt::ObjCEncodeExprClass:
8673 case Stmt::ObjCIvarRefExprClass:
8674 case Stmt::ObjCMessageExprClass:
8675 case Stmt::ObjCPropertyRefExprClass:
8676 case Stmt::ObjCStringLiteralClass:
8677 case Stmt::ObjCSubscriptRefExprClass:
8678 case Stmt::ParenExprClass:
8679 case Stmt::StringLiteralClass:
8680 case Stmt::UnaryOperatorClass:
8687static std::pair<QualType, StringRef>
8694 StringRef Name = UserTy->getDecl()->getName();
8695 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8696 .Case(
"CFIndex", Context.getNSIntegerType())
8697 .Case(
"NSInteger", Context.getNSIntegerType())
8698 .Case(
"NSUInteger", Context.getNSUIntegerType())
8699 .Case(
"SInt32", Context.IntTy)
8700 .Case(
"UInt32", Context.UnsignedIntTy)
8704 return std::make_pair(CastTy, Name);
8706 TyTy = UserTy->desugar();
8710 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8712 PE->getSubExpr()->getType(),
8721 StringRef TrueName, FalseName;
8723 std::tie(TrueTy, TrueName) =
8725 CO->getTrueExpr()->getType(),
8727 std::tie(FalseTy, FalseName) =
8729 CO->getFalseExpr()->getType(),
8730 CO->getFalseExpr());
8732 if (TrueTy == FalseTy)
8733 return std::make_pair(TrueTy, TrueName);
8734 else if (TrueTy.
isNull())
8735 return std::make_pair(FalseTy, FalseName);
8736 else if (FalseTy.
isNull())
8737 return std::make_pair(TrueTy, TrueName);
8740 return std::make_pair(
QualType(), StringRef());
8759 From = VecTy->getElementType();
8761 To = VecTy->getElementType();
8772 diag::warn_format_conversion_argument_type_mismatch_signedness,
8776 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
8785 const char *StartSpecifier,
8786 unsigned SpecifierLen,
8798 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8799 ExprTy = TET->getUnderlyingExpr()->getType();
8814 getSpecifierRange(StartSpecifier, SpecifierLen);
8816 llvm::raw_svector_ostream os(FSString);
8818 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8829 getSpecifierRange(StartSpecifier, SpecifierLen);
8830 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8840 if (
Match == ArgType::Match)
8844 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8853 E = ICE->getSubExpr();
8863 if (OrigMatch == ArgType::NoMatchSignedness &&
8864 ImplicitMatch != ArgType::NoMatchSignedness)
8871 if (ImplicitMatch == ArgType::Match)
8889 if (
Match == ArgType::MatchPromotion)
8893 if (
Match == ArgType::MatchPromotion) {
8897 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8898 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8902 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8903 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8904 Match = ImplicitMatch;
8905 assert(
Match != ArgType::MatchPromotion);
8908 bool IsEnum =
false;
8909 bool IsScopedEnum =
false;
8912 IntendedTy = ED->getIntegerType();
8913 if (!ED->isScoped()) {
8914 ExprTy = IntendedTy;
8919 IsScopedEnum =
true;
8926 if (isObjCContext() &&
8937 const llvm::APInt &
V = IL->getValue();
8947 if (TD->getUnderlyingType() == IntendedTy)
8957 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8965 if (!IsScopedEnum &&
8966 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8970 IntendedTy = CastTy;
8971 ShouldNotPrintDirectly =
true;
8976 PrintfSpecifier fixedFS = FS;
8983 llvm::raw_svector_ostream os(buf);
8986 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8988 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8994 llvm_unreachable(
"expected non-matching");
8996 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8999 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9002 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9005 Diag = diag::warn_format_conversion_argument_type_mismatch;
9026 llvm::raw_svector_ostream CastFix(CastBuf);
9027 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9029 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9035 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9040 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9062 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9068 Name = TypedefTy->getDecl()->getName();
9072 ? diag::warn_format_argument_needs_cast_pedantic
9073 : diag::warn_format_argument_needs_cast;
9074 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9085 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9086 : diag::warn_format_conversion_argument_type_mismatch;
9088 EmitFormatDiagnostic(
9100 bool EmitTypeMismatch =
false;
9109 llvm_unreachable(
"expected non-matching");
9111 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9114 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9117 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9121 ? diag::err_format_conversion_argument_type_mismatch
9122 : diag::warn_format_conversion_argument_type_mismatch;
9126 EmitFormatDiagnostic(
9135 EmitTypeMismatch =
true;
9137 EmitFormatDiagnostic(
9138 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9139 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9143 checkForCStrMembers(AT, E);
9149 EmitTypeMismatch =
true;
9151 EmitFormatDiagnostic(
9152 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9153 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9166 if (EmitTypeMismatch) {
9172 EmitFormatDiagnostic(
9173 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9179 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9180 "format string specifier index out of range");
9181 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9191class CheckScanfHandler :
public CheckFormatHandler {
9193 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9195 unsigned firstDataArg,
unsigned numDataArgs,
9197 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9199 llvm::SmallBitVector &CheckedVarArgs,
9200 UncoveredArgHandler &UncoveredArg)
9201 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9202 numDataArgs, beg, APK, Args, formatIdx,
9203 inFunctionCall, CallType, CheckedVarArgs,
9206 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9207 const char *startSpecifier,
9208 unsigned specifierLen)
override;
9210 bool HandleInvalidScanfConversionSpecifier(
9211 const analyze_scanf::ScanfSpecifier &FS,
9212 const char *startSpecifier,
9213 unsigned specifierLen)
override;
9215 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9220void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9222 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9223 getLocationOfByte(end),
true,
9224 getSpecifierRange(start, end - start));
9227bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9229 const char *startSpecifier,
9230 unsigned specifierLen) {
9234 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9236 startSpecifier, specifierLen,
9240bool CheckScanfHandler::HandleScanfSpecifier(
9242 const char *startSpecifier,
9243 unsigned specifierLen) {
9257 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9258 startSpecifier, specifierLen);
9269 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9284 if (argIndex < NumDataArgs) {
9288 CoveredArgs.set(argIndex);
9294 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9295 diag::warn_format_nonsensical_length);
9297 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9299 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9300 diag::warn_format_non_standard_conversion_spec);
9303 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9306 if (!HasFormatArguments())
9309 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9313 const Expr *Ex = getDataArg(argIndex);
9331 ScanfSpecifier fixedFS = FS;
9336 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9338 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9339 : diag::warn_format_conversion_argument_type_mismatch;
9344 llvm::raw_svector_ostream os(buf);
9347 EmitFormatDiagnostic(
9352 getSpecifierRange(startSpecifier, specifierLen),
9354 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9361 getSpecifierRange(startSpecifier, specifierLen));
9371 const Expr *FmtExpr,
bool InFunctionCall) {
9372 bool HadError =
false;
9373 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9374 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9375 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9387 for (; FmtIter < FmtEnd; ++FmtIter) {
9391 if (FmtIter->getPosition() < RefIter->getPosition())
9395 if (FmtIter->getPosition() > RefIter->getPosition())
9399 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9403 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9404 return Arg.getPosition() != RefIter->getPosition();
9408 if (FmtIter < FmtEnd) {
9409 CheckFormatHandler::EmitFormatDiagnostic(
9410 S, InFunctionCall, FmtExpr,
9411 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9412 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9413 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9414 }
else if (RefIter < RefEnd) {
9415 CheckFormatHandler::EmitFormatDiagnostic(
9416 S, InFunctionCall, FmtExpr,
9417 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9420 << 1 << RefIter->getSourceRange();
9426 Sema &S,
const FormatStringLiteral *FExpr,
9431 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9432 bool IgnoreStringsWithoutSpecifiers) {
9434 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9435 CheckFormatHandler::EmitFormatDiagnostic(
9436 S, inFunctionCall, Args[format_idx],
9437 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9443 StringRef StrRef = FExpr->getString();
9444 const char *Str = StrRef.data();
9448 assert(
T &&
"String literal not of constant array type!");
9449 size_t TypeSize =
T->getZExtSize();
9450 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9451 const unsigned numDataArgs = Args.size() - firstDataArg;
9453 if (IgnoreStringsWithoutSpecifiers &&
9460 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9461 CheckFormatHandler::EmitFormatDiagnostic(
9462 S, inFunctionCall, Args[format_idx],
9463 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9464 FExpr->getBeginLoc(),
9470 if (StrLen == 0 && numDataArgs > 0) {
9471 CheckFormatHandler::EmitFormatDiagnostic(
9472 S, inFunctionCall, Args[format_idx],
9473 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9484 if (ReferenceFormatString ==
nullptr) {
9485 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9486 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9487 inFunctionCall, CallType, CheckedVarArgs,
9497 Type, ReferenceFormatString, FExpr->getFormatString(),
9498 inFunctionCall ?
nullptr : Args[format_idx]);
9501 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9502 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9503 CallType, CheckedVarArgs, UncoveredArg);
9523 FormatStringLiteral RefLit = AuthoritativeFormatString;
9524 FormatStringLiteral TestLit = TestedFormatString;
9526 bool DiagAtStringLiteral;
9527 if (FunctionCallArg) {
9528 Arg = FunctionCallArg;
9529 DiagAtStringLiteral =
false;
9531 Arg = TestedFormatString;
9532 DiagAtStringLiteral =
true;
9534 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9535 AuthoritativeFormatString,
Type,
9536 IsObjC,
true, RefArgs) &&
9537 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9538 DiagAtStringLiteral, FmtArgs)) {
9540 TestedFormatString, FmtArgs, Arg,
9541 DiagAtStringLiteral);
9554 FormatStringLiteral RefLit = Str;
9558 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9567 bool HadError =
false;
9568 auto Iter = Args.begin();
9569 auto End = Args.end();
9570 while (Iter != End) {
9571 const auto &FirstInGroup = *Iter;
9573 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9575 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9584 const char *Str = StrRef.data();
9587 assert(
T &&
"String literal not of constant array type!");
9588 size_t TypeSize =
T->getZExtSize();
9589 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9600 switch (AbsFunction) {
9604 case Builtin::BI__builtin_abs:
9605 return Builtin::BI__builtin_labs;
9606 case Builtin::BI__builtin_labs:
9607 return Builtin::BI__builtin_llabs;
9608 case Builtin::BI__builtin_llabs:
9611 case Builtin::BI__builtin_fabsf:
9612 return Builtin::BI__builtin_fabs;
9613 case Builtin::BI__builtin_fabs:
9614 return Builtin::BI__builtin_fabsl;
9615 case Builtin::BI__builtin_fabsl:
9618 case Builtin::BI__builtin_cabsf:
9619 return Builtin::BI__builtin_cabs;
9620 case Builtin::BI__builtin_cabs:
9621 return Builtin::BI__builtin_cabsl;
9622 case Builtin::BI__builtin_cabsl:
9625 case Builtin::BIabs:
9626 return Builtin::BIlabs;
9627 case Builtin::BIlabs:
9628 return Builtin::BIllabs;
9629 case Builtin::BIllabs:
9632 case Builtin::BIfabsf:
9633 return Builtin::BIfabs;
9634 case Builtin::BIfabs:
9635 return Builtin::BIfabsl;
9636 case Builtin::BIfabsl:
9639 case Builtin::BIcabsf:
9640 return Builtin::BIcabs;
9641 case Builtin::BIcabs:
9642 return Builtin::BIcabsl;
9643 case Builtin::BIcabsl:
9672 unsigned AbsFunctionKind) {
9673 unsigned BestKind = 0;
9674 uint64_t ArgSize = Context.getTypeSize(ArgType);
9675 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9678 if (Context.getTypeSize(ParamType) >= ArgSize) {
9681 else if (Context.hasSameType(ParamType, ArgType)) {
9697 if (
T->isIntegralOrEnumerationType())
9699 if (
T->isRealFloatingType())
9701 if (
T->isAnyComplexType())
9704 llvm_unreachable(
"Type not integer, floating, or complex");
9711 switch (ValueKind) {
9716 case Builtin::BI__builtin_fabsf:
9717 case Builtin::BI__builtin_fabs:
9718 case Builtin::BI__builtin_fabsl:
9719 case Builtin::BI__builtin_cabsf:
9720 case Builtin::BI__builtin_cabs:
9721 case Builtin::BI__builtin_cabsl:
9722 return Builtin::BI__builtin_abs;
9723 case Builtin::BIfabsf:
9724 case Builtin::BIfabs:
9725 case Builtin::BIfabsl:
9726 case Builtin::BIcabsf:
9727 case Builtin::BIcabs:
9728 case Builtin::BIcabsl:
9729 return Builtin::BIabs;
9735 case Builtin::BI__builtin_abs:
9736 case Builtin::BI__builtin_labs:
9737 case Builtin::BI__builtin_llabs:
9738 case Builtin::BI__builtin_cabsf:
9739 case Builtin::BI__builtin_cabs:
9740 case Builtin::BI__builtin_cabsl:
9741 return Builtin::BI__builtin_fabsf;
9742 case Builtin::BIabs:
9743 case Builtin::BIlabs:
9744 case Builtin::BIllabs:
9745 case Builtin::BIcabsf:
9746 case Builtin::BIcabs:
9747 case Builtin::BIcabsl:
9748 return Builtin::BIfabsf;
9754 case Builtin::BI__builtin_abs:
9755 case Builtin::BI__builtin_labs:
9756 case Builtin::BI__builtin_llabs:
9757 case Builtin::BI__builtin_fabsf:
9758 case Builtin::BI__builtin_fabs:
9759 case Builtin::BI__builtin_fabsl:
9760 return Builtin::BI__builtin_cabsf;
9761 case Builtin::BIabs:
9762 case Builtin::BIlabs:
9763 case Builtin::BIllabs:
9764 case Builtin::BIfabsf:
9765 case Builtin::BIfabs:
9766 case Builtin::BIfabsl:
9767 return Builtin::BIcabsf;
9770 llvm_unreachable(
"Unable to convert function");
9781 case Builtin::BI__builtin_abs:
9782 case Builtin::BI__builtin_fabs:
9783 case Builtin::BI__builtin_fabsf:
9784 case Builtin::BI__builtin_fabsl:
9785 case Builtin::BI__builtin_labs:
9786 case Builtin::BI__builtin_llabs:
9787 case Builtin::BI__builtin_cabs:
9788 case Builtin::BI__builtin_cabsf:
9789 case Builtin::BI__builtin_cabsl:
9790 case Builtin::BIabs:
9791 case Builtin::BIlabs:
9792 case Builtin::BIllabs:
9793 case Builtin::BIfabs:
9794 case Builtin::BIfabsf:
9795 case Builtin::BIfabsl:
9796 case Builtin::BIcabs:
9797 case Builtin::BIcabsf:
9798 case Builtin::BIcabsl:
9801 llvm_unreachable(
"Unknown Builtin type");
9807 unsigned AbsKind,
QualType ArgType) {
9808 bool EmitHeaderHint =
true;
9809 const char *HeaderName =
nullptr;
9810 std::string FunctionName;
9811 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9812 FunctionName =
"std::abs";
9813 if (ArgType->isIntegralOrEnumerationType()) {
9814 HeaderName =
"cstdlib";
9815 }
else if (ArgType->isRealFloatingType()) {
9816 HeaderName =
"cmath";
9818 llvm_unreachable(
"Invalid Type");
9827 for (
const auto *I : R) {
9830 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9832 FDecl = dyn_cast<FunctionDecl>(I);
9847 EmitHeaderHint =
false;
9865 EmitHeaderHint =
false;
9869 }
else if (!R.
empty()) {
9875 S.
Diag(Loc, diag::note_replace_abs_function)
9881 if (!EmitHeaderHint)
9884 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9888template <std::
size_t StrLen>
9890 const char (&Str)[StrLen]) {
9903 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9904 return llvm::is_contained(names, calleeName);
9909 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9910 "__builtin_nanf16",
"__builtin_nanf128"});
9912 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9913 "__builtin_inff16",
"__builtin_inff128"});
9915 llvm_unreachable(
"unknown MathCheck");
9919 if (FDecl->
getName() !=
"infinity")
9922 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9924 if (RDecl->
getName() !=
"numeric_limits")
9941 if (FPO.getNoHonorNaNs() &&
9944 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9945 << 1 << 0 <<
Call->getSourceRange();
9949 if (FPO.getNoHonorInfs() &&
9953 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9954 << 0 << 0 <<
Call->getSourceRange();
9958void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9960 if (
Call->getNumArgs() != 1)
9965 if (AbsKind == 0 && !IsStdAbs)
9968 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9969 QualType ParamType =
Call->getArg(0)->getType();
9974 std::string FunctionName =
9975 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
9976 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9977 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10006 if (ArgValueKind == ParamValueKind) {
10007 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10011 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10012 << FDecl << ArgType << ParamType;
10014 if (NewAbsKind == 0)
10018 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10027 if (NewAbsKind == 0)
10030 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10031 << FDecl << ParamValueKind << ArgValueKind;
10034 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10040 if (!
Call || !FDecl)
return;
10044 if (
Call->getExprLoc().isMacroID())
return;
10047 if (
Call->getNumArgs() != 2)
return;
10050 if (!ArgList)
return;
10051 if (ArgList->size() != 1)
return;
10054 const auto& TA = ArgList->
get(0);
10056 QualType ArgType = TA.getAsType();
10060 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10061 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10062 if (!MTE)
return false;
10063 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10064 if (!
Num)
return false;
10065 if (
Num->getValue() != 0)
return false;
10069 const Expr *FirstArg =
Call->getArg(0);
10070 const Expr *SecondArg =
Call->getArg(1);
10071 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10072 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10075 if (IsFirstArgZero == IsSecondArgZero)
return;
10080 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10082 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10083 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10086 SourceRange RemovalRange;
10087 if (IsFirstArgZero) {
10088 RemovalRange = SourceRange(FirstRange.
getBegin(),
10095 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10110 const auto *Size = dyn_cast<BinaryOperator>(E);
10115 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10119 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10120 << SizeRange << FnName;
10121 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10126 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10137 bool &IsContained) {
10139 const Type *Ty =
T->getBaseElementTypeUnsafe();
10140 IsContained =
false;
10153 for (
auto *FD : RD->
fields()) {
10157 IsContained =
true;
10158 return ContainedRD;
10166 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10167 if (Unary->getKind() == UETT_SizeOf)
10176 if (!
SizeOf->isArgumentType())
10177 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10184 return SizeOf->getTypeOfArgument();
10190struct SearchNonTrivialToInitializeField
10193 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10195 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10198 SourceLocation SL) {
10199 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10200 asDerived().visitArray(PDIK, AT, SL);
10204 Super::visitWithKind(PDIK, FT, SL);
10207 void visitARCStrong(QualType FT, SourceLocation SL) {
10210 void visitARCWeak(QualType FT, SourceLocation SL) {
10213 void visitStruct(QualType FT, SourceLocation SL) {
10218 const ArrayType *AT, SourceLocation SL) {
10219 visit(getContext().getBaseElementType(AT), SL);
10221 void visitTrivial(QualType FT, SourceLocation SL) {}
10223 static void diag(QualType RT,
const Expr *E, Sema &S) {
10224 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10233struct SearchNonTrivialToCopyField
10235 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10237 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10240 SourceLocation SL) {
10241 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10242 asDerived().visitArray(PCK, AT, SL);
10246 Super::visitWithKind(PCK, FT, SL);
10249 void visitARCStrong(QualType FT, SourceLocation SL) {
10252 void visitARCWeak(QualType FT, SourceLocation SL) {
10255 void visitPtrAuth(QualType FT, SourceLocation SL) {
10258 void visitStruct(QualType FT, SourceLocation SL) {
10263 SourceLocation SL) {
10264 visit(getContext().getBaseElementType(AT), SL);
10267 SourceLocation SL) {}
10268 void visitTrivial(QualType FT, SourceLocation SL) {}
10269 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10271 static void diag(QualType RT,
const Expr *E, Sema &S) {
10272 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10287 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10288 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10312 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10314 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10315 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10321 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10324 const Expr *SizeArg =
10325 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10327 auto isLiteralZero = [](
const Expr *E) {
10337 if (isLiteralZero(SizeArg) &&
10344 if (BId == Builtin::BIbzero ||
10347 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10348 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10349 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10350 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10351 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10359 if (BId == Builtin::BImemset &&
10363 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10364 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10369void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10376 unsigned ExpectedNumArgs =
10377 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10378 if (
Call->getNumArgs() < ExpectedNumArgs)
10381 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10382 BId == Builtin::BIstrndup ? 1 : 2);
10384 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10385 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10388 Call->getBeginLoc(),
Call->getRParenLoc()))
10397 llvm::FoldingSetNodeID SizeOfArgID;
10402 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10403 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10406 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10407 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10408 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10410 QualType DestTy = Dest->
getType();
10411 QualType PointeeTy;
10412 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10425 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10429 if (SizeOfArgID == llvm::FoldingSetNodeID())
10431 llvm::FoldingSetNodeID DestID;
10433 if (DestID == SizeOfArgID) {
10436 unsigned ActionIdx = 0;
10437 StringRef ReadableName = FnName->
getName();
10439 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10440 if (UnaryOp->getOpcode() == UO_AddrOf)
10449 SourceLocation SL = SizeOfArg->
getExprLoc();
10454 if (
SM.isMacroArgExpansion(SL)) {
10456 SL =
SM.getSpellingLoc(SL);
10457 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10459 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10464 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10471 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10482 if (SizeOfArgTy != QualType()) {
10484 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10486 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10487 << FnName << SizeOfArgTy << ArgIdx
10494 PointeeTy = DestTy;
10497 if (PointeeTy == QualType())
10502 if (
const CXXRecordDecl *ContainedRD =
10505 unsigned OperationType = 0;
10506 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10509 if (ArgIdx != 0 || IsCmp) {
10510 if (BId == Builtin::BImemcpy)
10512 else if(BId == Builtin::BImemmove)
10519 PDiag(diag::warn_dyn_class_memaccess)
10520 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10521 << IsContained << ContainedRD << OperationType
10522 <<
Call->getCallee()->getSourceRange());
10524 BId != Builtin::BImemset)
10527 PDiag(diag::warn_arc_object_memaccess)
10528 << ArgIdx << FnName << PointeeTy
10529 <<
Call->getCallee()->getSourceRange());
10536 bool NonTriviallyCopyableCXXRecord =
10540 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10543 PDiag(diag::warn_cstruct_memaccess)
10544 << ArgIdx << FnName << PointeeTy << 0);
10545 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10546 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10547 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10551 PDiag(diag::warn_cxxstruct_memaccess)
10552 << FnName << PointeeTy);
10553 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10556 PDiag(diag::warn_cstruct_memaccess)
10557 << ArgIdx << FnName << PointeeTy << 1);
10558 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10559 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10560 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10564 PDiag(diag::warn_cxxstruct_memaccess)
10565 << FnName << PointeeTy);
10574 PDiag(diag::note_bad_memaccess_silence)
10610 if (CAT->getZExtSize() <= 1)
10618void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10622 unsigned NumArgs =
Call->getNumArgs();
10623 if ((NumArgs != 3) && (NumArgs != 4))
10628 const Expr *CompareWithSrc =
nullptr;
10631 Call->getBeginLoc(),
Call->getRParenLoc()))
10636 CompareWithSrc = Ex;
10639 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10640 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10641 SizeCall->getNumArgs() == 1)
10646 if (!CompareWithSrc)
10653 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10657 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10658 if (!CompareWithSrcDRE ||
10662 const Expr *OriginalSizeArg =
Call->getArg(2);
10663 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10670 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10674 SmallString<128> sizeString;
10675 llvm::raw_svector_ostream
OS(sizeString);
10680 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10687 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10688 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10689 return D1->getDecl() == D2->getDecl();
10694 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10703void Sema::CheckStrncatArguments(
const CallExpr *CE,
10718 unsigned PatternType = 0;
10726 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10727 if (BE->getOpcode() == BO_Sub) {
10728 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10729 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10740 if (PatternType == 0)
10749 if (
SM.isMacroArgExpansion(SL)) {
10750 SL =
SM.getSpellingLoc(SL);
10751 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10756 QualType DstTy = DstArg->
getType();
10759 if (!isKnownSizeArray) {
10760 if (PatternType == 1)
10761 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10763 Diag(SL, diag::warn_strncat_src_size) << SR;
10767 if (PatternType == 1)
10768 Diag(SL, diag::warn_strncat_large_size) << SR;
10770 Diag(SL, diag::warn_strncat_src_size) << SR;
10772 SmallString<128> sizeString;
10773 llvm::raw_svector_ostream
OS(sizeString);
10781 Diag(SL, diag::note_strncat_wrong_size)
10786void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10795void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10797 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10798 const Decl *D = Lvalue->getDecl();
10799 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10800 if (!DD->getType()->isReferenceType())
10801 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10805 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10806 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10807 Lvalue->getMemberDecl());
10810void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10812 const auto *Lambda = dyn_cast<LambdaExpr>(
10817 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10818 << CalleeName << 2 ;
10821void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10823 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10824 if (Var ==
nullptr)
10828 << CalleeName << 0 << Var;
10831void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10834 llvm::raw_svector_ostream
OS(SizeString);
10837 if (Kind == clang::CK_BitCast &&
10838 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10840 if (Kind == clang::CK_IntegralToPointer &&
10842 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10845 switch (
Cast->getCastKind()) {
10846 case clang::CK_BitCast:
10847 case clang::CK_IntegralToPointer:
10848 case clang::CK_FunctionToPointerDecay:
10857 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10858 << CalleeName << 0 <<
OS.str();
10862void Sema::CheckFreeArguments(
const CallExpr *E) {
10863 const std::string CalleeName =
10868 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10870 case UnaryOperator::Opcode::UO_AddrOf:
10871 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10872 case UnaryOperator::Opcode::UO_Plus:
10873 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10878 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10880 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10882 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10883 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10884 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10890 << CalleeName << 1 ;
10895 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
10896 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10900Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10909 Diag(ReturnLoc, diag::warn_null_ret)
10919 if (Op == OO_New || Op == OO_Array_New) {
10920 const FunctionProtoType *Proto
10924 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10930 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10935 if (
Context.getTargetInfo().getTriple().isPPC64())
10947 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10948 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10950 return FPLiteral && FPCast;
10953 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10959 llvm::APFloat TargetC = FPLiteral->
getValue();
10960 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
10961 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10965 Diag(Loc, diag::warn_float_compare_literal)
10966 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10979 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10980 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10981 if (DRL->getDecl() == DRR->getDecl())
10989 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10990 if (FLL->isExact())
10992 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10993 if (FLR->isExact())
10997 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10998 CL &&
CL->getBuiltinCallee())
11001 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11002 CR && CR->getBuiltinCallee())
11006 Diag(Loc, diag::warn_floatingpoint_eq)
11027 IntRange(
unsigned Width,
bool NonNegative)
11028 : Width(Width), NonNegative(NonNegative) {}
11031 unsigned valueBits()
const {
11032 return NonNegative ? Width : Width - 1;
11036 static IntRange forBoolType() {
11037 return IntRange(1,
true);
11041 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11042 return forValueOfCanonicalType(
C,
11047 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11050 if (
const auto *VT = dyn_cast<VectorType>(
T))
11051 T = VT->getElementType().getTypePtr();
11052 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11053 T = CT->getElementType().getTypePtr();
11054 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11055 T = AT->getValueType().getTypePtr();
11057 if (!
C.getLangOpts().CPlusPlus) {
11060 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11065 if (
Enum->isFixed()) {
11066 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11067 !
Enum->getIntegerType()->isSignedIntegerType());
11070 unsigned NumPositive =
Enum->getNumPositiveBits();
11071 unsigned NumNegative =
Enum->getNumNegativeBits();
11073 if (NumNegative == 0)
11074 return IntRange(NumPositive,
true);
11076 return IntRange(std::max(NumPositive + 1, NumNegative),
11080 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11081 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11094 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11097 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11098 T = VT->getElementType().getTypePtr();
11099 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11100 T = CT->getElementType().getTypePtr();
11101 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11102 T = AT->getValueType().getTypePtr();
11104 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11106 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11107 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11116 static IntRange join(IntRange L, IntRange R) {
11117 bool Unsigned = L.NonNegative && R.NonNegative;
11118 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
11119 L.NonNegative && R.NonNegative);
11123 static IntRange bit_and(IntRange L, IntRange R) {
11124 unsigned Bits = std::max(L.Width, R.Width);
11125 bool NonNegative =
false;
11126 if (L.NonNegative) {
11127 Bits = std::min(Bits, L.Width);
11128 NonNegative =
true;
11130 if (R.NonNegative) {
11131 Bits = std::min(Bits, R.Width);
11132 NonNegative =
true;
11134 return IntRange(Bits, NonNegative);
11138 static IntRange sum(IntRange L, IntRange R) {
11139 bool Unsigned = L.NonNegative && R.NonNegative;
11140 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
11145 static IntRange difference(IntRange L, IntRange R) {
11149 bool CanWiden = !L.NonNegative || !R.NonNegative;
11150 bool Unsigned = L.NonNegative && R.Width == 0;
11151 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
11157 static IntRange product(IntRange L, IntRange R) {
11161 bool CanWiden = !L.NonNegative && !R.NonNegative;
11162 bool Unsigned = L.NonNegative && R.NonNegative;
11163 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
11168 static IntRange rem(IntRange L, IntRange R) {
11172 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
11180 if (value.isSigned() && value.isNegative())
11181 return IntRange(value.getSignificantBits(),
false);
11183 if (value.getBitWidth() > MaxWidth)
11184 value = value.trunc(MaxWidth);
11188 return IntRange(value.getActiveBits(),
true);
11192 if (result.
isInt())
11199 R = IntRange::join(R, El);
11207 return IntRange::join(R, I);
11222 Ty = AtomicRHS->getValueType();
11241 bool InConstantContext,
11242 bool Approximate) {
11253 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11254 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11258 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11260 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11261 CE->getCastKind() == CK_BooleanToSignedIntegral;
11264 if (!isIntegerCast)
11265 return OutputTypeRange;
11268 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11269 InConstantContext, Approximate);
11271 return std::nullopt;
11274 if (SubRange->Width >= OutputTypeRange.Width)
11275 return OutputTypeRange;
11279 return IntRange(SubRange->Width,
11280 SubRange->NonNegative || OutputTypeRange.NonNegative);
11283 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11286 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11288 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11289 InConstantContext, Approximate);
11294 Expr *TrueExpr = CO->getTrueExpr();
11296 return std::nullopt;
11298 std::optional<IntRange> L =
11301 return std::nullopt;
11303 Expr *FalseExpr = CO->getFalseExpr();
11305 return std::nullopt;
11307 std::optional<IntRange> R =
11310 return std::nullopt;
11312 return IntRange::join(*L, *R);
11315 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11316 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11318 switch (BO->getOpcode()) {
11320 llvm_unreachable(
"builtin <=> should have class type");
11331 return IntRange::forBoolType();
11360 Combine = IntRange::bit_and;
11368 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11369 if (I->getValue() == 1) {
11370 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11371 return IntRange(R.Width,
true);
11381 case BO_ShrAssign: {
11383 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11385 return std::nullopt;
11389 if (std::optional<llvm::APSInt> shift =
11390 BO->getRHS()->getIntegerConstantExpr(
C)) {
11391 if (shift->isNonNegative()) {
11392 if (shift->uge(L->Width))
11393 L->Width = (L->NonNegative ? 0 : 1);
11395 L->Width -= shift->getZExtValue();
11409 Combine = IntRange::sum;
11413 if (BO->getLHS()->getType()->isPointerType())
11416 Combine = IntRange::difference;
11421 Combine = IntRange::product;
11430 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11432 return std::nullopt;
11435 if (std::optional<llvm::APSInt> divisor =
11436 BO->getRHS()->getIntegerConstantExpr(
C)) {
11437 unsigned log2 = divisor->logBase2();
11438 if (
log2 >= L->Width)
11439 L->Width = (L->NonNegative ? 0 : 1);
11441 L->Width = std::min(L->Width -
log2, MaxWidth);
11449 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11451 return std::nullopt;
11453 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11457 Combine = IntRange::rem;
11469 unsigned opWidth =
C.getIntWidth(
T);
11471 InConstantContext, Approximate);
11473 return std::nullopt;
11476 InConstantContext, Approximate);
11478 return std::nullopt;
11480 IntRange
C = Combine(*L, *R);
11481 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11482 C.Width = std::min(
C.Width, MaxWidth);
11486 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11487 switch (UO->getOpcode()) {
11490 return IntRange::forBoolType();
11504 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11507 return std::nullopt;
11512 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11522 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11525 return std::nullopt;
11530 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11540 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11541 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11545 return IntRange(BitField->getBitWidthValue(),
11546 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11549 return std::nullopt;
11555 bool InConstantContext,
11556 bool Approximate) {
11565 const llvm::fltSemantics &Src,
11566 const llvm::fltSemantics &Tgt) {
11567 llvm::APFloat truncated = value;
11570 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11571 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11573 return truncated.bitwiseIsEqual(value);
11582 const llvm::fltSemantics &Src,
11583 const llvm::fltSemantics &Tgt) {
11600 bool IsListInit =
false);
11615 return MacroName !=
"YES" && MacroName !=
"NO" &&
11616 MacroName !=
"true" && MacroName !=
"false";
11624 (!E->
getType()->isSignedIntegerType() ||
11639struct PromotedRange {
11641 llvm::APSInt PromotedMin;
11643 llvm::APSInt PromotedMax;
11645 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11647 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11648 else if (R.Width >= BitWidth && !
Unsigned) {
11652 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11653 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11655 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11656 .extOrTrunc(BitWidth);
11657 PromotedMin.setIsUnsigned(
Unsigned);
11659 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11660 .extOrTrunc(BitWidth);
11661 PromotedMax.setIsUnsigned(
Unsigned);
11666 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11676 InRangeFlag = 0x40,
11679 Min =
LE | InRangeFlag,
11680 InRange = InRangeFlag,
11681 Max =
GE | InRangeFlag,
11684 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11689 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11690 Value.isUnsigned() == PromotedMin.isUnsigned());
11691 if (!isContiguous()) {
11692 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11693 if (
Value.isMinValue())
return Min;
11694 if (
Value.isMaxValue())
return Max;
11695 if (
Value >= PromotedMin)
return InRange;
11696 if (
Value <= PromotedMax)
return InRange;
11700 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11701 case -1:
return Less;
11702 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11704 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11705 case -1:
return InRange;
11706 case 0:
return Max;
11711 llvm_unreachable(
"impossible compare result");
11714 static std::optional<StringRef>
11716 if (Op == BO_Cmp) {
11718 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11720 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11721 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11722 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11723 return std::nullopt;
11730 }
else if (Op == BO_NE) {
11734 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11741 if (Op == BO_GE || Op == BO_LE)
11742 std::swap(TrueFlag, FalseFlag);
11745 return StringRef(
"true");
11747 return StringRef(
"false");
11748 return std::nullopt;
11755 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11756 if (ICE->getCastKind() != CK_IntegralCast &&
11757 ICE->getCastKind() != CK_NoOp)
11759 E = ICE->getSubExpr();
11768 enum ConstantValueKind {
11773 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11774 return BL->getValue() ? ConstantValueKind::LiteralTrue
11775 : ConstantValueKind::LiteralFalse;
11776 return ConstantValueKind::Miscellaneous;
11781 const llvm::APSInt &
Value,
11782 bool RhsConstant) {
11804 if (!OtherValueRange)
11809 OtherT = AT->getValueType();
11810 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11814 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11820 bool OtherIsBooleanDespiteType =
11822 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11823 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11827 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11828 Value.isUnsigned());
11829 auto Cmp = OtherPromotedValueRange.compare(
Value);
11830 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11836 bool TautologicalTypeCompare =
false;
11838 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11839 Value.isUnsigned());
11840 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11843 TautologicalTypeCompare =
true;
11851 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11860 bool InRange = Cmp & PromotedRange::InRangeFlag;
11866 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11867 Other->getType()->isUnsignedIntegerOrEnumerationType())
11868 TautologicalTypeCompare =
true;
11873 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11874 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11878 llvm::raw_svector_ostream OS(PrettySourceValue);
11880 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11881 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11883 OS << (BL->getValue() ?
"YES" :
"NO");
11888 if (!TautologicalTypeCompare) {
11890 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11896 if (IsObjCSignedCharBool) {
11898 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11899 << OS.str() << *Result);
11906 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11910 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11911 : diag::warn_tautological_bool_compare)
11913 << OtherIsBooleanDespiteType << *Result
11920 ? diag::warn_unsigned_enum_always_true_comparison
11921 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11922 : diag::warn_unsigned_always_true_comparison)
11923 : diag::warn_tautological_constant_compare;
11926 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
11959 if (
T->isIntegralType(S.
Context)) {
11960 std::optional<llvm::APSInt> RHSValue =
11962 std::optional<llvm::APSInt> LHSValue =
11966 if (RHSValue && LHSValue)
11970 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11972 const bool RhsConstant = (
bool)RHSValue;
11973 Expr *Const = RhsConstant ? RHS : LHS;
11975 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11984 if (!
T->hasUnsignedIntegerRepresentation()) {
11998 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12000 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12006 Expr *signedOperand, *unsignedOperand;
12009 "unsigned comparison between two signed integer expressions?");
12010 signedOperand = LHS;
12011 unsignedOperand = RHS;
12013 signedOperand = RHS;
12014 unsignedOperand = LHS;
12020 std::optional<IntRange> signedRange =
12032 if (signedRange->NonNegative)
12044 if (!unsignedRange)
12049 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12051 if (unsignedRange->Width < comparisonWidth)
12056 S.
PDiag(diag::warn_mixed_sign_comparison)
12075 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12080 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12081 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12082 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12083 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12084 << BitfieldEnumDecl;
12091 Init->isValueDependent() ||
12092 Init->isTypeDependent())
12095 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12105 const PreferredTypeAttr *PTAttr =
nullptr;
12107 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12109 ED = PTAttr->getType()->getAsEnumDecl();
12117 bool SignedEnum = ED->getNumNegativeBits() > 0;
12124 unsigned DiagID = 0;
12125 if (SignedEnum && !SignedBitfield) {
12128 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12130 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12131 }
else if (SignedBitfield && !SignedEnum &&
12132 ED->getNumPositiveBits() == FieldWidth) {
12135 ? diag::warn_signed_bitfield_enum_conversion
12136 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12139 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12144 << SignedEnum << TypeRange;
12146 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12153 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12154 ED->getNumNegativeBits())
12155 : ED->getNumPositiveBits();
12158 if (BitsNeeded > FieldWidth) {
12162 ? diag::warn_bitfield_too_small_for_enum
12163 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12164 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12168 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12176 llvm::APSInt
Value = Result.Val.getInt();
12178 unsigned OriginalWidth =
Value.getBitWidth();
12184 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12185 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12192 if (!
Value.isSigned() ||
Value.isNegative())
12193 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12194 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12195 OriginalWidth =
Value.getSignificantBits();
12197 if (OriginalWidth <= FieldWidth)
12201 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12205 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12206 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12210 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12212 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12213 ? diag::warn_impcast_single_bit_bitield_precision_constant
12214 : diag::warn_impcast_bitfield_precision_constant)
12215 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12216 <<
Init->getSourceRange();
12248 bool PruneControlFlow =
false) {
12255 if (
T.hasAddressSpace())
12257 if (PruneControlFlow) {
12271 bool PruneControlFlow =
false) {
12278 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
12283 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12284 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12289 llvm::APFloat
Value(0.0);
12295 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12300 diag::warn_impcast_float_integer, PruneWarnings);
12303 bool isExact =
false;
12306 T->hasUnsignedIntegerRepresentation());
12307 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12308 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12316 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12317 precision = (precision * 59 + 195) / 196;
12318 Value.toString(PrettySourceValue, precision);
12322 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12323 << PrettySourceValue);
12326 if (Result == llvm::APFloat::opOK && isExact) {
12327 if (IsLiteral)
return;
12328 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
12334 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12337 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12338 : diag::warn_impcast_float_to_integer_out_of_range,
12341 unsigned DiagID = 0;
12344 DiagID = diag::warn_impcast_literal_float_to_integer;
12345 }
else if (IntegerValue == 0) {
12346 if (
Value.isZero()) {
12348 diag::warn_impcast_float_integer, PruneWarnings);
12351 DiagID = diag::warn_impcast_float_to_integer_zero;
12353 if (IntegerValue.isUnsigned()) {
12354 if (!IntegerValue.isMaxValue()) {
12356 diag::warn_impcast_float_integer, PruneWarnings);
12359 if (!IntegerValue.isMaxSignedValue() &&
12360 !IntegerValue.isMinSignedValue()) {
12362 diag::warn_impcast_float_integer, PruneWarnings);
12366 DiagID = diag::warn_impcast_float_to_integer;
12371 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12373 IntegerValue.toString(PrettyTargetValue);
12375 if (PruneWarnings) {
12378 << E->
getType() <<
T.getUnqualifiedType()
12379 << PrettySourceValue << PrettyTargetValue
12383 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12392 "Must be compound assignment operation");
12403 ->getComputationResultType()
12410 if (ResultBT->isInteger())
12412 E->
getExprLoc(), diag::warn_impcast_float_integer);
12414 if (!ResultBT->isFloatingPoint())
12423 diag::warn_impcast_float_result_precision);
12428 if (!Range.Width)
return "0";
12430 llvm::APSInt ValueInRange =
Value;
12431 ValueInRange.setIsSigned(!Range.NonNegative);
12432 ValueInRange = ValueInRange.trunc(Range.Width);
12433 return toString(ValueInRange, 10);
12443 const Type *Source =
12445 if (
Target->isDependentType())
12448 const auto *FloatCandidateBT =
12449 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12450 const Type *BoolCandidateType = ToBool ?
Target : Source;
12453 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12458 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12464 S, TheCall->
getArg(I - 1),
false));
12466 S, TheCall->
getArg(I + 1),
false));
12471 diag::warn_impcast_floating_point_to_bool);
12486 if (!IsGNUNullExpr && !HasNullPtrType)
12490 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12491 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12494 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12507 if (IsGNUNullExpr && Loc.
isMacroID()) {
12510 if (MacroName ==
"NULL")
12518 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12532 const char FirstLiteralCharacter =
12534 if (FirstLiteralCharacter ==
'0')
12540 if (CC.
isValid() &&
T->isCharType()) {
12541 const char FirstContextCharacter =
12543 if (FirstContextCharacter ==
'{')
12551 const auto *IL = dyn_cast<IntegerLiteral>(E);
12553 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12554 if (UO->getOpcode() == UO_Minus)
12555 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12566 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12570 if (Opc == BO_Shl) {
12573 if (LHS && LHS->getValue() == 0)
12574 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12576 RHS->getValue().isNonNegative() &&
12578 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12579 << (Result.Val.getInt() != 0);
12581 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12588 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12593 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12594 (RHS->getValue() == 0 || RHS->getValue() == 1))
12597 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12598 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12606 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12612 if (Source->isChar16Type() &&
Target->isChar32Type())
12618 llvm::APSInt
Value(32);
12619 Value = Result.Val.getInt();
12620 bool IsASCII =
Value <= 0x7F;
12621 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12622 bool ConversionPreservesSemantics =
12623 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12625 if (!ConversionPreservesSemantics) {
12626 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12627 const llvm::APSInt &
Value) {
12628 if (
T->isChar8Type())
12629 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12630 if (
T->isChar16Type())
12631 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12632 assert(
T->isChar32Type());
12633 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12636 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12645 LosesPrecision ? diag::warn_impcast_unicode_precision
12646 : diag::warn_impcast_unicode_char_type);
12651 From =
Context.getCanonicalType(From);
12652 To =
Context.getCanonicalType(To);
12655 From = MaybePointee;
12662 if (FromFn->getCFIUncheckedCalleeAttr() &&
12663 !ToFn->getCFIUncheckedCalleeAttr())
12671 bool *ICContext,
bool IsListInit) {
12676 if (Source ==
Target)
return;
12677 if (
Target->isDependentType())
return;
12687 if (Source->isAtomicType())
12691 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12697 diag::warn_impcast_string_literal_to_bool);
12703 diag::warn_impcast_objective_c_literal_to_bool);
12705 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12715 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12718 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12720 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12729 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12731 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12736 if (
Target->isSveVLSBuiltinType() &&
12743 if (
Target->isRVVVLSBuiltinType() &&
12753 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12761 diag::warn_hlsl_impcast_vector_truncation);
12773 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
12774 Target = VecTy->getElementType().getTypePtr();
12777 if (
Target->isScalarType())
12778 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
12786 diag::warn_hlsl_impcast_matrix_truncation);
12797 ? diag::err_impcast_complex_scalar
12798 : diag::warn_impcast_complex_scalar);
12805 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12811 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12814 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12816 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12858 else if (Order < 0) {
12868 if (TargetBT && TargetBT->
isInteger()) {
12895 diag::warn_impcast_floating_point_to_bool);
12903 if (Source->isFixedPointType()) {
12904 if (
Target->isUnsaturatedFixedPointType()) {
12908 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12909 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
12910 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
12913 PDiag(diag::warn_impcast_fixed_point_range)
12914 <<
Value.toString() <<
T
12920 }
else if (
Target->isIntegerType()) {
12924 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12927 llvm::APSInt IntResult = FXResult.convertToInt(
12928 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
12933 PDiag(diag::warn_impcast_fixed_point_range)
12934 << FXResult.toString() <<
T
12941 }
else if (
Target->isUnsaturatedFixedPointType()) {
12942 if (Source->isIntegerType()) {
12949 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12954 PDiag(diag::warn_impcast_fixed_point_range)
12975 unsigned int SourcePrecision =
SourceRange->Width;
12979 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12982 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12983 SourcePrecision > TargetPrecision) {
12985 if (std::optional<llvm::APSInt> SourceInt =
12990 llvm::APFloat TargetFloatValue(
12992 llvm::APFloat::opStatus ConversionStatus =
12993 TargetFloatValue.convertFromAPInt(
12995 llvm::APFloat::rmNearestTiesToEven);
12997 if (ConversionStatus != llvm::APFloat::opOK) {
12999 SourceInt->toString(PrettySourceValue, 10);
13001 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13005 PDiag(diag::warn_impcast_integer_float_precision_constant)
13006 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13012 diag::warn_impcast_integer_float_precision);
13021 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13026 if (
Target->isBooleanType())
13030 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13034 if (!Source->isIntegerType() || !
Target->isIntegerType())
13039 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13042 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13045 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13050 if (!LikelySourceRange)
13053 IntRange SourceTypeRange =
13054 IntRange::forTargetOfCanonicalType(
Context, Source);
13055 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13057 if (LikelySourceRange->Width > TargetRange.Width) {
13063 llvm::APSInt
Value(32);
13073 PDiag(diag::warn_impcast_integer_precision_constant)
13074 << PrettySourceValue << PrettyTargetValue
13084 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13085 if (UO->getOpcode() == UO_Minus)
13087 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
13090 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13094 diag::warn_impcast_integer_precision);
13097 if (TargetRange.Width > SourceTypeRange.Width) {
13098 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13099 if (UO->getOpcode() == UO_Minus)
13100 if (Source->isUnsignedIntegerType()) {
13101 if (
Target->isUnsignedIntegerType())
13103 diag::warn_impcast_high_order_zero_bits);
13104 if (
Target->isSignedIntegerType())
13106 diag::warn_impcast_nonnegative_result);
13110 if (TargetRange.Width == LikelySourceRange->Width &&
13111 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13112 Source->isSignedIntegerType()) {
13126 PDiag(diag::warn_impcast_integer_precision_constant)
13127 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13137 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13138 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13139 LikelySourceRange->Width == TargetRange.Width))) {
13143 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13145 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13149 unsigned DiagID = diag::warn_impcast_integer_sign;
13157 DiagID = diag::warn_impcast_integer_sign_conditional;
13174 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13176 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13177 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13178 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13179 TargetEnum->getDecl()->hasNameForLinkage() &&
13180 SourceEnum != TargetEnum) {
13185 diag::warn_impcast_different_enum_types);
13199 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13212 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13213 TrueExpr = BCO->getCommon();
13215 bool Suspicious =
false;
13219 if (
T->isBooleanType())
13224 if (!Suspicious)
return;
13227 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13234 Suspicious =
false;
13239 E->
getType(), CC, &Suspicious);
13256struct AnalyzeImplicitConversionsWorkItem {
13265 bool ExtraCheckForImplicitConversion,
13268 WorkList.push_back({E, CC,
false});
13270 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
13277 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13279 Expr *OrigE = Item.E;
13298 Expr *SourceExpr = E;
13303 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13304 if (
auto *Src = OVE->getSourceExpr())
13307 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13308 if (UO->getOpcode() == UO_Not &&
13309 UO->getSubExpr()->isKnownToHaveBooleanValue())
13310 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13314 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13315 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13316 BO->getLHS()->isKnownToHaveBooleanValue() &&
13317 BO->getRHS()->isKnownToHaveBooleanValue() &&
13318 BO->getLHS()->HasSideEffects(S.
Context) &&
13319 BO->getRHS()->HasSideEffects(S.
Context)) {
13330 if (SR.str() ==
"&" || SR.str() ==
"|") {
13332 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13333 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13336 BO->getOperatorLoc(),
13337 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13338 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13340 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13358 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13364 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13379 for (
auto *SE : POE->semantics())
13380 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13381 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13385 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13386 E = CE->getSubExpr();
13392 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13393 if (InitListE->getNumInits() == 1) {
13394 E = InitListE->getInit(0);
13401 WorkList.push_back({E, CC, IsListInit});
13405 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13406 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13410 if (OutArgE->isInOut())
13411 WorkList.push_back(
13412 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13413 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13419 if (BO->isComparisonOp())
13423 if (BO->getOpcode() == BO_Assign)
13426 if (BO->isAssignmentOp())
13442 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13444 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13448 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13449 if (ChildExpr == CSE->getOperand())
13455 if (IsLogicalAndOperator &&
13460 WorkList.push_back({ChildExpr, CC, IsListInit});
13474 if (
U->getOpcode() == UO_LNot) {
13476 }
else if (
U->getOpcode() != UO_AddrOf) {
13477 if (
U->getSubExpr()->getType()->isAtomicType())
13478 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13479 diag::warn_atomic_implicit_seq_cst);
13490 WorkList.push_back({OrigE, CC, IsListInit});
13491 while (!WorkList.empty())
13503 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13506 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13507 if (!M->getMemberDecl()->getType()->isReferenceType())
13509 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13510 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13512 FD =
Call->getDirectCallee();
13521 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13535 if (
SM.isMacroBodyExpansion(Loc))
13537 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13561 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13562 : diag::warn_this_bool_conversion;
13567 bool IsAddressOf =
false;
13569 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13570 if (UO->getOpcode() != UO_AddrOf)
13572 IsAddressOf =
true;
13573 E = UO->getSubExpr();
13577 unsigned DiagID = IsCompare
13578 ? diag::warn_address_of_reference_null_compare
13579 : diag::warn_address_of_reference_bool_conversion;
13587 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13590 llvm::raw_string_ostream S(Str);
13592 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13593 : diag::warn_cast_nonnull_to_bool;
13596 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13601 if (
auto *Callee =
Call->getDirectCallee()) {
13602 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13603 ComplainAboutNonnullParamOrCall(A);
13612 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13613 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13614 MRecordDecl && MRecordDecl->isLambda()) {
13617 << MRecordDecl->getSourceRange() << Range << IsEqual;
13627 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13628 D = M->getMemberDecl();
13636 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13639 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13640 ComplainAboutNonnullParamOrCall(A);
13644 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13648 auto ParamIter = llvm::find(FD->
parameters(), PV);
13650 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13654 ComplainAboutNonnullParamOrCall(
NonNull);
13659 if (ArgNo.getASTIndex() == ParamNo) {
13660 ComplainAboutNonnullParamOrCall(
NonNull);
13670 const bool IsArray =
T->isArrayType();
13671 const bool IsFunction =
T->isFunctionType();
13674 if (IsAddressOf && IsFunction) {
13679 if (!IsAddressOf && !IsFunction && !IsArray)
13684 llvm::raw_string_ostream S(Str);
13687 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13688 : diag::warn_impcast_pointer_to_bool;
13695 DiagType = AddressOf;
13696 else if (IsFunction)
13697 DiagType = FunctionPointer;
13699 DiagType = ArrayPointer;
13701 llvm_unreachable(
"Could not determine diagnostic.");
13703 << Range << IsEqual;
13716 if (ReturnType.
isNull())
13754 CheckArrayAccess(E);
13764void Sema::CheckForIntOverflow (
const Expr *E) {
13766 SmallVector<const Expr *, 2> Exprs(1, E);
13769 const Expr *OriginalE = Exprs.pop_back_val();
13777 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13778 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13781 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13782 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13783 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13785 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13786 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13787 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13788 Exprs.push_back(Temporary->getSubExpr());
13789 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13790 Exprs.push_back(Array->getIdx());
13791 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13792 Exprs.push_back(Compound->getInitializer());
13793 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13794 New &&
New->isArray()) {
13795 if (
auto ArraySize =
New->getArraySize())
13796 Exprs.push_back(*ArraySize);
13797 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13798 Exprs.push_back(MTE->getSubExpr());
13799 }
while (!Exprs.empty());
13807 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13814 class SequenceTree {
13816 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13817 unsigned Parent : 31;
13818 LLVM_PREFERRED_TYPE(
bool)
13819 unsigned Merged : 1;
13821 SmallVector<Value, 8> Values;
13827 friend class SequenceTree;
13831 explicit Seq(
unsigned N) : Index(N) {}
13834 Seq() : Index(0) {}
13837 SequenceTree() { Values.push_back(
Value(0)); }
13838 Seq root()
const {
return Seq(0); }
13843 Seq allocate(
Seq Parent) {
13844 Values.push_back(
Value(Parent.Index));
13845 return Seq(Values.size() - 1);
13850 Values[S.Index].Merged =
true;
13856 bool isUnsequenced(
Seq Cur,
Seq Old) {
13857 unsigned C = representative(Cur.Index);
13858 unsigned Target = representative(Old.Index);
13862 C = Values[
C].Parent;
13869 unsigned representative(
unsigned K) {
13870 if (Values[K].Merged)
13872 return Values[K].Parent = representative(Values[K].Parent);
13878 using Object =
const NamedDecl *;
13892 UK_ModAsSideEffect,
13894 UK_Count = UK_ModAsSideEffect + 1
13900 const Expr *UsageExpr =
nullptr;
13901 SequenceTree::Seq
Seq;
13907 Usage Uses[UK_Count];
13910 bool Diagnosed =
false;
13914 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13922 UsageInfoMap UsageMap;
13925 SequenceTree::Seq Region;
13929 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
13933 SmallVectorImpl<const Expr *> &WorkList;
13940 struct SequencedSubexpression {
13941 SequencedSubexpression(SequenceChecker &
Self)
13942 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
13943 Self.ModAsSideEffect = &ModAsSideEffect;
13946 ~SequencedSubexpression() {
13947 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13951 UsageInfo &UI =
Self.UsageMap[M.first];
13952 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13953 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13954 SideEffectUsage = M.second;
13956 Self.ModAsSideEffect = OldModAsSideEffect;
13959 SequenceChecker &
Self;
13960 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
13961 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
13968 class EvaluationTracker {
13970 EvaluationTracker(SequenceChecker &
Self)
13972 Self.EvalTracker =
this;
13975 ~EvaluationTracker() {
13976 Self.EvalTracker = Prev;
13978 Prev->EvalOK &= EvalOK;
13981 bool evaluate(
const Expr *E,
bool &
Result) {
13986 Self.SemaRef.isConstantEvaluatedContext());
13991 SequenceChecker &
Self;
13992 EvaluationTracker *Prev;
13993 bool EvalOK =
true;
13994 } *EvalTracker =
nullptr;
13998 Object getObject(
const Expr *E,
bool Mod)
const {
14000 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14001 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14002 return getObject(UO->getSubExpr(), Mod);
14003 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14004 if (BO->getOpcode() == BO_Comma)
14005 return getObject(BO->getRHS(), Mod);
14006 if (Mod && BO->isAssignmentOp())
14007 return getObject(BO->getLHS(), Mod);
14008 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14011 return ME->getMemberDecl();
14012 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14021 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14023 Usage &U = UI.Uses[UK];
14024 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14028 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14029 ModAsSideEffect->push_back(std::make_pair(O, U));
14031 U.UsageExpr = UsageExpr;
14041 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
14042 UsageKind OtherKind,
bool IsModMod) {
14046 const Usage &U = UI.Uses[OtherKind];
14047 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14050 const Expr *Mod = U.UsageExpr;
14051 const Expr *ModOrUse = UsageExpr;
14052 if (OtherKind == UK_Use)
14053 std::swap(Mod, ModOrUse);
14057 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14058 : diag::warn_unsequenced_mod_use)
14059 << O << SourceRange(ModOrUse->
getExprLoc()));
14060 UI.Diagnosed =
true;
14089 void notePreUse(Object O,
const Expr *UseExpr) {
14090 UsageInfo &UI = UsageMap[O];
14092 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14095 void notePostUse(Object O,
const Expr *UseExpr) {
14096 UsageInfo &UI = UsageMap[O];
14097 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14099 addUsage(O, UI, UseExpr, UK_Use);
14102 void notePreMod(Object O,
const Expr *ModExpr) {
14103 UsageInfo &UI = UsageMap[O];
14105 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14106 checkUsage(O, UI, ModExpr, UK_Use,
false);
14109 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
14110 UsageInfo &UI = UsageMap[O];
14111 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14113 addUsage(O, UI, ModExpr, UK);
14117 SequenceChecker(Sema &S,
const Expr *E,
14118 SmallVectorImpl<const Expr *> &WorkList)
14119 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14123 (void)this->WorkList;
14126 void VisitStmt(
const Stmt *S) {
14130 void VisitExpr(
const Expr *E) {
14132 Base::VisitStmt(E);
14135 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14136 for (
auto *Sub : CSE->
children()) {
14137 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14152 void VisitCastExpr(
const CastExpr *E) {
14164 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14165 const Expr *SequencedAfter) {
14166 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14167 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14168 SequenceTree::Seq OldRegion = Region;
14171 SequencedSubexpression SeqBefore(*
this);
14172 Region = BeforeRegion;
14173 Visit(SequencedBefore);
14176 Region = AfterRegion;
14177 Visit(SequencedAfter);
14179 Region = OldRegion;
14181 Tree.merge(BeforeRegion);
14182 Tree.merge(AfterRegion);
14185 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14190 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14197 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14198 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14199 void VisitBinPtrMem(
const BinaryOperator *BO) {
14204 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14211 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14212 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14213 void VisitBinShlShr(
const BinaryOperator *BO) {
14217 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14224 void VisitBinComma(
const BinaryOperator *BO) {
14229 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14232 void VisitBinAssign(
const BinaryOperator *BO) {
14233 SequenceTree::Seq RHSRegion;
14234 SequenceTree::Seq LHSRegion;
14236 RHSRegion = Tree.allocate(Region);
14237 LHSRegion = Tree.allocate(Region);
14239 RHSRegion = Region;
14240 LHSRegion = Region;
14242 SequenceTree::Seq OldRegion = Region;
14258 SequencedSubexpression SeqBefore(*
this);
14259 Region = RHSRegion;
14263 Region = LHSRegion;
14267 notePostUse(O, BO);
14271 Region = LHSRegion;
14275 notePostUse(O, BO);
14277 Region = RHSRegion;
14285 Region = OldRegion;
14289 : UK_ModAsSideEffect);
14291 Tree.merge(RHSRegion);
14292 Tree.merge(LHSRegion);
14296 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14297 VisitBinAssign(CAO);
14300 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14301 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14302 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14305 return VisitExpr(UO);
14313 : UK_ModAsSideEffect);
14316 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14317 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14318 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14321 return VisitExpr(UO);
14325 notePostMod(O, UO, UK_ModAsSideEffect);
14328 void VisitBinLOr(
const BinaryOperator *BO) {
14334 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14335 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14336 SequenceTree::Seq OldRegion = Region;
14338 EvaluationTracker Eval(*
this);
14340 SequencedSubexpression Sequenced(*
this);
14341 Region = LHSRegion;
14348 bool EvalResult =
false;
14349 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14350 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14351 if (ShouldVisitRHS) {
14352 Region = RHSRegion;
14356 Region = OldRegion;
14357 Tree.merge(LHSRegion);
14358 Tree.merge(RHSRegion);
14361 void VisitBinLAnd(
const BinaryOperator *BO) {
14367 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14368 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14369 SequenceTree::Seq OldRegion = Region;
14371 EvaluationTracker Eval(*
this);
14373 SequencedSubexpression Sequenced(*
this);
14374 Region = LHSRegion;
14380 bool EvalResult =
false;
14381 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14382 bool ShouldVisitRHS = !EvalOK || EvalResult;
14383 if (ShouldVisitRHS) {
14384 Region = RHSRegion;
14388 Region = OldRegion;
14389 Tree.merge(LHSRegion);
14390 Tree.merge(RHSRegion);
14393 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14398 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14414 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14415 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14416 SequenceTree::Seq OldRegion = Region;
14418 EvaluationTracker Eval(*
this);
14420 SequencedSubexpression Sequenced(*
this);
14421 Region = ConditionRegion;
14431 bool EvalResult =
false;
14432 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14433 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14434 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14435 if (ShouldVisitTrueExpr) {
14436 Region = TrueRegion;
14439 if (ShouldVisitFalseExpr) {
14440 Region = FalseRegion;
14444 Region = OldRegion;
14445 Tree.merge(ConditionRegion);
14446 Tree.merge(TrueRegion);
14447 Tree.merge(FalseRegion);
14450 void VisitCallExpr(
const CallExpr *CE) {
14462 SequencedSubexpression Sequenced(*
this);
14467 SequenceTree::Seq CalleeRegion;
14468 SequenceTree::Seq OtherRegion;
14469 if (SemaRef.getLangOpts().CPlusPlus17) {
14470 CalleeRegion = Tree.allocate(Region);
14471 OtherRegion = Tree.allocate(Region);
14473 CalleeRegion = Region;
14474 OtherRegion = Region;
14476 SequenceTree::Seq OldRegion = Region;
14479 Region = CalleeRegion;
14481 SequencedSubexpression Sequenced(*this);
14482 Visit(CE->getCallee());
14484 Visit(CE->getCallee());
14488 Region = OtherRegion;
14492 Region = OldRegion;
14494 Tree.merge(CalleeRegion);
14495 Tree.merge(OtherRegion);
14513 return VisitCallExpr(CXXOCE);
14524 case OO_MinusEqual:
14526 case OO_SlashEqual:
14527 case OO_PercentEqual:
14528 case OO_CaretEqual:
14531 case OO_LessLessEqual:
14532 case OO_GreaterGreaterEqual:
14533 SequencingKind = RHSBeforeLHS;
14537 case OO_GreaterGreater:
14543 SequencingKind = LHSBeforeRHS;
14547 SequencingKind = LHSBeforeRest;
14551 SequencingKind = NoSequencing;
14555 if (SequencingKind == NoSequencing)
14556 return VisitCallExpr(CXXOCE);
14559 SequencedSubexpression Sequenced(*
this);
14562 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14563 "Should only get there with C++17 and above!");
14564 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14565 "Should only get there with an overloaded binary operator"
14566 " or an overloaded call operator!");
14568 if (SequencingKind == LHSBeforeRest) {
14569 assert(CXXOCE->getOperator() == OO_Call &&
14570 "We should only have an overloaded call operator here!");
14579 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14580 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14581 SequenceTree::Seq OldRegion = Region;
14583 assert(CXXOCE->getNumArgs() >= 1 &&
14584 "An overloaded call operator must have at least one argument"
14585 " for the postfix-expression!");
14586 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14587 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14588 CXXOCE->getNumArgs() - 1);
14592 Region = PostfixExprRegion;
14593 SequencedSubexpression Sequenced(*this);
14594 Visit(PostfixExpr);
14598 Region = ArgsRegion;
14599 for (const Expr *Arg : Args)
14602 Region = OldRegion;
14603 Tree.merge(PostfixExprRegion);
14604 Tree.merge(ArgsRegion);
14606 assert(CXXOCE->getNumArgs() == 2 &&
14607 "Should only have two arguments here!");
14608 assert((SequencingKind == LHSBeforeRHS ||
14609 SequencingKind == RHSBeforeLHS) &&
14610 "Unexpected sequencing kind!");
14614 const Expr *E1 = CXXOCE->getArg(0);
14615 const Expr *E2 = CXXOCE->getArg(1);
14616 if (SequencingKind == RHSBeforeLHS)
14619 return VisitSequencedExpressions(E1, E2);
14626 SequencedSubexpression Sequenced(*
this);
14629 return VisitExpr(CCE);
14632 SequenceExpressionsInOrder(
14638 return VisitExpr(ILE);
14641 SequenceExpressionsInOrder(ILE->
inits());
14653 SequenceTree::Seq Parent = Region;
14654 for (
const Expr *E : ExpressionList) {
14657 Region = Tree.allocate(Parent);
14658 Elts.push_back(Region);
14664 for (
unsigned I = 0; I < Elts.size(); ++I)
14665 Tree.merge(Elts[I]);
14669SequenceChecker::UsageInfo::UsageInfo() =
default;
14673void Sema::CheckUnsequencedOperations(
const Expr *E) {
14674 SmallVector<const Expr *, 8> WorkList;
14675 WorkList.push_back(E);
14676 while (!WorkList.empty()) {
14677 const Expr *Item = WorkList.pop_back_val();
14678 SequenceChecker(*
this, Item, WorkList);
14683 bool IsConstexpr) {
14686 CheckImplicitConversions(E, CheckLoc);
14688 CheckUnsequencedOperations(E);
14690 CheckForIntOverflow(E);
14703 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14707 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14711 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14725 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14729 bool CheckParameterNames) {
14730 bool HasInvalidParm =
false;
14732 assert(Param &&
"null in a parameter list");
14741 if (!Param->isInvalidDecl() &&
14743 diag::err_typecheck_decl_incomplete_type) ||
14745 diag::err_abstract_type_in_decl,
14747 Param->setInvalidDecl();
14748 HasInvalidParm =
true;
14753 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14757 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14765 QualType PType = Param->getOriginalType();
14773 if (!Param->isInvalidDecl()) {
14774 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14775 if (!ClassDecl->isInvalidDecl() &&
14776 !ClassDecl->hasIrrelevantDestructor() &&
14777 !ClassDecl->isDependentContext() &&
14778 ClassDecl->isParamDestroyedInCallee()) {
14790 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14791 if (!Param->getType().isConstQualified())
14792 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14796 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14801 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14802 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14807 if (!Param->isInvalidDecl() &&
14808 Param->getOriginalType()->isWebAssemblyTableType()) {
14809 Param->setInvalidDecl();
14810 HasInvalidParm =
true;
14811 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14815 return HasInvalidParm;
14818std::optional<std::pair<
14827static std::pair<CharUnits, CharUnits>
14835 if (
Base->isVirtual()) {
14842 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14849 DerivedType =
Base->getType();
14852 return std::make_pair(BaseAlignment, Offset);
14856static std::optional<std::pair<CharUnits, CharUnits>>
14862 return std::nullopt;
14867 return std::nullopt;
14871 CharUnits Offset = EltSize * IdxRes->getExtValue();
14874 return std::make_pair(P->first, P->second + Offset);
14880 return std::make_pair(
14881 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14887std::optional<std::pair<
14895 case Stmt::CStyleCastExprClass:
14896 case Stmt::CXXStaticCastExprClass:
14897 case Stmt::ImplicitCastExprClass: {
14899 const Expr *From = CE->getSubExpr();
14900 switch (CE->getCastKind()) {
14905 case CK_UncheckedDerivedToBase:
14906 case CK_DerivedToBase: {
14916 case Stmt::ArraySubscriptExprClass: {
14921 case Stmt::DeclRefExprClass: {
14925 if (!VD->getType()->isReferenceType()) {
14927 if (VD->hasDependentAlignment())
14936 case Stmt::MemberExprClass: {
14938 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14942 std::optional<std::pair<CharUnits, CharUnits>> P;
14951 return std::make_pair(P->first,
14954 case Stmt::UnaryOperatorClass: {
14964 case Stmt::BinaryOperatorClass: {
14976 return std::nullopt;
14981std::optional<std::pair<
14990 case Stmt::CStyleCastExprClass:
14991 case Stmt::CXXStaticCastExprClass:
14992 case Stmt::ImplicitCastExprClass: {
14994 const Expr *From = CE->getSubExpr();
14995 switch (CE->getCastKind()) {
15000 case CK_ArrayToPointerDecay:
15002 case CK_UncheckedDerivedToBase:
15003 case CK_DerivedToBase: {
15013 case Stmt::CXXThisExprClass: {
15018 case Stmt::UnaryOperatorClass: {
15024 case Stmt::BinaryOperatorClass: {
15033 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15034 std::swap(LHS, RHS);
15044 return std::nullopt;
15049 std::optional<std::pair<CharUnits, CharUnits>> P =
15053 return P->first.alignmentAtOffset(P->second);
15071 if (!DestPtr)
return;
15077 if (DestAlign.
isOne())
return;
15081 if (!SrcPtr)
return;
15092 if (SrcAlign >= DestAlign)
return;
15097 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15101void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15103 bool AllowOnePastEnd,
bool IndexNegated) {
15112 const Type *EffectiveType =
15116 Context.getAsConstantArrayType(BaseExpr->
getType());
15119 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15121 const Type *BaseType =
15123 bool IsUnboundedArray =
15125 Context, StrictFlexArraysLevel,
15128 (!IsUnboundedArray && BaseType->isDependentType()))
15136 if (IndexNegated) {
15137 index.setIsUnsigned(
false);
15141 if (IsUnboundedArray) {
15144 if (
index.isUnsigned() || !
index.isNegative()) {
15146 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15148 if (
index.getBitWidth() < AddrBits)
15150 std::optional<CharUnits> ElemCharUnits =
15151 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15154 if (!ElemCharUnits || ElemCharUnits->isZero())
15156 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15161 if (
index.getActiveBits() <= AddrBits) {
15163 llvm::APInt Product(
index);
15165 Product = Product.umul_ov(ElemBytes, Overflow);
15166 if (!Overflow && Product.getActiveBits() <= AddrBits)
15172 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15173 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15175 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15176 MaxElems = MaxElems.udiv(ElemBytes);
15179 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15180 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15185 PDiag(DiagID) << index << AddrBits
15186 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15187 << ElemBytes << MaxElems
15188 << MaxElems.getZExtValue()
15191 const NamedDecl *ND =
nullptr;
15193 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15195 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15197 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15198 ND = ME->getMemberDecl();
15202 PDiag(diag::note_array_declared_here) << ND);
15207 if (index.isUnsigned() || !index.isNegative()) {
15217 llvm::APInt size = ArrayTy->
getSize();
15219 if (BaseType != EffectiveType) {
15227 if (!ptrarith_typesize)
15228 ptrarith_typesize =
Context.getCharWidth();
15230 if (ptrarith_typesize != array_typesize) {
15232 uint64_t ratio = array_typesize / ptrarith_typesize;
15236 if (ptrarith_typesize * ratio == array_typesize)
15237 size *= llvm::APInt(size.getBitWidth(), ratio);
15241 if (size.getBitWidth() > index.getBitWidth())
15242 index = index.zext(size.getBitWidth());
15243 else if (size.getBitWidth() < index.getBitWidth())
15244 size = size.zext(index.getBitWidth());
15250 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15257 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15259 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15260 SourceLocation IndexLoc =
15262 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15267 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15268 : diag::warn_ptr_arith_exceeds_bounds;
15269 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15270 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15274 << index << ArrayTy->
desugar() << CastMsg
15277 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15279 DiagID = diag::warn_ptr_arith_precedes_bounds;
15280 if (index.isNegative()) index = -index;
15287 const NamedDecl *ND =
nullptr;
15289 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15291 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15293 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15294 ND = ME->getMemberDecl();
15298 PDiag(diag::note_array_declared_here) << ND);
15301void Sema::CheckArrayAccess(
const Expr *
expr) {
15302 int AllowOnePastEnd = 0;
15304 expr =
expr->IgnoreParenImpCasts();
15305 switch (
expr->getStmtClass()) {
15306 case Stmt::ArraySubscriptExprClass: {
15309 AllowOnePastEnd > 0);
15313 case Stmt::MemberExprClass: {
15317 case Stmt::ArraySectionExprClass: {
15323 nullptr, AllowOnePastEnd > 0);
15326 case Stmt::UnaryOperatorClass: {
15342 case Stmt::ConditionalOperatorClass: {
15344 if (
const Expr *lhs = cond->
getLHS())
15345 CheckArrayAccess(lhs);
15346 if (
const Expr *rhs = cond->
getRHS())
15347 CheckArrayAccess(rhs);
15350 case Stmt::CXXOperatorCallExprClass: {
15352 for (
const auto *Arg : OCE->arguments())
15353 CheckArrayAccess(Arg);
15363 Expr *RHS,
bool isProperty) {
15375 S.
Diag(Loc, diag::warn_arc_literal_assign)
15377 << (isProperty ? 0 : 1)
15385 Expr *RHS,
bool isProperty) {
15388 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15389 S.
Diag(Loc, diag::warn_arc_retained_assign)
15391 << (isProperty ? 0 : 1)
15395 RHS =
cast->getSubExpr();
15437 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15466 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15467 Diag(Loc, diag::warn_arc_retained_property_assign)
15471 RHS =
cast->getSubExpr();
15494 bool StmtLineInvalid;
15495 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15497 if (StmtLineInvalid)
15500 bool BodyLineInvalid;
15501 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15503 if (BodyLineInvalid)
15507 if (StmtLine != BodyLine)
15522 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15531 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15535 const Stmt *PossibleBody) {
15541 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15542 StmtLoc = FS->getRParenLoc();
15543 Body = FS->getBody();
15544 DiagID = diag::warn_empty_for_body;
15545 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15546 StmtLoc = WS->getRParenLoc();
15547 Body = WS->getBody();
15548 DiagID = diag::warn_empty_while_body;
15553 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15577 if (!ProbableTypo) {
15578 bool BodyColInvalid;
15579 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15581 if (BodyColInvalid)
15584 bool StmtColInvalid;
15587 if (StmtColInvalid)
15590 if (BodyCol > StmtCol)
15591 ProbableTypo =
true;
15594 if (ProbableTypo) {
15596 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15604 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15616 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15618 RHSExpr = CE->
getArg(0);
15619 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15620 CXXSCE && CXXSCE->isXValue())
15621 RHSExpr = CXXSCE->getSubExpr();
15625 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15626 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15629 if (LHSDeclRef && RHSDeclRef) {
15636 auto D =
Diag(OpLoc, diag::warn_self_move)
15652 const Expr *LHSBase = LHSExpr;
15653 const Expr *RHSBase = RHSExpr;
15654 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15655 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15656 if (!LHSME || !RHSME)
15659 while (LHSME && RHSME) {
15666 LHSME = dyn_cast<MemberExpr>(LHSBase);
15667 RHSME = dyn_cast<MemberExpr>(RHSBase);
15670 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15671 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15672 if (LHSDeclRef && RHSDeclRef) {
15679 Diag(OpLoc, diag::warn_self_move)
15686 Diag(OpLoc, diag::warn_self_move)
15710 bool AreUnionMembers =
false) {
15714 assert(((Field1Parent->isStructureOrClassType() &&
15715 Field2Parent->isStructureOrClassType()) ||
15716 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15717 "Can't evaluate layout compatibility between a struct field and a "
15719 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15720 (AreUnionMembers && Field1Parent->isUnionType())) &&
15721 "AreUnionMembers should be 'true' for union fields (only).");
15735 if (Bits1 != Bits2)
15739 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15740 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15743 if (!AreUnionMembers &&
15755 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15756 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15758 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15759 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15764 return isLayoutCompatible(C, F1, F2);
15775 for (
auto *Field1 : RD1->
fields()) {
15776 auto I = UnmatchedFields.begin();
15777 auto E = UnmatchedFields.end();
15779 for ( ; I != E; ++I) {
15781 bool Result = UnmatchedFields.erase(*I);
15791 return UnmatchedFields.empty();
15817 if (
C.hasSameType(T1, T2))
15826 if (TC1 == Type::Enum)
15828 if (TC1 == Type::Record) {
15847 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15878 const ValueDecl **VD, uint64_t *MagicValue,
15879 bool isConstantEvaluated) {
15887 case Stmt::UnaryOperatorClass: {
15896 case Stmt::DeclRefExprClass: {
15902 case Stmt::IntegerLiteralClass: {
15904 llvm::APInt MagicValueAPInt = IL->
getValue();
15905 if (MagicValueAPInt.getActiveBits() <= 64) {
15906 *MagicValue = MagicValueAPInt.getZExtValue();
15912 case Stmt::BinaryConditionalOperatorClass:
15913 case Stmt::ConditionalOperatorClass: {
15918 isConstantEvaluated)) {
15928 case Stmt::BinaryOperatorClass: {
15931 TypeExpr = BO->
getRHS();
15961 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15964 bool isConstantEvaluated) {
15965 FoundWrongKind =
false;
15970 uint64_t MagicValue;
15972 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15976 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15977 if (I->getArgumentKind() != ArgumentKind) {
15978 FoundWrongKind =
true;
15981 TypeInfo.Type = I->getMatchingCType();
15982 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15983 TypeInfo.MustBeNull = I->getMustBeNull();
15994 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15995 if (I == MagicValues->end())
16004 bool LayoutCompatible,
16006 if (!TypeTagForDatatypeMagicValues)
16007 TypeTagForDatatypeMagicValues.reset(
16008 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16011 (*TypeTagForDatatypeMagicValues)[Magic] =
16027 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16028 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16029 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16030 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16033void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16036 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16037 bool IsPointerAttr = Attr->getIsPointer();
16040 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16041 if (TypeTagIdxAST >= ExprArgs.size()) {
16042 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16043 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16046 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16047 bool FoundWrongKind;
16050 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16052 if (FoundWrongKind)
16054 diag::warn_type_tag_for_datatype_wrong_kind)
16060 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16061 if (ArgumentIdxAST >= ExprArgs.size()) {
16062 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16063 << 1 << Attr->getArgumentIdx().getSourceIndex();
16066 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16067 if (IsPointerAttr) {
16069 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16070 if (ICE->getType()->isVoidPointerType() &&
16071 ICE->getCastKind() == CK_BitCast)
16072 ArgumentExpr = ICE->getSubExpr();
16074 QualType ArgumentType = ArgumentExpr->
getType();
16080 if (TypeInfo.MustBeNull) {
16085 diag::warn_type_safety_null_pointer_required)
16093 QualType RequiredType = TypeInfo.Type;
16095 RequiredType =
Context.getPointerType(RequiredType);
16097 bool mismatch =
false;
16098 if (!TypeInfo.LayoutCompatible) {
16099 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16120 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16121 << ArgumentType << ArgumentKind
16122 << TypeInfo.LayoutCompatible << RequiredType
16140 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16148 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
16154 auto &MisalignedMembersForExpr =
16156 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16157 if (MA != MisalignedMembersForExpr.end() &&
16158 (
T->isDependentType() ||
T->isIntegerType() ||
16159 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
16161 T->getPointeeType()) <= MA->Alignment))))
16162 MisalignedMembersForExpr.erase(MA);
16171 const auto *ME = dyn_cast<MemberExpr>(E);
16183 bool AnyIsPacked =
false;
16185 QualType BaseType = ME->getBase()->getType();
16186 if (BaseType->isDependentType())
16190 auto *RD = BaseType->castAsRecordDecl();
16195 auto *FD = dyn_cast<FieldDecl>(MD);
16201 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16202 ReverseMemberChain.push_back(FD);
16205 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16207 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16214 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16225 if (ExpectedAlignment.
isOne())
16230 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16231 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16235 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16239 if (DRE && !TopME->
isArrow()) {
16242 CompleteObjectAlignment =
16243 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16247 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16250 CompleteObjectAlignment < ExpectedAlignment) {
16261 for (
FieldDecl *FDI : ReverseMemberChain) {
16262 if (FDI->hasAttr<PackedAttr>() ||
16263 FDI->getParent()->hasAttr<PackedAttr>()) {
16265 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16271 assert(FD &&
"We did not find a packed FieldDecl!");
16272 Action(E, FD->
getParent(), FD, Alignment);
16276void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16277 using namespace std::placeholders;
16280 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16304bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16305 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16318 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
16319 TheCall->
setType(VecTy0->getElementType());
16332 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16349 assert(!Args.empty() &&
"Should have at least one argument.");
16351 Expr *Arg0 = Args.front();
16354 auto EmitError = [&](
Expr *ArgI) {
16356 diag::err_typecheck_call_different_arg_types)
16357 << Arg0->
getType() << ArgI->getType();
16362 for (
Expr *ArgI : Args.drop_front())
16373 for (
Expr *ArgI : Args.drop_front()) {
16374 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16377 VecI->getElementType()) ||
16378 Vec0->getNumElements() != VecI->getNumElements()) {
16387std::optional<QualType>
16391 return std::nullopt;
16395 return std::nullopt;
16398 for (
int I = 0; I < 2; ++I) {
16402 return std::nullopt;
16403 Args[I] = Converted.
get();
16410 return std::nullopt;
16413 return std::nullopt;
16415 TheCall->
setArg(0, Args[0]);
16416 TheCall->
setArg(1, Args[1]);
16427 TheCall->
getArg(1), Loc) ||
16429 TheCall->
getArg(2), Loc))
16433 for (
int I = 0; I < 3; ++I) {
16438 Args[I] = Converted.
get();
16441 int ArgOrdinal = 1;
16442 for (
Expr *Arg : Args) {
16444 ArgTyRestr, ArgOrdinal++))
16451 for (
int I = 0; I < 3; ++I)
16452 TheCall->
setArg(I, Args[I]);
16458bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16470bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16479 diag::err_builtin_invalid_arg_type)
16480 << 1 << 2 << 1 << 1 << TyArg;
16494 Expr *Matrix = MatrixArg.
get();
16496 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16499 << 1 << 3 << 0 << 0
16506 QualType ResultType =
Context.getConstantMatrixType(
16507 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16510 TheCall->
setType(ResultType);
16513 TheCall->
setArg(0, Matrix);
16518static std::optional<unsigned>
16526 uint64_t
Dim =
Value->getZExtValue();
16542 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16544 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16552 unsigned PtrArgIdx = 0;
16553 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16554 Expr *RowsExpr = TheCall->
getArg(1);
16555 Expr *ColumnsExpr = TheCall->
getArg(2);
16556 Expr *StrideExpr = TheCall->
getArg(3);
16558 bool ArgError =
false;
16565 PtrExpr = PtrConv.
get();
16566 TheCall->
setArg(0, PtrExpr);
16573 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16574 QualType ElementTy;
16577 << PtrArgIdx + 1 << 0 << 5 << 0
16581 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16585 << PtrArgIdx + 1 << 0 << 5
16592 auto ApplyArgumentConversions = [
this](Expr *E) {
16601 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16603 RowsExpr = RowsConv.
get();
16604 TheCall->
setArg(1, RowsExpr);
16606 RowsExpr =
nullptr;
16608 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16610 ColumnsExpr = ColumnsConv.
get();
16611 TheCall->
setArg(2, ColumnsExpr);
16613 ColumnsExpr =
nullptr;
16624 std::optional<unsigned> MaybeRows;
16628 std::optional<unsigned> MaybeColumns;
16633 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16636 StrideExpr = StrideConv.
get();
16637 TheCall->
setArg(3, StrideExpr);
16640 if (std::optional<llvm::APSInt>
Value =
16643 if (Stride < *MaybeRows) {
16645 diag::err_builtin_matrix_stride_too_small);
16651 if (ArgError || !MaybeRows || !MaybeColumns)
16655 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16666 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16668 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16676 unsigned PtrArgIdx = 1;
16677 Expr *MatrixExpr = TheCall->
getArg(0);
16678 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16679 Expr *StrideExpr = TheCall->
getArg(2);
16681 bool ArgError =
false;
16687 MatrixExpr = MatrixConv.
get();
16688 TheCall->
setArg(0, MatrixExpr);
16695 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16698 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16706 PtrExpr = PtrConv.
get();
16707 TheCall->
setArg(1, PtrExpr);
16715 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16718 << PtrArgIdx + 1 << 0 << 5 << 0
16722 QualType ElementTy = PtrTy->getPointeeType();
16724 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16729 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16731 diag::err_builtin_matrix_pointer_arg_mismatch)
16732 << ElementTy << MatrixTy->getElementType();
16747 StrideExpr = StrideConv.
get();
16748 TheCall->
setArg(2, StrideExpr);
16753 if (std::optional<llvm::APSInt>
Value =
16756 if (Stride < MatrixTy->getNumRows()) {
16758 diag::err_builtin_matrix_stride_too_small);
16778 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16783 llvm::StringSet<> CalleeTCBs;
16784 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16785 CalleeTCBs.insert(A->getTCBName());
16786 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16787 CalleeTCBs.insert(A->getTCBName());
16791 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16792 StringRef CallerTCB = A->getTCBName();
16793 if (CalleeTCBs.count(CallerTCB) == 0) {
16794 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16795 << 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.