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;
2335 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2337 << (OnlyUnsigned ? 3 : 1)
2345 ArgIndex(ArgIndex), OnlyUnsigned(OnlyUnsigned) {}
2348 return OnlyUnsigned ?
T->isUnsignedIntegerType() :
T->isIntegerType();
2353 return emitError(S, Loc,
T);
2358 return emitError(S, Loc,
T);
2364 return emitError(S, Loc,
T);
2369 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2374 return emitError(S, Loc,
T);
2379 return S.
Diag(Conv->
getLocation(), diag::note_conv_function_declared_at);
2385 llvm_unreachable(
"conversion functions are permitted");
2404 TheCall->
setArg(0, Arg0);
2418 TheCall->
setArg(1, Arg1);
2429 unsigned Pos,
bool AllowConst,
2433 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2438 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2439 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2440 << Pos <<
"scalar pointer";
2449 diag::err_typecheck_convert_incompatible)
2458 bool TypeDependent =
false;
2459 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2487 Builtin::BI__builtin_masked_load))
2501 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2524 Builtin::BI__builtin_masked_store))
2532 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2542 diag::err_vec_builtin_incompatible_vector)
2571 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2584 << MaskTy << IdxTy);
2593 diag::err_vec_masked_load_store_ptr)
2622 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2638 << MaskTy << IdxTy);
2644 << MaskTy << ValTy);
2650 diag::err_vec_builtin_incompatible_vector)
2664 if (Args.size() == 0) {
2666 diag::err_typecheck_call_too_few_args_at_least)
2672 QualType FuncT = Args[0]->getType();
2675 if (Args.size() < 2) {
2677 diag::err_typecheck_call_too_few_args_at_least)
2683 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2684 QualType ObjectT = Args[1]->getType();
2686 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2735 tok::periodstar, ObjectArg.
get(), Args[0]);
2739 if (MPT->isMemberDataPointer())
2742 auto *MemCall =
new (S.
Context)
2765Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2770 unsigned ICEArguments = 0;
2772 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2777 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2779 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2784 if (ArgNo < TheCall->getNumArgs() &&
2787 ICEArguments &= ~(1 << ArgNo);
2791 switch (BuiltinID) {
2792 case Builtin::BI__builtin_cpu_supports:
2793 case Builtin::BI__builtin_cpu_is:
2795 Context.getAuxTargetInfo(), BuiltinID))
2798 case Builtin::BI__builtin_cpu_init:
2799 if (!
Context.getTargetInfo().supportsCpuInit()) {
2805 case Builtin::BI__builtin___CFStringMakeConstantString:
2809 *
this, BuiltinID, TheCall,
2810 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2813 "Wrong # arguments to builtin CFStringMakeConstantString");
2814 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2817 case Builtin::BI__builtin_ms_va_start:
2818 case Builtin::BI__builtin_stdarg_start:
2819 case Builtin::BI__builtin_va_start:
2820 case Builtin::BI__builtin_c23_va_start:
2821 if (BuiltinVAStart(BuiltinID, TheCall))
2824 case Builtin::BI__va_start: {
2825 switch (
Context.getTargetInfo().getTriple().getArch()) {
2826 case llvm::Triple::aarch64:
2827 case llvm::Triple::arm:
2828 case llvm::Triple::thumb:
2829 if (BuiltinVAStartARMMicrosoft(TheCall))
2833 if (BuiltinVAStart(BuiltinID, TheCall))
2841 case Builtin::BI_interlockedbittestandset_acq:
2842 case Builtin::BI_interlockedbittestandset_rel:
2843 case Builtin::BI_interlockedbittestandset_nf:
2844 case Builtin::BI_interlockedbittestandreset_acq:
2845 case Builtin::BI_interlockedbittestandreset_rel:
2846 case Builtin::BI_interlockedbittestandreset_nf:
2849 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2854 case Builtin::BI_bittest64:
2855 case Builtin::BI_bittestandcomplement64:
2856 case Builtin::BI_bittestandreset64:
2857 case Builtin::BI_bittestandset64:
2858 case Builtin::BI_interlockedbittestandreset64:
2859 case Builtin::BI_interlockedbittestandset64:
2862 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2863 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2868 case Builtin::BI_interlockedbittestandreset64_acq:
2869 case Builtin::BI_interlockedbittestandreset64_rel:
2870 case Builtin::BI_interlockedbittestandreset64_nf:
2871 case Builtin::BI_interlockedbittestandset64_acq:
2872 case Builtin::BI_interlockedbittestandset64_rel:
2873 case Builtin::BI_interlockedbittestandset64_nf:
2878 case Builtin::BI__builtin_set_flt_rounds:
2881 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2882 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2883 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2884 llvm::Triple::ppc64le}))
2888 case Builtin::BI__builtin_isgreater:
2889 case Builtin::BI__builtin_isgreaterequal:
2890 case Builtin::BI__builtin_isless:
2891 case Builtin::BI__builtin_islessequal:
2892 case Builtin::BI__builtin_islessgreater:
2893 case Builtin::BI__builtin_isunordered:
2894 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2897 case Builtin::BI__builtin_fpclassify:
2898 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2901 case Builtin::BI__builtin_isfpclass:
2902 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2905 case Builtin::BI__builtin_isfinite:
2906 case Builtin::BI__builtin_isinf:
2907 case Builtin::BI__builtin_isinf_sign:
2908 case Builtin::BI__builtin_isnan:
2909 case Builtin::BI__builtin_issignaling:
2910 case Builtin::BI__builtin_isnormal:
2911 case Builtin::BI__builtin_issubnormal:
2912 case Builtin::BI__builtin_iszero:
2913 case Builtin::BI__builtin_signbit:
2914 case Builtin::BI__builtin_signbitf:
2915 case Builtin::BI__builtin_signbitl:
2916 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2919 case Builtin::BI__builtin_shufflevector:
2923 case Builtin::BI__builtin_masked_load:
2924 case Builtin::BI__builtin_masked_expand_load:
2926 case Builtin::BI__builtin_masked_store:
2927 case Builtin::BI__builtin_masked_compress_store:
2929 case Builtin::BI__builtin_masked_gather:
2931 case Builtin::BI__builtin_masked_scatter:
2933 case Builtin::BI__builtin_invoke:
2935 case Builtin::BI__builtin_prefetch:
2936 if (BuiltinPrefetch(TheCall))
2939 case Builtin::BI__builtin_alloca_with_align:
2940 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2941 if (BuiltinAllocaWithAlign(TheCall))
2944 case Builtin::BI__builtin_alloca:
2945 case Builtin::BI__builtin_alloca_uninitialized:
2952 case Builtin::BI__builtin_infer_alloc_token:
2956 case Builtin::BI__arithmetic_fence:
2957 if (BuiltinArithmeticFence(TheCall))
2960 case Builtin::BI__assume:
2961 case Builtin::BI__builtin_assume:
2962 if (BuiltinAssume(TheCall))
2965 case Builtin::BI__builtin_assume_aligned:
2966 if (BuiltinAssumeAligned(TheCall))
2969 case Builtin::BI__builtin_dynamic_object_size:
2970 case Builtin::BI__builtin_object_size:
2974 case Builtin::BI__builtin_longjmp:
2975 if (BuiltinLongjmp(TheCall))
2978 case Builtin::BI__builtin_setjmp:
2979 if (BuiltinSetjmp(TheCall))
2982 case Builtin::BI__builtin_classify_type:
2987 case Builtin::BI__builtin_complex:
2988 if (BuiltinComplex(TheCall))
2991 case Builtin::BI__builtin_constant_p: {
3000 case Builtin::BI__builtin_launder:
3002 case Builtin::BI__builtin_is_within_lifetime:
3004 case Builtin::BI__builtin_trivially_relocate:
3007 case Builtin::BI__sync_fetch_and_add:
3008 case Builtin::BI__sync_fetch_and_add_1:
3009 case Builtin::BI__sync_fetch_and_add_2:
3010 case Builtin::BI__sync_fetch_and_add_4:
3011 case Builtin::BI__sync_fetch_and_add_8:
3012 case Builtin::BI__sync_fetch_and_add_16:
3013 case Builtin::BI__sync_fetch_and_sub:
3014 case Builtin::BI__sync_fetch_and_sub_1:
3015 case Builtin::BI__sync_fetch_and_sub_2:
3016 case Builtin::BI__sync_fetch_and_sub_4:
3017 case Builtin::BI__sync_fetch_and_sub_8:
3018 case Builtin::BI__sync_fetch_and_sub_16:
3019 case Builtin::BI__sync_fetch_and_or:
3020 case Builtin::BI__sync_fetch_and_or_1:
3021 case Builtin::BI__sync_fetch_and_or_2:
3022 case Builtin::BI__sync_fetch_and_or_4:
3023 case Builtin::BI__sync_fetch_and_or_8:
3024 case Builtin::BI__sync_fetch_and_or_16:
3025 case Builtin::BI__sync_fetch_and_and:
3026 case Builtin::BI__sync_fetch_and_and_1:
3027 case Builtin::BI__sync_fetch_and_and_2:
3028 case Builtin::BI__sync_fetch_and_and_4:
3029 case Builtin::BI__sync_fetch_and_and_8:
3030 case Builtin::BI__sync_fetch_and_and_16:
3031 case Builtin::BI__sync_fetch_and_xor:
3032 case Builtin::BI__sync_fetch_and_xor_1:
3033 case Builtin::BI__sync_fetch_and_xor_2:
3034 case Builtin::BI__sync_fetch_and_xor_4:
3035 case Builtin::BI__sync_fetch_and_xor_8:
3036 case Builtin::BI__sync_fetch_and_xor_16:
3037 case Builtin::BI__sync_fetch_and_nand:
3038 case Builtin::BI__sync_fetch_and_nand_1:
3039 case Builtin::BI__sync_fetch_and_nand_2:
3040 case Builtin::BI__sync_fetch_and_nand_4:
3041 case Builtin::BI__sync_fetch_and_nand_8:
3042 case Builtin::BI__sync_fetch_and_nand_16:
3043 case Builtin::BI__sync_add_and_fetch:
3044 case Builtin::BI__sync_add_and_fetch_1:
3045 case Builtin::BI__sync_add_and_fetch_2:
3046 case Builtin::BI__sync_add_and_fetch_4:
3047 case Builtin::BI__sync_add_and_fetch_8:
3048 case Builtin::BI__sync_add_and_fetch_16:
3049 case Builtin::BI__sync_sub_and_fetch:
3050 case Builtin::BI__sync_sub_and_fetch_1:
3051 case Builtin::BI__sync_sub_and_fetch_2:
3052 case Builtin::BI__sync_sub_and_fetch_4:
3053 case Builtin::BI__sync_sub_and_fetch_8:
3054 case Builtin::BI__sync_sub_and_fetch_16:
3055 case Builtin::BI__sync_and_and_fetch:
3056 case Builtin::BI__sync_and_and_fetch_1:
3057 case Builtin::BI__sync_and_and_fetch_2:
3058 case Builtin::BI__sync_and_and_fetch_4:
3059 case Builtin::BI__sync_and_and_fetch_8:
3060 case Builtin::BI__sync_and_and_fetch_16:
3061 case Builtin::BI__sync_or_and_fetch:
3062 case Builtin::BI__sync_or_and_fetch_1:
3063 case Builtin::BI__sync_or_and_fetch_2:
3064 case Builtin::BI__sync_or_and_fetch_4:
3065 case Builtin::BI__sync_or_and_fetch_8:
3066 case Builtin::BI__sync_or_and_fetch_16:
3067 case Builtin::BI__sync_xor_and_fetch:
3068 case Builtin::BI__sync_xor_and_fetch_1:
3069 case Builtin::BI__sync_xor_and_fetch_2:
3070 case Builtin::BI__sync_xor_and_fetch_4:
3071 case Builtin::BI__sync_xor_and_fetch_8:
3072 case Builtin::BI__sync_xor_and_fetch_16:
3073 case Builtin::BI__sync_nand_and_fetch:
3074 case Builtin::BI__sync_nand_and_fetch_1:
3075 case Builtin::BI__sync_nand_and_fetch_2:
3076 case Builtin::BI__sync_nand_and_fetch_4:
3077 case Builtin::BI__sync_nand_and_fetch_8:
3078 case Builtin::BI__sync_nand_and_fetch_16:
3079 case Builtin::BI__sync_val_compare_and_swap:
3080 case Builtin::BI__sync_val_compare_and_swap_1:
3081 case Builtin::BI__sync_val_compare_and_swap_2:
3082 case Builtin::BI__sync_val_compare_and_swap_4:
3083 case Builtin::BI__sync_val_compare_and_swap_8:
3084 case Builtin::BI__sync_val_compare_and_swap_16:
3085 case Builtin::BI__sync_bool_compare_and_swap:
3086 case Builtin::BI__sync_bool_compare_and_swap_1:
3087 case Builtin::BI__sync_bool_compare_and_swap_2:
3088 case Builtin::BI__sync_bool_compare_and_swap_4:
3089 case Builtin::BI__sync_bool_compare_and_swap_8:
3090 case Builtin::BI__sync_bool_compare_and_swap_16:
3091 case Builtin::BI__sync_lock_test_and_set:
3092 case Builtin::BI__sync_lock_test_and_set_1:
3093 case Builtin::BI__sync_lock_test_and_set_2:
3094 case Builtin::BI__sync_lock_test_and_set_4:
3095 case Builtin::BI__sync_lock_test_and_set_8:
3096 case Builtin::BI__sync_lock_test_and_set_16:
3097 case Builtin::BI__sync_lock_release:
3098 case Builtin::BI__sync_lock_release_1:
3099 case Builtin::BI__sync_lock_release_2:
3100 case Builtin::BI__sync_lock_release_4:
3101 case Builtin::BI__sync_lock_release_8:
3102 case Builtin::BI__sync_lock_release_16:
3103 case Builtin::BI__sync_swap:
3104 case Builtin::BI__sync_swap_1:
3105 case Builtin::BI__sync_swap_2:
3106 case Builtin::BI__sync_swap_4:
3107 case Builtin::BI__sync_swap_8:
3108 case Builtin::BI__sync_swap_16:
3109 return BuiltinAtomicOverloaded(TheCallResult);
3110 case Builtin::BI__sync_synchronize:
3114 case Builtin::BI__builtin_nontemporal_load:
3115 case Builtin::BI__builtin_nontemporal_store:
3116 return BuiltinNontemporalOverloaded(TheCallResult);
3117 case Builtin::BI__builtin_memcpy_inline: {
3118 clang::Expr *SizeOp = TheCall->
getArg(2);
3130 case Builtin::BI__builtin_memset_inline: {
3131 clang::Expr *SizeOp = TheCall->
getArg(2);
3141#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3142 case Builtin::BI##ID: \
3143 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3144#include "clang/Basic/Builtins.inc"
3145 case Builtin::BI__annotation:
3149 case Builtin::BI__builtin_annotation:
3153 case Builtin::BI__builtin_addressof:
3157 case Builtin::BI__builtin_function_start:
3161 case Builtin::BI__builtin_is_aligned:
3162 case Builtin::BI__builtin_align_up:
3163 case Builtin::BI__builtin_align_down:
3167 case Builtin::BI__builtin_add_overflow:
3168 case Builtin::BI__builtin_sub_overflow:
3169 case Builtin::BI__builtin_mul_overflow:
3173 case Builtin::BI__builtin_operator_new:
3174 case Builtin::BI__builtin_operator_delete: {
3175 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3177 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3180 case Builtin::BI__builtin_dump_struct:
3182 case Builtin::BI__builtin_expect_with_probability: {
3187 const Expr *ProbArg = TheCall->
getArg(2);
3188 SmallVector<PartialDiagnosticAt, 8> Notes;
3189 Expr::EvalResult Eval;
3193 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3200 bool LoseInfo =
false;
3201 Probability.convert(llvm::APFloat::IEEEdouble(),
3202 llvm::RoundingMode::Dynamic, &LoseInfo);
3203 if (!(Probability >= llvm::APFloat(0.0) &&
3204 Probability <= llvm::APFloat(1.0))) {
3211 case Builtin::BI__builtin_preserve_access_index:
3215 case Builtin::BI__builtin_call_with_static_chain:
3219 case Builtin::BI__exception_code:
3220 case Builtin::BI_exception_code:
3222 diag::err_seh___except_block))
3225 case Builtin::BI__exception_info:
3226 case Builtin::BI_exception_info:
3228 diag::err_seh___except_filter))
3231 case Builtin::BI__GetExceptionInfo:
3243 case Builtin::BIaddressof:
3244 case Builtin::BI__addressof:
3245 case Builtin::BIforward:
3246 case Builtin::BIforward_like:
3247 case Builtin::BImove:
3248 case Builtin::BImove_if_noexcept:
3249 case Builtin::BIas_const: {
3257 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3258 BuiltinID == Builtin::BI__addressof;
3260 (ReturnsPointer ?
Result->isAnyPointerType()
3261 :
Result->isReferenceType()) &&
3264 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3270 case Builtin::BI__builtin_ptrauth_strip:
3272 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3274 case Builtin::BI__builtin_ptrauth_sign_constant:
3277 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3280 case Builtin::BI__builtin_ptrauth_auth:
3283 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3285 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3287 case Builtin::BI__builtin_ptrauth_string_discriminator:
3290 case Builtin::BI__builtin_get_vtable_pointer:
3294 case Builtin::BIread_pipe:
3295 case Builtin::BIwrite_pipe:
3298 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3301 case Builtin::BIreserve_read_pipe:
3302 case Builtin::BIreserve_write_pipe:
3303 case Builtin::BIwork_group_reserve_read_pipe:
3304 case Builtin::BIwork_group_reserve_write_pipe:
3305 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3308 case Builtin::BIsub_group_reserve_read_pipe:
3309 case Builtin::BIsub_group_reserve_write_pipe:
3310 if (
OpenCL().checkSubgroupExt(TheCall) ||
3311 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3314 case Builtin::BIcommit_read_pipe:
3315 case Builtin::BIcommit_write_pipe:
3316 case Builtin::BIwork_group_commit_read_pipe:
3317 case Builtin::BIwork_group_commit_write_pipe:
3318 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3321 case Builtin::BIsub_group_commit_read_pipe:
3322 case Builtin::BIsub_group_commit_write_pipe:
3323 if (
OpenCL().checkSubgroupExt(TheCall) ||
3324 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3327 case Builtin::BIget_pipe_num_packets:
3328 case Builtin::BIget_pipe_max_packets:
3329 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3332 case Builtin::BIto_global:
3333 case Builtin::BIto_local:
3334 case Builtin::BIto_private:
3335 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3339 case Builtin::BIenqueue_kernel:
3340 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3343 case Builtin::BIget_kernel_work_group_size:
3344 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3345 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3348 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3349 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3350 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3353 case Builtin::BI__builtin_os_log_format:
3354 Cleanup.setExprNeedsCleanups(
true);
3356 case Builtin::BI__builtin_os_log_format_buffer_size:
3357 if (BuiltinOSLogFormat(TheCall))
3360 case Builtin::BI__builtin_frame_address:
3361 case Builtin::BI__builtin_return_address: {
3370 Result.Val.getInt() != 0)
3372 << ((BuiltinID == Builtin::BI__builtin_return_address)
3373 ?
"__builtin_return_address"
3374 :
"__builtin_frame_address")
3379 case Builtin::BI__builtin_nondeterministic_value: {
3380 if (BuiltinNonDeterministicValue(TheCall))
3387 case Builtin::BI__builtin_elementwise_abs:
3395 case Builtin::BI__builtin_elementwise_acos:
3396 case Builtin::BI__builtin_elementwise_asin:
3397 case Builtin::BI__builtin_elementwise_atan:
3398 case Builtin::BI__builtin_elementwise_ceil:
3399 case Builtin::BI__builtin_elementwise_cos:
3400 case Builtin::BI__builtin_elementwise_cosh:
3401 case Builtin::BI__builtin_elementwise_exp:
3402 case Builtin::BI__builtin_elementwise_exp2:
3403 case Builtin::BI__builtin_elementwise_exp10:
3404 case Builtin::BI__builtin_elementwise_floor:
3405 case Builtin::BI__builtin_elementwise_log:
3406 case Builtin::BI__builtin_elementwise_log2:
3407 case Builtin::BI__builtin_elementwise_log10:
3408 case Builtin::BI__builtin_elementwise_roundeven:
3409 case Builtin::BI__builtin_elementwise_round:
3410 case Builtin::BI__builtin_elementwise_rint:
3411 case Builtin::BI__builtin_elementwise_nearbyint:
3412 case Builtin::BI__builtin_elementwise_sin:
3413 case Builtin::BI__builtin_elementwise_sinh:
3414 case Builtin::BI__builtin_elementwise_sqrt:
3415 case Builtin::BI__builtin_elementwise_tan:
3416 case Builtin::BI__builtin_elementwise_tanh:
3417 case Builtin::BI__builtin_elementwise_trunc:
3418 case Builtin::BI__builtin_elementwise_canonicalize:
3423 case Builtin::BI__builtin_elementwise_fma:
3428 case Builtin::BI__builtin_elementwise_ldexp: {
3450 const auto *Vec0 = TyA->
getAs<VectorType>();
3451 const auto *Vec1 = TyExp->
getAs<VectorType>();
3452 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3454 if (Arg0Length != Arg1Length) {
3456 diag::err_typecheck_vector_lengths_not_equal)
3470 case Builtin::BI__builtin_elementwise_minnum:
3471 case Builtin::BI__builtin_elementwise_maxnum:
3472 case Builtin::BI__builtin_elementwise_minimum:
3473 case Builtin::BI__builtin_elementwise_maximum:
3474 case Builtin::BI__builtin_elementwise_minimumnum:
3475 case Builtin::BI__builtin_elementwise_maximumnum:
3476 case Builtin::BI__builtin_elementwise_atan2:
3477 case Builtin::BI__builtin_elementwise_fmod:
3478 case Builtin::BI__builtin_elementwise_pow:
3479 if (BuiltinElementwiseMath(TheCall,
3485 case Builtin::BI__builtin_elementwise_add_sat:
3486 case Builtin::BI__builtin_elementwise_sub_sat:
3487 if (BuiltinElementwiseMath(TheCall,
3491 case Builtin::BI__builtin_elementwise_fshl:
3492 case Builtin::BI__builtin_elementwise_fshr:
3497 case Builtin::BI__builtin_elementwise_min:
3498 case Builtin::BI__builtin_elementwise_max:
3499 if (BuiltinElementwiseMath(TheCall))
3502 case Builtin::BI__builtin_elementwise_popcount:
3503 case Builtin::BI__builtin_elementwise_bitreverse:
3508 case Builtin::BI__builtin_elementwise_copysign: {
3517 QualType MagnitudeTy = Magnitude.
get()->
getType();
3530 diag::err_typecheck_call_different_arg_types)
3531 << MagnitudeTy << SignTy;
3539 case Builtin::BI__builtin_elementwise_clzg:
3540 case Builtin::BI__builtin_elementwise_ctzg:
3548 }
else if (BuiltinElementwiseMath(
3552 case Builtin::BI__builtin_reduce_max:
3553 case Builtin::BI__builtin_reduce_min: {
3554 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3557 const Expr *Arg = TheCall->
getArg(0);
3562 ElTy = TyA->getElementType();
3566 if (ElTy.isNull()) {
3576 case Builtin::BI__builtin_reduce_maximum:
3577 case Builtin::BI__builtin_reduce_minimum: {
3578 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3581 const Expr *Arg = TheCall->
getArg(0);
3586 ElTy = TyA->getElementType();
3590 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3603 case Builtin::BI__builtin_reduce_add:
3604 case Builtin::BI__builtin_reduce_mul:
3605 case Builtin::BI__builtin_reduce_xor:
3606 case Builtin::BI__builtin_reduce_or:
3607 case Builtin::BI__builtin_reduce_and: {
3608 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3611 const Expr *Arg = TheCall->
getArg(0);
3616 ElTy = TyA->getElementType();
3620 if (ElTy.isNull() || !ElTy->isIntegerType()) {
3631 case Builtin::BI__builtin_matrix_transpose:
3632 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3634 case Builtin::BI__builtin_matrix_column_major_load:
3635 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3637 case Builtin::BI__builtin_matrix_column_major_store:
3638 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3640 case Builtin::BI__builtin_verbose_trap:
3645 case Builtin::BI__builtin_get_device_side_mangled_name: {
3646 auto Check = [](CallExpr *TheCall) {
3652 auto *D = DRE->getDecl();
3655 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3656 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3658 if (!Check(TheCall)) {
3660 diag::err_hip_invalid_args_builtin_mangled_name);
3665 case Builtin::BI__builtin_bswapg:
3669 case Builtin::BI__builtin_popcountg:
3673 case Builtin::BI__builtin_clzg:
3674 case Builtin::BI__builtin_ctzg:
3679 case Builtin::BI__builtin_stdc_rotate_left:
3680 case Builtin::BI__builtin_stdc_rotate_right:
3685 case Builtin::BI__builtin_allow_runtime_check: {
3686 Expr *Arg = TheCall->
getArg(0);
3696 case Builtin::BI__builtin_allow_sanitize_check: {
3697 Expr *Arg = TheCall->
getArg(0);
3699 const StringLiteral *SanitizerName =
3701 if (!SanitizerName) {
3707 if (!llvm::StringSwitch<bool>(SanitizerName->
getString())
3708 .Cases({
"address",
"thread",
"memory",
"hwaddress",
3709 "kernel-address",
"kernel-memory",
"kernel-hwaddress"},
3713 << SanitizerName->
getString() <<
"__builtin_allow_sanitize_check"
3719 case Builtin::BI__builtin_counted_by_ref:
3720 if (BuiltinCountedByRef(TheCall))
3730 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3731 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3732 assert(
Context.getAuxTargetInfo() &&
3733 "Aux Target Builtin, but not an aux target?");
3735 if (CheckTSBuiltinFunctionCall(
3737 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3740 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3746 return TheCallResult;
3761 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3765 diag::err_argument_not_contiguous_bit_field)
3772 bool IsVariadic =
false;
3775 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3776 IsVariadic = BD->isVariadic();
3777 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3778 IsVariadic = OMD->isVariadic();
3785 bool HasImplicitThisParam,
bool IsVariadic,
3789 else if (IsVariadic)
3799 if (HasImplicitThisParam) {
3831 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
3832 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3833 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3834 Expr = ILE->getInit(0);
3844 const Expr *ArgExpr,
3848 S.
PDiag(diag::warn_null_arg)
3854 if (
auto nullability =
type->getNullability())
3865 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3871 llvm::SmallBitVector NonNullArgs;
3877 for (
const auto *Arg : Args)
3884 unsigned IdxAST = Idx.getASTIndex();
3885 if (IdxAST >= Args.size())
3887 if (NonNullArgs.empty())
3888 NonNullArgs.resize(Args.size());
3889 NonNullArgs.set(IdxAST);
3898 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3903 unsigned ParamIndex = 0;
3905 I != E; ++I, ++ParamIndex) {
3908 if (NonNullArgs.empty())
3909 NonNullArgs.resize(Args.size());
3911 NonNullArgs.set(ParamIndex);
3918 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3923 type = blockType->getPointeeType();
3937 if (NonNullArgs.empty())
3938 NonNullArgs.resize(Args.size());
3940 NonNullArgs.set(Index);
3949 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3950 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3951 if (NonNullArgs[ArgIndex])
3957 StringRef ParamName,
QualType ArgTy,
3980 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
3981 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
3985 if (ArgAlign < ParamAlign)
3986 Diag(Loc, diag::warn_param_mismatched_alignment)
3988 << ParamName << (FDecl !=
nullptr) << FDecl;
3992 const Expr *ThisArg,
3994 if (!FD || Args.empty())
3996 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3997 if (Idx == LifetimeCaptureByAttr::Global ||
3998 Idx == LifetimeCaptureByAttr::Unknown)
4000 if (IsMemberFunction && Idx == 0)
4002 return Args[Idx - IsMemberFunction];
4004 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
4009 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
4010 for (
int CapturingParamIdx :
Attr->params()) {
4013 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
4016 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
4024 I + IsMemberFunction);
4026 if (IsMemberFunction) {
4034 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
4047 llvm::SmallBitVector CheckedVarArgs;
4049 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
4051 CheckedVarArgs.resize(Args.size());
4052 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
4057 CheckedVarArgs.resize(Args.size());
4058 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
4065 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
4069 : isa_and_nonnull<FunctionDecl>(FDecl)
4071 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
4075 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
4077 if (
const Expr *Arg = Args[ArgIdx]) {
4078 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
4085 if (FDecl || Proto) {
4090 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
4091 CheckArgumentWithTypeTag(I, Args, Loc);
4097 if (!Proto && FDecl) {
4099 if (isa_and_nonnull<FunctionProtoType>(FT))
4105 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
4107 bool IsScalableArg =
false;
4108 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
4110 if (
const Expr *Arg = Args[ArgIdx]) {
4114 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
4122 IsScalableArg =
true;
4124 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4133 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4134 llvm::StringMap<bool> CallerFeatureMap;
4135 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4136 if (!CallerFeatureMap.contains(
"sme"))
4137 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4138 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4139 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4148 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4150 (IsScalableArg || IsScalableRet)) {
4151 bool IsCalleeStreaming =
4153 bool IsCalleeStreamingCompatible =
4157 if (!IsCalleeStreamingCompatible &&
4161 unsigned VL = LO.VScaleMin * 128;
4162 unsigned SVL = LO.VScaleStreamingMin * 128;
4163 bool IsVLMismatch = VL && SVL && VL != SVL;
4165 auto EmitDiag = [&](
bool IsArg) {
4169 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4170 << IsArg << IsCalleeStreaming << SVL << VL;
4173 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4174 << IsArg << SVL << VL;
4176 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4193 bool CallerHasZAState =
false;
4194 bool CallerHasZT0State =
false;
4196 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4198 CallerHasZAState =
true;
4200 CallerHasZT0State =
true;
4204 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4206 CallerHasZT0State |=
4208 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4214 Diag(Loc, diag::err_sme_za_call_no_za_state);
4217 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4221 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4222 Diag(Loc, diag::note_sme_use_preserves_za);
4227 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4228 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4229 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4230 if (!Arg->isValueDependent()) {
4232 if (Arg->EvaluateAsInt(Align,
Context)) {
4233 const llvm::APSInt &I = Align.
Val.
getInt();
4234 if (!I.isPowerOf2())
4235 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4236 << Arg->getSourceRange();
4239 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4265 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4266 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4268 checkCall(FDecl, Proto,
nullptr, Args,
true,
4277 IsMemberOperatorCall;
4283 Expr *ImplicitThis =
nullptr;
4288 ImplicitThis = Args[0];
4291 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4302 ThisType =
Context.getPointerType(ThisType);
4308 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4326 CheckAbsoluteValueFunction(TheCall, FDecl);
4327 CheckMaxUnsignedZero(TheCall, FDecl);
4328 CheckInfNaNFunction(TheCall, FDecl);
4339 case Builtin::BIstrlcpy:
4340 case Builtin::BIstrlcat:
4341 CheckStrlcpycatArguments(TheCall, FnInfo);
4343 case Builtin::BIstrncat:
4344 CheckStrncatArguments(TheCall, FnInfo);
4346 case Builtin::BIfree:
4347 CheckFreeArguments(TheCall);
4350 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4359 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4360 Ty =
V->getType().getNonReferenceType();
4361 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4362 Ty = F->getType().getNonReferenceType();
4399 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4402 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4404 case AtomicExpr::AO__c11_atomic_init:
4405 case AtomicExpr::AO__opencl_atomic_init:
4406 llvm_unreachable(
"There is no ordering argument for an init");
4408 case AtomicExpr::AO__c11_atomic_load:
4409 case AtomicExpr::AO__opencl_atomic_load:
4410 case AtomicExpr::AO__hip_atomic_load:
4411 case AtomicExpr::AO__atomic_load_n:
4412 case AtomicExpr::AO__atomic_load:
4413 case AtomicExpr::AO__scoped_atomic_load_n:
4414 case AtomicExpr::AO__scoped_atomic_load:
4415 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4416 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4418 case AtomicExpr::AO__c11_atomic_store:
4419 case AtomicExpr::AO__opencl_atomic_store:
4420 case AtomicExpr::AO__hip_atomic_store:
4421 case AtomicExpr::AO__atomic_store:
4422 case AtomicExpr::AO__atomic_store_n:
4423 case AtomicExpr::AO__scoped_atomic_store:
4424 case AtomicExpr::AO__scoped_atomic_store_n:
4425 case AtomicExpr::AO__atomic_clear:
4426 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4427 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4428 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4487 const unsigned NumForm = ClearByte + 1;
4488 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4489 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4497 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4498 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4499 "need to update code for modified forms");
4500 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4501 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4502 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4503 "need to update code for modified C11 atomics");
4504 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4505 Op <= AtomicExpr::AO__opencl_atomic_store;
4506 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4507 Op <= AtomicExpr::AO__hip_atomic_store;
4508 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4509 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4510 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4511 Op <= AtomicExpr::AO__c11_atomic_store) ||
4513 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4514 Op == AtomicExpr::AO__atomic_store_n ||
4515 Op == AtomicExpr::AO__atomic_exchange_n ||
4516 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4517 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4518 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4519 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4520 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4524 enum ArithOpExtraValueType {
4529 unsigned ArithAllows = AOEVT_None;
4532 case AtomicExpr::AO__c11_atomic_init:
4533 case AtomicExpr::AO__opencl_atomic_init:
4537 case AtomicExpr::AO__c11_atomic_load:
4538 case AtomicExpr::AO__opencl_atomic_load:
4539 case AtomicExpr::AO__hip_atomic_load:
4540 case AtomicExpr::AO__atomic_load_n:
4541 case AtomicExpr::AO__scoped_atomic_load_n:
4545 case AtomicExpr::AO__atomic_load:
4546 case AtomicExpr::AO__scoped_atomic_load:
4550 case AtomicExpr::AO__c11_atomic_store:
4551 case AtomicExpr::AO__opencl_atomic_store:
4552 case AtomicExpr::AO__hip_atomic_store:
4553 case AtomicExpr::AO__atomic_store:
4554 case AtomicExpr::AO__atomic_store_n:
4555 case AtomicExpr::AO__scoped_atomic_store:
4556 case AtomicExpr::AO__scoped_atomic_store_n:
4559 case AtomicExpr::AO__atomic_fetch_add:
4560 case AtomicExpr::AO__atomic_fetch_sub:
4561 case AtomicExpr::AO__atomic_add_fetch:
4562 case AtomicExpr::AO__atomic_sub_fetch:
4563 case AtomicExpr::AO__scoped_atomic_fetch_add:
4564 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4565 case AtomicExpr::AO__scoped_atomic_add_fetch:
4566 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4567 case AtomicExpr::AO__c11_atomic_fetch_add:
4568 case AtomicExpr::AO__c11_atomic_fetch_sub:
4569 case AtomicExpr::AO__opencl_atomic_fetch_add:
4570 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4571 case AtomicExpr::AO__hip_atomic_fetch_add:
4572 case AtomicExpr::AO__hip_atomic_fetch_sub:
4573 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4576 case AtomicExpr::AO__atomic_fetch_max:
4577 case AtomicExpr::AO__atomic_fetch_min:
4578 case AtomicExpr::AO__atomic_max_fetch:
4579 case AtomicExpr::AO__atomic_min_fetch:
4580 case AtomicExpr::AO__scoped_atomic_fetch_max:
4581 case AtomicExpr::AO__scoped_atomic_fetch_min:
4582 case AtomicExpr::AO__scoped_atomic_max_fetch:
4583 case AtomicExpr::AO__scoped_atomic_min_fetch:
4584 case AtomicExpr::AO__c11_atomic_fetch_max:
4585 case AtomicExpr::AO__c11_atomic_fetch_min:
4586 case AtomicExpr::AO__opencl_atomic_fetch_max:
4587 case AtomicExpr::AO__opencl_atomic_fetch_min:
4588 case AtomicExpr::AO__hip_atomic_fetch_max:
4589 case AtomicExpr::AO__hip_atomic_fetch_min:
4590 ArithAllows = AOEVT_FP;
4593 case AtomicExpr::AO__c11_atomic_fetch_and:
4594 case AtomicExpr::AO__c11_atomic_fetch_or:
4595 case AtomicExpr::AO__c11_atomic_fetch_xor:
4596 case AtomicExpr::AO__hip_atomic_fetch_and:
4597 case AtomicExpr::AO__hip_atomic_fetch_or:
4598 case AtomicExpr::AO__hip_atomic_fetch_xor:
4599 case AtomicExpr::AO__c11_atomic_fetch_nand:
4600 case AtomicExpr::AO__opencl_atomic_fetch_and:
4601 case AtomicExpr::AO__opencl_atomic_fetch_or:
4602 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4603 case AtomicExpr::AO__atomic_fetch_and:
4604 case AtomicExpr::AO__atomic_fetch_or:
4605 case AtomicExpr::AO__atomic_fetch_xor:
4606 case AtomicExpr::AO__atomic_fetch_nand:
4607 case AtomicExpr::AO__atomic_and_fetch:
4608 case AtomicExpr::AO__atomic_or_fetch:
4609 case AtomicExpr::AO__atomic_xor_fetch:
4610 case AtomicExpr::AO__atomic_nand_fetch:
4611 case AtomicExpr::AO__atomic_fetch_uinc:
4612 case AtomicExpr::AO__atomic_fetch_udec:
4613 case AtomicExpr::AO__scoped_atomic_fetch_and:
4614 case AtomicExpr::AO__scoped_atomic_fetch_or:
4615 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4616 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4617 case AtomicExpr::AO__scoped_atomic_and_fetch:
4618 case AtomicExpr::AO__scoped_atomic_or_fetch:
4619 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4620 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4621 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
4622 case AtomicExpr::AO__scoped_atomic_fetch_udec:
4626 case AtomicExpr::AO__c11_atomic_exchange:
4627 case AtomicExpr::AO__hip_atomic_exchange:
4628 case AtomicExpr::AO__opencl_atomic_exchange:
4629 case AtomicExpr::AO__atomic_exchange_n:
4630 case AtomicExpr::AO__scoped_atomic_exchange_n:
4634 case AtomicExpr::AO__atomic_exchange:
4635 case AtomicExpr::AO__scoped_atomic_exchange:
4639 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4640 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4641 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4642 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4643 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4644 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4648 case AtomicExpr::AO__atomic_compare_exchange:
4649 case AtomicExpr::AO__atomic_compare_exchange_n:
4650 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4651 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4655 case AtomicExpr::AO__atomic_test_and_set:
4656 Form = TestAndSetByte;
4659 case AtomicExpr::AO__atomic_clear:
4664 unsigned AdjustedNumArgs = NumArgs[Form];
4665 if ((IsOpenCL || IsHIP || IsScoped) &&
4666 Op != AtomicExpr::AO__opencl_atomic_init)
4669 if (Args.size() < AdjustedNumArgs) {
4670 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4671 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4674 }
else if (Args.size() > AdjustedNumArgs) {
4675 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4676 diag::err_typecheck_call_too_many_args)
4677 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4683 Expr *Ptr = Args[0];
4688 Ptr = ConvertedPtr.
get();
4691 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4701 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4707 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4713 }
else if (Form != Load && Form != LoadCopy) {
4715 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4721 if (Form != TestAndSetByte && Form != ClearByte) {
4724 diag::err_incomplete_type))
4727 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4728 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4738 pointerType->getPointeeType().getCVRQualifiers());
4748 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4757 auto IsAllowedValueType = [&](
QualType ValType,
4758 unsigned AllowedType) ->
bool {
4762 return AllowedType & AOEVT_Pointer;
4767 &
Context.getTargetInfo().getLongDoubleFormat() ==
4768 &llvm::APFloat::x87DoubleExtended())
4772 if (!IsAllowedValueType(ValType, ArithAllows)) {
4773 auto DID = ArithAllows & AOEVT_FP
4774 ? (ArithAllows & AOEVT_Pointer
4775 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4776 : diag::err_atomic_op_needs_atomic_int_or_fp)
4777 : diag::err_atomic_op_needs_atomic_int;
4784 diag::err_incomplete_type)) {
4790 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4801 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4817 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4829 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4832 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4838 bool IsPassedByAddress =
false;
4839 if (!IsC11 && !IsHIP && !IsN) {
4841 IsPassedByAddress =
true;
4846 APIOrderedArgs.push_back(Args[0]);
4850 APIOrderedArgs.push_back(Args[1]);
4856 APIOrderedArgs.push_back(Args[2]);
4857 APIOrderedArgs.push_back(Args[1]);
4860 APIOrderedArgs.push_back(Args[2]);
4861 APIOrderedArgs.push_back(Args[3]);
4862 APIOrderedArgs.push_back(Args[1]);
4865 APIOrderedArgs.push_back(Args[2]);
4866 APIOrderedArgs.push_back(Args[4]);
4867 APIOrderedArgs.push_back(Args[1]);
4868 APIOrderedArgs.push_back(Args[3]);
4871 APIOrderedArgs.push_back(Args[2]);
4872 APIOrderedArgs.push_back(Args[4]);
4873 APIOrderedArgs.push_back(Args[5]);
4874 APIOrderedArgs.push_back(Args[1]);
4875 APIOrderedArgs.push_back(Args[3]);
4877 case TestAndSetByte:
4879 APIOrderedArgs.push_back(Args[1]);
4883 APIOrderedArgs.append(Args.begin(), Args.end());
4890 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4892 if (i < NumVals[Form] + 1) {
4905 assert(Form != Load);
4907 Ty =
Context.getPointerDiffType();
4910 else if (Form ==
Copy || Form == Xchg) {
4911 if (IsPassedByAddress) {
4918 Expr *ValArg = APIOrderedArgs[i];
4925 AS = PtrTy->getPointeeType().getAddressSpace();
4934 if (IsPassedByAddress)
4954 APIOrderedArgs[i] = Arg.
get();
4959 SubExprs.push_back(Ptr);
4963 SubExprs.push_back(APIOrderedArgs[1]);
4966 case TestAndSetByte:
4968 SubExprs.push_back(APIOrderedArgs[1]);
4974 SubExprs.push_back(APIOrderedArgs[2]);
4975 SubExprs.push_back(APIOrderedArgs[1]);
4979 SubExprs.push_back(APIOrderedArgs[3]);
4980 SubExprs.push_back(APIOrderedArgs[1]);
4981 SubExprs.push_back(APIOrderedArgs[2]);
4984 SubExprs.push_back(APIOrderedArgs[3]);
4985 SubExprs.push_back(APIOrderedArgs[1]);
4986 SubExprs.push_back(APIOrderedArgs[4]);
4987 SubExprs.push_back(APIOrderedArgs[2]);
4990 SubExprs.push_back(APIOrderedArgs[4]);
4991 SubExprs.push_back(APIOrderedArgs[1]);
4992 SubExprs.push_back(APIOrderedArgs[5]);
4993 SubExprs.push_back(APIOrderedArgs[2]);
4994 SubExprs.push_back(APIOrderedArgs[3]);
4999 if (SubExprs.size() >= 2 && Form !=
Init) {
5000 std::optional<llvm::APSInt>
Success =
5001 SubExprs[1]->getIntegerConstantExpr(
Context);
5003 Diag(SubExprs[1]->getBeginLoc(),
5004 diag::warn_atomic_op_has_invalid_memory_order)
5005 << (Form == C11CmpXchg || Form == GNUCmpXchg)
5006 << SubExprs[1]->getSourceRange();
5008 if (SubExprs.size() >= 5) {
5009 if (std::optional<llvm::APSInt> Failure =
5010 SubExprs[3]->getIntegerConstantExpr(
Context)) {
5011 if (!llvm::is_contained(
5012 {llvm::AtomicOrderingCABI::relaxed,
5013 llvm::AtomicOrderingCABI::consume,
5014 llvm::AtomicOrderingCABI::acquire,
5015 llvm::AtomicOrderingCABI::seq_cst},
5016 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
5017 Diag(SubExprs[3]->getBeginLoc(),
5018 diag::warn_atomic_op_has_invalid_memory_order)
5019 << 2 << SubExprs[3]->getSourceRange();
5026 auto *
Scope = Args[Args.size() - 1];
5027 if (std::optional<llvm::APSInt>
Result =
5029 if (!ScopeModel->isValid(
Result->getZExtValue()))
5030 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
5031 <<
Scope->getSourceRange();
5033 SubExprs.push_back(
Scope);
5039 if ((Op == AtomicExpr::AO__c11_atomic_load ||
5040 Op == AtomicExpr::AO__c11_atomic_store ||
5041 Op == AtomicExpr::AO__opencl_atomic_load ||
5042 Op == AtomicExpr::AO__hip_atomic_load ||
5043 Op == AtomicExpr::AO__opencl_atomic_store ||
5044 Op == AtomicExpr::AO__hip_atomic_store) &&
5045 Context.AtomicUsesUnsupportedLibcall(AE))
5047 << ((Op == AtomicExpr::AO__c11_atomic_load ||
5048 Op == AtomicExpr::AO__opencl_atomic_load ||
5049 Op == AtomicExpr::AO__hip_atomic_load)
5054 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
5070 assert(Fn &&
"builtin call without direct callee!");
5086 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
5093 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5095 <<
Callee->getSourceRange();
5104 Expr *FirstArg = TheCall->
getArg(0);
5108 FirstArg = FirstArgResult.
get();
5109 TheCall->
setArg(0, FirstArg);
5121 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
5128 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5158 QualType ResultType = ValType;
5163#define BUILTIN_ROW(x) \
5164 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5165 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5167 static const unsigned BuiltinIndices[][5] = {
5192 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5193 case 1: SizeIndex = 0;
break;
5194 case 2: SizeIndex = 1;
break;
5195 case 4: SizeIndex = 2;
break;
5196 case 8: SizeIndex = 3;
break;
5197 case 16: SizeIndex = 4;
break;
5209 unsigned BuiltinIndex, NumFixed = 1;
5210 bool WarnAboutSemanticsChange =
false;
5211 switch (BuiltinID) {
5212 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5213 case Builtin::BI__sync_fetch_and_add:
5214 case Builtin::BI__sync_fetch_and_add_1:
5215 case Builtin::BI__sync_fetch_and_add_2:
5216 case Builtin::BI__sync_fetch_and_add_4:
5217 case Builtin::BI__sync_fetch_and_add_8:
5218 case Builtin::BI__sync_fetch_and_add_16:
5222 case Builtin::BI__sync_fetch_and_sub:
5223 case Builtin::BI__sync_fetch_and_sub_1:
5224 case Builtin::BI__sync_fetch_and_sub_2:
5225 case Builtin::BI__sync_fetch_and_sub_4:
5226 case Builtin::BI__sync_fetch_and_sub_8:
5227 case Builtin::BI__sync_fetch_and_sub_16:
5231 case Builtin::BI__sync_fetch_and_or:
5232 case Builtin::BI__sync_fetch_and_or_1:
5233 case Builtin::BI__sync_fetch_and_or_2:
5234 case Builtin::BI__sync_fetch_and_or_4:
5235 case Builtin::BI__sync_fetch_and_or_8:
5236 case Builtin::BI__sync_fetch_and_or_16:
5240 case Builtin::BI__sync_fetch_and_and:
5241 case Builtin::BI__sync_fetch_and_and_1:
5242 case Builtin::BI__sync_fetch_and_and_2:
5243 case Builtin::BI__sync_fetch_and_and_4:
5244 case Builtin::BI__sync_fetch_and_and_8:
5245 case Builtin::BI__sync_fetch_and_and_16:
5249 case Builtin::BI__sync_fetch_and_xor:
5250 case Builtin::BI__sync_fetch_and_xor_1:
5251 case Builtin::BI__sync_fetch_and_xor_2:
5252 case Builtin::BI__sync_fetch_and_xor_4:
5253 case Builtin::BI__sync_fetch_and_xor_8:
5254 case Builtin::BI__sync_fetch_and_xor_16:
5258 case Builtin::BI__sync_fetch_and_nand:
5259 case Builtin::BI__sync_fetch_and_nand_1:
5260 case Builtin::BI__sync_fetch_and_nand_2:
5261 case Builtin::BI__sync_fetch_and_nand_4:
5262 case Builtin::BI__sync_fetch_and_nand_8:
5263 case Builtin::BI__sync_fetch_and_nand_16:
5265 WarnAboutSemanticsChange =
true;
5268 case Builtin::BI__sync_add_and_fetch:
5269 case Builtin::BI__sync_add_and_fetch_1:
5270 case Builtin::BI__sync_add_and_fetch_2:
5271 case Builtin::BI__sync_add_and_fetch_4:
5272 case Builtin::BI__sync_add_and_fetch_8:
5273 case Builtin::BI__sync_add_and_fetch_16:
5277 case Builtin::BI__sync_sub_and_fetch:
5278 case Builtin::BI__sync_sub_and_fetch_1:
5279 case Builtin::BI__sync_sub_and_fetch_2:
5280 case Builtin::BI__sync_sub_and_fetch_4:
5281 case Builtin::BI__sync_sub_and_fetch_8:
5282 case Builtin::BI__sync_sub_and_fetch_16:
5286 case Builtin::BI__sync_and_and_fetch:
5287 case Builtin::BI__sync_and_and_fetch_1:
5288 case Builtin::BI__sync_and_and_fetch_2:
5289 case Builtin::BI__sync_and_and_fetch_4:
5290 case Builtin::BI__sync_and_and_fetch_8:
5291 case Builtin::BI__sync_and_and_fetch_16:
5295 case Builtin::BI__sync_or_and_fetch:
5296 case Builtin::BI__sync_or_and_fetch_1:
5297 case Builtin::BI__sync_or_and_fetch_2:
5298 case Builtin::BI__sync_or_and_fetch_4:
5299 case Builtin::BI__sync_or_and_fetch_8:
5300 case Builtin::BI__sync_or_and_fetch_16:
5304 case Builtin::BI__sync_xor_and_fetch:
5305 case Builtin::BI__sync_xor_and_fetch_1:
5306 case Builtin::BI__sync_xor_and_fetch_2:
5307 case Builtin::BI__sync_xor_and_fetch_4:
5308 case Builtin::BI__sync_xor_and_fetch_8:
5309 case Builtin::BI__sync_xor_and_fetch_16:
5313 case Builtin::BI__sync_nand_and_fetch:
5314 case Builtin::BI__sync_nand_and_fetch_1:
5315 case Builtin::BI__sync_nand_and_fetch_2:
5316 case Builtin::BI__sync_nand_and_fetch_4:
5317 case Builtin::BI__sync_nand_and_fetch_8:
5318 case Builtin::BI__sync_nand_and_fetch_16:
5320 WarnAboutSemanticsChange =
true;
5323 case Builtin::BI__sync_val_compare_and_swap:
5324 case Builtin::BI__sync_val_compare_and_swap_1:
5325 case Builtin::BI__sync_val_compare_and_swap_2:
5326 case Builtin::BI__sync_val_compare_and_swap_4:
5327 case Builtin::BI__sync_val_compare_and_swap_8:
5328 case Builtin::BI__sync_val_compare_and_swap_16:
5333 case Builtin::BI__sync_bool_compare_and_swap:
5334 case Builtin::BI__sync_bool_compare_and_swap_1:
5335 case Builtin::BI__sync_bool_compare_and_swap_2:
5336 case Builtin::BI__sync_bool_compare_and_swap_4:
5337 case Builtin::BI__sync_bool_compare_and_swap_8:
5338 case Builtin::BI__sync_bool_compare_and_swap_16:
5344 case Builtin::BI__sync_lock_test_and_set:
5345 case Builtin::BI__sync_lock_test_and_set_1:
5346 case Builtin::BI__sync_lock_test_and_set_2:
5347 case Builtin::BI__sync_lock_test_and_set_4:
5348 case Builtin::BI__sync_lock_test_and_set_8:
5349 case Builtin::BI__sync_lock_test_and_set_16:
5353 case Builtin::BI__sync_lock_release:
5354 case Builtin::BI__sync_lock_release_1:
5355 case Builtin::BI__sync_lock_release_2:
5356 case Builtin::BI__sync_lock_release_4:
5357 case Builtin::BI__sync_lock_release_8:
5358 case Builtin::BI__sync_lock_release_16:
5364 case Builtin::BI__sync_swap:
5365 case Builtin::BI__sync_swap_1:
5366 case Builtin::BI__sync_swap_2:
5367 case Builtin::BI__sync_swap_4:
5368 case Builtin::BI__sync_swap_8:
5369 case Builtin::BI__sync_swap_16:
5377 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5378 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5379 <<
Callee->getSourceRange();
5383 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5384 <<
Callee->getSourceRange();
5386 if (WarnAboutSemanticsChange) {
5387 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5388 <<
Callee->getSourceRange();
5393 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5394 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5395 FunctionDecl *NewBuiltinDecl;
5396 if (NewBuiltinID == BuiltinID)
5397 NewBuiltinDecl = FDecl;
5400 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5403 assert(Res.getFoundDecl());
5404 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5405 if (!NewBuiltinDecl)
5412 for (
unsigned i = 0; i != NumFixed; ++i) {
5441 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5443 CK_BuiltinFnToFnPtr);
5454 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5455 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5456 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5460 return TheCallResult;
5464 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5469 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5470 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5471 "Unexpected nontemporal load/store builtin!");
5472 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5473 unsigned numArgs = isStore ? 2 : 1;
5483 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5489 PointerArg = PointerArgResult.
get();
5490 TheCall->
setArg(numArgs - 1, PointerArg);
5494 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5507 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5514 return TheCallResult;
5526 return TheCallResult;
5533 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5535 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5536 Literal = ObjcLiteral->getString();
5540 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5547 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5548 InitializedEntity Entity =
5558 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5559 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5560 TT.getArch() == llvm::Triple::aarch64_32);
5561 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5562 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5563 if (IsX64 || IsAArch64) {
5570 return S.
Diag(Fn->getBeginLoc(),
5571 diag::err_ms_va_start_used_in_sysv_function);
5578 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5579 return S.
Diag(Fn->getBeginLoc(),
5580 diag::err_va_start_used_in_wrong_abi_function)
5581 << !IsWindowsOrUEFI;
5587 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5595 bool IsVariadic =
false;
5598 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5599 IsVariadic =
Block->isVariadic();
5600 Params =
Block->parameters();
5601 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5604 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5605 IsVariadic = MD->isVariadic();
5607 Params = MD->parameters();
5610 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5614 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5619 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5624 *LastParam = Params.empty() ?
nullptr : Params.back();
5629bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5634 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5658 ParmVarDecl *LastParam;
5669 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5671 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5676 if (std::optional<llvm::APSInt> Val =
5678 Val &&
LangOpts.C23 && *Val == 0 &&
5679 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5680 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5687 SourceLocation ParamLoc;
5688 bool IsCRegister =
false;
5689 bool SecondArgIsLastNonVariadicArgument =
false;
5690 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5691 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5692 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5695 ParamLoc = PV->getLocation();
5701 if (!SecondArgIsLastNonVariadicArgument)
5703 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5704 else if (IsCRegister ||
Type->isReferenceType() ||
5705 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5708 if (!Context.isPromotableIntegerType(Type))
5710 const auto *ED = Type->getAsEnumDecl();
5713 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5715 unsigned Reason = 0;
5716 if (
Type->isReferenceType()) Reason = 1;
5717 else if (IsCRegister) Reason = 2;
5718 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5719 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5726 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5746 if (
Call->getNumArgs() < 3)
5748 diag::err_typecheck_call_too_few_args_at_least)
5749 << 0 << 3 <<
Call->getNumArgs()
5762 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5765 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5768 const QualType &ConstCharPtrTy =
5770 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5772 << Arg1->
getType() << ConstCharPtrTy << 1
5775 << 2 << Arg1->
getType() << ConstCharPtrTy;
5777 const QualType SizeTy =
Context.getSizeType();
5782 << Arg2->
getType() << SizeTy << 1
5785 << 3 << Arg2->
getType() << SizeTy;
5790bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5794 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5822 diag::err_typecheck_call_invalid_ordered_compare)
5830bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5831 unsigned BuiltinID) {
5836 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5837 BuiltinID == Builtin::BI__builtin_isinf ||
5838 BuiltinID == Builtin::BI__builtin_isinf_sign))
5842 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5843 BuiltinID == Builtin::BI__builtin_isunordered))
5847 bool IsFPClass = NumArgs == 2;
5850 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5854 for (
unsigned i = 0; i < FPArgNo; ++i) {
5855 Expr *Arg = TheCall->
getArg(i);
5868 Expr *OrigArg = TheCall->
getArg(FPArgNo);
5876 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
5881 OrigArg = Res.
get();
5887 OrigArg = Res.
get();
5889 TheCall->
setArg(FPArgNo, OrigArg);
5891 QualType VectorResultTy;
5892 QualType ElementTy = OrigArg->
getType();
5897 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
5903 diag::err_typecheck_call_invalid_unary_fp)
5915 if (!VectorResultTy.
isNull())
5916 ResultTy = VectorResultTy;
5925bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5930 for (
unsigned I = 0; I != 2; ++I) {
5931 Expr *Arg = TheCall->
getArg(I);
5941 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5956 Expr *Real = TheCall->
getArg(0);
5957 Expr *Imag = TheCall->
getArg(1);
5960 diag::err_typecheck_call_different_arg_types)
5975 diag::err_typecheck_call_too_few_args_at_least)
5976 << 0 << 2 << NumArgs
5983 unsigned NumElements = 0;
5998 unsigned NumResElements = NumArgs - 2;
6007 diag::err_vec_builtin_incompatible_vector)
6012 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
6014 diag::err_vec_builtin_incompatible_vector)
6019 }
else if (NumElements != NumResElements) {
6022 ?
Context.getExtVectorType(EltType, NumResElements)
6023 :
Context.getVectorType(EltType, NumResElements,
6028 for (
unsigned I = 2; I != NumArgs; ++I) {
6036 diag::err_shufflevector_nonconstant_argument)
6042 else if (
Result->getActiveBits() > 64 ||
6043 Result->getZExtValue() >= NumElements * 2)
6045 diag::err_shufflevector_argument_too_large)
6070 diag::err_convertvector_non_vector)
6073 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
6075 <<
"__builtin_convertvector");
6080 if (SrcElts != DstElts)
6082 diag::err_convertvector_incompatible_vector)
6090bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
6095 diag::err_typecheck_call_too_many_args_at_most)
6096 << 0 << 3 << NumArgs << 0
6101 for (
unsigned i = 1; i != NumArgs; ++i)
6108bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
6109 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
6110 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
6120 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
6130bool Sema::BuiltinAssume(
CallExpr *TheCall) {
6131 Expr *Arg = TheCall->
getArg(0);
6142bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6144 Expr *Arg = TheCall->
getArg(1);
6148 if (
const auto *UE =
6150 if (UE->getKind() == UETT_AlignOf ||
6151 UE->getKind() == UETT_PreferredAlignOf)
6157 if (!
Result.isPowerOf2())
6158 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6165 if (
Result > std::numeric_limits<int32_t>::max())
6173bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6178 Expr *FirstArg = TheCall->
getArg(0);
6184 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6188 TheCall->
setArg(0, FirstArgResult.
get());
6192 Expr *SecondArg = TheCall->
getArg(1);
6200 if (!
Result.isPowerOf2())
6201 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6213 Expr *ThirdArg = TheCall->
getArg(2);
6216 TheCall->
setArg(2, ThirdArg);
6222bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6223 unsigned BuiltinID =
6225 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6228 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6229 if (NumArgs < NumRequiredArgs) {
6230 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6231 << 0 << NumRequiredArgs << NumArgs
6234 if (NumArgs >= NumRequiredArgs + 0x100) {
6236 diag::err_typecheck_call_too_many_args_at_most)
6237 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6248 if (Arg.isInvalid())
6250 TheCall->
setArg(i, Arg.get());
6255 unsigned FormatIdx = i;
6265 unsigned FirstDataArg = i;
6266 while (i < NumArgs) {
6284 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6286 bool Success = CheckFormatArguments(
6289 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6313 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6322 int High,
bool RangeIsError) {
6336 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6344 PDiag(diag::warn_argument_invalid_range)
6387 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6392 if (
Value.isNegative())
6403 if ((
Value & 0xFF) != 0)
6428 Result.setIsUnsigned(
true);
6433 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6453 Result.setIsUnsigned(
true);
6461 diag::err_argument_not_shifted_byte_or_xxff)
6465bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6466 if (!Context.getTargetInfo().hasSjLjLowering())
6467 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6478 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6484bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6485 if (!Context.getTargetInfo().hasSjLjLowering())
6486 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6491bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6506 diag::err_builtin_counted_by_ref_invalid_arg)
6511 diag::err_builtin_counted_by_ref_has_side_effects)
6514 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6516 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6521 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6528 QualType MemberTy = ME->getMemberDecl()->getType();
6531 diag::err_builtin_counted_by_ref_invalid_arg)
6535 diag::err_builtin_counted_by_ref_invalid_arg)
6545bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6547 const CallExpr *CE =
6556 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6561 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6566 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6570 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6574 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6584class UncoveredArgHandler {
6585 enum {
Unknown = -1, AllCovered = -2 };
6587 signed FirstUncoveredArg =
Unknown;
6588 SmallVector<const Expr *, 4> DiagnosticExprs;
6591 UncoveredArgHandler() =
default;
6593 bool hasUncoveredArg()
const {
6594 return (FirstUncoveredArg >= 0);
6597 unsigned getUncoveredArg()
const {
6598 assert(hasUncoveredArg() &&
"no uncovered argument");
6599 return FirstUncoveredArg;
6602 void setAllCovered() {
6605 DiagnosticExprs.clear();
6606 FirstUncoveredArg = AllCovered;
6609 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6610 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6613 if (FirstUncoveredArg == AllCovered)
6618 if (NewFirstUncoveredArg == FirstUncoveredArg)
6619 DiagnosticExprs.push_back(StrExpr);
6620 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6621 DiagnosticExprs.clear();
6622 DiagnosticExprs.push_back(StrExpr);
6623 FirstUncoveredArg = NewFirstUncoveredArg;
6627 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6630enum StringLiteralCheckType {
6632 SLCT_UncheckedLiteral,
6640 bool AddendIsRight) {
6641 unsigned BitWidth = Offset.getBitWidth();
6642 unsigned AddendBitWidth = Addend.getBitWidth();
6644 if (Addend.isUnsigned()) {
6645 Addend = Addend.zext(++AddendBitWidth);
6646 Addend.setIsSigned(
true);
6649 if (AddendBitWidth > BitWidth) {
6650 Offset = Offset.sext(AddendBitWidth);
6651 BitWidth = AddendBitWidth;
6652 }
else if (BitWidth > AddendBitWidth) {
6653 Addend = Addend.sext(BitWidth);
6657 llvm::APSInt ResOffset = Offset;
6658 if (BinOpKind == BO_Add)
6659 ResOffset = Offset.sadd_ov(Addend, Ov);
6661 assert(AddendIsRight && BinOpKind == BO_Sub &&
6662 "operator must be add or sub with addend on the right");
6663 ResOffset = Offset.ssub_ov(Addend, Ov);
6669 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6670 "index (intermediate) result too big");
6671 Offset = Offset.sext(2 * BitWidth);
6672 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6684class FormatStringLiteral {
6685 const StringLiteral *FExpr;
6689 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6690 : FExpr(fexpr), Offset(Offset) {}
6692 const StringLiteral *getFormatString()
const {
return FExpr; }
6694 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6696 unsigned getByteLength()
const {
6697 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6700 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6707 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6708 bool isWide()
const {
return FExpr->
isWide(); }
6709 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6710 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6711 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6712 bool isPascal()
const {
return FExpr->
isPascal(); }
6714 SourceLocation getLocationOfByte(
6715 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6716 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6717 unsigned *StartTokenByteOffset =
nullptr)
const {
6719 StartToken, StartTokenByteOffset);
6722 SourceLocation getBeginLoc() const LLVM_READONLY {
6726 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6732 Sema &S,
const FormatStringLiteral *FExpr,
6737 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6738 bool IgnoreStringsWithoutSpecifiers);
6747static StringLiteralCheckType
6753 llvm::SmallBitVector &CheckedVarArgs,
6754 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
6755 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
6756 bool IgnoreStringsWithoutSpecifiers =
false) {
6758 return SLCT_NotALiteral;
6760 assert(Offset.isSigned() &&
"invalid offset");
6763 return SLCT_NotALiteral;
6772 return SLCT_UncheckedLiteral;
6775 case Stmt::InitListExprClass:
6779 format_idx, firstDataArg,
Type, CallType,
6780 false, CheckedVarArgs,
6781 UncoveredArg, Offset, CallerFormatParamIdx,
6782 IgnoreStringsWithoutSpecifiers);
6784 return SLCT_NotALiteral;
6785 case Stmt::BinaryConditionalOperatorClass:
6786 case Stmt::ConditionalOperatorClass: {
6795 bool CheckLeft =
true, CheckRight =
true;
6798 if (
C->getCond()->EvaluateAsBooleanCondition(
6810 StringLiteralCheckType Left;
6812 Left = SLCT_UncheckedLiteral;
6815 Args, APK, format_idx, firstDataArg,
Type,
6816 CallType, InFunctionCall, CheckedVarArgs,
6817 UncoveredArg, Offset, CallerFormatParamIdx,
6818 IgnoreStringsWithoutSpecifiers);
6819 if (Left == SLCT_NotALiteral || !CheckRight) {
6825 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6826 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6827 UncoveredArg, Offset, CallerFormatParamIdx,
6828 IgnoreStringsWithoutSpecifiers);
6830 return (CheckLeft && Left < Right) ? Left : Right;
6833 case Stmt::ImplicitCastExprClass:
6837 case Stmt::OpaqueValueExprClass:
6842 return SLCT_NotALiteral;
6844 case Stmt::PredefinedExprClass:
6848 return SLCT_UncheckedLiteral;
6850 case Stmt::DeclRefExprClass: {
6856 bool isConstant =
false;
6860 isConstant = AT->getElementType().isConstant(S.
Context);
6862 isConstant =
T.isConstant(S.
Context) &&
6863 PT->getPointeeType().isConstant(S.
Context);
6864 }
else if (
T->isObjCObjectPointerType()) {
6867 isConstant =
T.isConstant(S.
Context);
6871 if (
const Expr *
Init = VD->getAnyInitializer()) {
6874 if (InitList->isStringLiteralInit())
6875 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6878 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6879 firstDataArg,
Type, CallType,
false,
6880 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
6931 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6932 if (CallerFormatParamIdx)
6933 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
6934 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
6935 for (
const auto *PVFormatMatches :
6936 D->specific_attrs<FormatMatchesAttr>()) {
6941 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6945 S.
Diag(Args[format_idx]->getBeginLoc(),
6946 diag::warn_format_string_type_incompatible)
6947 << PVFormatMatches->getType()->getName()
6949 if (!InFunctionCall) {
6950 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6951 diag::note_format_string_defined);
6953 return SLCT_UncheckedLiteral;
6956 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6957 Args, APK, format_idx, firstDataArg,
Type, CallType,
6958 false, CheckedVarArgs, UncoveredArg,
6959 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6963 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
6966 PVFormat->getFirstArg(), &CallerFSI))
6968 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6972 S.
Diag(Args[format_idx]->getBeginLoc(),
6973 diag::warn_format_string_type_incompatible)
6974 << PVFormat->getType()->getName()
6976 if (!InFunctionCall) {
6979 return SLCT_UncheckedLiteral;
6992 return SLCT_UncheckedLiteral;
7000 return SLCT_NotALiteral;
7003 case Stmt::CallExprClass:
7004 case Stmt::CXXMemberCallExprClass: {
7008 StringLiteralCheckType CommonResult;
7009 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
7010 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
7012 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7013 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7014 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7016 CommonResult = Result;
7021 return CommonResult;
7023 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
7025 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
7026 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
7029 S, ReferenceFormatString, Arg, Args, APK, format_idx,
7030 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
7031 UncoveredArg, Offset, CallerFormatParamIdx,
7032 IgnoreStringsWithoutSpecifiers);
7038 format_idx, firstDataArg,
Type, CallType,
7039 false, CheckedVarArgs,
7040 UncoveredArg, Offset, CallerFormatParamIdx,
7041 IgnoreStringsWithoutSpecifiers);
7042 return SLCT_NotALiteral;
7044 case Stmt::ObjCMessageExprClass: {
7046 if (
const auto *MD = ME->getMethodDecl()) {
7047 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
7056 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
7058 MD->getSelector().isKeywordSelector(
7059 {
"localizedStringForKey",
"value",
"table"})) {
7060 IgnoreStringsWithoutSpecifiers =
true;
7063 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
7065 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
7066 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
7067 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
7071 return SLCT_NotALiteral;
7073 case Stmt::ObjCStringLiteralClass:
7074 case Stmt::StringLiteralClass: {
7083 if (Offset.isNegative() || Offset > StrE->
getLength()) {
7086 return SLCT_NotALiteral;
7088 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
7090 format_idx, firstDataArg,
Type, InFunctionCall,
7091 CallType, CheckedVarArgs, UncoveredArg,
7092 IgnoreStringsWithoutSpecifiers);
7093 return SLCT_CheckedLiteral;
7096 return SLCT_NotALiteral;
7098 case Stmt::BinaryOperatorClass: {
7112 if (LIsInt != RIsInt) {
7116 if (BinOpKind == BO_Add) {
7129 return SLCT_NotALiteral;
7131 case Stmt::UnaryOperatorClass: {
7133 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
7134 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7136 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7146 return SLCT_NotALiteral;
7150 return SLCT_NotALiteral;
7161 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7162 if (isa_and_nonnull<StringLiteral>(LVE))
7183 return "freebsd_kprintf";
7192 return llvm::StringSwitch<FormatStringType>(Flavor)
7194 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7199 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7215bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7219 llvm::SmallBitVector &CheckedVarArgs) {
7220 FormatStringInfo FSI;
7224 return CheckFormatArguments(
7225 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7230bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7234 llvm::SmallBitVector &CheckedVarArgs) {
7235 FormatStringInfo FSI;
7239 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7240 Format->getFormatString(), FSI.FormatIdx,
7242 CallType, Loc, Range, CheckedVarArgs);
7250 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7263 unsigned CallerArgumentIndexOffset =
7266 unsigned FirstArgumentIndex = -1;
7276 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7277 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7281 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7282 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7284 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7287 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7288 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7291 FirstArgumentIndex =
7292 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7298 ? (NumCallerParams + CallerArgumentIndexOffset)
7303 if (!ReferenceFormatString)
7309 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7311 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7313 std::string
Attr, Fixit;
7314 llvm::raw_string_ostream AttrOS(
Attr);
7316 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7317 << FirstArgumentIndex <<
")";
7319 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7321 AttrOS.write_escaped(ReferenceFormatString->
getString());
7325 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7336 llvm::raw_string_ostream IS(Fixit);
7344 if (LO.C23 || LO.CPlusPlus11)
7345 IS <<
"[[gnu::" <<
Attr <<
"]]";
7346 else if (LO.ObjC || LO.GNUMode)
7347 IS <<
"__attribute__((" <<
Attr <<
"))";
7361 Caller->
addAttr(FormatAttr::CreateImplicit(
7363 FormatStringIndex, FirstArgumentIndex));
7365 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7367 FormatStringIndex, ReferenceFormatString));
7371 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7383 unsigned format_idx,
unsigned firstDataArg,
7387 llvm::SmallBitVector &CheckedVarArgs) {
7389 if (format_idx >= Args.size()) {
7390 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7394 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7408 UncoveredArgHandler UncoveredArg;
7409 std::optional<unsigned> CallerParamIdx;
7411 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7412 firstDataArg,
Type, CallType,
7413 true, CheckedVarArgs, UncoveredArg,
7414 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7417 if (UncoveredArg.hasUncoveredArg()) {
7418 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7419 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7420 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7423 if (CT != SLCT_NotALiteral)
7425 return CT == SLCT_CheckedLiteral;
7431 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7437 this, Args, APK, ReferenceFormatString, format_idx,
7438 firstDataArg,
Type, *CallerParamIdx, Loc))
7448 if (Args.size() == firstDataArg) {
7449 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7457 Diag(FormatLoc, diag::note_format_security_fixit)
7461 Diag(FormatLoc, diag::note_format_security_fixit)
7466 Diag(FormatLoc, diag::warn_format_nonliteral)
7477 const FormatStringLiteral *FExpr;
7478 const Expr *OrigFormatExpr;
7480 const unsigned FirstDataArg;
7481 const unsigned NumDataArgs;
7484 ArrayRef<const Expr *> Args;
7486 llvm::SmallBitVector CoveredArgs;
7487 bool usesPositionalArgs =
false;
7488 bool atFirstArg =
true;
7489 bool inFunctionCall;
7491 llvm::SmallBitVector &CheckedVarArgs;
7492 UncoveredArgHandler &UncoveredArg;
7495 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7497 unsigned firstDataArg,
unsigned numDataArgs,
7499 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7501 llvm::SmallBitVector &CheckedVarArgs,
7502 UncoveredArgHandler &UncoveredArg)
7503 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7504 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7505 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7506 inFunctionCall(inFunctionCall), CallType(callType),
7507 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7508 CoveredArgs.resize(numDataArgs);
7509 CoveredArgs.reset();
7512 bool HasFormatArguments()
const {
7517 void DoneProcessing();
7519 void HandleIncompleteSpecifier(
const char *startSpecifier,
7520 unsigned specifierLen)
override;
7522 void HandleInvalidLengthModifier(
7523 const analyze_format_string::FormatSpecifier &FS,
7524 const analyze_format_string::ConversionSpecifier &CS,
7525 const char *startSpecifier,
unsigned specifierLen,
7528 void HandleNonStandardLengthModifier(
7529 const analyze_format_string::FormatSpecifier &FS,
7530 const char *startSpecifier,
unsigned specifierLen);
7532 void HandleNonStandardConversionSpecifier(
7533 const analyze_format_string::ConversionSpecifier &CS,
7534 const char *startSpecifier,
unsigned specifierLen);
7536 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7538 void HandleInvalidPosition(
const char *startSpecifier,
7539 unsigned specifierLen,
7542 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7544 void HandleNullChar(
const char *nullCharacter)
override;
7546 template <
typename Range>
7548 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7549 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7550 bool IsStringLocation, Range StringRange,
7551 ArrayRef<FixItHint> Fixit = {});
7554 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7555 const char *startSpec,
7556 unsigned specifierLen,
7557 const char *csStart,
unsigned csLen);
7559 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7560 const char *startSpec,
7561 unsigned specifierLen);
7563 SourceRange getFormatStringRange();
7564 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7565 unsigned specifierLen);
7566 SourceLocation getLocationOfByte(
const char *x);
7568 const Expr *getDataArg(
unsigned i)
const;
7570 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7571 const analyze_format_string::ConversionSpecifier &CS,
7572 const char *startSpecifier,
unsigned specifierLen,
7575 template <
typename Range>
7576 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7577 bool IsStringLocation, Range StringRange,
7578 ArrayRef<FixItHint> Fixit = {});
7583SourceRange CheckFormatHandler::getFormatStringRange() {
7588getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7590 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7598SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7603void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7604 unsigned specifierLen){
7605 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7606 getLocationOfByte(startSpecifier),
7608 getSpecifierRange(startSpecifier, specifierLen));
7611void CheckFormatHandler::HandleInvalidLengthModifier(
7614 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7626 getSpecifierRange(startSpecifier, specifierLen));
7628 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7629 << FixedLM->toString()
7634 if (DiagID == diag::warn_format_nonsensical_length)
7640 getSpecifierRange(startSpecifier, specifierLen),
7645void CheckFormatHandler::HandleNonStandardLengthModifier(
7647 const char *startSpecifier,
unsigned specifierLen) {
7656 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7660 getSpecifierRange(startSpecifier, specifierLen));
7662 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7663 << FixedLM->toString()
7667 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7671 getSpecifierRange(startSpecifier, specifierLen));
7675void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7677 const char *startSpecifier,
unsigned specifierLen) {
7683 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7687 getSpecifierRange(startSpecifier, specifierLen));
7690 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7691 << FixedCS->toString()
7694 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7698 getSpecifierRange(startSpecifier, specifierLen));
7702void CheckFormatHandler::HandlePosition(
const char *startPos,
7705 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7706 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7707 getLocationOfByte(startPos),
7709 getSpecifierRange(startPos, posLen));
7712void CheckFormatHandler::HandleInvalidPosition(
7713 const char *startSpecifier,
unsigned specifierLen,
7716 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7717 EmitFormatDiagnostic(
7718 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7719 getLocationOfByte(startSpecifier),
true,
7720 getSpecifierRange(startSpecifier, specifierLen));
7723void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7727 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7728 getLocationOfByte(startPos),
7730 getSpecifierRange(startPos, posLen));
7733void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7736 EmitFormatDiagnostic(
7737 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7738 getLocationOfByte(nullCharacter),
true,
7739 getFormatStringRange());
7745const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7746 return Args[FirstDataArg + i];
7749void CheckFormatHandler::DoneProcessing() {
7752 if (HasFormatArguments()) {
7755 signed notCoveredArg = CoveredArgs.find_first();
7756 if (notCoveredArg >= 0) {
7757 assert((
unsigned)notCoveredArg < NumDataArgs);
7758 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7760 UncoveredArg.setAllCovered();
7765void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7766 const Expr *ArgExpr) {
7767 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7779 for (
auto E : DiagnosticExprs)
7782 CheckFormatHandler::EmitFormatDiagnostic(
7783 S, IsFunctionCall, DiagnosticExprs[0],
7789CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7791 const char *startSpec,
7792 unsigned specifierLen,
7793 const char *csStart,
7795 bool keepGoing =
true;
7796 if (argIndex < NumDataArgs) {
7799 CoveredArgs.set(argIndex);
7815 std::string CodePointStr;
7816 if (!llvm::sys::locale::isPrint(*csStart)) {
7817 llvm::UTF32 CodePoint;
7818 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7819 const llvm::UTF8 *E =
7820 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7821 llvm::ConversionResult
Result =
7822 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7824 if (
Result != llvm::conversionOK) {
7825 unsigned char FirstChar = *csStart;
7826 CodePoint = (llvm::UTF32)FirstChar;
7829 llvm::raw_string_ostream
OS(CodePointStr);
7830 if (CodePoint < 256)
7831 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7832 else if (CodePoint <= 0xFFFF)
7833 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7835 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7839 EmitFormatDiagnostic(
7840 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7841 true, getSpecifierRange(startSpec, specifierLen));
7847CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7848 const char *startSpec,
7849 unsigned specifierLen) {
7850 EmitFormatDiagnostic(
7851 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7852 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7856CheckFormatHandler::CheckNumArgs(
7859 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7861 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7863 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7864 << (argIndex+1) << NumDataArgs)
7865 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7866 EmitFormatDiagnostic(
7867 PDiag, getLocationOfByte(CS.
getStart()),
true,
7868 getSpecifierRange(startSpecifier, specifierLen));
7872 UncoveredArg.setAllCovered();
7878template<
typename Range>
7881 bool IsStringLocation,
7884 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7885 Loc, IsStringLocation, StringRange, FixIt);
7915template <
typename Range>
7916void CheckFormatHandler::EmitFormatDiagnostic(
7917 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7920 if (InFunctionCall) {
7925 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
7929 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
7930 diag::note_format_string_defined);
7932 Note << StringRange;
7941class CheckPrintfHandler :
public CheckFormatHandler {
7943 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7945 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7947 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7949 llvm::SmallBitVector &CheckedVarArgs,
7950 UncoveredArgHandler &UncoveredArg)
7951 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7952 numDataArgs, beg, APK, Args, formatIdx,
7953 inFunctionCall, CallType, CheckedVarArgs,
7956 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7959 bool allowsObjCArg()
const {
7960 return FSType == FormatStringType::NSString ||
7961 FSType == FormatStringType::OSLog ||
7962 FSType == FormatStringType::OSTrace;
7965 bool HandleInvalidPrintfConversionSpecifier(
7966 const analyze_printf::PrintfSpecifier &FS,
7967 const char *startSpecifier,
7968 unsigned specifierLen)
override;
7970 void handleInvalidMaskType(StringRef MaskType)
override;
7972 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7973 const char *startSpecifier,
unsigned specifierLen,
7974 const TargetInfo &
Target)
override;
7975 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
7976 const char *StartSpecifier,
7977 unsigned SpecifierLen,
7980 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
7981 const char *startSpecifier,
unsigned specifierLen);
7982 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
7983 const analyze_printf::OptionalAmount &Amt,
7985 const char *startSpecifier,
unsigned specifierLen);
7986 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
7987 const analyze_printf::OptionalFlag &flag,
7988 const char *startSpecifier,
unsigned specifierLen);
7989 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
7990 const analyze_printf::OptionalFlag &ignoredFlag,
7991 const analyze_printf::OptionalFlag &flag,
7992 const char *startSpecifier,
unsigned specifierLen);
7993 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7996 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7997 unsigned flagLen)
override;
7999 void HandleInvalidObjCModifierFlag(
const char *startFlag,
8000 unsigned flagLen)
override;
8003 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
8004 const char *flagsEnd,
8005 const char *conversionPosition)
override;
8010class EquatableFormatArgument {
8012 enum SpecifierSensitivity :
unsigned {
8019 enum FormatArgumentRole :
unsigned {
8027 analyze_format_string::ArgType ArgType;
8029 StringRef SpecifierLetter;
8030 CharSourceRange
Range;
8031 SourceLocation ElementLoc;
8032 FormatArgumentRole
Role : 2;
8033 SpecifierSensitivity Sensitivity : 2;
8034 unsigned Position : 14;
8035 unsigned ModifierFor : 14;
8037 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
8038 bool InFunctionCall)
const;
8041 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
8043 StringRef SpecifierLetter,
8044 analyze_format_string::ArgType ArgType,
8045 FormatArgumentRole
Role,
8046 SpecifierSensitivity Sensitivity,
unsigned Position,
8047 unsigned ModifierFor)
8048 : ArgType(ArgType), LengthMod(LengthMod),
8049 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
8050 Role(
Role), Sensitivity(Sensitivity), Position(Position),
8051 ModifierFor(ModifierFor) {}
8053 unsigned getPosition()
const {
return Position; }
8054 SourceLocation getSourceLocation()
const {
return ElementLoc; }
8056 analyze_format_string::LengthModifier getLengthModifier()
const {
8057 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
8059 void setModifierFor(
unsigned V) { ModifierFor =
V; }
8061 std::string buildFormatSpecifier()
const {
8063 llvm::raw_string_ostream(result)
8064 << getLengthModifier().toString() << SpecifierLetter;
8068 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
8069 const Expr *FmtExpr,
bool InFunctionCall)
const;
8073class DecomposePrintfHandler :
public CheckPrintfHandler {
8074 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
8077 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
8078 const Expr *origFormatExpr,
8080 unsigned numDataArgs,
bool isObjC,
const char *beg,
8082 ArrayRef<const Expr *> Args,
unsigned formatIdx,
8084 llvm::SmallBitVector &CheckedVarArgs,
8085 UncoveredArgHandler &UncoveredArg,
8086 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
8087 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
8088 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
8089 inFunctionCall, CallType, CheckedVarArgs,
8091 Specs(Specs), HadError(
false) {}
8095 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8097 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
8099 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
8100 const char *startSpecifier,
8101 unsigned specifierLen,
8102 const TargetInfo &
Target)
override;
8107bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
8109 unsigned specifierLen) {
8113 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
8115 startSpecifier, specifierLen,
8119void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
8120 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
8128 return T->isRecordType() ||
T->isComplexType();
8131bool CheckPrintfHandler::HandleAmount(
8133 const char *startSpecifier,
unsigned specifierLen) {
8135 if (HasFormatArguments()) {
8137 if (argIndex >= NumDataArgs) {
8138 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8142 getSpecifierRange(startSpecifier, specifierLen));
8152 CoveredArgs.set(argIndex);
8153 const Expr *Arg = getDataArg(argIndex);
8164 ? diag::err_printf_asterisk_wrong_type
8165 : diag::warn_printf_asterisk_wrong_type;
8166 EmitFormatDiagnostic(S.
PDiag(DiagID)
8171 getSpecifierRange(startSpecifier, specifierLen));
8181void CheckPrintfHandler::HandleInvalidAmount(
8185 const char *startSpecifier,
8186 unsigned specifierLen) {
8196 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8200 getSpecifierRange(startSpecifier, specifierLen),
8206 const char *startSpecifier,
8207 unsigned specifierLen) {
8211 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
8215 getSpecifierRange(startSpecifier, specifierLen),
8220void CheckPrintfHandler::HandleIgnoredFlag(
8224 const char *startSpecifier,
8225 unsigned specifierLen) {
8227 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8231 getSpecifierRange(startSpecifier, specifierLen),
8233 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8236void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8239 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
8240 getLocationOfByte(startFlag),
8242 getSpecifierRange(startFlag, flagLen));
8245void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8248 auto Range = getSpecifierRange(startFlag, flagLen);
8249 StringRef flag(startFlag, flagLen);
8250 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8251 getLocationOfByte(startFlag),
8256void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8257 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
8259 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8260 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8261 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8262 getLocationOfByte(conversionPosition),
8268 const Expr *FmtExpr,
8269 bool InFunctionCall)
const {
8270 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8271 ElementLoc,
true, Range);
8274bool EquatableFormatArgument::VerifyCompatible(
8275 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8276 bool InFunctionCall)
const {
8281 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8282 FmtExpr, InFunctionCall);
8283 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8287 if (
Role != FAR_Data) {
8288 if (ModifierFor !=
Other.ModifierFor) {
8291 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8292 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8293 FmtExpr, InFunctionCall);
8294 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8300 bool HadError =
false;
8301 if (Sensitivity !=
Other.Sensitivity) {
8304 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8305 << Sensitivity <<
Other.Sensitivity,
8306 FmtExpr, InFunctionCall);
8307 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8308 << 0 <<
Other.Range;
8311 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8315 case MK::MatchPromotion:
8319 case MK::NoMatchTypeConfusion:
8320 case MK::NoMatchPromotionTypeConfusion:
8322 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8323 << buildFormatSpecifier()
8324 <<
Other.buildFormatSpecifier(),
8325 FmtExpr, InFunctionCall);
8326 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8327 << 0 <<
Other.Range;
8330 case MK::NoMatchPedantic:
8332 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8333 << buildFormatSpecifier()
8334 <<
Other.buildFormatSpecifier(),
8335 FmtExpr, InFunctionCall);
8336 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8337 << 0 <<
Other.Range;
8340 case MK::NoMatchSignedness:
8342 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8343 << buildFormatSpecifier()
8344 <<
Other.buildFormatSpecifier(),
8345 FmtExpr, InFunctionCall);
8346 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8347 << 0 <<
Other.Range;
8353bool DecomposePrintfHandler::GetSpecifiers(
8354 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8357 StringRef
Data = FSL->getString();
8358 const char *Str =
Data.data();
8359 llvm::SmallBitVector BV;
8360 UncoveredArgHandler UA;
8361 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8362 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8374 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8375 const EquatableFormatArgument &B) {
8376 return A.getPosition() < B.getPosition();
8381bool DecomposePrintfHandler::HandlePrintfSpecifier(
8384 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8399 const unsigned Unset = ~0;
8400 unsigned FieldWidthIndex = Unset;
8401 unsigned PrecisionIndex = Unset;
8405 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8406 FieldWidthIndex = Specs.size();
8407 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8408 getLocationOfByte(FieldWidth.getStart()),
8410 FieldWidth.getArgType(S.
Context),
8411 EquatableFormatArgument::FAR_FieldWidth,
8412 EquatableFormatArgument::SS_None,
8413 FieldWidth.usesPositionalArg()
8414 ? FieldWidth.getPositionalArgIndex() - 1
8420 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8421 PrecisionIndex = Specs.size();
8423 getSpecifierRange(startSpecifier, specifierLen),
8424 getLocationOfByte(Precision.getStart()),
8426 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8427 EquatableFormatArgument::SS_None,
8428 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8434 unsigned SpecIndex =
8436 if (FieldWidthIndex != Unset)
8437 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8438 if (PrecisionIndex != Unset)
8439 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8441 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8443 Sensitivity = EquatableFormatArgument::SS_Private;
8445 Sensitivity = EquatableFormatArgument::SS_Public;
8447 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8449 Sensitivity = EquatableFormatArgument::SS_None;
8452 getSpecifierRange(startSpecifier, specifierLen),
8455 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8460 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8465 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8466 SpecIndex + 1, SpecIndex);
8474template<
typename MemberKind>
8492 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8507 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8509 if ((*MI)->getMinRequiredArguments() == 0)
8517bool CheckPrintfHandler::checkForCStrMembers(
8524 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8527 if (
Method->getMinRequiredArguments() == 0 &&
8540bool CheckPrintfHandler::HandlePrintfSpecifier(
8554 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8555 startSpecifier, specifierLen);
8563 startSpecifier, specifierLen)) {
8568 startSpecifier, specifierLen)) {
8572 if (!CS.consumesDataArgument()) {
8580 if (argIndex < NumDataArgs) {
8584 CoveredArgs.set(argIndex);
8591 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8594 if (HasFormatArguments()) {
8596 CoveredArgs.set(argIndex + 1);
8599 const Expr *Ex = getDataArg(argIndex);
8603 : ArgType::CPointerTy;
8605 EmitFormatDiagnostic(
8606 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8610 getSpecifierRange(startSpecifier, specifierLen));
8613 Ex = getDataArg(argIndex + 1);
8616 EmitFormatDiagnostic(
8617 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8621 getSpecifierRange(startSpecifier, specifierLen));
8628 if (!allowsObjCArg() && CS.isObjCArg()) {
8629 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8636 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8643 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8644 getLocationOfByte(CS.getStart()),
8646 getSpecifierRange(startSpecifier, specifierLen));
8656 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8663 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8667 getSpecifierRange(startSpecifier, specifierLen));
8670 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8674 getSpecifierRange(startSpecifier, specifierLen));
8678 const llvm::Triple &Triple =
Target.getTriple();
8680 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8681 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8682 getLocationOfByte(CS.getStart()),
8684 getSpecifierRange(startSpecifier, specifierLen));
8690 startSpecifier, specifierLen);
8696 startSpecifier, specifierLen);
8702 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8703 getLocationOfByte(startSpecifier),
8705 getSpecifierRange(startSpecifier, specifierLen));
8714 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8716 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8725 startSpecifier, specifierLen);
8728 startSpecifier, specifierLen);
8733 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8734 diag::warn_format_nonsensical_length);
8736 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8738 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8739 diag::warn_format_non_standard_conversion_spec);
8742 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8745 if (!HasFormatArguments())
8748 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8751 const Expr *Arg = getDataArg(argIndex);
8755 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8767 case Stmt::ArraySubscriptExprClass:
8768 case Stmt::CallExprClass:
8769 case Stmt::CharacterLiteralClass:
8770 case Stmt::CXXBoolLiteralExprClass:
8771 case Stmt::DeclRefExprClass:
8772 case Stmt::FloatingLiteralClass:
8773 case Stmt::IntegerLiteralClass:
8774 case Stmt::MemberExprClass:
8775 case Stmt::ObjCArrayLiteralClass:
8776 case Stmt::ObjCBoolLiteralExprClass:
8777 case Stmt::ObjCBoxedExprClass:
8778 case Stmt::ObjCDictionaryLiteralClass:
8779 case Stmt::ObjCEncodeExprClass:
8780 case Stmt::ObjCIvarRefExprClass:
8781 case Stmt::ObjCMessageExprClass:
8782 case Stmt::ObjCPropertyRefExprClass:
8783 case Stmt::ObjCStringLiteralClass:
8784 case Stmt::ObjCSubscriptRefExprClass:
8785 case Stmt::ParenExprClass:
8786 case Stmt::StringLiteralClass:
8787 case Stmt::UnaryOperatorClass:
8794static std::pair<QualType, StringRef>
8801 StringRef Name = UserTy->getDecl()->getName();
8802 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8803 .Case(
"CFIndex", Context.getNSIntegerType())
8804 .Case(
"NSInteger", Context.getNSIntegerType())
8805 .Case(
"NSUInteger", Context.getNSUIntegerType())
8806 .Case(
"SInt32", Context.IntTy)
8807 .Case(
"UInt32", Context.UnsignedIntTy)
8811 return std::make_pair(CastTy, Name);
8813 TyTy = UserTy->desugar();
8817 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8819 PE->getSubExpr()->getType(),
8828 StringRef TrueName, FalseName;
8830 std::tie(TrueTy, TrueName) =
8832 CO->getTrueExpr()->getType(),
8834 std::tie(FalseTy, FalseName) =
8836 CO->getFalseExpr()->getType(),
8837 CO->getFalseExpr());
8839 if (TrueTy == FalseTy)
8840 return std::make_pair(TrueTy, TrueName);
8841 else if (TrueTy.
isNull())
8842 return std::make_pair(FalseTy, FalseName);
8843 else if (FalseTy.
isNull())
8844 return std::make_pair(TrueTy, TrueName);
8847 return std::make_pair(
QualType(), StringRef());
8866 From = VecTy->getElementType();
8868 To = VecTy->getElementType();
8879 diag::warn_format_conversion_argument_type_mismatch_signedness,
8883 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
8892 const char *StartSpecifier,
8893 unsigned SpecifierLen,
8905 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8906 ExprTy = TET->getUnderlyingExpr()->getType();
8921 getSpecifierRange(StartSpecifier, SpecifierLen);
8923 llvm::raw_svector_ostream os(FSString);
8925 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8936 getSpecifierRange(StartSpecifier, SpecifierLen);
8937 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8947 if (
Match == ArgType::Match)
8951 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8960 E = ICE->getSubExpr();
8970 if (OrigMatch == ArgType::NoMatchSignedness &&
8971 ImplicitMatch != ArgType::NoMatchSignedness)
8978 if (ImplicitMatch == ArgType::Match)
8996 if (
Match == ArgType::MatchPromotion)
9000 if (
Match == ArgType::MatchPromotion) {
9004 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
9005 ImplicitMatch != ArgType::NoMatchTypeConfusion)
9009 if (ImplicitMatch == ArgType::NoMatchPedantic ||
9010 ImplicitMatch == ArgType::NoMatchTypeConfusion)
9011 Match = ImplicitMatch;
9012 assert(
Match != ArgType::MatchPromotion);
9015 bool IsEnum =
false;
9016 bool IsScopedEnum =
false;
9019 IntendedTy = ED->getIntegerType();
9020 if (!ED->isScoped()) {
9021 ExprTy = IntendedTy;
9026 IsScopedEnum =
true;
9033 if (isObjCContext() &&
9044 const llvm::APInt &
V = IL->getValue();
9054 if (TD->getUnderlyingType() == IntendedTy)
9064 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
9072 if (!IsScopedEnum &&
9073 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
9077 IntendedTy = CastTy;
9078 ShouldNotPrintDirectly =
true;
9083 PrintfSpecifier fixedFS = FS;
9090 llvm::raw_svector_ostream os(buf);
9093 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
9095 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
9101 llvm_unreachable(
"expected non-matching");
9103 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9106 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9109 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9112 Diag = diag::warn_format_conversion_argument_type_mismatch;
9133 llvm::raw_svector_ostream CastFix(CastBuf);
9134 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9136 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9142 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9147 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9169 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9175 Name = TypedefTy->getDecl()->getName();
9179 ? diag::warn_format_argument_needs_cast_pedantic
9180 : diag::warn_format_argument_needs_cast;
9181 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9192 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9193 : diag::warn_format_conversion_argument_type_mismatch;
9195 EmitFormatDiagnostic(
9207 bool EmitTypeMismatch =
false;
9216 llvm_unreachable(
"expected non-matching");
9218 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9221 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9224 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9228 ? diag::err_format_conversion_argument_type_mismatch
9229 : diag::warn_format_conversion_argument_type_mismatch;
9233 EmitFormatDiagnostic(
9242 EmitTypeMismatch =
true;
9244 EmitFormatDiagnostic(
9245 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9246 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9250 checkForCStrMembers(AT, E);
9256 EmitTypeMismatch =
true;
9258 EmitFormatDiagnostic(
9259 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9260 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9273 if (EmitTypeMismatch) {
9279 EmitFormatDiagnostic(
9280 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9286 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9287 "format string specifier index out of range");
9288 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9298class CheckScanfHandler :
public CheckFormatHandler {
9300 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9302 unsigned firstDataArg,
unsigned numDataArgs,
9304 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9306 llvm::SmallBitVector &CheckedVarArgs,
9307 UncoveredArgHandler &UncoveredArg)
9308 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9309 numDataArgs, beg, APK, Args, formatIdx,
9310 inFunctionCall, CallType, CheckedVarArgs,
9313 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9314 const char *startSpecifier,
9315 unsigned specifierLen)
override;
9317 bool HandleInvalidScanfConversionSpecifier(
9318 const analyze_scanf::ScanfSpecifier &FS,
9319 const char *startSpecifier,
9320 unsigned specifierLen)
override;
9322 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9327void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9329 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9330 getLocationOfByte(end),
true,
9331 getSpecifierRange(start, end - start));
9334bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9336 const char *startSpecifier,
9337 unsigned specifierLen) {
9341 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9343 startSpecifier, specifierLen,
9347bool CheckScanfHandler::HandleScanfSpecifier(
9349 const char *startSpecifier,
9350 unsigned specifierLen) {
9364 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9365 startSpecifier, specifierLen);
9376 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9391 if (argIndex < NumDataArgs) {
9395 CoveredArgs.set(argIndex);
9401 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9402 diag::warn_format_nonsensical_length);
9404 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9406 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9407 diag::warn_format_non_standard_conversion_spec);
9410 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9413 if (!HasFormatArguments())
9416 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9420 const Expr *Ex = getDataArg(argIndex);
9438 ScanfSpecifier fixedFS = FS;
9443 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9445 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9446 : diag::warn_format_conversion_argument_type_mismatch;
9451 llvm::raw_svector_ostream os(buf);
9454 EmitFormatDiagnostic(
9459 getSpecifierRange(startSpecifier, specifierLen),
9461 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9468 getSpecifierRange(startSpecifier, specifierLen));
9478 const Expr *FmtExpr,
bool InFunctionCall) {
9479 bool HadError =
false;
9480 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9481 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9482 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9494 for (; FmtIter < FmtEnd; ++FmtIter) {
9498 if (FmtIter->getPosition() < RefIter->getPosition())
9502 if (FmtIter->getPosition() > RefIter->getPosition())
9506 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9510 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9511 return Arg.getPosition() != RefIter->getPosition();
9515 if (FmtIter < FmtEnd) {
9516 CheckFormatHandler::EmitFormatDiagnostic(
9517 S, InFunctionCall, FmtExpr,
9518 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9519 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9520 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9521 }
else if (RefIter < RefEnd) {
9522 CheckFormatHandler::EmitFormatDiagnostic(
9523 S, InFunctionCall, FmtExpr,
9524 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9527 << 1 << RefIter->getSourceRange();
9533 Sema &S,
const FormatStringLiteral *FExpr,
9538 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9539 bool IgnoreStringsWithoutSpecifiers) {
9541 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9542 CheckFormatHandler::EmitFormatDiagnostic(
9543 S, inFunctionCall, Args[format_idx],
9544 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9550 StringRef StrRef = FExpr->getString();
9551 const char *Str = StrRef.data();
9555 assert(
T &&
"String literal not of constant array type!");
9556 size_t TypeSize =
T->getZExtSize();
9557 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9558 const unsigned numDataArgs = Args.size() - firstDataArg;
9560 if (IgnoreStringsWithoutSpecifiers &&
9567 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9568 CheckFormatHandler::EmitFormatDiagnostic(
9569 S, inFunctionCall, Args[format_idx],
9570 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9571 FExpr->getBeginLoc(),
9577 if (StrLen == 0 && numDataArgs > 0) {
9578 CheckFormatHandler::EmitFormatDiagnostic(
9579 S, inFunctionCall, Args[format_idx],
9580 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9591 if (ReferenceFormatString ==
nullptr) {
9592 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9593 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9594 inFunctionCall, CallType, CheckedVarArgs,
9604 Type, ReferenceFormatString, FExpr->getFormatString(),
9605 inFunctionCall ?
nullptr : Args[format_idx]);
9608 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9609 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9610 CallType, CheckedVarArgs, UncoveredArg);
9630 FormatStringLiteral RefLit = AuthoritativeFormatString;
9631 FormatStringLiteral TestLit = TestedFormatString;
9633 bool DiagAtStringLiteral;
9634 if (FunctionCallArg) {
9635 Arg = FunctionCallArg;
9636 DiagAtStringLiteral =
false;
9638 Arg = TestedFormatString;
9639 DiagAtStringLiteral =
true;
9641 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9642 AuthoritativeFormatString,
Type,
9643 IsObjC,
true, RefArgs) &&
9644 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9645 DiagAtStringLiteral, FmtArgs)) {
9647 TestedFormatString, FmtArgs, Arg,
9648 DiagAtStringLiteral);
9661 FormatStringLiteral RefLit = Str;
9665 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9674 bool HadError =
false;
9675 auto Iter = Args.begin();
9676 auto End = Args.end();
9677 while (Iter != End) {
9678 const auto &FirstInGroup = *Iter;
9680 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9682 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9691 const char *Str = StrRef.data();
9694 assert(
T &&
"String literal not of constant array type!");
9695 size_t TypeSize =
T->getZExtSize();
9696 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9707 switch (AbsFunction) {
9711 case Builtin::BI__builtin_abs:
9712 return Builtin::BI__builtin_labs;
9713 case Builtin::BI__builtin_labs:
9714 return Builtin::BI__builtin_llabs;
9715 case Builtin::BI__builtin_llabs:
9718 case Builtin::BI__builtin_fabsf:
9719 return Builtin::BI__builtin_fabs;
9720 case Builtin::BI__builtin_fabs:
9721 return Builtin::BI__builtin_fabsl;
9722 case Builtin::BI__builtin_fabsl:
9725 case Builtin::BI__builtin_cabsf:
9726 return Builtin::BI__builtin_cabs;
9727 case Builtin::BI__builtin_cabs:
9728 return Builtin::BI__builtin_cabsl;
9729 case Builtin::BI__builtin_cabsl:
9732 case Builtin::BIabs:
9733 return Builtin::BIlabs;
9734 case Builtin::BIlabs:
9735 return Builtin::BIllabs;
9736 case Builtin::BIllabs:
9739 case Builtin::BIfabsf:
9740 return Builtin::BIfabs;
9741 case Builtin::BIfabs:
9742 return Builtin::BIfabsl;
9743 case Builtin::BIfabsl:
9746 case Builtin::BIcabsf:
9747 return Builtin::BIcabs;
9748 case Builtin::BIcabs:
9749 return Builtin::BIcabsl;
9750 case Builtin::BIcabsl:
9779 unsigned AbsFunctionKind) {
9780 unsigned BestKind = 0;
9781 uint64_t ArgSize = Context.getTypeSize(ArgType);
9782 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9785 if (Context.getTypeSize(ParamType) >= ArgSize) {
9788 else if (Context.hasSameType(ParamType, ArgType)) {
9804 if (
T->isIntegralOrEnumerationType())
9806 if (
T->isRealFloatingType())
9808 if (
T->isAnyComplexType())
9811 llvm_unreachable(
"Type not integer, floating, or complex");
9818 switch (ValueKind) {
9823 case Builtin::BI__builtin_fabsf:
9824 case Builtin::BI__builtin_fabs:
9825 case Builtin::BI__builtin_fabsl:
9826 case Builtin::BI__builtin_cabsf:
9827 case Builtin::BI__builtin_cabs:
9828 case Builtin::BI__builtin_cabsl:
9829 return Builtin::BI__builtin_abs;
9830 case Builtin::BIfabsf:
9831 case Builtin::BIfabs:
9832 case Builtin::BIfabsl:
9833 case Builtin::BIcabsf:
9834 case Builtin::BIcabs:
9835 case Builtin::BIcabsl:
9836 return Builtin::BIabs;
9842 case Builtin::BI__builtin_abs:
9843 case Builtin::BI__builtin_labs:
9844 case Builtin::BI__builtin_llabs:
9845 case Builtin::BI__builtin_cabsf:
9846 case Builtin::BI__builtin_cabs:
9847 case Builtin::BI__builtin_cabsl:
9848 return Builtin::BI__builtin_fabsf;
9849 case Builtin::BIabs:
9850 case Builtin::BIlabs:
9851 case Builtin::BIllabs:
9852 case Builtin::BIcabsf:
9853 case Builtin::BIcabs:
9854 case Builtin::BIcabsl:
9855 return Builtin::BIfabsf;
9861 case Builtin::BI__builtin_abs:
9862 case Builtin::BI__builtin_labs:
9863 case Builtin::BI__builtin_llabs:
9864 case Builtin::BI__builtin_fabsf:
9865 case Builtin::BI__builtin_fabs:
9866 case Builtin::BI__builtin_fabsl:
9867 return Builtin::BI__builtin_cabsf;
9868 case Builtin::BIabs:
9869 case Builtin::BIlabs:
9870 case Builtin::BIllabs:
9871 case Builtin::BIfabsf:
9872 case Builtin::BIfabs:
9873 case Builtin::BIfabsl:
9874 return Builtin::BIcabsf;
9877 llvm_unreachable(
"Unable to convert function");
9888 case Builtin::BI__builtin_abs:
9889 case Builtin::BI__builtin_fabs:
9890 case Builtin::BI__builtin_fabsf:
9891 case Builtin::BI__builtin_fabsl:
9892 case Builtin::BI__builtin_labs:
9893 case Builtin::BI__builtin_llabs:
9894 case Builtin::BI__builtin_cabs:
9895 case Builtin::BI__builtin_cabsf:
9896 case Builtin::BI__builtin_cabsl:
9897 case Builtin::BIabs:
9898 case Builtin::BIlabs:
9899 case Builtin::BIllabs:
9900 case Builtin::BIfabs:
9901 case Builtin::BIfabsf:
9902 case Builtin::BIfabsl:
9903 case Builtin::BIcabs:
9904 case Builtin::BIcabsf:
9905 case Builtin::BIcabsl:
9908 llvm_unreachable(
"Unknown Builtin type");
9914 unsigned AbsKind,
QualType ArgType) {
9915 bool EmitHeaderHint =
true;
9916 const char *HeaderName =
nullptr;
9917 std::string FunctionName;
9918 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9919 FunctionName =
"std::abs";
9920 if (ArgType->isIntegralOrEnumerationType()) {
9921 HeaderName =
"cstdlib";
9922 }
else if (ArgType->isRealFloatingType()) {
9923 HeaderName =
"cmath";
9925 llvm_unreachable(
"Invalid Type");
9934 for (
const auto *I : R) {
9937 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9939 FDecl = dyn_cast<FunctionDecl>(I);
9954 EmitHeaderHint =
false;
9972 EmitHeaderHint =
false;
9976 }
else if (!R.
empty()) {
9982 S.
Diag(Loc, diag::note_replace_abs_function)
9988 if (!EmitHeaderHint)
9991 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9995template <std::
size_t StrLen>
9997 const char (&Str)[StrLen]) {
10010 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
10011 return llvm::is_contained(names, calleeName);
10016 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
10017 "__builtin_nanf16",
"__builtin_nanf128"});
10019 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
10020 "__builtin_inff16",
"__builtin_inff128"});
10022 llvm_unreachable(
"unknown MathCheck");
10026 if (FDecl->
getName() !=
"infinity")
10029 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
10031 if (RDecl->
getName() !=
"numeric_limits")
10048 if (FPO.getNoHonorNaNs() &&
10051 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10052 << 1 << 0 <<
Call->getSourceRange();
10056 if (FPO.getNoHonorInfs() &&
10060 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
10061 << 0 << 0 <<
Call->getSourceRange();
10065void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
10067 if (
Call->getNumArgs() != 1)
10072 if (AbsKind == 0 && !IsStdAbs)
10075 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10076 QualType ParamType =
Call->getArg(0)->getType();
10081 std::string FunctionName =
10082 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
10083 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
10084 Diag(
Call->getExprLoc(), diag::note_remove_abs)
10113 if (ArgValueKind == ParamValueKind) {
10114 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
10118 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
10119 << FDecl << ArgType << ParamType;
10121 if (NewAbsKind == 0)
10125 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10134 if (NewAbsKind == 0)
10137 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10138 << FDecl << ParamValueKind << ArgValueKind;
10141 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10147 if (!
Call || !FDecl)
return;
10151 if (
Call->getExprLoc().isMacroID())
return;
10154 if (
Call->getNumArgs() != 2)
return;
10157 if (!ArgList)
return;
10158 if (ArgList->size() != 1)
return;
10161 const auto& TA = ArgList->
get(0);
10163 QualType ArgType = TA.getAsType();
10167 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10168 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10169 if (!MTE)
return false;
10170 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10171 if (!
Num)
return false;
10172 if (
Num->getValue() != 0)
return false;
10176 const Expr *FirstArg =
Call->getArg(0);
10177 const Expr *SecondArg =
Call->getArg(1);
10178 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10179 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10182 if (IsFirstArgZero == IsSecondArgZero)
return;
10187 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10189 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10190 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10193 SourceRange RemovalRange;
10194 if (IsFirstArgZero) {
10195 RemovalRange = SourceRange(FirstRange.
getBegin(),
10202 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10217 const auto *Size = dyn_cast<BinaryOperator>(E);
10222 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10226 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10227 << SizeRange << FnName;
10228 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10233 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10244 bool &IsContained) {
10246 const Type *Ty =
T->getBaseElementTypeUnsafe();
10247 IsContained =
false;
10260 for (
auto *FD : RD->
fields()) {
10264 IsContained =
true;
10265 return ContainedRD;
10273 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10274 if (Unary->getKind() == UETT_SizeOf)
10283 if (!
SizeOf->isArgumentType())
10284 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10291 return SizeOf->getTypeOfArgument();
10297struct SearchNonTrivialToInitializeField
10300 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10302 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10305 SourceLocation SL) {
10306 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10307 asDerived().visitArray(PDIK, AT, SL);
10311 Super::visitWithKind(PDIK, FT, SL);
10314 void visitARCStrong(QualType FT, SourceLocation SL) {
10317 void visitARCWeak(QualType FT, SourceLocation SL) {
10320 void visitStruct(QualType FT, SourceLocation SL) {
10325 const ArrayType *AT, SourceLocation SL) {
10326 visit(getContext().getBaseElementType(AT), SL);
10328 void visitTrivial(QualType FT, SourceLocation SL) {}
10330 static void diag(QualType RT,
const Expr *E, Sema &S) {
10331 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10340struct SearchNonTrivialToCopyField
10342 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10344 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10347 SourceLocation SL) {
10348 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10349 asDerived().visitArray(PCK, AT, SL);
10353 Super::visitWithKind(PCK, FT, SL);
10356 void visitARCStrong(QualType FT, SourceLocation SL) {
10359 void visitARCWeak(QualType FT, SourceLocation SL) {
10362 void visitPtrAuth(QualType FT, SourceLocation SL) {
10365 void visitStruct(QualType FT, SourceLocation SL) {
10370 SourceLocation SL) {
10371 visit(getContext().getBaseElementType(AT), SL);
10374 SourceLocation SL) {}
10375 void visitTrivial(QualType FT, SourceLocation SL) {}
10376 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10378 static void diag(QualType RT,
const Expr *E, Sema &S) {
10379 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10394 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10395 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10419 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10421 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10422 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10428 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10431 const Expr *SizeArg =
10432 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10434 auto isLiteralZero = [](
const Expr *E) {
10444 if (isLiteralZero(SizeArg) &&
10451 if (BId == Builtin::BIbzero ||
10454 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10455 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10456 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10457 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10458 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10466 if (BId == Builtin::BImemset &&
10470 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10471 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10476void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10483 unsigned ExpectedNumArgs =
10484 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10485 if (
Call->getNumArgs() < ExpectedNumArgs)
10488 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10489 BId == Builtin::BIstrndup ? 1 : 2);
10491 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10492 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10495 Call->getBeginLoc(),
Call->getRParenLoc()))
10504 llvm::FoldingSetNodeID SizeOfArgID;
10509 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10510 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10513 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10514 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10515 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10517 QualType DestTy = Dest->
getType();
10518 QualType PointeeTy;
10519 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10532 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10536 if (SizeOfArgID == llvm::FoldingSetNodeID())
10538 llvm::FoldingSetNodeID DestID;
10540 if (DestID == SizeOfArgID) {
10543 unsigned ActionIdx = 0;
10544 StringRef ReadableName = FnName->
getName();
10546 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10547 if (UnaryOp->getOpcode() == UO_AddrOf)
10556 SourceLocation SL = SizeOfArg->
getExprLoc();
10561 if (
SM.isMacroArgExpansion(SL)) {
10563 SL =
SM.getSpellingLoc(SL);
10564 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10566 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10571 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10578 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10589 if (SizeOfArgTy != QualType()) {
10591 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10593 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10594 << FnName << SizeOfArgTy << ArgIdx
10601 PointeeTy = DestTy;
10604 if (PointeeTy == QualType())
10609 if (
const CXXRecordDecl *ContainedRD =
10612 unsigned OperationType = 0;
10613 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10616 if (ArgIdx != 0 || IsCmp) {
10617 if (BId == Builtin::BImemcpy)
10619 else if(BId == Builtin::BImemmove)
10626 PDiag(diag::warn_dyn_class_memaccess)
10627 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10628 << IsContained << ContainedRD << OperationType
10629 <<
Call->getCallee()->getSourceRange());
10631 BId != Builtin::BImemset)
10634 PDiag(diag::warn_arc_object_memaccess)
10635 << ArgIdx << FnName << PointeeTy
10636 <<
Call->getCallee()->getSourceRange());
10643 bool NonTriviallyCopyableCXXRecord =
10647 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10650 PDiag(diag::warn_cstruct_memaccess)
10651 << ArgIdx << FnName << PointeeTy << 0);
10652 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10653 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10654 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10658 PDiag(diag::warn_cxxstruct_memaccess)
10659 << FnName << PointeeTy);
10660 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10663 PDiag(diag::warn_cstruct_memaccess)
10664 << ArgIdx << FnName << PointeeTy << 1);
10665 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10666 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10667 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10671 PDiag(diag::warn_cxxstruct_memaccess)
10672 << FnName << PointeeTy);
10681 PDiag(diag::note_bad_memaccess_silence)
10717 if (CAT->getZExtSize() <= 1)
10725void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10729 unsigned NumArgs =
Call->getNumArgs();
10730 if ((NumArgs != 3) && (NumArgs != 4))
10735 const Expr *CompareWithSrc =
nullptr;
10738 Call->getBeginLoc(),
Call->getRParenLoc()))
10743 CompareWithSrc = Ex;
10746 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10747 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10748 SizeCall->getNumArgs() == 1)
10753 if (!CompareWithSrc)
10760 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10764 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10765 if (!CompareWithSrcDRE ||
10769 const Expr *OriginalSizeArg =
Call->getArg(2);
10770 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10777 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10781 SmallString<128> sizeString;
10782 llvm::raw_svector_ostream
OS(sizeString);
10787 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10794 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10795 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10796 return D1->getDecl() == D2->getDecl();
10801 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10810void Sema::CheckStrncatArguments(
const CallExpr *CE,
10825 unsigned PatternType = 0;
10833 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10834 if (BE->getOpcode() == BO_Sub) {
10835 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10836 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10847 if (PatternType == 0)
10856 if (
SM.isMacroArgExpansion(SL)) {
10857 SL =
SM.getSpellingLoc(SL);
10858 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10863 QualType DstTy = DstArg->
getType();
10866 if (!isKnownSizeArray) {
10867 if (PatternType == 1)
10868 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10870 Diag(SL, diag::warn_strncat_src_size) << SR;
10874 if (PatternType == 1)
10875 Diag(SL, diag::warn_strncat_large_size) << SR;
10877 Diag(SL, diag::warn_strncat_src_size) << SR;
10879 SmallString<128> sizeString;
10880 llvm::raw_svector_ostream
OS(sizeString);
10888 Diag(SL, diag::note_strncat_wrong_size)
10893void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10902void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10904 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10905 const Decl *D = Lvalue->getDecl();
10906 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10907 if (!DD->getType()->isReferenceType())
10908 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10912 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10913 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10914 Lvalue->getMemberDecl());
10917void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10919 const auto *Lambda = dyn_cast<LambdaExpr>(
10924 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10925 << CalleeName << 2 ;
10928void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10930 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10931 if (Var ==
nullptr)
10935 << CalleeName << 0 << Var;
10938void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10941 llvm::raw_svector_ostream
OS(SizeString);
10944 if (Kind == clang::CK_BitCast &&
10945 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10947 if (Kind == clang::CK_IntegralToPointer &&
10949 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10952 switch (
Cast->getCastKind()) {
10953 case clang::CK_BitCast:
10954 case clang::CK_IntegralToPointer:
10955 case clang::CK_FunctionToPointerDecay:
10964 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10965 << CalleeName << 0 <<
OS.str();
10969void Sema::CheckFreeArguments(
const CallExpr *E) {
10970 const std::string CalleeName =
10975 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10977 case UnaryOperator::Opcode::UO_AddrOf:
10978 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10979 case UnaryOperator::Opcode::UO_Plus:
10980 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10985 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10987 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10989 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10990 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10991 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10997 << CalleeName << 1 ;
11002 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
11003 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
11007Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
11016 Diag(ReturnLoc, diag::warn_null_ret)
11026 if (Op == OO_New || Op == OO_Array_New) {
11027 const FunctionProtoType *Proto
11031 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
11037 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
11042 if (
Context.getTargetInfo().getTriple().isPPC64())
11054 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
11055 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
11057 return FPLiteral && FPCast;
11060 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
11066 llvm::APFloat TargetC = FPLiteral->
getValue();
11067 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
11068 llvm::APFloat::rmNearestTiesToEven, &Lossy);
11072 Diag(Loc, diag::warn_float_compare_literal)
11073 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
11086 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
11087 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
11088 if (DRL->getDecl() == DRR->getDecl())
11096 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
11097 if (FLL->isExact())
11099 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
11100 if (FLR->isExact())
11104 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
11105 CL &&
CL->getBuiltinCallee())
11108 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
11109 CR && CR->getBuiltinCallee())
11113 Diag(Loc, diag::warn_floatingpoint_eq)
11134 IntRange(
unsigned Width,
bool NonNegative)
11135 : Width(Width), NonNegative(NonNegative) {}
11138 unsigned valueBits()
const {
11139 return NonNegative ? Width : Width - 1;
11143 static IntRange forBoolType() {
11144 return IntRange(1,
true);
11148 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11149 return forValueOfCanonicalType(
C,
11154 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11157 if (
const auto *VT = dyn_cast<VectorType>(
T))
11158 T = VT->getElementType().getTypePtr();
11159 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11160 T = CT->getElementType().getTypePtr();
11161 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11162 T = AT->getValueType().getTypePtr();
11164 if (!
C.getLangOpts().CPlusPlus) {
11167 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11172 if (
Enum->isFixed()) {
11173 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11174 !
Enum->getIntegerType()->isSignedIntegerType());
11177 unsigned NumPositive =
Enum->getNumPositiveBits();
11178 unsigned NumNegative =
Enum->getNumNegativeBits();
11180 if (NumNegative == 0)
11181 return IntRange(NumPositive,
true);
11183 return IntRange(std::max(NumPositive + 1, NumNegative),
11187 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11188 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11201 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11204 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11205 T = VT->getElementType().getTypePtr();
11206 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11207 T = CT->getElementType().getTypePtr();
11208 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11209 T = AT->getValueType().getTypePtr();
11211 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11213 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11214 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11223 static IntRange join(IntRange L, IntRange R) {
11224 bool Unsigned = L.NonNegative && R.NonNegative;
11225 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
11226 L.NonNegative && R.NonNegative);
11230 static IntRange bit_and(IntRange L, IntRange R) {
11231 unsigned Bits = std::max(L.Width, R.Width);
11232 bool NonNegative =
false;
11233 if (L.NonNegative) {
11234 Bits = std::min(Bits, L.Width);
11235 NonNegative =
true;
11237 if (R.NonNegative) {
11238 Bits = std::min(Bits, R.Width);
11239 NonNegative =
true;
11241 return IntRange(Bits, NonNegative);
11245 static IntRange sum(IntRange L, IntRange R) {
11246 bool Unsigned = L.NonNegative && R.NonNegative;
11247 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
11252 static IntRange difference(IntRange L, IntRange R) {
11256 bool CanWiden = !L.NonNegative || !R.NonNegative;
11257 bool Unsigned = L.NonNegative && R.Width == 0;
11258 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
11264 static IntRange product(IntRange L, IntRange R) {
11268 bool CanWiden = !L.NonNegative && !R.NonNegative;
11269 bool Unsigned = L.NonNegative && R.NonNegative;
11270 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
11275 static IntRange rem(IntRange L, IntRange R) {
11279 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
11287 if (value.isSigned() && value.isNegative())
11288 return IntRange(value.getSignificantBits(),
false);
11290 if (value.getBitWidth() > MaxWidth)
11291 value = value.trunc(MaxWidth);
11295 return IntRange(value.getActiveBits(),
true);
11299 if (result.
isInt())
11306 R = IntRange::join(R, El);
11314 return IntRange::join(R, I);
11329 Ty = AtomicRHS->getValueType();
11348 bool InConstantContext,
11349 bool Approximate) {
11360 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11361 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11365 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11367 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11368 CE->getCastKind() == CK_BooleanToSignedIntegral;
11371 if (!isIntegerCast)
11372 return OutputTypeRange;
11375 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11376 InConstantContext, Approximate);
11378 return std::nullopt;
11381 if (SubRange->Width >= OutputTypeRange.Width)
11382 return OutputTypeRange;
11386 return IntRange(SubRange->Width,
11387 SubRange->NonNegative || OutputTypeRange.NonNegative);
11390 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11393 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11395 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11396 InConstantContext, Approximate);
11401 Expr *TrueExpr = CO->getTrueExpr();
11403 return std::nullopt;
11405 std::optional<IntRange> L =
11408 return std::nullopt;
11410 Expr *FalseExpr = CO->getFalseExpr();
11412 return std::nullopt;
11414 std::optional<IntRange> R =
11417 return std::nullopt;
11419 return IntRange::join(*L, *R);
11422 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11423 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11425 switch (BO->getOpcode()) {
11427 llvm_unreachable(
"builtin <=> should have class type");
11438 return IntRange::forBoolType();
11467 Combine = IntRange::bit_and;
11475 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11476 if (I->getValue() == 1) {
11477 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11478 return IntRange(R.Width,
true);
11488 case BO_ShrAssign: {
11490 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11492 return std::nullopt;
11496 if (std::optional<llvm::APSInt> shift =
11497 BO->getRHS()->getIntegerConstantExpr(
C)) {
11498 if (shift->isNonNegative()) {
11499 if (shift->uge(L->Width))
11500 L->Width = (L->NonNegative ? 0 : 1);
11502 L->Width -= shift->getZExtValue();
11516 Combine = IntRange::sum;
11520 if (BO->getLHS()->getType()->isPointerType())
11523 Combine = IntRange::difference;
11528 Combine = IntRange::product;
11537 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11539 return std::nullopt;
11542 if (std::optional<llvm::APSInt> divisor =
11543 BO->getRHS()->getIntegerConstantExpr(
C)) {
11544 unsigned log2 = divisor->logBase2();
11545 if (
log2 >= L->Width)
11546 L->Width = (L->NonNegative ? 0 : 1);
11548 L->Width = std::min(L->Width -
log2, MaxWidth);
11556 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11558 return std::nullopt;
11560 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11564 Combine = IntRange::rem;
11576 unsigned opWidth =
C.getIntWidth(
T);
11578 InConstantContext, Approximate);
11580 return std::nullopt;
11583 InConstantContext, Approximate);
11585 return std::nullopt;
11587 IntRange
C = Combine(*L, *R);
11588 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11589 C.Width = std::min(
C.Width, MaxWidth);
11593 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11594 switch (UO->getOpcode()) {
11597 return IntRange::forBoolType();
11611 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11614 return std::nullopt;
11619 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11629 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11632 return std::nullopt;
11637 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11647 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11648 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11652 return IntRange(BitField->getBitWidthValue(),
11653 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11656 return std::nullopt;
11662 bool InConstantContext,
11663 bool Approximate) {
11672 const llvm::fltSemantics &Src,
11673 const llvm::fltSemantics &Tgt) {
11674 llvm::APFloat truncated = value;
11677 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11678 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11680 return truncated.bitwiseIsEqual(value);
11689 const llvm::fltSemantics &Src,
11690 const llvm::fltSemantics &Tgt) {
11707 bool IsListInit =
false);
11722 return MacroName !=
"YES" && MacroName !=
"NO" &&
11723 MacroName !=
"true" && MacroName !=
"false";
11731 (!E->
getType()->isSignedIntegerType() ||
11746struct PromotedRange {
11748 llvm::APSInt PromotedMin;
11750 llvm::APSInt PromotedMax;
11752 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11754 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11755 else if (R.Width >= BitWidth && !
Unsigned) {
11759 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11760 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11762 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11763 .extOrTrunc(BitWidth);
11764 PromotedMin.setIsUnsigned(
Unsigned);
11766 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11767 .extOrTrunc(BitWidth);
11768 PromotedMax.setIsUnsigned(
Unsigned);
11773 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11783 InRangeFlag = 0x40,
11786 Min =
LE | InRangeFlag,
11787 InRange = InRangeFlag,
11788 Max =
GE | InRangeFlag,
11791 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11796 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11797 Value.isUnsigned() == PromotedMin.isUnsigned());
11798 if (!isContiguous()) {
11799 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11800 if (
Value.isMinValue())
return Min;
11801 if (
Value.isMaxValue())
return Max;
11802 if (
Value >= PromotedMin)
return InRange;
11803 if (
Value <= PromotedMax)
return InRange;
11807 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11808 case -1:
return Less;
11809 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11811 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11812 case -1:
return InRange;
11813 case 0:
return Max;
11818 llvm_unreachable(
"impossible compare result");
11821 static std::optional<StringRef>
11823 if (Op == BO_Cmp) {
11825 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11827 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11828 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11829 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11830 return std::nullopt;
11837 }
else if (Op == BO_NE) {
11841 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11848 if (Op == BO_GE || Op == BO_LE)
11849 std::swap(TrueFlag, FalseFlag);
11852 return StringRef(
"true");
11854 return StringRef(
"false");
11855 return std::nullopt;
11862 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11863 if (ICE->getCastKind() != CK_IntegralCast &&
11864 ICE->getCastKind() != CK_NoOp)
11866 E = ICE->getSubExpr();
11875 enum ConstantValueKind {
11880 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11881 return BL->getValue() ? ConstantValueKind::LiteralTrue
11882 : ConstantValueKind::LiteralFalse;
11883 return ConstantValueKind::Miscellaneous;
11888 const llvm::APSInt &
Value,
11889 bool RhsConstant) {
11911 if (!OtherValueRange)
11916 OtherT = AT->getValueType();
11917 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11921 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11927 bool OtherIsBooleanDespiteType =
11929 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11930 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11934 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11935 Value.isUnsigned());
11936 auto Cmp = OtherPromotedValueRange.compare(
Value);
11937 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11943 bool TautologicalTypeCompare =
false;
11945 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11946 Value.isUnsigned());
11947 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11950 TautologicalTypeCompare =
true;
11958 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11967 bool InRange = Cmp & PromotedRange::InRangeFlag;
11973 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11974 Other->getType()->isUnsignedIntegerOrEnumerationType())
11975 TautologicalTypeCompare =
true;
11980 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11981 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11985 llvm::raw_svector_ostream OS(PrettySourceValue);
11987 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11988 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11990 OS << (BL->getValue() ?
"YES" :
"NO");
11995 if (!TautologicalTypeCompare) {
11997 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
12003 if (IsObjCSignedCharBool) {
12005 S.
PDiag(diag::warn_tautological_compare_objc_bool)
12006 << OS.str() << *Result);
12013 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
12017 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
12018 : diag::warn_tautological_bool_compare)
12020 << OtherIsBooleanDespiteType << *Result
12027 ? diag::warn_unsigned_enum_always_true_comparison
12028 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
12029 : diag::warn_unsigned_always_true_comparison)
12030 : diag::warn_tautological_constant_compare;
12033 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
12066 if (
T->isIntegralType(S.
Context)) {
12067 std::optional<llvm::APSInt> RHSValue =
12069 std::optional<llvm::APSInt> LHSValue =
12073 if (RHSValue && LHSValue)
12077 if ((
bool)RHSValue ^ (
bool)LHSValue) {
12079 const bool RhsConstant = (
bool)RHSValue;
12080 Expr *Const = RhsConstant ? RHS : LHS;
12082 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
12091 if (!
T->hasUnsignedIntegerRepresentation()) {
12105 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
12107 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
12113 Expr *signedOperand, *unsignedOperand;
12116 "unsigned comparison between two signed integer expressions?");
12117 signedOperand = LHS;
12118 unsignedOperand = RHS;
12120 signedOperand = RHS;
12121 unsignedOperand = LHS;
12127 std::optional<IntRange> signedRange =
12139 if (signedRange->NonNegative)
12151 if (!unsignedRange)
12156 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12158 if (unsignedRange->Width < comparisonWidth)
12163 S.
PDiag(diag::warn_mixed_sign_comparison)
12182 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12187 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12188 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12189 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12190 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12191 << BitfieldEnumDecl;
12198 Init->isValueDependent() ||
12199 Init->isTypeDependent())
12202 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12212 const PreferredTypeAttr *PTAttr =
nullptr;
12214 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12216 ED = PTAttr->getType()->getAsEnumDecl();
12224 bool SignedEnum = ED->getNumNegativeBits() > 0;
12231 unsigned DiagID = 0;
12232 if (SignedEnum && !SignedBitfield) {
12235 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12237 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12238 }
else if (SignedBitfield && !SignedEnum &&
12239 ED->getNumPositiveBits() == FieldWidth) {
12242 ? diag::warn_signed_bitfield_enum_conversion
12243 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12246 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12251 << SignedEnum << TypeRange;
12253 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12260 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12261 ED->getNumNegativeBits())
12262 : ED->getNumPositiveBits();
12265 if (BitsNeeded > FieldWidth) {
12269 ? diag::warn_bitfield_too_small_for_enum
12270 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12271 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12275 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12283 llvm::APSInt
Value = Result.Val.getInt();
12285 unsigned OriginalWidth =
Value.getBitWidth();
12291 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12292 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12299 if (!
Value.isSigned() ||
Value.isNegative())
12300 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12301 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12302 OriginalWidth =
Value.getSignificantBits();
12304 if (OriginalWidth <= FieldWidth)
12308 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12312 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12313 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12317 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12319 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12320 ? diag::warn_impcast_single_bit_bitield_precision_constant
12321 : diag::warn_impcast_bitfield_precision_constant)
12322 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12323 <<
Init->getSourceRange();
12355 bool PruneControlFlow =
false) {
12362 if (
T.hasAddressSpace())
12364 if (PruneControlFlow) {
12378 bool PruneControlFlow =
false) {
12385 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
12390 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12391 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12396 llvm::APFloat
Value(0.0);
12402 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12407 diag::warn_impcast_float_integer, PruneWarnings);
12410 bool isExact =
false;
12413 T->hasUnsignedIntegerRepresentation());
12414 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12415 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12423 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12424 precision = (precision * 59 + 195) / 196;
12425 Value.toString(PrettySourceValue, precision);
12429 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12430 << PrettySourceValue);
12433 if (Result == llvm::APFloat::opOK && isExact) {
12434 if (IsLiteral)
return;
12435 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
12441 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12444 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12445 : diag::warn_impcast_float_to_integer_out_of_range,
12448 unsigned DiagID = 0;
12451 DiagID = diag::warn_impcast_literal_float_to_integer;
12452 }
else if (IntegerValue == 0) {
12453 if (
Value.isZero()) {
12455 diag::warn_impcast_float_integer, PruneWarnings);
12458 DiagID = diag::warn_impcast_float_to_integer_zero;
12460 if (IntegerValue.isUnsigned()) {
12461 if (!IntegerValue.isMaxValue()) {
12463 diag::warn_impcast_float_integer, PruneWarnings);
12466 if (!IntegerValue.isMaxSignedValue() &&
12467 !IntegerValue.isMinSignedValue()) {
12469 diag::warn_impcast_float_integer, PruneWarnings);
12473 DiagID = diag::warn_impcast_float_to_integer;
12478 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12480 IntegerValue.toString(PrettyTargetValue);
12482 if (PruneWarnings) {
12485 << E->
getType() <<
T.getUnqualifiedType()
12486 << PrettySourceValue << PrettyTargetValue
12490 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12499 "Must be compound assignment operation");
12510 ->getComputationResultType()
12517 if (ResultBT->isInteger())
12519 E->
getExprLoc(), diag::warn_impcast_float_integer);
12521 if (!ResultBT->isFloatingPoint())
12530 diag::warn_impcast_float_result_precision);
12535 if (!Range.Width)
return "0";
12537 llvm::APSInt ValueInRange =
Value;
12538 ValueInRange.setIsSigned(!Range.NonNegative);
12539 ValueInRange = ValueInRange.trunc(Range.Width);
12540 return toString(ValueInRange, 10);
12550 const Type *Source =
12552 if (
Target->isDependentType())
12555 const auto *FloatCandidateBT =
12556 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12557 const Type *BoolCandidateType = ToBool ?
Target : Source;
12560 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12565 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12571 S, TheCall->
getArg(I - 1),
false));
12573 S, TheCall->
getArg(I + 1),
false));
12578 diag::warn_impcast_floating_point_to_bool);
12593 if (!IsGNUNullExpr && !HasNullPtrType)
12597 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12598 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12601 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12614 if (IsGNUNullExpr && Loc.
isMacroID()) {
12617 if (MacroName ==
"NULL")
12625 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12639 const char FirstLiteralCharacter =
12641 if (FirstLiteralCharacter ==
'0')
12647 if (CC.
isValid() &&
T->isCharType()) {
12648 const char FirstContextCharacter =
12650 if (FirstContextCharacter ==
'{')
12658 const auto *IL = dyn_cast<IntegerLiteral>(E);
12660 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12661 if (UO->getOpcode() == UO_Minus)
12662 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12673 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12677 if (Opc == BO_Shl) {
12680 if (LHS && LHS->getValue() == 0)
12681 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12683 RHS->getValue().isNonNegative() &&
12685 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12686 << (Result.Val.getInt() != 0);
12688 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12695 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12700 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12701 (RHS->getValue() == 0 || RHS->getValue() == 1))
12704 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12705 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12713 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12719 if (Source->isChar16Type() &&
Target->isChar32Type())
12725 llvm::APSInt
Value(32);
12726 Value = Result.Val.getInt();
12727 bool IsASCII =
Value <= 0x7F;
12728 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12729 bool ConversionPreservesSemantics =
12730 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12732 if (!ConversionPreservesSemantics) {
12733 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12734 const llvm::APSInt &
Value) {
12735 if (
T->isChar8Type())
12736 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12737 if (
T->isChar16Type())
12738 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12739 assert(
T->isChar32Type());
12740 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12743 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12752 LosesPrecision ? diag::warn_impcast_unicode_precision
12753 : diag::warn_impcast_unicode_char_type);
12758 From =
Context.getCanonicalType(From);
12759 To =
Context.getCanonicalType(To);
12762 From = MaybePointee;
12769 if (FromFn->getCFIUncheckedCalleeAttr() &&
12770 !ToFn->getCFIUncheckedCalleeAttr())
12778 bool *ICContext,
bool IsListInit) {
12783 if (Source ==
Target)
return;
12784 if (
Target->isDependentType())
return;
12794 if (Source->isAtomicType())
12798 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12804 diag::warn_impcast_string_literal_to_bool);
12810 diag::warn_impcast_objective_c_literal_to_bool);
12812 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12822 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12825 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12827 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12836 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12838 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12843 if (
Target->isSveVLSBuiltinType() &&
12850 if (
Target->isRVVVLSBuiltinType() &&
12860 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12868 diag::warn_hlsl_impcast_vector_truncation);
12880 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
12881 Target = VecTy->getElementType().getTypePtr();
12884 if (
Target->isScalarType())
12885 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
12893 diag::warn_hlsl_impcast_matrix_truncation);
12904 ? diag::err_impcast_complex_scalar
12905 : diag::warn_impcast_complex_scalar);
12912 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12918 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12921 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12923 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12965 else if (Order < 0) {
12975 if (TargetBT && TargetBT->
isInteger()) {
13002 diag::warn_impcast_floating_point_to_bool);
13010 if (Source->isFixedPointType()) {
13011 if (
Target->isUnsaturatedFixedPointType()) {
13015 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
13016 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
13017 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
13020 PDiag(diag::warn_impcast_fixed_point_range)
13021 <<
Value.toString() <<
T
13027 }
else if (
Target->isIntegerType()) {
13031 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
13034 llvm::APSInt IntResult = FXResult.convertToInt(
13035 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
13040 PDiag(diag::warn_impcast_fixed_point_range)
13041 << FXResult.toString() <<
T
13048 }
else if (
Target->isUnsaturatedFixedPointType()) {
13049 if (Source->isIntegerType()) {
13056 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
13061 PDiag(diag::warn_impcast_fixed_point_range)
13082 unsigned int SourcePrecision =
SourceRange->Width;
13086 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
13089 if (SourcePrecision > 0 && TargetPrecision > 0 &&
13090 SourcePrecision > TargetPrecision) {
13092 if (std::optional<llvm::APSInt> SourceInt =
13097 llvm::APFloat TargetFloatValue(
13099 llvm::APFloat::opStatus ConversionStatus =
13100 TargetFloatValue.convertFromAPInt(
13102 llvm::APFloat::rmNearestTiesToEven);
13104 if (ConversionStatus != llvm::APFloat::opOK) {
13106 SourceInt->toString(PrettySourceValue, 10);
13108 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
13112 PDiag(diag::warn_impcast_integer_float_precision_constant)
13113 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13119 diag::warn_impcast_integer_float_precision);
13128 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
13133 if (
Target->isBooleanType())
13137 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13141 if (!Source->isIntegerType() || !
Target->isIntegerType())
13146 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13149 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13152 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13157 if (!LikelySourceRange)
13160 IntRange SourceTypeRange =
13161 IntRange::forTargetOfCanonicalType(
Context, Source);
13162 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13164 if (LikelySourceRange->Width > TargetRange.Width) {
13170 llvm::APSInt
Value(32);
13180 PDiag(diag::warn_impcast_integer_precision_constant)
13181 << PrettySourceValue << PrettyTargetValue
13191 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13192 if (UO->getOpcode() == UO_Minus)
13194 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
13197 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13201 diag::warn_impcast_integer_precision);
13204 if (TargetRange.Width > SourceTypeRange.Width) {
13205 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13206 if (UO->getOpcode() == UO_Minus)
13207 if (Source->isUnsignedIntegerType()) {
13208 if (
Target->isUnsignedIntegerType())
13210 diag::warn_impcast_high_order_zero_bits);
13211 if (
Target->isSignedIntegerType())
13213 diag::warn_impcast_nonnegative_result);
13217 if (TargetRange.Width == LikelySourceRange->Width &&
13218 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13219 Source->isSignedIntegerType()) {
13233 PDiag(diag::warn_impcast_integer_precision_constant)
13234 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13244 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13245 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13246 LikelySourceRange->Width == TargetRange.Width))) {
13250 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13252 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13256 unsigned DiagID = diag::warn_impcast_integer_sign;
13264 DiagID = diag::warn_impcast_integer_sign_conditional;
13281 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13283 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13284 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13285 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13286 TargetEnum->getDecl()->hasNameForLinkage() &&
13287 SourceEnum != TargetEnum) {
13292 diag::warn_impcast_different_enum_types);
13306 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13319 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13320 TrueExpr = BCO->getCommon();
13322 bool Suspicious =
false;
13326 if (
T->isBooleanType())
13331 if (!Suspicious)
return;
13334 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13341 Suspicious =
false;
13346 E->
getType(), CC, &Suspicious);
13363struct AnalyzeImplicitConversionsWorkItem {
13372 bool ExtraCheckForImplicitConversion,
13375 WorkList.push_back({E, CC,
false});
13377 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
13384 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13386 Expr *OrigE = Item.E;
13405 Expr *SourceExpr = E;
13410 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13411 if (
auto *Src = OVE->getSourceExpr())
13414 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13415 if (UO->getOpcode() == UO_Not &&
13416 UO->getSubExpr()->isKnownToHaveBooleanValue())
13417 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13421 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13422 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13423 BO->getLHS()->isKnownToHaveBooleanValue() &&
13424 BO->getRHS()->isKnownToHaveBooleanValue() &&
13425 BO->getLHS()->HasSideEffects(S.
Context) &&
13426 BO->getRHS()->HasSideEffects(S.
Context)) {
13437 if (SR.str() ==
"&" || SR.str() ==
"|") {
13439 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13440 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13443 BO->getOperatorLoc(),
13444 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13445 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13447 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13465 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13471 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13486 for (
auto *SE : POE->semantics())
13487 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13488 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13492 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13493 E = CE->getSubExpr();
13499 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13500 if (InitListE->getNumInits() == 1) {
13501 E = InitListE->getInit(0);
13508 WorkList.push_back({E, CC, IsListInit});
13512 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13513 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13517 if (OutArgE->isInOut())
13518 WorkList.push_back(
13519 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13520 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13526 if (BO->isComparisonOp())
13530 if (BO->getOpcode() == BO_Assign)
13533 if (BO->isAssignmentOp())
13549 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13551 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13555 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13556 if (ChildExpr == CSE->getOperand())
13562 if (IsLogicalAndOperator &&
13567 WorkList.push_back({ChildExpr, CC, IsListInit});
13581 if (
U->getOpcode() == UO_LNot) {
13583 }
else if (
U->getOpcode() != UO_AddrOf) {
13584 if (
U->getSubExpr()->getType()->isAtomicType())
13585 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13586 diag::warn_atomic_implicit_seq_cst);
13597 WorkList.push_back({OrigE, CC, IsListInit});
13598 while (!WorkList.empty())
13610 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13613 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13614 if (!M->getMemberDecl()->getType()->isReferenceType())
13616 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13617 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13619 FD =
Call->getDirectCallee();
13628 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13642 if (
SM.isMacroBodyExpansion(Loc))
13644 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13668 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13669 : diag::warn_this_bool_conversion;
13674 bool IsAddressOf =
false;
13676 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13677 if (UO->getOpcode() != UO_AddrOf)
13679 IsAddressOf =
true;
13680 E = UO->getSubExpr();
13684 unsigned DiagID = IsCompare
13685 ? diag::warn_address_of_reference_null_compare
13686 : diag::warn_address_of_reference_bool_conversion;
13694 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13697 llvm::raw_string_ostream S(Str);
13699 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13700 : diag::warn_cast_nonnull_to_bool;
13703 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13708 if (
auto *Callee =
Call->getDirectCallee()) {
13709 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13710 ComplainAboutNonnullParamOrCall(A);
13719 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13720 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13721 MRecordDecl && MRecordDecl->isLambda()) {
13724 << MRecordDecl->getSourceRange() << Range << IsEqual;
13734 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13735 D = M->getMemberDecl();
13743 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13746 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13747 ComplainAboutNonnullParamOrCall(A);
13751 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13755 auto ParamIter = llvm::find(FD->
parameters(), PV);
13757 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13761 ComplainAboutNonnullParamOrCall(
NonNull);
13766 if (ArgNo.getASTIndex() == ParamNo) {
13767 ComplainAboutNonnullParamOrCall(
NonNull);
13777 const bool IsArray =
T->isArrayType();
13778 const bool IsFunction =
T->isFunctionType();
13781 if (IsAddressOf && IsFunction) {
13786 if (!IsAddressOf && !IsFunction && !IsArray)
13791 llvm::raw_string_ostream S(Str);
13794 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13795 : diag::warn_impcast_pointer_to_bool;
13802 DiagType = AddressOf;
13803 else if (IsFunction)
13804 DiagType = FunctionPointer;
13806 DiagType = ArrayPointer;
13808 llvm_unreachable(
"Could not determine diagnostic.");
13810 << Range << IsEqual;
13823 if (ReturnType.
isNull())
13861 CheckArrayAccess(E);
13871void Sema::CheckForIntOverflow (
const Expr *E) {
13873 SmallVector<const Expr *, 2> Exprs(1, E);
13876 const Expr *OriginalE = Exprs.pop_back_val();
13884 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13885 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13888 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13889 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13890 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13892 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13893 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13894 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13895 Exprs.push_back(Temporary->getSubExpr());
13896 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13897 Exprs.push_back(Array->getIdx());
13898 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13899 Exprs.push_back(Compound->getInitializer());
13900 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13901 New &&
New->isArray()) {
13902 if (
auto ArraySize =
New->getArraySize())
13903 Exprs.push_back(*ArraySize);
13904 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13905 Exprs.push_back(MTE->getSubExpr());
13906 }
while (!Exprs.empty());
13914 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13921 class SequenceTree {
13923 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13924 unsigned Parent : 31;
13925 LLVM_PREFERRED_TYPE(
bool)
13926 unsigned Merged : 1;
13928 SmallVector<Value, 8> Values;
13934 friend class SequenceTree;
13938 explicit Seq(
unsigned N) : Index(N) {}
13941 Seq() : Index(0) {}
13944 SequenceTree() { Values.push_back(
Value(0)); }
13945 Seq root()
const {
return Seq(0); }
13950 Seq allocate(
Seq Parent) {
13951 Values.push_back(
Value(Parent.Index));
13952 return Seq(Values.size() - 1);
13957 Values[S.Index].Merged =
true;
13963 bool isUnsequenced(
Seq Cur,
Seq Old) {
13964 unsigned C = representative(Cur.Index);
13965 unsigned Target = representative(Old.Index);
13969 C = Values[
C].Parent;
13976 unsigned representative(
unsigned K) {
13977 if (Values[K].Merged)
13979 return Values[K].Parent = representative(Values[K].Parent);
13985 using Object =
const NamedDecl *;
13999 UK_ModAsSideEffect,
14001 UK_Count = UK_ModAsSideEffect + 1
14007 const Expr *UsageExpr =
nullptr;
14008 SequenceTree::Seq
Seq;
14014 Usage Uses[UK_Count];
14017 bool Diagnosed =
false;
14021 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
14029 UsageInfoMap UsageMap;
14032 SequenceTree::Seq Region;
14036 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
14040 SmallVectorImpl<const Expr *> &WorkList;
14047 struct SequencedSubexpression {
14048 SequencedSubexpression(SequenceChecker &
Self)
14049 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
14050 Self.ModAsSideEffect = &ModAsSideEffect;
14053 ~SequencedSubexpression() {
14054 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
14058 UsageInfo &UI =
Self.UsageMap[M.first];
14059 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
14060 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
14061 SideEffectUsage = M.second;
14063 Self.ModAsSideEffect = OldModAsSideEffect;
14066 SequenceChecker &
Self;
14067 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
14068 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
14075 class EvaluationTracker {
14077 EvaluationTracker(SequenceChecker &
Self)
14079 Self.EvalTracker =
this;
14082 ~EvaluationTracker() {
14083 Self.EvalTracker = Prev;
14085 Prev->EvalOK &= EvalOK;
14088 bool evaluate(
const Expr *E,
bool &
Result) {
14093 Self.SemaRef.isConstantEvaluatedContext());
14098 SequenceChecker &
Self;
14099 EvaluationTracker *Prev;
14100 bool EvalOK =
true;
14101 } *EvalTracker =
nullptr;
14105 Object getObject(
const Expr *E,
bool Mod)
const {
14107 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
14108 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
14109 return getObject(UO->getSubExpr(), Mod);
14110 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
14111 if (BO->getOpcode() == BO_Comma)
14112 return getObject(BO->getRHS(), Mod);
14113 if (Mod && BO->isAssignmentOp())
14114 return getObject(BO->getLHS(), Mod);
14115 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
14118 return ME->getMemberDecl();
14119 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
14128 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
14130 Usage &U = UI.Uses[UK];
14131 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14135 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14136 ModAsSideEffect->push_back(std::make_pair(O, U));
14138 U.UsageExpr = UsageExpr;
14148 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
14149 UsageKind OtherKind,
bool IsModMod) {
14153 const Usage &U = UI.Uses[OtherKind];
14154 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14157 const Expr *Mod = U.UsageExpr;
14158 const Expr *ModOrUse = UsageExpr;
14159 if (OtherKind == UK_Use)
14160 std::swap(Mod, ModOrUse);
14164 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14165 : diag::warn_unsequenced_mod_use)
14166 << O << SourceRange(ModOrUse->
getExprLoc()));
14167 UI.Diagnosed =
true;
14196 void notePreUse(Object O,
const Expr *UseExpr) {
14197 UsageInfo &UI = UsageMap[O];
14199 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14202 void notePostUse(Object O,
const Expr *UseExpr) {
14203 UsageInfo &UI = UsageMap[O];
14204 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14206 addUsage(O, UI, UseExpr, UK_Use);
14209 void notePreMod(Object O,
const Expr *ModExpr) {
14210 UsageInfo &UI = UsageMap[O];
14212 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14213 checkUsage(O, UI, ModExpr, UK_Use,
false);
14216 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
14217 UsageInfo &UI = UsageMap[O];
14218 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14220 addUsage(O, UI, ModExpr, UK);
14224 SequenceChecker(Sema &S,
const Expr *E,
14225 SmallVectorImpl<const Expr *> &WorkList)
14226 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14230 (void)this->WorkList;
14233 void VisitStmt(
const Stmt *S) {
14237 void VisitExpr(
const Expr *E) {
14239 Base::VisitStmt(E);
14242 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14243 for (
auto *Sub : CSE->
children()) {
14244 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14259 void VisitCastExpr(
const CastExpr *E) {
14271 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14272 const Expr *SequencedAfter) {
14273 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14274 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14275 SequenceTree::Seq OldRegion = Region;
14278 SequencedSubexpression SeqBefore(*
this);
14279 Region = BeforeRegion;
14280 Visit(SequencedBefore);
14283 Region = AfterRegion;
14284 Visit(SequencedAfter);
14286 Region = OldRegion;
14288 Tree.merge(BeforeRegion);
14289 Tree.merge(AfterRegion);
14292 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14297 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14304 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14305 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14306 void VisitBinPtrMem(
const BinaryOperator *BO) {
14311 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14318 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14319 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14320 void VisitBinShlShr(
const BinaryOperator *BO) {
14324 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14331 void VisitBinComma(
const BinaryOperator *BO) {
14336 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14339 void VisitBinAssign(
const BinaryOperator *BO) {
14340 SequenceTree::Seq RHSRegion;
14341 SequenceTree::Seq LHSRegion;
14343 RHSRegion = Tree.allocate(Region);
14344 LHSRegion = Tree.allocate(Region);
14346 RHSRegion = Region;
14347 LHSRegion = Region;
14349 SequenceTree::Seq OldRegion = Region;
14365 SequencedSubexpression SeqBefore(*
this);
14366 Region = RHSRegion;
14370 Region = LHSRegion;
14374 notePostUse(O, BO);
14378 Region = LHSRegion;
14382 notePostUse(O, BO);
14384 Region = RHSRegion;
14392 Region = OldRegion;
14396 : UK_ModAsSideEffect);
14398 Tree.merge(RHSRegion);
14399 Tree.merge(LHSRegion);
14403 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14404 VisitBinAssign(CAO);
14407 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14408 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14409 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14412 return VisitExpr(UO);
14420 : UK_ModAsSideEffect);
14423 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14424 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14425 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14428 return VisitExpr(UO);
14432 notePostMod(O, UO, UK_ModAsSideEffect);
14435 void VisitBinLOr(
const BinaryOperator *BO) {
14441 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14442 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14443 SequenceTree::Seq OldRegion = Region;
14445 EvaluationTracker Eval(*
this);
14447 SequencedSubexpression Sequenced(*
this);
14448 Region = LHSRegion;
14455 bool EvalResult =
false;
14456 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14457 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14458 if (ShouldVisitRHS) {
14459 Region = RHSRegion;
14463 Region = OldRegion;
14464 Tree.merge(LHSRegion);
14465 Tree.merge(RHSRegion);
14468 void VisitBinLAnd(
const BinaryOperator *BO) {
14474 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14475 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14476 SequenceTree::Seq OldRegion = Region;
14478 EvaluationTracker Eval(*
this);
14480 SequencedSubexpression Sequenced(*
this);
14481 Region = LHSRegion;
14487 bool EvalResult =
false;
14488 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14489 bool ShouldVisitRHS = !EvalOK || EvalResult;
14490 if (ShouldVisitRHS) {
14491 Region = RHSRegion;
14495 Region = OldRegion;
14496 Tree.merge(LHSRegion);
14497 Tree.merge(RHSRegion);
14500 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14505 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14521 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14522 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14523 SequenceTree::Seq OldRegion = Region;
14525 EvaluationTracker Eval(*
this);
14527 SequencedSubexpression Sequenced(*
this);
14528 Region = ConditionRegion;
14538 bool EvalResult =
false;
14539 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14540 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14541 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14542 if (ShouldVisitTrueExpr) {
14543 Region = TrueRegion;
14546 if (ShouldVisitFalseExpr) {
14547 Region = FalseRegion;
14551 Region = OldRegion;
14552 Tree.merge(ConditionRegion);
14553 Tree.merge(TrueRegion);
14554 Tree.merge(FalseRegion);
14557 void VisitCallExpr(
const CallExpr *CE) {
14569 SequencedSubexpression Sequenced(*
this);
14574 SequenceTree::Seq CalleeRegion;
14575 SequenceTree::Seq OtherRegion;
14576 if (SemaRef.getLangOpts().CPlusPlus17) {
14577 CalleeRegion = Tree.allocate(Region);
14578 OtherRegion = Tree.allocate(Region);
14580 CalleeRegion = Region;
14581 OtherRegion = Region;
14583 SequenceTree::Seq OldRegion = Region;
14586 Region = CalleeRegion;
14588 SequencedSubexpression Sequenced(*this);
14589 Visit(CE->getCallee());
14591 Visit(CE->getCallee());
14595 Region = OtherRegion;
14599 Region = OldRegion;
14601 Tree.merge(CalleeRegion);
14602 Tree.merge(OtherRegion);
14620 return VisitCallExpr(CXXOCE);
14631 case OO_MinusEqual:
14633 case OO_SlashEqual:
14634 case OO_PercentEqual:
14635 case OO_CaretEqual:
14638 case OO_LessLessEqual:
14639 case OO_GreaterGreaterEqual:
14640 SequencingKind = RHSBeforeLHS;
14644 case OO_GreaterGreater:
14650 SequencingKind = LHSBeforeRHS;
14654 SequencingKind = LHSBeforeRest;
14658 SequencingKind = NoSequencing;
14662 if (SequencingKind == NoSequencing)
14663 return VisitCallExpr(CXXOCE);
14666 SequencedSubexpression Sequenced(*
this);
14669 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14670 "Should only get there with C++17 and above!");
14671 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14672 "Should only get there with an overloaded binary operator"
14673 " or an overloaded call operator!");
14675 if (SequencingKind == LHSBeforeRest) {
14676 assert(CXXOCE->getOperator() == OO_Call &&
14677 "We should only have an overloaded call operator here!");
14686 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14687 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14688 SequenceTree::Seq OldRegion = Region;
14690 assert(CXXOCE->getNumArgs() >= 1 &&
14691 "An overloaded call operator must have at least one argument"
14692 " for the postfix-expression!");
14693 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14694 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14695 CXXOCE->getNumArgs() - 1);
14699 Region = PostfixExprRegion;
14700 SequencedSubexpression Sequenced(*this);
14701 Visit(PostfixExpr);
14705 Region = ArgsRegion;
14706 for (const Expr *Arg : Args)
14709 Region = OldRegion;
14710 Tree.merge(PostfixExprRegion);
14711 Tree.merge(ArgsRegion);
14713 assert(CXXOCE->getNumArgs() == 2 &&
14714 "Should only have two arguments here!");
14715 assert((SequencingKind == LHSBeforeRHS ||
14716 SequencingKind == RHSBeforeLHS) &&
14717 "Unexpected sequencing kind!");
14721 const Expr *E1 = CXXOCE->getArg(0);
14722 const Expr *E2 = CXXOCE->getArg(1);
14723 if (SequencingKind == RHSBeforeLHS)
14726 return VisitSequencedExpressions(E1, E2);
14733 SequencedSubexpression Sequenced(*
this);
14736 return VisitExpr(CCE);
14739 SequenceExpressionsInOrder(
14745 return VisitExpr(ILE);
14748 SequenceExpressionsInOrder(ILE->
inits());
14760 SequenceTree::Seq Parent = Region;
14761 for (
const Expr *E : ExpressionList) {
14764 Region = Tree.allocate(Parent);
14765 Elts.push_back(Region);
14771 for (
unsigned I = 0; I < Elts.size(); ++I)
14772 Tree.merge(Elts[I]);
14776SequenceChecker::UsageInfo::UsageInfo() =
default;
14780void Sema::CheckUnsequencedOperations(
const Expr *E) {
14781 SmallVector<const Expr *, 8> WorkList;
14782 WorkList.push_back(E);
14783 while (!WorkList.empty()) {
14784 const Expr *Item = WorkList.pop_back_val();
14785 SequenceChecker(*
this, Item, WorkList);
14790 bool IsConstexpr) {
14793 CheckImplicitConversions(E, CheckLoc);
14795 CheckUnsequencedOperations(E);
14797 CheckForIntOverflow(E);
14810 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14814 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14818 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14832 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14836 bool CheckParameterNames) {
14837 bool HasInvalidParm =
false;
14839 assert(Param &&
"null in a parameter list");
14848 if (!Param->isInvalidDecl() &&
14850 diag::err_typecheck_decl_incomplete_type) ||
14852 diag::err_abstract_type_in_decl,
14854 Param->setInvalidDecl();
14855 HasInvalidParm =
true;
14860 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14864 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14872 QualType PType = Param->getOriginalType();
14880 if (!Param->isInvalidDecl()) {
14881 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14882 if (!ClassDecl->isInvalidDecl() &&
14883 !ClassDecl->hasIrrelevantDestructor() &&
14884 !ClassDecl->isDependentContext() &&
14885 ClassDecl->isParamDestroyedInCallee()) {
14897 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14898 if (!Param->getType().isConstQualified())
14899 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14903 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14908 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14909 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14914 if (!Param->isInvalidDecl() &&
14915 Param->getOriginalType()->isWebAssemblyTableType()) {
14916 Param->setInvalidDecl();
14917 HasInvalidParm =
true;
14918 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14922 return HasInvalidParm;
14925std::optional<std::pair<
14934static std::pair<CharUnits, CharUnits>
14942 if (
Base->isVirtual()) {
14949 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14956 DerivedType =
Base->getType();
14959 return std::make_pair(BaseAlignment, Offset);
14963static std::optional<std::pair<CharUnits, CharUnits>>
14969 return std::nullopt;
14974 return std::nullopt;
14978 CharUnits Offset = EltSize * IdxRes->getExtValue();
14981 return std::make_pair(P->first, P->second + Offset);
14987 return std::make_pair(
14988 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14994std::optional<std::pair<
15002 case Stmt::CStyleCastExprClass:
15003 case Stmt::CXXStaticCastExprClass:
15004 case Stmt::ImplicitCastExprClass: {
15006 const Expr *From = CE->getSubExpr();
15007 switch (CE->getCastKind()) {
15012 case CK_UncheckedDerivedToBase:
15013 case CK_DerivedToBase: {
15023 case Stmt::ArraySubscriptExprClass: {
15028 case Stmt::DeclRefExprClass: {
15032 if (!VD->getType()->isReferenceType()) {
15034 if (VD->hasDependentAlignment())
15043 case Stmt::MemberExprClass: {
15045 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
15049 std::optional<std::pair<CharUnits, CharUnits>> P;
15058 return std::make_pair(P->first,
15061 case Stmt::UnaryOperatorClass: {
15071 case Stmt::BinaryOperatorClass: {
15083 return std::nullopt;
15088std::optional<std::pair<
15097 case Stmt::CStyleCastExprClass:
15098 case Stmt::CXXStaticCastExprClass:
15099 case Stmt::ImplicitCastExprClass: {
15101 const Expr *From = CE->getSubExpr();
15102 switch (CE->getCastKind()) {
15107 case CK_ArrayToPointerDecay:
15109 case CK_UncheckedDerivedToBase:
15110 case CK_DerivedToBase: {
15120 case Stmt::CXXThisExprClass: {
15125 case Stmt::UnaryOperatorClass: {
15131 case Stmt::BinaryOperatorClass: {
15140 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15141 std::swap(LHS, RHS);
15151 return std::nullopt;
15156 std::optional<std::pair<CharUnits, CharUnits>> P =
15160 return P->first.alignmentAtOffset(P->second);
15178 if (!DestPtr)
return;
15184 if (DestAlign.
isOne())
return;
15188 if (!SrcPtr)
return;
15199 if (SrcAlign >= DestAlign)
return;
15204 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15208void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15210 bool AllowOnePastEnd,
bool IndexNegated) {
15219 const Type *EffectiveType =
15223 Context.getAsConstantArrayType(BaseExpr->
getType());
15226 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15228 const Type *BaseType =
15230 bool IsUnboundedArray =
15232 Context, StrictFlexArraysLevel,
15235 (!IsUnboundedArray && BaseType->isDependentType()))
15243 if (IndexNegated) {
15244 index.setIsUnsigned(
false);
15248 if (IsUnboundedArray) {
15251 if (
index.isUnsigned() || !
index.isNegative()) {
15253 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15255 if (
index.getBitWidth() < AddrBits)
15257 std::optional<CharUnits> ElemCharUnits =
15258 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15261 if (!ElemCharUnits || ElemCharUnits->isZero())
15263 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15268 if (
index.getActiveBits() <= AddrBits) {
15270 llvm::APInt Product(
index);
15272 Product = Product.umul_ov(ElemBytes, Overflow);
15273 if (!Overflow && Product.getActiveBits() <= AddrBits)
15279 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15280 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15282 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15283 MaxElems = MaxElems.udiv(ElemBytes);
15286 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15287 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15292 PDiag(DiagID) << index << AddrBits
15293 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15294 << ElemBytes << MaxElems
15295 << MaxElems.getZExtValue()
15298 const NamedDecl *ND =
nullptr;
15300 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15302 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15304 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15305 ND = ME->getMemberDecl();
15309 PDiag(diag::note_array_declared_here) << ND);
15314 if (index.isUnsigned() || !index.isNegative()) {
15324 llvm::APInt size = ArrayTy->
getSize();
15326 if (BaseType != EffectiveType) {
15334 if (!ptrarith_typesize)
15335 ptrarith_typesize =
Context.getCharWidth();
15337 if (ptrarith_typesize != array_typesize) {
15339 uint64_t ratio = array_typesize / ptrarith_typesize;
15343 if (ptrarith_typesize * ratio == array_typesize)
15344 size *= llvm::APInt(size.getBitWidth(), ratio);
15348 if (size.getBitWidth() > index.getBitWidth())
15349 index = index.zext(size.getBitWidth());
15350 else if (size.getBitWidth() < index.getBitWidth())
15351 size = size.zext(index.getBitWidth());
15357 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15364 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15366 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15367 SourceLocation IndexLoc =
15369 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15374 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15375 : diag::warn_ptr_arith_exceeds_bounds;
15376 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15377 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15381 << index << ArrayTy->
desugar() << CastMsg
15384 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15386 DiagID = diag::warn_ptr_arith_precedes_bounds;
15387 if (index.isNegative()) index = -index;
15394 const NamedDecl *ND =
nullptr;
15396 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15398 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15400 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15401 ND = ME->getMemberDecl();
15405 PDiag(diag::note_array_declared_here) << ND);
15408void Sema::CheckArrayAccess(
const Expr *
expr) {
15409 int AllowOnePastEnd = 0;
15411 expr =
expr->IgnoreParenImpCasts();
15412 switch (
expr->getStmtClass()) {
15413 case Stmt::ArraySubscriptExprClass: {
15416 AllowOnePastEnd > 0);
15420 case Stmt::MemberExprClass: {
15424 case Stmt::ArraySectionExprClass: {
15430 nullptr, AllowOnePastEnd > 0);
15433 case Stmt::UnaryOperatorClass: {
15449 case Stmt::ConditionalOperatorClass: {
15451 if (
const Expr *lhs = cond->
getLHS())
15452 CheckArrayAccess(lhs);
15453 if (
const Expr *rhs = cond->
getRHS())
15454 CheckArrayAccess(rhs);
15457 case Stmt::CXXOperatorCallExprClass: {
15459 for (
const auto *Arg : OCE->arguments())
15460 CheckArrayAccess(Arg);
15470 Expr *RHS,
bool isProperty) {
15482 S.
Diag(Loc, diag::warn_arc_literal_assign)
15484 << (isProperty ? 0 : 1)
15492 Expr *RHS,
bool isProperty) {
15495 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15496 S.
Diag(Loc, diag::warn_arc_retained_assign)
15498 << (isProperty ? 0 : 1)
15502 RHS =
cast->getSubExpr();
15544 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15573 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15574 Diag(Loc, diag::warn_arc_retained_property_assign)
15578 RHS =
cast->getSubExpr();
15601 bool StmtLineInvalid;
15602 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15604 if (StmtLineInvalid)
15607 bool BodyLineInvalid;
15608 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15610 if (BodyLineInvalid)
15614 if (StmtLine != BodyLine)
15629 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15638 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15642 const Stmt *PossibleBody) {
15648 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15649 StmtLoc = FS->getRParenLoc();
15650 Body = FS->getBody();
15651 DiagID = diag::warn_empty_for_body;
15652 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15653 StmtLoc = WS->getRParenLoc();
15654 Body = WS->getBody();
15655 DiagID = diag::warn_empty_while_body;
15660 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15684 if (!ProbableTypo) {
15685 bool BodyColInvalid;
15686 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15688 if (BodyColInvalid)
15691 bool StmtColInvalid;
15694 if (StmtColInvalid)
15697 if (BodyCol > StmtCol)
15698 ProbableTypo =
true;
15701 if (ProbableTypo) {
15703 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15711 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15723 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15725 RHSExpr = CE->
getArg(0);
15726 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15727 CXXSCE && CXXSCE->isXValue())
15728 RHSExpr = CXXSCE->getSubExpr();
15732 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15733 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15736 if (LHSDeclRef && RHSDeclRef) {
15743 auto D =
Diag(OpLoc, diag::warn_self_move)
15759 const Expr *LHSBase = LHSExpr;
15760 const Expr *RHSBase = RHSExpr;
15761 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15762 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15763 if (!LHSME || !RHSME)
15766 while (LHSME && RHSME) {
15773 LHSME = dyn_cast<MemberExpr>(LHSBase);
15774 RHSME = dyn_cast<MemberExpr>(RHSBase);
15777 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15778 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15779 if (LHSDeclRef && RHSDeclRef) {
15786 Diag(OpLoc, diag::warn_self_move)
15793 Diag(OpLoc, diag::warn_self_move)
15817 bool AreUnionMembers =
false) {
15821 assert(((Field1Parent->isStructureOrClassType() &&
15822 Field2Parent->isStructureOrClassType()) ||
15823 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15824 "Can't evaluate layout compatibility between a struct field and a "
15826 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15827 (AreUnionMembers && Field1Parent->isUnionType())) &&
15828 "AreUnionMembers should be 'true' for union fields (only).");
15842 if (Bits1 != Bits2)
15846 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15847 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15850 if (!AreUnionMembers &&
15862 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15863 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15865 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15866 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15871 return isLayoutCompatible(C, F1, F2);
15882 for (
auto *Field1 : RD1->
fields()) {
15883 auto I = UnmatchedFields.begin();
15884 auto E = UnmatchedFields.end();
15886 for ( ; I != E; ++I) {
15888 bool Result = UnmatchedFields.erase(*I);
15898 return UnmatchedFields.empty();
15924 if (
C.hasSameType(T1, T2))
15933 if (TC1 == Type::Enum)
15935 if (TC1 == Type::Record) {
15954 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15985 const ValueDecl **VD, uint64_t *MagicValue,
15986 bool isConstantEvaluated) {
15994 case Stmt::UnaryOperatorClass: {
16003 case Stmt::DeclRefExprClass: {
16009 case Stmt::IntegerLiteralClass: {
16011 llvm::APInt MagicValueAPInt = IL->
getValue();
16012 if (MagicValueAPInt.getActiveBits() <= 64) {
16013 *MagicValue = MagicValueAPInt.getZExtValue();
16019 case Stmt::BinaryConditionalOperatorClass:
16020 case Stmt::ConditionalOperatorClass: {
16025 isConstantEvaluated)) {
16035 case Stmt::BinaryOperatorClass: {
16038 TypeExpr = BO->
getRHS();
16068 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
16071 bool isConstantEvaluated) {
16072 FoundWrongKind =
false;
16077 uint64_t MagicValue;
16079 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
16083 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
16084 if (I->getArgumentKind() != ArgumentKind) {
16085 FoundWrongKind =
true;
16088 TypeInfo.Type = I->getMatchingCType();
16089 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
16090 TypeInfo.MustBeNull = I->getMustBeNull();
16101 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
16102 if (I == MagicValues->end())
16111 bool LayoutCompatible,
16113 if (!TypeTagForDatatypeMagicValues)
16114 TypeTagForDatatypeMagicValues.reset(
16115 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
16118 (*TypeTagForDatatypeMagicValues)[Magic] =
16134 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16135 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16136 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16137 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16140void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16143 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16144 bool IsPointerAttr = Attr->getIsPointer();
16147 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16148 if (TypeTagIdxAST >= ExprArgs.size()) {
16149 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16150 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16153 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16154 bool FoundWrongKind;
16157 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16159 if (FoundWrongKind)
16161 diag::warn_type_tag_for_datatype_wrong_kind)
16167 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16168 if (ArgumentIdxAST >= ExprArgs.size()) {
16169 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16170 << 1 << Attr->getArgumentIdx().getSourceIndex();
16173 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16174 if (IsPointerAttr) {
16176 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16177 if (ICE->getType()->isVoidPointerType() &&
16178 ICE->getCastKind() == CK_BitCast)
16179 ArgumentExpr = ICE->getSubExpr();
16181 QualType ArgumentType = ArgumentExpr->
getType();
16187 if (TypeInfo.MustBeNull) {
16192 diag::warn_type_safety_null_pointer_required)
16200 QualType RequiredType = TypeInfo.Type;
16202 RequiredType =
Context.getPointerType(RequiredType);
16204 bool mismatch =
false;
16205 if (!TypeInfo.LayoutCompatible) {
16206 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16227 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16228 << ArgumentType << ArgumentKind
16229 << TypeInfo.LayoutCompatible << RequiredType
16247 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16255 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
16261 auto &MisalignedMembersForExpr =
16263 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16264 if (MA != MisalignedMembersForExpr.end() &&
16265 (
T->isDependentType() ||
T->isIntegerType() ||
16266 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
16268 T->getPointeeType()) <= MA->Alignment))))
16269 MisalignedMembersForExpr.erase(MA);
16278 const auto *ME = dyn_cast<MemberExpr>(E);
16290 bool AnyIsPacked =
false;
16292 QualType BaseType = ME->getBase()->getType();
16293 if (BaseType->isDependentType())
16297 auto *RD = BaseType->castAsRecordDecl();
16302 auto *FD = dyn_cast<FieldDecl>(MD);
16308 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16309 ReverseMemberChain.push_back(FD);
16312 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16314 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16321 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16332 if (ExpectedAlignment.
isOne())
16337 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16338 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16342 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16346 if (DRE && !TopME->
isArrow()) {
16349 CompleteObjectAlignment =
16350 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16354 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16357 CompleteObjectAlignment < ExpectedAlignment) {
16368 for (
FieldDecl *FDI : ReverseMemberChain) {
16369 if (FDI->hasAttr<PackedAttr>() ||
16370 FDI->getParent()->hasAttr<PackedAttr>()) {
16372 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16378 assert(FD &&
"We did not find a packed FieldDecl!");
16379 Action(E, FD->
getParent(), FD, Alignment);
16383void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16384 using namespace std::placeholders;
16387 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16411bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16412 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16425 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
16426 TheCall->
setType(VecTy0->getElementType());
16439 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16456 assert(!Args.empty() &&
"Should have at least one argument.");
16458 Expr *Arg0 = Args.front();
16461 auto EmitError = [&](
Expr *ArgI) {
16463 diag::err_typecheck_call_different_arg_types)
16464 << Arg0->
getType() << ArgI->getType();
16469 for (
Expr *ArgI : Args.drop_front())
16480 for (
Expr *ArgI : Args.drop_front()) {
16481 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16484 VecI->getElementType()) ||
16485 Vec0->getNumElements() != VecI->getNumElements()) {
16494std::optional<QualType>
16498 return std::nullopt;
16502 return std::nullopt;
16505 for (
int I = 0; I < 2; ++I) {
16509 return std::nullopt;
16510 Args[I] = Converted.
get();
16517 return std::nullopt;
16520 return std::nullopt;
16522 TheCall->
setArg(0, Args[0]);
16523 TheCall->
setArg(1, Args[1]);
16534 TheCall->
getArg(1), Loc) ||
16536 TheCall->
getArg(2), Loc))
16540 for (
int I = 0; I < 3; ++I) {
16545 Args[I] = Converted.
get();
16548 int ArgOrdinal = 1;
16549 for (
Expr *Arg : Args) {
16551 ArgTyRestr, ArgOrdinal++))
16558 for (
int I = 0; I < 3; ++I)
16559 TheCall->
setArg(I, Args[I]);
16565bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16577bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16586 diag::err_builtin_invalid_arg_type)
16587 << 1 << 2 << 1 << 1 << TyArg;
16601 Expr *Matrix = MatrixArg.
get();
16603 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16606 << 1 << 3 << 0 << 0
16613 QualType ResultType =
Context.getConstantMatrixType(
16614 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16617 TheCall->
setType(ResultType);
16620 TheCall->
setArg(0, Matrix);
16625static std::optional<unsigned>
16633 uint64_t
Dim =
Value->getZExtValue();
16649 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16651 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16659 unsigned PtrArgIdx = 0;
16660 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16661 Expr *RowsExpr = TheCall->
getArg(1);
16662 Expr *ColumnsExpr = TheCall->
getArg(2);
16663 Expr *StrideExpr = TheCall->
getArg(3);
16665 bool ArgError =
false;
16672 PtrExpr = PtrConv.
get();
16673 TheCall->
setArg(0, PtrExpr);
16680 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16681 QualType ElementTy;
16684 << PtrArgIdx + 1 << 0 << 5 << 0
16688 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16692 << PtrArgIdx + 1 << 0 << 5
16699 auto ApplyArgumentConversions = [
this](Expr *E) {
16708 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16710 RowsExpr = RowsConv.
get();
16711 TheCall->
setArg(1, RowsExpr);
16713 RowsExpr =
nullptr;
16715 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16717 ColumnsExpr = ColumnsConv.
get();
16718 TheCall->
setArg(2, ColumnsExpr);
16720 ColumnsExpr =
nullptr;
16731 std::optional<unsigned> MaybeRows;
16735 std::optional<unsigned> MaybeColumns;
16740 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16743 StrideExpr = StrideConv.
get();
16744 TheCall->
setArg(3, StrideExpr);
16747 if (std::optional<llvm::APSInt>
Value =
16750 if (Stride < *MaybeRows) {
16752 diag::err_builtin_matrix_stride_too_small);
16758 if (ArgError || !MaybeRows || !MaybeColumns)
16762 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16773 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16775 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16783 unsigned PtrArgIdx = 1;
16784 Expr *MatrixExpr = TheCall->
getArg(0);
16785 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16786 Expr *StrideExpr = TheCall->
getArg(2);
16788 bool ArgError =
false;
16794 MatrixExpr = MatrixConv.
get();
16795 TheCall->
setArg(0, MatrixExpr);
16802 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16805 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16813 PtrExpr = PtrConv.
get();
16814 TheCall->
setArg(1, PtrExpr);
16822 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16825 << PtrArgIdx + 1 << 0 << 5 << 0
16829 QualType ElementTy = PtrTy->getPointeeType();
16831 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16836 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16838 diag::err_builtin_matrix_pointer_arg_mismatch)
16839 << ElementTy << MatrixTy->getElementType();
16854 StrideExpr = StrideConv.
get();
16855 TheCall->
setArg(2, StrideExpr);
16860 if (std::optional<llvm::APSInt>
Value =
16863 if (Stride < MatrixTy->getNumRows()) {
16865 diag::err_builtin_matrix_stride_too_small);
16885 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16890 llvm::StringSet<> CalleeTCBs;
16891 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16892 CalleeTCBs.insert(A->getTCBName());
16893 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16894 CalleeTCBs.insert(A->getTCBName());
16898 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16899 StringRef CallerTCB = A->getTCBName();
16900 if (CalleeTCBs.count(CallerTCB) == 0) {
16901 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16902 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall)
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType, QualType T)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool BuiltinRotateGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_stdc_rotate_{left,right} was called with two arguments, that the first argument...
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bswapg was called with a single argument, which is an unsigned integer,...
static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool isValidMathElementType(QualType T)
static bool IsSameCharType(QualType T1, QualType T2)
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth)
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static 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
Sema::SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when the only matching conversion function is explicit.
Sema::SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when the expression has incomplete class type.
Sema::SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for one of the candidate conversions.
Sema::SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic when there are multiple possible conversion functions.
Sema::SemaDiagnosticBuilder diagnoseNoMatch(Sema &S, SourceLocation Loc, QualType T) override
Emits a diagnostic complaining that the expression does not have integral or enumeration type.
RotateIntegerConverter(unsigned ArgIndex, bool OnlyUnsigned)
Sema::SemaDiagnosticBuilder diagnoseConversion(Sema &S, SourceLocation Loc, QualType T, QualType ConvTy) override
Emits a diagnostic when we picked a conversion function (for cases when we are not allowed to pick a ...
Sema::SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, QualType ConvTy) override
Emits a note for the explicit conversion function.
bool match(QualType T) override
Determine whether the specified type is a valid destination type for this conversion.
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
void toString(raw_ostream &os) const
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
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++ conversion function within a class.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
bool isDynamicClass() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getEndLoc() const
SourceLocation getRParenLoc() const
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
void shrinkNumArgs(unsigned NewNumArgs)
Reduce the number of arguments in this call expression.
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
Represents a 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)
Abstract base class used to perform a contextual implicit conversion from an expression to any type p...
ContextualImplicitConverter(bool Suppress=false, bool SuppressConversion=false)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
FPOptionsOverride CurFPFeatureOverrides()
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
DiagnosticsEngine & getDiagnostics() const
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
EltwiseBuiltinArgTyRestriction
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FormatStringI...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
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.