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:
2143 EltTy = VecTy->getElementType();
2145 switch (ArgTyRestr) {
2149 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2150 << ArgOrdinal << 2 << 1 << 1
2156 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2157 << ArgOrdinal << 5 << 0
2163 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2164 << ArgOrdinal << 5 << 1
2170 return S.
Diag(Loc, diag::err_builtin_invalid_arg_type)
2184 const TargetInfo *AuxTI,
unsigned BuiltinID) {
2185 assert((BuiltinID == Builtin::BI__builtin_cpu_supports ||
2186 BuiltinID == Builtin::BI__builtin_cpu_is) &&
2187 "Expecting __builtin_cpu_...");
2189 bool IsCPUSupports = BuiltinID == Builtin::BI__builtin_cpu_supports;
2191 auto SupportsBI = [=](
const TargetInfo *TInfo) {
2192 return TInfo && ((IsCPUSupports && TInfo->supportsCpuSupports()) ||
2193 (!IsCPUSupports && TInfo->supportsCpuIs()));
2195 if (!SupportsBI(&TI) && SupportsBI(AuxTI))
2202 ? diag::err_builtin_aix_os_unsupported
2203 : diag::err_builtin_target_unsupported)
2209 return S.
Diag(TheCall->
getBeginLoc(), diag::err_expr_not_string_literal)
2247 if (
const auto *BT = dyn_cast<BitIntType>(ArgTy)) {
2248 if (BT->getNumBits() % 16 != 0 && BT->getNumBits() != 8) {
2250 << ArgTy << BT->getNumBits();
2294 TheCall->
setArg(0, Arg0);
2311 TheCall->
setArg(1, Arg1);
2317 << 2 << 1 << 4 << 0 << Arg1Ty;
2326 unsigned Pos,
bool AllowConst,
2330 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2335 if (!PtrTy->isPointerType() || PtrTy->getPointeeType()->isVectorType())
2336 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2337 << Pos <<
"scalar pointer";
2346 diag::err_typecheck_convert_incompatible)
2355 bool TypeDependent =
false;
2356 for (
unsigned Arg = 0, E = TheCall->
getNumArgs(); Arg != E; ++Arg) {
2384 Builtin::BI__builtin_masked_load))
2398 return S.
Diag(PtrArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2421 Builtin::BI__builtin_masked_store))
2429 S.
Diag(ValArg->
getExprLoc(), diag::err_vec_masked_load_store_ptr)
2439 diag::err_vec_builtin_incompatible_vector)
2468 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2481 << MaskTy << IdxTy);
2490 diag::err_vec_masked_load_store_ptr)
2519 return S.
Diag(MaskArg->
getBeginLoc(), diag::err_builtin_invalid_arg_type)
2535 << MaskTy << IdxTy);
2541 << MaskTy << ValTy);
2547 diag::err_vec_builtin_incompatible_vector)
2561 if (Args.size() == 0) {
2563 diag::err_typecheck_call_too_few_args_at_least)
2569 QualType FuncT = Args[0]->getType();
2572 if (Args.size() < 2) {
2574 diag::err_typecheck_call_too_few_args_at_least)
2580 const Type *MemPtrClass = MPT->getQualifier().getAsType();
2581 QualType ObjectT = Args[1]->getType();
2583 if (MPT->isMemberDataPointer() && S.
checkArgCount(TheCall, 2))
2632 tok::periodstar, ObjectArg.
get(), Args[0]);
2636 if (MPT->isMemberDataPointer())
2639 auto *MemCall =
new (S.
Context)
2662Sema::CheckBuiltinFunctionCall(
FunctionDecl *FDecl,
unsigned BuiltinID,
2667 unsigned ICEArguments = 0;
2669 Context.GetBuiltinType(BuiltinID,
Error, &ICEArguments);
2674 for (
unsigned ArgNo = 0; ICEArguments != 0; ++ArgNo) {
2676 if ((ICEArguments & (1 << ArgNo)) == 0)
continue;
2681 if (ArgNo < TheCall->getNumArgs() &&
2684 ICEArguments &= ~(1 << ArgNo);
2688 switch (BuiltinID) {
2689 case Builtin::BI__builtin_cpu_supports:
2690 case Builtin::BI__builtin_cpu_is:
2692 Context.getAuxTargetInfo(), BuiltinID))
2695 case Builtin::BI__builtin_cpu_init:
2696 if (!
Context.getTargetInfo().supportsCpuInit()) {
2702 case Builtin::BI__builtin___CFStringMakeConstantString:
2706 *
this, BuiltinID, TheCall,
2707 {llvm::Triple::GOFF, llvm::Triple::XCOFF}))
2710 "Wrong # arguments to builtin CFStringMakeConstantString");
2711 if (
ObjC().CheckObjCString(TheCall->
getArg(0)))
2714 case Builtin::BI__builtin_ms_va_start:
2715 case Builtin::BI__builtin_stdarg_start:
2716 case Builtin::BI__builtin_va_start:
2717 case Builtin::BI__builtin_c23_va_start:
2718 if (BuiltinVAStart(BuiltinID, TheCall))
2721 case Builtin::BI__va_start: {
2722 switch (
Context.getTargetInfo().getTriple().getArch()) {
2723 case llvm::Triple::aarch64:
2724 case llvm::Triple::arm:
2725 case llvm::Triple::thumb:
2726 if (BuiltinVAStartARMMicrosoft(TheCall))
2730 if (BuiltinVAStart(BuiltinID, TheCall))
2738 case Builtin::BI_interlockedbittestandset_acq:
2739 case Builtin::BI_interlockedbittestandset_rel:
2740 case Builtin::BI_interlockedbittestandset_nf:
2741 case Builtin::BI_interlockedbittestandreset_acq:
2742 case Builtin::BI_interlockedbittestandreset_rel:
2743 case Builtin::BI_interlockedbittestandreset_nf:
2746 {llvm::Triple::arm, llvm::Triple::thumb, llvm::Triple::aarch64}))
2751 case Builtin::BI_bittest64:
2752 case Builtin::BI_bittestandcomplement64:
2753 case Builtin::BI_bittestandreset64:
2754 case Builtin::BI_bittestandset64:
2755 case Builtin::BI_interlockedbittestandreset64:
2756 case Builtin::BI_interlockedbittestandset64:
2759 {llvm::Triple::x86_64, llvm::Triple::arm, llvm::Triple::thumb,
2760 llvm::Triple::aarch64, llvm::Triple::amdgcn}))
2765 case Builtin::BI_interlockedbittestandreset64_acq:
2766 case Builtin::BI_interlockedbittestandreset64_rel:
2767 case Builtin::BI_interlockedbittestandreset64_nf:
2768 case Builtin::BI_interlockedbittestandset64_acq:
2769 case Builtin::BI_interlockedbittestandset64_rel:
2770 case Builtin::BI_interlockedbittestandset64_nf:
2775 case Builtin::BI__builtin_set_flt_rounds:
2778 {llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::arm,
2779 llvm::Triple::thumb, llvm::Triple::aarch64, llvm::Triple::amdgcn,
2780 llvm::Triple::ppc, llvm::Triple::ppc64, llvm::Triple::ppcle,
2781 llvm::Triple::ppc64le}))
2785 case Builtin::BI__builtin_isgreater:
2786 case Builtin::BI__builtin_isgreaterequal:
2787 case Builtin::BI__builtin_isless:
2788 case Builtin::BI__builtin_islessequal:
2789 case Builtin::BI__builtin_islessgreater:
2790 case Builtin::BI__builtin_isunordered:
2791 if (BuiltinUnorderedCompare(TheCall, BuiltinID))
2794 case Builtin::BI__builtin_fpclassify:
2795 if (BuiltinFPClassification(TheCall, 6, BuiltinID))
2798 case Builtin::BI__builtin_isfpclass:
2799 if (BuiltinFPClassification(TheCall, 2, BuiltinID))
2802 case Builtin::BI__builtin_isfinite:
2803 case Builtin::BI__builtin_isinf:
2804 case Builtin::BI__builtin_isinf_sign:
2805 case Builtin::BI__builtin_isnan:
2806 case Builtin::BI__builtin_issignaling:
2807 case Builtin::BI__builtin_isnormal:
2808 case Builtin::BI__builtin_issubnormal:
2809 case Builtin::BI__builtin_iszero:
2810 case Builtin::BI__builtin_signbit:
2811 case Builtin::BI__builtin_signbitf:
2812 case Builtin::BI__builtin_signbitl:
2813 if (BuiltinFPClassification(TheCall, 1, BuiltinID))
2816 case Builtin::BI__builtin_shufflevector:
2820 case Builtin::BI__builtin_masked_load:
2821 case Builtin::BI__builtin_masked_expand_load:
2823 case Builtin::BI__builtin_masked_store:
2824 case Builtin::BI__builtin_masked_compress_store:
2826 case Builtin::BI__builtin_masked_gather:
2828 case Builtin::BI__builtin_masked_scatter:
2830 case Builtin::BI__builtin_invoke:
2832 case Builtin::BI__builtin_prefetch:
2833 if (BuiltinPrefetch(TheCall))
2836 case Builtin::BI__builtin_alloca_with_align:
2837 case Builtin::BI__builtin_alloca_with_align_uninitialized:
2838 if (BuiltinAllocaWithAlign(TheCall))
2841 case Builtin::BI__builtin_alloca:
2842 case Builtin::BI__builtin_alloca_uninitialized:
2849 case Builtin::BI__builtin_infer_alloc_token:
2853 case Builtin::BI__arithmetic_fence:
2854 if (BuiltinArithmeticFence(TheCall))
2857 case Builtin::BI__assume:
2858 case Builtin::BI__builtin_assume:
2859 if (BuiltinAssume(TheCall))
2862 case Builtin::BI__builtin_assume_aligned:
2863 if (BuiltinAssumeAligned(TheCall))
2866 case Builtin::BI__builtin_dynamic_object_size:
2867 case Builtin::BI__builtin_object_size:
2871 case Builtin::BI__builtin_longjmp:
2872 if (BuiltinLongjmp(TheCall))
2875 case Builtin::BI__builtin_setjmp:
2876 if (BuiltinSetjmp(TheCall))
2879 case Builtin::BI__builtin_classify_type:
2884 case Builtin::BI__builtin_complex:
2885 if (BuiltinComplex(TheCall))
2888 case Builtin::BI__builtin_constant_p: {
2897 case Builtin::BI__builtin_launder:
2899 case Builtin::BI__builtin_is_within_lifetime:
2901 case Builtin::BI__builtin_trivially_relocate:
2904 case Builtin::BI__sync_fetch_and_add:
2905 case Builtin::BI__sync_fetch_and_add_1:
2906 case Builtin::BI__sync_fetch_and_add_2:
2907 case Builtin::BI__sync_fetch_and_add_4:
2908 case Builtin::BI__sync_fetch_and_add_8:
2909 case Builtin::BI__sync_fetch_and_add_16:
2910 case Builtin::BI__sync_fetch_and_sub:
2911 case Builtin::BI__sync_fetch_and_sub_1:
2912 case Builtin::BI__sync_fetch_and_sub_2:
2913 case Builtin::BI__sync_fetch_and_sub_4:
2914 case Builtin::BI__sync_fetch_and_sub_8:
2915 case Builtin::BI__sync_fetch_and_sub_16:
2916 case Builtin::BI__sync_fetch_and_or:
2917 case Builtin::BI__sync_fetch_and_or_1:
2918 case Builtin::BI__sync_fetch_and_or_2:
2919 case Builtin::BI__sync_fetch_and_or_4:
2920 case Builtin::BI__sync_fetch_and_or_8:
2921 case Builtin::BI__sync_fetch_and_or_16:
2922 case Builtin::BI__sync_fetch_and_and:
2923 case Builtin::BI__sync_fetch_and_and_1:
2924 case Builtin::BI__sync_fetch_and_and_2:
2925 case Builtin::BI__sync_fetch_and_and_4:
2926 case Builtin::BI__sync_fetch_and_and_8:
2927 case Builtin::BI__sync_fetch_and_and_16:
2928 case Builtin::BI__sync_fetch_and_xor:
2929 case Builtin::BI__sync_fetch_and_xor_1:
2930 case Builtin::BI__sync_fetch_and_xor_2:
2931 case Builtin::BI__sync_fetch_and_xor_4:
2932 case Builtin::BI__sync_fetch_and_xor_8:
2933 case Builtin::BI__sync_fetch_and_xor_16:
2934 case Builtin::BI__sync_fetch_and_nand:
2935 case Builtin::BI__sync_fetch_and_nand_1:
2936 case Builtin::BI__sync_fetch_and_nand_2:
2937 case Builtin::BI__sync_fetch_and_nand_4:
2938 case Builtin::BI__sync_fetch_and_nand_8:
2939 case Builtin::BI__sync_fetch_and_nand_16:
2940 case Builtin::BI__sync_add_and_fetch:
2941 case Builtin::BI__sync_add_and_fetch_1:
2942 case Builtin::BI__sync_add_and_fetch_2:
2943 case Builtin::BI__sync_add_and_fetch_4:
2944 case Builtin::BI__sync_add_and_fetch_8:
2945 case Builtin::BI__sync_add_and_fetch_16:
2946 case Builtin::BI__sync_sub_and_fetch:
2947 case Builtin::BI__sync_sub_and_fetch_1:
2948 case Builtin::BI__sync_sub_and_fetch_2:
2949 case Builtin::BI__sync_sub_and_fetch_4:
2950 case Builtin::BI__sync_sub_and_fetch_8:
2951 case Builtin::BI__sync_sub_and_fetch_16:
2952 case Builtin::BI__sync_and_and_fetch:
2953 case Builtin::BI__sync_and_and_fetch_1:
2954 case Builtin::BI__sync_and_and_fetch_2:
2955 case Builtin::BI__sync_and_and_fetch_4:
2956 case Builtin::BI__sync_and_and_fetch_8:
2957 case Builtin::BI__sync_and_and_fetch_16:
2958 case Builtin::BI__sync_or_and_fetch:
2959 case Builtin::BI__sync_or_and_fetch_1:
2960 case Builtin::BI__sync_or_and_fetch_2:
2961 case Builtin::BI__sync_or_and_fetch_4:
2962 case Builtin::BI__sync_or_and_fetch_8:
2963 case Builtin::BI__sync_or_and_fetch_16:
2964 case Builtin::BI__sync_xor_and_fetch:
2965 case Builtin::BI__sync_xor_and_fetch_1:
2966 case Builtin::BI__sync_xor_and_fetch_2:
2967 case Builtin::BI__sync_xor_and_fetch_4:
2968 case Builtin::BI__sync_xor_and_fetch_8:
2969 case Builtin::BI__sync_xor_and_fetch_16:
2970 case Builtin::BI__sync_nand_and_fetch:
2971 case Builtin::BI__sync_nand_and_fetch_1:
2972 case Builtin::BI__sync_nand_and_fetch_2:
2973 case Builtin::BI__sync_nand_and_fetch_4:
2974 case Builtin::BI__sync_nand_and_fetch_8:
2975 case Builtin::BI__sync_nand_and_fetch_16:
2976 case Builtin::BI__sync_val_compare_and_swap:
2977 case Builtin::BI__sync_val_compare_and_swap_1:
2978 case Builtin::BI__sync_val_compare_and_swap_2:
2979 case Builtin::BI__sync_val_compare_and_swap_4:
2980 case Builtin::BI__sync_val_compare_and_swap_8:
2981 case Builtin::BI__sync_val_compare_and_swap_16:
2982 case Builtin::BI__sync_bool_compare_and_swap:
2983 case Builtin::BI__sync_bool_compare_and_swap_1:
2984 case Builtin::BI__sync_bool_compare_and_swap_2:
2985 case Builtin::BI__sync_bool_compare_and_swap_4:
2986 case Builtin::BI__sync_bool_compare_and_swap_8:
2987 case Builtin::BI__sync_bool_compare_and_swap_16:
2988 case Builtin::BI__sync_lock_test_and_set:
2989 case Builtin::BI__sync_lock_test_and_set_1:
2990 case Builtin::BI__sync_lock_test_and_set_2:
2991 case Builtin::BI__sync_lock_test_and_set_4:
2992 case Builtin::BI__sync_lock_test_and_set_8:
2993 case Builtin::BI__sync_lock_test_and_set_16:
2994 case Builtin::BI__sync_lock_release:
2995 case Builtin::BI__sync_lock_release_1:
2996 case Builtin::BI__sync_lock_release_2:
2997 case Builtin::BI__sync_lock_release_4:
2998 case Builtin::BI__sync_lock_release_8:
2999 case Builtin::BI__sync_lock_release_16:
3000 case Builtin::BI__sync_swap:
3001 case Builtin::BI__sync_swap_1:
3002 case Builtin::BI__sync_swap_2:
3003 case Builtin::BI__sync_swap_4:
3004 case Builtin::BI__sync_swap_8:
3005 case Builtin::BI__sync_swap_16:
3006 return BuiltinAtomicOverloaded(TheCallResult);
3007 case Builtin::BI__sync_synchronize:
3011 case Builtin::BI__builtin_nontemporal_load:
3012 case Builtin::BI__builtin_nontemporal_store:
3013 return BuiltinNontemporalOverloaded(TheCallResult);
3014 case Builtin::BI__builtin_memcpy_inline: {
3015 clang::Expr *SizeOp = TheCall->
getArg(2);
3027 case Builtin::BI__builtin_memset_inline: {
3028 clang::Expr *SizeOp = TheCall->
getArg(2);
3038#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
3039 case Builtin::BI##ID: \
3040 return AtomicOpsOverloaded(TheCallResult, AtomicExpr::AO##ID);
3041#include "clang/Basic/Builtins.inc"
3042 case Builtin::BI__annotation:
3046 case Builtin::BI__builtin_annotation:
3050 case Builtin::BI__builtin_addressof:
3054 case Builtin::BI__builtin_function_start:
3058 case Builtin::BI__builtin_is_aligned:
3059 case Builtin::BI__builtin_align_up:
3060 case Builtin::BI__builtin_align_down:
3064 case Builtin::BI__builtin_add_overflow:
3065 case Builtin::BI__builtin_sub_overflow:
3066 case Builtin::BI__builtin_mul_overflow:
3070 case Builtin::BI__builtin_operator_new:
3071 case Builtin::BI__builtin_operator_delete: {
3072 bool IsDelete = BuiltinID == Builtin::BI__builtin_operator_delete;
3074 BuiltinOperatorNewDeleteOverloaded(TheCallResult, IsDelete);
3077 case Builtin::BI__builtin_dump_struct:
3079 case Builtin::BI__builtin_expect_with_probability: {
3084 const Expr *ProbArg = TheCall->
getArg(2);
3085 SmallVector<PartialDiagnosticAt, 8> Notes;
3086 Expr::EvalResult Eval;
3090 Diag(ProbArg->
getBeginLoc(), diag::err_probability_not_constant_float)
3097 bool LoseInfo =
false;
3098 Probability.convert(llvm::APFloat::IEEEdouble(),
3099 llvm::RoundingMode::Dynamic, &LoseInfo);
3100 if (!(Probability >= llvm::APFloat(0.0) &&
3101 Probability <= llvm::APFloat(1.0))) {
3108 case Builtin::BI__builtin_preserve_access_index:
3112 case Builtin::BI__builtin_call_with_static_chain:
3116 case Builtin::BI__exception_code:
3117 case Builtin::BI_exception_code:
3119 diag::err_seh___except_block))
3122 case Builtin::BI__exception_info:
3123 case Builtin::BI_exception_info:
3125 diag::err_seh___except_filter))
3128 case Builtin::BI__GetExceptionInfo:
3140 case Builtin::BIaddressof:
3141 case Builtin::BI__addressof:
3142 case Builtin::BIforward:
3143 case Builtin::BIforward_like:
3144 case Builtin::BImove:
3145 case Builtin::BImove_if_noexcept:
3146 case Builtin::BIas_const: {
3154 bool ReturnsPointer = BuiltinID == Builtin::BIaddressof ||
3155 BuiltinID == Builtin::BI__addressof;
3157 (ReturnsPointer ?
Result->isAnyPointerType()
3158 :
Result->isReferenceType()) &&
3161 Diag(TheCall->
getBeginLoc(), diag::err_builtin_move_forward_unsupported)
3167 case Builtin::BI__builtin_ptrauth_strip:
3169 case Builtin::BI__builtin_ptrauth_blend_discriminator:
3171 case Builtin::BI__builtin_ptrauth_sign_constant:
3174 case Builtin::BI__builtin_ptrauth_sign_unauthenticated:
3177 case Builtin::BI__builtin_ptrauth_auth:
3180 case Builtin::BI__builtin_ptrauth_sign_generic_data:
3182 case Builtin::BI__builtin_ptrauth_auth_and_resign:
3184 case Builtin::BI__builtin_ptrauth_string_discriminator:
3187 case Builtin::BI__builtin_get_vtable_pointer:
3191 case Builtin::BIread_pipe:
3192 case Builtin::BIwrite_pipe:
3195 if (
OpenCL().checkBuiltinRWPipe(TheCall))
3198 case Builtin::BIreserve_read_pipe:
3199 case Builtin::BIreserve_write_pipe:
3200 case Builtin::BIwork_group_reserve_read_pipe:
3201 case Builtin::BIwork_group_reserve_write_pipe:
3202 if (
OpenCL().checkBuiltinReserveRWPipe(TheCall))
3205 case Builtin::BIsub_group_reserve_read_pipe:
3206 case Builtin::BIsub_group_reserve_write_pipe:
3207 if (
OpenCL().checkSubgroupExt(TheCall) ||
3208 OpenCL().checkBuiltinReserveRWPipe(TheCall))
3211 case Builtin::BIcommit_read_pipe:
3212 case Builtin::BIcommit_write_pipe:
3213 case Builtin::BIwork_group_commit_read_pipe:
3214 case Builtin::BIwork_group_commit_write_pipe:
3215 if (
OpenCL().checkBuiltinCommitRWPipe(TheCall))
3218 case Builtin::BIsub_group_commit_read_pipe:
3219 case Builtin::BIsub_group_commit_write_pipe:
3220 if (
OpenCL().checkSubgroupExt(TheCall) ||
3221 OpenCL().checkBuiltinCommitRWPipe(TheCall))
3224 case Builtin::BIget_pipe_num_packets:
3225 case Builtin::BIget_pipe_max_packets:
3226 if (
OpenCL().checkBuiltinPipePackets(TheCall))
3229 case Builtin::BIto_global:
3230 case Builtin::BIto_local:
3231 case Builtin::BIto_private:
3232 if (
OpenCL().checkBuiltinToAddr(BuiltinID, TheCall))
3236 case Builtin::BIenqueue_kernel:
3237 if (
OpenCL().checkBuiltinEnqueueKernel(TheCall))
3240 case Builtin::BIget_kernel_work_group_size:
3241 case Builtin::BIget_kernel_preferred_work_group_size_multiple:
3242 if (
OpenCL().checkBuiltinKernelWorkGroupSize(TheCall))
3245 case Builtin::BIget_kernel_max_sub_group_size_for_ndrange:
3246 case Builtin::BIget_kernel_sub_group_count_for_ndrange:
3247 if (
OpenCL().checkBuiltinNDRangeAndBlock(TheCall))
3250 case Builtin::BI__builtin_os_log_format:
3251 Cleanup.setExprNeedsCleanups(
true);
3253 case Builtin::BI__builtin_os_log_format_buffer_size:
3254 if (BuiltinOSLogFormat(TheCall))
3257 case Builtin::BI__builtin_frame_address:
3258 case Builtin::BI__builtin_return_address: {
3267 Result.Val.getInt() != 0)
3269 << ((BuiltinID == Builtin::BI__builtin_return_address)
3270 ?
"__builtin_return_address"
3271 :
"__builtin_frame_address")
3276 case Builtin::BI__builtin_nondeterministic_value: {
3277 if (BuiltinNonDeterministicValue(TheCall))
3284 case Builtin::BI__builtin_elementwise_abs:
3292 case Builtin::BI__builtin_elementwise_acos:
3293 case Builtin::BI__builtin_elementwise_asin:
3294 case Builtin::BI__builtin_elementwise_atan:
3295 case Builtin::BI__builtin_elementwise_ceil:
3296 case Builtin::BI__builtin_elementwise_cos:
3297 case Builtin::BI__builtin_elementwise_cosh:
3298 case Builtin::BI__builtin_elementwise_exp:
3299 case Builtin::BI__builtin_elementwise_exp2:
3300 case Builtin::BI__builtin_elementwise_exp10:
3301 case Builtin::BI__builtin_elementwise_floor:
3302 case Builtin::BI__builtin_elementwise_log:
3303 case Builtin::BI__builtin_elementwise_log2:
3304 case Builtin::BI__builtin_elementwise_log10:
3305 case Builtin::BI__builtin_elementwise_roundeven:
3306 case Builtin::BI__builtin_elementwise_round:
3307 case Builtin::BI__builtin_elementwise_rint:
3308 case Builtin::BI__builtin_elementwise_nearbyint:
3309 case Builtin::BI__builtin_elementwise_sin:
3310 case Builtin::BI__builtin_elementwise_sinh:
3311 case Builtin::BI__builtin_elementwise_sqrt:
3312 case Builtin::BI__builtin_elementwise_tan:
3313 case Builtin::BI__builtin_elementwise_tanh:
3314 case Builtin::BI__builtin_elementwise_trunc:
3315 case Builtin::BI__builtin_elementwise_canonicalize:
3320 case Builtin::BI__builtin_elementwise_fma:
3325 case Builtin::BI__builtin_elementwise_ldexp: {
3347 const auto *Vec0 = TyA->
getAs<VectorType>();
3348 const auto *Vec1 = TyExp->
getAs<VectorType>();
3349 unsigned Arg0Length = Vec0 ? Vec0->getNumElements() : 0;
3351 if (Arg0Length != Arg1Length) {
3353 diag::err_typecheck_vector_lengths_not_equal)
3367 case Builtin::BI__builtin_elementwise_minnum:
3368 case Builtin::BI__builtin_elementwise_maxnum:
3369 case Builtin::BI__builtin_elementwise_minimum:
3370 case Builtin::BI__builtin_elementwise_maximum:
3371 case Builtin::BI__builtin_elementwise_minimumnum:
3372 case Builtin::BI__builtin_elementwise_maximumnum:
3373 case Builtin::BI__builtin_elementwise_atan2:
3374 case Builtin::BI__builtin_elementwise_fmod:
3375 case Builtin::BI__builtin_elementwise_pow:
3376 if (BuiltinElementwiseMath(TheCall,
3382 case Builtin::BI__builtin_elementwise_add_sat:
3383 case Builtin::BI__builtin_elementwise_sub_sat:
3384 if (BuiltinElementwiseMath(TheCall,
3388 case Builtin::BI__builtin_elementwise_fshl:
3389 case Builtin::BI__builtin_elementwise_fshr:
3394 case Builtin::BI__builtin_elementwise_min:
3395 case Builtin::BI__builtin_elementwise_max:
3396 if (BuiltinElementwiseMath(TheCall))
3399 case Builtin::BI__builtin_elementwise_popcount:
3400 case Builtin::BI__builtin_elementwise_bitreverse:
3405 case Builtin::BI__builtin_elementwise_copysign: {
3414 QualType MagnitudeTy = Magnitude.
get()->
getType();
3427 diag::err_typecheck_call_different_arg_types)
3428 << MagnitudeTy << SignTy;
3436 case Builtin::BI__builtin_elementwise_clzg:
3437 case Builtin::BI__builtin_elementwise_ctzg:
3445 }
else if (BuiltinElementwiseMath(
3449 case Builtin::BI__builtin_reduce_max:
3450 case Builtin::BI__builtin_reduce_min: {
3451 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3454 const Expr *Arg = TheCall->
getArg(0);
3459 ElTy = TyA->getElementType();
3463 if (ElTy.isNull()) {
3473 case Builtin::BI__builtin_reduce_maximum:
3474 case Builtin::BI__builtin_reduce_minimum: {
3475 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3478 const Expr *Arg = TheCall->
getArg(0);
3483 ElTy = TyA->getElementType();
3487 if (ElTy.isNull() || !ElTy->isFloatingType()) {
3500 case Builtin::BI__builtin_reduce_add:
3501 case Builtin::BI__builtin_reduce_mul:
3502 case Builtin::BI__builtin_reduce_xor:
3503 case Builtin::BI__builtin_reduce_or:
3504 case Builtin::BI__builtin_reduce_and: {
3505 if (PrepareBuiltinReduceMathOneArgCall(TheCall))
3508 const Expr *Arg = TheCall->
getArg(0);
3513 ElTy = TyA->getElementType();
3517 if (ElTy.isNull() || !ElTy->isIntegerType()) {
3528 case Builtin::BI__builtin_matrix_transpose:
3529 return BuiltinMatrixTranspose(TheCall, TheCallResult);
3531 case Builtin::BI__builtin_matrix_column_major_load:
3532 return BuiltinMatrixColumnMajorLoad(TheCall, TheCallResult);
3534 case Builtin::BI__builtin_matrix_column_major_store:
3535 return BuiltinMatrixColumnMajorStore(TheCall, TheCallResult);
3537 case Builtin::BI__builtin_verbose_trap:
3542 case Builtin::BI__builtin_get_device_side_mangled_name: {
3543 auto Check = [](CallExpr *TheCall) {
3549 auto *D = DRE->getDecl();
3552 return D->hasAttr<CUDAGlobalAttr>() || D->hasAttr<CUDADeviceAttr>() ||
3553 D->hasAttr<CUDAConstantAttr>() || D->hasAttr<HIPManagedAttr>();
3555 if (!Check(TheCall)) {
3557 diag::err_hip_invalid_args_builtin_mangled_name);
3562 case Builtin::BI__builtin_bswapg:
3566 case Builtin::BI__builtin_popcountg:
3570 case Builtin::BI__builtin_clzg:
3571 case Builtin::BI__builtin_ctzg:
3576 case Builtin::BI__builtin_allow_runtime_check: {
3577 Expr *Arg = TheCall->
getArg(0);
3586 case Builtin::BI__builtin_counted_by_ref:
3587 if (BuiltinCountedByRef(TheCall))
3597 if (
Context.BuiltinInfo.isTSBuiltin(BuiltinID)) {
3598 if (
Context.BuiltinInfo.isAuxBuiltinID(BuiltinID)) {
3599 assert(
Context.getAuxTargetInfo() &&
3600 "Aux Target Builtin, but not an aux target?");
3602 if (CheckTSBuiltinFunctionCall(
3604 Context.BuiltinInfo.getAuxBuiltinID(BuiltinID), TheCall))
3607 if (CheckTSBuiltinFunctionCall(
Context.getTargetInfo(), BuiltinID,
3613 return TheCallResult;
3628 if (
Result.isShiftedMask() || (~
Result).isShiftedMask())
3632 diag::err_argument_not_contiguous_bit_field)
3639 bool IsVariadic =
false;
3642 else if (
const auto *BD = dyn_cast<BlockDecl>(D))
3643 IsVariadic = BD->isVariadic();
3644 else if (
const auto *OMD = dyn_cast<ObjCMethodDecl>(D))
3645 IsVariadic = OMD->isVariadic();
3652 bool HasImplicitThisParam,
bool IsVariadic,
3656 else if (IsVariadic)
3666 if (HasImplicitThisParam) {
3698 UT->getDecl()->getMostRecentDecl()->hasAttr<TransparentUnionAttr>()) {
3699 if (
const auto *CLE = dyn_cast<CompoundLiteralExpr>(
Expr))
3700 if (
const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
3701 Expr = ILE->getInit(0);
3711 const Expr *ArgExpr,
3715 S.
PDiag(diag::warn_null_arg)
3721 if (
auto nullability =
type->getNullability())
3732 assert((FDecl || Proto) &&
"Need a function declaration or prototype");
3738 llvm::SmallBitVector NonNullArgs;
3744 for (
const auto *Arg : Args)
3751 unsigned IdxAST = Idx.getASTIndex();
3752 if (IdxAST >= Args.size())
3754 if (NonNullArgs.empty())
3755 NonNullArgs.resize(Args.size());
3756 NonNullArgs.set(IdxAST);
3765 if (
const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
3770 unsigned ParamIndex = 0;
3772 I != E; ++I, ++ParamIndex) {
3775 if (NonNullArgs.empty())
3776 NonNullArgs.resize(Args.size());
3778 NonNullArgs.set(ParamIndex);
3785 if (
const ValueDecl *VD = dyn_cast<ValueDecl>(FDecl)) {
3790 type = blockType->getPointeeType();
3804 if (NonNullArgs.empty())
3805 NonNullArgs.resize(Args.size());
3807 NonNullArgs.set(Index);
3816 for (
unsigned ArgIndex = 0, ArgIndexEnd = NonNullArgs.size();
3817 ArgIndex != ArgIndexEnd; ++ArgIndex) {
3818 if (NonNullArgs[ArgIndex])
3824 StringRef ParamName,
QualType ArgTy,
3847 CharUnits ParamAlign =
Context.getTypeAlignInChars(ParamTy);
3848 CharUnits ArgAlign =
Context.getTypeAlignInChars(ArgTy);
3852 if (ArgAlign < ParamAlign)
3853 Diag(Loc, diag::warn_param_mismatched_alignment)
3855 << ParamName << (FDecl !=
nullptr) << FDecl;
3859 const Expr *ThisArg,
3861 if (!FD || Args.empty())
3863 auto GetArgAt = [&](
int Idx) ->
const Expr * {
3864 if (Idx == LifetimeCaptureByAttr::Global ||
3865 Idx == LifetimeCaptureByAttr::Unknown)
3867 if (IsMemberFunction && Idx == 0)
3869 return Args[Idx - IsMemberFunction];
3871 auto HandleCaptureByAttr = [&](
const LifetimeCaptureByAttr *
Attr,
3876 Expr *Captured =
const_cast<Expr *
>(GetArgAt(ArgIdx));
3877 for (
int CapturingParamIdx :
Attr->params()) {
3880 if (CapturingParamIdx == LifetimeCaptureByAttr::This &&
3883 Expr *Capturing =
const_cast<Expr *
>(GetArgAt(CapturingParamIdx));
3891 I + IsMemberFunction);
3893 if (IsMemberFunction) {
3901 HandleCaptureByAttr(ATL.
getAttrAs<LifetimeCaptureByAttr>(), 0);
3914 llvm::SmallBitVector CheckedVarArgs;
3916 for (
const auto *I : FDecl->
specific_attrs<FormatMatchesAttr>()) {
3918 CheckedVarArgs.resize(Args.size());
3919 CheckFormatString(I, Args, IsMemberFunction, CallType, Loc, Range,
3924 CheckedVarArgs.resize(Args.size());
3925 CheckFormatArguments(I, Args, IsMemberFunction, CallType, Loc, Range,
3932 auto *FD = dyn_cast_or_null<FunctionDecl>(FDecl);
3936 : isa_and_nonnull<FunctionDecl>(FDecl)
3938 : isa_and_nonnull<ObjCMethodDecl>(FDecl)
3942 for (
unsigned ArgIdx = NumParams; ArgIdx < Args.size(); ++ArgIdx) {
3944 if (
const Expr *Arg = Args[ArgIdx]) {
3945 if (CheckedVarArgs.empty() || !CheckedVarArgs[ArgIdx])
3952 if (FDecl || Proto) {
3957 for (
const auto *I : FDecl->
specific_attrs<ArgumentWithTypeTagAttr>())
3958 CheckArgumentWithTypeTag(I, Args, Loc);
3964 if (!Proto && FDecl) {
3966 if (isa_and_nonnull<FunctionProtoType>(FT))
3972 const auto N = std::min<unsigned>(Proto->
getNumParams(), Args.size());
3974 bool IsScalableArg =
false;
3975 for (
unsigned ArgIdx = 0; ArgIdx < N; ++ArgIdx) {
3977 if (
const Expr *Arg = Args[ArgIdx]) {
3981 if (
Context.getTargetInfo().getTriple().isOSAIX() && FDecl && Arg &&
3989 IsScalableArg =
true;
3991 CheckArgAlignment(Arg->
getExprLoc(), FDecl, std::to_string(ArgIdx + 1),
4000 if (
auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext)) {
4001 llvm::StringMap<bool> CallerFeatureMap;
4002 Context.getFunctionFeatureMap(CallerFeatureMap, CallerFD);
4003 if (!CallerFeatureMap.contains(
"sme"))
4004 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4005 }
else if (!
Context.getTargetInfo().hasFeature(
"sme")) {
4006 Diag(Loc, diag::err_sme_call_in_non_sme_target);
4015 const auto *CallerFD = dyn_cast<FunctionDecl>(
CurContext);
4017 (IsScalableArg || IsScalableRet)) {
4018 bool IsCalleeStreaming =
4020 bool IsCalleeStreamingCompatible =
4024 if (!IsCalleeStreamingCompatible &&
4028 unsigned VL = LO.VScaleMin * 128;
4029 unsigned SVL = LO.VScaleStreamingMin * 128;
4030 bool IsVLMismatch = VL && SVL && VL != SVL;
4032 auto EmitDiag = [&](
bool IsArg) {
4036 Diag(Loc, diag::warn_sme_streaming_compatible_vl_mismatch)
4037 << IsArg << IsCalleeStreaming << SVL << VL;
4040 Diag(Loc, diag::err_sme_streaming_transition_vl_mismatch)
4041 << IsArg << SVL << VL;
4043 Diag(Loc, diag::warn_sme_streaming_pass_return_vl_to_non_streaming)
4060 bool CallerHasZAState =
false;
4061 bool CallerHasZT0State =
false;
4063 auto *
Attr = CallerFD->getAttr<ArmNewAttr>();
4065 CallerHasZAState =
true;
4067 CallerHasZT0State =
true;
4071 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4073 CallerHasZT0State |=
4075 FPT->getExtProtoInfo().AArch64SMEAttributes) !=
4081 Diag(Loc, diag::err_sme_za_call_no_za_state);
4084 Diag(Loc, diag::err_sme_zt0_call_no_zt0_state);
4088 Diag(Loc, diag::err_sme_unimplemented_za_save_restore);
4089 Diag(Loc, diag::note_sme_use_preserves_za);
4094 if (FDecl && FDecl->
hasAttr<AllocAlignAttr>()) {
4095 auto *AA = FDecl->
getAttr<AllocAlignAttr>();
4096 const Expr *Arg = Args[AA->getParamIndex().getASTIndex()];
4097 if (!Arg->isValueDependent()) {
4099 if (Arg->EvaluateAsInt(Align,
Context)) {
4100 const llvm::APSInt &I = Align.
Val.
getInt();
4101 if (!I.isPowerOf2())
4102 Diag(Arg->getExprLoc(), diag::warn_alignment_not_power_of_two)
4103 << Arg->getSourceRange();
4106 Diag(Arg->getExprLoc(), diag::warn_assume_aligned_too_great)
4132 Loc, FDecl,
"'this'", Context.getPointerType(ThisType),
4133 Context.getPointerType(Ctor->getFunctionObjectParameterType()));
4135 checkCall(FDecl, Proto,
nullptr, Args,
true,
4144 IsMemberOperatorCall;
4150 Expr *ImplicitThis =
nullptr;
4155 ImplicitThis = Args[0];
4158 }
else if (IsMemberFunction && !FDecl->
isStatic() &&
4169 ThisType =
Context.getPointerType(ThisType);
4175 CheckArgAlignment(TheCall->
getRParenLoc(), FDecl,
"'this'", ThisType,
4193 CheckAbsoluteValueFunction(TheCall, FDecl);
4194 CheckMaxUnsignedZero(TheCall, FDecl);
4195 CheckInfNaNFunction(TheCall, FDecl);
4206 case Builtin::BIstrlcpy:
4207 case Builtin::BIstrlcat:
4208 CheckStrlcpycatArguments(TheCall, FnInfo);
4210 case Builtin::BIstrncat:
4211 CheckStrncatArguments(TheCall, FnInfo);
4213 case Builtin::BIfree:
4214 CheckFreeArguments(TheCall);
4217 CheckMemaccessArguments(TheCall, CMId, FnInfo);
4226 if (
const auto *
V = dyn_cast<VarDecl>(NDecl))
4227 Ty =
V->getType().getNonReferenceType();
4228 else if (
const auto *F = dyn_cast<FieldDecl>(NDecl))
4229 Ty = F->getType().getNonReferenceType();
4266 if (!llvm::isValidAtomicOrderingCABI(Ordering))
4269 auto OrderingCABI = (llvm::AtomicOrderingCABI)Ordering;
4271 case AtomicExpr::AO__c11_atomic_init:
4272 case AtomicExpr::AO__opencl_atomic_init:
4273 llvm_unreachable(
"There is no ordering argument for an init");
4275 case AtomicExpr::AO__c11_atomic_load:
4276 case AtomicExpr::AO__opencl_atomic_load:
4277 case AtomicExpr::AO__hip_atomic_load:
4278 case AtomicExpr::AO__atomic_load_n:
4279 case AtomicExpr::AO__atomic_load:
4280 case AtomicExpr::AO__scoped_atomic_load_n:
4281 case AtomicExpr::AO__scoped_atomic_load:
4282 return OrderingCABI != llvm::AtomicOrderingCABI::release &&
4283 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4285 case AtomicExpr::AO__c11_atomic_store:
4286 case AtomicExpr::AO__opencl_atomic_store:
4287 case AtomicExpr::AO__hip_atomic_store:
4288 case AtomicExpr::AO__atomic_store:
4289 case AtomicExpr::AO__atomic_store_n:
4290 case AtomicExpr::AO__scoped_atomic_store:
4291 case AtomicExpr::AO__scoped_atomic_store_n:
4292 case AtomicExpr::AO__atomic_clear:
4293 return OrderingCABI != llvm::AtomicOrderingCABI::consume &&
4294 OrderingCABI != llvm::AtomicOrderingCABI::acquire &&
4295 OrderingCABI != llvm::AtomicOrderingCABI::acq_rel;
4354 const unsigned NumForm = ClearByte + 1;
4355 const unsigned NumArgs[] = {2, 2, 3, 3, 3, 3, 4, 5, 6, 2, 2};
4356 const unsigned NumVals[] = {1, 0, 1, 1, 1, 1, 2, 2, 3, 0, 0};
4364 static_assert(
sizeof(NumArgs)/
sizeof(NumArgs[0]) == NumForm
4365 &&
sizeof(NumVals)/
sizeof(NumVals[0]) == NumForm,
4366 "need to update code for modified forms");
4367 static_assert(AtomicExpr::AO__atomic_add_fetch == 0 &&
4368 AtomicExpr::AO__atomic_xor_fetch + 1 ==
4369 AtomicExpr::AO__c11_atomic_compare_exchange_strong,
4370 "need to update code for modified C11 atomics");
4371 bool IsOpenCL = Op >= AtomicExpr::AO__opencl_atomic_compare_exchange_strong &&
4372 Op <= AtomicExpr::AO__opencl_atomic_store;
4373 bool IsHIP = Op >= AtomicExpr::AO__hip_atomic_compare_exchange_strong &&
4374 Op <= AtomicExpr::AO__hip_atomic_store;
4375 bool IsScoped = Op >= AtomicExpr::AO__scoped_atomic_add_fetch &&
4376 Op <= AtomicExpr::AO__scoped_atomic_xor_fetch;
4377 bool IsC11 = (Op >= AtomicExpr::AO__c11_atomic_compare_exchange_strong &&
4378 Op <= AtomicExpr::AO__c11_atomic_store) ||
4380 bool IsN = Op == AtomicExpr::AO__atomic_load_n ||
4381 Op == AtomicExpr::AO__atomic_store_n ||
4382 Op == AtomicExpr::AO__atomic_exchange_n ||
4383 Op == AtomicExpr::AO__atomic_compare_exchange_n ||
4384 Op == AtomicExpr::AO__scoped_atomic_load_n ||
4385 Op == AtomicExpr::AO__scoped_atomic_store_n ||
4386 Op == AtomicExpr::AO__scoped_atomic_exchange_n ||
4387 Op == AtomicExpr::AO__scoped_atomic_compare_exchange_n;
4391 enum ArithOpExtraValueType {
4396 unsigned ArithAllows = AOEVT_None;
4399 case AtomicExpr::AO__c11_atomic_init:
4400 case AtomicExpr::AO__opencl_atomic_init:
4404 case AtomicExpr::AO__c11_atomic_load:
4405 case AtomicExpr::AO__opencl_atomic_load:
4406 case AtomicExpr::AO__hip_atomic_load:
4407 case AtomicExpr::AO__atomic_load_n:
4408 case AtomicExpr::AO__scoped_atomic_load_n:
4412 case AtomicExpr::AO__atomic_load:
4413 case AtomicExpr::AO__scoped_atomic_load:
4417 case AtomicExpr::AO__c11_atomic_store:
4418 case AtomicExpr::AO__opencl_atomic_store:
4419 case AtomicExpr::AO__hip_atomic_store:
4420 case AtomicExpr::AO__atomic_store:
4421 case AtomicExpr::AO__atomic_store_n:
4422 case AtomicExpr::AO__scoped_atomic_store:
4423 case AtomicExpr::AO__scoped_atomic_store_n:
4426 case AtomicExpr::AO__atomic_fetch_add:
4427 case AtomicExpr::AO__atomic_fetch_sub:
4428 case AtomicExpr::AO__atomic_add_fetch:
4429 case AtomicExpr::AO__atomic_sub_fetch:
4430 case AtomicExpr::AO__scoped_atomic_fetch_add:
4431 case AtomicExpr::AO__scoped_atomic_fetch_sub:
4432 case AtomicExpr::AO__scoped_atomic_add_fetch:
4433 case AtomicExpr::AO__scoped_atomic_sub_fetch:
4434 case AtomicExpr::AO__c11_atomic_fetch_add:
4435 case AtomicExpr::AO__c11_atomic_fetch_sub:
4436 case AtomicExpr::AO__opencl_atomic_fetch_add:
4437 case AtomicExpr::AO__opencl_atomic_fetch_sub:
4438 case AtomicExpr::AO__hip_atomic_fetch_add:
4439 case AtomicExpr::AO__hip_atomic_fetch_sub:
4440 ArithAllows = AOEVT_Pointer | AOEVT_FP;
4443 case AtomicExpr::AO__atomic_fetch_max:
4444 case AtomicExpr::AO__atomic_fetch_min:
4445 case AtomicExpr::AO__atomic_max_fetch:
4446 case AtomicExpr::AO__atomic_min_fetch:
4447 case AtomicExpr::AO__scoped_atomic_fetch_max:
4448 case AtomicExpr::AO__scoped_atomic_fetch_min:
4449 case AtomicExpr::AO__scoped_atomic_max_fetch:
4450 case AtomicExpr::AO__scoped_atomic_min_fetch:
4451 case AtomicExpr::AO__c11_atomic_fetch_max:
4452 case AtomicExpr::AO__c11_atomic_fetch_min:
4453 case AtomicExpr::AO__opencl_atomic_fetch_max:
4454 case AtomicExpr::AO__opencl_atomic_fetch_min:
4455 case AtomicExpr::AO__hip_atomic_fetch_max:
4456 case AtomicExpr::AO__hip_atomic_fetch_min:
4457 ArithAllows = AOEVT_FP;
4460 case AtomicExpr::AO__c11_atomic_fetch_and:
4461 case AtomicExpr::AO__c11_atomic_fetch_or:
4462 case AtomicExpr::AO__c11_atomic_fetch_xor:
4463 case AtomicExpr::AO__hip_atomic_fetch_and:
4464 case AtomicExpr::AO__hip_atomic_fetch_or:
4465 case AtomicExpr::AO__hip_atomic_fetch_xor:
4466 case AtomicExpr::AO__c11_atomic_fetch_nand:
4467 case AtomicExpr::AO__opencl_atomic_fetch_and:
4468 case AtomicExpr::AO__opencl_atomic_fetch_or:
4469 case AtomicExpr::AO__opencl_atomic_fetch_xor:
4470 case AtomicExpr::AO__atomic_fetch_and:
4471 case AtomicExpr::AO__atomic_fetch_or:
4472 case AtomicExpr::AO__atomic_fetch_xor:
4473 case AtomicExpr::AO__atomic_fetch_nand:
4474 case AtomicExpr::AO__atomic_and_fetch:
4475 case AtomicExpr::AO__atomic_or_fetch:
4476 case AtomicExpr::AO__atomic_xor_fetch:
4477 case AtomicExpr::AO__atomic_nand_fetch:
4478 case AtomicExpr::AO__scoped_atomic_fetch_and:
4479 case AtomicExpr::AO__scoped_atomic_fetch_or:
4480 case AtomicExpr::AO__scoped_atomic_fetch_xor:
4481 case AtomicExpr::AO__scoped_atomic_fetch_nand:
4482 case AtomicExpr::AO__scoped_atomic_and_fetch:
4483 case AtomicExpr::AO__scoped_atomic_or_fetch:
4484 case AtomicExpr::AO__scoped_atomic_xor_fetch:
4485 case AtomicExpr::AO__scoped_atomic_nand_fetch:
4486 case AtomicExpr::AO__scoped_atomic_uinc_wrap:
4487 case AtomicExpr::AO__scoped_atomic_udec_wrap:
4491 case AtomicExpr::AO__c11_atomic_exchange:
4492 case AtomicExpr::AO__hip_atomic_exchange:
4493 case AtomicExpr::AO__opencl_atomic_exchange:
4494 case AtomicExpr::AO__atomic_exchange_n:
4495 case AtomicExpr::AO__scoped_atomic_exchange_n:
4499 case AtomicExpr::AO__atomic_exchange:
4500 case AtomicExpr::AO__scoped_atomic_exchange:
4504 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
4505 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
4506 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
4507 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
4508 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
4509 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
4513 case AtomicExpr::AO__atomic_compare_exchange:
4514 case AtomicExpr::AO__atomic_compare_exchange_n:
4515 case AtomicExpr::AO__scoped_atomic_compare_exchange:
4516 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
4520 case AtomicExpr::AO__atomic_test_and_set:
4521 Form = TestAndSetByte;
4524 case AtomicExpr::AO__atomic_clear:
4529 unsigned AdjustedNumArgs = NumArgs[Form];
4530 if ((IsOpenCL || IsHIP || IsScoped) &&
4531 Op != AtomicExpr::AO__opencl_atomic_init)
4534 if (Args.size() < AdjustedNumArgs) {
4535 Diag(CallRange.
getEnd(), diag::err_typecheck_call_too_few_args)
4536 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4539 }
else if (Args.size() > AdjustedNumArgs) {
4540 Diag(Args[AdjustedNumArgs]->getBeginLoc(),
4541 diag::err_typecheck_call_too_many_args)
4542 << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size())
4548 Expr *Ptr = Args[0];
4553 Ptr = ConvertedPtr.
get();
4556 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4566 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic)
4572 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_atomic)
4578 }
else if (Form != Load && Form != LoadCopy) {
4580 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_non_const_pointer)
4586 if (Form != TestAndSetByte && Form != ClearByte) {
4589 diag::err_incomplete_type))
4592 if (
Context.getTypeInfoInChars(AtomTy).Width.isZero()) {
4593 Diag(ExprRange.
getBegin(), diag::err_atomic_builtin_must_be_pointer)
4603 pointerType->getPointeeType().getCVRQualifiers());
4613 diag::err_atomic_op_needs_non_address_discriminated_pointer)
4622 auto IsAllowedValueType = [&](
QualType ValType,
4623 unsigned AllowedType) ->
bool {
4627 return AllowedType & AOEVT_Pointer;
4632 &
Context.getTargetInfo().getLongDoubleFormat() ==
4633 &llvm::APFloat::x87DoubleExtended())
4637 if (!IsAllowedValueType(ValType, ArithAllows)) {
4638 auto DID = ArithAllows & AOEVT_FP
4639 ? (ArithAllows & AOEVT_Pointer
4640 ? diag::err_atomic_op_needs_atomic_int_ptr_or_fp
4641 : diag::err_atomic_op_needs_atomic_int_or_fp)
4642 : diag::err_atomic_op_needs_atomic_int;
4649 diag::err_incomplete_type)) {
4655 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_atomic_int_or_ptr)
4666 Diag(ExprRange.
getBegin(), diag::err_atomic_op_needs_trivial_copy)
4682 Diag(ExprRange.
getBegin(), diag::err_arc_atomic_ownership)
4694 if (Form ==
Copy || Form == LoadCopy || Form == GNUXchg || Form ==
Init ||
4697 else if (Form == C11CmpXchg || Form == GNUCmpXchg || Form == TestAndSetByte)
4703 bool IsPassedByAddress =
false;
4704 if (!IsC11 && !IsHIP && !IsN) {
4706 IsPassedByAddress =
true;
4711 APIOrderedArgs.push_back(Args[0]);
4715 APIOrderedArgs.push_back(Args[1]);
4721 APIOrderedArgs.push_back(Args[2]);
4722 APIOrderedArgs.push_back(Args[1]);
4725 APIOrderedArgs.push_back(Args[2]);
4726 APIOrderedArgs.push_back(Args[3]);
4727 APIOrderedArgs.push_back(Args[1]);
4730 APIOrderedArgs.push_back(Args[2]);
4731 APIOrderedArgs.push_back(Args[4]);
4732 APIOrderedArgs.push_back(Args[1]);
4733 APIOrderedArgs.push_back(Args[3]);
4736 APIOrderedArgs.push_back(Args[2]);
4737 APIOrderedArgs.push_back(Args[4]);
4738 APIOrderedArgs.push_back(Args[5]);
4739 APIOrderedArgs.push_back(Args[1]);
4740 APIOrderedArgs.push_back(Args[3]);
4742 case TestAndSetByte:
4744 APIOrderedArgs.push_back(Args[1]);
4748 APIOrderedArgs.append(Args.begin(), Args.end());
4755 for (
unsigned i = 0; i != APIOrderedArgs.size(); ++i) {
4757 if (i < NumVals[Form] + 1) {
4770 assert(Form != Load);
4772 Ty =
Context.getPointerDiffType();
4775 else if (Form ==
Copy || Form == Xchg) {
4776 if (IsPassedByAddress) {
4783 Expr *ValArg = APIOrderedArgs[i];
4790 AS = PtrTy->getPointeeType().getAddressSpace();
4799 if (IsPassedByAddress)
4819 APIOrderedArgs[i] = Arg.
get();
4824 SubExprs.push_back(Ptr);
4828 SubExprs.push_back(APIOrderedArgs[1]);
4831 case TestAndSetByte:
4833 SubExprs.push_back(APIOrderedArgs[1]);
4839 SubExprs.push_back(APIOrderedArgs[2]);
4840 SubExprs.push_back(APIOrderedArgs[1]);
4844 SubExprs.push_back(APIOrderedArgs[3]);
4845 SubExprs.push_back(APIOrderedArgs[1]);
4846 SubExprs.push_back(APIOrderedArgs[2]);
4849 SubExprs.push_back(APIOrderedArgs[3]);
4850 SubExprs.push_back(APIOrderedArgs[1]);
4851 SubExprs.push_back(APIOrderedArgs[4]);
4852 SubExprs.push_back(APIOrderedArgs[2]);
4855 SubExprs.push_back(APIOrderedArgs[4]);
4856 SubExprs.push_back(APIOrderedArgs[1]);
4857 SubExprs.push_back(APIOrderedArgs[5]);
4858 SubExprs.push_back(APIOrderedArgs[2]);
4859 SubExprs.push_back(APIOrderedArgs[3]);
4864 if (SubExprs.size() >= 2 && Form !=
Init) {
4865 std::optional<llvm::APSInt>
Success =
4866 SubExprs[1]->getIntegerConstantExpr(
Context);
4868 Diag(SubExprs[1]->getBeginLoc(),
4869 diag::warn_atomic_op_has_invalid_memory_order)
4870 << (Form == C11CmpXchg || Form == GNUCmpXchg)
4871 << SubExprs[1]->getSourceRange();
4873 if (SubExprs.size() >= 5) {
4874 if (std::optional<llvm::APSInt> Failure =
4875 SubExprs[3]->getIntegerConstantExpr(
Context)) {
4876 if (!llvm::is_contained(
4877 {llvm::AtomicOrderingCABI::relaxed,
4878 llvm::AtomicOrderingCABI::consume,
4879 llvm::AtomicOrderingCABI::acquire,
4880 llvm::AtomicOrderingCABI::seq_cst},
4881 (llvm::AtomicOrderingCABI)Failure->getSExtValue())) {
4882 Diag(SubExprs[3]->getBeginLoc(),
4883 diag::warn_atomic_op_has_invalid_memory_order)
4884 << 2 << SubExprs[3]->getSourceRange();
4891 auto *
Scope = Args[Args.size() - 1];
4892 if (std::optional<llvm::APSInt>
Result =
4894 if (!ScopeModel->isValid(
Result->getZExtValue()))
4895 Diag(
Scope->getBeginLoc(), diag::err_atomic_op_has_invalid_sync_scope)
4896 <<
Scope->getSourceRange();
4898 SubExprs.push_back(
Scope);
4904 if ((Op == AtomicExpr::AO__c11_atomic_load ||
4905 Op == AtomicExpr::AO__c11_atomic_store ||
4906 Op == AtomicExpr::AO__opencl_atomic_load ||
4907 Op == AtomicExpr::AO__hip_atomic_load ||
4908 Op == AtomicExpr::AO__opencl_atomic_store ||
4909 Op == AtomicExpr::AO__hip_atomic_store) &&
4910 Context.AtomicUsesUnsupportedLibcall(AE))
4912 << ((Op == AtomicExpr::AO__c11_atomic_load ||
4913 Op == AtomicExpr::AO__opencl_atomic_load ||
4914 Op == AtomicExpr::AO__hip_atomic_load)
4919 Diag(Ptr->
getExprLoc(), diag::err_atomic_builtin_bit_int_prohibit);
4935 assert(Fn &&
"builtin call without direct callee!");
4951 CallExpr *TheCall =
static_cast<CallExpr *
>(TheCallResult.
get());
4958 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
4960 <<
Callee->getSourceRange();
4969 Expr *FirstArg = TheCall->
getArg(0);
4973 FirstArg = FirstArgResult.
get();
4974 TheCall->
setArg(0, FirstArg);
4986 Diag(DRE->
getBeginLoc(), diag::err_atomic_builtin_must_be_pointer_intptr)
4993 diag::err_atomic_op_needs_non_address_discriminated_pointer)
5023 QualType ResultType = ValType;
5028#define BUILTIN_ROW(x) \
5029 { Builtin::BI##x##_1, Builtin::BI##x##_2, Builtin::BI##x##_4, \
5030 Builtin::BI##x##_8, Builtin::BI##x##_16 }
5032 static const unsigned BuiltinIndices[][5] = {
5057 switch (
Context.getTypeSizeInChars(ValType).getQuantity()) {
5058 case 1: SizeIndex = 0;
break;
5059 case 2: SizeIndex = 1;
break;
5060 case 4: SizeIndex = 2;
break;
5061 case 8: SizeIndex = 3;
break;
5062 case 16: SizeIndex = 4;
break;
5074 unsigned BuiltinIndex, NumFixed = 1;
5075 bool WarnAboutSemanticsChange =
false;
5076 switch (BuiltinID) {
5077 default: llvm_unreachable(
"Unknown overloaded atomic builtin!");
5078 case Builtin::BI__sync_fetch_and_add:
5079 case Builtin::BI__sync_fetch_and_add_1:
5080 case Builtin::BI__sync_fetch_and_add_2:
5081 case Builtin::BI__sync_fetch_and_add_4:
5082 case Builtin::BI__sync_fetch_and_add_8:
5083 case Builtin::BI__sync_fetch_and_add_16:
5087 case Builtin::BI__sync_fetch_and_sub:
5088 case Builtin::BI__sync_fetch_and_sub_1:
5089 case Builtin::BI__sync_fetch_and_sub_2:
5090 case Builtin::BI__sync_fetch_and_sub_4:
5091 case Builtin::BI__sync_fetch_and_sub_8:
5092 case Builtin::BI__sync_fetch_and_sub_16:
5096 case Builtin::BI__sync_fetch_and_or:
5097 case Builtin::BI__sync_fetch_and_or_1:
5098 case Builtin::BI__sync_fetch_and_or_2:
5099 case Builtin::BI__sync_fetch_and_or_4:
5100 case Builtin::BI__sync_fetch_and_or_8:
5101 case Builtin::BI__sync_fetch_and_or_16:
5105 case Builtin::BI__sync_fetch_and_and:
5106 case Builtin::BI__sync_fetch_and_and_1:
5107 case Builtin::BI__sync_fetch_and_and_2:
5108 case Builtin::BI__sync_fetch_and_and_4:
5109 case Builtin::BI__sync_fetch_and_and_8:
5110 case Builtin::BI__sync_fetch_and_and_16:
5114 case Builtin::BI__sync_fetch_and_xor:
5115 case Builtin::BI__sync_fetch_and_xor_1:
5116 case Builtin::BI__sync_fetch_and_xor_2:
5117 case Builtin::BI__sync_fetch_and_xor_4:
5118 case Builtin::BI__sync_fetch_and_xor_8:
5119 case Builtin::BI__sync_fetch_and_xor_16:
5123 case Builtin::BI__sync_fetch_and_nand:
5124 case Builtin::BI__sync_fetch_and_nand_1:
5125 case Builtin::BI__sync_fetch_and_nand_2:
5126 case Builtin::BI__sync_fetch_and_nand_4:
5127 case Builtin::BI__sync_fetch_and_nand_8:
5128 case Builtin::BI__sync_fetch_and_nand_16:
5130 WarnAboutSemanticsChange =
true;
5133 case Builtin::BI__sync_add_and_fetch:
5134 case Builtin::BI__sync_add_and_fetch_1:
5135 case Builtin::BI__sync_add_and_fetch_2:
5136 case Builtin::BI__sync_add_and_fetch_4:
5137 case Builtin::BI__sync_add_and_fetch_8:
5138 case Builtin::BI__sync_add_and_fetch_16:
5142 case Builtin::BI__sync_sub_and_fetch:
5143 case Builtin::BI__sync_sub_and_fetch_1:
5144 case Builtin::BI__sync_sub_and_fetch_2:
5145 case Builtin::BI__sync_sub_and_fetch_4:
5146 case Builtin::BI__sync_sub_and_fetch_8:
5147 case Builtin::BI__sync_sub_and_fetch_16:
5151 case Builtin::BI__sync_and_and_fetch:
5152 case Builtin::BI__sync_and_and_fetch_1:
5153 case Builtin::BI__sync_and_and_fetch_2:
5154 case Builtin::BI__sync_and_and_fetch_4:
5155 case Builtin::BI__sync_and_and_fetch_8:
5156 case Builtin::BI__sync_and_and_fetch_16:
5160 case Builtin::BI__sync_or_and_fetch:
5161 case Builtin::BI__sync_or_and_fetch_1:
5162 case Builtin::BI__sync_or_and_fetch_2:
5163 case Builtin::BI__sync_or_and_fetch_4:
5164 case Builtin::BI__sync_or_and_fetch_8:
5165 case Builtin::BI__sync_or_and_fetch_16:
5169 case Builtin::BI__sync_xor_and_fetch:
5170 case Builtin::BI__sync_xor_and_fetch_1:
5171 case Builtin::BI__sync_xor_and_fetch_2:
5172 case Builtin::BI__sync_xor_and_fetch_4:
5173 case Builtin::BI__sync_xor_and_fetch_8:
5174 case Builtin::BI__sync_xor_and_fetch_16:
5178 case Builtin::BI__sync_nand_and_fetch:
5179 case Builtin::BI__sync_nand_and_fetch_1:
5180 case Builtin::BI__sync_nand_and_fetch_2:
5181 case Builtin::BI__sync_nand_and_fetch_4:
5182 case Builtin::BI__sync_nand_and_fetch_8:
5183 case Builtin::BI__sync_nand_and_fetch_16:
5185 WarnAboutSemanticsChange =
true;
5188 case Builtin::BI__sync_val_compare_and_swap:
5189 case Builtin::BI__sync_val_compare_and_swap_1:
5190 case Builtin::BI__sync_val_compare_and_swap_2:
5191 case Builtin::BI__sync_val_compare_and_swap_4:
5192 case Builtin::BI__sync_val_compare_and_swap_8:
5193 case Builtin::BI__sync_val_compare_and_swap_16:
5198 case Builtin::BI__sync_bool_compare_and_swap:
5199 case Builtin::BI__sync_bool_compare_and_swap_1:
5200 case Builtin::BI__sync_bool_compare_and_swap_2:
5201 case Builtin::BI__sync_bool_compare_and_swap_4:
5202 case Builtin::BI__sync_bool_compare_and_swap_8:
5203 case Builtin::BI__sync_bool_compare_and_swap_16:
5209 case Builtin::BI__sync_lock_test_and_set:
5210 case Builtin::BI__sync_lock_test_and_set_1:
5211 case Builtin::BI__sync_lock_test_and_set_2:
5212 case Builtin::BI__sync_lock_test_and_set_4:
5213 case Builtin::BI__sync_lock_test_and_set_8:
5214 case Builtin::BI__sync_lock_test_and_set_16:
5218 case Builtin::BI__sync_lock_release:
5219 case Builtin::BI__sync_lock_release_1:
5220 case Builtin::BI__sync_lock_release_2:
5221 case Builtin::BI__sync_lock_release_4:
5222 case Builtin::BI__sync_lock_release_8:
5223 case Builtin::BI__sync_lock_release_16:
5229 case Builtin::BI__sync_swap:
5230 case Builtin::BI__sync_swap_1:
5231 case Builtin::BI__sync_swap_2:
5232 case Builtin::BI__sync_swap_4:
5233 case Builtin::BI__sync_swap_8:
5234 case Builtin::BI__sync_swap_16:
5242 Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args_at_least)
5243 << 0 << 1 + NumFixed << TheCall->
getNumArgs() << 0
5244 <<
Callee->getSourceRange();
5248 Diag(TheCall->
getEndLoc(), diag::warn_atomic_implicit_seq_cst)
5249 <<
Callee->getSourceRange();
5251 if (WarnAboutSemanticsChange) {
5252 Diag(TheCall->
getEndLoc(), diag::warn_sync_fetch_and_nand_semantics_change)
5253 <<
Callee->getSourceRange();
5258 unsigned NewBuiltinID = BuiltinIndices[BuiltinIndex][SizeIndex];
5259 std::string NewBuiltinName =
Context.BuiltinInfo.getName(NewBuiltinID);
5260 FunctionDecl *NewBuiltinDecl;
5261 if (NewBuiltinID == BuiltinID)
5262 NewBuiltinDecl = FDecl;
5265 DeclarationName DN(&
Context.Idents.get(NewBuiltinName));
5268 assert(Res.getFoundDecl());
5269 NewBuiltinDecl = dyn_cast<FunctionDecl>(Res.getFoundDecl());
5270 if (!NewBuiltinDecl)
5277 for (
unsigned i = 0; i != NumFixed; ++i) {
5306 QualType CalleePtrTy =
Context.getPointerType(NewBuiltinDecl->
getType());
5308 CK_BuiltinFnToFnPtr);
5319 const auto *BitIntValType = ValType->
getAs<BitIntType>();
5320 if (BitIntValType && !llvm::isPowerOf2_64(BitIntValType->getNumBits())) {
5321 Diag(FirstArg->
getExprLoc(), diag::err_atomic_builtin_ext_int_size);
5325 return TheCallResult;
5329 CallExpr *TheCall = (CallExpr *)TheCallResult.
get();
5334 assert((BuiltinID == Builtin::BI__builtin_nontemporal_store ||
5335 BuiltinID == Builtin::BI__builtin_nontemporal_load) &&
5336 "Unexpected nontemporal load/store builtin!");
5337 bool isStore = BuiltinID == Builtin::BI__builtin_nontemporal_store;
5338 unsigned numArgs = isStore ? 2 : 1;
5348 Expr *PointerArg = TheCall->
getArg(numArgs - 1);
5354 PointerArg = PointerArgResult.
get();
5355 TheCall->
setArg(numArgs - 1, PointerArg);
5359 Diag(DRE->
getBeginLoc(), diag::err_nontemporal_builtin_must_be_pointer)
5372 diag::err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector)
5379 return TheCallResult;
5391 return TheCallResult;
5398 auto *
Literal = dyn_cast<StringLiteral>(Arg);
5400 if (
auto *ObjcLiteral = dyn_cast<ObjCStringLiteral>(Arg)) {
5401 Literal = ObjcLiteral->getString();
5405 if (!Literal || (!
Literal->isOrdinary() && !
Literal->isUTF8())) {
5412 QualType ResultTy =
Context.getPointerType(
Context.CharTy.withConst());
5413 InitializedEntity Entity =
5423 bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
5424 bool IsAArch64 = (TT.getArch() == llvm::Triple::aarch64 ||
5425 TT.getArch() == llvm::Triple::aarch64_32);
5426 bool IsWindowsOrUEFI = TT.isOSWindows() || TT.isUEFI();
5427 bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
5428 if (IsX64 || IsAArch64) {
5435 return S.
Diag(Fn->getBeginLoc(),
5436 diag::err_ms_va_start_used_in_sysv_function);
5443 (!IsWindowsOrUEFI && CC ==
CC_Win64))
5444 return S.
Diag(Fn->getBeginLoc(),
5445 diag::err_va_start_used_in_wrong_abi_function)
5446 << !IsWindowsOrUEFI;
5452 return S.
Diag(Fn->getBeginLoc(), diag::err_builtin_x64_aarch64_only);
5460 bool IsVariadic =
false;
5463 if (
auto *
Block = dyn_cast<BlockDecl>(Caller)) {
5464 IsVariadic =
Block->isVariadic();
5465 Params =
Block->parameters();
5466 }
else if (
auto *FD = dyn_cast<FunctionDecl>(Caller)) {
5469 }
else if (
auto *MD = dyn_cast<ObjCMethodDecl>(Caller)) {
5470 IsVariadic = MD->isVariadic();
5472 Params = MD->parameters();
5475 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_captured_stmt);
5479 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_outside_function);
5484 S.
Diag(Fn->getBeginLoc(), diag::err_va_start_fixed_function);
5489 *LastParam = Params.empty() ?
nullptr : Params.back();
5494bool Sema::BuiltinVAStart(
unsigned BuiltinID,
CallExpr *TheCall) {
5499 if (BuiltinID == Builtin::BI__builtin_c23_va_start) {
5523 ParmVarDecl *LastParam;
5534 if (BuiltinID == Builtin::BI__builtin_c23_va_start &&
5536 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5541 if (std::optional<llvm::APSInt> Val =
5543 Val &&
LangOpts.C23 && *Val == 0 &&
5544 BuiltinID != Builtin::BI__builtin_c23_va_start) {
5545 Diag(TheCall->
getExprLoc(), diag::warn_c17_compat_va_start_one_arg);
5552 SourceLocation ParamLoc;
5553 bool IsCRegister =
false;
5554 bool SecondArgIsLastNonVariadicArgument =
false;
5555 if (
const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
5556 if (
const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
5557 SecondArgIsLastNonVariadicArgument = PV == LastParam;
5560 ParamLoc = PV->getLocation();
5566 if (!SecondArgIsLastNonVariadicArgument)
5568 diag::warn_second_arg_of_va_start_not_last_non_variadic_param);
5569 else if (IsCRegister ||
Type->isReferenceType() ||
5570 Type->isSpecificBuiltinType(BuiltinType::Float) || [=] {
5573 if (!Context.isPromotableIntegerType(Type))
5575 const auto *ED = Type->getAsEnumDecl();
5578 return !Context.typesAreCompatible(ED->getPromotionType(), Type);
5580 unsigned Reason = 0;
5581 if (
Type->isReferenceType()) Reason = 1;
5582 else if (IsCRegister) Reason = 2;
5583 Diag(Arg->
getBeginLoc(), diag::warn_va_start_type_is_undefined) << Reason;
5584 Diag(ParamLoc, diag::note_parameter_type) <<
Type;
5591 auto IsSuitablyTypedFormatArgument = [
this](
const Expr *Arg) ->
bool {
5611 if (
Call->getNumArgs() < 3)
5613 diag::err_typecheck_call_too_few_args_at_least)
5614 << 0 << 3 <<
Call->getNumArgs()
5627 const Expr *Arg1 =
Call->getArg(1)->IgnoreParens();
5630 const Expr *Arg2 =
Call->getArg(2)->IgnoreParens();
5633 const QualType &ConstCharPtrTy =
5635 if (!Arg1Ty->
isPointerType() || !IsSuitablyTypedFormatArgument(Arg1))
5637 << Arg1->
getType() << ConstCharPtrTy << 1
5640 << 2 << Arg1->
getType() << ConstCharPtrTy;
5642 const QualType SizeTy =
Context.getSizeType();
5647 << Arg2->
getType() << SizeTy << 1
5650 << 3 << Arg2->
getType() << SizeTy;
5655bool Sema::BuiltinUnorderedCompare(
CallExpr *TheCall,
unsigned BuiltinID) {
5659 if (BuiltinID == Builtin::BI__builtin_isunordered &&
5687 diag::err_typecheck_call_invalid_ordered_compare)
5695bool Sema::BuiltinFPClassification(
CallExpr *TheCall,
unsigned NumArgs,
5696 unsigned BuiltinID) {
5701 if (FPO.getNoHonorInfs() && (BuiltinID == Builtin::BI__builtin_isfinite ||
5702 BuiltinID == Builtin::BI__builtin_isinf ||
5703 BuiltinID == Builtin::BI__builtin_isinf_sign))
5707 if (FPO.getNoHonorNaNs() && (BuiltinID == Builtin::BI__builtin_isnan ||
5708 BuiltinID == Builtin::BI__builtin_isunordered))
5712 bool IsFPClass = NumArgs == 2;
5715 unsigned FPArgNo = IsFPClass ? 0 : NumArgs - 1;
5719 for (
unsigned i = 0; i < FPArgNo; ++i) {
5720 Expr *Arg = TheCall->
getArg(i);
5733 Expr *OrigArg = TheCall->
getArg(FPArgNo);
5741 if (
Context.getTargetInfo().useFP16ConversionIntrinsics()) {
5746 OrigArg = Res.
get();
5752 OrigArg = Res.
get();
5754 TheCall->
setArg(FPArgNo, OrigArg);
5756 QualType VectorResultTy;
5757 QualType ElementTy = OrigArg->
getType();
5762 ElementTy = ElementTy->
castAs<VectorType>()->getElementType();
5768 diag::err_typecheck_call_invalid_unary_fp)
5780 if (!VectorResultTy.
isNull())
5781 ResultTy = VectorResultTy;
5790bool Sema::BuiltinComplex(
CallExpr *TheCall) {
5795 for (
unsigned I = 0; I != 2; ++I) {
5796 Expr *Arg = TheCall->
getArg(I);
5806 return Diag(Arg->
getBeginLoc(), diag::err_typecheck_call_requires_real_fp)
5821 Expr *Real = TheCall->
getArg(0);
5822 Expr *Imag = TheCall->
getArg(1);
5825 diag::err_typecheck_call_different_arg_types)
5840 diag::err_typecheck_call_too_few_args_at_least)
5841 << 0 << 2 << NumArgs
5848 unsigned NumElements = 0;
5863 unsigned NumResElements = NumArgs - 2;
5872 diag::err_vec_builtin_incompatible_vector)
5877 }
else if (!
Context.hasSameUnqualifiedType(LHSType, RHSType)) {
5879 diag::err_vec_builtin_incompatible_vector)
5884 }
else if (NumElements != NumResElements) {
5887 ?
Context.getExtVectorType(EltType, NumResElements)
5888 :
Context.getVectorType(EltType, NumResElements,
5893 for (
unsigned I = 2; I != NumArgs; ++I) {
5901 diag::err_shufflevector_nonconstant_argument)
5907 else if (
Result->getActiveBits() > 64 ||
5908 Result->getZExtValue() >= NumElements * 2)
5910 diag::err_shufflevector_argument_too_large)
5935 diag::err_convertvector_non_vector)
5938 return ExprError(
Diag(BuiltinLoc, diag::err_builtin_non_vector_type)
5940 <<
"__builtin_convertvector");
5945 if (SrcElts != DstElts)
5947 diag::err_convertvector_incompatible_vector)
5955bool Sema::BuiltinPrefetch(
CallExpr *TheCall) {
5960 diag::err_typecheck_call_too_many_args_at_most)
5961 << 0 << 3 << NumArgs << 0
5966 for (
unsigned i = 1; i != NumArgs; ++i)
5973bool Sema::BuiltinArithmeticFence(
CallExpr *TheCall) {
5974 if (!Context.getTargetInfo().checkArithmeticFenceSupported())
5975 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_target_unsupported)
5985 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_expect_flt_or_vector)
5995bool Sema::BuiltinAssume(
CallExpr *TheCall) {
5996 Expr *Arg = TheCall->
getArg(0);
6007bool Sema::BuiltinAllocaWithAlign(
CallExpr *TheCall) {
6009 Expr *Arg = TheCall->
getArg(1);
6013 if (
const auto *UE =
6015 if (UE->getKind() == UETT_AlignOf ||
6016 UE->getKind() == UETT_PreferredAlignOf)
6022 if (!
Result.isPowerOf2())
6023 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6030 if (
Result > std::numeric_limits<int32_t>::max())
6038bool Sema::BuiltinAssumeAligned(
CallExpr *TheCall) {
6043 Expr *FirstArg = TheCall->
getArg(0);
6049 Diag(TheCall->
getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
6053 TheCall->
setArg(0, FirstArgResult.
get());
6057 Expr *SecondArg = TheCall->
getArg(1);
6065 if (!
Result.isPowerOf2())
6066 return Diag(TheCall->
getBeginLoc(), diag::err_alignment_not_power_of_two)
6078 Expr *ThirdArg = TheCall->
getArg(2);
6081 TheCall->
setArg(2, ThirdArg);
6087bool Sema::BuiltinOSLogFormat(
CallExpr *TheCall) {
6088 unsigned BuiltinID =
6090 bool IsSizeCall = BuiltinID == Builtin::BI__builtin_os_log_format_buffer_size;
6093 unsigned NumRequiredArgs = IsSizeCall ? 1 : 2;
6094 if (NumArgs < NumRequiredArgs) {
6095 return Diag(TheCall->
getEndLoc(), diag::err_typecheck_call_too_few_args)
6096 << 0 << NumRequiredArgs << NumArgs
6099 if (NumArgs >= NumRequiredArgs + 0x100) {
6101 diag::err_typecheck_call_too_many_args_at_most)
6102 << 0 << (NumRequiredArgs + 0xff) << NumArgs
6113 if (Arg.isInvalid())
6115 TheCall->
setArg(i, Arg.get());
6120 unsigned FormatIdx = i;
6130 unsigned FirstDataArg = i;
6131 while (i < NumArgs) {
6149 llvm::SmallBitVector CheckedVarArgs(NumArgs,
false);
6151 bool Success = CheckFormatArguments(
6154 TheCall->
getBeginLoc(), SourceRange(), CheckedVarArgs);
6178 return Diag(TheCall->
getBeginLoc(), diag::err_constant_integer_arg_type)
6187 int High,
bool RangeIsError) {
6201 if (
Result.getSExtValue() < Low ||
Result.getSExtValue() > High) {
6209 PDiag(diag::warn_argument_invalid_range)
6252 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_power_of_2)
6257 if (
Value.isNegative())
6268 if ((
Value & 0xFF) != 0)
6293 Result.setIsUnsigned(
true);
6298 return Diag(TheCall->
getBeginLoc(), diag::err_argument_not_shifted_byte)
6318 Result.setIsUnsigned(
true);
6326 diag::err_argument_not_shifted_byte_or_xxff)
6330bool Sema::BuiltinLongjmp(
CallExpr *TheCall) {
6331 if (!Context.getTargetInfo().hasSjLjLowering())
6332 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_unsupported)
6343 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_longjmp_invalid_val)
6349bool Sema::BuiltinSetjmp(
CallExpr *TheCall) {
6350 if (!Context.getTargetInfo().hasSjLjLowering())
6351 return Diag(TheCall->
getBeginLoc(), diag::err_builtin_setjmp_unsupported)
6356bool Sema::BuiltinCountedByRef(
CallExpr *TheCall) {
6371 diag::err_builtin_counted_by_ref_invalid_arg)
6376 diag::err_builtin_counted_by_ref_has_side_effects)
6379 if (
const auto *ME = dyn_cast<MemberExpr>(Arg)) {
6381 ME->getMemberDecl()->getType()->getAs<CountAttributedType>();
6386 if (
const FieldDecl *CountFD = MemberDecl->findCountedByField()) {
6393 QualType MemberTy = ME->getMemberDecl()->getType();
6396 diag::err_builtin_counted_by_ref_invalid_arg)
6400 diag::err_builtin_counted_by_ref_invalid_arg)
6410bool Sema::CheckInvalidBuiltinCountedByRef(
const Expr *E,
6412 const CallExpr *CE =
6421 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6426 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6431 diag::err_builtin_counted_by_ref_cannot_leak_reference)
6435 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6439 Diag(E->
getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
6449class UncoveredArgHandler {
6450 enum {
Unknown = -1, AllCovered = -2 };
6452 signed FirstUncoveredArg =
Unknown;
6453 SmallVector<const Expr *, 4> DiagnosticExprs;
6456 UncoveredArgHandler() =
default;
6458 bool hasUncoveredArg()
const {
6459 return (FirstUncoveredArg >= 0);
6462 unsigned getUncoveredArg()
const {
6463 assert(hasUncoveredArg() &&
"no uncovered argument");
6464 return FirstUncoveredArg;
6467 void setAllCovered() {
6470 DiagnosticExprs.clear();
6471 FirstUncoveredArg = AllCovered;
6474 void Update(
signed NewFirstUncoveredArg,
const Expr *StrExpr) {
6475 assert(NewFirstUncoveredArg >= 0 &&
"Outside range");
6478 if (FirstUncoveredArg == AllCovered)
6483 if (NewFirstUncoveredArg == FirstUncoveredArg)
6484 DiagnosticExprs.push_back(StrExpr);
6485 else if (NewFirstUncoveredArg > FirstUncoveredArg) {
6486 DiagnosticExprs.clear();
6487 DiagnosticExprs.push_back(StrExpr);
6488 FirstUncoveredArg = NewFirstUncoveredArg;
6492 void Diagnose(Sema &S,
bool IsFunctionCall,
const Expr *ArgExpr);
6495enum StringLiteralCheckType {
6497 SLCT_UncheckedLiteral,
6505 bool AddendIsRight) {
6506 unsigned BitWidth = Offset.getBitWidth();
6507 unsigned AddendBitWidth = Addend.getBitWidth();
6509 if (Addend.isUnsigned()) {
6510 Addend = Addend.zext(++AddendBitWidth);
6511 Addend.setIsSigned(
true);
6514 if (AddendBitWidth > BitWidth) {
6515 Offset = Offset.sext(AddendBitWidth);
6516 BitWidth = AddendBitWidth;
6517 }
else if (BitWidth > AddendBitWidth) {
6518 Addend = Addend.sext(BitWidth);
6522 llvm::APSInt ResOffset = Offset;
6523 if (BinOpKind == BO_Add)
6524 ResOffset = Offset.sadd_ov(Addend, Ov);
6526 assert(AddendIsRight && BinOpKind == BO_Sub &&
6527 "operator must be add or sub with addend on the right");
6528 ResOffset = Offset.ssub_ov(Addend, Ov);
6534 assert(BitWidth <= std::numeric_limits<unsigned>::max() / 2 &&
6535 "index (intermediate) result too big");
6536 Offset = Offset.sext(2 * BitWidth);
6537 sumOffsets(Offset, Addend, BinOpKind, AddendIsRight);
6549class FormatStringLiteral {
6550 const StringLiteral *FExpr;
6554 FormatStringLiteral(
const StringLiteral *fexpr, int64_t Offset = 0)
6555 : FExpr(fexpr), Offset(Offset) {}
6557 const StringLiteral *getFormatString()
const {
return FExpr; }
6559 StringRef getString()
const {
return FExpr->
getString().drop_front(Offset); }
6561 unsigned getByteLength()
const {
6562 return FExpr->
getByteLength() - getCharByteWidth() * Offset;
6565 unsigned getLength()
const {
return FExpr->
getLength() - Offset; }
6572 bool isAscii()
const {
return FExpr->
isOrdinary(); }
6573 bool isWide()
const {
return FExpr->
isWide(); }
6574 bool isUTF8()
const {
return FExpr->
isUTF8(); }
6575 bool isUTF16()
const {
return FExpr->
isUTF16(); }
6576 bool isUTF32()
const {
return FExpr->
isUTF32(); }
6577 bool isPascal()
const {
return FExpr->
isPascal(); }
6579 SourceLocation getLocationOfByte(
6580 unsigned ByteNo,
const SourceManager &
SM,
const LangOptions &Features,
6581 const TargetInfo &
Target,
unsigned *StartToken =
nullptr,
6582 unsigned *StartTokenByteOffset =
nullptr)
const {
6584 StartToken, StartTokenByteOffset);
6587 SourceLocation getBeginLoc() const LLVM_READONLY {
6591 SourceLocation getEndLoc() const LLVM_READONLY {
return FExpr->
getEndLoc(); }
6597 Sema &S,
const FormatStringLiteral *FExpr,
6602 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
6603 bool IgnoreStringsWithoutSpecifiers);
6612static StringLiteralCheckType
6618 llvm::SmallBitVector &CheckedVarArgs,
6619 UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset,
6620 std::optional<unsigned> *CallerFormatParamIdx =
nullptr,
6621 bool IgnoreStringsWithoutSpecifiers =
false) {
6623 return SLCT_NotALiteral;
6625 assert(Offset.isSigned() &&
"invalid offset");
6628 return SLCT_NotALiteral;
6637 return SLCT_UncheckedLiteral;
6640 case Stmt::InitListExprClass:
6644 format_idx, firstDataArg,
Type, CallType,
6645 false, CheckedVarArgs,
6646 UncoveredArg, Offset, CallerFormatParamIdx,
6647 IgnoreStringsWithoutSpecifiers);
6649 return SLCT_NotALiteral;
6650 case Stmt::BinaryConditionalOperatorClass:
6651 case Stmt::ConditionalOperatorClass: {
6660 bool CheckLeft =
true, CheckRight =
true;
6663 if (
C->getCond()->EvaluateAsBooleanCondition(
6675 StringLiteralCheckType Left;
6677 Left = SLCT_UncheckedLiteral;
6680 Args, APK, format_idx, firstDataArg,
Type,
6681 CallType, InFunctionCall, CheckedVarArgs,
6682 UncoveredArg, Offset, CallerFormatParamIdx,
6683 IgnoreStringsWithoutSpecifiers);
6684 if (Left == SLCT_NotALiteral || !CheckRight) {
6690 S, ReferenceFormatString,
C->getFalseExpr(), Args, APK, format_idx,
6691 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6692 UncoveredArg, Offset, CallerFormatParamIdx,
6693 IgnoreStringsWithoutSpecifiers);
6695 return (CheckLeft && Left < Right) ? Left : Right;
6698 case Stmt::ImplicitCastExprClass:
6702 case Stmt::OpaqueValueExprClass:
6707 return SLCT_NotALiteral;
6709 case Stmt::PredefinedExprClass:
6713 return SLCT_UncheckedLiteral;
6715 case Stmt::DeclRefExprClass: {
6721 bool isConstant =
false;
6725 isConstant = AT->getElementType().isConstant(S.
Context);
6727 isConstant =
T.isConstant(S.
Context) &&
6728 PT->getPointeeType().isConstant(S.
Context);
6729 }
else if (
T->isObjCObjectPointerType()) {
6732 isConstant =
T.isConstant(S.
Context);
6736 if (
const Expr *
Init = VD->getAnyInitializer()) {
6739 if (InitList->isStringLiteralInit())
6740 Init = InitList->getInit(0)->IgnoreParenImpCasts();
6743 S, ReferenceFormatString,
Init, Args, APK, format_idx,
6744 firstDataArg,
Type, CallType,
false,
6745 CheckedVarArgs, UncoveredArg, Offset, CallerFormatParamIdx);
6796 if (
const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
6797 if (CallerFormatParamIdx)
6798 *CallerFormatParamIdx = PV->getFunctionScopeIndex();
6799 if (
const auto *D = dyn_cast<Decl>(PV->getDeclContext())) {
6800 for (
const auto *PVFormatMatches :
6801 D->specific_attrs<FormatMatchesAttr>()) {
6806 if (PV->getFunctionScopeIndex() == CalleeFSI.
FormatIdx) {
6810 S.
Diag(Args[format_idx]->getBeginLoc(),
6811 diag::warn_format_string_type_incompatible)
6812 << PVFormatMatches->getType()->getName()
6814 if (!InFunctionCall) {
6815 S.
Diag(PVFormatMatches->getFormatString()->getBeginLoc(),
6816 diag::note_format_string_defined);
6818 return SLCT_UncheckedLiteral;
6821 S, ReferenceFormatString, PVFormatMatches->getFormatString(),
6822 Args, APK, format_idx, firstDataArg,
Type, CallType,
6823 false, CheckedVarArgs, UncoveredArg,
6824 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6828 for (
const auto *PVFormat : D->specific_attrs<FormatAttr>()) {
6831 PVFormat->getFirstArg(), &CallerFSI))
6833 if (PV->getFunctionScopeIndex() == CallerFSI.
FormatIdx) {
6837 S.
Diag(Args[format_idx]->getBeginLoc(),
6838 diag::warn_format_string_type_incompatible)
6839 << PVFormat->getType()->getName()
6841 if (!InFunctionCall) {
6844 return SLCT_UncheckedLiteral;
6857 return SLCT_UncheckedLiteral;
6865 return SLCT_NotALiteral;
6868 case Stmt::CallExprClass:
6869 case Stmt::CXXMemberCallExprClass: {
6873 StringLiteralCheckType CommonResult;
6874 for (
const auto *FA : ND->specific_attrs<FormatArgAttr>()) {
6875 const Expr *Arg = CE->
getArg(FA->getFormatIdx().getASTIndex());
6877 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6878 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6879 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6881 CommonResult = Result;
6886 return CommonResult;
6888 if (
const auto *FD = dyn_cast<FunctionDecl>(ND)) {
6890 if (BuiltinID == Builtin::BI__builtin___CFStringMakeConstantString ||
6891 BuiltinID == Builtin::BI__builtin___NSStringMakeConstantString) {
6894 S, ReferenceFormatString, Arg, Args, APK, format_idx,
6895 firstDataArg,
Type, CallType, InFunctionCall, CheckedVarArgs,
6896 UncoveredArg, Offset, CallerFormatParamIdx,
6897 IgnoreStringsWithoutSpecifiers);
6903 format_idx, firstDataArg,
Type, CallType,
6904 false, CheckedVarArgs,
6905 UncoveredArg, Offset, CallerFormatParamIdx,
6906 IgnoreStringsWithoutSpecifiers);
6907 return SLCT_NotALiteral;
6909 case Stmt::ObjCMessageExprClass: {
6911 if (
const auto *MD = ME->getMethodDecl()) {
6912 if (
const auto *FA = MD->getAttr<FormatArgAttr>()) {
6921 if (MD->isInstanceMethod() && (IFace = MD->getClassInterface()) &&
6923 MD->getSelector().isKeywordSelector(
6924 {
"localizedStringForKey",
"value",
"table"})) {
6925 IgnoreStringsWithoutSpecifiers =
true;
6928 const Expr *Arg = ME->getArg(FA->getFormatIdx().getASTIndex());
6930 S, ReferenceFormatString, Arg, Args, APK, format_idx, firstDataArg,
6931 Type, CallType, InFunctionCall, CheckedVarArgs, UncoveredArg,
6932 Offset, CallerFormatParamIdx, IgnoreStringsWithoutSpecifiers);
6936 return SLCT_NotALiteral;
6938 case Stmt::ObjCStringLiteralClass:
6939 case Stmt::StringLiteralClass: {
6948 if (Offset.isNegative() || Offset > StrE->
getLength()) {
6951 return SLCT_NotALiteral;
6953 FormatStringLiteral FStr(StrE, Offset.sextOrTrunc(64).getSExtValue());
6955 format_idx, firstDataArg,
Type, InFunctionCall,
6956 CallType, CheckedVarArgs, UncoveredArg,
6957 IgnoreStringsWithoutSpecifiers);
6958 return SLCT_CheckedLiteral;
6961 return SLCT_NotALiteral;
6963 case Stmt::BinaryOperatorClass: {
6977 if (LIsInt != RIsInt) {
6981 if (BinOpKind == BO_Add) {
6994 return SLCT_NotALiteral;
6996 case Stmt::UnaryOperatorClass: {
6998 auto ASE = dyn_cast<ArraySubscriptExpr>(UnaOp->
getSubExpr());
6999 if (UnaOp->
getOpcode() == UO_AddrOf && ASE) {
7001 if (ASE->getRHS()->EvaluateAsInt(IndexResult, S.
Context,
7011 return SLCT_NotALiteral;
7015 return SLCT_NotALiteral;
7026 const auto *LVE = Result.Val.getLValueBase().dyn_cast<
const Expr *>();
7027 if (isa_and_nonnull<StringLiteral>(LVE))
7048 return "freebsd_kprintf";
7057 return llvm::StringSwitch<FormatStringType>(Flavor)
7059 .Cases({
"gnu_printf",
"printf",
"printf0",
"syslog"},
7064 .Cases({
"kprintf",
"cmn_err",
"vcmn_err",
"zcmn_err"},
7080bool Sema::CheckFormatArguments(
const FormatAttr *Format,
7084 llvm::SmallBitVector &CheckedVarArgs) {
7085 FormatStringInfo FSI;
7089 return CheckFormatArguments(
7090 Args, FSI.ArgPassingKind,
nullptr, FSI.FormatIdx, FSI.FirstDataArg,
7095bool Sema::CheckFormatString(
const FormatMatchesAttr *Format,
7099 llvm::SmallBitVector &CheckedVarArgs) {
7100 FormatStringInfo FSI;
7104 return CheckFormatArguments(Args, FSI.ArgPassingKind,
7105 Format->getFormatString(), FSI.FormatIdx,
7107 CallType, Loc, Range, CheckedVarArgs);
7115 unsigned FirstDataArg,
FormatStringType FormatType,
unsigned CallerParamIdx,
7128 unsigned CallerArgumentIndexOffset =
7131 unsigned FirstArgumentIndex = -1;
7141 unsigned NumCalleeArgs = Args.size() - FirstDataArg;
7142 if (NumCalleeArgs == 0 || NumCallerParams < NumCalleeArgs) {
7146 for (
unsigned CalleeIdx = Args.size() - 1, CallerIdx = NumCallerParams - 1;
7147 CalleeIdx >= FirstDataArg; --CalleeIdx, --CallerIdx) {
7149 dyn_cast<DeclRefExpr>(Args[CalleeIdx]->IgnoreParenCasts());
7152 const auto *Param = dyn_cast<ParmVarDecl>(Arg->getDecl());
7153 if (!Param || Param->getFunctionScopeIndex() != CallerIdx)
7156 FirstArgumentIndex =
7157 NumCallerParams + CallerArgumentIndexOffset - NumCalleeArgs;
7163 ? (NumCallerParams + CallerArgumentIndexOffset)
7168 if (!ReferenceFormatString)
7174 unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
7176 NamedDecl *ND = dyn_cast<NamedDecl>(Caller);
7178 std::string
Attr, Fixit;
7179 llvm::raw_string_ostream AttrOS(
Attr);
7181 AttrOS <<
"format(" << FormatTypeName <<
", " << FormatStringIndex <<
", "
7182 << FirstArgumentIndex <<
")";
7184 AttrOS <<
"format_matches(" << FormatTypeName <<
", " << FormatStringIndex
7186 AttrOS.write_escaped(ReferenceFormatString->
getString());
7190 auto DB = S->
Diag(Loc, diag::warn_missing_format_attribute) <<
Attr;
7201 llvm::raw_string_ostream IS(Fixit);
7209 if (LO.C23 || LO.CPlusPlus11)
7210 IS <<
"[[gnu::" <<
Attr <<
"]]";
7211 else if (LO.ObjC || LO.GNUMode)
7212 IS <<
"__attribute__((" <<
Attr <<
"))";
7226 Caller->
addAttr(FormatAttr::CreateImplicit(
7228 FormatStringIndex, FirstArgumentIndex));
7230 Caller->
addAttr(FormatMatchesAttr::CreateImplicit(
7232 FormatStringIndex, ReferenceFormatString));
7236 auto DB = S->
Diag(Caller->
getLocation(), diag::note_entity_declared_at);
7248 unsigned format_idx,
unsigned firstDataArg,
7252 llvm::SmallBitVector &CheckedVarArgs) {
7254 if (format_idx >= Args.size()) {
7255 Diag(Loc, diag::warn_missing_format_string) <<
Range;
7259 const Expr *OrigFormatExpr = Args[format_idx]->IgnoreParenCasts();
7273 UncoveredArgHandler UncoveredArg;
7274 std::optional<unsigned> CallerParamIdx;
7276 *
this, ReferenceFormatString, OrigFormatExpr, Args, APK, format_idx,
7277 firstDataArg,
Type, CallType,
7278 true, CheckedVarArgs, UncoveredArg,
7279 llvm::APSInt(64,
false) = 0, &CallerParamIdx);
7282 if (UncoveredArg.hasUncoveredArg()) {
7283 unsigned ArgIdx = UncoveredArg.getUncoveredArg() + firstDataArg;
7284 assert(ArgIdx < Args.size() &&
"ArgIdx outside bounds");
7285 UncoveredArg.Diagnose(*
this,
true, Args[ArgIdx]);
7288 if (CT != SLCT_NotALiteral)
7290 return CT == SLCT_CheckedLiteral;
7296 SourceLocation FormatLoc = Args[format_idx]->getBeginLoc();
7302 this, Args, APK, ReferenceFormatString, format_idx,
7303 firstDataArg,
Type, *CallerParamIdx, Loc))
7313 if (Args.size() == firstDataArg) {
7314 Diag(FormatLoc, diag::warn_format_nonliteral_noargs)
7322 Diag(FormatLoc, diag::note_format_security_fixit)
7326 Diag(FormatLoc, diag::note_format_security_fixit)
7331 Diag(FormatLoc, diag::warn_format_nonliteral)
7342 const FormatStringLiteral *FExpr;
7343 const Expr *OrigFormatExpr;
7345 const unsigned FirstDataArg;
7346 const unsigned NumDataArgs;
7349 ArrayRef<const Expr *> Args;
7351 llvm::SmallBitVector CoveredArgs;
7352 bool usesPositionalArgs =
false;
7353 bool atFirstArg =
true;
7354 bool inFunctionCall;
7356 llvm::SmallBitVector &CheckedVarArgs;
7357 UncoveredArgHandler &UncoveredArg;
7360 CheckFormatHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7362 unsigned firstDataArg,
unsigned numDataArgs,
7364 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7366 llvm::SmallBitVector &CheckedVarArgs,
7367 UncoveredArgHandler &UncoveredArg)
7368 : S(
s), FExpr(fexpr), OrigFormatExpr(origFormatExpr), FSType(
type),
7369 FirstDataArg(firstDataArg), NumDataArgs(numDataArgs), Beg(beg),
7370 ArgPassingKind(APK), Args(Args), FormatIdx(formatIdx),
7371 inFunctionCall(inFunctionCall), CallType(callType),
7372 CheckedVarArgs(CheckedVarArgs), UncoveredArg(UncoveredArg) {
7373 CoveredArgs.resize(numDataArgs);
7374 CoveredArgs.reset();
7377 bool HasFormatArguments()
const {
7382 void DoneProcessing();
7384 void HandleIncompleteSpecifier(
const char *startSpecifier,
7385 unsigned specifierLen)
override;
7387 void HandleInvalidLengthModifier(
7388 const analyze_format_string::FormatSpecifier &FS,
7389 const analyze_format_string::ConversionSpecifier &CS,
7390 const char *startSpecifier,
unsigned specifierLen,
7393 void HandleNonStandardLengthModifier(
7394 const analyze_format_string::FormatSpecifier &FS,
7395 const char *startSpecifier,
unsigned specifierLen);
7397 void HandleNonStandardConversionSpecifier(
7398 const analyze_format_string::ConversionSpecifier &CS,
7399 const char *startSpecifier,
unsigned specifierLen);
7401 void HandlePosition(
const char *startPos,
unsigned posLen)
override;
7403 void HandleInvalidPosition(
const char *startSpecifier,
7404 unsigned specifierLen,
7407 void HandleZeroPosition(
const char *startPos,
unsigned posLen)
override;
7409 void HandleNullChar(
const char *nullCharacter)
override;
7411 template <
typename Range>
7413 EmitFormatDiagnostic(Sema &S,
bool inFunctionCall,
const Expr *ArgumentExpr,
7414 const PartialDiagnostic &PDiag, SourceLocation StringLoc,
7415 bool IsStringLocation, Range StringRange,
7416 ArrayRef<FixItHint> Fixit = {});
7419 bool HandleInvalidConversionSpecifier(
unsigned argIndex, SourceLocation Loc,
7420 const char *startSpec,
7421 unsigned specifierLen,
7422 const char *csStart,
unsigned csLen);
7424 void HandlePositionalNonpositionalArgs(SourceLocation Loc,
7425 const char *startSpec,
7426 unsigned specifierLen);
7428 SourceRange getFormatStringRange();
7429 CharSourceRange getSpecifierRange(
const char *startSpecifier,
7430 unsigned specifierLen);
7431 SourceLocation getLocationOfByte(
const char *x);
7433 const Expr *getDataArg(
unsigned i)
const;
7435 bool CheckNumArgs(
const analyze_format_string::FormatSpecifier &FS,
7436 const analyze_format_string::ConversionSpecifier &CS,
7437 const char *startSpecifier,
unsigned specifierLen,
7440 template <
typename Range>
7441 void EmitFormatDiagnostic(PartialDiagnostic PDiag, SourceLocation StringLoc,
7442 bool IsStringLocation, Range StringRange,
7443 ArrayRef<FixItHint> Fixit = {});
7448SourceRange CheckFormatHandler::getFormatStringRange() {
7453getSpecifierRange(
const char *startSpecifier,
unsigned specifierLen) {
7455 SourceLocation End = getLocationOfByte(startSpecifier + specifierLen - 1);
7463SourceLocation CheckFormatHandler::getLocationOfByte(
const char *x) {
7468void CheckFormatHandler::HandleIncompleteSpecifier(
const char *startSpecifier,
7469 unsigned specifierLen){
7470 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_incomplete_specifier),
7471 getLocationOfByte(startSpecifier),
7473 getSpecifierRange(startSpecifier, specifierLen));
7476void CheckFormatHandler::HandleInvalidLengthModifier(
7479 const char *startSpecifier,
unsigned specifierLen,
unsigned DiagID) {
7491 getSpecifierRange(startSpecifier, specifierLen));
7493 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7494 << FixedLM->toString()
7499 if (DiagID == diag::warn_format_nonsensical_length)
7505 getSpecifierRange(startSpecifier, specifierLen),
7510void CheckFormatHandler::HandleNonStandardLengthModifier(
7512 const char *startSpecifier,
unsigned specifierLen) {
7521 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7525 getSpecifierRange(startSpecifier, specifierLen));
7527 S.
Diag(getLocationOfByte(LM.
getStart()), diag::note_format_fix_specifier)
7528 << FixedLM->toString()
7532 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7536 getSpecifierRange(startSpecifier, specifierLen));
7540void CheckFormatHandler::HandleNonStandardConversionSpecifier(
7542 const char *startSpecifier,
unsigned specifierLen) {
7548 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7552 getSpecifierRange(startSpecifier, specifierLen));
7555 S.
Diag(getLocationOfByte(CS.
getStart()), diag::note_format_fix_specifier)
7556 << FixedCS->toString()
7559 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard)
7563 getSpecifierRange(startSpecifier, specifierLen));
7567void CheckFormatHandler::HandlePosition(
const char *startPos,
7570 diag::warn_format_non_standard_positional_arg,
SourceLocation()))
7571 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_non_standard_positional_arg),
7572 getLocationOfByte(startPos),
7574 getSpecifierRange(startPos, posLen));
7577void CheckFormatHandler::HandleInvalidPosition(
7578 const char *startSpecifier,
unsigned specifierLen,
7581 diag::warn_format_invalid_positional_specifier,
SourceLocation()))
7582 EmitFormatDiagnostic(
7583 S.
PDiag(diag::warn_format_invalid_positional_specifier) << (
unsigned)p,
7584 getLocationOfByte(startSpecifier),
true,
7585 getSpecifierRange(startSpecifier, specifierLen));
7588void CheckFormatHandler::HandleZeroPosition(
const char *startPos,
7592 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_zero_positional_specifier),
7593 getLocationOfByte(startPos),
7595 getSpecifierRange(startPos, posLen));
7598void CheckFormatHandler::HandleNullChar(
const char *nullCharacter) {
7601 EmitFormatDiagnostic(
7602 S.
PDiag(diag::warn_printf_format_string_contains_null_char),
7603 getLocationOfByte(nullCharacter),
true,
7604 getFormatStringRange());
7610const Expr *CheckFormatHandler::getDataArg(
unsigned i)
const {
7611 return Args[FirstDataArg + i];
7614void CheckFormatHandler::DoneProcessing() {
7617 if (HasFormatArguments()) {
7620 signed notCoveredArg = CoveredArgs.find_first();
7621 if (notCoveredArg >= 0) {
7622 assert((
unsigned)notCoveredArg < NumDataArgs);
7623 UncoveredArg.Update(notCoveredArg, OrigFormatExpr);
7625 UncoveredArg.setAllCovered();
7630void UncoveredArgHandler::Diagnose(
Sema &S,
bool IsFunctionCall,
7631 const Expr *ArgExpr) {
7632 assert(hasUncoveredArg() && !DiagnosticExprs.empty() &&
7644 for (
auto E : DiagnosticExprs)
7647 CheckFormatHandler::EmitFormatDiagnostic(
7648 S, IsFunctionCall, DiagnosticExprs[0],
7654CheckFormatHandler::HandleInvalidConversionSpecifier(
unsigned argIndex,
7656 const char *startSpec,
7657 unsigned specifierLen,
7658 const char *csStart,
7660 bool keepGoing =
true;
7661 if (argIndex < NumDataArgs) {
7664 CoveredArgs.set(argIndex);
7680 std::string CodePointStr;
7681 if (!llvm::sys::locale::isPrint(*csStart)) {
7682 llvm::UTF32 CodePoint;
7683 const llvm::UTF8 **B =
reinterpret_cast<const llvm::UTF8 **
>(&csStart);
7684 const llvm::UTF8 *E =
7685 reinterpret_cast<const llvm::UTF8 *
>(csStart + csLen);
7686 llvm::ConversionResult
Result =
7687 llvm::convertUTF8Sequence(B, E, &CodePoint, llvm::strictConversion);
7689 if (
Result != llvm::conversionOK) {
7690 unsigned char FirstChar = *csStart;
7691 CodePoint = (llvm::UTF32)FirstChar;
7694 llvm::raw_string_ostream
OS(CodePointStr);
7695 if (CodePoint < 256)
7696 OS <<
"\\x" << llvm::format(
"%02x", CodePoint);
7697 else if (CodePoint <= 0xFFFF)
7698 OS <<
"\\u" << llvm::format(
"%04x", CodePoint);
7700 OS <<
"\\U" << llvm::format(
"%08x", CodePoint);
7704 EmitFormatDiagnostic(
7705 S.
PDiag(diag::warn_format_invalid_conversion) << Specifier, Loc,
7706 true, getSpecifierRange(startSpec, specifierLen));
7712CheckFormatHandler::HandlePositionalNonpositionalArgs(
SourceLocation Loc,
7713 const char *startSpec,
7714 unsigned specifierLen) {
7715 EmitFormatDiagnostic(
7716 S.
PDiag(diag::warn_format_mix_positional_nonpositional_args),
7717 Loc,
true, getSpecifierRange(startSpec, specifierLen));
7721CheckFormatHandler::CheckNumArgs(
7724 const char *startSpecifier,
unsigned specifierLen,
unsigned argIndex) {
7726 if (HasFormatArguments() && argIndex >= NumDataArgs) {
7728 ? (S.
PDiag(diag::warn_printf_positional_arg_exceeds_data_args)
7729 << (argIndex+1) << NumDataArgs)
7730 : S.
PDiag(diag::warn_printf_insufficient_data_args);
7731 EmitFormatDiagnostic(
7732 PDiag, getLocationOfByte(CS.
getStart()),
true,
7733 getSpecifierRange(startSpecifier, specifierLen));
7737 UncoveredArg.setAllCovered();
7743template<
typename Range>
7746 bool IsStringLocation,
7749 EmitFormatDiagnostic(S, inFunctionCall, Args[FormatIdx], PDiag,
7750 Loc, IsStringLocation, StringRange, FixIt);
7780template <
typename Range>
7781void CheckFormatHandler::EmitFormatDiagnostic(
7782 Sema &S,
bool InFunctionCall,
const Expr *ArgumentExpr,
7785 if (InFunctionCall) {
7790 S.
Diag(IsStringLocation ? ArgumentExpr->
getExprLoc() : Loc, PDiag)
7794 S.
Diag(IsStringLocation ? Loc : StringRange.getBegin(),
7795 diag::note_format_string_defined);
7797 Note << StringRange;
7806class CheckPrintfHandler :
public CheckFormatHandler {
7808 CheckPrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7810 unsigned firstDataArg,
unsigned numDataArgs,
bool isObjC,
7812 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7814 llvm::SmallBitVector &CheckedVarArgs,
7815 UncoveredArgHandler &UncoveredArg)
7816 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7817 numDataArgs, beg, APK, Args, formatIdx,
7818 inFunctionCall, CallType, CheckedVarArgs,
7821 bool isObjCContext()
const {
return FSType == FormatStringType::NSString; }
7824 bool allowsObjCArg()
const {
7825 return FSType == FormatStringType::NSString ||
7826 FSType == FormatStringType::OSLog ||
7827 FSType == FormatStringType::OSTrace;
7830 bool HandleInvalidPrintfConversionSpecifier(
7831 const analyze_printf::PrintfSpecifier &FS,
7832 const char *startSpecifier,
7833 unsigned specifierLen)
override;
7835 void handleInvalidMaskType(StringRef MaskType)
override;
7837 bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7838 const char *startSpecifier,
unsigned specifierLen,
7839 const TargetInfo &
Target)
override;
7840 bool checkFormatExpr(
const analyze_printf::PrintfSpecifier &FS,
7841 const char *StartSpecifier,
7842 unsigned SpecifierLen,
7845 bool HandleAmount(
const analyze_format_string::OptionalAmount &Amt,
unsigned k,
7846 const char *startSpecifier,
unsigned specifierLen);
7847 void HandleInvalidAmount(
const analyze_printf::PrintfSpecifier &FS,
7848 const analyze_printf::OptionalAmount &Amt,
7850 const char *startSpecifier,
unsigned specifierLen);
7851 void HandleFlag(
const analyze_printf::PrintfSpecifier &FS,
7852 const analyze_printf::OptionalFlag &flag,
7853 const char *startSpecifier,
unsigned specifierLen);
7854 void HandleIgnoredFlag(
const analyze_printf::PrintfSpecifier &FS,
7855 const analyze_printf::OptionalFlag &ignoredFlag,
7856 const analyze_printf::OptionalFlag &flag,
7857 const char *startSpecifier,
unsigned specifierLen);
7858 bool checkForCStrMembers(
const analyze_printf::ArgType &AT,
7861 void HandleEmptyObjCModifierFlag(
const char *startFlag,
7862 unsigned flagLen)
override;
7864 void HandleInvalidObjCModifierFlag(
const char *startFlag,
7865 unsigned flagLen)
override;
7868 HandleObjCFlagsWithNonObjCConversion(
const char *flagsStart,
7869 const char *flagsEnd,
7870 const char *conversionPosition)
override;
7875class EquatableFormatArgument {
7877 enum SpecifierSensitivity :
unsigned {
7884 enum FormatArgumentRole :
unsigned {
7892 analyze_format_string::ArgType ArgType;
7894 StringRef SpecifierLetter;
7895 CharSourceRange
Range;
7896 SourceLocation ElementLoc;
7897 FormatArgumentRole
Role : 2;
7898 SpecifierSensitivity Sensitivity : 2;
7899 unsigned Position : 14;
7900 unsigned ModifierFor : 14;
7902 void EmitDiagnostic(Sema &S, PartialDiagnostic PDiag,
const Expr *FmtExpr,
7903 bool InFunctionCall)
const;
7906 EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
7908 StringRef SpecifierLetter,
7909 analyze_format_string::ArgType ArgType,
7910 FormatArgumentRole
Role,
7911 SpecifierSensitivity Sensitivity,
unsigned Position,
7912 unsigned ModifierFor)
7913 : ArgType(ArgType), LengthMod(LengthMod),
7914 SpecifierLetter(SpecifierLetter),
Range(
Range), ElementLoc(ElementLoc),
7915 Role(
Role), Sensitivity(Sensitivity), Position(Position),
7916 ModifierFor(ModifierFor) {}
7918 unsigned getPosition()
const {
return Position; }
7919 SourceLocation getSourceLocation()
const {
return ElementLoc; }
7921 analyze_format_string::LengthModifier getLengthModifier()
const {
7922 return analyze_format_string::LengthModifier(
nullptr, LengthMod);
7924 void setModifierFor(
unsigned V) { ModifierFor =
V; }
7926 std::string buildFormatSpecifier()
const {
7928 llvm::raw_string_ostream(result)
7929 << getLengthModifier().toString() << SpecifierLetter;
7933 bool VerifyCompatible(Sema &S,
const EquatableFormatArgument &
Other,
7934 const Expr *FmtExpr,
bool InFunctionCall)
const;
7938class DecomposePrintfHandler :
public CheckPrintfHandler {
7939 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs;
7942 DecomposePrintfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
7943 const Expr *origFormatExpr,
7945 unsigned numDataArgs,
bool isObjC,
const char *beg,
7947 ArrayRef<const Expr *> Args,
unsigned formatIdx,
7949 llvm::SmallBitVector &CheckedVarArgs,
7950 UncoveredArgHandler &UncoveredArg,
7951 llvm::SmallVectorImpl<EquatableFormatArgument> &Specs)
7952 : CheckPrintfHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
7953 numDataArgs,
isObjC, beg, APK, Args, formatIdx,
7954 inFunctionCall, CallType, CheckedVarArgs,
7956 Specs(Specs), HadError(
false) {}
7960 GetSpecifiers(Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
7962 llvm::SmallVectorImpl<EquatableFormatArgument> &Args);
7964 virtual bool HandlePrintfSpecifier(
const analyze_printf::PrintfSpecifier &FS,
7965 const char *startSpecifier,
7966 unsigned specifierLen,
7967 const TargetInfo &
Target)
override;
7972bool CheckPrintfHandler::HandleInvalidPrintfConversionSpecifier(
7974 unsigned specifierLen) {
7978 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
7980 startSpecifier, specifierLen,
7984void CheckPrintfHandler::handleInvalidMaskType(StringRef MaskType) {
7985 S.
Diag(getLocationOfByte(MaskType.data()), diag::err_invalid_mask_type_size);
7993 return T->isRecordType() ||
T->isComplexType();
7996bool CheckPrintfHandler::HandleAmount(
7998 const char *startSpecifier,
unsigned specifierLen) {
8000 if (HasFormatArguments()) {
8002 if (argIndex >= NumDataArgs) {
8003 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_asterisk_missing_arg)
8007 getSpecifierRange(startSpecifier, specifierLen));
8017 CoveredArgs.set(argIndex);
8018 const Expr *Arg = getDataArg(argIndex);
8029 ? diag::err_printf_asterisk_wrong_type
8030 : diag::warn_printf_asterisk_wrong_type;
8031 EmitFormatDiagnostic(S.
PDiag(DiagID)
8036 getSpecifierRange(startSpecifier, specifierLen));
8046void CheckPrintfHandler::HandleInvalidAmount(
8050 const char *startSpecifier,
8051 unsigned specifierLen) {
8061 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_optional_amount)
8065 getSpecifierRange(startSpecifier, specifierLen),
8071 const char *startSpecifier,
8072 unsigned specifierLen) {
8076 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_nonsensical_flag)
8080 getSpecifierRange(startSpecifier, specifierLen),
8085void CheckPrintfHandler::HandleIgnoredFlag(
8089 const char *startSpecifier,
8090 unsigned specifierLen) {
8092 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_ignored_flag)
8096 getSpecifierRange(startSpecifier, specifierLen),
8098 getSpecifierRange(ignoredFlag.
getPosition(), 1)));
8101void CheckPrintfHandler::HandleEmptyObjCModifierFlag(
const char *startFlag,
8104 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_empty_objc_flag),
8105 getLocationOfByte(startFlag),
8107 getSpecifierRange(startFlag, flagLen));
8110void CheckPrintfHandler::HandleInvalidObjCModifierFlag(
const char *startFlag,
8113 auto Range = getSpecifierRange(startFlag, flagLen);
8114 StringRef flag(startFlag, flagLen);
8115 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_invalid_objc_flag) << flag,
8116 getLocationOfByte(startFlag),
8121void CheckPrintfHandler::HandleObjCFlagsWithNonObjCConversion(
8122 const char *flagsStart,
const char *flagsEnd,
const char *conversionPosition) {
8124 auto Range = getSpecifierRange(flagsStart, flagsEnd - flagsStart + 1);
8125 auto diag = diag::warn_printf_ObjCflags_without_ObjCConversion;
8126 EmitFormatDiagnostic(S.
PDiag(
diag) << StringRef(conversionPosition, 1),
8127 getLocationOfByte(conversionPosition),
8133 const Expr *FmtExpr,
8134 bool InFunctionCall)
const {
8135 CheckFormatHandler::EmitFormatDiagnostic(S, InFunctionCall, FmtExpr, PDiag,
8136 ElementLoc,
true, Range);
8139bool EquatableFormatArgument::VerifyCompatible(
8140 Sema &S,
const EquatableFormatArgument &
Other,
const Expr *FmtExpr,
8141 bool InFunctionCall)
const {
8146 S, S.
PDiag(diag::warn_format_cmp_role_mismatch) <<
Role <<
Other.Role,
8147 FmtExpr, InFunctionCall);
8148 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8152 if (
Role != FAR_Data) {
8153 if (ModifierFor !=
Other.ModifierFor) {
8156 S.
PDiag(diag::warn_format_cmp_modifierfor_mismatch)
8157 << (ModifierFor + 1) << (
Other.ModifierFor + 1),
8158 FmtExpr, InFunctionCall);
8159 S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with) << 0 <<
Other.Range;
8165 bool HadError =
false;
8166 if (Sensitivity !=
Other.Sensitivity) {
8169 S.
PDiag(diag::warn_format_cmp_sensitivity_mismatch)
8170 << Sensitivity <<
Other.Sensitivity,
8171 FmtExpr, InFunctionCall);
8172 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8173 << 0 <<
Other.Range;
8176 switch (ArgType.matchesArgType(S.
Context,
Other.ArgType)) {
8180 case MK::MatchPromotion:
8184 case MK::NoMatchTypeConfusion:
8185 case MK::NoMatchPromotionTypeConfusion:
8187 S.
PDiag(diag::warn_format_cmp_specifier_mismatch)
8188 << buildFormatSpecifier()
8189 <<
Other.buildFormatSpecifier(),
8190 FmtExpr, InFunctionCall);
8191 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8192 << 0 <<
Other.Range;
8195 case MK::NoMatchPedantic:
8197 S.
PDiag(diag::warn_format_cmp_specifier_mismatch_pedantic)
8198 << buildFormatSpecifier()
8199 <<
Other.buildFormatSpecifier(),
8200 FmtExpr, InFunctionCall);
8201 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8202 << 0 <<
Other.Range;
8205 case MK::NoMatchSignedness:
8207 S.
PDiag(diag::warn_format_cmp_specifier_sign_mismatch)
8208 << buildFormatSpecifier()
8209 <<
Other.buildFormatSpecifier(),
8210 FmtExpr, InFunctionCall);
8211 HadError = S.
Diag(
Other.ElementLoc, diag::note_format_cmp_with)
8212 << 0 <<
Other.Range;
8218bool DecomposePrintfHandler::GetSpecifiers(
8219 Sema &S,
const FormatStringLiteral *FSL,
const Expr *FmtExpr,
8222 StringRef
Data = FSL->getString();
8223 const char *Str =
Data.data();
8224 llvm::SmallBitVector BV;
8225 UncoveredArgHandler UA;
8226 const Expr *PrintfArgs[] = {FSL->getFormatString()};
8227 DecomposePrintfHandler H(S, FSL, FSL->getFormatString(),
Type, 0, 0, IsObjC,
8239 llvm::stable_sort(Args, [](
const EquatableFormatArgument &A,
8240 const EquatableFormatArgument &B) {
8241 return A.getPosition() < B.getPosition();
8246bool DecomposePrintfHandler::HandlePrintfSpecifier(
8249 if (!CheckPrintfHandler::HandlePrintfSpecifier(FS, startSpecifier,
8264 const unsigned Unset = ~0;
8265 unsigned FieldWidthIndex = Unset;
8266 unsigned PrecisionIndex = Unset;
8270 if (!FieldWidth.isInvalid() && FieldWidth.hasDataArgument()) {
8271 FieldWidthIndex = Specs.size();
8272 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8273 getLocationOfByte(FieldWidth.getStart()),
8275 FieldWidth.getArgType(S.
Context),
8276 EquatableFormatArgument::FAR_FieldWidth,
8277 EquatableFormatArgument::SS_None,
8278 FieldWidth.usesPositionalArg()
8279 ? FieldWidth.getPositionalArgIndex() - 1
8285 if (!Precision.isInvalid() && Precision.hasDataArgument()) {
8286 PrecisionIndex = Specs.size();
8288 getSpecifierRange(startSpecifier, specifierLen),
8289 getLocationOfByte(Precision.getStart()),
8291 Precision.getArgType(S.
Context), EquatableFormatArgument::FAR_Precision,
8292 EquatableFormatArgument::SS_None,
8293 Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
8299 unsigned SpecIndex =
8301 if (FieldWidthIndex != Unset)
8302 Specs[FieldWidthIndex].setModifierFor(SpecIndex);
8303 if (PrecisionIndex != Unset)
8304 Specs[PrecisionIndex].setModifierFor(SpecIndex);
8306 EquatableFormatArgument::SpecifierSensitivity Sensitivity;
8308 Sensitivity = EquatableFormatArgument::SS_Private;
8310 Sensitivity = EquatableFormatArgument::SS_Public;
8312 Sensitivity = EquatableFormatArgument::SS_Sensitive;
8314 Sensitivity = EquatableFormatArgument::SS_None;
8317 getSpecifierRange(startSpecifier, specifierLen),
8320 EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
8325 Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
8330 EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
8331 SpecIndex + 1, SpecIndex);
8339template<
typename MemberKind>
8357 if (MemberKind *FK = dyn_cast<MemberKind>(
decl))
8372 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8374 if ((*MI)->getMinRequiredArguments() == 0)
8382bool CheckPrintfHandler::checkForCStrMembers(
8389 for (MethodSet::iterator MI = Results.begin(), ME = Results.end();
8392 if (
Method->getMinRequiredArguments() == 0 &&
8405bool CheckPrintfHandler::HandlePrintfSpecifier(
8419 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.getStart()),
8420 startSpecifier, specifierLen);
8428 startSpecifier, specifierLen)) {
8433 startSpecifier, specifierLen)) {
8437 if (!CS.consumesDataArgument()) {
8445 if (argIndex < NumDataArgs) {
8449 CoveredArgs.set(argIndex);
8456 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex + 1))
8459 if (HasFormatArguments()) {
8461 CoveredArgs.set(argIndex + 1);
8464 const Expr *Ex = getDataArg(argIndex);
8468 : ArgType::CPointerTy;
8470 EmitFormatDiagnostic(
8471 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8475 getSpecifierRange(startSpecifier, specifierLen));
8478 Ex = getDataArg(argIndex + 1);
8481 EmitFormatDiagnostic(
8482 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
8486 getSpecifierRange(startSpecifier, specifierLen));
8493 if (!allowsObjCArg() && CS.isObjCArg()) {
8494 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8501 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8508 EmitFormatDiagnostic(S.
PDiag(diag::warn_os_log_format_narg),
8509 getLocationOfByte(CS.getStart()),
8511 getSpecifierRange(startSpecifier, specifierLen));
8521 return HandleInvalidPrintfConversionSpecifier(FS, startSpecifier,
8528 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8532 getSpecifierRange(startSpecifier, specifierLen));
8535 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_invalid_annotation)
8539 getSpecifierRange(startSpecifier, specifierLen));
8543 const llvm::Triple &Triple =
Target.getTriple();
8545 (Triple.isAndroid() || Triple.isOSFuchsia())) {
8546 EmitFormatDiagnostic(S.
PDiag(diag::warn_printf_narg_not_supported),
8547 getLocationOfByte(CS.getStart()),
8549 getSpecifierRange(startSpecifier, specifierLen));
8555 startSpecifier, specifierLen);
8561 startSpecifier, specifierLen);
8567 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_no_precision),
8568 getLocationOfByte(startSpecifier),
8570 getSpecifierRange(startSpecifier, specifierLen));
8579 HandleFlag(FS, FS.
hasPlusPrefix(), startSpecifier, specifierLen);
8581 HandleFlag(FS, FS.
hasSpacePrefix(), startSpecifier, specifierLen);
8590 startSpecifier, specifierLen);
8593 startSpecifier, specifierLen);
8598 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8599 diag::warn_format_nonsensical_length);
8601 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
8603 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
8604 diag::warn_format_non_standard_conversion_spec);
8607 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
8610 if (!HasFormatArguments())
8613 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
8616 const Expr *Arg = getDataArg(argIndex);
8620 return checkFormatExpr(FS, startSpecifier, specifierLen, Arg);
8632 case Stmt::ArraySubscriptExprClass:
8633 case Stmt::CallExprClass:
8634 case Stmt::CharacterLiteralClass:
8635 case Stmt::CXXBoolLiteralExprClass:
8636 case Stmt::DeclRefExprClass:
8637 case Stmt::FloatingLiteralClass:
8638 case Stmt::IntegerLiteralClass:
8639 case Stmt::MemberExprClass:
8640 case Stmt::ObjCArrayLiteralClass:
8641 case Stmt::ObjCBoolLiteralExprClass:
8642 case Stmt::ObjCBoxedExprClass:
8643 case Stmt::ObjCDictionaryLiteralClass:
8644 case Stmt::ObjCEncodeExprClass:
8645 case Stmt::ObjCIvarRefExprClass:
8646 case Stmt::ObjCMessageExprClass:
8647 case Stmt::ObjCPropertyRefExprClass:
8648 case Stmt::ObjCStringLiteralClass:
8649 case Stmt::ObjCSubscriptRefExprClass:
8650 case Stmt::ParenExprClass:
8651 case Stmt::StringLiteralClass:
8652 case Stmt::UnaryOperatorClass:
8659static std::pair<QualType, StringRef>
8666 StringRef Name = UserTy->getDecl()->getName();
8667 QualType CastTy = llvm::StringSwitch<QualType>(Name)
8668 .Case(
"CFIndex", Context.getNSIntegerType())
8669 .Case(
"NSInteger", Context.getNSIntegerType())
8670 .Case(
"NSUInteger", Context.getNSUIntegerType())
8671 .Case(
"SInt32", Context.IntTy)
8672 .Case(
"UInt32", Context.UnsignedIntTy)
8676 return std::make_pair(CastTy, Name);
8678 TyTy = UserTy->desugar();
8682 if (
const ParenExpr *PE = dyn_cast<ParenExpr>(E))
8684 PE->getSubExpr()->getType(),
8693 StringRef TrueName, FalseName;
8695 std::tie(TrueTy, TrueName) =
8697 CO->getTrueExpr()->getType(),
8699 std::tie(FalseTy, FalseName) =
8701 CO->getFalseExpr()->getType(),
8702 CO->getFalseExpr());
8704 if (TrueTy == FalseTy)
8705 return std::make_pair(TrueTy, TrueName);
8706 else if (TrueTy.
isNull())
8707 return std::make_pair(FalseTy, FalseName);
8708 else if (FalseTy.
isNull())
8709 return std::make_pair(TrueTy, TrueName);
8712 return std::make_pair(
QualType(), StringRef());
8731 From = VecTy->getElementType();
8733 To = VecTy->getElementType();
8744 diag::warn_format_conversion_argument_type_mismatch_signedness,
8748 diag::warn_format_conversion_argument_type_mismatch, Loc)) {
8757 const char *StartSpecifier,
8758 unsigned SpecifierLen,
8770 while (
const TypeOfExprType *TET = dyn_cast<TypeOfExprType>(ExprTy)) {
8771 ExprTy = TET->getUnderlyingExpr()->getType();
8786 getSpecifierRange(StartSpecifier, SpecifierLen);
8788 llvm::raw_svector_ostream os(FSString);
8790 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_bool_as_character)
8801 getSpecifierRange(StartSpecifier, SpecifierLen);
8802 EmitFormatDiagnostic(S.
PDiag(diag::warn_format_P_with_objc_pointer),
8812 if (
Match == ArgType::Match)
8816 assert(
Match != ArgType::NoMatchPromotionTypeConfusion);
8825 E = ICE->getSubExpr();
8835 if (OrigMatch == ArgType::NoMatchSignedness &&
8836 ImplicitMatch != ArgType::NoMatchSignedness)
8843 if (ImplicitMatch == ArgType::Match)
8861 if (
Match == ArgType::MatchPromotion)
8865 if (
Match == ArgType::MatchPromotion) {
8869 ImplicitMatch != ArgType::NoMatchPromotionTypeConfusion &&
8870 ImplicitMatch != ArgType::NoMatchTypeConfusion)
8874 if (ImplicitMatch == ArgType::NoMatchPedantic ||
8875 ImplicitMatch == ArgType::NoMatchTypeConfusion)
8876 Match = ImplicitMatch;
8877 assert(
Match != ArgType::MatchPromotion);
8880 bool IsEnum =
false;
8881 bool IsScopedEnum =
false;
8884 IntendedTy = ED->getIntegerType();
8885 if (!ED->isScoped()) {
8886 ExprTy = IntendedTy;
8891 IsScopedEnum =
true;
8898 if (isObjCContext() &&
8909 const llvm::APInt &
V = IL->getValue();
8919 if (TD->getUnderlyingType() == IntendedTy)
8929 bool ShouldNotPrintDirectly =
false; StringRef CastTyName;
8937 if (!IsScopedEnum &&
8938 (CastTyName ==
"NSInteger" || CastTyName ==
"NSUInteger") &&
8942 IntendedTy = CastTy;
8943 ShouldNotPrintDirectly =
true;
8948 PrintfSpecifier fixedFS = FS;
8955 llvm::raw_svector_ostream os(buf);
8958 CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
8960 if (IntendedTy == ExprTy && !ShouldNotPrintDirectly && !IsScopedEnum) {
8966 llvm_unreachable(
"expected non-matching");
8968 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
8971 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
8974 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
8977 Diag = diag::warn_format_conversion_argument_type_mismatch;
8998 llvm::raw_svector_ostream CastFix(CastBuf);
8999 CastFix << (S.
LangOpts.CPlusPlus ?
"static_cast<" :
"(");
9001 CastFix << (S.
LangOpts.CPlusPlus ?
">" :
")");
9007 if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
9012 SourceRange CastRange(CCast->getLParenLoc(), CCast->getRParenLoc());
9034 if (ShouldNotPrintDirectly && !IsScopedEnum) {
9040 Name = TypedefTy->getDecl()->getName();
9044 ? diag::warn_format_argument_needs_cast_pedantic
9045 : diag::warn_format_argument_needs_cast;
9046 EmitFormatDiagnostic(S.
PDiag(
Diag) << Name << IntendedTy << IsEnum
9057 ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9058 : diag::warn_format_conversion_argument_type_mismatch;
9060 EmitFormatDiagnostic(
9072 bool EmitTypeMismatch =
false;
9081 llvm_unreachable(
"expected non-matching");
9083 Diag = diag::warn_format_conversion_argument_type_mismatch_signedness;
9086 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
9089 Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
9093 ? diag::err_format_conversion_argument_type_mismatch
9094 : diag::warn_format_conversion_argument_type_mismatch;
9098 EmitFormatDiagnostic(
9107 EmitTypeMismatch =
true;
9109 EmitFormatDiagnostic(
9110 S.
PDiag(diag::warn_non_pod_vararg_with_format_string)
9111 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9115 checkForCStrMembers(AT, E);
9121 EmitTypeMismatch =
true;
9123 EmitFormatDiagnostic(
9124 S.
PDiag(diag::err_cannot_pass_objc_interface_to_vararg_format)
9125 << S.
getLangOpts().CPlusPlus11 << ExprTy << CallType
9138 if (EmitTypeMismatch) {
9144 EmitFormatDiagnostic(
9145 S.
PDiag(diag::warn_format_conversion_argument_type_mismatch)
9151 assert(FirstDataArg + FS.
getArgIndex() < CheckedVarArgs.size() &&
9152 "format string specifier index out of range");
9153 CheckedVarArgs[FirstDataArg + FS.
getArgIndex()] =
true;
9163class CheckScanfHandler :
public CheckFormatHandler {
9165 CheckScanfHandler(Sema &
s,
const FormatStringLiteral *fexpr,
9167 unsigned firstDataArg,
unsigned numDataArgs,
9169 ArrayRef<const Expr *> Args,
unsigned formatIdx,
9171 llvm::SmallBitVector &CheckedVarArgs,
9172 UncoveredArgHandler &UncoveredArg)
9173 : CheckFormatHandler(
s, fexpr, origFormatExpr,
type, firstDataArg,
9174 numDataArgs, beg, APK, Args, formatIdx,
9175 inFunctionCall, CallType, CheckedVarArgs,
9178 bool HandleScanfSpecifier(
const analyze_scanf::ScanfSpecifier &FS,
9179 const char *startSpecifier,
9180 unsigned specifierLen)
override;
9182 bool HandleInvalidScanfConversionSpecifier(
9183 const analyze_scanf::ScanfSpecifier &FS,
9184 const char *startSpecifier,
9185 unsigned specifierLen)
override;
9187 void HandleIncompleteScanList(
const char *start,
const char *end)
override;
9192void CheckScanfHandler::HandleIncompleteScanList(
const char *start,
9194 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_scanlist_incomplete),
9195 getLocationOfByte(end),
true,
9196 getSpecifierRange(start, end - start));
9199bool CheckScanfHandler::HandleInvalidScanfConversionSpecifier(
9201 const char *startSpecifier,
9202 unsigned specifierLen) {
9206 return HandleInvalidConversionSpecifier(FS.
getArgIndex(),
9208 startSpecifier, specifierLen,
9212bool CheckScanfHandler::HandleScanfSpecifier(
9214 const char *startSpecifier,
9215 unsigned specifierLen) {
9229 HandlePositionalNonpositionalArgs(getLocationOfByte(CS.
getStart()),
9230 startSpecifier, specifierLen);
9241 EmitFormatDiagnostic(S.
PDiag(diag::warn_scanf_nonzero_width),
9256 if (argIndex < NumDataArgs) {
9260 CoveredArgs.set(argIndex);
9266 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9267 diag::warn_format_nonsensical_length);
9269 HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
9271 HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
9272 diag::warn_format_non_standard_conversion_spec);
9275 HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
9278 if (!HasFormatArguments())
9281 if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))
9285 const Expr *Ex = getDataArg(argIndex);
9303 ScanfSpecifier fixedFS = FS;
9308 Pedantic ? diag::warn_format_conversion_argument_type_mismatch_pedantic
9310 ? diag::warn_format_conversion_argument_type_mismatch_signedness
9311 : diag::warn_format_conversion_argument_type_mismatch;
9316 llvm::raw_svector_ostream os(buf);
9319 EmitFormatDiagnostic(
9324 getSpecifierRange(startSpecifier, specifierLen),
9326 getSpecifierRange(startSpecifier, specifierLen), os.str()));
9333 getSpecifierRange(startSpecifier, specifierLen));
9343 const Expr *FmtExpr,
bool InFunctionCall) {
9344 bool HadError =
false;
9345 auto FmtIter = FmtArgs.begin(), FmtEnd = FmtArgs.end();
9346 auto RefIter = RefArgs.begin(), RefEnd = RefArgs.end();
9347 while (FmtIter < FmtEnd && RefIter < RefEnd) {
9359 for (; FmtIter < FmtEnd; ++FmtIter) {
9363 if (FmtIter->getPosition() < RefIter->getPosition())
9367 if (FmtIter->getPosition() > RefIter->getPosition())
9371 !FmtIter->VerifyCompatible(S, *RefIter, FmtExpr, InFunctionCall);
9375 RefIter = std::find_if(RefIter + 1, RefEnd, [=](
const auto &Arg) {
9376 return Arg.getPosition() != RefIter->getPosition();
9380 if (FmtIter < FmtEnd) {
9381 CheckFormatHandler::EmitFormatDiagnostic(
9382 S, InFunctionCall, FmtExpr,
9383 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 1,
9384 FmtExpr->
getBeginLoc(),
false, FmtIter->getSourceRange());
9385 HadError = S.
Diag(Ref->
getBeginLoc(), diag::note_format_cmp_with) << 1;
9386 }
else if (RefIter < RefEnd) {
9387 CheckFormatHandler::EmitFormatDiagnostic(
9388 S, InFunctionCall, FmtExpr,
9389 S.
PDiag(diag::warn_format_cmp_specifier_arity) << 0,
9392 << 1 << RefIter->getSourceRange();
9398 Sema &S,
const FormatStringLiteral *FExpr,
9403 llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg,
9404 bool IgnoreStringsWithoutSpecifiers) {
9406 if (!FExpr->isAscii() && !FExpr->isUTF8()) {
9407 CheckFormatHandler::EmitFormatDiagnostic(
9408 S, inFunctionCall, Args[format_idx],
9409 S.
PDiag(diag::warn_format_string_is_wide_literal), FExpr->getBeginLoc(),
9415 StringRef StrRef = FExpr->getString();
9416 const char *Str = StrRef.data();
9420 assert(
T &&
"String literal not of constant array type!");
9421 size_t TypeSize =
T->getZExtSize();
9422 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9423 const unsigned numDataArgs = Args.size() - firstDataArg;
9425 if (IgnoreStringsWithoutSpecifiers &&
9432 if (TypeSize <= StrRef.size() && !StrRef.substr(0, TypeSize).contains(
'\0')) {
9433 CheckFormatHandler::EmitFormatDiagnostic(
9434 S, inFunctionCall, Args[format_idx],
9435 S.
PDiag(diag::warn_printf_format_string_not_null_terminated),
9436 FExpr->getBeginLoc(),
9442 if (StrLen == 0 && numDataArgs > 0) {
9443 CheckFormatHandler::EmitFormatDiagnostic(
9444 S, inFunctionCall, Args[format_idx],
9445 S.
PDiag(diag::warn_empty_format_string), FExpr->getBeginLoc(),
9456 if (ReferenceFormatString ==
nullptr) {
9457 CheckPrintfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9458 numDataArgs, IsObjC, Str, APK, Args, format_idx,
9459 inFunctionCall, CallType, CheckedVarArgs,
9469 Type, ReferenceFormatString, FExpr->getFormatString(),
9470 inFunctionCall ?
nullptr : Args[format_idx]);
9473 CheckScanfHandler H(S, FExpr, OrigFormatExpr,
Type, firstDataArg,
9474 numDataArgs, Str, APK, Args, format_idx, inFunctionCall,
9475 CallType, CheckedVarArgs, UncoveredArg);
9495 FormatStringLiteral RefLit = AuthoritativeFormatString;
9496 FormatStringLiteral TestLit = TestedFormatString;
9498 bool DiagAtStringLiteral;
9499 if (FunctionCallArg) {
9500 Arg = FunctionCallArg;
9501 DiagAtStringLiteral =
false;
9503 Arg = TestedFormatString;
9504 DiagAtStringLiteral =
true;
9506 if (DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit,
9507 AuthoritativeFormatString,
Type,
9508 IsObjC,
true, RefArgs) &&
9509 DecomposePrintfHandler::GetSpecifiers(*
this, &TestLit, Arg,
Type, IsObjC,
9510 DiagAtStringLiteral, FmtArgs)) {
9512 TestedFormatString, FmtArgs, Arg,
9513 DiagAtStringLiteral);
9526 FormatStringLiteral RefLit = Str;
9530 if (!DecomposePrintfHandler::GetSpecifiers(*
this, &RefLit, Str,
Type, IsObjC,
9539 bool HadError =
false;
9540 auto Iter = Args.begin();
9541 auto End = Args.end();
9542 while (Iter != End) {
9543 const auto &FirstInGroup = *Iter;
9545 Iter != End && Iter->getPosition() == FirstInGroup.getPosition();
9547 HadError |= !Iter->VerifyCompatible(*
this, FirstInGroup, Str,
true);
9556 const char *Str = StrRef.data();
9559 assert(
T &&
"String literal not of constant array type!");
9560 size_t TypeSize =
T->getZExtSize();
9561 size_t StrLen = std::min(std::max(TypeSize,
size_t(1)) - 1, StrRef.size());
9572 switch (AbsFunction) {
9576 case Builtin::BI__builtin_abs:
9577 return Builtin::BI__builtin_labs;
9578 case Builtin::BI__builtin_labs:
9579 return Builtin::BI__builtin_llabs;
9580 case Builtin::BI__builtin_llabs:
9583 case Builtin::BI__builtin_fabsf:
9584 return Builtin::BI__builtin_fabs;
9585 case Builtin::BI__builtin_fabs:
9586 return Builtin::BI__builtin_fabsl;
9587 case Builtin::BI__builtin_fabsl:
9590 case Builtin::BI__builtin_cabsf:
9591 return Builtin::BI__builtin_cabs;
9592 case Builtin::BI__builtin_cabs:
9593 return Builtin::BI__builtin_cabsl;
9594 case Builtin::BI__builtin_cabsl:
9597 case Builtin::BIabs:
9598 return Builtin::BIlabs;
9599 case Builtin::BIlabs:
9600 return Builtin::BIllabs;
9601 case Builtin::BIllabs:
9604 case Builtin::BIfabsf:
9605 return Builtin::BIfabs;
9606 case Builtin::BIfabs:
9607 return Builtin::BIfabsl;
9608 case Builtin::BIfabsl:
9611 case Builtin::BIcabsf:
9612 return Builtin::BIcabs;
9613 case Builtin::BIcabs:
9614 return Builtin::BIcabsl;
9615 case Builtin::BIcabsl:
9644 unsigned AbsFunctionKind) {
9645 unsigned BestKind = 0;
9646 uint64_t ArgSize = Context.getTypeSize(ArgType);
9647 for (
unsigned Kind = AbsFunctionKind; Kind != 0;
9650 if (Context.getTypeSize(ParamType) >= ArgSize) {
9653 else if (Context.hasSameType(ParamType, ArgType)) {
9669 if (
T->isIntegralOrEnumerationType())
9671 if (
T->isRealFloatingType())
9673 if (
T->isAnyComplexType())
9676 llvm_unreachable(
"Type not integer, floating, or complex");
9683 switch (ValueKind) {
9688 case Builtin::BI__builtin_fabsf:
9689 case Builtin::BI__builtin_fabs:
9690 case Builtin::BI__builtin_fabsl:
9691 case Builtin::BI__builtin_cabsf:
9692 case Builtin::BI__builtin_cabs:
9693 case Builtin::BI__builtin_cabsl:
9694 return Builtin::BI__builtin_abs;
9695 case Builtin::BIfabsf:
9696 case Builtin::BIfabs:
9697 case Builtin::BIfabsl:
9698 case Builtin::BIcabsf:
9699 case Builtin::BIcabs:
9700 case Builtin::BIcabsl:
9701 return Builtin::BIabs;
9707 case Builtin::BI__builtin_abs:
9708 case Builtin::BI__builtin_labs:
9709 case Builtin::BI__builtin_llabs:
9710 case Builtin::BI__builtin_cabsf:
9711 case Builtin::BI__builtin_cabs:
9712 case Builtin::BI__builtin_cabsl:
9713 return Builtin::BI__builtin_fabsf;
9714 case Builtin::BIabs:
9715 case Builtin::BIlabs:
9716 case Builtin::BIllabs:
9717 case Builtin::BIcabsf:
9718 case Builtin::BIcabs:
9719 case Builtin::BIcabsl:
9720 return Builtin::BIfabsf;
9726 case Builtin::BI__builtin_abs:
9727 case Builtin::BI__builtin_labs:
9728 case Builtin::BI__builtin_llabs:
9729 case Builtin::BI__builtin_fabsf:
9730 case Builtin::BI__builtin_fabs:
9731 case Builtin::BI__builtin_fabsl:
9732 return Builtin::BI__builtin_cabsf;
9733 case Builtin::BIabs:
9734 case Builtin::BIlabs:
9735 case Builtin::BIllabs:
9736 case Builtin::BIfabsf:
9737 case Builtin::BIfabs:
9738 case Builtin::BIfabsl:
9739 return Builtin::BIcabsf;
9742 llvm_unreachable(
"Unable to convert function");
9753 case Builtin::BI__builtin_abs:
9754 case Builtin::BI__builtin_fabs:
9755 case Builtin::BI__builtin_fabsf:
9756 case Builtin::BI__builtin_fabsl:
9757 case Builtin::BI__builtin_labs:
9758 case Builtin::BI__builtin_llabs:
9759 case Builtin::BI__builtin_cabs:
9760 case Builtin::BI__builtin_cabsf:
9761 case Builtin::BI__builtin_cabsl:
9762 case Builtin::BIabs:
9763 case Builtin::BIlabs:
9764 case Builtin::BIllabs:
9765 case Builtin::BIfabs:
9766 case Builtin::BIfabsf:
9767 case Builtin::BIfabsl:
9768 case Builtin::BIcabs:
9769 case Builtin::BIcabsf:
9770 case Builtin::BIcabsl:
9773 llvm_unreachable(
"Unknown Builtin type");
9779 unsigned AbsKind,
QualType ArgType) {
9780 bool EmitHeaderHint =
true;
9781 const char *HeaderName =
nullptr;
9782 std::string FunctionName;
9783 if (S.
getLangOpts().CPlusPlus && !ArgType->isAnyComplexType()) {
9784 FunctionName =
"std::abs";
9785 if (ArgType->isIntegralOrEnumerationType()) {
9786 HeaderName =
"cstdlib";
9787 }
else if (ArgType->isRealFloatingType()) {
9788 HeaderName =
"cmath";
9790 llvm_unreachable(
"Invalid Type");
9799 for (
const auto *I : R) {
9802 FDecl = dyn_cast<FunctionDecl>(UsingD->getTargetDecl());
9804 FDecl = dyn_cast<FunctionDecl>(I);
9819 EmitHeaderHint =
false;
9837 EmitHeaderHint =
false;
9841 }
else if (!R.
empty()) {
9847 S.
Diag(Loc, diag::note_replace_abs_function)
9853 if (!EmitHeaderHint)
9856 S.
Diag(Loc, diag::note_include_header_or_declare) << HeaderName
9860template <std::
size_t StrLen>
9862 const char (&Str)[StrLen]) {
9875 auto MatchesAny = [&](std::initializer_list<llvm::StringRef> names) {
9876 return llvm::is_contained(names, calleeName);
9881 return MatchesAny({
"__builtin_nan",
"__builtin_nanf",
"__builtin_nanl",
9882 "__builtin_nanf16",
"__builtin_nanf128"});
9884 return MatchesAny({
"__builtin_inf",
"__builtin_inff",
"__builtin_infl",
9885 "__builtin_inff16",
"__builtin_inff128"});
9887 llvm_unreachable(
"unknown MathCheck");
9891 if (FDecl->
getName() !=
"infinity")
9894 if (
const CXXMethodDecl *MDecl = dyn_cast<CXXMethodDecl>(FDecl)) {
9896 if (RDecl->
getName() !=
"numeric_limits")
9913 if (FPO.getNoHonorNaNs() &&
9916 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9917 << 1 << 0 <<
Call->getSourceRange();
9921 if (FPO.getNoHonorInfs() &&
9925 Diag(
Call->getBeginLoc(), diag::warn_fp_nan_inf_when_disabled)
9926 << 0 << 0 <<
Call->getSourceRange();
9930void Sema::CheckAbsoluteValueFunction(
const CallExpr *
Call,
9932 if (
Call->getNumArgs() != 1)
9937 if (AbsKind == 0 && !IsStdAbs)
9940 QualType ArgType =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
9941 QualType ParamType =
Call->getArg(0)->getType();
9946 std::string FunctionName =
9947 IsStdAbs ?
"std::abs" :
Context.BuiltinInfo.getName(AbsKind);
9948 Diag(
Call->getExprLoc(), diag::warn_unsigned_abs) << ArgType << ParamType;
9949 Diag(
Call->getExprLoc(), diag::note_remove_abs)
9978 if (ArgValueKind == ParamValueKind) {
9979 if (
Context.getTypeSize(ArgType) <=
Context.getTypeSize(ParamType))
9983 Diag(
Call->getExprLoc(), diag::warn_abs_too_small)
9984 << FDecl << ArgType << ParamType;
9986 if (NewAbsKind == 0)
9990 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
9999 if (NewAbsKind == 0)
10002 Diag(
Call->getExprLoc(), diag::warn_wrong_absolute_value_type)
10003 << FDecl << ParamValueKind << ArgValueKind;
10006 Call->getCallee()->getSourceRange(), NewAbsKind, ArgType);
10012 if (!
Call || !FDecl)
return;
10016 if (
Call->getExprLoc().isMacroID())
return;
10019 if (
Call->getNumArgs() != 2)
return;
10022 if (!ArgList)
return;
10023 if (ArgList->size() != 1)
return;
10026 const auto& TA = ArgList->
get(0);
10028 QualType ArgType = TA.getAsType();
10032 auto IsLiteralZeroArg = [](
const Expr* E) ->
bool {
10033 const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E);
10034 if (!MTE)
return false;
10035 const auto *
Num = dyn_cast<IntegerLiteral>(MTE->getSubExpr());
10036 if (!
Num)
return false;
10037 if (
Num->getValue() != 0)
return false;
10041 const Expr *FirstArg =
Call->getArg(0);
10042 const Expr *SecondArg =
Call->getArg(1);
10043 const bool IsFirstArgZero = IsLiteralZeroArg(FirstArg);
10044 const bool IsSecondArgZero = IsLiteralZeroArg(SecondArg);
10047 if (IsFirstArgZero == IsSecondArgZero)
return;
10052 SourceRange ZeroRange = IsFirstArgZero ? FirstRange : SecondRange;
10054 Diag(
Call->getExprLoc(), diag::warn_max_unsigned_zero)
10055 << IsFirstArgZero <<
Call->getCallee()->getSourceRange() << ZeroRange;
10058 SourceRange RemovalRange;
10059 if (IsFirstArgZero) {
10060 RemovalRange = SourceRange(FirstRange.
getBegin(),
10067 Diag(
Call->getExprLoc(), diag::note_remove_max_call)
10082 const auto *Size = dyn_cast<BinaryOperator>(E);
10087 if (!Size->isComparisonOp() && !Size->isLogicalOp())
10091 S.
Diag(Size->getOperatorLoc(), diag::warn_memsize_comparison)
10092 << SizeRange << FnName;
10093 S.
Diag(FnLoc, diag::note_memsize_comparison_paren)
10098 S.
Diag(SizeRange.
getBegin(), diag::note_memsize_comparison_cast_silence)
10109 bool &IsContained) {
10111 const Type *Ty =
T->getBaseElementTypeUnsafe();
10112 IsContained =
false;
10125 for (
auto *FD : RD->
fields()) {
10129 IsContained =
true;
10130 return ContainedRD;
10138 if (
const auto *Unary = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
10139 if (Unary->getKind() == UETT_SizeOf)
10148 if (!
SizeOf->isArgumentType())
10149 return SizeOf->getArgumentExpr()->IgnoreParenImpCasts();
10156 return SizeOf->getTypeOfArgument();
10162struct SearchNonTrivialToInitializeField
10165 DefaultInitializedTypeVisitor<SearchNonTrivialToInitializeField>;
10167 SearchNonTrivialToInitializeField(
const Expr *E, Sema &S) : E(E), S(S) {}
10170 SourceLocation SL) {
10171 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10172 asDerived().visitArray(PDIK, AT, SL);
10176 Super::visitWithKind(PDIK, FT, SL);
10179 void visitARCStrong(QualType FT, SourceLocation SL) {
10182 void visitARCWeak(QualType FT, SourceLocation SL) {
10185 void visitStruct(QualType FT, SourceLocation SL) {
10190 const ArrayType *AT, SourceLocation SL) {
10191 visit(getContext().getBaseElementType(AT), SL);
10193 void visitTrivial(QualType FT, SourceLocation SL) {}
10195 static void diag(QualType RT,
const Expr *E, Sema &S) {
10196 SearchNonTrivialToInitializeField(E, S).visitStruct(RT, SourceLocation());
10205struct SearchNonTrivialToCopyField
10207 using Super = CopiedTypeVisitor<SearchNonTrivialToCopyField, false>;
10209 SearchNonTrivialToCopyField(
const Expr *E, Sema &S) : E(E), S(S) {}
10212 SourceLocation SL) {
10213 if (
const auto *AT = asDerived().getContext().getAsArrayType(FT)) {
10214 asDerived().visitArray(PCK, AT, SL);
10218 Super::visitWithKind(PCK, FT, SL);
10221 void visitARCStrong(QualType FT, SourceLocation SL) {
10224 void visitARCWeak(QualType FT, SourceLocation SL) {
10227 void visitPtrAuth(QualType FT, SourceLocation SL) {
10230 void visitStruct(QualType FT, SourceLocation SL) {
10235 SourceLocation SL) {
10236 visit(getContext().getBaseElementType(AT), SL);
10239 SourceLocation SL) {}
10240 void visitTrivial(QualType FT, SourceLocation SL) {}
10241 void visitVolatileTrivial(QualType FT, SourceLocation SL) {}
10243 static void diag(QualType RT,
const Expr *E, Sema &S) {
10244 SearchNonTrivialToCopyField(E, S).visitStruct(RT, SourceLocation());
10259 if (
const auto *BO = dyn_cast<BinaryOperator>(SizeofExpr)) {
10260 if (BO->getOpcode() != BO_Mul && BO->getOpcode() != BO_Add)
10284 return SM.getFileID(CallLoc) !=
SM.getFileID(ArgLoc);
10286 return SM.getFileID(
SM.getImmediateMacroCallerLoc(CallLoc)) !=
10287 SM.getFileID(
SM.getImmediateMacroCallerLoc(ArgLoc));
10293 if (BId != Builtin::BImemset && BId != Builtin::BIbzero)
10296 const Expr *SizeArg =
10297 Call->getArg(BId == Builtin::BImemset ? 2 : 1)->IgnoreImpCasts();
10299 auto isLiteralZero = [](
const Expr *E) {
10309 if (isLiteralZero(SizeArg) &&
10316 if (BId == Builtin::BIbzero ||
10319 S.
Diag(DiagLoc, diag::warn_suspicious_bzero_size);
10320 S.
Diag(DiagLoc, diag::note_suspicious_bzero_size_silence);
10321 }
else if (!isLiteralZero(
Call->getArg(1)->IgnoreImpCasts())) {
10322 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 0;
10323 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 0;
10331 if (BId == Builtin::BImemset &&
10335 S.
Diag(DiagLoc, diag::warn_suspicious_sizeof_memset) << 1;
10336 S.
Diag(DiagLoc, diag::note_suspicious_sizeof_memset_silence) << 1;
10341void Sema::CheckMemaccessArguments(
const CallExpr *
Call,
10348 unsigned ExpectedNumArgs =
10349 (BId == Builtin::BIstrndup || BId == Builtin::BIbzero ? 2 : 3);
10350 if (
Call->getNumArgs() < ExpectedNumArgs)
10353 unsigned LastArg = (BId == Builtin::BImemset || BId == Builtin::BIbzero ||
10354 BId == Builtin::BIstrndup ? 1 : 2);
10356 (BId == Builtin::BIbzero || BId == Builtin::BIstrndup ? 1 : 2);
10357 const Expr *LenExpr =
Call->getArg(LenArg)->IgnoreParenImpCasts();
10360 Call->getBeginLoc(),
Call->getRParenLoc()))
10369 llvm::FoldingSetNodeID SizeOfArgID;
10374 QualType FirstArgTy =
Call->getArg(0)->IgnoreParenImpCasts()->getType();
10375 if (BId == Builtin::BIbzero && !FirstArgTy->
getAs<PointerType>())
10378 for (
unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
10379 const Expr *Dest =
Call->getArg(ArgIdx)->IgnoreParenImpCasts();
10380 SourceRange ArgRange =
Call->getArg(ArgIdx)->getSourceRange();
10382 QualType DestTy = Dest->
getType();
10383 QualType PointeeTy;
10384 if (
const PointerType *DestPtrTy = DestTy->
getAs<PointerType>()) {
10397 !
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess,
10401 if (SizeOfArgID == llvm::FoldingSetNodeID())
10403 llvm::FoldingSetNodeID DestID;
10405 if (DestID == SizeOfArgID) {
10408 unsigned ActionIdx = 0;
10409 StringRef ReadableName = FnName->
getName();
10411 if (
const UnaryOperator *UnaryOp = dyn_cast<UnaryOperator>(Dest))
10412 if (UnaryOp->getOpcode() == UO_AddrOf)
10421 SourceLocation SL = SizeOfArg->
getExprLoc();
10426 if (
SM.isMacroArgExpansion(SL)) {
10428 SL =
SM.getSpellingLoc(SL);
10429 DSR = SourceRange(
SM.getSpellingLoc(DSR.
getBegin()),
10431 SSR = SourceRange(
SM.getSpellingLoc(SSR.
getBegin()),
10436 PDiag(diag::warn_sizeof_pointer_expr_memaccess)
10443 PDiag(diag::warn_sizeof_pointer_expr_memaccess_note)
10454 if (SizeOfArgTy != QualType()) {
10456 Context.typesAreCompatible(SizeOfArgTy, DestTy)) {
10458 PDiag(diag::warn_sizeof_pointer_type_memaccess)
10459 << FnName << SizeOfArgTy << ArgIdx
10466 PointeeTy = DestTy;
10469 if (PointeeTy == QualType())
10474 if (
const CXXRecordDecl *ContainedRD =
10477 unsigned OperationType = 0;
10478 const bool IsCmp = BId == Builtin::BImemcmp || BId == Builtin::BIbcmp;
10481 if (ArgIdx != 0 || IsCmp) {
10482 if (BId == Builtin::BImemcpy)
10484 else if(BId == Builtin::BImemmove)
10491 PDiag(diag::warn_dyn_class_memaccess)
10492 << (IsCmp ? ArgIdx + 2 : ArgIdx) << FnName
10493 << IsContained << ContainedRD << OperationType
10494 <<
Call->getCallee()->getSourceRange());
10496 BId != Builtin::BImemset)
10499 PDiag(diag::warn_arc_object_memaccess)
10500 << ArgIdx << FnName << PointeeTy
10501 <<
Call->getCallee()->getSourceRange());
10508 bool NonTriviallyCopyableCXXRecord =
10512 if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10515 PDiag(diag::warn_cstruct_memaccess)
10516 << ArgIdx << FnName << PointeeTy << 0);
10517 SearchNonTrivialToInitializeField::diag(PointeeTy, Dest, *
this);
10518 }
else if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
10519 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10523 PDiag(diag::warn_cxxstruct_memaccess)
10524 << FnName << PointeeTy);
10525 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10528 PDiag(diag::warn_cstruct_memaccess)
10529 << ArgIdx << FnName << PointeeTy << 1);
10530 SearchNonTrivialToCopyField::diag(PointeeTy, Dest, *
this);
10531 }
else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
10532 NonTriviallyCopyableCXXRecord && ArgIdx == 0) {
10536 PDiag(diag::warn_cxxstruct_memaccess)
10537 << FnName << PointeeTy);
10546 PDiag(diag::note_bad_memaccess_silence)
10582 if (CAT->getZExtSize() <= 1)
10590void Sema::CheckStrlcpycatArguments(
const CallExpr *
Call,
10594 unsigned NumArgs =
Call->getNumArgs();
10595 if ((NumArgs != 3) && (NumArgs != 4))
10600 const Expr *CompareWithSrc =
nullptr;
10603 Call->getBeginLoc(),
Call->getRParenLoc()))
10608 CompareWithSrc = Ex;
10611 if (
const CallExpr *SizeCall = dyn_cast<CallExpr>(SizeArg)) {
10612 if (SizeCall->getBuiltinCallee() == Builtin::BIstrlen &&
10613 SizeCall->getNumArgs() == 1)
10618 if (!CompareWithSrc)
10625 const DeclRefExpr *SrcArgDRE = dyn_cast<DeclRefExpr>(SrcArg);
10629 const DeclRefExpr *CompareWithSrcDRE = dyn_cast<DeclRefExpr>(CompareWithSrc);
10630 if (!CompareWithSrcDRE ||
10634 const Expr *OriginalSizeArg =
Call->getArg(2);
10635 Diag(CompareWithSrcDRE->
getBeginLoc(), diag::warn_strlcpycat_wrong_size)
10642 const Expr *DstArg =
Call->getArg(0)->IgnoreParenImpCasts();
10646 SmallString<128> sizeString;
10647 llvm::raw_svector_ostream
OS(sizeString);
10652 Diag(OriginalSizeArg->
getBeginLoc(), diag::note_strlcpycat_wrong_size)
10659 if (
const DeclRefExpr *D1 = dyn_cast_or_null<DeclRefExpr>(E1))
10660 if (
const DeclRefExpr *D2 = dyn_cast_or_null<DeclRefExpr>(E2))
10661 return D1->getDecl() == D2->getDecl();
10666 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
10675void Sema::CheckStrncatArguments(
const CallExpr *CE,
10690 unsigned PatternType = 0;
10698 }
else if (
const BinaryOperator *BE = dyn_cast<BinaryOperator>(LenArg)) {
10699 if (BE->getOpcode() == BO_Sub) {
10700 const Expr *L = BE->getLHS()->IgnoreParenCasts();
10701 const Expr *R = BE->getRHS()->IgnoreParenCasts();
10712 if (PatternType == 0)
10721 if (
SM.isMacroArgExpansion(SL)) {
10722 SL =
SM.getSpellingLoc(SL);
10723 SR = SourceRange(
SM.getSpellingLoc(SR.
getBegin()),
10728 QualType DstTy = DstArg->
getType();
10731 if (!isKnownSizeArray) {
10732 if (PatternType == 1)
10733 Diag(SL, diag::warn_strncat_wrong_size) << SR;
10735 Diag(SL, diag::warn_strncat_src_size) << SR;
10739 if (PatternType == 1)
10740 Diag(SL, diag::warn_strncat_large_size) << SR;
10742 Diag(SL, diag::warn_strncat_src_size) << SR;
10744 SmallString<128> sizeString;
10745 llvm::raw_svector_ostream
OS(sizeString);
10753 Diag(SL, diag::note_strncat_wrong_size)
10758void CheckFreeArgumentsOnLvalue(
Sema &S,
const std::string &CalleeName,
10767void CheckFreeArgumentsAddressof(
Sema &S,
const std::string &CalleeName,
10769 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(UnaryExpr->
getSubExpr())) {
10770 const Decl *D = Lvalue->getDecl();
10771 if (
const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
10772 if (!DD->getType()->isReferenceType())
10773 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr, D);
10777 if (
const auto *Lvalue = dyn_cast<MemberExpr>(UnaryExpr->
getSubExpr()))
10778 return CheckFreeArgumentsOnLvalue(S, CalleeName, UnaryExpr,
10779 Lvalue->getMemberDecl());
10782void CheckFreeArgumentsPlus(
Sema &S,
const std::string &CalleeName,
10784 const auto *Lambda = dyn_cast<LambdaExpr>(
10789 S.
Diag(Lambda->getBeginLoc(), diag::warn_free_nonheap_object)
10790 << CalleeName << 2 ;
10793void CheckFreeArgumentsStackArray(
Sema &S,
const std::string &CalleeName,
10795 const auto *Var = dyn_cast<VarDecl>(Lvalue->
getDecl());
10796 if (Var ==
nullptr)
10800 << CalleeName << 0 << Var;
10803void CheckFreeArgumentsCast(
Sema &S,
const std::string &CalleeName,
10806 llvm::raw_svector_ostream
OS(SizeString);
10809 if (Kind == clang::CK_BitCast &&
10810 !
Cast->getSubExpr()->getType()->isFunctionPointerType())
10812 if (Kind == clang::CK_IntegralToPointer &&
10814 Cast->getSubExpr()->IgnoreParenImpCasts()->IgnoreParens()))
10817 switch (
Cast->getCastKind()) {
10818 case clang::CK_BitCast:
10819 case clang::CK_IntegralToPointer:
10820 case clang::CK_FunctionToPointerDecay:
10829 S.
Diag(
Cast->getBeginLoc(), diag::warn_free_nonheap_object)
10830 << CalleeName << 0 <<
OS.str();
10834void Sema::CheckFreeArguments(
const CallExpr *E) {
10835 const std::string CalleeName =
10840 if (
const auto *UnaryExpr = dyn_cast<UnaryOperator>(Arg))
10842 case UnaryOperator::Opcode::UO_AddrOf:
10843 return CheckFreeArgumentsAddressof(*
this, CalleeName, UnaryExpr);
10844 case UnaryOperator::Opcode::UO_Plus:
10845 return CheckFreeArgumentsPlus(*
this, CalleeName, UnaryExpr);
10850 if (
const auto *Lvalue = dyn_cast<DeclRefExpr>(Arg))
10852 return CheckFreeArgumentsStackArray(*
this, CalleeName, Lvalue);
10854 if (
const auto *Label = dyn_cast<AddrLabelExpr>(Arg)) {
10855 Diag(Label->getBeginLoc(), diag::warn_free_nonheap_object)
10856 << CalleeName << 0 << Label->getLabel()->getIdentifier();
10862 << CalleeName << 1 ;
10867 if (
const auto *Cast = dyn_cast<CastExpr>(E->
getArg(0)))
10868 return CheckFreeArgumentsCast(*
this, CalleeName, Cast);
10872Sema::CheckReturnValExpr(
Expr *RetValExp,
QualType lhsType,
10881 Diag(ReturnLoc, diag::warn_null_ret)
10891 if (Op == OO_New || Op == OO_Array_New) {
10892 const FunctionProtoType *Proto
10896 Diag(ReturnLoc, diag::warn_operator_new_returns_null)
10902 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
10907 if (
Context.getTargetInfo().getTriple().isPPC64())
10919 auto getCastAndLiteral = [&FPLiteral, &FPCast](
const Expr *L,
const Expr *R) {
10920 FPLiteral = dyn_cast<FloatingLiteral>(L->IgnoreParens());
10922 return FPLiteral && FPCast;
10925 if (getCastAndLiteral(LHS, RHS) || getCastAndLiteral(RHS, LHS)) {
10931 llvm::APFloat TargetC = FPLiteral->
getValue();
10932 TargetC.convert(
Context.getFloatTypeSemantics(
QualType(SourceTy, 0)),
10933 llvm::APFloat::rmNearestTiesToEven, &Lossy);
10937 Diag(Loc, diag::warn_float_compare_literal)
10938 << (Opcode == BO_EQ) <<
QualType(SourceTy, 0)
10951 if (
const auto *DRL = dyn_cast<DeclRefExpr>(LeftExprSansParen))
10952 if (
const auto *DRR = dyn_cast<DeclRefExpr>(RightExprSansParen))
10953 if (DRL->getDecl() == DRR->getDecl())
10961 if (
const auto *FLL = dyn_cast<FloatingLiteral>(LeftExprSansParen)) {
10962 if (FLL->isExact())
10964 }
else if (
const auto *FLR = dyn_cast<FloatingLiteral>(RightExprSansParen))
10965 if (FLR->isExact())
10969 if (
const auto *
CL = dyn_cast<CallExpr>(LeftExprSansParen);
10970 CL &&
CL->getBuiltinCallee())
10973 if (
const auto *CR = dyn_cast<CallExpr>(RightExprSansParen);
10974 CR && CR->getBuiltinCallee())
10978 Diag(Loc, diag::warn_floatingpoint_eq)
10999 IntRange(
unsigned Width,
bool NonNegative)
11000 : Width(Width), NonNegative(NonNegative) {}
11003 unsigned valueBits()
const {
11004 return NonNegative ? Width : Width - 1;
11008 static IntRange forBoolType() {
11009 return IntRange(1,
true);
11013 static IntRange forValueOfType(ASTContext &
C, QualType
T) {
11014 return forValueOfCanonicalType(
C,
11019 static IntRange forValueOfCanonicalType(ASTContext &
C,
const Type *
T) {
11022 if (
const auto *VT = dyn_cast<VectorType>(
T))
11023 T = VT->getElementType().getTypePtr();
11024 if (
const auto *CT = dyn_cast<ComplexType>(
T))
11025 T = CT->getElementType().getTypePtr();
11026 if (
const auto *AT = dyn_cast<AtomicType>(
T))
11027 T = AT->getValueType().getTypePtr();
11029 if (!
C.getLangOpts().CPlusPlus) {
11032 T = ED->getIntegerType().getDesugaredType(
C).getTypePtr();
11037 if (
Enum->isFixed()) {
11038 return IntRange(
C.getIntWidth(QualType(
T, 0)),
11039 !
Enum->getIntegerType()->isSignedIntegerType());
11042 unsigned NumPositive =
Enum->getNumPositiveBits();
11043 unsigned NumNegative =
Enum->getNumNegativeBits();
11045 if (NumNegative == 0)
11046 return IntRange(NumPositive,
true);
11048 return IntRange(std::max(NumPositive + 1, NumNegative),
11052 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11053 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11066 static IntRange forTargetOfCanonicalType(ASTContext &
C,
const Type *
T) {
11069 if (
const VectorType *VT = dyn_cast<VectorType>(
T))
11070 T = VT->getElementType().getTypePtr();
11071 if (
const ComplexType *CT = dyn_cast<ComplexType>(
T))
11072 T = CT->getElementType().getTypePtr();
11073 if (
const AtomicType *AT = dyn_cast<AtomicType>(
T))
11074 T = AT->getValueType().getTypePtr();
11076 T =
C.getCanonicalType(ED->getIntegerType()).getTypePtr();
11078 if (
const auto *EIT = dyn_cast<BitIntType>(
T))
11079 return IntRange(EIT->getNumBits(), EIT->isUnsigned());
11088 static IntRange join(IntRange L, IntRange R) {
11089 bool Unsigned = L.NonNegative && R.NonNegative;
11090 return IntRange(std::max(L.valueBits(), R.valueBits()) + !
Unsigned,
11091 L.NonNegative && R.NonNegative);
11095 static IntRange bit_and(IntRange L, IntRange R) {
11096 unsigned Bits = std::max(L.Width, R.Width);
11097 bool NonNegative =
false;
11098 if (L.NonNegative) {
11099 Bits = std::min(Bits, L.Width);
11100 NonNegative =
true;
11102 if (R.NonNegative) {
11103 Bits = std::min(Bits, R.Width);
11104 NonNegative =
true;
11106 return IntRange(Bits, NonNegative);
11110 static IntRange sum(IntRange L, IntRange R) {
11111 bool Unsigned = L.NonNegative && R.NonNegative;
11112 return IntRange(std::max(L.valueBits(), R.valueBits()) + 1 + !
Unsigned,
11117 static IntRange difference(IntRange L, IntRange R) {
11121 bool CanWiden = !L.NonNegative || !R.NonNegative;
11122 bool Unsigned = L.NonNegative && R.Width == 0;
11123 return IntRange(std::max(L.valueBits(), R.valueBits()) + CanWiden +
11129 static IntRange product(IntRange L, IntRange R) {
11133 bool CanWiden = !L.NonNegative && !R.NonNegative;
11134 bool Unsigned = L.NonNegative && R.NonNegative;
11135 return IntRange(L.valueBits() + R.valueBits() + CanWiden + !
Unsigned,
11140 static IntRange rem(IntRange L, IntRange R) {
11144 return IntRange(std::min(L.valueBits(), R.valueBits()) + !
Unsigned,
11152 if (value.isSigned() && value.isNegative())
11153 return IntRange(value.getSignificantBits(),
false);
11155 if (value.getBitWidth() > MaxWidth)
11156 value = value.trunc(MaxWidth);
11160 return IntRange(value.getActiveBits(),
true);
11164 if (result.
isInt())
11171 R = IntRange::join(R, El);
11179 return IntRange::join(R, I);
11194 Ty = AtomicRHS->getValueType();
11213 bool InConstantContext,
11214 bool Approximate) {
11225 if (
const auto *CE = dyn_cast<ImplicitCastExpr>(E)) {
11226 if (CE->getCastKind() == CK_NoOp || CE->getCastKind() == CK_LValueToRValue)
11230 IntRange OutputTypeRange = IntRange::forValueOfType(
C,
GetExprType(CE));
11232 bool isIntegerCast = CE->getCastKind() == CK_IntegralCast ||
11233 CE->getCastKind() == CK_BooleanToSignedIntegral;
11236 if (!isIntegerCast)
11237 return OutputTypeRange;
11240 C, CE->getSubExpr(), std::min(MaxWidth, OutputTypeRange.Width),
11241 InConstantContext, Approximate);
11243 return std::nullopt;
11246 if (SubRange->Width >= OutputTypeRange.Width)
11247 return OutputTypeRange;
11251 return IntRange(SubRange->Width,
11252 SubRange->NonNegative || OutputTypeRange.NonNegative);
11255 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
11258 if (CO->getCond()->EvaluateAsBooleanCondition(CondResult,
C))
11260 C, CondResult ? CO->getTrueExpr() : CO->getFalseExpr(), MaxWidth,
11261 InConstantContext, Approximate);
11266 Expr *TrueExpr = CO->getTrueExpr();
11268 return std::nullopt;
11270 std::optional<IntRange> L =
11273 return std::nullopt;
11275 Expr *FalseExpr = CO->getFalseExpr();
11277 return std::nullopt;
11279 std::optional<IntRange> R =
11282 return std::nullopt;
11284 return IntRange::join(*L, *R);
11287 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
11288 IntRange (*Combine)(IntRange, IntRange) = IntRange::join;
11290 switch (BO->getOpcode()) {
11292 llvm_unreachable(
"builtin <=> should have class type");
11303 return IntRange::forBoolType();
11332 Combine = IntRange::bit_and;
11340 = dyn_cast<IntegerLiteral>(BO->getLHS()->IgnoreParenCasts())) {
11341 if (I->getValue() == 1) {
11342 IntRange R = IntRange::forValueOfType(
C,
GetExprType(E));
11343 return IntRange(R.Width,
true);
11353 case BO_ShrAssign: {
11355 C, BO->getLHS(), MaxWidth, InConstantContext, Approximate);
11357 return std::nullopt;
11361 if (std::optional<llvm::APSInt> shift =
11362 BO->getRHS()->getIntegerConstantExpr(
C)) {
11363 if (shift->isNonNegative()) {
11364 if (shift->uge(L->Width))
11365 L->Width = (L->NonNegative ? 0 : 1);
11367 L->Width -= shift->getZExtValue();
11381 Combine = IntRange::sum;
11385 if (BO->getLHS()->getType()->isPointerType())
11388 Combine = IntRange::difference;
11393 Combine = IntRange::product;
11402 C, BO->getLHS(), opWidth, InConstantContext, Approximate);
11404 return std::nullopt;
11407 if (std::optional<llvm::APSInt> divisor =
11408 BO->getRHS()->getIntegerConstantExpr(
C)) {
11409 unsigned log2 = divisor->logBase2();
11410 if (
log2 >= L->Width)
11411 L->Width = (L->NonNegative ? 0 : 1);
11413 L->Width = std::min(L->Width -
log2, MaxWidth);
11421 C, BO->getRHS(), opWidth, InConstantContext, Approximate);
11423 return std::nullopt;
11425 return IntRange(L->Width, L->NonNegative && R->NonNegative);
11429 Combine = IntRange::rem;
11441 unsigned opWidth =
C.getIntWidth(
T);
11443 InConstantContext, Approximate);
11445 return std::nullopt;
11448 InConstantContext, Approximate);
11450 return std::nullopt;
11452 IntRange
C = Combine(*L, *R);
11453 C.NonNegative |=
T->isUnsignedIntegerOrEnumerationType();
11454 C.Width = std::min(
C.Width, MaxWidth);
11458 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
11459 switch (UO->getOpcode()) {
11462 return IntRange::forBoolType();
11476 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11479 return std::nullopt;
11484 return IntRange(std::min(SubRange->Width + 1, MaxWidth),
false);
11494 C, UO->getSubExpr(), MaxWidth, InConstantContext, Approximate);
11497 return std::nullopt;
11502 std::min(SubRange->Width + (
int)SubRange->NonNegative, MaxWidth),
11512 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
11513 return TryGetExprRange(
C, OVE->getSourceExpr(), MaxWidth, InConstantContext,
11517 return IntRange(BitField->getBitWidthValue(),
11518 BitField->getType()->isUnsignedIntegerOrEnumerationType());
11521 return std::nullopt;
11527 bool InConstantContext,
11528 bool Approximate) {
11537 const llvm::fltSemantics &Src,
11538 const llvm::fltSemantics &Tgt) {
11539 llvm::APFloat truncated = value;
11542 truncated.convert(Src, llvm::APFloat::rmNearestTiesToEven, &ignored);
11543 truncated.convert(Tgt, llvm::APFloat::rmNearestTiesToEven, &ignored);
11545 return truncated.bitwiseIsEqual(value);
11554 const llvm::fltSemantics &Src,
11555 const llvm::fltSemantics &Tgt) {
11572 bool IsListInit =
false);
11587 return MacroName !=
"YES" && MacroName !=
"NO" &&
11588 MacroName !=
"true" && MacroName !=
"false";
11596 (!E->
getType()->isSignedIntegerType() ||
11611struct PromotedRange {
11613 llvm::APSInt PromotedMin;
11615 llvm::APSInt PromotedMax;
11617 PromotedRange(IntRange R,
unsigned BitWidth,
bool Unsigned) {
11619 PromotedMin = PromotedMax = llvm::APSInt(BitWidth,
Unsigned);
11620 else if (R.Width >= BitWidth && !
Unsigned) {
11624 PromotedMin = llvm::APSInt::getMinValue(BitWidth,
Unsigned);
11625 PromotedMax = llvm::APSInt::getMaxValue(BitWidth,
Unsigned);
11627 PromotedMin = llvm::APSInt::getMinValue(R.Width, R.NonNegative)
11628 .extOrTrunc(BitWidth);
11629 PromotedMin.setIsUnsigned(
Unsigned);
11631 PromotedMax = llvm::APSInt::getMaxValue(R.Width, R.NonNegative)
11632 .extOrTrunc(BitWidth);
11633 PromotedMax.setIsUnsigned(
Unsigned);
11638 bool isContiguous()
const {
return PromotedMin <= PromotedMax; }
11648 InRangeFlag = 0x40,
11651 Min =
LE | InRangeFlag,
11652 InRange = InRangeFlag,
11653 Max =
GE | InRangeFlag,
11656 OnlyValue =
LE |
GE |
EQ | InRangeFlag,
11661 assert(
Value.getBitWidth() == PromotedMin.getBitWidth() &&
11662 Value.isUnsigned() == PromotedMin.isUnsigned());
11663 if (!isContiguous()) {
11664 assert(
Value.isUnsigned() &&
"discontiguous range for signed compare");
11665 if (
Value.isMinValue())
return Min;
11666 if (
Value.isMaxValue())
return Max;
11667 if (
Value >= PromotedMin)
return InRange;
11668 if (
Value <= PromotedMax)
return InRange;
11672 switch (llvm::APSInt::compareValues(
Value, PromotedMin)) {
11673 case -1:
return Less;
11674 case 0:
return PromotedMin == PromotedMax ? OnlyValue :
Min;
11676 switch (llvm::APSInt::compareValues(
Value, PromotedMax)) {
11677 case -1:
return InRange;
11678 case 0:
return Max;
11683 llvm_unreachable(
"impossible compare result");
11686 static std::optional<StringRef>
11688 if (Op == BO_Cmp) {
11690 if (ConstantOnRHS) std::swap(LTFlag, GTFlag);
11692 if (R & EQ)
return StringRef(
"'std::strong_ordering::equal'");
11693 if (R & LTFlag)
return StringRef(
"'std::strong_ordering::less'");
11694 if (R & GTFlag)
return StringRef(
"'std::strong_ordering::greater'");
11695 return std::nullopt;
11702 }
else if (Op == BO_NE) {
11706 if ((Op == BO_LT || Op == BO_GE) ^ ConstantOnRHS) {
11713 if (Op == BO_GE || Op == BO_LE)
11714 std::swap(TrueFlag, FalseFlag);
11717 return StringRef(
"true");
11719 return StringRef(
"false");
11720 return std::nullopt;
11727 while (
const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
11728 if (ICE->getCastKind() != CK_IntegralCast &&
11729 ICE->getCastKind() != CK_NoOp)
11731 E = ICE->getSubExpr();
11740 enum ConstantValueKind {
11745 if (
auto *BL = dyn_cast<CXXBoolLiteralExpr>(Constant))
11746 return BL->getValue() ? ConstantValueKind::LiteralTrue
11747 : ConstantValueKind::LiteralFalse;
11748 return ConstantValueKind::Miscellaneous;
11753 const llvm::APSInt &
Value,
11754 bool RhsConstant) {
11776 if (!OtherValueRange)
11781 OtherT = AT->getValueType();
11782 IntRange OtherTypeRange = IntRange::forValueOfType(S.
Context, OtherT);
11786 bool IsObjCSignedCharBool = S.
getLangOpts().ObjC &&
11792 bool OtherIsBooleanDespiteType =
11794 if (OtherIsBooleanDespiteType || IsObjCSignedCharBool)
11795 OtherTypeRange = *OtherValueRange = IntRange::forBoolType();
11799 PromotedRange OtherPromotedValueRange(*OtherValueRange,
Value.getBitWidth(),
11800 Value.isUnsigned());
11801 auto Cmp = OtherPromotedValueRange.compare(
Value);
11802 auto Result = PromotedRange::constantValue(E->
getOpcode(), Cmp, RhsConstant);
11808 bool TautologicalTypeCompare =
false;
11810 PromotedRange OtherPromotedTypeRange(OtherTypeRange,
Value.getBitWidth(),
11811 Value.isUnsigned());
11812 auto TypeCmp = OtherPromotedTypeRange.compare(
Value);
11815 TautologicalTypeCompare =
true;
11823 if (!TautologicalTypeCompare && OtherValueRange->Width == 0)
11832 bool InRange = Cmp & PromotedRange::InRangeFlag;
11838 if (
Other->refersToBitField() && InRange &&
Value == 0 &&
11839 Other->getType()->isUnsignedIntegerOrEnumerationType())
11840 TautologicalTypeCompare =
true;
11845 if (
const auto *DR = dyn_cast<DeclRefExpr>(Constant))
11846 ED = dyn_cast<EnumConstantDecl>(DR->getDecl());
11850 llvm::raw_svector_ostream OS(PrettySourceValue);
11852 OS <<
'\'' << *ED <<
"' (" <<
Value <<
")";
11853 }
else if (
auto *BL = dyn_cast<ObjCBoolLiteralExpr>(
11855 OS << (BL->getValue() ?
"YES" :
"NO");
11860 if (!TautologicalTypeCompare) {
11862 << RhsConstant << OtherValueRange->Width << OtherValueRange->NonNegative
11868 if (IsObjCSignedCharBool) {
11870 S.
PDiag(diag::warn_tautological_compare_objc_bool)
11871 << OS.str() << *Result);
11878 if (!InRange ||
Other->isKnownToHaveBooleanValue()) {
11882 S.
PDiag(!InRange ? diag::warn_out_of_range_compare
11883 : diag::warn_tautological_bool_compare)
11885 << OtherIsBooleanDespiteType << *Result
11892 ? diag::warn_unsigned_enum_always_true_comparison
11893 : IsCharTy ? diag::warn_unsigned_char_always_true_comparison
11894 : diag::warn_unsigned_always_true_comparison)
11895 : diag::warn_tautological_constant_compare;
11898 << RhsConstant << OtherT << E->
getOpcodeStr() << OS.str() << *Result
11931 if (
T->isIntegralType(S.
Context)) {
11932 std::optional<llvm::APSInt> RHSValue =
11934 std::optional<llvm::APSInt> LHSValue =
11938 if (RHSValue && LHSValue)
11942 if ((
bool)RHSValue ^ (
bool)LHSValue) {
11944 const bool RhsConstant = (
bool)RHSValue;
11945 Expr *Const = RhsConstant ? RHS : LHS;
11947 const llvm::APSInt &
Value = RhsConstant ? *RHSValue : *LHSValue;
11956 if (!
T->hasUnsignedIntegerRepresentation()) {
11970 if (
const auto *TET = dyn_cast<TypeOfExprType>(LHS->
getType()))
11972 if (
const auto *TET = dyn_cast<TypeOfExprType>(RHS->
getType()))
11978 Expr *signedOperand, *unsignedOperand;
11981 "unsigned comparison between two signed integer expressions?");
11982 signedOperand = LHS;
11983 unsignedOperand = RHS;
11985 signedOperand = RHS;
11986 unsignedOperand = LHS;
11992 std::optional<IntRange> signedRange =
12004 if (signedRange->NonNegative)
12016 if (!unsignedRange)
12021 assert(unsignedRange->NonNegative &&
"unsigned range includes negative?");
12023 if (unsignedRange->Width < comparisonWidth)
12028 S.
PDiag(diag::warn_mixed_sign_comparison)
12047 if (
auto *BitfieldEnumDecl = BitfieldType->
getAsEnumDecl()) {
12052 !BitfieldEnumDecl->getIntegerTypeSourceInfo() &&
12053 BitfieldEnumDecl->getNumPositiveBits() > 0 &&
12054 BitfieldEnumDecl->getNumNegativeBits() == 0) {
12055 S.
Diag(InitLoc, diag::warn_no_underlying_type_specified_for_enum_bitfield)
12056 << BitfieldEnumDecl;
12063 Init->isValueDependent() ||
12064 Init->isTypeDependent())
12067 Expr *OriginalInit =
Init->IgnoreParenImpCasts();
12077 const PreferredTypeAttr *PTAttr =
nullptr;
12079 PTAttr = Bitfield->
getAttr<PreferredTypeAttr>();
12081 ED = PTAttr->getType()->getAsEnumDecl();
12089 bool SignedEnum = ED->getNumNegativeBits() > 0;
12096 unsigned DiagID = 0;
12097 if (SignedEnum && !SignedBitfield) {
12100 ? diag::warn_unsigned_bitfield_assigned_signed_enum
12102 warn_preferred_type_unsigned_bitfield_assigned_signed_enum;
12103 }
else if (SignedBitfield && !SignedEnum &&
12104 ED->getNumPositiveBits() == FieldWidth) {
12107 ? diag::warn_signed_bitfield_enum_conversion
12108 : diag::warn_preferred_type_signed_bitfield_enum_conversion;
12111 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12116 << SignedEnum << TypeRange;
12118 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12125 unsigned BitsNeeded = SignedEnum ? std::max(ED->getNumPositiveBits() + 1,
12126 ED->getNumNegativeBits())
12127 : ED->getNumPositiveBits();
12130 if (BitsNeeded > FieldWidth) {
12134 ? diag::warn_bitfield_too_small_for_enum
12135 : diag::warn_preferred_type_bitfield_too_small_for_enum;
12136 S.
Diag(InitLoc, DiagID) << Bitfield << ED;
12140 S.
Diag(PTAttr->getLocation(), diag::note_bitfield_preferred_type)
12148 llvm::APSInt
Value = Result.Val.getInt();
12150 unsigned OriginalWidth =
Value.getBitWidth();
12156 bool OneAssignedToOneBitBitfield = FieldWidth == 1 &&
Value == 1;
12157 if (OneAssignedToOneBitBitfield && !S.
LangOpts.CPlusPlus) {
12164 if (!
Value.isSigned() ||
Value.isNegative())
12165 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
12166 if (UO->getOpcode() == UO_Minus || UO->getOpcode() == UO_Not)
12167 OriginalWidth =
Value.getSignificantBits();
12169 if (OriginalWidth <= FieldWidth)
12173 llvm::APSInt TruncatedValue =
Value.trunc(FieldWidth);
12177 TruncatedValue = TruncatedValue.extend(OriginalWidth);
12178 if (llvm::APSInt::isSameValue(
Value, TruncatedValue))
12182 std::string PrettyTrunc =
toString(TruncatedValue, 10);
12184 S.
Diag(InitLoc, OneAssignedToOneBitBitfield
12185 ? diag::warn_impcast_single_bit_bitield_precision_constant
12186 : diag::warn_impcast_bitfield_precision_constant)
12187 << PrettyValue << PrettyTrunc << OriginalInit->
getType()
12188 <<
Init->getSourceRange();
12220 bool PruneControlFlow =
false) {
12227 if (
T.hasAddressSpace())
12229 if (PruneControlFlow) {
12243 bool PruneControlFlow =
false) {
12250 bool IsBool =
T->isSpecificBuiltinType(BuiltinType::Bool);
12255 if (
const auto *UOp = dyn_cast<UnaryOperator>(InnerE))
12256 if (UOp->getOpcode() == UO_Minus || UOp->getOpcode() == UO_Plus)
12261 llvm::APFloat
Value(0.0);
12267 E, S.
Diag(CContext, diag::warn_impcast_float_to_objc_signed_char_bool)
12272 diag::warn_impcast_float_integer, PruneWarnings);
12275 bool isExact =
false;
12278 T->hasUnsignedIntegerRepresentation());
12279 llvm::APFloat::opStatus Result =
Value.convertToInteger(
12280 IntegerValue, llvm::APFloat::rmTowardZero, &isExact);
12288 unsigned precision = llvm::APFloat::semanticsPrecision(
Value.getSemantics());
12289 precision = (precision * 59 + 195) / 196;
12290 Value.toString(PrettySourceValue, precision);
12294 E, S.
Diag(CContext, diag::warn_impcast_constant_value_to_objc_bool)
12295 << PrettySourceValue);
12298 if (Result == llvm::APFloat::opOK && isExact) {
12299 if (IsLiteral)
return;
12300 return DiagnoseImpCast(S, E,
T, CContext, diag::warn_impcast_float_integer,
12306 if (!IsBool && Result == llvm::APFloat::opInvalidOp)
12309 IsLiteral ? diag::warn_impcast_literal_float_to_integer_out_of_range
12310 : diag::warn_impcast_float_to_integer_out_of_range,
12313 unsigned DiagID = 0;
12316 DiagID = diag::warn_impcast_literal_float_to_integer;
12317 }
else if (IntegerValue == 0) {
12318 if (
Value.isZero()) {
12320 diag::warn_impcast_float_integer, PruneWarnings);
12323 DiagID = diag::warn_impcast_float_to_integer_zero;
12325 if (IntegerValue.isUnsigned()) {
12326 if (!IntegerValue.isMaxValue()) {
12328 diag::warn_impcast_float_integer, PruneWarnings);
12331 if (!IntegerValue.isMaxSignedValue() &&
12332 !IntegerValue.isMinSignedValue()) {
12334 diag::warn_impcast_float_integer, PruneWarnings);
12338 DiagID = diag::warn_impcast_float_to_integer;
12343 PrettyTargetValue =
Value.isZero() ?
"false" :
"true";
12345 IntegerValue.toString(PrettyTargetValue);
12347 if (PruneWarnings) {
12350 << E->
getType() <<
T.getUnqualifiedType()
12351 << PrettySourceValue << PrettyTargetValue
12355 << E->
getType() <<
T.getUnqualifiedType() << PrettySourceValue
12364 "Must be compound assignment operation");
12375 ->getComputationResultType()
12382 if (ResultBT->isInteger())
12384 E->
getExprLoc(), diag::warn_impcast_float_integer);
12386 if (!ResultBT->isFloatingPoint())
12395 diag::warn_impcast_float_result_precision);
12400 if (!Range.Width)
return "0";
12402 llvm::APSInt ValueInRange =
Value;
12403 ValueInRange.setIsSigned(!Range.NonNegative);
12404 ValueInRange = ValueInRange.trunc(Range.Width);
12405 return toString(ValueInRange, 10);
12415 const Type *Source =
12417 if (
Target->isDependentType())
12420 const auto *FloatCandidateBT =
12421 dyn_cast<BuiltinType>(ToBool ? Source :
Target);
12422 const Type *BoolCandidateType = ToBool ?
Target : Source;
12425 FloatCandidateBT && (FloatCandidateBT->isFloatingPoint()));
12430 for (
unsigned I = 0, N = TheCall->
getNumArgs(); I < N; ++I) {
12436 S, TheCall->
getArg(I - 1),
false));
12438 S, TheCall->
getArg(I + 1),
false));
12443 diag::warn_impcast_floating_point_to_bool);
12458 if (!IsGNUNullExpr && !HasNullPtrType)
12462 if (
T->isAnyPointerType() ||
T->isBlockPointerType() ||
12463 T->isMemberPointerType() || !
T->isScalarType() ||
T->isNullPtrType())
12466 if (S.
Diags.
isIgnored(diag::warn_impcast_null_pointer_to_integer,
12479 if (IsGNUNullExpr && Loc.
isMacroID()) {
12482 if (MacroName ==
"NULL")
12490 S.
Diag(Loc, diag::warn_impcast_null_pointer_to_integer)
12504 const char FirstLiteralCharacter =
12506 if (FirstLiteralCharacter ==
'0')
12512 if (CC.
isValid() &&
T->isCharType()) {
12513 const char FirstContextCharacter =
12515 if (FirstContextCharacter ==
'{')
12523 const auto *IL = dyn_cast<IntegerLiteral>(E);
12525 if (
auto *UO = dyn_cast<UnaryOperator>(E)) {
12526 if (UO->getOpcode() == UO_Minus)
12527 return dyn_cast<IntegerLiteral>(UO->getSubExpr());
12538 if (
const auto *BO = dyn_cast<BinaryOperator>(E)) {
12542 if (Opc == BO_Shl) {
12545 if (LHS && LHS->getValue() == 0)
12546 S.
Diag(ExprLoc, diag::warn_left_shift_always) << 0;
12548 RHS->getValue().isNonNegative() &&
12550 S.
Diag(ExprLoc, diag::warn_left_shift_always)
12551 << (Result.Val.getInt() != 0);
12553 S.
Diag(ExprLoc, diag::warn_left_shift_in_bool_context)
12560 if (
const auto *CO = dyn_cast<ConditionalOperator>(E)) {
12565 if ((LHS->getValue() == 0 || LHS->getValue() == 1) &&
12566 (RHS->getValue() == 0 || RHS->getValue() == 1))
12569 if (LHS->getValue() != 0 && RHS->getValue() != 0)
12570 S.
Diag(ExprLoc, diag::warn_integer_constants_in_conditional_always_true);
12578 assert(Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType() &&
12584 if (Source->isChar16Type() &&
Target->isChar32Type())
12590 llvm::APSInt
Value(32);
12591 Value = Result.Val.getInt();
12592 bool IsASCII =
Value <= 0x7F;
12593 bool IsBMP =
Value <= 0xDFFF || (
Value >= 0xE000 &&
Value <= 0xFFFF);
12594 bool ConversionPreservesSemantics =
12595 IsASCII || (!Source->isChar8Type() && !
Target->isChar8Type() && IsBMP);
12597 if (!ConversionPreservesSemantics) {
12598 auto IsSingleCodeUnitCP = [](
const QualType &
T,
12599 const llvm::APSInt &
Value) {
12600 if (
T->isChar8Type())
12601 return llvm::IsSingleCodeUnitUTF8Codepoint(
Value.getExtValue());
12602 if (
T->isChar16Type())
12603 return llvm::IsSingleCodeUnitUTF16Codepoint(
Value.getExtValue());
12604 assert(
T->isChar32Type());
12605 return llvm::IsSingleCodeUnitUTF32Codepoint(
Value.getExtValue());
12608 S.
Diag(CC, diag::warn_impcast_unicode_char_type_constant)
12617 LosesPrecision ? diag::warn_impcast_unicode_precision
12618 : diag::warn_impcast_unicode_char_type);
12623 From =
Context.getCanonicalType(From);
12624 To =
Context.getCanonicalType(To);
12627 From = MaybePointee;
12634 if (FromFn->getCFIUncheckedCalleeAttr() &&
12635 !ToFn->getCFIUncheckedCalleeAttr())
12643 bool *ICContext,
bool IsListInit) {
12648 if (Source ==
Target)
return;
12649 if (
Target->isDependentType())
return;
12659 if (Source->isAtomicType())
12663 if (
Target->isSpecificBuiltinType(BuiltinType::Bool)) {
12669 diag::warn_impcast_string_literal_to_bool);
12675 diag::warn_impcast_objective_c_literal_to_bool);
12677 if (Source->isPointerType() || Source->canDecayToPointerType()) {
12687 if (
ObjC().isSignedCharBool(
T) && Source->isIntegralType(
Context)) {
12690 if (
Result.Val.getInt() != 1 &&
Result.Val.getInt() != 0) {
12692 E,
Diag(CC, diag::warn_impcast_constant_value_to_objc_bool)
12701 if (
auto *ArrayLiteral = dyn_cast<ObjCArrayLiteral>(E))
12703 else if (
auto *DictionaryLiteral = dyn_cast<ObjCDictionaryLiteral>(E))
12708 if (
Target->isSveVLSBuiltinType() &&
12715 if (
Target->isRVVVLSBuiltinType() &&
12725 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_vector_scalar);
12733 diag::warn_hlsl_impcast_vector_truncation);
12745 if (
const auto *VecTy = dyn_cast<VectorType>(
Target))
12746 Target = VecTy->getElementType().getTypePtr();
12749 if (
Target->isScalarType())
12750 return DiagnoseImpCast(*
this, E,
T, CC, diag::warn_impcast_matrix_scalar);
12758 diag::warn_hlsl_impcast_matrix_truncation);
12769 ? diag::err_impcast_complex_scalar
12770 : diag::warn_impcast_complex_scalar);
12777 const BuiltinType *SourceBT = dyn_cast<BuiltinType>(Source);
12783 const Type *OriginalTarget =
Context.getCanonicalType(
T).getTypePtr();
12786 if (
ARM().areCompatibleSveTypes(
QualType(OriginalTarget, 0),
12788 ARM().areLaxCompatibleSveTypes(
QualType(OriginalTarget, 0),
12830 else if (Order < 0) {
12840 if (TargetBT && TargetBT->
isInteger()) {
12867 diag::warn_impcast_floating_point_to_bool);
12875 if (Source->isFixedPointType()) {
12876 if (
Target->isUnsaturatedFixedPointType()) {
12880 llvm::APFixedPoint
Value =
Result.Val.getFixedPoint();
12881 llvm::APFixedPoint MaxVal =
Context.getFixedPointMax(
T);
12882 llvm::APFixedPoint MinVal =
Context.getFixedPointMin(
T);
12885 PDiag(diag::warn_impcast_fixed_point_range)
12886 <<
Value.toString() <<
T
12892 }
else if (
Target->isIntegerType()) {
12896 llvm::APFixedPoint FXResult =
Result.Val.getFixedPoint();
12899 llvm::APSInt IntResult = FXResult.convertToInt(
12900 Context.getIntWidth(
T),
Target->isSignedIntegerOrEnumerationType(),
12905 PDiag(diag::warn_impcast_fixed_point_range)
12906 << FXResult.toString() <<
T
12913 }
else if (
Target->isUnsaturatedFixedPointType()) {
12914 if (Source->isIntegerType()) {
12921 llvm::APFixedPoint IntResult = llvm::APFixedPoint::getFromIntValue(
12926 PDiag(diag::warn_impcast_fixed_point_range)
12947 unsigned int SourcePrecision =
SourceRange->Width;
12951 unsigned int TargetPrecision = llvm::APFloatBase::semanticsPrecision(
12954 if (SourcePrecision > 0 && TargetPrecision > 0 &&
12955 SourcePrecision > TargetPrecision) {
12957 if (std::optional<llvm::APSInt> SourceInt =
12962 llvm::APFloat TargetFloatValue(
12964 llvm::APFloat::opStatus ConversionStatus =
12965 TargetFloatValue.convertFromAPInt(
12967 llvm::APFloat::rmNearestTiesToEven);
12969 if (ConversionStatus != llvm::APFloat::opOK) {
12971 SourceInt->toString(PrettySourceValue, 10);
12973 TargetFloatValue.toString(PrettyTargetValue, TargetPrecision);
12977 PDiag(diag::warn_impcast_integer_float_precision_constant)
12978 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
12984 diag::warn_impcast_integer_float_precision);
12993 if (Source->isUnicodeCharacterType() &&
Target->isUnicodeCharacterType()) {
12998 if (
Target->isBooleanType())
13002 Diag(CC, diag::warn_cast_discards_cfi_unchecked_callee)
13006 if (!Source->isIntegerType() || !
Target->isIntegerType())
13011 if (
Target->isSpecificBuiltinType(BuiltinType::Bool))
13014 if (
ObjC().isSignedCharBool(
T) && !Source->isCharType() &&
13017 E,
Diag(CC, diag::warn_impcast_int_to_objc_signed_char_bool)
13022 if (!LikelySourceRange)
13025 IntRange SourceTypeRange =
13026 IntRange::forTargetOfCanonicalType(
Context, Source);
13027 IntRange TargetRange = IntRange::forTargetOfCanonicalType(
Context,
Target);
13029 if (LikelySourceRange->Width > TargetRange.Width) {
13035 llvm::APSInt
Value(32);
13045 PDiag(diag::warn_impcast_integer_precision_constant)
13046 << PrettySourceValue << PrettyTargetValue
13056 if (
const auto *UO = dyn_cast<UnaryOperator>(E)) {
13057 if (UO->getOpcode() == UO_Minus)
13059 *
this, E,
T, CC, diag::warn_impcast_integer_precision_on_negation);
13062 if (TargetRange.Width == 32 &&
Context.getIntWidth(E->
getType()) == 64)
13066 diag::warn_impcast_integer_precision);
13069 if (TargetRange.Width > SourceTypeRange.Width) {
13070 if (
auto *UO = dyn_cast<UnaryOperator>(E))
13071 if (UO->getOpcode() == UO_Minus)
13072 if (Source->isUnsignedIntegerType()) {
13073 if (
Target->isUnsignedIntegerType())
13075 diag::warn_impcast_high_order_zero_bits);
13076 if (
Target->isSignedIntegerType())
13078 diag::warn_impcast_nonnegative_result);
13082 if (TargetRange.Width == LikelySourceRange->Width &&
13083 !TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13084 Source->isSignedIntegerType()) {
13098 PDiag(diag::warn_impcast_integer_precision_constant)
13099 << PrettySourceValue << PrettyTargetValue << E->
getType() <<
T
13109 ((TargetRange.NonNegative && !LikelySourceRange->NonNegative) ||
13110 (!TargetRange.NonNegative && LikelySourceRange->NonNegative &&
13111 LikelySourceRange->Width == TargetRange.Width))) {
13115 if (SourceBT && SourceBT->
isInteger() && TargetBT &&
13117 Source->isSignedIntegerType() ==
Target->isSignedIntegerType()) {
13121 unsigned DiagID = diag::warn_impcast_integer_sign;
13129 DiagID = diag::warn_impcast_integer_sign_conditional;
13146 Source =
Context.getCanonicalType(SourceType).getTypePtr();
13148 if (
const EnumType *SourceEnum = Source->getAsCanonical<EnumType>())
13149 if (
const EnumType *TargetEnum =
Target->getAsCanonical<EnumType>())
13150 if (SourceEnum->getDecl()->hasNameForLinkage() &&
13151 TargetEnum->getDecl()->hasNameForLinkage() &&
13152 SourceEnum != TargetEnum) {
13157 diag::warn_impcast_different_enum_types);
13171 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(E))
13184 if (
auto *BCO = dyn_cast<BinaryConditionalOperator>(E))
13185 TrueExpr = BCO->getCommon();
13187 bool Suspicious =
false;
13191 if (
T->isBooleanType())
13196 if (!Suspicious)
return;
13199 if (!S.
Diags.
isIgnored(diag::warn_impcast_integer_sign_conditional, CC))
13206 Suspicious =
false;
13211 E->
getType(), CC, &Suspicious);
13228struct AnalyzeImplicitConversionsWorkItem {
13237 bool ExtraCheckForImplicitConversion,
13240 WorkList.push_back({E, CC,
false});
13242 if (ExtraCheckForImplicitConversion && E->
getType() !=
T)
13249 Sema &S, AnalyzeImplicitConversionsWorkItem Item,
13251 Expr *OrigE = Item.E;
13270 Expr *SourceExpr = E;
13275 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(E))
13276 if (
auto *Src = OVE->getSourceExpr())
13279 if (
const auto *UO = dyn_cast<UnaryOperator>(SourceExpr))
13280 if (UO->getOpcode() == UO_Not &&
13281 UO->getSubExpr()->isKnownToHaveBooleanValue())
13282 S.
Diag(UO->getBeginLoc(), diag::warn_bitwise_negation_bool)
13286 if (
auto *BO = dyn_cast<BinaryOperator>(SourceExpr)) {
13287 if ((BO->getOpcode() == BO_And || BO->getOpcode() == BO_Or) &&
13288 BO->getLHS()->isKnownToHaveBooleanValue() &&
13289 BO->getRHS()->isKnownToHaveBooleanValue() &&
13290 BO->getLHS()->HasSideEffects(S.
Context) &&
13291 BO->getRHS()->HasSideEffects(S.
Context)) {
13302 if (SR.str() ==
"&" || SR.str() ==
"|") {
13304 S.
Diag(BO->getBeginLoc(), diag::warn_bitwise_instead_of_logical)
13305 << (BO->getOpcode() == BO_And ?
"&" :
"|")
13308 BO->getOperatorLoc(),
13309 (BO->getOpcode() == BO_And ?
"&&" :
"||"));
13310 S.
Diag(BO->getBeginLoc(), diag::note_cast_operand_to_int);
13312 }
else if (BO->isCommaOp() && !S.
getLangOpts().CPlusPlus) {
13330 if (
auto *CO = dyn_cast<AbstractConditionalOperator>(SourceExpr)) {
13336 if (
const auto *
Call = dyn_cast<CallExpr>(SourceExpr))
13351 for (
auto *SE : POE->semantics())
13352 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(SE))
13353 WorkList.push_back({OVE->getSourceExpr(), CC, IsListInit});
13357 if (
auto *CE = dyn_cast<ExplicitCastExpr>(E)) {
13358 E = CE->getSubExpr();
13364 if (
auto *InitListE = dyn_cast<InitListExpr>(E)) {
13365 if (InitListE->getNumInits() == 1) {
13366 E = InitListE->getInit(0);
13373 WorkList.push_back({E, CC, IsListInit});
13377 if (
auto *OutArgE = dyn_cast<HLSLOutArgExpr>(E)) {
13378 WorkList.push_back({OutArgE->getArgLValue(), CC, IsListInit});
13382 if (OutArgE->isInOut())
13383 WorkList.push_back(
13384 {OutArgE->getCastedTemporary()->getSourceExpr(), CC, IsListInit});
13385 WorkList.push_back({OutArgE->getWritebackCast(), CC, IsListInit});
13391 if (BO->isComparisonOp())
13395 if (BO->getOpcode() == BO_Assign)
13398 if (BO->isAssignmentOp())
13414 bool IsLogicalAndOperator = BO && BO->
getOpcode() == BO_LAnd;
13416 Expr *ChildExpr = dyn_cast_or_null<Expr>(SubStmt);
13420 if (
auto *CSE = dyn_cast<CoroutineSuspendExpr>(E))
13421 if (ChildExpr == CSE->getOperand())
13427 if (IsLogicalAndOperator &&
13432 WorkList.push_back({ChildExpr, CC, IsListInit});
13446 if (
U->getOpcode() == UO_LNot) {
13448 }
else if (
U->getOpcode() != UO_AddrOf) {
13449 if (
U->getSubExpr()->getType()->isAtomicType())
13450 S.
Diag(
U->getSubExpr()->getBeginLoc(),
13451 diag::warn_atomic_implicit_seq_cst);
13462 WorkList.push_back({OrigE, CC, IsListInit});
13463 while (!WorkList.empty())
13475 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
13478 }
else if (
const MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13479 if (!M->getMemberDecl()->getType()->isReferenceType())
13481 }
else if (
const CallExpr *
Call = dyn_cast<CallExpr>(E)) {
13482 if (!
Call->getCallReturnType(SemaRef.
Context)->isReferenceType())
13484 FD =
Call->getDirectCallee();
13493 SemaRef.
Diag(FD->
getLocation(), diag::note_reference_is_return_value) << FD;
13507 if (
SM.isMacroBodyExpansion(Loc))
13509 Loc =
SM.getImmediateMacroCallerLoc(Loc);
13533 unsigned DiagID = IsCompare ? diag::warn_this_null_compare
13534 : diag::warn_this_bool_conversion;
13539 bool IsAddressOf =
false;
13541 if (
auto *UO = dyn_cast<UnaryOperator>(E->
IgnoreParens())) {
13542 if (UO->getOpcode() != UO_AddrOf)
13544 IsAddressOf =
true;
13545 E = UO->getSubExpr();
13549 unsigned DiagID = IsCompare
13550 ? diag::warn_address_of_reference_null_compare
13551 : diag::warn_address_of_reference_bool_conversion;
13559 auto ComplainAboutNonnullParamOrCall = [&](
const Attr *NonnullAttr) {
13562 llvm::raw_string_ostream S(Str);
13564 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
13565 : diag::warn_cast_nonnull_to_bool;
13568 Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
13573 if (
auto *Callee =
Call->getDirectCallee()) {
13574 if (
const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
13575 ComplainAboutNonnullParamOrCall(A);
13584 if (
const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
13585 if (
const auto *MRecordDecl = MCallExpr->getRecordDecl();
13586 MRecordDecl && MRecordDecl->isLambda()) {
13589 << MRecordDecl->getSourceRange() << Range << IsEqual;
13599 }
else if (
MemberExpr *M = dyn_cast<MemberExpr>(E)) {
13600 D = M->getMemberDecl();
13608 if (
const auto* PV = dyn_cast<ParmVarDecl>(D)) {
13611 if (
const Attr *A = PV->getAttr<NonNullAttr>()) {
13612 ComplainAboutNonnullParamOrCall(A);
13616 if (
const auto *FD = dyn_cast<FunctionDecl>(PV->getDeclContext())) {
13620 auto ParamIter = llvm::find(FD->
parameters(), PV);
13622 unsigned ParamNo = std::distance(FD->
param_begin(), ParamIter);
13626 ComplainAboutNonnullParamOrCall(
NonNull);
13631 if (ArgNo.getASTIndex() == ParamNo) {
13632 ComplainAboutNonnullParamOrCall(
NonNull);
13642 const bool IsArray =
T->isArrayType();
13643 const bool IsFunction =
T->isFunctionType();
13646 if (IsAddressOf && IsFunction) {
13651 if (!IsAddressOf && !IsFunction && !IsArray)
13656 llvm::raw_string_ostream S(Str);
13659 unsigned DiagID = IsCompare ? diag::warn_null_pointer_compare
13660 : diag::warn_impcast_pointer_to_bool;
13667 DiagType = AddressOf;
13668 else if (IsFunction)
13669 DiagType = FunctionPointer;
13671 DiagType = ArrayPointer;
13673 llvm_unreachable(
"Could not determine diagnostic.");
13675 << Range << IsEqual;
13688 if (ReturnType.
isNull())
13726 CheckArrayAccess(E);
13736void Sema::CheckForIntOverflow (
const Expr *E) {
13738 SmallVector<const Expr *, 2> Exprs(1, E);
13741 const Expr *OriginalE = Exprs.pop_back_val();
13749 if (
const auto *InitList = dyn_cast<InitListExpr>(OriginalE))
13750 Exprs.append(InitList->inits().begin(), InitList->inits().end());
13753 else if (
const auto *
Call = dyn_cast<CallExpr>(E))
13754 Exprs.append(
Call->arg_begin(),
Call->arg_end());
13755 else if (
const auto *Message = dyn_cast<ObjCMessageExpr>(E))
13757 else if (
const auto *Construct = dyn_cast<CXXConstructExpr>(E))
13758 Exprs.append(Construct->arg_begin(), Construct->arg_end());
13759 else if (
const auto *Temporary = dyn_cast<CXXBindTemporaryExpr>(E))
13760 Exprs.push_back(Temporary->getSubExpr());
13761 else if (
const auto *Array = dyn_cast<ArraySubscriptExpr>(E))
13762 Exprs.push_back(Array->getIdx());
13763 else if (
const auto *Compound = dyn_cast<CompoundLiteralExpr>(E))
13764 Exprs.push_back(Compound->getInitializer());
13765 else if (
const auto *
New = dyn_cast<CXXNewExpr>(E);
13766 New &&
New->isArray()) {
13767 if (
auto ArraySize =
New->getArraySize())
13768 Exprs.push_back(*ArraySize);
13769 }
else if (
const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(OriginalE))
13770 Exprs.push_back(MTE->getSubExpr());
13771 }
while (!Exprs.empty());
13779 using Base = ConstEvaluatedExprVisitor<SequenceChecker>;
13786 class SequenceTree {
13788 explicit Value(
unsigned Parent) : Parent(Parent), Merged(
false) {}
13789 unsigned Parent : 31;
13790 LLVM_PREFERRED_TYPE(
bool)
13791 unsigned Merged : 1;
13793 SmallVector<Value, 8> Values;
13799 friend class SequenceTree;
13803 explicit Seq(
unsigned N) : Index(N) {}
13806 Seq() : Index(0) {}
13809 SequenceTree() { Values.push_back(
Value(0)); }
13810 Seq root()
const {
return Seq(0); }
13815 Seq allocate(
Seq Parent) {
13816 Values.push_back(
Value(Parent.Index));
13817 return Seq(Values.size() - 1);
13822 Values[S.Index].Merged =
true;
13828 bool isUnsequenced(
Seq Cur,
Seq Old) {
13829 unsigned C = representative(Cur.Index);
13830 unsigned Target = representative(Old.Index);
13834 C = Values[
C].Parent;
13841 unsigned representative(
unsigned K) {
13842 if (Values[K].Merged)
13844 return Values[K].Parent = representative(Values[K].Parent);
13850 using Object =
const NamedDecl *;
13864 UK_ModAsSideEffect,
13866 UK_Count = UK_ModAsSideEffect + 1
13872 const Expr *UsageExpr =
nullptr;
13873 SequenceTree::Seq
Seq;
13879 Usage Uses[UK_Count];
13882 bool Diagnosed =
false;
13886 using UsageInfoMap = llvm::SmallDenseMap<Object, UsageInfo, 16>;
13894 UsageInfoMap UsageMap;
13897 SequenceTree::Seq Region;
13901 SmallVectorImpl<std::pair<Object, Usage>> *ModAsSideEffect =
nullptr;
13905 SmallVectorImpl<const Expr *> &WorkList;
13912 struct SequencedSubexpression {
13913 SequencedSubexpression(SequenceChecker &
Self)
13914 :
Self(
Self), OldModAsSideEffect(
Self.ModAsSideEffect) {
13915 Self.ModAsSideEffect = &ModAsSideEffect;
13918 ~SequencedSubexpression() {
13919 for (
const std::pair<Object, Usage> &M : llvm::reverse(ModAsSideEffect)) {
13923 UsageInfo &UI =
Self.UsageMap[M.first];
13924 auto &SideEffectUsage = UI.Uses[UK_ModAsSideEffect];
13925 Self.addUsage(M.first, UI, SideEffectUsage.UsageExpr, UK_ModAsValue);
13926 SideEffectUsage = M.second;
13928 Self.ModAsSideEffect = OldModAsSideEffect;
13931 SequenceChecker &
Self;
13932 SmallVector<std::pair<Object, Usage>, 4> ModAsSideEffect;
13933 SmallVectorImpl<std::pair<Object, Usage>> *OldModAsSideEffect;
13940 class EvaluationTracker {
13942 EvaluationTracker(SequenceChecker &
Self)
13944 Self.EvalTracker =
this;
13947 ~EvaluationTracker() {
13948 Self.EvalTracker = Prev;
13950 Prev->EvalOK &= EvalOK;
13953 bool evaluate(
const Expr *E,
bool &
Result) {
13958 Self.SemaRef.isConstantEvaluatedContext());
13963 SequenceChecker &
Self;
13964 EvaluationTracker *Prev;
13965 bool EvalOK =
true;
13966 } *EvalTracker =
nullptr;
13970 Object getObject(
const Expr *E,
bool Mod)
const {
13972 if (
const UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
13973 if (Mod && (UO->getOpcode() == UO_PreInc || UO->getOpcode() == UO_PreDec))
13974 return getObject(UO->getSubExpr(), Mod);
13975 }
else if (
const BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
13976 if (BO->getOpcode() == BO_Comma)
13977 return getObject(BO->getRHS(), Mod);
13978 if (Mod && BO->isAssignmentOp())
13979 return getObject(BO->getLHS(), Mod);
13980 }
else if (
const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
13983 return ME->getMemberDecl();
13984 }
else if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
13993 void addUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr, UsageKind UK) {
13995 Usage &U = UI.Uses[UK];
13996 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq)) {
14000 if (UK == UK_ModAsSideEffect && ModAsSideEffect)
14001 ModAsSideEffect->push_back(std::make_pair(O, U));
14003 U.UsageExpr = UsageExpr;
14013 void checkUsage(Object O, UsageInfo &UI,
const Expr *UsageExpr,
14014 UsageKind OtherKind,
bool IsModMod) {
14018 const Usage &U = UI.Uses[OtherKind];
14019 if (!U.UsageExpr || !Tree.isUnsequenced(Region, U.Seq))
14022 const Expr *Mod = U.UsageExpr;
14023 const Expr *ModOrUse = UsageExpr;
14024 if (OtherKind == UK_Use)
14025 std::swap(Mod, ModOrUse);
14029 SemaRef.
PDiag(IsModMod ? diag::warn_unsequenced_mod_mod
14030 : diag::warn_unsequenced_mod_use)
14031 << O << SourceRange(ModOrUse->
getExprLoc()));
14032 UI.Diagnosed =
true;
14061 void notePreUse(Object O,
const Expr *UseExpr) {
14062 UsageInfo &UI = UsageMap[O];
14064 checkUsage(O, UI, UseExpr, UK_ModAsValue,
false);
14067 void notePostUse(Object O,
const Expr *UseExpr) {
14068 UsageInfo &UI = UsageMap[O];
14069 checkUsage(O, UI, UseExpr, UK_ModAsSideEffect,
14071 addUsage(O, UI, UseExpr, UK_Use);
14074 void notePreMod(Object O,
const Expr *ModExpr) {
14075 UsageInfo &UI = UsageMap[O];
14077 checkUsage(O, UI, ModExpr, UK_ModAsValue,
true);
14078 checkUsage(O, UI, ModExpr, UK_Use,
false);
14081 void notePostMod(Object O,
const Expr *ModExpr, UsageKind UK) {
14082 UsageInfo &UI = UsageMap[O];
14083 checkUsage(O, UI, ModExpr, UK_ModAsSideEffect,
14085 addUsage(O, UI, ModExpr, UK);
14089 SequenceChecker(Sema &S,
const Expr *E,
14090 SmallVectorImpl<const Expr *> &WorkList)
14091 :
Base(S.Context), SemaRef(S), Region(Tree.root()), WorkList(WorkList) {
14095 (void)this->WorkList;
14098 void VisitStmt(
const Stmt *S) {
14102 void VisitExpr(
const Expr *E) {
14104 Base::VisitStmt(E);
14107 void VisitCoroutineSuspendExpr(
const CoroutineSuspendExpr *CSE) {
14108 for (
auto *Sub : CSE->
children()) {
14109 const Expr *ChildExpr = dyn_cast_or_null<Expr>(Sub);
14124 void VisitCastExpr(
const CastExpr *E) {
14136 void VisitSequencedExpressions(
const Expr *SequencedBefore,
14137 const Expr *SequencedAfter) {
14138 SequenceTree::Seq BeforeRegion = Tree.allocate(Region);
14139 SequenceTree::Seq AfterRegion = Tree.allocate(Region);
14140 SequenceTree::Seq OldRegion = Region;
14143 SequencedSubexpression SeqBefore(*
this);
14144 Region = BeforeRegion;
14145 Visit(SequencedBefore);
14148 Region = AfterRegion;
14149 Visit(SequencedAfter);
14151 Region = OldRegion;
14153 Tree.merge(BeforeRegion);
14154 Tree.merge(AfterRegion);
14157 void VisitArraySubscriptExpr(
const ArraySubscriptExpr *ASE) {
14162 VisitSequencedExpressions(ASE->
getLHS(), ASE->
getRHS());
14169 void VisitBinPtrMemD(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14170 void VisitBinPtrMemI(
const BinaryOperator *BO) { VisitBinPtrMem(BO); }
14171 void VisitBinPtrMem(
const BinaryOperator *BO) {
14176 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14183 void VisitBinShl(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14184 void VisitBinShr(
const BinaryOperator *BO) { VisitBinShlShr(BO); }
14185 void VisitBinShlShr(
const BinaryOperator *BO) {
14189 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14196 void VisitBinComma(
const BinaryOperator *BO) {
14201 VisitSequencedExpressions(BO->
getLHS(), BO->
getRHS());
14204 void VisitBinAssign(
const BinaryOperator *BO) {
14205 SequenceTree::Seq RHSRegion;
14206 SequenceTree::Seq LHSRegion;
14208 RHSRegion = Tree.allocate(Region);
14209 LHSRegion = Tree.allocate(Region);
14211 RHSRegion = Region;
14212 LHSRegion = Region;
14214 SequenceTree::Seq OldRegion = Region;
14230 SequencedSubexpression SeqBefore(*
this);
14231 Region = RHSRegion;
14235 Region = LHSRegion;
14239 notePostUse(O, BO);
14243 Region = LHSRegion;
14247 notePostUse(O, BO);
14249 Region = RHSRegion;
14257 Region = OldRegion;
14261 : UK_ModAsSideEffect);
14263 Tree.merge(RHSRegion);
14264 Tree.merge(LHSRegion);
14268 void VisitCompoundAssignOperator(
const CompoundAssignOperator *CAO) {
14269 VisitBinAssign(CAO);
14272 void VisitUnaryPreInc(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14273 void VisitUnaryPreDec(
const UnaryOperator *UO) { VisitUnaryPreIncDec(UO); }
14274 void VisitUnaryPreIncDec(
const UnaryOperator *UO) {
14277 return VisitExpr(UO);
14285 : UK_ModAsSideEffect);
14288 void VisitUnaryPostInc(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14289 void VisitUnaryPostDec(
const UnaryOperator *UO) { VisitUnaryPostIncDec(UO); }
14290 void VisitUnaryPostIncDec(
const UnaryOperator *UO) {
14293 return VisitExpr(UO);
14297 notePostMod(O, UO, UK_ModAsSideEffect);
14300 void VisitBinLOr(
const BinaryOperator *BO) {
14306 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14307 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14308 SequenceTree::Seq OldRegion = Region;
14310 EvaluationTracker Eval(*
this);
14312 SequencedSubexpression Sequenced(*
this);
14313 Region = LHSRegion;
14320 bool EvalResult =
false;
14321 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14322 bool ShouldVisitRHS = !EvalOK || !EvalResult;
14323 if (ShouldVisitRHS) {
14324 Region = RHSRegion;
14328 Region = OldRegion;
14329 Tree.merge(LHSRegion);
14330 Tree.merge(RHSRegion);
14333 void VisitBinLAnd(
const BinaryOperator *BO) {
14339 SequenceTree::Seq LHSRegion = Tree.allocate(Region);
14340 SequenceTree::Seq RHSRegion = Tree.allocate(Region);
14341 SequenceTree::Seq OldRegion = Region;
14343 EvaluationTracker Eval(*
this);
14345 SequencedSubexpression Sequenced(*
this);
14346 Region = LHSRegion;
14352 bool EvalResult =
false;
14353 bool EvalOK = Eval.evaluate(BO->
getLHS(), EvalResult);
14354 bool ShouldVisitRHS = !EvalOK || EvalResult;
14355 if (ShouldVisitRHS) {
14356 Region = RHSRegion;
14360 Region = OldRegion;
14361 Tree.merge(LHSRegion);
14362 Tree.merge(RHSRegion);
14365 void VisitAbstractConditionalOperator(
const AbstractConditionalOperator *CO) {
14370 SequenceTree::Seq ConditionRegion = Tree.allocate(Region);
14386 SequenceTree::Seq TrueRegion = Tree.allocate(Region);
14387 SequenceTree::Seq FalseRegion = Tree.allocate(Region);
14388 SequenceTree::Seq OldRegion = Region;
14390 EvaluationTracker Eval(*
this);
14392 SequencedSubexpression Sequenced(*
this);
14393 Region = ConditionRegion;
14403 bool EvalResult =
false;
14404 bool EvalOK = Eval.evaluate(CO->
getCond(), EvalResult);
14405 bool ShouldVisitTrueExpr = !EvalOK || EvalResult;
14406 bool ShouldVisitFalseExpr = !EvalOK || !EvalResult;
14407 if (ShouldVisitTrueExpr) {
14408 Region = TrueRegion;
14411 if (ShouldVisitFalseExpr) {
14412 Region = FalseRegion;
14416 Region = OldRegion;
14417 Tree.merge(ConditionRegion);
14418 Tree.merge(TrueRegion);
14419 Tree.merge(FalseRegion);
14422 void VisitCallExpr(
const CallExpr *CE) {
14434 SequencedSubexpression Sequenced(*
this);
14439 SequenceTree::Seq CalleeRegion;
14440 SequenceTree::Seq OtherRegion;
14441 if (SemaRef.getLangOpts().CPlusPlus17) {
14442 CalleeRegion = Tree.allocate(Region);
14443 OtherRegion = Tree.allocate(Region);
14445 CalleeRegion = Region;
14446 OtherRegion = Region;
14448 SequenceTree::Seq OldRegion = Region;
14451 Region = CalleeRegion;
14453 SequencedSubexpression Sequenced(*this);
14454 Visit(CE->getCallee());
14456 Visit(CE->getCallee());
14460 Region = OtherRegion;
14464 Region = OldRegion;
14466 Tree.merge(CalleeRegion);
14467 Tree.merge(OtherRegion);
14485 return VisitCallExpr(CXXOCE);
14496 case OO_MinusEqual:
14498 case OO_SlashEqual:
14499 case OO_PercentEqual:
14500 case OO_CaretEqual:
14503 case OO_LessLessEqual:
14504 case OO_GreaterGreaterEqual:
14505 SequencingKind = RHSBeforeLHS;
14509 case OO_GreaterGreater:
14515 SequencingKind = LHSBeforeRHS;
14519 SequencingKind = LHSBeforeRest;
14523 SequencingKind = NoSequencing;
14527 if (SequencingKind == NoSequencing)
14528 return VisitCallExpr(CXXOCE);
14531 SequencedSubexpression Sequenced(*
this);
14534 assert(SemaRef.getLangOpts().CPlusPlus17 &&
14535 "Should only get there with C++17 and above!");
14536 assert((CXXOCE->getNumArgs() == 2 || CXXOCE->getOperator() == OO_Call) &&
14537 "Should only get there with an overloaded binary operator"
14538 " or an overloaded call operator!");
14540 if (SequencingKind == LHSBeforeRest) {
14541 assert(CXXOCE->getOperator() == OO_Call &&
14542 "We should only have an overloaded call operator here!");
14551 SequenceTree::Seq PostfixExprRegion = Tree.allocate(Region);
14552 SequenceTree::Seq ArgsRegion = Tree.allocate(Region);
14553 SequenceTree::Seq OldRegion = Region;
14555 assert(CXXOCE->getNumArgs() >= 1 &&
14556 "An overloaded call operator must have at least one argument"
14557 " for the postfix-expression!");
14558 const Expr *PostfixExpr = CXXOCE->getArgs()[0];
14559 llvm::ArrayRef<const Expr *> Args(CXXOCE->getArgs() + 1,
14560 CXXOCE->getNumArgs() - 1);
14564 Region = PostfixExprRegion;
14565 SequencedSubexpression Sequenced(*this);
14566 Visit(PostfixExpr);
14570 Region = ArgsRegion;
14571 for (const Expr *Arg : Args)
14574 Region = OldRegion;
14575 Tree.merge(PostfixExprRegion);
14576 Tree.merge(ArgsRegion);
14578 assert(CXXOCE->getNumArgs() == 2 &&
14579 "Should only have two arguments here!");
14580 assert((SequencingKind == LHSBeforeRHS ||
14581 SequencingKind == RHSBeforeLHS) &&
14582 "Unexpected sequencing kind!");
14586 const Expr *E1 = CXXOCE->getArg(0);
14587 const Expr *E2 = CXXOCE->getArg(1);
14588 if (SequencingKind == RHSBeforeLHS)
14591 return VisitSequencedExpressions(E1, E2);
14598 SequencedSubexpression Sequenced(*
this);
14601 return VisitExpr(CCE);
14604 SequenceExpressionsInOrder(
14610 return VisitExpr(ILE);
14613 SequenceExpressionsInOrder(ILE->
inits());
14625 SequenceTree::Seq Parent = Region;
14626 for (
const Expr *E : ExpressionList) {
14629 Region = Tree.allocate(Parent);
14630 Elts.push_back(Region);
14636 for (
unsigned I = 0; I < Elts.size(); ++I)
14637 Tree.merge(Elts[I]);
14641SequenceChecker::UsageInfo::UsageInfo() =
default;
14645void Sema::CheckUnsequencedOperations(
const Expr *E) {
14646 SmallVector<const Expr *, 8> WorkList;
14647 WorkList.push_back(E);
14648 while (!WorkList.empty()) {
14649 const Expr *Item = WorkList.pop_back_val();
14650 SequenceChecker(*
this, Item, WorkList);
14655 bool IsConstexpr) {
14658 CheckImplicitConversions(E, CheckLoc);
14660 CheckUnsequencedOperations(E);
14662 CheckForIntOverflow(E);
14675 if (
const auto *PointerTy = dyn_cast<PointerType>(PType)) {
14679 if (
const auto *ReferenceTy = dyn_cast<ReferenceType>(PType)) {
14683 if (
const auto *ParenTy = dyn_cast<ParenType>(PType)) {
14697 S.
Diag(Loc, diag::err_array_star_in_function_definition);
14701 bool CheckParameterNames) {
14702 bool HasInvalidParm =
false;
14704 assert(Param &&
"null in a parameter list");
14713 if (!Param->isInvalidDecl() &&
14715 diag::err_typecheck_decl_incomplete_type) ||
14717 diag::err_abstract_type_in_decl,
14719 Param->setInvalidDecl();
14720 HasInvalidParm =
true;
14725 if (CheckParameterNames && Param->getIdentifier() ==
nullptr &&
14729 Diag(Param->getLocation(), diag::ext_parameter_name_omitted_c23);
14737 QualType PType = Param->getOriginalType();
14745 if (!Param->isInvalidDecl()) {
14746 if (
CXXRecordDecl *ClassDecl = Param->getType()->getAsCXXRecordDecl()) {
14747 if (!ClassDecl->isInvalidDecl() &&
14748 !ClassDecl->hasIrrelevantDestructor() &&
14749 !ClassDecl->isDependentContext() &&
14750 ClassDecl->isParamDestroyedInCallee()) {
14762 if (
const auto *
Attr = Param->getAttr<PassObjectSizeAttr>())
14763 if (!Param->getType().isConstQualified())
14764 Diag(Param->getLocation(), diag::err_attribute_pointers_only)
14768 if (
LangOpts.CPlusPlus && !Param->isInvalidDecl()) {
14773 if (
auto *RD = dyn_cast<CXXRecordDecl>(DC->
getParent()))
14774 CheckShadowInheritedFields(Param->getLocation(), Param->getDeclName(),
14779 if (!Param->isInvalidDecl() &&
14780 Param->getOriginalType()->isWebAssemblyTableType()) {
14781 Param->setInvalidDecl();
14782 HasInvalidParm =
true;
14783 Diag(Param->getLocation(), diag::err_wasm_table_as_function_parameter);
14787 return HasInvalidParm;
14790std::optional<std::pair<
14799static std::pair<CharUnits, CharUnits>
14807 if (
Base->isVirtual()) {
14814 BaseAlignment = std::min(BaseAlignment, NonVirtualAlignment);
14821 DerivedType =
Base->getType();
14824 return std::make_pair(BaseAlignment, Offset);
14828static std::optional<std::pair<CharUnits, CharUnits>>
14834 return std::nullopt;
14839 return std::nullopt;
14843 CharUnits Offset = EltSize * IdxRes->getExtValue();
14846 return std::make_pair(P->first, P->second + Offset);
14852 return std::make_pair(
14853 P->first.alignmentAtOffset(P->second).alignmentAtOffset(EltSize),
14859std::optional<std::pair<
14867 case Stmt::CStyleCastExprClass:
14868 case Stmt::CXXStaticCastExprClass:
14869 case Stmt::ImplicitCastExprClass: {
14871 const Expr *From = CE->getSubExpr();
14872 switch (CE->getCastKind()) {
14877 case CK_UncheckedDerivedToBase:
14878 case CK_DerivedToBase: {
14888 case Stmt::ArraySubscriptExprClass: {
14893 case Stmt::DeclRefExprClass: {
14897 if (!VD->getType()->isReferenceType()) {
14899 if (VD->hasDependentAlignment())
14908 case Stmt::MemberExprClass: {
14910 auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl());
14914 std::optional<std::pair<CharUnits, CharUnits>> P;
14923 return std::make_pair(P->first,
14926 case Stmt::UnaryOperatorClass: {
14936 case Stmt::BinaryOperatorClass: {
14948 return std::nullopt;
14953std::optional<std::pair<
14962 case Stmt::CStyleCastExprClass:
14963 case Stmt::CXXStaticCastExprClass:
14964 case Stmt::ImplicitCastExprClass: {
14966 const Expr *From = CE->getSubExpr();
14967 switch (CE->getCastKind()) {
14972 case CK_ArrayToPointerDecay:
14974 case CK_UncheckedDerivedToBase:
14975 case CK_DerivedToBase: {
14985 case Stmt::CXXThisExprClass: {
14990 case Stmt::UnaryOperatorClass: {
14996 case Stmt::BinaryOperatorClass: {
15005 if (Opcode == BO_Add && !RHS->getType()->isIntegralOrEnumerationType())
15006 std::swap(LHS, RHS);
15016 return std::nullopt;
15021 std::optional<std::pair<CharUnits, CharUnits>> P =
15025 return P->first.alignmentAtOffset(P->second);
15043 if (!DestPtr)
return;
15049 if (DestAlign.
isOne())
return;
15053 if (!SrcPtr)
return;
15064 if (SrcAlign >= DestAlign)
return;
15069 <<
static_cast<unsigned>(DestAlign.
getQuantity())
15073void Sema::CheckArrayAccess(
const Expr *BaseExpr,
const Expr *IndexExpr,
15075 bool AllowOnePastEnd,
bool IndexNegated) {
15084 const Type *EffectiveType =
15088 Context.getAsConstantArrayType(BaseExpr->
getType());
15091 StrictFlexArraysLevel =
getLangOpts().getStrictFlexArraysLevel();
15093 const Type *BaseType =
15095 bool IsUnboundedArray =
15097 Context, StrictFlexArraysLevel,
15100 (!IsUnboundedArray && BaseType->isDependentType()))
15108 if (IndexNegated) {
15109 index.setIsUnsigned(
false);
15113 if (IsUnboundedArray) {
15116 if (
index.isUnsigned() || !
index.isNegative()) {
15118 unsigned AddrBits = ASTC.getTargetInfo().getPointerWidth(
15120 if (
index.getBitWidth() < AddrBits)
15122 std::optional<CharUnits> ElemCharUnits =
15123 ASTC.getTypeSizeInCharsIfKnown(EffectiveType);
15126 if (!ElemCharUnits || ElemCharUnits->isZero())
15128 llvm::APInt ElemBytes(
index.getBitWidth(), ElemCharUnits->getQuantity());
15133 if (
index.getActiveBits() <= AddrBits) {
15135 llvm::APInt Product(
index);
15137 Product = Product.umul_ov(ElemBytes, Overflow);
15138 if (!Overflow && Product.getActiveBits() <= AddrBits)
15144 llvm::APInt MaxElems = llvm::APInt::getMaxValue(AddrBits);
15145 MaxElems = MaxElems.zext(std::max(AddrBits + 1, ElemBytes.getBitWidth()));
15147 ElemBytes = ElemBytes.zextOrTrunc(MaxElems.getBitWidth());
15148 MaxElems = MaxElems.udiv(ElemBytes);
15151 ASE ? diag::warn_array_index_exceeds_max_addressable_bounds
15152 : diag::warn_ptr_arith_exceeds_max_addressable_bounds;
15157 PDiag(DiagID) << index << AddrBits
15158 << (
unsigned)ASTC.toBits(*ElemCharUnits)
15159 << ElemBytes << MaxElems
15160 << MaxElems.getZExtValue()
15163 const NamedDecl *ND =
nullptr;
15165 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15167 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15169 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15170 ND = ME->getMemberDecl();
15174 PDiag(diag::note_array_declared_here) << ND);
15179 if (index.isUnsigned() || !index.isNegative()) {
15189 llvm::APInt size = ArrayTy->
getSize();
15191 if (BaseType != EffectiveType) {
15199 if (!ptrarith_typesize)
15200 ptrarith_typesize =
Context.getCharWidth();
15202 if (ptrarith_typesize != array_typesize) {
15204 uint64_t ratio = array_typesize / ptrarith_typesize;
15208 if (ptrarith_typesize * ratio == array_typesize)
15209 size *= llvm::APInt(size.getBitWidth(), ratio);
15213 if (size.getBitWidth() > index.getBitWidth())
15214 index = index.zext(size.getBitWidth());
15215 else if (size.getBitWidth() < index.getBitWidth())
15216 size = size.zext(index.getBitWidth());
15222 if (AllowOnePastEnd ? index.ule(size) : index.ult(size))
15229 SourceLocation RBracketLoc =
SourceMgr.getSpellingLoc(
15231 if (
SourceMgr.isInSystemHeader(RBracketLoc)) {
15232 SourceLocation IndexLoc =
15234 if (
SourceMgr.isWrittenInSameFile(RBracketLoc, IndexLoc))
15239 unsigned DiagID = ASE ? diag::warn_array_index_exceeds_bounds
15240 : diag::warn_ptr_arith_exceeds_bounds;
15241 unsigned CastMsg = (!ASE || BaseType == EffectiveType) ? 0 : 1;
15242 QualType CastMsgTy = ASE ? ASE->
getLHS()->
getType() : QualType();
15246 << index << ArrayTy->
desugar() << CastMsg
15249 unsigned DiagID = diag::warn_array_index_precedes_bounds;
15251 DiagID = diag::warn_ptr_arith_precedes_bounds;
15252 if (index.isNegative()) index = -index;
15259 const NamedDecl *ND =
nullptr;
15261 while (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(BaseExpr))
15263 if (
const auto *DRE = dyn_cast<DeclRefExpr>(BaseExpr))
15265 if (
const auto *ME = dyn_cast<MemberExpr>(BaseExpr))
15266 ND = ME->getMemberDecl();
15270 PDiag(diag::note_array_declared_here) << ND);
15273void Sema::CheckArrayAccess(
const Expr *
expr) {
15274 int AllowOnePastEnd = 0;
15276 expr =
expr->IgnoreParenImpCasts();
15277 switch (
expr->getStmtClass()) {
15278 case Stmt::ArraySubscriptExprClass: {
15281 AllowOnePastEnd > 0);
15285 case Stmt::MemberExprClass: {
15289 case Stmt::ArraySectionExprClass: {
15295 nullptr, AllowOnePastEnd > 0);
15298 case Stmt::UnaryOperatorClass: {
15314 case Stmt::ConditionalOperatorClass: {
15316 if (
const Expr *lhs = cond->
getLHS())
15317 CheckArrayAccess(lhs);
15318 if (
const Expr *rhs = cond->
getRHS())
15319 CheckArrayAccess(rhs);
15322 case Stmt::CXXOperatorCallExprClass: {
15324 for (
const auto *Arg : OCE->arguments())
15325 CheckArrayAccess(Arg);
15335 Expr *RHS,
bool isProperty) {
15347 S.
Diag(Loc, diag::warn_arc_literal_assign)
15349 << (isProperty ? 0 : 1)
15357 Expr *RHS,
bool isProperty) {
15360 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15361 S.
Diag(Loc, diag::warn_arc_retained_assign)
15363 << (isProperty ? 0 : 1)
15367 RHS =
cast->getSubExpr();
15409 if (!
Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
15438 if (
cast->getCastKind() == CK_ARCConsumeObject) {
15439 Diag(Loc, diag::warn_arc_retained_property_assign)
15443 RHS =
cast->getSubExpr();
15466 bool StmtLineInvalid;
15467 unsigned StmtLine = SourceMgr.getPresumedLineNumber(StmtLoc,
15469 if (StmtLineInvalid)
15472 bool BodyLineInvalid;
15473 unsigned BodyLine = SourceMgr.getSpellingLineNumber(Body->
getSemiLoc(),
15475 if (BodyLineInvalid)
15479 if (StmtLine != BodyLine)
15494 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15503 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15507 const Stmt *PossibleBody) {
15513 if (
const ForStmt *FS = dyn_cast<ForStmt>(S)) {
15514 StmtLoc = FS->getRParenLoc();
15515 Body = FS->getBody();
15516 DiagID = diag::warn_empty_for_body;
15517 }
else if (
const WhileStmt *WS = dyn_cast<WhileStmt>(S)) {
15518 StmtLoc = WS->getRParenLoc();
15519 Body = WS->getBody();
15520 DiagID = diag::warn_empty_while_body;
15525 const NullStmt *NBody = dyn_cast<NullStmt>(Body);
15549 if (!ProbableTypo) {
15550 bool BodyColInvalid;
15551 unsigned BodyCol =
SourceMgr.getPresumedColumnNumber(
15553 if (BodyColInvalid)
15556 bool StmtColInvalid;
15559 if (StmtColInvalid)
15562 if (BodyCol > StmtCol)
15563 ProbableTypo =
true;
15566 if (ProbableTypo) {
15568 Diag(NBody->
getSemiLoc(), diag::note_empty_body_on_separate_line);
15576 if (
Diags.isIgnored(diag::warn_sizeof_pointer_expr_memaccess, OpLoc))
15588 if (
const auto *CE = dyn_cast<CallExpr>(RHSExpr);
15590 RHSExpr = CE->
getArg(0);
15591 else if (
const auto *CXXSCE = dyn_cast<CXXStaticCastExpr>(RHSExpr);
15592 CXXSCE && CXXSCE->isXValue())
15593 RHSExpr = CXXSCE->getSubExpr();
15597 const DeclRefExpr *LHSDeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
15598 const DeclRefExpr *RHSDeclRef = dyn_cast<DeclRefExpr>(RHSExpr);
15601 if (LHSDeclRef && RHSDeclRef) {
15608 auto D =
Diag(OpLoc, diag::warn_self_move)
15624 const Expr *LHSBase = LHSExpr;
15625 const Expr *RHSBase = RHSExpr;
15626 const MemberExpr *LHSME = dyn_cast<MemberExpr>(LHSExpr);
15627 const MemberExpr *RHSME = dyn_cast<MemberExpr>(RHSExpr);
15628 if (!LHSME || !RHSME)
15631 while (LHSME && RHSME) {
15638 LHSME = dyn_cast<MemberExpr>(LHSBase);
15639 RHSME = dyn_cast<MemberExpr>(RHSBase);
15642 LHSDeclRef = dyn_cast<DeclRefExpr>(LHSBase);
15643 RHSDeclRef = dyn_cast<DeclRefExpr>(RHSBase);
15644 if (LHSDeclRef && RHSDeclRef) {
15651 Diag(OpLoc, diag::warn_self_move)
15658 Diag(OpLoc, diag::warn_self_move)
15682 bool AreUnionMembers =
false) {
15686 assert(((Field1Parent->isStructureOrClassType() &&
15687 Field2Parent->isStructureOrClassType()) ||
15688 (Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
15689 "Can't evaluate layout compatibility between a struct field and a "
15691 assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
15692 (AreUnionMembers && Field1Parent->isUnionType())) &&
15693 "AreUnionMembers should be 'true' for union fields (only).");
15707 if (Bits1 != Bits2)
15711 if (Field1->
hasAttr<clang::NoUniqueAddressAttr>() ||
15712 Field2->
hasAttr<clang::NoUniqueAddressAttr>())
15715 if (!AreUnionMembers &&
15727 if (
const CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(RD1))
15728 RD1 = D1CXX->getStandardLayoutBaseWithFields();
15730 if (
const CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(RD2))
15731 RD2 = D2CXX->getStandardLayoutBaseWithFields();
15736 return isLayoutCompatible(C, F1, F2);
15747 for (
auto *Field1 : RD1->
fields()) {
15748 auto I = UnmatchedFields.begin();
15749 auto E = UnmatchedFields.end();
15751 for ( ; I != E; ++I) {
15753 bool Result = UnmatchedFields.erase(*I);
15763 return UnmatchedFields.empty();
15789 if (
C.hasSameType(T1, T2))
15798 if (TC1 == Type::Enum)
15800 if (TC1 == Type::Record) {
15819 QualType BaseT =
Base->getType()->getCanonicalTypeUnqualified();
15850 const ValueDecl **VD, uint64_t *MagicValue,
15851 bool isConstantEvaluated) {
15859 case Stmt::UnaryOperatorClass: {
15868 case Stmt::DeclRefExprClass: {
15874 case Stmt::IntegerLiteralClass: {
15876 llvm::APInt MagicValueAPInt = IL->
getValue();
15877 if (MagicValueAPInt.getActiveBits() <= 64) {
15878 *MagicValue = MagicValueAPInt.getZExtValue();
15884 case Stmt::BinaryConditionalOperatorClass:
15885 case Stmt::ConditionalOperatorClass: {
15890 isConstantEvaluated)) {
15900 case Stmt::BinaryOperatorClass: {
15903 TypeExpr = BO->
getRHS();
15933 const llvm::DenseMap<Sema::TypeTagMagicValue, Sema::TypeTagData>
15936 bool isConstantEvaluated) {
15937 FoundWrongKind =
false;
15942 uint64_t MagicValue;
15944 if (!
FindTypeTagExpr(TypeExpr, Ctx, &VD, &MagicValue, isConstantEvaluated))
15948 if (TypeTagForDatatypeAttr *I = VD->
getAttr<TypeTagForDatatypeAttr>()) {
15949 if (I->getArgumentKind() != ArgumentKind) {
15950 FoundWrongKind =
true;
15953 TypeInfo.Type = I->getMatchingCType();
15954 TypeInfo.LayoutCompatible = I->getLayoutCompatible();
15955 TypeInfo.MustBeNull = I->getMustBeNull();
15966 MagicValues->find(std::make_pair(ArgumentKind, MagicValue));
15967 if (I == MagicValues->end())
15976 bool LayoutCompatible,
15978 if (!TypeTagForDatatypeMagicValues)
15979 TypeTagForDatatypeMagicValues.reset(
15980 new llvm::DenseMap<TypeTagMagicValue, TypeTagData>);
15983 (*TypeTagForDatatypeMagicValues)[Magic] =
15999 return (T1Kind == BuiltinType::SChar && T2Kind == BuiltinType::Char_S) ||
16000 (T1Kind == BuiltinType::UChar && T2Kind == BuiltinType::Char_U) ||
16001 (T1Kind == BuiltinType::Char_U && T2Kind == BuiltinType::UChar) ||
16002 (T1Kind == BuiltinType::Char_S && T2Kind == BuiltinType::SChar);
16005void Sema::CheckArgumentWithTypeTag(
const ArgumentWithTypeTagAttr *
Attr,
16008 const IdentifierInfo *ArgumentKind = Attr->getArgumentKind();
16009 bool IsPointerAttr = Attr->getIsPointer();
16012 unsigned TypeTagIdxAST = Attr->getTypeTagIdx().getASTIndex();
16013 if (TypeTagIdxAST >= ExprArgs.size()) {
16014 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16015 << 0 << Attr->getTypeTagIdx().getSourceIndex();
16018 const Expr *TypeTagExpr = ExprArgs[TypeTagIdxAST];
16019 bool FoundWrongKind;
16022 TypeTagForDatatypeMagicValues.get(), FoundWrongKind,
16024 if (FoundWrongKind)
16026 diag::warn_type_tag_for_datatype_wrong_kind)
16032 unsigned ArgumentIdxAST = Attr->getArgumentIdx().getASTIndex();
16033 if (ArgumentIdxAST >= ExprArgs.size()) {
16034 Diag(CallSiteLoc, diag::err_tag_index_out_of_range)
16035 << 1 << Attr->getArgumentIdx().getSourceIndex();
16038 const Expr *ArgumentExpr = ExprArgs[ArgumentIdxAST];
16039 if (IsPointerAttr) {
16041 if (
const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgumentExpr))
16042 if (ICE->getType()->isVoidPointerType() &&
16043 ICE->getCastKind() == CK_BitCast)
16044 ArgumentExpr = ICE->getSubExpr();
16046 QualType ArgumentType = ArgumentExpr->
getType();
16052 if (TypeInfo.MustBeNull) {
16057 diag::warn_type_safety_null_pointer_required)
16065 QualType RequiredType = TypeInfo.Type;
16067 RequiredType =
Context.getPointerType(RequiredType);
16069 bool mismatch =
false;
16070 if (!TypeInfo.LayoutCompatible) {
16071 mismatch = !
Context.hasSameType(ArgumentType, RequiredType);
16092 Diag(ArgumentExpr->
getExprLoc(), diag::warn_type_safety_type_mismatch)
16093 << ArgumentType << ArgumentKind
16094 << TypeInfo.LayoutCompatible << RequiredType
16112 Diag(m.E->getBeginLoc(), diag::warn_taking_address_of_packed_member)
16120 if (!
T->isPointerType() && !
T->isIntegerType() && !
T->isDependentType())
16126 auto &MisalignedMembersForExpr =
16128 auto *MA = llvm::find(MisalignedMembersForExpr, MisalignedMember(Op));
16129 if (MA != MisalignedMembersForExpr.end() &&
16130 (
T->isDependentType() ||
T->isIntegerType() ||
16131 (
T->isPointerType() && (
T->getPointeeType()->isIncompleteType() ||
16133 T->getPointeeType()) <= MA->Alignment))))
16134 MisalignedMembersForExpr.erase(MA);
16143 const auto *ME = dyn_cast<MemberExpr>(E);
16155 bool AnyIsPacked =
false;
16157 QualType BaseType = ME->getBase()->getType();
16158 if (BaseType->isDependentType())
16162 auto *RD = BaseType->castAsRecordDecl();
16167 auto *FD = dyn_cast<FieldDecl>(MD);
16173 AnyIsPacked || (RD->
hasAttr<PackedAttr>() || MD->
hasAttr<PackedAttr>());
16174 ReverseMemberChain.push_back(FD);
16177 ME = dyn_cast<MemberExpr>(ME->getBase()->IgnoreParens());
16179 assert(TopME &&
"We did not compute a topmost MemberExpr!");
16186 const auto *DRE = dyn_cast<DeclRefExpr>(TopBase);
16197 if (ExpectedAlignment.
isOne())
16202 for (
const FieldDecl *FD : llvm::reverse(ReverseMemberChain))
16203 Offset +=
Context.toCharUnitsFromBits(
Context.getFieldOffset(FD));
16207 Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
16211 if (DRE && !TopME->
isArrow()) {
16214 CompleteObjectAlignment =
16215 std::max(CompleteObjectAlignment,
Context.getDeclAlign(VD));
16219 if (!Offset.isMultipleOf(ExpectedAlignment) ||
16222 CompleteObjectAlignment < ExpectedAlignment) {
16233 for (
FieldDecl *FDI : ReverseMemberChain) {
16234 if (FDI->hasAttr<PackedAttr>() ||
16235 FDI->getParent()->hasAttr<PackedAttr>()) {
16237 Alignment = std::min(
Context.getTypeAlignInChars(FD->
getType()),
16243 assert(FD &&
"We did not find a packed FieldDecl!");
16244 Action(E, FD->
getParent(), FD, Alignment);
16248void Sema::CheckAddressOfPackedMember(
Expr *rhs) {
16249 using namespace std::placeholders;
16252 rhs, std::bind(&Sema::AddPotentialMisalignedMembers, std::ref(*
this), _1,
16276bool Sema::BuiltinElementwiseMath(
CallExpr *TheCall,
16277 EltwiseBuiltinArgTyRestriction ArgTyRestr) {
16290 if (
auto *VecTy0 = (*Res)->getAs<
VectorType>())
16291 TheCall->
setType(VecTy0->getElementType());
16304 return S.
Diag(Loc, diag::err_conv_mixed_enum_types)
16321 assert(!Args.empty() &&
"Should have at least one argument.");
16323 Expr *Arg0 = Args.front();
16326 auto EmitError = [&](
Expr *ArgI) {
16328 diag::err_typecheck_call_different_arg_types)
16329 << Arg0->
getType() << ArgI->getType();
16334 for (
Expr *ArgI : Args.drop_front())
16345 for (
Expr *ArgI : Args.drop_front()) {
16346 const auto *VecI = ArgI->getType()->getAs<
VectorType>();
16349 VecI->getElementType()) ||
16350 Vec0->getNumElements() != VecI->getNumElements()) {
16359std::optional<QualType>
16363 return std::nullopt;
16367 return std::nullopt;
16370 for (
int I = 0; I < 2; ++I) {
16374 return std::nullopt;
16375 Args[I] = Converted.
get();
16382 return std::nullopt;
16385 return std::nullopt;
16387 TheCall->
setArg(0, Args[0]);
16388 TheCall->
setArg(1, Args[1]);
16399 TheCall->
getArg(1), Loc) ||
16401 TheCall->
getArg(2), Loc))
16405 for (
int I = 0; I < 3; ++I) {
16410 Args[I] = Converted.
get();
16413 int ArgOrdinal = 1;
16414 for (
Expr *Arg : Args) {
16416 ArgTyRestr, ArgOrdinal++))
16423 for (
int I = 0; I < 3; ++I)
16424 TheCall->
setArg(I, Args[I]);
16430bool Sema::PrepareBuiltinReduceMathOneArgCall(
CallExpr *TheCall) {
16442bool Sema::BuiltinNonDeterministicValue(
CallExpr *TheCall) {
16451 diag::err_builtin_invalid_arg_type)
16452 << 1 << 2 << 1 << 1 << TyArg;
16466 Expr *Matrix = MatrixArg.
get();
16468 auto *MType = Matrix->
getType()->
getAs<ConstantMatrixType>();
16471 << 1 << 3 << 0 << 0
16478 QualType ResultType =
Context.getConstantMatrixType(
16479 MType->getElementType(), MType->getNumColumns(), MType->getNumRows());
16482 TheCall->
setType(ResultType);
16485 TheCall->
setArg(0, Matrix);
16490static std::optional<unsigned>
16498 uint64_t
Dim =
Value->getZExtValue();
16514 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16516 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16524 unsigned PtrArgIdx = 0;
16525 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16526 Expr *RowsExpr = TheCall->
getArg(1);
16527 Expr *ColumnsExpr = TheCall->
getArg(2);
16528 Expr *StrideExpr = TheCall->
getArg(3);
16530 bool ArgError =
false;
16537 PtrExpr = PtrConv.
get();
16538 TheCall->
setArg(0, PtrExpr);
16545 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16546 QualType ElementTy;
16549 << PtrArgIdx + 1 << 0 << 5 << 0
16553 ElementTy = PtrTy->getPointeeType().getUnqualifiedType();
16557 << PtrArgIdx + 1 << 0 << 5
16564 auto ApplyArgumentConversions = [
this](Expr *E) {
16573 ExprResult RowsConv = ApplyArgumentConversions(RowsExpr);
16575 RowsExpr = RowsConv.
get();
16576 TheCall->
setArg(1, RowsExpr);
16578 RowsExpr =
nullptr;
16580 ExprResult ColumnsConv = ApplyArgumentConversions(ColumnsExpr);
16582 ColumnsExpr = ColumnsConv.
get();
16583 TheCall->
setArg(2, ColumnsExpr);
16585 ColumnsExpr =
nullptr;
16596 std::optional<unsigned> MaybeRows;
16600 std::optional<unsigned> MaybeColumns;
16605 ExprResult StrideConv = ApplyArgumentConversions(StrideExpr);
16608 StrideExpr = StrideConv.
get();
16609 TheCall->
setArg(3, StrideExpr);
16612 if (std::optional<llvm::APSInt>
Value =
16615 if (Stride < *MaybeRows) {
16617 diag::err_builtin_matrix_stride_too_small);
16623 if (ArgError || !MaybeRows || !MaybeColumns)
16627 Context.getConstantMatrixType(ElementTy, *MaybeRows, *MaybeColumns));
16638 if (
getLangOpts().getDefaultMatrixMemoryLayout() !=
16640 Diag(TheCall->
getBeginLoc(), diag::err_builtin_matrix_major_order_disabled)
16648 unsigned PtrArgIdx = 1;
16649 Expr *MatrixExpr = TheCall->
getArg(0);
16650 Expr *PtrExpr = TheCall->
getArg(PtrArgIdx);
16651 Expr *StrideExpr = TheCall->
getArg(2);
16653 bool ArgError =
false;
16659 MatrixExpr = MatrixConv.
get();
16660 TheCall->
setArg(0, MatrixExpr);
16667 auto *MatrixTy = MatrixExpr->
getType()->
getAs<ConstantMatrixType>();
16670 << 1 << 3 << 0 << 0 << MatrixExpr->
getType();
16678 PtrExpr = PtrConv.
get();
16679 TheCall->
setArg(1, PtrExpr);
16687 auto *PtrTy = PtrExpr->
getType()->
getAs<PointerType>();
16690 << PtrArgIdx + 1 << 0 << 5 << 0
16694 QualType ElementTy = PtrTy->getPointeeType();
16696 Diag(PtrExpr->
getBeginLoc(), diag::err_builtin_matrix_store_to_const);
16701 !
Context.hasSameType(ElementTy, MatrixTy->getElementType())) {
16703 diag::err_builtin_matrix_pointer_arg_mismatch)
16704 << ElementTy << MatrixTy->getElementType();
16719 StrideExpr = StrideConv.
get();
16720 TheCall->
setArg(2, StrideExpr);
16725 if (std::optional<llvm::APSInt>
Value =
16728 if (Stride < MatrixTy->getNumRows()) {
16730 diag::err_builtin_matrix_stride_too_small);
16750 if (!Caller || !Caller->
hasAttr<EnforceTCBAttr>())
16755 llvm::StringSet<> CalleeTCBs;
16756 for (
const auto *A : Callee->specific_attrs<EnforceTCBAttr>())
16757 CalleeTCBs.insert(A->getTCBName());
16758 for (
const auto *A : Callee->specific_attrs<EnforceTCBLeafAttr>())
16759 CalleeTCBs.insert(A->getTCBName());
16763 for (
const auto *A : Caller->
specific_attrs<EnforceTCBAttr>()) {
16764 StringRef CallerTCB = A->getTCBName();
16765 if (CalleeTCBs.count(CallerTCB) == 0) {
16766 this->
Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
16767 << Callee << CallerTCB;
Defines the clang::ASTContext interface.
Provides definitions for the various language-specific address spaces.
Defines the Diagnostic-related interfaces.
static bool getTypeString(SmallStringEnc &Enc, const Decl *D, const CodeGen::CodeGenModule &CGM, TypeStringCache &TSC)
The XCore ABI includes a type information section that communicates symbol type information to the li...
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Defines the clang::OpenCLOptions class.
Defines an enumeration for C++ overloaded operators.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis functions specific to AMDGPU.
This file declares semantic analysis functions specific to ARM.
This file declares semantic analysis functions specific to BPF.
static bool isLayoutCompatibleUnion(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout unions are layout-compatible.
static bool FindTypeTagExpr(const Expr *TypeExpr, const ASTContext &Ctx, const ValueDecl **VD, uint64_t *MagicValue, bool isConstantEvaluated)
Given a type tag expression find the type tag itself.
static void CheckConditionalOperator(Sema &S, AbstractConditionalOperator *E, SourceLocation CC, QualType T)
static QualType getSizeOfArgType(const Expr *E)
If E is a sizeof expression, returns its argument type.
static void CheckNonNullArgument(Sema &S, const Expr *ArgExpr, SourceLocation CallSiteLoc)
static bool checkPointerAuthValue(Sema &S, Expr *&Arg, PointerAuthOpKind OpKind, bool RequireConstant=false)
static bool checkBuiltinInferAllocToken(Sema &S, CallExpr *TheCall)
static const CXXRecordDecl * getContainedDynamicClass(QualType T, bool &IsContained)
Determine whether the given type is or contains a dynamic class type (e.g., whether it has a vtable).
static ExprResult PointerAuthSignGenericData(Sema &S, CallExpr *Call)
static void builtinAllocaAddrSpace(Sema &S, CallExpr *TheCall)
static ExprResult PointerAuthStrip(Sema &S, CallExpr *Call)
static bool isInvalidOSLogArgTypeForCodeGen(FormatStringType FSType, QualType T)
static bool IsSameFloatAfterCast(const llvm::APFloat &value, const llvm::fltSemantics &Src, const llvm::fltSemantics &Tgt)
Checks whether the given value, which currently has the given source semantics, has the same value wh...
static void AnalyzeComparison(Sema &S, BinaryOperator *E)
Implements -Wsign-compare.
static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, BinaryOperatorKind BinOpKind, bool AddendIsRight)
static std::pair< QualType, StringRef > shouldNotPrintDirectly(const ASTContext &Context, QualType IntendedTy, const Expr *E)
static QualType GetExprType(const Expr *E)
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromLValue(const Expr *E, ASTContext &Ctx)
This helper function takes an lvalue expression and returns the alignment of a VarDecl and a constant...
static bool CheckTautologicalComparison(Sema &S, BinaryOperator *E, Expr *Constant, Expr *Other, const llvm::APSInt &Value, bool RhsConstant)
static bool IsImplicitBoolFloatConversion(Sema &S, const Expr *Ex, bool ToBool)
static AbsoluteValueKind getAbsoluteValueKind(QualType T)
static bool CheckMemorySizeofForComparison(Sema &S, const Expr *E, const IdentifierInfo *FnName, SourceLocation FnLoc, SourceLocation RParenLoc)
Takes the expression passed to the size_t parameter of functions such as memcmp, strncat,...
static ExprResult BuiltinDumpStruct(Sema &S, CallExpr *TheCall)
static bool CompareFormatSpecifiers(Sema &S, const StringLiteral *Ref, ArrayRef< EquatableFormatArgument > RefArgs, const StringLiteral *Fmt, ArrayRef< EquatableFormatArgument > FmtArgs, const Expr *FmtExpr, bool InFunctionCall)
static bool BuiltinBswapg(Sema &S, CallExpr *TheCall)
Checks that __builtin_bswapg was called with a single argument, which is an unsigned integer,...
static ExprResult BuiltinTriviallyRelocate(Sema &S, CallExpr *TheCall)
static bool isValidOrderingForOp(int64_t Ordering, AtomicExpr::AtomicOp Op)
static bool BuiltinSEHScopeCheck(Sema &SemaRef, CallExpr *TheCall, Scope::ScopeFlags NeededScopeFlags, unsigned DiagID)
static void AnalyzeCompoundAssignment(Sema &S, BinaryOperator *E)
Analyze the given compound assignment for the possible losing of floating-point precision.
static bool doesExprLikelyComputeSize(const Expr *SizeofExpr)
Detect if SizeofExpr is likely to calculate the sizeof an object.
static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, const StringLiteral *ReferenceFormatString, const Expr *OrigFormatExpr, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, bool inFunctionCall, VariadicCallType CallType, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, bool IgnoreStringsWithoutSpecifiers)
static bool BuiltinPreserveAI(Sema &S, CallExpr *TheCall)
Check the number of arguments and set the result type to the argument type.
static bool CheckForReference(Sema &SemaRef, const Expr *E, const PartialDiagnostic &PD)
static const UnaryExprOrTypeTraitExpr * getAsSizeOfExpr(const Expr *E)
static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID)
Check that the value argument for __builtin_is_aligned(value, alignment) and __builtin_aligned_{up,...
static void CheckBoolLikeConversion(Sema &S, Expr *E, SourceLocation CC)
Check conversion of given expression to boolean.
static bool isKnownToHaveUnsignedValue(const Expr *E)
static bool checkBuiltinVectorMathArgTypes(Sema &SemaRef, ArrayRef< Expr * > Args)
Check if all arguments have the same type.
static void CheckMemaccessSize(Sema &S, unsigned BId, const CallExpr *Call)
Diagnose cases like 'memset(buf, sizeof(buf), 0)', which should have the last two arguments transpose...
static bool checkPointerAuthEnabled(Sema &S, Expr *E)
static std::string PrettyPrintInRange(const llvm::APSInt &Value, IntRange Range)
static ExprResult BuiltinMaskedStore(Sema &S, CallExpr *TheCall)
static const Expr * getStrlenExprArg(const Expr *E)
static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty, ASTContext &Context)
static bool IsInfOrNanFunction(StringRef calleeName, MathCheck Check)
static bool BuiltinCpu(Sema &S, const TargetInfo &TI, CallExpr *TheCall, const TargetInfo *AuxTI, unsigned BuiltinID)
BuiltinCpu{Supports|Is} - Handle __builtin_cpu_{supports|is}(char *).
static bool IsSameCharType(QualType T1, QualType T2)
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E)
static bool CheckNonNullExpr(Sema &S, const Expr *Expr)
Checks if a the given expression evaluates to null.
static ExprResult BuiltinIsWithinLifetime(Sema &S, CallExpr *TheCall)
static bool isArgumentExpandedFromMacro(SourceManager &SM, SourceLocation CallLoc, SourceLocation ArgLoc)
Check if the ArgLoc originated from a macro passed to the call at CallLoc.
static IntRange GetValueRange(llvm::APSInt &value, unsigned MaxWidth)
static const IntegerLiteral * getIntegerLiteral(Expr *E)
static bool CheckBuiltinTargetInSupported(Sema &S, CallExpr *TheCall, ArrayRef< llvm::Triple::ArchType > SupportedArchs)
static const Expr * maybeConstEvalStringLiteral(ASTContext &Context, const Expr *E)
static bool IsStdFunction(const FunctionDecl *FDecl, const char(&Str)[StrLen])
static void AnalyzeAssignment(Sema &S, BinaryOperator *E)
Analyze the given simple or compound assignment for warning-worthy operations.
static bool BuiltinFunctionStart(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_function_start is a function.
static bool BuiltinCallWithStaticChain(Sema &S, CallExpr *BuiltinCall)
static bool ShouldDiagnoseEmptyStmtBody(const SourceManager &SourceMgr, SourceLocation StmtLoc, const NullStmt *Body)
static std::pair< CharUnits, CharUnits > getDerivedToBaseAlignmentAndOffset(const CastExpr *CE, QualType DerivedType, CharUnits BaseAlignment, CharUnits Offset, ASTContext &Ctx)
Compute the alignment and offset of the base class object given the derived-to-base cast expression a...
static std::pair< const ValueDecl *, CharUnits > findConstantBaseAndOffset(Sema &S, Expr *E)
static bool IsEnumConstOrFromMacro(Sema &S, const Expr *E)
static void diagnoseArrayStarInParamType(Sema &S, QualType PType, SourceLocation Loc)
static std::optional< IntRange > TryGetExprRange(ASTContext &C, const Expr *E, unsigned MaxWidth, bool InConstantContext, bool Approximate)
Attempts to estimate an approximate range for the given integer expression.
static unsigned changeAbsFunction(unsigned AbsKind, AbsoluteValueKind ValueKind)
static ExprResult BuiltinMaskedLoad(Sema &S, CallExpr *TheCall)
static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall, SourceLocation CC)
static void CheckConditionalOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool &ICContext)
static void DiagnoseNullConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool checkUnsafeAssignLiteral(Sema &S, SourceLocation Loc, Expr *RHS, bool isProperty)
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall)
static bool CheckMissingFormatAttribute(Sema *S, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, StringLiteral *ReferenceFormatString, unsigned FormatIdx, unsigned FirstDataArg, FormatStringType FormatType, unsigned CallerParamIdx, SourceLocation Loc)
static ExprResult PointerAuthBlendDiscriminator(Sema &S, CallExpr *Call)
static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init, SourceLocation InitLoc)
Analyzes an attempt to assign the given value to a bitfield.
static void CheckCommaOperand(Sema &S, Expr *E, QualType T, SourceLocation CC, bool ExtraCheckForImplicitConversion, llvm::SmallVectorImpl< AnalyzeImplicitConversionsWorkItem > &WorkList)
static void DiagnoseFloatingImpCast(Sema &S, const Expr *E, QualType T, SourceLocation CContext)
Diagnose an implicit cast from a floating point value to an integer value.
static int classifyConstantValue(Expr *Constant)
static bool IsInAnyMacroBody(const SourceManager &SM, SourceLocation Loc)
static void emitReplacement(Sema &S, SourceLocation Loc, SourceRange Range, unsigned AbsKind, QualType ArgType)
static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2)
Check if two types are layout-compatible in C++11 sense.
static bool checkPointerAuthKey(Sema &S, Expr *&Arg)
static bool checkUnsafeAssignObject(Sema &S, SourceLocation Loc, Qualifiers::ObjCLifetime LT, Expr *RHS, bool isProperty)
static bool BuiltinOverflow(Sema &S, CallExpr *TheCall, unsigned BuiltinID)
static unsigned getAbsoluteValueFunctionKind(const FunctionDecl *FDecl)
static llvm::SmallPtrSet< MemberKind *, 1 > CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty)
static bool isSameWidthConstantConversion(Sema &S, Expr *E, QualType T, SourceLocation CC)
static bool IsInfinityFunction(const FunctionDecl *FDecl)
static void DiagnoseImpCast(Sema &S, const Expr *E, QualType SourceType, QualType T, SourceLocation CContext, unsigned diag, bool PruneControlFlow=false)
Diagnose an implicit cast; purely a helper for CheckImplicitConversion.
static void CheckNonNullArguments(Sema &S, const NamedDecl *FDecl, const FunctionProtoType *Proto, ArrayRef< const Expr * > Args, SourceLocation CallSiteLoc)
static unsigned getLargerAbsoluteValueFunction(unsigned AbsFunction)
static analyze_format_string::ArgType::MatchKind handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match, DiagnosticsEngine &Diags, SourceLocation Loc)
static bool referToTheSameDecl(const Expr *E1, const Expr *E2)
Check if two expressions refer to the same declaration.
static ExprResult BuiltinMaskedScatter(Sema &S, CallExpr *TheCall)
static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall)
Checks that __builtin_{clzg,ctzg} was called with a first argument, which is an unsigned integer,...
static ExprResult GetVTablePointer(Sema &S, CallExpr *Call)
static bool requiresParensToAddCast(const Expr *E)
static bool HasEnumType(const Expr *E)
static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call)
static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall)
static const Expr * ignoreLiteralAdditions(const Expr *Ex, ASTContext &Ctx)
static StringLiteralCheckType checkFormatStringExpr(Sema &S, const StringLiteral *ReferenceFormatString, const Expr *E, ArrayRef< const Expr * > Args, Sema::FormatArgumentPassingKind APK, unsigned format_idx, unsigned firstDataArg, FormatStringType Type, VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, UncoveredArgHandler &UncoveredArg, llvm::APSInt Offset, std::optional< unsigned > *CallerFormatParamIdx=nullptr, bool IgnoreStringsWithoutSpecifiers=false)
static std::optional< unsigned > getAndVerifyMatrixDimension(Expr *Expr, StringRef Name, Sema &S)
static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty)
static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *Call)
static bool ProcessFormatStringLiteral(const Expr *FormatExpr, StringRef &FormatStrRef, size_t &StrLen, ASTContext &Context)
static bool isLayoutCompatibleStruct(const ASTContext &C, const RecordDecl *RD1, const RecordDecl *RD2)
Check if two standard-layout structs are layout-compatible.
static bool BuiltinPopcountg(Sema &S, CallExpr *TheCall)
Checks that __builtin_popcountg was called with a single argument, which is an unsigned integer.
static const Expr * getSizeOfExprArg(const Expr *E)
If E is a sizeof expression, returns its argument expression, otherwise returns NULL.
static void DiagnoseIntInBoolContext(Sema &S, Expr *E)
static bool CheckBuiltinTargetNotInUnsupported(Sema &S, unsigned BuiltinID, CallExpr *TheCall, ArrayRef< llvm::Triple::ObjectFormatType > UnsupportedObjectFormatTypes)
static void DiagnoseMixedUnicodeImplicitConversion(Sema &S, const Type *Source, const Type *Target, Expr *E, QualType T, SourceLocation CC)
static bool BuiltinAddressof(Sema &S, CallExpr *TheCall)
Check that the argument to __builtin_addressof is a glvalue, and set the result type to the correspon...
static CharUnits getPresumedAlignmentOfPointer(const Expr *E, Sema &S)
static bool CheckMaskedBuiltinArgs(Sema &S, Expr *MaskArg, Expr *PtrArg, unsigned Pos, bool AllowConst, bool AllowAS)
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn)
Check that the user is calling the appropriate va_start builtin for the target and calling convention...
static ExprResult PointerAuthSignOrAuth(Sema &S, CallExpr *Call, PointerAuthOpKind OpKind, bool RequireConstant)
static bool checkBuiltinVerboseTrap(CallExpr *Call, Sema &S)
static bool checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, Sema::EltwiseBuiltinArgTyRestriction ArgTyRestr, int ArgOrdinal)
static bool GetMatchingCType(const IdentifierInfo *ArgumentKind, const Expr *TypeExpr, const ASTContext &Ctx, const llvm::DenseMap< Sema::TypeTagMagicValue, Sema::TypeTagData > *MagicValues, bool &FoundWrongKind, Sema::TypeTagData &TypeInfo, bool isConstantEvaluated)
Retrieve the C type corresponding to type tag TypeExpr.
static QualType getAbsoluteValueArgumentType(ASTContext &Context, unsigned AbsType)
static ExprResult BuiltinMaskedGather(Sema &S, CallExpr *TheCall)
static bool ConvertMaskedBuiltinArgs(Sema &S, CallExpr *TheCall)
static bool isNonNullType(QualType type)
Determine whether the given type has a non-null nullability annotation.
static constexpr unsigned short combineFAPK(Sema::FormatArgumentPassingKind A, Sema::FormatArgumentPassingKind B)
static bool BuiltinAnnotation(Sema &S, CallExpr *TheCall)
Check that the first argument to __builtin_annotation is an integer and the second argument is a non-...
static std::optional< std::pair< CharUnits, CharUnits > > getBaseAlignmentAndOffsetFromPtr(const Expr *E, ASTContext &Ctx)
This helper function takes a pointer expression and returns the alignment of a VarDecl and a constant...
static bool IsShiftedByte(llvm::APSInt Value)
static unsigned getBestAbsFunction(ASTContext &Context, QualType ArgType, unsigned AbsFunctionKind)
static bool checkBuiltinArgument(Sema &S, CallExpr *E, unsigned ArgIndex)
checkBuiltinArgument - Given a call to a builtin function, perform normal type-checking on the given ...
static void AnalyzeImpConvsInComparison(Sema &S, BinaryOperator *E)
Analyze the operands of the given comparison.
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS, SourceLocation Loc)
static bool isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE)
Return true if ICE is an implicit argument promotion of an arithmetic type.
static void AnalyzeImplicitConversions(Sema &S, Expr *E, SourceLocation CC, bool IsListInit=false)
AnalyzeImplicitConversions - Find and report any interesting implicit conversions in the given expres...
static std::optional< std::pair< CharUnits, CharUnits > > getAlignmentAndOffsetFromBinAddOrSub(const Expr *PtrE, const Expr *IntE, bool IsSub, ASTContext &Ctx)
Compute the alignment and offset of a binary additive operator.
static bool BuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall)
static bool checkVAStartIsInVariadicFunction(Sema &S, Expr *Fn, ParmVarDecl **LastParam=nullptr)
This file declares semantic analysis for DirectX constructs.
This file declares semantic analysis for HLSL constructs.
This file declares semantic analysis functions specific to Hexagon.
This file declares semantic analysis functions specific to LoongArch.
This file declares semantic analysis functions specific to MIPS.
This file declares semantic analysis functions specific to NVPTX.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis routines for OpenCL.
This file declares semantic analysis functions specific to PowerPC.
This file declares semantic analysis functions specific to RISC-V.
This file declares semantic analysis for SPIRV constructs.
This file declares semantic analysis functions specific to SystemZ.
This file declares semantic analysis functions specific to Wasm.
This file declares semantic analysis functions specific to X86.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Provides definitions for the atomic synchronization scopes.
C Language Family Type Representation.
Defines the clang::TypeLoc interface and its subclasses.
Defines enumerations for the type traits support.
C Language Family Type Representation.
__DEVICE__ int min(int __a, int __b)
__device__ __2f16 float __ockl_bool s
MatchKind
How well a given conversion specifier matches its argument.
@ NoMatch
The conversion specifier and the argument types are incompatible.
@ NoMatchPedantic
The conversion specifier and the argument type are disallowed by the C standard, but are in practice ...
@ Match
The conversion specifier and the argument type are compatible.
@ MatchPromotion
The conversion specifier and the argument type are compatible because of default argument promotions.
@ NoMatchSignedness
The conversion specifier and the argument type have different sign.
@ NoMatchTypeConfusion
The conversion specifier and the argument type are compatible, but still seems likely to be an error.
@ NoMatchPromotionTypeConfusion
The conversion specifier and the argument type are compatible but still seems likely to be an error.
unsigned getLength() const
const char * toString() const
const char * getStart() const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantAmount() const
unsigned getConstantLength() const
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx, bool IsObjCLiteral)
Changes the specifier and length according to a QualType, retaining any flags or options.
void toString(raw_ostream &os) const
bool fixType(QualType QT, QualType RawQT, const LangOptions &LangOpt, ASTContext &Ctx)
void toString(raw_ostream &os) const
llvm::APInt getValue() const
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
const LValueBase getLValueBase() const
APSInt & getComplexIntImag()
bool isComplexInt() const
bool isComplexFloat() const
APValue & getVectorElt(unsigned I)
unsigned getVectorLength() const
APSInt & getComplexIntReal()
APFloat & getComplexFloatImag()
APFloat & getComplexFloatReal()
bool isAddrLabelDiff() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
int getFloatingTypeSemanticOrder(QualType LHS, QualType RHS) const
Compare the rank of two floating point types as above, but compare equal if both types have the same ...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
int getFloatingTypeOrder(QualType LHS, QualType RHS) const
Compare the rank of the two specified floating point types, ignoring the domain of the type (i....
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType removeAddrSpaceQualType(QualType T) const
Remove any existing address space on the type and returns the type with qualifiers intact (or that's ...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedIntTy
QualType getTypedefType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypedefNameDecl *Decl, QualType UnderlyingType=QualType(), std::optional< bool > TypeMatchesDeclOrNone=std::nullopt) const
Return the unique reference to the type for the specified typedef-name decl.
CanQualType UnsignedShortTy
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getPromotedIntegerType(QualType PromotableType) const
Return the type that PromotableType will promote to: C99 6.3.1.1p2, assuming that PromotableType is a...
StringLiteral * getPredefinedStringLiteralFromCache(StringRef Key) const
Return a string representing the human readable name for the specified function declaration or file n...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
const TargetInfo & getTargetInfo() const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
CanQualType getCanonicalTagType(const TagDecl *TD) const
bool isPromotableIntegerType(QualType T) const
More type predicates useful for type checking/promotion.
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
SourceLocation getQuestionLoc() const
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getBase()
Get base of the array section.
Expr * getLowerBound()
Get lower bound of array section.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getRBracketLoc() const
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
ArraySizeModifier getSizeModifier() const
QualType getElementType() const
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
static std::unique_ptr< AtomicScopeModel > getScopeModel(AtomicOp Op)
Get atomic scope model for the atomic op code.
SourceLocation getBeginLoc() const LLVM_READONLY
Attr - This represents one attribute.
const char * getSpelling() const
Type source information for an attributed type.
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
SourceLocation getOperatorLoc() const
SourceLocation getExprLoc() const
static StringRef getOpcodeStr(Opcode Op)
getOpcodeStr - Turn an Opcode enum value into the punctuation char it corresponds to,...
static bool isAdditiveOp(Opcode Opc)
static bool isEqualityOp(Opcode Opc)
BinaryOperatorKind Opcode
This class is used for builtin types like 'int'.
bool isFloatingPoint() const
bool isSignedInteger() const
bool isUnsignedInteger() const
std::string getQuotedName(unsigned ID) const
Return the identifier name for the specified builtin inside single quotes for a diagnostic,...
const char * getHeaderName(unsigned ID) const
If this is a library function that comes from a specific header, retrieve that header name.
std::string getName(unsigned ID) const
Return the identifier name for the specified builtin, e.g.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ destructor within a class.
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
SourceLocation getExprLoc() const LLVM_READONLY
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ struct/union/class.
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
CXXRecordDecl * getDefinition() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
bool isDynamicClass() const
Represents a C++ nested-name-specifier or a global scope specifier.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
unsigned getBuiltinCallee() const
getBuiltinCallee - If this is a call to a builtin, return the builtin ID of the callee.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Get the FP features status of this operator.
Expr ** getArgs()
Retrieve the call arguments.
SourceLocation getEndLoc() const
SourceLocation getRParenLoc() const
bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const
Returns true if this is a call to a builtin which does not evaluate side-effects within its arguments...
void shrinkNumArgs(unsigned NewNumArgs)
Reduce the number of arguments in this call expression.
QualType withConst() const
Retrieves a version of this type with const applied.
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
Represents a character-granular source range.
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
SourceLocation getBegin() const
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
ConditionalOperator - The ?
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumElementsFlattened() const
Returns the number of elements required to embed the matrix into a vector.
static ConvertVectorExpr * Create(const ASTContext &C, Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, ExprValueKind VK, ExprObjectKind OK, SourceLocation BuiltinLoc, SourceLocation RParenLoc, FPOptionsOverride FPFeatures)
Expr * getOperand() const
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isStdNamespace() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NestedNameSpecifierLoc getQualifierLoc() const
If the name was qualified, retrieves the nested-name-specifier that precedes the name,...
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getBeginLoc() const
SourceLocation getLocation() const
Decl - This represents one declaration (or definition), e.g.
bool isInStdNamespace() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
bool isInvalidDecl() const
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
The name of a declaration.
std::string getAsString() const
Retrieve the human-readable string for this name.
SourceLocation getTypeSpecStartLoc() const
TypeSourceInfo * getTypeSourceInfo() const
bool hasErrorOccurred() const
Determine whether any errors have occurred since this object instance was created.
Concrete class used by the front-end to report problems and issues.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
An instance of this object exists for each enum constant that is defined.
bool isComplete() const
Returns true if this can be considered a complete type.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
@ SE_NoSideEffects
Strictly evaluate the expression.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
bool tryEvaluateStrLen(uint64_t &Result, ASTContext &Ctx) const
If the current Expr is a pointer, this will try to statically determine the strlen of the string poin...
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
bool EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFloat - Return true if this is a constant which we can fold and convert to a floating point...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isFlexibleArrayMemberLike(const ASTContext &Context, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, bool IgnoreTemplateOrMacroSubstitution=false) const
Check whether this array fits the idiom of a flexible array member, depending on the value of -fstric...
bool EvaluateAsFixedPoint(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsFixedPoint - Return true if this is a constant which we can fold and convert to a fixed poi...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
FieldDecl * getSourceBitField()
If this expression refers to a bit-field, retrieve the declaration of that bit-field.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
@ NPC_ValueDependentIsNotNull
Specifies that a value-dependent expression should be considered to never be a null pointer constant.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Expr * IgnoreImplicitAsWritten() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
NullPointerConstantKind
Enumeration used to describe the kind of Null pointer constant returned from isNullPointerConstant().
@ NPCK_ZeroExpression
Expression is a Null pointer constant built from a zero integer expression that is not a simple,...
@ NPCK_ZeroLiteral
Expression is a Null pointer constant built from a literal zero.
@ NPCK_NotNull
Expression is not a Null pointer constant.
bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsBooleanCondition - Return true if this is a constant which we can fold and convert to a boo...
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
QualType getEnumCoercedType(const ASTContext &Ctx) const
If this expression is an enumeration constant, return the enumeration type under which said constant ...
void setValueKind(ExprValueKind Cat)
setValueKind - Set the value kind produced by this expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
void setObjectKind(ExprObjectKind Cat)
setObjectKind - Set the object kind produced by this expression.
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, unsigned Type) const
If the current Expr is a pointer, this will try to statically determine the number of bytes available...
const ValueDecl * getAsBuiltinConstantDeclRef(const ASTContext &Context) const
If this expression is an unambiguous reference to a single declaration, in the style of __builtin_fun...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
void EvaluateForOverflow(const ASTContext &Ctx) const
ExtVectorType - Extended vector type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
llvm::APFloat getValue() const
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
unsigned getMemoryFunctionKind() const
Identify a memory copying or setting function.
const ParmVarDecl * getParamDecl(unsigned i) const
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
param_iterator param_end()
bool hasCXXExplicitFunctionObjectParameter() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
param_iterator param_begin()
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
bool isNothrow(bool ResultIfDependent=false) const
Determine whether this function type has a non-throwing exception specification.
ArrayRef< QualType > getParamTypes() const
FunctionType - C99 6.7.5.3 - Function Declarators.
@ SME_PStateSMEnabledMask
@ SME_PStateSMCompatibleMask
static ArmStateValue getArmZT0State(unsigned AttrBits)
static ArmStateValue getArmZAState(unsigned AttrBits)
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Describes an C or C++ initializer list.
ArrayRef< Expr * > inits()
Describes an entity that is being initialized.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
StrictFlexArraysLevelKind
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
static StringRef getImmediateMacroName(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static unsigned MeasureTokenLength(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
MeasureTokenLength - Relex the token at the specified location and return its length in bytes in the ...
static StringRef getImmediateMacroNameForDiagnostics(SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts)
Retrieve the name of the immediate macro expansion.
static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset, const SourceManager &SM, const LangOptions &LangOpts)
Computes the source location just past the end of the token at this source location.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
UnresolvedSetImpl::iterator iterator
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
static bool isValidElementType(QualType T)
Valid elements types are the following:
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Linkage getFormalLinkage() const
Get the linkage from a semantic point of view.
bool hasLinkage() const
Determine whether this declaration has linkage.
Represent a C++ namespace.
NullStmt - This is the null statement ";": C99 6.8.3p3.
bool hasLeadingEmptyMacro() const
SourceLocation getSemiLoc() const
Represents an ObjC class declaration.
Represents one property declaration in an Objective-C interface.
ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
ObjCPropertyDecl * getExplicitProperty() const
bool isImplicitProperty() const
ObjCStringLiteral, used for Objective-C string literals i.e.
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
Pointer-authentication qualifiers.
@ MaxDiscriminator
The maximum supported pointer-authentication discriminator.
bool isAddressDiscriminated() const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
static PseudoObjectExpr * Create(const ASTContext &Context, Expr *syntactic, ArrayRef< Expr * > semantic, unsigned resultIndex)
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
PrimitiveDefaultInitializeKind
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
void removeLocalVolatile()
QualType withCVRQualifiers(unsigned CVR) const
bool isConstQualified() const
Determine whether this type is const-qualified.
bool hasAddressSpace() const
Check if this type has any address space qualifier.
QualType getAtomicUnqualifiedType() const
Remove all qualifiers including _Atomic.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
bool hasNonTrivialObjCLifetime() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
bool hasUnaligned() const
Represents a struct/union/class.
bool isNonTrivialToPrimitiveCopy() const
field_range fields() const
bool isNonTrivialToPrimitiveDefaultInitialize() const
Functions to query basic properties of non-trivial C structs.
Scope - A scope is a transient data structure that is used while parsing the program.
bool isSEHExceptScope() const
Determine whether this scope is a SEH '__except' block.
unsigned getFlags() const
getFlags - Return the flags for this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
ScopeFlags
ScopeFlags - These are bitfields that are or'd together when creating a scope, which defines the sort...
@ SEHFilterScope
We are currently in the filter expression of an SEH except block.
@ SEHExceptScope
This scope corresponds to an SEH except.
bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
@ ArmStreaming
Intrinsic is only available in normal mode.
@ ArmStreamingCompatible
Intrinsic is only available in Streaming-SVE mode.
bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
bool CheckDirectXBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkArrayLiteral(QualType TargetType, ObjCArrayLiteral *ArrayLiteral)
Check an Objective-C array literal being converted to the given target type.
ObjCLiteralKind CheckLiteralKind(Expr *FromE)
void adornBoolConversionDiagWithTernaryFixit(const Expr *SourceExpr, const Sema::SemaDiagnosticBuilder &Builder)
bool isSignedCharBool(QualType Ty)
void DiagnoseCStringFormatDirectiveInCFAPI(const NamedDecl *FDecl, Expr **Args, unsigned NumArgs)
Diagnose use of s directive in an NSString which is being passed as formatting string to formatting m...
void checkDictionaryLiteral(QualType TargetType, ObjCDictionaryLiteral *DictionaryLiteral)
Check an Objective-C dictionary literal being converted to the given target type.
std::unique_ptr< NSAPI > NSAPIObj
Caches identifiers/selectors for NSFoundation APIs.
bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg)
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSPIRVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall)
bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
bool CheckBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall)
Sema - This implements semantic analysis and AST building for C.
const FieldDecl * getSelfAssignmentClassMemberCandidate(const ValueDecl *SelfAssigned)
Returns a field in a CXXRecordDecl that has the same name as the decl SelfAssigned when inside a CXXM...
bool DiscardingCFIUncheckedCallee(QualType From, QualType To) const
Returns true if From is a function or pointer to a function with the cfi_unchecked_callee attribute b...
bool BuiltinConstantArgShiftedByte(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByte - Check if argument ArgNum of TheCall is a constant expression represen...
bool IsPointerInterconvertibleBaseOf(const TypeSourceInfo *Base, const TypeSourceInfo *Derived)
bool diagnoseArgDependentDiagnoseIfAttrs(const FunctionDecl *Function, const Expr *ThisArg, ArrayRef< const Expr * > Args, SourceLocation Loc)
Emit diagnostics for the diagnose_if attributes on Function, ignoring any non-ArgDependent DiagnoseIf...
bool BuiltinConstantArgMultiple(CallExpr *TheCall, unsigned ArgNum, unsigned Multiple)
BuiltinConstantArgMultiple - Handle a check if argument ArgNum of CallExpr TheCall is a constant expr...
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
std::optional< QualType > BuiltinVectorMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads)
Figure out if an expression could be turned into a call.
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
@ LookupAnyName
Look up any declaration with any name.
bool checkArgCountAtMost(CallExpr *Call, unsigned MaxArgCount)
Checks that a call expression's argument count is at most the desired number.
bool checkPointerAuthDiscriminatorArg(Expr *Arg, PointerAuthDiscArgKind Kind, unsigned &IntVal)
bool ValueIsRunOfOnes(CallExpr *TheCall, unsigned ArgNum)
Returns true if the argument consists of one contiguous run of 1s with any number of 0s on either sid...
void RegisterTypeTagForDatatype(const IdentifierInfo *ArgumentKind, uint64_t MagicValue, QualType Type, bool LayoutCompatible, bool MustBeNull)
Register a magic integral constant to be used as a type tag.
bool isValidPointerAttrType(QualType T, bool RefOkay=false)
Determine if type T is a valid subject for a nonnull and similar attributes.
void DiagnoseAlwaysNonNullPointer(Expr *E, Expr::NullPointerConstantKind NullType, bool IsEqual, SourceRange Range)
Diagnose pointers that are always non-null.
VariadicCallType getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto, Expr *Fn)
bool FormatStringHasSArg(const StringLiteral *FExpr)
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
void CheckFloatComparison(SourceLocation Loc, const Expr *LHS, const Expr *RHS, BinaryOperatorKind Opcode)
Check for comparisons of floating-point values using == and !=.
void RefersToMemberWithReducedAlignment(Expr *E, llvm::function_ref< void(Expr *, RecordDecl *, FieldDecl *, CharUnits)> Action)
This function calls Action when it determines that E designates a misaligned member due to the packed...
const ExpressionEvaluationContextRecord & currentEvaluationContext() const
bool CheckFormatStringsCompatible(FormatStringType FST, const StringLiteral *AuthoritativeFormatString, const StringLiteral *TestedFormatString, const Expr *FunctionCallArg=nullptr)
Verify that two format strings (as understood by attribute(format) and attribute(format_matches) are ...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
FPOptionsOverride CurFPFeatureOverrides()
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
bool checkPointerAuthEnabled(SourceLocation Loc, SourceRange Range)
bool BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT, QualType RhsT)
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT, FunctionDecl *FDecl)
ExprResult tryConvertExprToType(Expr *E, QualType Ty)
Try to convert an expression E to type Ty.
QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc)
CheckAddressOfOperand - The operand of & must be either a function designator or an lvalue designatin...
DiagnosticsEngine & getDiagnostics() const
bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, bool Complain=false, SourceLocation Loc=SourceLocation())
Returns whether the given function's address can be taken or not, optionally emitting a diagnostic if...
void CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC, bool *ICContext=nullptr, bool IsListInit=false)
std::string getFixItZeroLiteralForType(QualType T, SourceLocation Loc) const
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isConstantEvaluatedOverride
Used to change context to isConstantEvaluated without pushing a heavy ExpressionEvaluationContextReco...
bool BuiltinVectorToScalarMath(CallExpr *TheCall)
bool BuiltinConstantArg(CallExpr *TheCall, unsigned ArgNum, llvm::APSInt &Result)
BuiltinConstantArg - Handle a check if argument ArgNum of CallExpr TheCall is a constant expression.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc)
DiagnoseSelfMove - Emits a warning if a value is moved to itself.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
bool BuiltinConstantArgRange(CallExpr *TheCall, unsigned ArgNum, int Low, int High, bool RangeIsError=true)
BuiltinConstantArgRange - Handle a check if argument ArgNum of CallExpr TheCall is a constant express...
bool IsLayoutCompatible(QualType T1, QualType T2) const
const LangOptions & getLangOpts() const
bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type of the given expression is complete.
void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange)
CheckCastAlign - Implements -Wcast-align, which warns when a pointer cast increases the alignment req...
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
bool hasCStrMethod(const Expr *E)
Check to see if a given expression could have '.c_str()' called on it.
const LangOptions & LangOpts
static const uint64_t MaximumAlignment
VarArgKind isValidVarArgType(const QualType &Ty)
Determine the degree of POD-ness for an expression.
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
static StringRef GetFormatStringTypeName(FormatStringType FST)
bool checkConstantPointerAuthKey(Expr *keyExpr, unsigned &key)
bool checkUnsafeAssigns(SourceLocation Loc, QualType LHS, Expr *RHS)
checkUnsafeAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained type.
EltwiseBuiltinArgTyRestriction
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
void popCodeSynthesisContext()
void DiagnoseMisalignedMembers()
Diagnoses the current set of gathered accesses.
sema::FunctionScopeInfo * getCurFunction() const
void checkUnsafeExprAssigns(SourceLocation Loc, Expr *LHS, Expr *RHS)
checkUnsafeExprAssigns - Check whether +1 expr is being assigned to weak/__unsafe_unretained expressi...
std::pair< const IdentifierInfo *, uint64_t > TypeTagMagicValue
A pair of ArgumentKind identifier and magic value.
QualType BuiltinRemoveCVRef(QualType BaseType, SourceLocation Loc)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
ExprResult ActOnMemberAccessExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Member, Decl *ObjCImpDecl)
The main callback when the parser finds something like expression .
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const
void CheckTCBEnforcement(const SourceLocation CallExprLoc, const NamedDecl *Callee)
Enforce the bounds of a TCB CheckTCBEnforcement - Enforces that every function in a named TCB only di...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool checkArgCountAtLeast(CallExpr *Call, unsigned MinArgCount)
Checks that a call expression's argument count is at least the desired number.
FormatArgumentPassingKind
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
static FormatStringType GetFormatStringType(StringRef FormatFlavor)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool checkArgCountRange(CallExpr *Call, unsigned MinArgCount, unsigned MaxArgCount)
Checks that a call expression's argument count is in the desired range.
bool ValidateFormatString(FormatStringType FST, const StringLiteral *Str)
Verify that one format string (as understood by attribute(format)) is self-consistent; for instance,...
void DiscardMisalignedMemberAddress(const Type *T, Expr *E)
This function checks if the expression is in the sef of potentially misaligned members and it is conv...
bool PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::None)
bool DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the current evaluation context.
ExprResult BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, SourceLocation nameLoc, IndirectFieldDecl *indirectField, DeclAccessPair FoundDecl=DeclAccessPair::make(nullptr, AS_none), Expr *baseObjectExpr=nullptr, SourceLocation opLoc=SourceLocation())
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
bool CheckParmsForFunctionDef(ArrayRef< ParmVarDecl * > Parameters, bool CheckParameterNames)
CheckParmsForFunctionDef - Check that the parameters of the given function are appropriate for the de...
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
bool isConstantEvaluatedContext() const
bool BuiltinElementwiseTernaryMath(CallExpr *TheCall, EltwiseBuiltinArgTyRestriction ArgTyRestr=EltwiseBuiltinArgTyRestriction::FloatTy)
bool checkArgCount(CallExpr *Call, unsigned DesiredArgCount)
Checks that a call expression's argument count is the desired number.
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
QualType GetSignedVectorType(QualType V)
Return a signed ext_vector_type that is of identical size and number of elements.
void CheckConstrainedAuto(const AutoType *AutoT, SourceLocation Loc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
static bool getFormatStringInfo(const Decl *Function, unsigned FormatIdx, unsigned FirstArg, FormatStringInfo *FSI)
Given a function and its FormatAttr or FormatMatchesAttr info, attempts to populate the FormatStringI...
bool BuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, unsigned ArgNum, unsigned ArgBits)
BuiltinConstantArgShiftedByteOr0xFF - Check if argument ArgNum of TheCall is a constant expression re...
SourceManager & SourceMgr
ExprResult UsualUnaryFPConversions(Expr *E)
UsualUnaryFPConversions - Promotes floating-point types according to the current language semantics.
DiagnosticsEngine & Diags
NamespaceDecl * getStdNamespace() const
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void checkVariadicArgument(const Expr *E, VariadicCallType CT)
Check to see if the given expression is a valid argument to a variadic function, issuing a diagnostic...
void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction, const Expr *ThisArg, ArrayRef< const Expr * > Args)
void runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref< void()> Fn)
Run some code with "sufficient" stack space.
bool BuiltinConstantArgPower2(CallExpr *TheCall, unsigned ArgNum)
BuiltinConstantArgPower2 - Check if argument ArgNum of TheCall is a constant expression representing ...
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
SemaLoongArch & LoongArch()
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto)
CheckFunctionCall - Check a direct function call for various correctness and safety properties not st...
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
FileID getFileID(SourceLocation SpellingLoc) const
Return the FileID for a SourceLocation.
SourceLocation getTopMacroCallerLoc(SourceLocation Loc) const
SourceLocation getSpellingLoc(SourceLocation Loc) const
Given a SourceLocation object, return the spelling location referenced by the ID.
const char * getCharacterData(SourceLocation SL, bool *Invalid=nullptr) const
Return a pointer to the start of the specified location in the appropriate spelling MemoryBuffer.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
CharSourceRange getImmediateExpansionRange(SourceLocation Loc) const
Return the start/end of the expansion information for an expansion location.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const LLVM_READONLY
unsigned getLength() const
StringLiteralKind getKind() const
SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target, unsigned *StartToken=nullptr, unsigned *StartTokenByteOffset=nullptr) const
getLocationOfByte - Return a source location that points to the specified byte of this string literal...
unsigned getByteLength() const
StringRef getString() const
SourceLocation getEndLoc() const LLVM_READONLY
unsigned getCharByteWidth() const
bool isBeingDefined() const
Return true if this decl is currently being defined.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Exposes information about the current target.
virtual bool supportsCpuSupports() const
virtual bool validateCpuIs(StringRef Name) const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
unsigned getTypeWidth(IntType T) const
Return the width (in bits) of the specified integer type enum.
IntType getSizeType() const
virtual bool validateCpuSupports(StringRef Name) const
virtual bool supportsCpuIs() const
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
@ Type
The template argument is a type.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Base wrapper for a particular "section" of type source info.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isBooleanType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
const Type * getPointeeOrArrayElementType() const
If this is a pointer type, return the pointee type.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
bool isIntegralOrUnscopedEnumerationType() const
Determine whether this type is an integral or unscoped enumeration type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool canDecayToPointerType() const
Determines whether this type can decay to a pointer type.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
bool isVoidPointerType() const
bool isConstantSizeType() const
Return true if this is not a variable sized type, according to the rules of C99 6....
bool isFunctionPointerType() const
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
const CXXRecordDecl * getPointeeCXXRecordDecl() const
If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.
bool isVariableArrayType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
bool isExtVectorBoolType() const
QualType getSveEltType(const ASTContext &Ctx) const
Returns the representative type for the element of an SVE builtin type.
bool isBitIntType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
RecordDecl * castAsRecordDecl() const
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g....
QualType getCanonicalTypeInternal() const
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
bool isAtomicType() const
bool isFunctionProtoType() const
bool isStandardLayoutType() const
Test if this type is a standard-layout type.
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUnscopedEnumerationType() const
bool isObjCObjectType() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool hasFloatingRepresentation() const
Determine whether this type has a floating-point representation of some sort, e.g....
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
bool isFloatingType() const
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
bool isAnyPointerType() const
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isSizelessVectorType() const
Returns true for all scalable vector types.
QualType getSizelessVectorEltType(const ASTContext &Ctx) const
Returns the representative type for the element of a sizeless vector builtin type.
Base class for declarations which introduce a typedef-name.
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
SourceLocation getBeginLoc() const LLVM_READONLY
Represents a C++ unqualified-id that has been parsed.
void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Specify that this unqualified-id was parsed as an identifier.
A set of unresolved declarations.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
Represents a variable declaration or definition.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
WhileStmt - This represents a 'while' stmt.
std::string getRepresentativeTypeName(ASTContext &C) const
MatchKind matchesType(ASTContext &C, QualType argTy) const
const char * getStart() const
HowSpecified getHowSpecified() const
unsigned getConstantLength() const
const char * toString() const
const char * getPosition() const
const OptionalFlag & isPrivate() const
bool hasValidLeftJustified() const
bool hasValidFieldWidth() const
bool hasValidSpacePrefix() const
const OptionalAmount & getPrecision() const
const OptionalFlag & hasSpacePrefix() const
bool usesPositionalArg() const
const OptionalFlag & isSensitive() const
const OptionalFlag & isLeftJustified() const
bool hasValidPrecision() const
const OptionalFlag & hasLeadingZeros() const
const OptionalFlag & hasAlternativeForm() const
bool hasValidLeadingZeros() const
void toString(raw_ostream &os) const
const PrintfConversionSpecifier & getConversionSpecifier() const
const OptionalFlag & hasPlusPrefix() const
const OptionalFlag & hasThousandsGrouping() const
bool hasValidThousandsGroupingPrefix() const
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const
Returns the builtin type that a data argument paired with this format specifier should have.
const OptionalFlag & isPublic() const
bool consumesDataArgument() const
bool hasValidPlusPrefix() const
bool hasValidAlternativeForm() const
bool consumesDataArgument() const
const ScanfConversionSpecifier & getConversionSpecifier() const
ArgType getArgType(ASTContext &Ctx) const
void markSafeWeakUse(const Expr *E)
Record that a given expression is a "safe" access of a weak object (e.g.
Defines the clang::TargetInfo interface.
__inline void unsigned int _2
Pieces specific to fprintf format strings.
Pieces specific to fscanf format strings.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< PointerType > pointerType
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
uint32_t Literal
Literals are represented as positive integers.
ComparisonResult
Indicates the result of a tentative comparison.
bool isObjC(ID Id)
isObjC - Is this an "ObjC" input (Obj-C and Obj-C++ sources and headers).
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ After
Like System, but searched after the system directories.
@ FixIt
Parse and apply any fixits to the source.
bool GT(InterpState &S, CodePtr OpPC)
bool LT(InterpState &S, CodePtr OpPC)
bool NE(InterpState &S, CodePtr OpPC)
bool LE(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
bool EQ(InterpState &S, CodePtr OpPC)
bool GE(InterpState &S, CodePtr OpPC)
void checkCaptureByLifetime(Sema &SemaRef, const CapturingEntity &Entity, Expr *Init)
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
bool hasSpecificAttr(const Container &container)
@ Arithmetic
An arithmetic operation.
@ Comparison
A comparison.
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ Success
Annotation was successful.
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_Ordinary
An ordinary object is located at an address in memory.
std::string FormatUTFCodeUnitAsCodepoint(unsigned Value, QualType T)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD)
MutableArrayRef< Expr * > MultiExprArg
@ Internal
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
bool isFunctionOrMethodVariadic(const Decl *D)
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool hasImplicitObjectParameter(const Decl *D)
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
for(const auto &A :T->param_types())
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
unsigned getFunctionOrMethodNumParams(const Decl *D)
getFunctionOrMethodNumParams - Return number of function or method parameters.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ None
No keyword precedes the qualified type name.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Extra information about a function prototype.
unsigned AArch64SMEAttributes
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned Indentation
The number of spaces to use to indent each line.
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
unsigned NumCallArgs
The number of expressions in CallArgs.
const Expr *const * CallArgs
The list of argument expressions in a synthesized call.
@ BuildingBuiltinDumpStructCall
We are building an implied call from __builtin_dump_struct.
SmallVector< MisalignedMember, 4 > MisalignedMembers
Small set of gathered accesses to potentially misaligned members due to the packed attribute.